View | Details | Raw Unified | Return to bug 56188
Collapse All | Expand All

(-)modules/proxy/mod_proxy_fcgi.c (-10 / +38 lines)
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
         * Client connection aborted before any attempt to flush
585
         * data out has been made. This can happen for long running FCGI
586
         * tasks. According to the FCGI specs, an FCGI_ABORT should be sent
587
         * and the FCGI backend should respond with an END_REQUEST, but as of
588
         * today (December 2016) there seems to be no FCGI backend implementation
589
         * that really honor/care about this functionality.
590
         */
591
        if (pfd[1].rtnevents & APR_POLLIN) {
592
            rv = ap_get_brigade(r->connection->input_filters, cib,
593
                                AP_MODE_SPECULATIVE, APR_NONBLOCK_READ, 8);
594
            if(rv == APR_EOF) {
595
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
596
                              "EOF detected from the main client connection.");
597
                r->connection->aborted = 1;
598
                break;
599
            }
600
        }
601
602
        if (pfd[0].rtnevents & APR_POLLIN) {
576
            apr_size_t readbuflen;
603
            apr_size_t readbuflen;
577
            apr_uint16_t clen, rid;
604
            apr_uint16_t clen, rid;
578
            apr_bucket *b;
605
            apr_bucket *b;
Lines 802-807 Link Here
802
    apr_brigade_destroy(ib);
829
    apr_brigade_destroy(ib);
803
    apr_brigade_destroy(ob);
830
    apr_brigade_destroy(ob);
831
    apr_brigade_destroy(cib);
804
    if (script_error_status != HTTP_OK) {
832
    if (script_error_status != HTTP_OK) {
805
        ap_die(script_error_status, r); /* send ErrorDocument */
833
        ap_die(script_error_status, r); /* send ErrorDocument */

Return to bug 56188