// ModifyRequest logs the request, optionally including the body. // // The format logged is: // -------------------------------------------------------------------------------- // Request to http://www.google.com/path?querystring // -------------------------------------------------------------------------------- // GET /path?querystring HTTP/1.1 // Host: www.google.com // Connection: close // Other-Header: values // // request content // -------------------------------------------------------------------------------- func (l *Logger) ModifyRequest(req *http.Request) error { b := &bytes.Buffer{} fmt.Fprintln(b, "") fmt.Fprintln(b, strings.Repeat("-", 80)) fmt.Fprintf(b, "Request to %s\n", req.URL) fmt.Fprintln(b, strings.Repeat("-", 80)) mv := messageview.New() mv.SkipBody(l.headersOnly) if err := mv.SnapshotRequest(req); err != nil { return err } var opts []messageview.Option if l.decode { opts = append(opts, messageview.Decode()) } r, err := mv.Reader(opts...) if err != nil { return err } io.Copy(b, r) fmt.Fprintln(b, "") fmt.Fprintln(b, strings.Repeat("-", 80)) l.log(b.String()) return nil }
// RecordResponse logs an HTTP response, associating it with the previously-logged // HTTP request with the same ID. func (l *Logger) RecordResponse(id string, res *http.Response) error { hres := &Response{ HTTPVersion: res.Proto, Status: res.StatusCode, StatusText: http.StatusText(res.StatusCode), HeadersSize: -1, BodySize: res.ContentLength, Headers: headers(proxyutil.ResponseHeader(res).Map()), Cookies: cookies(res.Cookies()), } if res.StatusCode >= 300 && res.StatusCode < 400 { hres.RedirectURL = res.Header.Get("Location") } hres.Content = &Content{ Encoding: "base64", MimeType: res.Header.Get("Content-Type"), } if l.bodyLogging(res) { mv := messageview.New() if err := mv.SnapshotResponse(res); err != nil { return err } br, err := mv.BodyReader(messageview.Decode()) if err != nil { return err } body, err := ioutil.ReadAll(br) if err != nil { return err } hres.Content.Text = body hres.Content.Size = int64(len(body)) } l.mu.Lock() defer l.mu.Unlock() if e, ok := l.entries[id]; ok { e.Response = hres e.Time = time.Since(e.StartedDateTime).Nanoseconds() / 1000000 } return nil }