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

(-)a/modules/proxy/mod_proxy_connect.c (-48 / +68 lines)
Lines 182-196 static void del_pollset(apr_pollset_t *pollset, Link Here
182
    apr_status_t rv;
182
    apr_status_t rv;
183
183
184
    rv = apr_pollset_remove(pollset, &conn->pfd);
184
    rv = apr_pollset_remove(pollset, &conn->pfd);
185
    ap_assert(rv == APR_SUCCESS);
186
185
187
    conn->pfd.reqevents &= ~events;
186
    conn->pfd.reqevents &= ~events;
188
    if (conn->pfd.reqevents) {
187
    if (conn->pfd.reqevents) {
189
        rv = apr_pollset_add(pollset, &conn->pfd);
188
        rv = apr_pollset_add(pollset, &conn->pfd);
190
        ap_assert(rv == APR_SUCCESS);
191
    }
189
    }
192
}
190
}
193
191
192
static int ap_proxy_connect_transfer( request_rec *r,
193
                                      struct proxy_connect_conn *conn,
194
                                      struct proxy_connect_conn *other,
195
                                      apr_pollset_t *pollset,
196
                                      apr_size_t read_buf_size )
197
{
198
    apr_status_t rv;
199
200
    rv = ap_proxy_transfer_between_connections(r, conn->c, other->c, conn->bb,
201
                                               other->bb, conn->name, NULL,
202
                                               read_buf_size,
203
                                               AP_PROXY_TRANSFER_CHECK_FULL);
204
    if (rv != APR_SUCCESS) {
205
        if (APR_STATUS_IS_INCOMPLETE(rv)) {
206
            /* Pause POLLIN while waiting for POLLOUT on the other
207
             * side, hence avoid filling the output filters even
208
             * more and hence blocking there.
209
             */
210
            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
211
                          "%s wait writable", other->name);
212
        }
213
        else if (APR_STATUS_IS_EOF(rv)) {
214
            /* Stop POLLIN and wait for POLLOUT (and flush) on the
215
             * other side to shut it down.
216
             */
217
            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
218
                          "%s read shutdown", conn->name);
219
            conn->shutdown |= PROXY_SHUTDOWN_READ;
220
        }
221
        else {
222
            /* Real failure, bail out */
223
            return 1;
224
        }
225
        del_pollset(pollset, conn, APR_POLLIN | APR_POLLHUP);
226
        if (!(other->shutdown & PROXY_SHUTDOWN_WRITE)) {
227
            add_pollset(pollset, other, APR_POLLOUT);
228
        }
229
    }
230
231
    return 0;
232
}
233
194
/* CONNECT handler */
234
/* CONNECT handler */
195
static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
235
static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
196
                                 proxy_server_conf *conf,
236
                                 proxy_server_conf *conf,
Lines 499-537 static int proxy_connect_handler(request_rec *r, proxy_worker *worker, Link Here
499
                ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, APLOGNO(01025)
539
                ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, APLOGNO(01025)
500
                              "%s is readable", conn->name);
540
                              "%s is readable", conn->name);
501
541
502
                rv = ap_proxy_transfer_between_connections(r,
542
                failed = ap_proxy_connect_transfer( r, conn, other, pollset,
503
                                               conn->c, other->c,
543
                                                    read_buf_size );
504
                                               conn->bb, other->bb,
544
                if (failed)
505
                                               conn->name,
545
                    break;
506
                                               NULL, read_buf_size,
507
                                               AP_PROXY_TRANSFER_CHECK_FULL);
508
                if (rv != APR_SUCCESS) {
509
                    if (APR_STATUS_IS_INCOMPLETE(rv)) {
510
                        /* Pause POLLIN while waiting for POLLOUT on the other
511
                         * side, hence avoid filling the output filters even
512
                         * more and hence blocking there.
513
                         */
514
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
515
                                      "%s wait writable", other->name);
516
                    }
517
                    else if (APR_STATUS_IS_EOF(rv)) {
518
                        /* Stop POLLIN and wait for POLLOUT (and flush) on the
519
                         * other side to shut it down.
520
                         */
521
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
522
                                      "%s read shutdown", conn->name);
523
                        conn->shutdown |= PROXY_SHUTDOWN_READ;
524
                    }
525
                    else {
526
                        /* Real failure, bail out */
527
                        failed = 1;
528
                        break;
529
                    }
530
                    del_pollset(pollset, conn, APR_POLLIN | APR_POLLHUP);
531
                    if (!(other->shutdown & PROXY_SHUTDOWN_WRITE)) {
532
                        add_pollset(pollset, other, APR_POLLOUT);
533
                    }
534
                }
535
            }
546
            }
