Commit 34436d11e24884e190b5addb8fb575ad2676eb3f

Authored by Marko Tikvić
1 parent 932f814613
Exists in master and in 1 other branch v2

in-out http logs are written at the same time

Showing 2 changed files with 29 additions and 7 deletions   Show diff stats
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "encoding/json" 4 "encoding/json"
5 "fmt" 5 "fmt"
6 "net/http" 6 "net/http"
7 ) 7 )
8 8
9 type ResponseWriterStatusRecorder struct {
10 http.ResponseWriter
11 status int
12 }
13
14 func WrapWithStatusRecorder(w http.ResponseWriter) *ResponseWriterStatusRecorder {
15 return &ResponseWriterStatusRecorder{w, 0}
16 }
17
18 func (r *ResponseWriterStatusRecorder) WriteHeader(code int) {
19 r.status = code
20 r.ResponseWriter.WriteHeader(code)
21 }
22
23 func (r *ResponseWriterStatusRecorder) Status() int {
24 return r.status
25 }
26
9 // NotFoundHandlerFunc writes HTTP error 404 to w. 27 // NotFoundHandlerFunc writes HTTP error 404 to w.
10 func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) { 28 func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) {
11 SetDefaultHeaders(w) 29 SetDefaultHeaders(w)
12 if req.Method == "OPTIONS" { 30 if req.Method == "OPTIONS" {
13 return 31 return
14 } 32 }
15 NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String())) 33 NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String()))
16 } 34 }
17 35
18 // SetDefaultHeaders set's default headers for an HTTP response. 36 // SetDefaultHeaders set's default headers for an HTTP response.
19 func SetDefaultHeaders(w http.ResponseWriter) { 37 func SetDefaultHeaders(w http.ResponseWriter) {
20 w.Header().Set("Access-Control-Allow-Origin", "*") 38 w.Header().Set("Access-Control-Allow-Origin", "*")
21 w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") 39 w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
22 w.Header().Set("Access-Control-Allow-Headers", `Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization`) 40 w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
23 w.Header().Set("Content-Type", "application/json; charset=utf-8") 41 w.Header().Set("Content-Type", "application/json; charset=utf-8")
24 } 42 }
25 43
26 func ReqLocale(req *http.Request, dflt string) string { 44 func GetLocale(req *http.Request, dflt string) string {
27 loc := req.FormValue("locale") 45 loc := req.FormValue("locale")
28 if loc == "" { 46 if loc == "" {
29 return dflt 47 return dflt
30 } 48 }
31 return loc 49 return loc
32 } 50 }
33 51
34 // 2xx 52 // 2xx
35 func Success(w http.ResponseWriter, payload interface{}, code int) { 53 func Success(w http.ResponseWriter, payload interface{}, code int) {
36 w.WriteHeader(code) 54 w.WriteHeader(code)
37 if payload != nil { 55 if payload != nil {
38 json.NewEncoder(w).Encode(payload) 56 json.NewEncoder(w).Encode(payload)
39 } 57 }
40 } 58 }
41 59
42 // 200 60 // 200
43 func OK(w http.ResponseWriter, payload interface{}) { 61 func OK(w http.ResponseWriter, payload interface{}) {
44 Success(w, payload, http.StatusOK) 62 Success(w, payload, http.StatusOK)
45 } 63 }
46 64
47 // 201 65 // 201
48 func Created(w http.ResponseWriter, payload interface{}) { 66 func Created(w http.ResponseWriter, payload interface{}) {
49 Success(w, payload, http.StatusCreated) 67 Success(w, payload, http.StatusCreated)
50 } 68 }
51 69
52 type weberror struct { 70 type weberror struct {
53 Request string `json:"request"` 71 Request string `json:"request"`
54 Error string `json:"error"` 72 Error string `json:"error"`
55 } 73 }
56 74
57 // 4xx; 5xx 75 // 4xx; 5xx
58 func Error(w http.ResponseWriter, r *http.Request, code int, err string) { 76 func Error(w http.ResponseWriter, r *http.Request, code int, err string) {
59 werr := weberror{Error: err, Request: r.Method + " " + r.RequestURI} 77 werr := weberror{Error: err, Request: r.Method + " " + r.RequestURI}
60 w.WriteHeader(code) 78 w.WriteHeader(code)
61 json.NewEncoder(w).Encode(werr) 79 json.NewEncoder(w).Encode(werr)
62 } 80 }
63 81
64 // 400 82 // 400
65 func BadRequest(w http.ResponseWriter, r *http.Request, err string) { 83 func BadRequest(w http.ResponseWriter, r *http.Request, err string) {
66 Error(w, r, http.StatusBadRequest, err) 84 Error(w, r, http.StatusBadRequest, err)
67 } 85 }
68 86
69 // 401 87 // 401
70 func Unauthorized(w http.ResponseWriter, r *http.Request, err string) { 88 func Unauthorized(w http.ResponseWriter, r *http.Request, err string) {
71 Error(w, r, http.StatusUnauthorized, err) 89 Error(w, r, http.StatusUnauthorized, err)
72 } 90 }
73 91
74 // 403 92 // 403
75 func Forbidden(w http.ResponseWriter, r *http.Request, err string) { 93 func Forbidden(w http.ResponseWriter, r *http.Request, err string) {
76 Error(w, r, http.StatusForbidden, err) 94 Error(w, r, http.StatusForbidden, err)
77 } 95 }
78 96
79 // 404 97 // 404
80 func NotFound(w http.ResponseWriter, r *http.Request, err string) { 98 func NotFound(w http.ResponseWriter, r *http.Request, err string) {
81 Error(w, r, http.StatusNotFound, err) 99 Error(w, r, http.StatusNotFound, err)
82 } 100 }
83 101
84 // 409 102 // 409
85 func Conflict(w http.ResponseWriter, r *http.Request, err string) { 103 func Conflict(w http.ResponseWriter, r *http.Request, err string) {
86 Error(w, r, http.StatusConflict, err) 104 Error(w, r, http.StatusConflict, err)
87 } 105 }
88 106
89 // 500 107 // 500
90 func InternalServerError(w http.ResponseWriter, r *http.Request, err string) { 108 func InternalServerError(w http.ResponseWriter, r *http.Request, err string) {
91 Error(w, r, http.StatusInternalServerError, err) 109 Error(w, r, http.StatusInternalServerError, err)
92 } 110 }
93 111
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "net/http" 4 "net/http"
5 "time" 5 "time"
6 6
7 "git.to-net.rs/marko.tikvic/gologger" 7 "git.to-net.rs/marko.tikvic/gologger"
8 ) 8 )
9 9
10 func SetHeaders(h http.HandlerFunc) http.HandlerFunc { 10 func SetHeaders(h http.HandlerFunc) http.HandlerFunc {
11 return func(w http.ResponseWriter, req *http.Request) { 11 return func(w http.ResponseWriter, req *http.Request) {
12 SetDefaultHeaders(w) 12 SetDefaultHeaders(w)
13 if req.Method == http.MethodOptions { 13 if req.Method == http.MethodOptions {
14 return 14 return
15 } 15 }
16 h(w, req) 16 h(w, req)
17 } 17 }
18 } 18 }
19 19
20 func ParseForm(h http.HandlerFunc) http.HandlerFunc { 20 func ParseForm(h http.HandlerFunc) http.HandlerFunc {
21 return func(w http.ResponseWriter, req *http.Request) { 21 return func(w http.ResponseWriter, req *http.Request) {
22 err := req.ParseForm() 22 err := req.ParseForm()
23 if err != nil { 23 if err != nil {
24 BadRequest(w, req, err.Error()) 24 BadRequest(w, req, err.Error())
25 return 25 return
26 } 26 }
27 h(w, req) 27 h(w, req)
28 } 28 }
29 } 29 }
30 30
31 var reqLogger *gologger.Logger 31 var trafficLogger *gologger.Logger
32 32
33 func EnableLogging(log string) error { 33 func EnableLogging(log string) error {
34 var err error 34 var err error
35 reqLogger, err = gologger.New(log, gologger.MaxLogSize5MB) 35 trafficLogger, err = gologger.New(log, gologger.MaxLogSize5MB)
36 return err 36 return err
37 } 37 }
38 38
39 func Log(h http.HandlerFunc) http.HandlerFunc { 39 func Log(h http.HandlerFunc) http.HandlerFunc {
40 return func(w http.ResponseWriter, req *http.Request) { 40 return func(w http.ResponseWriter, req *http.Request) {
41 reqLogger.LogRequest(req, "") 41 in := trafficLogger.RequestLog(req, "")
42
43 w2 := WrapWithStatusRecorder(w)
42 t1 := time.Now() 44 t1 := time.Now()
43 h(w, req) 45 h(w2, req)
44 t2 := time.Now() 46 t2 := time.Now()
45 reqLogger.LogResponse(w, req, t2.Sub(t1)) 47
48 out := trafficLogger.ResponseLog(w2.Status(), t2.Sub(t1))
49 trafficLogger.LogHTTPTraffic(in, out)
46 } 50 }
47 } 51 }
48 52
49 func Auth(roles string, h http.HandlerFunc) http.HandlerFunc { 53 func Auth(roles string, h http.HandlerFunc) http.HandlerFunc {
50 return func(w http.ResponseWriter, req *http.Request) { 54 return func(w http.ResponseWriter, req *http.Request) {
51 if _, ok := AuthCheck(req, roles); !ok { 55 if _, ok := AuthCheck(req, roles); !ok {
52 Unauthorized(w, req, "") 56 Unauthorized(w, req, "")
53 return 57 return
54 } 58 }
55 h(w, req) 59 h(w, req)
56 } 60 }
57 } 61 }
58 62