Blame view

http.go 5.02 KB
ea858b8a7   Marko Tikvić   refactoring
1
  package webutility
64041a2ea   Marko Tikvić   first commit
2
3
  
  import (
11933054a   Marko Tikvić   Added Get, Post a...
4
  	"bytes"
64041a2ea   Marko Tikvić   first commit
5
  	"encoding/json"
ad8e9dd2a   Marko Tikvić   added middleware ...
6
  	"fmt"
11933054a   Marko Tikvić   Added Get, Post a...
7
  	"io"
d2ddf82ef   Marko Tikvić   started on new rbac
8
  	"net/http"
11933054a   Marko Tikvić   Added Get, Post a...
9
  	"net/url"
64041a2ea   Marko Tikvić   first commit
10
  )
707782344   Marko Tikvić   lint; vet
11
  // StatusRecorder ...
f38e87cf4   Marko Tikvić   status recorder
12
13
  type StatusRecorder struct {
  	writer http.ResponseWriter
34436d11e   Marko Tikvić   in-out http logs ...
14
  	status int
f38e87cf4   Marko Tikvić   status recorder
15
  	size   int
34436d11e   Marko Tikvić   in-out http logs ...
16
  }
707782344   Marko Tikvić   lint; vet
17
  // NewStatusRecorder ...
f38e87cf4   Marko Tikvić   status recorder
18
19
20
21
22
23
  func NewStatusRecorder(w http.ResponseWriter) *StatusRecorder {
  	return &StatusRecorder{
  		writer: w,
  		status: 0,
  		size:   0,
  	}
34436d11e   Marko Tikvić   in-out http logs ...
24
  }
707782344   Marko Tikvić   lint; vet
25
  // WriteHeader is a wrapper http.ResponseWriter interface
f38e87cf4   Marko Tikvić   status recorder
26
  func (r *StatusRecorder) WriteHeader(code int) {
34436d11e   Marko Tikvić   in-out http logs ...
27
  	r.status = code
f38e87cf4   Marko Tikvić   status recorder
28
29
  	r.writer.WriteHeader(code)
  }
707782344   Marko Tikvić   lint; vet
30
  // Write is a wrapper for http.ResponseWriter interface
f38e87cf4   Marko Tikvić   status recorder
31
32
33
  func (r *StatusRecorder) Write(in []byte) (int, error) {
  	r.size = len(in)
  	return r.writer.Write(in)
34436d11e   Marko Tikvić   in-out http logs ...
34
  }
707782344   Marko Tikvić   lint; vet
35
  // Header is a wrapper for http.ResponseWriter interface
f38e87cf4   Marko Tikvić   status recorder
36
37
38
  func (r *StatusRecorder) Header() http.Header {
  	return r.writer.Header()
  }
707782344   Marko Tikvić   lint; vet
39
  // Status ...
f38e87cf4   Marko Tikvić   status recorder
40
  func (r *StatusRecorder) Status() int {
34436d11e   Marko Tikvić   in-out http logs ...
41
42
  	return r.status
  }
707782344   Marko Tikvić   lint; vet
43
  // Size ...
f38e87cf4   Marko Tikvić   status recorder
44
45
46
  func (r *StatusRecorder) Size() int {
  	return r.size
  }
ad8e9dd2a   Marko Tikvić   added middleware ...
47
48
  // NotFoundHandlerFunc writes HTTP error 404 to w.
  func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) {
9933169c8   Marko Tikvić   localization support
49
50
51
52
  	SetDefaultHeaders(w)
  	if req.Method == "OPTIONS" {
  		return
  	}
ad8e9dd2a   Marko Tikvić   added middleware ...
53
  	NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String()))
9933169c8   Marko Tikvić   localization support
54
  }
46b2215eb   Marko Tikvić   lintfix
55
  // SetContentType ...
cacf57bd4   Marko Tikvić   merging with /uti...
56
57
58
  func SetContentType(w http.ResponseWriter, ctype string) {
  	w.Header().Set("Content-Type", ctype)
  }
46b2215eb   Marko Tikvić   lintfix
59
  // SetResponseStatus ...
cacf57bd4   Marko Tikvić   merging with /uti...
60
61
62
  func SetResponseStatus(w http.ResponseWriter, status int) {
  	w.WriteHeader(status)
  }
46b2215eb   Marko Tikvić   lintfix
63
  // WriteResponse ...
cacf57bd4   Marko Tikvić   merging with /uti...
64
65
66
  func WriteResponse(w http.ResponseWriter, content []byte) {
  	w.Write(content)
  }
9933169c8   Marko Tikvić   localization support
67
68
69
70
  // SetDefaultHeaders set's default headers for an HTTP response.
  func SetDefaultHeaders(w http.ResponseWriter) {
  	w.Header().Set("Access-Control-Allow-Origin", "*")
  	w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
34436d11e   Marko Tikvić   in-out http logs ...
71
  	w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
cacf57bd4   Marko Tikvić   merging with /uti...
72
  	SetContentType(w, "application/json; charset=utf-8")
9933169c8   Marko Tikvić   localization support
73
  }
707782344   Marko Tikvić   lint; vet
74
  // GetLocale ...
34436d11e   Marko Tikvić   in-out http logs ...
75
  func GetLocale(req *http.Request, dflt string) string {
a205e8f40   Marko Tikvić   changes
76
77
78
79
80
81
  	loc := req.FormValue("locale")
  	if loc == "" {
  		return dflt
  	}
  	return loc
  }
707782344   Marko Tikvić   lint; vet
82
  // Success ...