536
547
537
            if (revents & APR_POLLOUT) {
548
            if (revents & APR_POLLOUT) {
Lines 547-566 static int proxy_connect_handler(request_rec *r, proxy_worker *worker, Link Here
547
                    break;
558
                    break;
548
                }
559
                }
549
                if (!conn->c->data_in_output_filters) {
560
                if (!conn->c->data_in_output_filters) {
550
                    /* Pending data now flushed, stop POLLOUT on this conn, and
561
                    /* Pending data now flushed, now check, if there's still
551
                     * restore POLLIN on the other one unless it's shut down
562
                     * data on the input filter chain. If so, try to drain that.
552
                     * for read already (in which case we just forward the
563
                     * Otherwise, stop POLLOUT on this conn, and restore POLLIN
553
                     * shutdown).
564
                     * on the other one unless it's shut down for read already
565
                     * (in which case we just forward the shutdown).
554
                     */
566
                     */
555
                    del_pollset(pollset, conn, APR_POLLOUT);
567
                    if (other->c->data_in_input_filters) {
556
                    if (!(other->shutdown & PROXY_SHUTDOWN_READ)) {
568
                        failed = ap_proxy_connect_transfer( r, other, conn,
557
                        add_pollset(pollset, other, APR_POLLIN | APR_POLLHUP);
569
                                                            pollset,
558
                    }
570
                                                            read_buf_size );
559
                    else {
571
                        if (failed)
560
                        ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
572
                            break;
561
                                      "%s write shutdown", conn->name);
573
                    } else {
562
                        apr_socket_shutdown(conn->pfd.desc.s, 1);
574
                        del_pollset(pollset, conn, APR_POLLOUT);
563
                        conn->shutdown |= PROXY_SHUTDOWN_WRITE;
575
                        if (!(other->shutdown & PROXY_SHUTDOWN_READ)) {
576
                            add_pollset(pollset, other, APR_POLLIN | APR_POLLHUP);
577
                        }
578
                        else {
579
                            ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r,
580
                                          "%s write shutdown", conn->name);
581
                            apr_socket_shutdown(conn->pfd.desc.s, 1);
582
                            conn->shutdown |= PROXY_SHUTDOWN_WRITE;
583
                        }
564
                    }
584
                    }
565
                }
585
                }
566
            }
586
            }
(-)a/server/core_filters.c (-2 / +13 lines)
Lines 103-108 apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, Link Here
103
                                  ap_input_mode_t mode, apr_read_type_e block,
103
                                  ap_input_mode_t mode, apr_read_type_e block,
104
                                  apr_off_t readbytes)
104
                                  apr_off_t readbytes)
105
{
105
{
106
    conn_rec *con = f->c;
106
    apr_status_t rv;
107
    apr_status_t rv;
107
    core_net_rec *net = f->ctx;
108
    core_net_rec *net = f->ctx;
108
    core_ctx_t *ctx = net->in_ctx;
109
    core_ctx_t *ctx = net->in_ctx;
Lines 134-139 apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, Link Here
134
            return rv;
135
            return rv;
135
    }
136
    }
136
    else if (APR_BRIGADE_EMPTY(ctx->b)) {
137
    else if (APR_BRIGADE_EMPTY(ctx->b)) {
138
        con->data_in_input_filters = 0;
137
        return APR_EOF;
139
        return APR_EOF;
138
    }
140
    }
139
141
Lines 147-152 apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, Link Here
147
     * some higher-up APIs (spec. read_request_line via ap_rgetline)
149
     * some higher-up APIs (spec. read_request_line via ap_rgetline)
148
     * want an error code. */
150
     * want an error code. */
149
    if (APR_BRIGADE_EMPTY(ctx->b)) {
151
    if (APR_BRIGADE_EMPTY(ctx->b)) {
152
        con->data_in_input_filters = 0;
150
        return APR_EOF;
153
        return APR_EOF;
151
    }
154
    }
152
155
Lines 158-163 apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, Link Here
158
         * or may not be bogus, but is consistent (for now) with EOF logic.
161
         * or may not be bogus, but is consistent (for now) with EOF logic.
159
         */
162
         */
160
        if (APR_STATUS_IS_EAGAIN(rv) && block == APR_NONBLOCK_READ) {
163
        if (APR_STATUS_IS_EAGAIN(rv) && block == APR_NONBLOCK_READ) {
164
            con->data_in_input_filters = 0;
161
            rv = APR_SUCCESS;
165
            rv = APR_SUCCESS;
162
        }
166
        }
163
        return rv;
167
        return rv;
Lines 180-187 apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, Link Here
180
         * mean that there is another request, just a blank line.
184
         * mean that there is another request, just a blank line.
181
         */
185
         */
182
        while (1) {
186
        while (1) {
183
            if (APR_BRIGADE_EMPTY(ctx->b))
187
            if (APR_BRIGADE_EMPTY(ctx->b)) {
188
                con->data_in_input_filters = 0;
184
                return APR_EOF;
189
                return APR_EOF;
190
            }
185
191
186
            e = APR_BRIGADE_FIRST(ctx->b);
192
            e = APR_BRIGADE_FIRST(ctx->b);
187
193
Lines 223-228 apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, Link Here
223
229
224
        /* Tack on any buckets that were set aside. */
230
        /* Tack on any buckets that were set aside. */
225
        APR_BRIGADE_CONCAT(b, ctx->b);
231
        APR_BRIGADE_CONCAT(b, ctx->b);
232
        con->data_in_input_filters = 0;
226
233
227
        /* Since we've just added all potential buckets (which will most
234
        /* Since we've just added all potential buckets (which will most
228
         * likely simply be the socket bucket) we know this is the end,
235
         * likely simply be the socket bucket) we know this is the end,
Lines 333-338 apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, Link Here
333
340
334
        /* Take what was originally there and place it back on ctx->b */
341
        /* Take what was originally there and place it back on ctx->b */
335
        APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb);
342
        APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb);
343
344
        if ( APR_BRIGADE_EMPTY(ctx->b) )
345
            con->data_in_input_filters = 0;
346
        else
347
            con->data_in_input_filters = 1;
336
    }
348
    }
337
    return APR_SUCCESS;
349
    return APR_SUCCESS;
338
}
350
}
339
- 

Return to bug 61616