You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
1.6 KiB
70 lines
1.6 KiB
package debug
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"os"
|
|
)
|
|
|
|
// DebugRequestTransport 会打印请求和响应信息, 方便调试.
|
|
type DebugRequestTransport struct {
|
|
RequestHeader bool
|
|
RequestBody bool // RequestHeader 为 true 时,这个选项才会生效
|
|
ResponseHeader bool
|
|
ResponseBody bool // ResponseHeader 为 true 时,这个选项才会生效
|
|
|
|
// debug 信息输出到 Writer 中, 默认是 os.Stderr
|
|
Writer io.Writer
|
|
|
|
Transport http.RoundTripper
|
|
}
|
|
|
|
// RoundTrip implements the RoundTripper interface.
|
|
func (t *DebugRequestTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
req = cloneRequest(req) // per RoundTrip contract
|
|
w := t.Writer
|
|
if w == nil {
|
|
w = os.Stderr
|
|
}
|
|
|
|
if t.RequestHeader {
|
|
a, _ := httputil.DumpRequest(req, t.RequestBody)
|
|
fmt.Fprintf(w, "%s\n\n", string(a))
|
|
}
|
|
|
|
resp, err := t.transport().RoundTrip(req)
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
|
|
if t.ResponseHeader {
|
|
|
|
b, _ := httputil.DumpResponse(resp, t.ResponseBody)
|
|
fmt.Fprintf(w, "%s\n", string(b))
|
|
}
|
|
|
|
return resp, err
|
|
}
|
|
|
|
func (t *DebugRequestTransport) transport() http.RoundTripper {
|
|
if t.Transport != nil {
|
|
return t.Transport
|
|
}
|
|
return http.DefaultTransport
|
|
}
|
|
|
|
// cloneRequest returns a clone of the provided *http.Request. The clone is a
|
|
// shallow copy of the struct and its Header map.
|
|
func cloneRequest(r *http.Request) *http.Request {
|
|
// shallow copy of the struct
|
|
r2 := new(http.Request)
|
|
*r2 = *r
|
|
// deep copy of the Header
|
|
r2.Header = make(http.Header, len(r.Header))
|
|
for k, s := range r.Header {
|
|
r2.Header[k] = append([]string(nil), s...)
|
|
}
|
|
return r2
|
|
}
|