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"
restful "github.com/emicklei/go-restful/v3"
)
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
}
|