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

(-)modules/proxy/mod_proxy_fcgi.c (-10 / +47 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, in the general case FCGI_ABORT
587
         * should be sent to the FCGI backend, that it turns should inform the
588
         * running application and finally respond with the appropriate
589
         * END_REQUEST containing the final status of the (interrupted)
590
         * FCGI response. As the specs dictates, this should be a response from
591
         * the application, not a low-level acknowledgement from
592
         * the FastCGI library.
593
         * When a Web server is not multiplexing requests over a transport
594
         * connection (this module does not support it), it can abort a request
595
         * by simply closing the request's transport connection.
596
         * As of today (January 2017) there seems to be no FCGI backend
597
         * implementation that really honors/cares about FCGI_ABORT in the way
598
         * described by the specs, so it has not been implemented.
599
         */
600
        if (pfd[1].rtnevents & APR_POLLIN) {
601
            rv = ap_get_brigade(r->connection->input_filters, cib,
602
                                AP_MODE_SPECULATIVE, APR_NONBLOCK_READ, 8);
603
            if(rv == APR_EOF) {
604
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
605
                              "EOF detected from the main client connection.");
606
                r->connection->aborted = 1;
607
                break;
608
            }
609
        }
610
611
        if (pfd[0].rtnevents & APR_POLLIN) {
576
            apr_size_t readbuflen;
612
            apr_size_t readbuflen;
577
            apr_uint16_t clen, rid;
613
            apr_uint16_t clen, rid;
578
            apr_bucket *b;
614
            apr_bucket *b;
Lines 802-807 Link Here
802
    apr_brigade_destroy(ib);
838
    apr_brigade_destroy(ib);
803
    apr_brigade_destroy(ob);
839
    apr_brigade_destroy(ob);
840
    apr_brigade_destroy(cib);
804
    if (script_error_status != HTTP_OK) {
841
    if (script_error_status != HTTP_OK) {
805
        ap_die(script_error_status, r); /* send ErrorDocument */
842
        ap_die(script_error_status, r); /* send ErrorDocument */

Return to bug 56188