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 *) &num;
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 *) &num;
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