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