// DoRequest invokes a request on the given handler with the given // parameters. func DoRequest(c *gc.C, p DoRequestParams) *httptest.ResponseRecorder { if p.Method == "" { p.Method = "GET" } if p.Do == nil { p.Do = http.DefaultClient.Do } srv := httptest.NewServer(p.Handler) defer srv.Close() if p.JSONBody != nil { data, err := json.Marshal(p.JSONBody) c.Assert(err, jc.ErrorIsNil) p.Body = bytes.NewReader(data) } // Note: we avoid NewRequest's odious reader wrapping by using // a custom nopCloser function. req, err := http.NewRequest(p.Method, srv.URL+p.URL, nopCloser(p.Body)) c.Assert(err, jc.ErrorIsNil) if p.JSONBody != nil { req.Header.Set("Content-Type", "application/json") } for key, val := range p.Header { req.Header[key] = val } if p.ContentLength != 0 { req.ContentLength = p.ContentLength } else { req.ContentLength = bodyContentLength(p.Body) } if p.Username != "" || p.Password != "" { req.SetBasicAuth(p.Username, p.Password) } for _, cookie := range p.Cookies { req.AddCookie(cookie) } resp, err := p.Do(req) if p.ExpectError != "" { c.Assert(err, gc.ErrorMatches, p.ExpectError) return nil } c.Assert(err, jc.ErrorIsNil) defer resp.Body.Close() // TODO(rog) don't return a ResponseRecorder because we're not actually // using httptest.NewRecorder ? var rec httptest.ResponseRecorder rec.HeaderMap = resp.Header rec.Code = resp.StatusCode rec.Body = new(bytes.Buffer) _, err = io.Copy(rec.Body, resp.Body) c.Assert(err, jc.ErrorIsNil) return &rec }
// DoRequest is the same as Do except that it returns // an httptest.ResponseRecorder instead of an http.Response. // This function exists for backward compatibility reasons. func DoRequest(c *gc.C, p DoRequestParams) *httptest.ResponseRecorder { resp := Do(c, p) if p.ExpectError != "" { return nil } defer resp.Body.Close() var rec httptest.ResponseRecorder rec.HeaderMap = resp.Header rec.Code = resp.StatusCode rec.Body = new(bytes.Buffer) _, err := io.Copy(rec.Body, resp.Body) c.Assert(err, jc.ErrorIsNil) return &rec }