Skip to content

Commit ebedf06

Browse files
author
Sascha Schumann
committed
Fix POST handling once and for all. The daemon now never blocks and handles
uploads of up to 2GB on 32 bit platforms. Uploads >16KB are put into a file-backed mmap area. SG(request_info).content_type got corrupted somewhere. As a workaround, we provide SAPI with a duplicate of the original string.
1 parent 973c5fa commit ebedf06

File tree

2 files changed

+166
-117
lines changed

2 files changed

+166
-117
lines changed

sapi/thttpd/thttpd.c

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242

4343
typedef struct {
4444
httpd_conn *hc;
45-
int read_post_data;
4645
void (*on_close)(int);
4746

4847
smart_str sbuf;
@@ -231,41 +230,6 @@ static int sapi_thttpd_read_post(char *buffer, uint count_bytes TSRMLS_DC)
231230
count_bytes -= read_bytes;
232231
}
233232

234-
count_bytes = MIN(count_bytes,
235-
SG(request_info).content_length - SG(read_post_bytes));
236-
237-
while (read_bytes < count_bytes) {
238-
tmp = recv(TG(hc)->conn_fd, buffer + read_bytes,
239-
count_bytes - read_bytes, 0);
240-
if (tmp == 0 || (tmp == -1 && errno != EAGAIN))
241-
break;
242-
/* A simple "tmp > 0" produced broken code on Solaris/GCC */
243-
if (tmp != 0 && tmp != -1)
244-
read_bytes += tmp;
245-
246-
if (tmp == -1 && errno == EAGAIN) {
247-
fd_set fdr;
248-
249-
FD_ZERO(&fdr);
250-
FD_SET(TG(hc)->conn_fd, &fdr);
251-
n = select(TG(hc)->conn_fd + 1, &fdr, NULL, NULL, NULL);
252-
if (n <= 0)
253-
php_handle_aborted_connection();
254-
255-
continue;
256-
}
257-
}
258-
259-
TG(read_post_data) += read_bytes;
260-
261-
/* Hack for user-agents which send a LR or CRLF after POST data */
262-
if (TG(read_post_data) >= TG(hc)->contentlength) {
263-
char tmpbuf[2];
264-
265-
/* we are in non-blocking mode */
266-
recv(TG(hc)->conn_fd, tmpbuf, 2, 0);
267-
}
268-
269233
return read_bytes;
270234
}
271235

@@ -471,7 +435,8 @@ static void thttpd_request_ctor(TSRMLS_D)
471435
SG(request_info).request_uri = s.c;
472436
SG(request_info).request_method = httpd_method_str(TG(hc)->method);
473437
SG(sapi_headers).http_response_code = 200;
474-
SG(request_info).content_type = TG(hc)->contenttype;
438+
if (TG(hc)->contenttype)
439+
SG(request_info).content_type = strdup(TG(hc)->contenttype);
475440
SG(request_info).content_length = TG(hc)->contentlength == -1 ? 0
476441
: TG(hc)->contentlength;
477442

@@ -485,6 +450,8 @@ static void thttpd_request_dtor(TSRMLS_D)
485450
free(SG(request_info).query_string);
486451
free(SG(request_info).request_uri);
487452
free(SG(request_info).path_translated);
453+
if (SG(request_info).content_type)
454+
free(SG(request_info).content_type);
488455
}
489456

490457
#ifdef ZTS
@@ -664,27 +631,20 @@ static void remove_dead_conn(int fd)
664631

665632
#endif
666633

667-
#define CT_LEN_MAX_RAM 8192
668-
669634
static off_t thttpd_real_php_request(httpd_conn *hc, int show_source TSRMLS_DC)
670635
{
671636
TG(hc) = hc;
672637
hc->bytes_sent = 0;
673638

674-
TG(read_post_data) = 0;
675639
if (hc->method == METHOD_POST)
676640
hc->should_linger = 1;
677641

678642
if (hc->contentlength > 0
679643
&& SIZEOF_UNCONSUMED_BYTES() < hc->contentlength) {
680644
int missing = hc->contentlength - SIZEOF_UNCONSUMED_BYTES();
681645

682-
if (hc->contentlength < CT_LEN_MAX_RAM) {
683-
hc->read_body_into_mem = 1;
684-
return 0;
685-
} else {
686-
return -1;
687-
}
646+
hc->read_body_into_mem = 1;
647+
return 0;
688648
}
689649

690650
thttpd_request_ctor(TSRMLS_C);

0 commit comments

Comments
 (0)