forked from emicklei/go-restful
-
Notifications
You must be signed in to change notification settings - Fork 0
/
restful-full-logging-filter.go
104 lines (84 loc) · 2.22 KB
/
restful-full-logging-filter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"bytes"
"io/ioutil"
"log"
"net/http"
"github.com/emicklei/go-restful"
)
type User struct {
Id int
Name string
}
//
// This example shows how to log both the request body and response body
func main() {
restful.Add(newUserService())
log.Print("start listening on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func newUserService() *restful.WebService {
ws := new(restful.WebService)
ws.
Path("/users").
Consumes(restful.MIME_XML, restful.MIME_JSON).
Produces(restful.MIME_JSON, restful.MIME_XML)
ws.Route(ws.POST("/").Filter(bodyLogFilter).To(createUser))
return ws
}
// Route Filter (defines FilterFunction)
func bodyLogFilter(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
inBody, err := ioutil.ReadAll(req.Request.Body)
if err != nil {
resp.WriteError(400, err)
return
}
req.Request.Body = ioutil.NopCloser(bytes.NewReader(inBody))
c := NewResponseCapture(resp.ResponseWriter)
resp.ResponseWriter = c
chain.ProcessFilter(req, resp)
log.Println("Request body:", string(inBody))
log.Println("Response body:", string(c.Bytes()))
}
// curl -H "content-type:application/json" http://localhost:8080/users -d '{"Id":42, "Name":"Captain Marvel"}'
//
func createUser(request *restful.Request, response *restful.Response) {
u := new(User)
err := request.ReadEntity(u)
log.Print("createUser", err, u)
response.WriteEntity(u)
}
type ResponseCapture struct {
http.ResponseWriter
wroteHeader bool
status int
body *bytes.Buffer
}
func NewResponseCapture(w http.ResponseWriter) *ResponseCapture {
return &ResponseCapture{
ResponseWriter: w,
wroteHeader: false,
body: new(bytes.Buffer),
}
}
func (c ResponseCapture) Header() http.Header {
return c.ResponseWriter.Header()
}
func (c ResponseCapture) Write(data []byte) (int, error) {
if !c.wroteHeader {
c.WriteHeader(http.StatusOK)
}
c.body.Write(data)
return c.ResponseWriter.Write(data)
}
func (c *ResponseCapture) WriteHeader(statusCode int) {
c.status = statusCode
c.wroteHeader = true
c.ResponseWriter.WriteHeader(statusCode)
}
func (c ResponseCapture) Bytes() []byte {
return c.body.Bytes()
}
func (c ResponseCapture) StatusCode() int {
return c.status
}