func (s *httpSuite) TestBasicAuthHeader(c *gc.C) { header := utils.BasicAuthHeader("eric", "sekrit") c.Assert(len(header), gc.Equals, 1) auth := header.Get("Authorization") fields := strings.Fields(auth) c.Assert(len(fields), gc.Equals, 2) basic, encoded := fields[0], fields[1] c.Assert(basic, gc.Equals, "Basic") decoded, err := base64.StdEncoding.DecodeString(encoded) c.Assert(err, gc.IsNil) c.Assert(string(decoded), gc.Equals, "eric:sekrit") }
func (s *debugLogSuite) dialWebsocket(c *gc.C, queryParams url.Values) (*websocket.Conn, error) { header := utils.BasicAuthHeader(s.userTag, s.password) return s.dialWebsocketInternal(c, queryParams, header) }
// WatchDebugLog returns a ReadCloser that the caller can read the log // lines from. Only log lines that match the filtering specified in // the DebugLogParams are returned. It returns an error that satisfies // errors.IsNotImplemented when the API server does not support the // end-point. // // TODO(dimitern) We already have errors.IsNotImplemented - why do we // need to define a different error for this purpose here? func (c *Client) WatchDebugLog(args DebugLogParams) (io.ReadCloser, error) { // The websocket connection just hangs if the server doesn't have the log // end point. So do a version check, as version was added at the same time // as the remote end point. _, err := c.AgentVersion() if err != nil { return nil, errors.NotSupportedf("WatchDebugLog") } // Prepare URL. attrs := url.Values{} if args.Replay { attrs.Set("replay", fmt.Sprint(args.Replay)) } if args.Limit > 0 { attrs.Set("maxLines", fmt.Sprint(args.Limit)) } if args.Backlog > 0 { attrs.Set("backlog", fmt.Sprint(args.Backlog)) } if args.Level != loggo.UNSPECIFIED { attrs.Set("level", fmt.Sprint(args.Level)) } attrs["includeEntity"] = args.IncludeEntity attrs["includeModule"] = args.IncludeModule attrs["excludeEntity"] = args.ExcludeEntity attrs["excludeModule"] = args.ExcludeModule target := url.URL{ Scheme: "wss", Host: c.st.addr, Path: "/log", RawQuery: attrs.Encode(), } cfg, err := websocket.NewConfig(target.String(), "http://localhost/") cfg.Header = utils.BasicAuthHeader(c.st.tag, c.st.password) cfg.TlsConfig = &tls.Config{RootCAs: c.st.certPool, ServerName: "anything"} connection, err := websocketDialConfig(cfg) if err != nil { return nil, err } // Read the initial error and translate to a real error. // Read up to the first new line character. We can't use bufio here as it // reads too much from the reader. line := make([]byte, 4096) n, err := connection.Read(line) if err != nil { return nil, fmt.Errorf("unable to read initial response: %v", err) } line = line[0:n] logger.Debugf("initial line: %q", line) var errResult params.ErrorResult err = json.Unmarshal(line, &errResult) if err != nil { return nil, fmt.Errorf("unable to unmarshal initial response: %v", err) } if errResult.Error != nil { return nil, errResult.Error } return connection, nil }