1 #include "uwsgi.h"
2 
3 extern struct uwsgi_server uwsgi;
4 
uwsgi_proto_raw_parser(struct wsgi_request * wsgi_req)5 int uwsgi_proto_raw_parser(struct wsgi_request *wsgi_req) {
6 	wsgi_req->is_raw = 1;
7 	wsgi_req->uh->modifier1 = uwsgi.raw_modifier1;
8 	wsgi_req->uh->modifier2 = uwsgi.raw_modifier2;
9 	return UWSGI_OK;
10 }
11 
proto_base_add_uwsgi_header(struct wsgi_request * wsgi_req,char * key,uint16_t keylen,char * val,uint16_t vallen)12 uint16_t proto_base_add_uwsgi_header(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, char *val, uint16_t vallen) {
13 
14 
15 	int i;
16 	char *buffer = wsgi_req->buffer + wsgi_req->uh->pktsize;
17 	char *watermark = wsgi_req->buffer + uwsgi.buffer_size;
18 	char *ptr = buffer;
19 
20 
21 	for (i = 0; i < keylen; i++) {
22 		if (key[i] == '-') {
23 			key[i] = '_';
24 		}
25 		else {
26 			key[i] = toupper((int)key[i]);
27 		}
28 	}
29 
30 	if (uwsgi_strncmp("CONTENT_TYPE", 12, key, keylen) && uwsgi_strncmp("CONTENT_LENGTH", 14, key, keylen)) {
31 		if (buffer + keylen + vallen + 2 + 2 + 5 >= watermark) {
32 			uwsgi_log("[WARNING] unable to add %.*s=%.*s to uwsgi packet, consider increasing buffer size\n", keylen, key, vallen, val);
33 			return 0;
34 		}
35 		*ptr++ = (uint8_t) ((keylen + 5) & 0xff);
36 		*ptr++ = (uint8_t) (((keylen + 5) >> 8) & 0xff);
37 		memcpy(ptr, "HTTP_", 5);
38 		ptr += 5;
39 		memcpy(ptr, key, keylen);
40 		ptr += keylen;
41 		keylen += 5;
42 	}
43 	else {
44 		if (buffer + keylen + vallen + 2 + 2 >= watermark) {
45 			uwsgi_log("[WARNING] unable to add %.*s=%.*s to uwsgi packet, consider increasing buffer size\n", keylen, key, vallen, val);
46 			return 0;
47 		}
48 		*ptr++ = (uint8_t) (keylen & 0xff);
49 		*ptr++ = (uint8_t) ((keylen >> 8) & 0xff);
50 		memcpy(ptr, key, keylen);
51 		ptr += keylen;
52 	}
53 
54 	*ptr++ = (uint8_t) (vallen & 0xff);
55 	*ptr++ = (uint8_t) ((vallen >> 8) & 0xff);
56 	memcpy(ptr, val, vallen);
57 
58 #ifdef UWSGI_DEBUG
59 	uwsgi_log("add uwsgi var: %.*s = %.*s\n", keylen, key, vallen, val);
60 #endif
61 
62 	return keylen + vallen + 2 + 2;
63 }
64 
65 
66 
proto_base_add_uwsgi_var(struct wsgi_request * wsgi_req,char * key,uint16_t keylen,char * val,uint16_t vallen)67 uint16_t proto_base_add_uwsgi_var(struct wsgi_request * wsgi_req, char *key, uint16_t keylen, char *val, uint16_t vallen) {
68 
69 
70 	char *buffer = wsgi_req->buffer + wsgi_req->uh->pktsize;
71 	char *watermark = wsgi_req->buffer + uwsgi.buffer_size;
72 	char *ptr = buffer;
73 
74 	if (buffer + keylen + vallen + 2 + 2 >= watermark) {
75 		uwsgi_log("[WARNING] unable to add %.*s=%.*s to uwsgi packet, consider increasing buffer size\n", keylen, key, vallen, val);
76 		return 0;
77 	}
78 
79 
80 	*ptr++ = (uint8_t) (keylen & 0xff);
81 	*ptr++ = (uint8_t) ((keylen >> 8) & 0xff);
82 	memcpy(ptr, key, keylen);
83 	ptr += keylen;
84 
85 	*ptr++ = (uint8_t) (vallen & 0xff);
86 	*ptr++ = (uint8_t) ((vallen >> 8) & 0xff);
87 	memcpy(ptr, val, vallen);
88 
89 #ifdef UWSGI_DEBUG
90 	uwsgi_log("add uwsgi var: %.*s = %.*s\n", keylen, key, vallen, val);
91 #endif
92 
93 	return keylen + vallen + 2 + 2;
94 }
95 
96 
uwsgi_proto_base_accept(struct wsgi_request * wsgi_req,int fd)97 int uwsgi_proto_base_accept(struct wsgi_request *wsgi_req, int fd) {
98 
99 	wsgi_req->c_len = sizeof(struct sockaddr_un);
100 #if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
101 	return accept4(fd, (struct sockaddr *) &wsgi_req->client_addr, (socklen_t *) & wsgi_req->c_len, SOCK_NONBLOCK);
102 #elif defined(__linux__)
103 	int client_fd = accept(fd, (struct sockaddr *) &wsgi_req->client_addr, (socklen_t *) & wsgi_req->c_len);
104 	if (client_fd >= 0) {
105 		uwsgi_socket_nb(client_fd);
106 	}
107 	return client_fd;
108 #else
109 	return accept(fd, (struct sockaddr *) &wsgi_req->client_addr, (socklen_t *) & wsgi_req->c_len);
110 #endif
111 }
112 
uwsgi_proto_base_close(struct wsgi_request * wsgi_req)113 void uwsgi_proto_base_close(struct wsgi_request *wsgi_req) {
114 	close(wsgi_req->fd);
115 }
116 
117 #ifdef UWSGI_SSL
uwsgi_proto_ssl_accept(struct wsgi_request * wsgi_req,int server_fd)118 int uwsgi_proto_ssl_accept(struct wsgi_request *wsgi_req, int server_fd) {
119 
120 	int fd = uwsgi_proto_base_accept(wsgi_req, server_fd);
121 	if (fd >= 0) {
122 		wsgi_req->ssl = SSL_new(wsgi_req->socket->ssl_ctx);
123         	SSL_set_fd(wsgi_req->ssl, fd);
124         	SSL_set_accept_state(wsgi_req->ssl);
125 	}
126 	return fd;
127 }
128 
uwsgi_proto_ssl_close(struct wsgi_request * wsgi_req)129 void uwsgi_proto_ssl_close(struct wsgi_request *wsgi_req) {
130 	uwsgi_proto_base_close(wsgi_req);
131 	// clear the errors (otherwise they could be propagated)
132         ERR_clear_error();
133         SSL_free(wsgi_req->ssl);
134 }
135 #endif
136 
uwsgi_proto_base_add_header(struct wsgi_request * wsgi_req,char * k,uint16_t kl,char * v,uint16_t vl)137 struct uwsgi_buffer *uwsgi_proto_base_add_header(struct wsgi_request *wsgi_req, char *k, uint16_t kl, char *v, uint16_t vl) {
138 	struct uwsgi_buffer *ub = NULL;
139 	if (kl > 0) {
140 		ub = uwsgi_buffer_new(kl + 2 + vl + 2);
141 		if (uwsgi_buffer_append(ub, k, kl)) goto end;
142 		if (uwsgi_buffer_append(ub, ": ", 2)) goto end;
143 		if (uwsgi_buffer_append(ub, v, vl)) goto end;
144 		if (uwsgi_buffer_append(ub, "\r\n", 2)) goto end;
145 	}
146 	else {
147 		ub = uwsgi_buffer_new(vl + 2);
148 		if (uwsgi_buffer_append(ub, v, vl)) goto end;
149                 if (uwsgi_buffer_append(ub, "\r\n", 2)) goto end;
150 	}
151 	return ub;
152 end:
153 	uwsgi_buffer_destroy(ub);
154 	return NULL;
155 }
156 
uwsgi_proto_base_prepare_headers(struct wsgi_request * wsgi_req,char * s,uint16_t sl)157 struct uwsgi_buffer *uwsgi_proto_base_prepare_headers(struct wsgi_request *wsgi_req, char *s, uint16_t sl) {
158         struct uwsgi_buffer *ub = NULL;
159 	if (uwsgi.cgi_mode == 0) {
160 		if (wsgi_req->protocol_len) {
161 			ub = uwsgi_buffer_new(wsgi_req->protocol_len + 1 + sl + 2);
162 			if (uwsgi_buffer_append(ub, wsgi_req->protocol, wsgi_req->protocol_len)) goto end;
163 			if (uwsgi_buffer_append(ub, " ", 1)) goto end;
164 		}
165 		else {
166 			ub = uwsgi_buffer_new(9 + sl + 2);
167 			if (uwsgi_buffer_append(ub, "HTTP/1.0 ", 9)) goto end;
168 		}
169 	}
170 	else {
171 		ub = uwsgi_buffer_new(8 + sl + 2);
172 		if (uwsgi_buffer_append(ub, "Status: ", 8)) goto end;
173 	}
174         if (uwsgi_buffer_append(ub, s, sl)) goto end;
175 	if (uwsgi_buffer_append(ub, "\r\n", 2)) goto end;
176         return ub;
177 end:
178         uwsgi_buffer_destroy(ub);
179         return NULL;
180 }
181 
uwsgi_proto_base_cgi_prepare_headers(struct wsgi_request * wsgi_req,char * s,uint16_t sl)182 struct uwsgi_buffer *uwsgi_proto_base_cgi_prepare_headers(struct wsgi_request *wsgi_req, char *s, uint16_t sl) {
183 	struct uwsgi_buffer *ub = uwsgi_buffer_new(8 + sl + 2);
184 	if (uwsgi_buffer_append(ub, "Status: ", 8)) goto end;
185         if (uwsgi_buffer_append(ub, s, sl)) goto end;
186 	if (uwsgi_buffer_append(ub, "\r\n", 2)) goto end;
187 	return ub;
188 end:
189 	uwsgi_buffer_destroy(ub);
190 	return NULL;
191 }
192 
193 
uwsgi_proto_base_write(struct wsgi_request * wsgi_req,char * buf,size_t len)194 int uwsgi_proto_base_write(struct wsgi_request * wsgi_req, char *buf, size_t len) {
195         ssize_t wlen = write(wsgi_req->fd, buf+wsgi_req->write_pos, len-wsgi_req->write_pos);
196         if (wlen > 0) {
197                 wsgi_req->write_pos += wlen;
198                 if (wsgi_req->write_pos == len) {
199                         return UWSGI_OK;
200                 }
201                 return UWSGI_AGAIN;
202         }
203         if (wlen < 0) {
204                 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
205                         return UWSGI_AGAIN;
206                 }
207         }
208         return -1;
209 }
210 
211 /*
212 	NOTE: len is a pointer as it could be changed on the fly
213 */
uwsgi_proto_base_writev(struct wsgi_request * wsgi_req,struct iovec * iov,size_t * len)214 int uwsgi_proto_base_writev(struct wsgi_request * wsgi_req, struct iovec *iov, size_t *len) {
215 	size_t i,needed = 0;
216 	// count the number of bytes to write
217 	for(i=0;i<*len;i++) needed += iov[i].iov_len;
218 	ssize_t wlen = writev(wsgi_req->fd, iov, *len);
219         if (wlen > 0) {
220 		wsgi_req->write_pos += wlen;
221                 if ((size_t)wlen == needed) {
222                         return UWSGI_OK;
223                 }
224 		// now the complex part, we need to rebuild iovec and len...
225 		size_t orig_len = *len;
226 		size_t new_len = orig_len;
227 		// first remove the consumed items
228 		size_t first_iov = 0;
229 		size_t skip_bytes = 0;
230 		for(i=0;i<orig_len;i++) {
231 			if (iov[i].iov_len <= (size_t)wlen) {
232 				wlen -= iov[i].iov_len;
233 				new_len--;
234 			}
235 			else {
236 				first_iov = i;
237 				skip_bytes = wlen;
238 				break;
239 			}
240 		}
241 		*len = new_len;
242 		// now moves remaining iovec's to top
243 		size_t pos = 0;
244 		for(i=first_iov;i<orig_len;i++) {
245 			if (pos == 0) {
246 				iov[i].iov_base += skip_bytes;
247 				iov[i].iov_len -= skip_bytes;
248 			}
249 			iov[pos].iov_base = iov[i].iov_base;
250 			iov[pos].iov_len = iov[i].iov_len;
251 			pos++;
252 		}
253                 return UWSGI_AGAIN;
254         }
255         if (wlen < 0) {
256                 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
257                         return UWSGI_AGAIN;
258                 }
259         }
260         return -1;
261 }
262 
263 
264 #ifdef UWSGI_SSL
uwsgi_proto_ssl_write(struct wsgi_request * wsgi_req,char * buf,size_t len)265 int uwsgi_proto_ssl_write(struct wsgi_request * wsgi_req, char *buf, size_t len) {
266 	int ret = -1;
267 retry:
268         ret = SSL_write(wsgi_req->ssl, buf, len);
269         if (ret > 0) {
270 		wsgi_req->write_pos += ret;
271 		if (wsgi_req->write_pos == len) {
272                         return UWSGI_OK;
273                 }
274                 return UWSGI_AGAIN;
275 	}
276 
277         int err = SSL_get_error(wsgi_req->ssl, ret);
278 
279         if (err == SSL_ERROR_WANT_WRITE) {
280                 ret = uwsgi_wait_write_req(wsgi_req);
281                 if (ret <= 0) return -1;
282                 goto retry;
283         }
284 
285         else if (err == SSL_ERROR_WANT_READ) {
286                 ret = uwsgi_wait_read_req(wsgi_req);
287                 if (ret <= 0) return -1;
288                 goto retry;
289         }
290 
291         else if (err == SSL_ERROR_SYSCALL) {
292 		if (errno != 0)
293                 	uwsgi_error("uwsgi_proto_ssl_write()/SSL_write()");
294         }
295 
296         return -1;
297 }
298 
299 #endif
uwsgi_proto_base_sendfile(struct wsgi_request * wsgi_req,int fd,size_t pos,size_t len)300 int uwsgi_proto_base_sendfile(struct wsgi_request * wsgi_req, int fd, size_t pos, size_t len) {
301         ssize_t wlen = uwsgi_sendfile_do(wsgi_req->fd, fd, pos+wsgi_req->write_pos, len-wsgi_req->write_pos);
302         if (wlen > 0) {
303                 wsgi_req->write_pos += wlen;
304                 if (wsgi_req->write_pos == len) {
305                         return UWSGI_OK;
306                 }
307                 return UWSGI_AGAIN;
308         }
309         if (wlen < 0) {
310                 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
311                         return UWSGI_AGAIN;
312                 }
313         }
314         return -1;
315 }
316 
317 #ifdef UWSGI_SSL
uwsgi_proto_ssl_sendfile(struct wsgi_request * wsgi_req,int fd,size_t pos,size_t len)318 int uwsgi_proto_ssl_sendfile(struct wsgi_request *wsgi_req, int fd, size_t pos, size_t len) {
319 	char buf[32768];
320 
321 	if (lseek(fd, pos+wsgi_req->write_pos, SEEK_SET) < 0) {
322 		uwsgi_error("lseek()");
323 		return -1;
324 	}
325 	ssize_t rlen = read(fd, buf, UMIN(len-wsgi_req->write_pos, 32768));
326 	if (rlen <= 0) return -1;
327 
328 	char *rbuf = buf;
329 
330 	while(rlen > 0) {
331 		size_t current_write_pos = wsgi_req->write_pos;
332 		int ret = uwsgi_proto_ssl_write(wsgi_req, rbuf, rlen);
333 		if (ret == UWSGI_OK) {
334 			break;
335                 }
336 		if (ret == UWSGI_AGAIN) {
337 			rbuf += (wsgi_req->write_pos - current_write_pos);
338 			rlen -= (wsgi_req->write_pos - current_write_pos);
339 			continue;
340 		}
341 		return -1;
342 	}
343 
344 	if (wsgi_req->write_pos == len) {
345 		return UWSGI_OK;
346 	}
347 	return UWSGI_AGAIN;
348 }
349 
350 #endif
351 
uwsgi_proto_base_fix_headers(struct wsgi_request * wsgi_req)352 int uwsgi_proto_base_fix_headers(struct wsgi_request * wsgi_req) {
353         return uwsgi_buffer_append(wsgi_req->headers, "\r\n", 2);
354 }
355 
uwsgi_proto_base_read_body(struct wsgi_request * wsgi_req,char * buf,size_t len)356 ssize_t uwsgi_proto_base_read_body(struct wsgi_request *wsgi_req, char *buf, size_t len) {
357 	if (wsgi_req->proto_parser_remains > 0) {
358 		size_t remains = UMIN(wsgi_req->proto_parser_remains, len);
359 		memcpy(buf, wsgi_req->proto_parser_remains_buf, remains);
360 		wsgi_req->proto_parser_remains -= remains;
361 		wsgi_req->proto_parser_remains_buf += remains;
362 		return remains;
363 	}
364 	return read(wsgi_req->fd, buf, len);
365 }
366 
367 #ifdef UWSGI_SSL
uwsgi_proto_ssl_read_body(struct wsgi_request * wsgi_req,char * buf,size_t len)368 ssize_t uwsgi_proto_ssl_read_body(struct wsgi_request *wsgi_req, char *buf, size_t len) {
369 	int ret = -1;
370         if (wsgi_req->proto_parser_remains > 0) {
371                 size_t remains = UMIN(wsgi_req->proto_parser_remains, len);
372                 memcpy(buf, wsgi_req->proto_parser_remains_buf, remains);
373                 wsgi_req->proto_parser_remains -= remains;
374                 wsgi_req->proto_parser_remains_buf += remains;
375                 return remains;
376         }
377 
378 retry:
379 	ret = SSL_read(wsgi_req->ssl, buf, len);
380         if (ret > 0) return ret;
381 
382         int err = SSL_get_error(wsgi_req->ssl, ret);
383 
384         if (err == SSL_ERROR_WANT_READ) {
385 		errno = EAGAIN;
386                 return -1;
387         }
388 
389         else if (err == SSL_ERROR_WANT_WRITE) {
390 		ret = uwsgi_wait_write_req(wsgi_req);
391                 if (ret <= 0) return -1;
392 		goto retry;
393         }
394 
395         else if (err == SSL_ERROR_SYSCALL) {
396 		if (errno != 0)
397                 	uwsgi_error("uwsgi_proto_ssl_read_body()/SSL_read()");
398         }
399 
400 	return -1;
401 }
402 #endif
403 
uwsgi_proto_noop_read_body(struct wsgi_request * wsgi_req,char * buf,size_t len)404 ssize_t uwsgi_proto_noop_read_body(struct wsgi_request *wsgi_req, char *buf, size_t len) {
405 	uwsgi_log_verbose("!!! the current protocol does not support request body !!!\n");
406 	return -1;
407 }
408 
uwsgi_proto_raw_setup(struct uwsgi_socket * uwsgi_sock)409 void uwsgi_proto_raw_setup(struct uwsgi_socket *uwsgi_sock) {
410 	uwsgi_sock->proto = uwsgi_proto_raw_parser;
411                         uwsgi_sock->proto_accept = uwsgi_proto_base_accept;
412                         uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers;
413                         uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
414                         uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
415                         uwsgi_sock->proto_read_body = uwsgi_proto_base_read_body;
416                         uwsgi_sock->proto_write = uwsgi_proto_base_write;
417                         uwsgi_sock->proto_write_headers = uwsgi_proto_base_write;
418                         uwsgi_sock->proto_sendfile = uwsgi_proto_base_sendfile;
419                         uwsgi_sock->proto_close = uwsgi_proto_base_close;
420                         if (uwsgi.offload_threads > 0)
421                                 uwsgi_sock->can_offload = 1;
422 }
423