1b7dfab73   Marko Tikvić   Payload changed t...
83
  func Success(w http.ResponseWriter, payload interface{}, code int) {
9933169c8   Marko Tikvić   localization support
84
85
  	w.WriteHeader(code)
  	if payload != nil {
1b7dfab73   Marko Tikvić   Payload changed t...
86
  		json.NewEncoder(w).Encode(payload)
9933169c8   Marko Tikvić   localization support
87
88
  	}
  }
707782344   Marko Tikvić   lint; vet
89
  // OK ...
1b7dfab73   Marko Tikvić   Payload changed t...
90
  func OK(w http.ResponseWriter, payload interface{}) {
9933169c8   Marko Tikvić   localization support
91
92
  	Success(w, payload, http.StatusOK)
  }
707782344   Marko Tikvić   lint; vet
93
  // Created ...
1b7dfab73   Marko Tikvić   Payload changed t...
94
  func Created(w http.ResponseWriter, payload interface{}) {
9933169c8   Marko Tikvić   localization support
95
96
  	Success(w, payload, http.StatusCreated)
  }
3fffcb954   Marko Tikvić   removed old http API
97
98
99
100
  type weberror struct {
  	Request string `json:"request"`
  	Error   string `json:"error"`
  }
707782344   Marko Tikvić   lint; vet
101
  // Error ...
9933169c8   Marko Tikvić   localization support
102
  func Error(w http.ResponseWriter, r *http.Request, code int, err string) {
3fffcb954   Marko Tikvić   removed old http API
103
  	werr := weberror{Error: err, Request: r.Method + " " + r.RequestURI}
9933169c8   Marko Tikvić   localization support
104
105
106
  	w.WriteHeader(code)
  	json.NewEncoder(w).Encode(werr)
  }
707782344   Marko Tikvić   lint; vet
107
  // BadRequest ...
9933169c8   Marko Tikvić   localization support
108
109
110
  func BadRequest(w http.ResponseWriter, r *http.Request, err string) {
  	Error(w, r, http.StatusBadRequest, err)
  }
707782344   Marko Tikvić   lint; vet
111
  // Unauthorized ...
9933169c8   Marko Tikvić   localization support
112
113
114
  func Unauthorized(w http.ResponseWriter, r *http.Request, err string) {
  	Error(w, r, http.StatusUnauthorized, err)
  }
707782344   Marko Tikvić   lint; vet
115
  // Forbidden ...
9933169c8   Marko Tikvić   localization support
116
117
118
  func Forbidden(w http.ResponseWriter, r *http.Request, err string) {
  	Error(w, r, http.StatusForbidden, err)
  }
707782344   Marko Tikvić   lint; vet
119
  // NotFound ...
1b7dfab73   Marko Tikvić   Payload changed t...
120
121
122
  func NotFound(w http.ResponseWriter, r *http.Request, err string) {
  	Error(w, r, http.StatusNotFound, err)
  }
707782344   Marko Tikvić   lint; vet
123
  // Conflict ...
9933169c8   Marko Tikvić   localization support
124
125
126
  func Conflict(w http.ResponseWriter, r *http.Request, err string) {
  	Error(w, r, http.StatusConflict, err)
  }
707782344   Marko Tikvić   lint; vet
127
  // InternalServerError ...
9933169c8   Marko Tikvić   localization support
128
129
130
  func InternalServerError(w http.ResponseWriter, r *http.Request, err string) {
  	Error(w, r, http.StatusInternalServerError, err)
  }
46b2215eb   Marko Tikvić   lintfix
131

11933054a   Marko Tikvić   Added Get, Post a...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  // DecodeJSON decodes JSON data from r to v.
  // Returns an error if it fails.
  func DecodeJSON(r io.Reader, v interface{}) error {
  	return json.NewDecoder(r).Decode(v)
  }
  
  func GetJSON(url string, v interface{}, params url.Values, headers http.Header) (status int, err error) {
  	p := params.Encode()
  	if p != "" {
  		url += "?" + p
  	}
  
  	req, err := http.NewRequest(http.MethodGet, url, nil)
  	if err != nil {
  		return 0, err
  	}
  
  	if headers != nil {
  		for k, head := range headers {
  			for i, h := range head {
  				if i == 0 {
  					req.Header.Set(k, h)
  				} else {
  					req.Header.Add(k, h)
  				}
  			}
  		}
  	}
  
  	resp, err := http.DefaultClient.Do(req)
  	if err != nil {
  		return 0, err
  	}
  	status = resp.StatusCode
  
  	return status, DecodeJSON(resp.Body, v)
  }
  
  func PostJSON(url string, v, r interface{}, params url.Values, headers http.Header) (status int, err error) {
  	buffer := bytes.NewBuffer(make([]byte, 0))
  	json.NewEncoder(buffer).Encode(v)
  
  	p := params.Encode()
  	if p != "" {
  		url += "?" + p
  	}
  
  	req, err := http.NewRequest(http.MethodPost, url, buffer)
  	if err != nil {
  		return 0, err
  	}
  
  	if headers != nil {
  		for k, head := range headers {
  			for i, h := range head {
  				if i == 0 {
  					req.Header.Set(k, h)
  				} else {
  					req.Header.Add(k, h)
  				}
  			}
  		}
  	}
  	req.Header.Set("Content-Type", "application/json")
  
  	resp, err := http.DefaultClient.Do(req)
  	if err != nil {
  		return 0, err
  	}
  	status = resp.StatusCode
  
  	return status, DecodeJSON(resp.Body, r)
  }