Lines 444-450
Link Here
|
444 |
apr_uint16_t request_id, const char **err, |
444 |
apr_uint16_t request_id, const char **err, |
445 |
int *bad_request, int *has_responded) |
445 |
int *bad_request, int *has_responded) |
446 |
{ |
446 |
{ |
447 |
apr_bucket_brigade *ib, *ob; |
447 |
apr_bucket_brigade *ib, *ob, *cib; |
448 |
int seen_end_of_headers = 0, done = 0, ignore_body = 0; |
448 |
int seen_end_of_headers = 0, done = 0, ignore_body = 0; |
449 |
apr_status_t rv = APR_SUCCESS; |
449 |
apr_status_t rv = APR_SUCCESS; |
450 |
int script_error_status = HTTP_OK; |
450 |
int script_error_status = HTTP_OK; |
Lines 452-458
Link Here
|
452 |
struct iovec vec[2]; |
452 |
struct iovec vec[2]; |
453 |
ap_fcgi_header header; |
453 |
ap_fcgi_header header; |
454 |
unsigned char farray[AP_FCGI_HEADER_LEN]; |
454 |
unsigned char farray[AP_FCGI_HEADER_LEN]; |
455 |
apr_pollfd_t pfd; |
455 |
apr_pollfd_t pfd[2]; |
456 |
int header_state = HDR_STATE_READING_HEADERS; |
456 |
int header_state = HDR_STATE_READING_HEADERS; |
457 |
char stack_iobuf[AP_IOBUFSIZE]; |
457 |
char stack_iobuf[AP_IOBUFSIZE]; |
458 |
apr_size_t iobuf_size = AP_IOBUFSIZE; |
458 |
apr_size_t iobuf_size = AP_IOBUFSIZE; |
Lines 464-476
Link Here
|
464 |
iobuf = apr_palloc(r->pool, iobuf_size); |
464 |
iobuf = apr_palloc(r->pool, iobuf_size); |
465 |
} |
465 |
} |
466 |
pfd.desc_type = APR_POLL_SOCKET; |
466 |
pfd[0].desc_type = APR_POLL_SOCKET; |
467 |
pfd.desc.s = conn->sock; |
467 |
pfd[0].desc.s = conn->sock; |
468 |
pfd.p = r->pool; |
468 |
pfd[0].p = r->pool; |
469 |
pfd.reqevents = APR_POLLIN | APR_POLLOUT; |
469 |
pfd[0].reqevents = APR_POLLIN | APR_POLLOUT; |
|
|
470 |
/* Specific pollfd to detect client connection aborts */ |
471 |
pfd[1].desc_type = APR_POLL_SOCKET; |
472 |
pfd[1].desc.s = (apr_socket_t*) ap_get_module_config(r->connection->conn_config, |
473 |
&core_module); |
474 |
pfd[1].p = r->connection->pool; |
475 |
pfd[1].reqevents = APR_POLLIN; |
476 |
|
470 |
ib = apr_brigade_create(r->pool, c->bucket_alloc); |
477 |
ib = apr_brigade_create(r->pool, c->bucket_alloc); |
471 |
ob = apr_brigade_create(r->pool, c->bucket_alloc); |
478 |
ob = apr_brigade_create(r->pool, c->bucket_alloc); |
|
|
479 |
cib = apr_brigade_create(r->connection->pool, c->bucket_alloc); |
472 |
while (! done) { |
480 |
while (! done) { |
473 |
apr_interval_time_t timeout; |
481 |
apr_interval_time_t timeout; |
Lines 481-487
Link Here
|
481 |
* cause timeout errors. */ |
489 |
* cause timeout errors. */ |
482 |
apr_socket_timeout_get(conn->sock, &timeout); |
490 |
apr_socket_timeout_get(conn->sock, &timeout); |
483 |
rv = apr_poll(&pfd, 1, &n, timeout); |
491 |
rv = apr_poll(pfd, 2, &n, timeout); |
484 |
if (rv != APR_SUCCESS) { |
492 |
if (rv != APR_SUCCESS) { |
485 |
if (APR_STATUS_IS_EINTR(rv)) { |
493 |
if (APR_STATUS_IS_EINTR(rv)) { |
486 |
continue; |
494 |
continue; |
Lines 490-496
Link Here
|
490 |
break; |
498 |
break; |
491 |
} |
499 |
} |
492 |
if (pfd.rtnevents & APR_POLLOUT) { |
500 |
if (pfd[0].rtnevents & APR_POLLOUT) { |
493 |
apr_size_t to_send, writebuflen; |
501 |
apr_size_t to_send, writebuflen; |
494 |
int last_stdin = 0; |
502 |
int last_stdin = 0; |
495 |
char *iobuf_cursor; |
503 |
char *iobuf_cursor; |
Lines 555-561
Link Here
|
555 |
} |
563 |
} |
556 |
if (last_stdin) { |
564 |
if (last_stdin) { |
557 |
pfd.reqevents = APR_POLLIN; /* Done with input data */ |
565 |
pfd[0].reqevents = APR_POLLIN; /* Done with input data */ |
558 |
/* signal EOF (empty FCGI_STDIN) */ |
566 |
/* signal EOF (empty FCGI_STDIN) */ |
559 |
ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id, |
567 |
ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id, |
Lines 573-579
Link Here
|
573 |
} |
581 |
} |
574 |
} |
582 |
} |
575 |
if (pfd.rtnevents & APR_POLLIN) { |
583 |
/* |
|
|
584 |
* If a client connection abort is detected, |
585 |
* a FCGI abort request (AP_FCGI_ABORT_REQUEST) |
586 |
* is issued. This helps aborting FCGI scripts taking |
587 |
* a long time to complete when the client does not |
588 |
* need their response anymore. |
589 |
*/ |
590 |
if (pfd[1].rtnevents & APR_POLLIN) { |
591 |
rv = ap_get_brigade(r->connection->input_filters, cib, |
592 |
AP_MODE_SPECULATIVE, APR_NONBLOCK_READ, 8); |
593 |
if(rv != APR_SUCCESS && rv != APR_EAGAIN) { |
594 |
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, |
595 |
"Error reading from the input filters chain, " |
596 |
"sending FCGI_ABORT_REQUEST"); |
597 |
ap_fcgi_fill_in_header(&header, AP_FCGI_ABORT_REQUEST, |
598 |
request_id, 0, 0); |
599 |
ap_fcgi_header_to_array(&header, farray); |
600 |
vec[0].iov_base = (void *)farray; |
601 |
vec[0].iov_len = sizeof(farray); |
602 |
apr_status_t rv_abort = send_data(conn, vec, 1, &len); |
603 |
if (rv_abort != APR_SUCCESS) { |
604 |
*err = "sending FCGI_ABORT_REQUEST"; |
605 |
rv = rv_abort; |
606 |
} |
607 |
apr_brigade_destroy(cib); |
608 |
break; |
609 |
} |
610 |
} |
611 |
|
612 |
if (pfd[0].rtnevents & APR_POLLIN) { |
576 |
apr_size_t readbuflen; |
613 |
apr_size_t readbuflen; |
577 |
apr_uint16_t clen, rid; |
614 |
apr_uint16_t clen, rid; |
578 |
apr_bucket *b; |
615 |
apr_bucket *b; |
Lines 777-782
Link Here
|
777 |
case AP_FCGI_END_REQUEST: |
814 |
case AP_FCGI_END_REQUEST: |
778 |
done = 1; |
815 |
done = 1; |
|
|
816 |
apr_brigade_destroy(cib); |
779 |
break; |
817 |
break; |
780 |
default: |
818 |
default: |