1
mirror of https://github.com/rclone/rclone synced 2025-01-13 17:06:24 +01:00

Implement --dump-headers and --dump-bodies debug flags

This commit is contained in:
Nick Craig-Wood 2015-09-08 21:01:26 +01:00
parent 7e7c239f09
commit dd8717797e
2 changed files with 65 additions and 1 deletions

View File

@ -50,6 +50,8 @@ var (
dryRun = pflag.BoolP("dry-run", "n", false, "Do a trial run with no permanent changes")
connectTimeout = pflag.DurationP("contimeout", "", 60*time.Second, "Connect timeout")
timeout = pflag.DurationP("timeout", "", 5*60*time.Second, "IO idle timeout")
dumpHeaders = pflag.BoolP("dump-headers", "", false, "Dump HTTP headers - may contain sensitive info")
dumpBodies = pflag.BoolP("dump-bodies", "", false, "Dump HTTP headers and bodies - may contain sensitive info")
bwLimit SizeSuffix
)
@ -155,11 +157,13 @@ type ConfigInfo struct {
Transfers int
ConnectTimeout time.Duration // Connect timeout
Timeout time.Duration // Data channel timeout
DumpHeaders bool
DumpBodies bool
}
// Transport returns an http.RoundTripper with the correct timeouts
func (ci *ConfigInfo) Transport() http.RoundTripper {
return &httpclient.Transport{
t := &httpclient.Transport{
Proxy: http.ProxyFromEnvironment,
MaxIdleConnsPerHost: ci.Checkers + ci.Transfers + 1,
@ -182,6 +186,10 @@ func (ci *ConfigInfo) Transport() http.RoundTripper {
// Write operation on the request connection.
ReadWriteTimeout: ci.Timeout,
}
if ci.DumpHeaders || ci.DumpBodies {
return NewLoggedTransport(t, ci.DumpBodies)
}
return t
}
// Transport returns an http.Client with the correct timeouts
@ -227,6 +235,8 @@ func LoadConfig() {
Config.ConnectTimeout = *connectTimeout
Config.CheckSum = *checkSum
Config.SizeOnly = *sizeOnly
Config.DumpHeaders = *dumpHeaders
Config.DumpBodies = *dumpBodies
ConfigPath = *configFile

54
fs/loghttp.go Normal file
View File

@ -0,0 +1,54 @@
// A logging http transport
package fs
import (
"log"
"net/http"
"net/http/httputil"
)
const separator = "------------------------------------------------------------"
// An http transport which logs the traffic
type loggedTransport struct {
wrapped http.RoundTripper
logBody bool
}
// NewLoggedTransport wraps the transport passed in and logs all roundtrips
// including the body if logBody is set.
func NewLoggedTransport(transport http.RoundTripper, logBody bool) *loggedTransport {
return &loggedTransport{
wrapped: transport,
logBody: logBody,
}
}
// CancelRequest cancels an in-flight request by closing its
// connection. CancelRequest should only be called after RoundTrip has
// returned.
func (t *loggedTransport) CancelRequest(req *http.Request) {
if wrapped, ok := t.wrapped.(interface {
CancelRequest(*http.Request)
}); ok {
log.Printf("CANCEL REQUEST %v", req)
wrapped.CancelRequest(req)
}
}
// RoundTrip implements the RoundTripper interface.
func (t *loggedTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
buf, _ := httputil.DumpRequest(req, t.logBody)
log.Println(separator)
log.Println("HTTP REQUEST")
log.Println(string(buf))
log.Println(separator)
resp, err = t.wrapped.RoundTrip(req)
buf, _ = httputil.DumpResponse(resp, t.logBody)
log.Println(separator)
log.Println("HTTP RESPONSE")
log.Println(string(buf))
log.Println(separator)
return resp, err
}