Commit 65d214f47d49a6a5637598d8fac7523f5fb40fa8
1 parent
32a277faa6
Exists in
master
improved middleware: more control over content type
Showing
4 changed files
with
47 additions
and
30 deletions
Show diff stats
auth.go
... | ... | @@ -171,7 +171,7 @@ func GetTokenClaims(req *http.Request) (*TokenClaims, error) { |
171 | 171 | if ok := strings.HasPrefix(authHead, "Bearer "); ok { |
172 | 172 | tokstr = strings.TrimPrefix(authHead, "Bearer ") |
173 | 173 | } else { |
174 | - return &TokenClaims{}, errors.New("authorization header in incomplete") | |
174 | + return &TokenClaims{}, errors.New("authorization header is incomplete") | |
175 | 175 | } |
176 | 176 | |
177 | 177 | token, err := jwt.ParseWithClaims(tokstr, &TokenClaims{}, secretFunc) | ... | ... |
http.go
... | ... | @@ -51,14 +51,12 @@ func (r *StatusRecorder) Size() int { |
51 | 51 | |
52 | 52 | // NotFoundHandlerFunc writes HTTP error 404 to w. |
53 | 53 | func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) { |
54 | - SetDefaultHeaders(w) | |
55 | - if req.Method == "OPTIONS" { | |
56 | - return | |
57 | - } | |
54 | + SetAccessControlHeaders(w) | |
55 | + SetContentType(w, "application/json") | |
58 | 56 | NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String())) |
59 | 57 | } |
60 | 58 | |
61 | -// SetContentType ... | |
59 | +// SetContentType must be called before SetResponseStatus (w.WriteHeader) (?) | |
62 | 60 | func SetContentType(w http.ResponseWriter, ctype string) { |
63 | 61 | w.Header().Set("Content-Type", ctype) |
64 | 62 | } |
... | ... | @@ -73,12 +71,11 @@ func WriteResponse(w http.ResponseWriter, content []byte) { |
73 | 71 | w.Write(content) |
74 | 72 | } |
75 | 73 | |
76 | -// SetDefaultHeaders set's default headers for an HTTP response. | |
77 | -func SetDefaultHeaders(w http.ResponseWriter) { | |
74 | +// SetAccessControlHeaders set's default headers for an HTTP response. | |
75 | +func SetAccessControlHeaders(w http.ResponseWriter) { | |
78 | 76 | w.Header().Set("Access-Control-Allow-Origin", "*") |
79 | 77 | w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") |
80 | 78 | w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") |
81 | - SetContentType(w, "application/json; charset=utf-8") | |
82 | 79 | } |
83 | 80 | |
84 | 81 | // GetLocale ... |
... | ... | @@ -100,11 +97,13 @@ func Success(w http.ResponseWriter, payload interface{}, code int) { |
100 | 97 | |
101 | 98 | // OK ... |
102 | 99 | func OK(w http.ResponseWriter, payload interface{}) { |
100 | + SetContentType(w, "application/json") | |
103 | 101 | Success(w, payload, http.StatusOK) |
104 | 102 | } |
105 | 103 | |
106 | 104 | // Created ... |
107 | 105 | func Created(w http.ResponseWriter, payload interface{}) { |
106 | + SetContentType(w, "application/json") | |
108 | 107 | Success(w, payload, http.StatusCreated) |
109 | 108 | } |
110 | 109 | |
... | ... | @@ -122,30 +121,36 @@ func Error(w http.ResponseWriter, r *http.Request, code int, err string) { |
122 | 121 | |
123 | 122 | // BadRequest ... |
124 | 123 | func BadRequest(w http.ResponseWriter, r *http.Request, err string) { |
124 | + SetContentType(w, "application/json") | |
125 | 125 | Error(w, r, http.StatusBadRequest, err) |
126 | 126 | } |
127 | 127 | |
128 | 128 | // Unauthorized ... |
129 | 129 | func Unauthorized(w http.ResponseWriter, r *http.Request, err string) { |
130 | + SetContentType(w, "application/json") | |
130 | 131 | Error(w, r, http.StatusUnauthorized, err) |
131 | 132 | } |
132 | 133 | |
133 | 134 | // Forbidden ... |
134 | 135 | func Forbidden(w http.ResponseWriter, r *http.Request, err string) { |
136 | + SetContentType(w, "application/json") | |
135 | 137 | Error(w, r, http.StatusForbidden, err) |
136 | 138 | } |
137 | 139 | |
138 | 140 | // NotFound ... |
139 | 141 | func NotFound(w http.ResponseWriter, r *http.Request, err string) { |
142 | + SetContentType(w, "application/json") | |
140 | 143 | Error(w, r, http.StatusNotFound, err) |
141 | 144 | } |
142 | 145 | |
143 | 146 | // Conflict ... |
144 | 147 | func Conflict(w http.ResponseWriter, r *http.Request, err string) { |
148 | + SetContentType(w, "application/json") | |
145 | 149 | Error(w, r, http.StatusConflict, err) |
146 | 150 | } |
147 | 151 | |
148 | 152 | // InternalServerError ... |
149 | 153 | func InternalServerError(w http.ResponseWriter, r *http.Request, err string) { |
154 | + SetContentType(w, "application/json") | |
150 | 155 | Error(w, r, http.StatusInternalServerError, err) |
151 | 156 | } | ... | ... |
middleware/main.go
... | ... | @@ -5,17 +5,17 @@ import ( |
5 | 5 | ) |
6 | 6 | |
7 | 7 | func Headers(h http.HandlerFunc) http.HandlerFunc { |
8 | - return IgnoreOptionsRequests(ParseForm(h)) | |
8 | + return SetAccessControlHeaders(IgnoreOptionsRequests(ParseForm(h))) | |
9 | 9 | } |
10 | 10 | |
11 | -func AuthOnly(roles string, h http.HandlerFunc) http.HandlerFunc { | |
12 | - return IgnoreOptionsRequests(ParseForm(Auth(roles, h))) | |
11 | +func AuthUser(roles string, h http.HandlerFunc) http.HandlerFunc { | |
12 | + return SetAccessControlHeaders(IgnoreOptionsRequests(ParseForm(Auth(roles, h)))) | |
13 | 13 | } |
14 | 14 | |
15 | -func Full(roles string, h http.HandlerFunc) http.HandlerFunc { | |
16 | - return IgnoreOptionsRequests(ParseForm(LogTraffic(Auth(roles, h)))) | |
15 | +func AuthUserLogTraffic(roles string, h http.HandlerFunc) http.HandlerFunc { | |
16 | + return SetAccessControlHeaders(IgnoreOptionsRequests(ParseForm(LogHTTP(Auth(roles, h))))) | |
17 | 17 | } |
18 | 18 | |
19 | 19 | func LogTraffic(h http.HandlerFunc) http.HandlerFunc { |
20 | - return IgnoreOptionsRequests(ParseForm(LogRequestAndResponse(h))) | |
20 | + return SetAccessControlHeaders(IgnoreOptionsRequests(ParseForm(LogHTTP(h)))) | |
21 | 21 | } | ... | ... |
middleware/middleware.go
... | ... | @@ -11,13 +11,21 @@ import ( |
11 | 11 | |
12 | 12 | var httpLogger *gologger.Logger |
13 | 13 | |
14 | +func SetAccessControlHeaders(h http.HandlerFunc) http.HandlerFunc { | |
15 | + return func(w http.ResponseWriter, req *http.Request) { | |
16 | + web.SetAccessControlHeaders(w) | |
17 | + | |
18 | + h(w, req) | |
19 | + } | |
20 | +} | |
21 | + | |
14 | 22 | // IgnoreOptionsRequests ... |
15 | 23 | func IgnoreOptionsRequests(h http.HandlerFunc) http.HandlerFunc { |
16 | 24 | return func(w http.ResponseWriter, req *http.Request) { |
17 | - web.SetDefaultHeaders(w) | |
18 | 25 | if req.Method == http.MethodOptions { |
19 | 26 | return |
20 | 27 | } |
28 | + | |
21 | 29 | h(w, req) |
22 | 30 | } |
23 | 31 | } |
... | ... | @@ -30,6 +38,7 @@ func ParseForm(h http.HandlerFunc) http.HandlerFunc { |
30 | 38 | web.BadRequest(w, req, err.Error()) |
31 | 39 | return |
32 | 40 | } |
41 | + | |
33 | 42 | h(w, req) |
34 | 43 | } |
35 | 44 | } |
... | ... | @@ -42,6 +51,7 @@ func ParseMultipartForm(h http.HandlerFunc) http.HandlerFunc { |
42 | 51 | web.BadRequest(w, req, err.Error()) |
43 | 52 | return |
44 | 53 | } |
54 | + | |
45 | 55 | h(w, req) |
46 | 56 | } |
47 | 57 | } |
... | ... | @@ -51,26 +61,27 @@ func SetLogger(logger *gologger.Logger) { |
51 | 61 | httpLogger = logger |
52 | 62 | } |
53 | 63 | |
54 | -// LogRequestAndResponse ... | |
55 | -func LogRequestAndResponse(h http.HandlerFunc) http.HandlerFunc { | |
64 | +// LogHTTP ... | |
65 | +func LogHTTP(h http.HandlerFunc) http.HandlerFunc { | |
56 | 66 | return func(w http.ResponseWriter, req *http.Request) { |
57 | - if httpLogger != nil { | |
58 | - t1 := time.Now() | |
67 | + if httpLogger == nil { | |
68 | + h(w, req) | |
69 | + return | |
70 | + } | |
59 | 71 | |
60 | - claims, _ := web.GetTokenClaims(req) | |
61 | - in := httpLogger.LogHTTPRequest(req, claims.Username) | |
72 | + t1 := time.Now() | |
62 | 73 | |
63 | - rec := web.NewStatusRecorder(w) | |
74 | + claims, _ := web.GetTokenClaims(req) | |
75 | + in := httpLogger.LogHTTPRequest(req, claims.Username) | |
64 | 76 | |
65 | - h(rec, req) | |
77 | + rec := web.NewStatusRecorder(w) | |
66 | 78 | |
67 | - t2 := time.Now() | |
68 | - out := httpLogger.LogHTTPResponse(rec.Status(), t2.Sub(t1), rec.Size()) | |
79 | + h(rec, req) | |
69 | 80 | |
70 | - httpLogger.CombineHTTPLogs(in, out) | |
71 | - } else { | |
72 | - h(w, req) | |
73 | - } | |
81 | + t2 := time.Now() | |
82 | + out := httpLogger.LogHTTPResponse(rec.Status(), t2.Sub(t1), rec.Size()) | |
83 | + | |
84 | + httpLogger.CombineHTTPLogs(in, out) | |
74 | 85 | } |
75 | 86 | } |
76 | 87 | |
... | ... | @@ -81,6 +92,7 @@ func Auth(roles string, h http.HandlerFunc) http.HandlerFunc { |
81 | 92 | web.Unauthorized(w, req, err.Error()) |
82 | 93 | return |
83 | 94 | } |
95 | + | |
84 | 96 | h(w, req) |
85 | 97 | } |
86 | 98 | } | ... | ... |