mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-24 01:26:47 +01:00
Merge pull request #1023 from mholt/log-request-body
Now logging the request body
This commit is contained in:
commit
7dd385f6b4
2 changed files with 81 additions and 2 deletions
|
@ -1,6 +1,9 @@
|
||||||
package httpserver
|
package httpserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
|
@ -116,6 +119,18 @@ func NewReplacer(r *http.Request, rr *ResponseRecorder, emptyValue string) Repla
|
||||||
|
|
||||||
return requestReplacer.Replace(string(dump))
|
return requestReplacer.Replace(string(dump))
|
||||||
},
|
},
|
||||||
|
"{request_body}": func() string {
|
||||||
|
if !canLogRequest(r) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := readRequestBody(r, maxLogBodySize)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestReplacer.Replace(string(body))
|
||||||
|
},
|
||||||
},
|
},
|
||||||
emptyValue: emptyValue,
|
emptyValue: emptyValue,
|
||||||
}
|
}
|
||||||
|
@ -129,6 +144,39 @@ func NewReplacer(r *http.Request, rr *ResponseRecorder, emptyValue string) Repla
|
||||||
return rep
|
return rep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canLogRequest(r *http.Request) bool {
|
||||||
|
if r.Method == "POST" || r.Method == "PUT" {
|
||||||
|
for _, cType := range r.Header[headerContentType] {
|
||||||
|
// the cType could have charset and other info
|
||||||
|
if strings.Index(cType, contentTypeJSON) > -1 || strings.Index(cType, contentTypeXML) > -1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// readRequestBody reads the request body and sets a
|
||||||
|
// new io.ReadCloser that has not yet been read.
|
||||||
|
func readRequestBody(r *http.Request, n int64) ([]byte, error) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(io.LimitReader(r.Body, n))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the remaining bytes
|
||||||
|
remaining, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.NewBuffer(append(body, remaining...))
|
||||||
|
r.Body = ioutil.NopCloser(buf)
|
||||||
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Replace performs a replacement of values on s and returns
|
// Replace performs a replacement of values on s and returns
|
||||||
// the string with the replaced values.
|
// the string with the replaced values.
|
||||||
func (r *replacer) Replace(s string) string {
|
func (r *replacer) Replace(s string) string {
|
||||||
|
@ -223,6 +271,10 @@ func (r *replacer) Set(key, value string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
timeFormat = "02/Jan/2006:15:04:05 -0700"
|
timeFormat = "02/Jan/2006:15:04:05 -0700"
|
||||||
headerReplacer = "{>"
|
headerReplacer = "{>"
|
||||||
|
headerContentType = "Content-Type"
|
||||||
|
contentTypeJSON = "application/json"
|
||||||
|
contentTypeXML = "application/xml"
|
||||||
|
maxLogBodySize = 100 * 1024
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package httpserver
|
package httpserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
|
@ -161,3 +163,28 @@ func TestRound(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadRequestBody(t *testing.T) {
|
||||||
|
payload := []byte(`{ "foo": "bar" }`)
|
||||||
|
var readSize int64 = 5
|
||||||
|
r, err := http.NewRequest("POST", "/", bytes.NewReader(payload))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
logBody, err := readRequestBody(r, readSize)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("readRequestBody failed", err)
|
||||||
|
} else if !bytes.EqualFold(payload[0:readSize], logBody) {
|
||||||
|
t.Error("Expected log comparison failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the Request body is the same as the original.
|
||||||
|
reqBody, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Unable to read request body", err)
|
||||||
|
} else if !bytes.EqualFold(payload, reqBody) {
|
||||||
|
t.Error("Expected request body comparison failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue