1 #include "uwsgi.h"
2
3 extern struct uwsgi_server uwsgi;
4
uwsgi_buffer_new(size_t len)5 struct uwsgi_buffer *uwsgi_buffer_new(size_t len) {
6 #ifdef UWSGI_DEBUG_BUFFER
7 uwsgi_log("[uwsgi-buffer] allocating a new buffer of %llu\n", (unsigned long long) len);
8 #endif
9 struct uwsgi_buffer *ub = uwsgi_calloc(sizeof(struct uwsgi_buffer));
10
11 if (len) {
12 ub->buf = uwsgi_malloc(len);
13 ub->len = len;
14 }
15 return ub;
16
17 }
18
uwsgi_buffer_fix(struct uwsgi_buffer * ub,size_t len)19 int uwsgi_buffer_fix(struct uwsgi_buffer *ub, size_t len) {
20 if (ub->limit > 0 && len > ub->limit)
21 return -1;
22 if (ub->len < len) {
23 char *new_buf = realloc(ub->buf, len);
24 if (!new_buf) {
25 uwsgi_error("uwsgi_buffer_fix()");
26 return -1;
27 }
28 ub->buf = new_buf;
29 ub->len = len;
30 }
31 return 0;
32 }
33
uwsgi_buffer_ensure(struct uwsgi_buffer * ub,size_t len)34 int uwsgi_buffer_ensure(struct uwsgi_buffer *ub, size_t len) {
35 size_t remains = ub->len - ub->pos;
36 if (remains < len) {
37 size_t new_len = ub->len + (len - remains);
38 if (ub->limit > 0 && new_len > ub->limit) {
39 new_len = ub->limit;
40 if (new_len == ub->len)
41 return -1;
42 }
43 char *new_buf = realloc(ub->buf, new_len);
44 if (!new_buf) {
45 uwsgi_error("uwsgi_buffer_ensure()");
46 return -1;
47 }
48 ub->buf = new_buf;
49 ub->len = new_len;
50 }
51 return 0;
52 }
53
uwsgi_buffer_insert(struct uwsgi_buffer * ub,size_t pos,char * buf,size_t len)54 int uwsgi_buffer_insert(struct uwsgi_buffer *ub, size_t pos, char *buf, size_t len) {
55 size_t to_move = (ub->pos-pos);
56 if (uwsgi_buffer_ensure(ub, len)) return -1;
57 memmove(ub->buf+pos+len, ub->buf+pos, to_move);
58 memcpy(ub->buf+pos, buf, len);
59 ub->pos += len;
60 return 0;
61 }
62
uwsgi_buffer_insert_chunked(struct uwsgi_buffer * ub,size_t pos,size_t len)63 int uwsgi_buffer_insert_chunked(struct uwsgi_buffer *ub, size_t pos, size_t len) {
64 // 0xFFFFFFFFFFFFFFFF\r\n\0
65 char chunked[19];
66 int ret = snprintf(chunked, 19, "%X\r\n", (unsigned int) len);
67 if (ret <= 0 || ret >= 19) {
68 return -1;
69 }
70 return uwsgi_buffer_insert(ub, pos, chunked, ret);
71 }
72
uwsgi_buffer_append_chunked(struct uwsgi_buffer * ub,size_t len)73 int uwsgi_buffer_append_chunked(struct uwsgi_buffer *ub, size_t len) {
74 // 0xFFFFFFFFFFFFFFFF\r\n\0
75 char chunked[19];
76 int ret = snprintf(chunked, 19, "%X\r\n", (unsigned int) len);
77 if (ret <= 0 || ret >= 19) {
78 return -1;
79 }
80 return uwsgi_buffer_append(ub, chunked, ret);
81 }
82
83
uwsgi_buffer_decapitate(struct uwsgi_buffer * ub,size_t len)84 int uwsgi_buffer_decapitate(struct uwsgi_buffer *ub, size_t len) {
85 if (len > ub->pos) return -1;
86 memmove(ub->buf, ub->buf + len, ub->pos-len);
87 ub->pos = ub->pos-len;
88 return 0;
89 }
90
uwsgi_buffer_byte(struct uwsgi_buffer * ub,char byte)91 int uwsgi_buffer_byte(struct uwsgi_buffer *ub, char byte) {
92 return uwsgi_buffer_append(ub, &byte, 1);
93 }
94
uwsgi_buffer_u8(struct uwsgi_buffer * ub,uint8_t u8)95 int uwsgi_buffer_u8(struct uwsgi_buffer *ub, uint8_t u8) {
96 return uwsgi_buffer_append(ub, (char *) &u8, 1);
97 }
98
uwsgi_buffer_append(struct uwsgi_buffer * ub,char * buf,size_t len)99 int uwsgi_buffer_append(struct uwsgi_buffer *ub, char *buf, size_t len) {
100
101 size_t remains = ub->len - ub->pos;
102
103 if (len > remains) {
104 size_t chunk_size = UMAX(len, (size_t) uwsgi.page_size);
105 if (ub->limit > 0 && ub->len + chunk_size > ub->limit) {
106 // retry with another minimal size
107 if (len < (size_t) uwsgi.page_size) {
108 chunk_size = len;
109 }
110 if (ub->len + chunk_size > ub->limit)
111 return -1;
112 }
113 char *new_buf = realloc(ub->buf, ub->len + chunk_size);
114 if (!new_buf) {
115 uwsgi_error("uwsgi_buffer_append()");
116 return -1;
117 }
118 ub->buf = new_buf;
119 ub->len += chunk_size;
120 }
121
122 memcpy(ub->buf + ub->pos, buf, len);
123 ub->pos += len;
124 return 0;
125 }
126
uwsgi_buffer_append_json(struct uwsgi_buffer * ub,char * buf,size_t len)127 int uwsgi_buffer_append_json(struct uwsgi_buffer *ub, char *buf, size_t len) {
128 // need to escape \ and "
129 size_t i;
130 for(i=0;i<len;i++) {
131 if (buf[i] == '\t') {
132 if (uwsgi_buffer_append(ub, "\\t", 2)) return -1;
133 }
134 else if (buf[i] == '\n') {
135 if (uwsgi_buffer_append(ub, "\\n", 2)) return -1;
136 }
137 else if (buf[i] == '\r') {
138 if (uwsgi_buffer_append(ub, "\\r", 2)) return -1;
139 }
140 else if (buf[i] == '"') {
141 if (uwsgi_buffer_append(ub, "\\\"", 2)) return -1;
142 }
143 else if (buf[i] == '\\') {
144 if (uwsgi_buffer_append(ub, "\\\\", 2)) return -1;
145 }
146 else {
147 if (uwsgi_buffer_append(ub, buf+i, 1)) return -1;
148 }
149 }
150 return 0;
151 }
152
uwsgi_buffer_u16le(struct uwsgi_buffer * ub,uint16_t num)153 int uwsgi_buffer_u16le(struct uwsgi_buffer *ub, uint16_t num) {
154 uint8_t buf[2];
155 buf[0] = (uint8_t) (num & 0xff);
156 buf[1] = (uint8_t) ((num >> 8) & 0xff);
157 return uwsgi_buffer_append(ub, (char *) buf, 2);
158 }
159
uwsgi_buffer_u16be(struct uwsgi_buffer * ub,uint16_t num)160 int uwsgi_buffer_u16be(struct uwsgi_buffer *ub, uint16_t num) {
161 uint8_t buf[2];
162 buf[1] = (uint8_t) (num & 0xff);
163 buf[0] = (uint8_t) ((num >> 8) & 0xff);
164 return uwsgi_buffer_append(ub, (char *) buf, 2);
165 }
166
uwsgi_buffer_u24be(struct uwsgi_buffer * ub,uint32_t num)167 int uwsgi_buffer_u24be(struct uwsgi_buffer *ub, uint32_t num) {
168 uint8_t buf[3];
169 buf[2] = (uint8_t) (num & 0xff);
170 buf[1] = (uint8_t) ((num >> 8) & 0xff);
171 buf[0] = (uint8_t) ((num >> 16) & 0xff);
172 return uwsgi_buffer_append(ub, (char *) buf, 3);
173 }
174
uwsgi_buffer_u32be(struct uwsgi_buffer * ub,uint32_t num)175 int uwsgi_buffer_u32be(struct uwsgi_buffer *ub, uint32_t num) {
176 uint8_t buf[4];
177 buf[3] = (uint8_t) (num & 0xff);
178 buf[2] = (uint8_t) ((num >> 8) & 0xff);
179 buf[1] = (uint8_t) ((num >> 16) & 0xff);
180 buf[0] = (uint8_t) ((num >> 24) & 0xff);
181 return uwsgi_buffer_append(ub, (char *) buf, 4);
182 }
183
uwsgi_buffer_f32be(struct uwsgi_buffer * ub,float num)184 int uwsgi_buffer_f32be(struct uwsgi_buffer *ub, float num) {
185 uint8_t buf[4];
186 uint32_t *pnum = (uint32_t *) #
187 buf[3] = (uint8_t) (*pnum & 0xff);
188 buf[2] = (uint8_t) ((*pnum >> 8) & 0xff);
189 buf[1] = (uint8_t) ((*pnum >> 16) & 0xff);
190 buf[0] = (uint8_t) ((*pnum >> 24) & 0xff);
191 return uwsgi_buffer_append(ub, (char *) buf, 4);
192 }
193
uwsgi_buffer_u32le(struct uwsgi_buffer * ub,uint32_t num)194 int uwsgi_buffer_u32le(struct uwsgi_buffer *ub, uint32_t num) {
195 uint8_t buf[4];
196 buf[0] = (uint8_t) (num & 0xff);
197 buf[1] = (uint8_t) ((num >> 8) & 0xff);
198 buf[2] = (uint8_t) ((num >> 16) & 0xff);
199 buf[3] = (uint8_t) ((num >> 24) & 0xff);
200 return uwsgi_buffer_append(ub, (char *) buf, 4);
201 }
202
uwsgi_buffer_u64be(struct uwsgi_buffer * ub,uint64_t num)203 int uwsgi_buffer_u64be(struct uwsgi_buffer *ub, uint64_t num) {
204 uint8_t buf[8];
205 buf[7] = (uint8_t) (num & 0xff);
206 buf[6] = (uint8_t) ((num >> 8) & 0xff);
207 buf[5] = (uint8_t) ((num >> 16) & 0xff);
208 buf[4] = (uint8_t) ((num >> 24) & 0xff);
209 buf[3] = (uint8_t) ((num >> 32) & 0xff);
210 buf[2] = (uint8_t) ((num >> 40) & 0xff);
211 buf[1] = (uint8_t) ((num >> 48) & 0xff);
212 buf[0] = (uint8_t) ((num >> 56) & 0xff);
213 return uwsgi_buffer_append(ub, (char *) buf, 8);
214 }
215
uwsgi_buffer_u64le(struct uwsgi_buffer * ub,uint64_t num)216 int uwsgi_buffer_u64le(struct uwsgi_buffer *ub, uint64_t num) {
217 uint8_t buf[8];
218 buf[0] = (uint8_t) (num & 0xff);
219 buf[1] = (uint8_t) ((num >> 8) & 0xff);
220 buf[2] = (uint8_t) ((num >> 16) & 0xff);
221 buf[3] = (uint8_t) ((num >> 24) & 0xff);
222 buf[4] = (uint8_t) ((num >> 32) & 0xff);
223 buf[5] = (uint8_t) ((num >> 40) & 0xff);
224 buf[6] = (uint8_t) ((num >> 48) & 0xff);
225 buf[7] = (uint8_t) ((num >> 56) & 0xff);
226 return uwsgi_buffer_append(ub, (char *) buf, 8);
227 }
228
229
uwsgi_buffer_f64be(struct uwsgi_buffer * ub,double num)230 int uwsgi_buffer_f64be(struct uwsgi_buffer *ub, double num) {
231 uint8_t buf[8];
232 uint64_t *pnum = (uint64_t *) #
233 buf[7] = (uint8_t) (*pnum & 0xff);
234 buf[6] = (uint8_t) ((*pnum >> 8) & 0xff);
235 buf[5] = (uint8_t) ((*pnum >> 16) & 0xff);
236 buf[4] = (uint8_t) ((*pnum >> 24) & 0xff);
237 buf[3] = (uint8_t) ((*pnum >> 32) & 0xff);
238 buf[2] = (uint8_t) ((*pnum >> 40) & 0xff);
239 buf[1] = (uint8_t) ((*pnum >> 48) & 0xff);
240 buf[0] = (uint8_t) ((*pnum >> 56) & 0xff);
241 return uwsgi_buffer_append(ub, (char *) buf, 8);
242 }
243
uwsgi_buffer_append_ipv4(struct uwsgi_buffer * ub,void * addr)244 int uwsgi_buffer_append_ipv4(struct uwsgi_buffer *ub, void *addr) {
245 char ip[INET_ADDRSTRLEN];
246 if (!inet_ntop(AF_INET, addr, ip, INET_ADDRSTRLEN)) {
247 uwsgi_error("uwsgi_buffer_append_ipv4() -> inet_ntop()");
248 return -1;
249 }
250 return uwsgi_buffer_append(ub, ip, strlen(ip));
251 }
252
253
uwsgi_buffer_num64(struct uwsgi_buffer * ub,int64_t num)254 int uwsgi_buffer_num64(struct uwsgi_buffer *ub, int64_t num) {
255 char buf[sizeof(UMAX64_STR)+1];
256 int ret = snprintf(buf, sizeof(UMAX64_STR)+1, "%lld", (long long) num);
257 if (ret <= 0 || ret >= (int) (sizeof(UMAX64_STR)+1)) {
258 return -1;
259 }
260 return uwsgi_buffer_append(ub, buf, ret);
261 }
262
uwsgi_buffer_append_keyval(struct uwsgi_buffer * ub,char * key,uint16_t keylen,char * val,uint16_t vallen)263 int uwsgi_buffer_append_keyval(struct uwsgi_buffer *ub, char *key, uint16_t keylen, char *val, uint16_t vallen) {
264 if (uwsgi_buffer_u16le(ub, keylen)) return -1;
265 if (uwsgi_buffer_append(ub, key, keylen)) return -1;
266 if (uwsgi_buffer_u16le(ub, vallen)) return -1;
267 return uwsgi_buffer_append(ub, val, vallen);
268 }
269
uwsgi_buffer_append_keyval32(struct uwsgi_buffer * ub,char * key,uint32_t keylen,char * val,uint32_t vallen)270 int uwsgi_buffer_append_keyval32(struct uwsgi_buffer *ub, char *key, uint32_t keylen, char *val, uint32_t vallen) {
271 if (uwsgi_buffer_u32be(ub, keylen)) return -1;
272 if (uwsgi_buffer_append(ub, key, keylen)) return -1;
273 if (uwsgi_buffer_u32be(ub, vallen)) return -1;
274 return uwsgi_buffer_append(ub, val, vallen);
275 }
276
uwsgi_buffer_append_keynum(struct uwsgi_buffer * ub,char * key,uint16_t keylen,int64_t num)277 int uwsgi_buffer_append_keynum(struct uwsgi_buffer *ub, char *key, uint16_t keylen, int64_t num) {
278 char buf[sizeof(UMAX64_STR)+1];
279 int ret = snprintf(buf, (sizeof(UMAX64_STR)+1), "%lld", (long long) num);
280 if (ret <= 0 || ret >= (int) (sizeof(UMAX64_STR)+1)) {
281 return -1;
282 }
283 if (uwsgi_buffer_u16le(ub, keylen)) return -1;
284 if (uwsgi_buffer_append(ub, key, keylen)) return -1;
285 if (uwsgi_buffer_u16le(ub, ret)) return -1;
286 return uwsgi_buffer_append(ub, buf, ret);
287 }
288
uwsgi_buffer_append_valnum(struct uwsgi_buffer * ub,int64_t num)289 int uwsgi_buffer_append_valnum(struct uwsgi_buffer *ub, int64_t num) {
290 char buf[sizeof(UMAX64_STR)+1];
291 int ret = snprintf(buf, (sizeof(UMAX64_STR)+1), "%lld", (long long) num);
292 if (ret <= 0 || ret >= (int) (sizeof(UMAX64_STR)+1)) {
293 return -1;
294 }
295 if (uwsgi_buffer_u16le(ub, ret)) return -1;
296 return uwsgi_buffer_append(ub, buf, ret);
297 }
298
299
uwsgi_buffer_append_keyipv4(struct uwsgi_buffer * ub,char * key,uint16_t keylen,void * addr)300 int uwsgi_buffer_append_keyipv4(struct uwsgi_buffer *ub, char *key, uint16_t keylen, void *addr) {
301 if (uwsgi_buffer_u16le(ub, keylen)) return -1;
302 if (uwsgi_buffer_append(ub, key, keylen)) return -1;
303 if (uwsgi_buffer_u16le(ub, 15)) return -1;
304 char *ptr = ub->buf + (ub->pos - 2);
305 if (uwsgi_buffer_append_ipv4(ub, addr)) return -1;
306 // fix the size
307 *ptr = ((ub->buf+ub->pos) - (ptr+2));
308 return 0;
309 }
310
uwsgi_buffer_append_base64(struct uwsgi_buffer * ub,char * s,size_t len)311 int uwsgi_buffer_append_base64(struct uwsgi_buffer *ub, char *s, size_t len) {
312 size_t b64_len = 0;
313 char *b64 = uwsgi_base64_encode(s, len, &b64_len);
314 if (!b64) return -1;
315 int ret = uwsgi_buffer_append(ub, b64, b64_len);
316 free(b64);
317 return ret;
318 }
319
320
uwsgi_buffer_destroy(struct uwsgi_buffer * ub)321 void uwsgi_buffer_destroy(struct uwsgi_buffer *ub) {
322 #ifdef UWSGI_DEBUG_BUFFER
323 uwsgi_log("[uwsgi-buffer] destroying buffer of %llu bytes\n", (unsigned long long) ub->len);
324 if (ub->freed) {
325 uwsgi_log("[uwsgi-buffer][BUG] buffer at %p already destroyed !!!\n", ub);
326 }
327 ub->freed = 1;
328 #endif
329 if (ub->buf)
330 free(ub->buf);
331 free(ub);
332 }
333
uwsgi_buffer_write_simple(struct wsgi_request * wsgi_req,struct uwsgi_buffer * ub)334 ssize_t uwsgi_buffer_write_simple(struct wsgi_request *wsgi_req, struct uwsgi_buffer *ub) {
335 size_t remains = ub->pos;
336 while(remains) {
337 ssize_t len = write(wsgi_req->fd, ub->buf + (ub->pos - remains), remains);
338 if (len <= 0) {
339 return len;
340 }
341 remains -= len;
342 }
343
344 return ub->pos;
345 }
346
uwsgi_buffer_send(struct uwsgi_buffer * ub,int fd)347 int uwsgi_buffer_send(struct uwsgi_buffer *ub, int fd) {
348 size_t remains = ub->pos;
349 char *ptr = ub->buf;
350
351 while (remains > 0) {
352 int ret = uwsgi_waitfd_write(fd, uwsgi.socket_timeout);
353 if (ret > 0) {
354 ssize_t len = write(fd, ptr, remains);
355 if (len > 0) {
356 ptr += len;
357 remains -= len;
358 }
359 else if (len == 0) {
360 return -1;
361 }
362 else {
363 uwsgi_error("uwsgi_buffer_send()");
364 return -1;
365 }
366 }
367 else if (ret == 0) {
368 uwsgi_log("timeout while sending buffer !!!\n");
369 return -1;
370 }
371 else {
372 return -1;
373 }
374 }
375
376 return 0;
377 }
378
uwsgi_buffer_set_uh(struct uwsgi_buffer * ub,uint8_t modifier1,uint8_t modifier2)379 int uwsgi_buffer_set_uh(struct uwsgi_buffer *ub, uint8_t modifier1, uint8_t modifier2) {
380 if (ub->pos < 4) return -1;
381 ub->buf[0] = modifier1;
382 ub->buf[1] = (uint8_t) ((ub->pos - 4) & 0xff);
383 ub->buf[2] = (uint8_t) (((ub->pos - 4) >> 8) & 0xff);
384 ub->buf[3] = modifier2;
385 return 0;
386 }
387
uwsgi_buffer_from_file(char * filename)388 struct uwsgi_buffer *uwsgi_buffer_from_file(char *filename) {
389 struct stat st;
390 int fd = open(filename, O_RDONLY);
391 if (fd < 0) {
392 return NULL;
393 }
394
395 if (fstat(fd, &st)) {
396 close(fd);
397 return NULL;
398 }
399
400 struct uwsgi_buffer *ub = uwsgi_buffer_new(st.st_size);
401
402 ssize_t len = read(fd, ub->buf, st.st_size);
403 close(fd);
404 if (len != st.st_size) {
405 uwsgi_buffer_destroy(ub);
406 return NULL;
407 }
408
409 ub->pos = len;
410 return ub;
411 }
412
uwsgi_buffer_map(struct uwsgi_buffer * ub,char * buf,size_t len)413 void uwsgi_buffer_map(struct uwsgi_buffer *ub, char *buf, size_t len) {
414 if (ub->buf) {
415 free(ub->buf);
416 }
417 ub->buf = buf;
418 ub->pos = len;
419 ub->len = len;
420 }
421