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

(-)modules/proxy/mod_proxy.h (-2 / +10 lines)
Lines 1172-1177 PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifet Link Here
1172
                                                      apr_bucket_brigade *from,
1172
                                                      apr_bucket_brigade *from,
1173
                                                      apr_bucket_brigade *to);
1173
                                                      apr_bucket_brigade *to);
1174
1174
1175
/* The flags for ap_proxy_transfer_between_connections(). */
1176
#define AP_PROXY_TRANSFER_FLUSH_EACH  (0)
1177
#define AP_PROXY_TRANSFER_FLUSH_AFTER (1 << 0)
1178
#define AP_PROXY_TRANSFER_FLUSH_NEVER (1 << 1)
1179
#define AP_PROXY_TRANSFER_FLUSH_MASK  (AP_PROXY_TRANSFER_FLUSH_AFTER | \
1180
                                       AP_PROXY_TRANSFER_FLUSH_NEVER)
1181
#define AP_PROXY_TRANSFER_UNBUFFERED  (1 << 2)
1182
1175
/*
1183
/*
1176
 * Sends all data that can be read non blocking from the input filter chain of
1184
 * Sends all data that can be read non blocking from the input filter chain of
1177
 * c_i and send it down the output filter chain of c_o. For reading it uses
1185
 * c_i and send it down the output filter chain of c_o. For reading it uses
Lines 1189-1195 PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifet Link Here
1189
 * @param name  string for logging from where data was pulled
1197
 * @param name  string for logging from where data was pulled
1190
 * @param sent  if not NULL will be set to 1 if data was sent through c_o
1198
 * @param sent  if not NULL will be set to 1 if data was sent through c_o
1191
 * @param bsize maximum amount of data pulled in one iteration from c_i
1199
 * @param bsize maximum amount of data pulled in one iteration from c_i
1192
 * @param after if set flush data on c_o only once after the loop
1200
 * @param flags AP_PROXY_TRANSFER_* bitmask
1193
 * @return      apr_status_t of the operation. Could be any error returned from
1201
 * @return      apr_status_t of the operation. Could be any error returned from
1194
 *              either the input filter chain of c_i or the output filter chain
1202
 *              either the input filter chain of c_i or the output filter chain
1195
 *              of c_o. APR_EPIPE if the outgoing connection was aborted.
1203
 *              of c_o. APR_EPIPE if the outgoing connection was aborted.
Lines 1203-1209 PROXY_DECLARE(apr_status_t) ap_proxy_transfer_betw Link Here
1203
                                                       const char *name,
1211
                                                       const char *name,
1204
                                                       int *sent,
1212
                                                       int *sent,
1205
                                                       apr_off_t bsize,
1213
                                                       apr_off_t bsize,
1206
                                                       int after);
1214
                                                       int flags);
1207
1215
1208
extern module PROXY_DECLARE_DATA proxy_module;
1216
extern module PROXY_DECLARE_DATA proxy_module;
1209
1217
(-)modules/proxy/mod_proxy_connect.c (-103 / +215 lines)
Lines 143-148 static int proxy_connect_canon(request_rec *r, cha Link Here
143
    return OK;
143
    return OK;
144
}
144
}
145
145
146
struct proxy_connect_conn
147
{
148
    conn_rec *c;
149
    apr_pollfd_t pfd;
150
    apr_bucket_brigade *bb;
151
    ap_filter_t *core_filter;
152
    ap_out_filter_func core_output;
153
    apr_interval_time_t timeout;
154
    const char *name;
155
    int shutdown;
156
};
157
158
#define PROXY_SHUTDOWN_READ  0x1
159
#define PROXY_SHUTDOWN_WRITE 0x2
160
#define PROXY_SHUTDOWN_BOTH  0x3
161
162
static void pollset_add_conn(apr_pollset_t *pollset,
163
                             struct proxy_connect_conn *conn,
164
                             apr_int16_t events)
165
{
166
    if ((conn->pfd.reqevents & events) != events) {
167
        apr_pollset_remove(pollset, &conn->pfd);
168
169
        conn->pfd.reqevents |= events;
170
        apr_pollset_add(pollset, &conn->pfd);
171
    }
172
}
173
174
static void pollset_del_conn(apr_pollset_t *pollset,
175
                             struct proxy_connect_conn *conn,
176
                             apr_int16_t events)
177
{
178
    if (conn->pfd.reqevents & events) {
179
        apr_pollset_remove(pollset, &conn->pfd);
180
181
        conn->pfd.reqevents &= ~events;
182
        if (conn->pfd.reqevents) {
183
            apr_pollset_add(pollset, &conn->pfd);
184
        }
185
    }
186
}
187
146
/* CONNECT handler */
188
/* CONNECT handler */
147
static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
189
static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
148
                                 proxy_server_conf *conf,
190
                                 proxy_server_conf *conf,
Lines 153-176 static int proxy_connect_handler(request_rec *r, p Link Here
153
        ap_get_module_config(r->server->module_config, &proxy_connect_module);
195
        ap_get_module_config(r->server->module_config, &proxy_connect_module);
154
196
155
    apr_pool_t *p = r->pool;
197
    apr_pool_t *p = r->pool;
156
    apr_socket_t *sock;
157
    conn_rec *c = r->connection;
198
    conn_rec *c = r->connection;
158
    conn_rec *backconn;
159
    int done = 0;
199
    int done = 0;
160
161
    apr_bucket_brigade *bb_front;
162
    apr_bucket_brigade *bb_back;
163
    apr_status_t rv;
200
    apr_status_t rv;
164
    apr_size_t nbytes;
201
    apr_size_t nbytes;
165
    char buffer[HUGE_STRING_LEN];
202
    char buffer[HUGE_STRING_LEN];
166
    apr_socket_t *client_socket = ap_get_conn_socket(c);
167
    int failed, rc;
203
    int failed, rc;
168
    apr_pollset_t *pollset;
204
    apr_pollset_t *pollset;
169
    apr_pollfd_t pollfd;
170
    const apr_pollfd_t *signalled;
205
    const apr_pollfd_t *signalled;
171
    apr_int32_t pollcnt, pi;
206
    apr_int32_t pollcnt, pi;
172
    apr_int16_t pollevent;
173
    apr_sockaddr_t *nexthop;
207
    apr_sockaddr_t *nexthop;
208
    apr_interval_time_t timeout;
209
    struct proxy_connect_conn conns[2],
210
                              *client = &conns[0],
211
                              *backend = &conns[1];
212
#if AP_MODULE_MAGIC_AT_LEAST(20120211, 69)
213
    apr_size_t read_buf_size = ap_get_read_buf_size(r);
214
#else
215
    apr_size_t read_buf_size = CONN_BLKSZ;
216
#endif
174
217
175
    apr_uri_t uri;
218
    apr_uri_t uri;
176
    const char *connectname;
219
    const char *connectname;
Lines 238-243 static int proxy_connect_handler(request_rec *r, p Link Here
238
     * We have determined who to connect to. Now make the connection.
281
     * We have determined who to connect to. Now make the connection.
239
     */
282
     */
240
283
284
    client->c = c;
285
    client->pfd.p = p;
286
    client->pfd.client_data = NULL;
287
    client->pfd.reqevents = APR_POLLIN;
288
    client->pfd.desc_type = APR_POLL_SOCKET;
289
    client->pfd.desc.s = ap_get_conn_socket(c);
290
    client->name = "client";
291
    client->shutdown = 0;
292
293
    backend->c = NULL;
294
    backend->pfd.p = p;
295
    backend->pfd.client_data = NULL;
296
    backend->pfd.reqevents = APR_POLLIN;
297
    backend->pfd.desc_type = APR_POLL_SOCKET;
298
    backend->name = "backend";
299
    backend->shutdown = 0;
300
241
    /*
301
    /*
242
     * At this point we have a list of one or more IP addresses of
302
     * At this point we have a list of one or more IP addresses of
243
     * the machine to connect to. If configured, reorder this
303
     * the machine to connect to. If configured, reorder this
Lines 248-255 static int proxy_connect_handler(request_rec *r, p Link Here
248
     * For now we do nothing, ie we get DNS round robin.
308
     * For now we do nothing, ie we get DNS round robin.
249
     * XXX FIXME
309
     * XXX FIXME
250
     */
310
     */
251
    failed = ap_proxy_connect_to_backend(&sock, "CONNECT", nexthop,
311
    failed = ap_proxy_connect_to_backend(&backend->pfd.desc.s, "CONNECT",
252
                                         connectname, conf, r);
312
                                         nexthop, connectname, conf, r);
253
313
254
    /* handle a permanent error from the above loop */
314
    /* handle a permanent error from the above loop */
255
    if (failed) {
315
    if (failed) {
Lines 261-288 static int proxy_connect_handler(request_rec *r, p Link Here
261
        }
321
        }
262
    }
322
    }
263
323
264
    /* setup polling for connection */
265
    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "setting up poll()");
266
267
    if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) {
268
        apr_socket_close(sock);
269
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01020)
270
                      "error apr_pollset_create()");
271
        return HTTP_INTERNAL_SERVER_ERROR;
272
    }
273
274
    /* Add client side to the poll */
275
    pollfd.p = r->pool;
276
    pollfd.desc_type = APR_POLL_SOCKET;
277
    pollfd.reqevents = APR_POLLIN | APR_POLLHUP;
278
    pollfd.desc.s = client_socket;
279
    pollfd.client_data = NULL;
280
    apr_pollset_add(pollset, &pollfd);
281
282
    /* Add the server side to the poll */
283
    pollfd.desc.s = sock;
284
    apr_pollset_add(pollset, &pollfd);
285
286
    /*
324
    /*
287
     * Step Three: Send the Request
325
     * Step Three: Send the Request
288
     *
326
     *
Lines 289-308 static int proxy_connect_handler(request_rec *r, p Link Here
289
     * Send the HTTP/1.1 CONNECT request to the remote server
327
     * Send the HTTP/1.1 CONNECT request to the remote server
290
     */
328
     */
291
329
292
    backconn = ap_run_create_connection(c->pool, r->server, sock,
330
    backend->c = ap_run_create_connection(c->pool, r->server,
293
                                        c->id, c->sbh, c->bucket_alloc);
331
                                          backend->pfd.desc.s, 0, NULL,
294
    if (!backconn) {
332
                                          c->bucket_alloc);
333
    if (!backend->c) {
295
        /* peer reset */
334
        /* peer reset */
296
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01021)
335
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01021)
297
                      "an error occurred creating a new connection "
336
                      "an error occurred creating a new connection "
298
                      "to %pI (%s)", nexthop, connectname);
337
                      "to %pI (%s)", nexthop, connectname);
299
        apr_socket_close(sock);
338
        apr_socket_close(backend->pfd.desc.s);
300
        return HTTP_INTERNAL_SERVER_ERROR;
339
        return HTTP_INTERNAL_SERVER_ERROR;
301
    }
340
    }
302
    ap_proxy_ssl_disable(backconn);
341
    ap_proxy_ssl_disable(backend->c);
303
    rc = ap_run_pre_connection(backconn, sock);
342
343
    rc = ap_run_pre_connection(backend->c, backend->pfd.desc.s);
304
    if (rc != OK && rc != DONE) {
344
    if (rc != OK && rc != DONE) {
305
        backconn->aborted = 1;
345
        backend->c->aborted = 1;
306
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01022)
346
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01022)
307
                      "pre_connection setup failed (%d)", rc);
347
                      "pre_connection setup failed (%d)", rc);
308
        return HTTP_INTERNAL_SERVER_ERROR;
348
        return HTTP_INTERNAL_SERVER_ERROR;
Lines 312-323 static int proxy_connect_handler(request_rec *r, p Link Here
312
                  "connection complete to %pI (%s)",
352
                  "connection complete to %pI (%s)",
313
                  nexthop, connectname);
353
                  nexthop, connectname);
314
    apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu",
354
    apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu",
315
                   backconn->local_addr->port));
355
                   backend->c->local_addr->port));
316
356
357
    client->bb = apr_brigade_create(p, client->c->bucket_alloc);
358
    backend->bb = apr_brigade_create(p, backend->c->bucket_alloc);
317
359
318
    bb_front = apr_brigade_create(p, c->bucket_alloc);
319
    bb_back = apr_brigade_create(p, backconn->bucket_alloc);
320
321
    /* If we are connecting through a remote proxy, we need to pass
360
    /* If we are connecting through a remote proxy, we need to pass
322
     * the CONNECT request on to it.
361
     * the CONNECT request on to it.
323
     */
362
     */
Lines 326-336 static int proxy_connect_handler(request_rec *r, p Link Here
326
     */
365
     */
327
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
366
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
328
                      "sending the CONNECT request to the remote proxy");
367
                      "sending the CONNECT request to the remote proxy");
329
        ap_fprintf(backconn->output_filters, bb_back,
368
        ap_fprintf(backend->c->output_filters, backend->bb,
330
                   "CONNECT %s HTTP/1.0" CRLF, r->uri);
369
                   "CONNECT %s HTTP/1.0" CRLF, r->uri);
331
        ap_fprintf(backconn->output_filters, bb_back,
370
        ap_fprintf(backend->c->output_filters, backend->bb,
332
                   "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner());
371
                   "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner());
333
        ap_fflush(backconn->output_filters, bb_back);
372
        ap_fflush(backend->c->output_filters, backend->bb);
334
    }
373
    }
335
    else {
374
    else {
336
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Returning 200 OK");
375
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Returning 200 OK");
Lines 337-349 static int proxy_connect_handler(request_rec *r, p Link Here
337
        nbytes = apr_snprintf(buffer, sizeof(buffer),
376
        nbytes = apr_snprintf(buffer, sizeof(buffer),
338
                              "HTTP/1.0 200 Connection Established" CRLF);
377
                              "HTTP/1.0 200 Connection Established" CRLF);
339
        ap_xlate_proto_to_ascii(buffer, nbytes);
378
        ap_xlate_proto_to_ascii(buffer, nbytes);
340
        ap_fwrite(c->output_filters, bb_front, buffer, nbytes);
379
        ap_fwrite(client->c->output_filters, client->bb, buffer, nbytes);
341
        nbytes = apr_snprintf(buffer, sizeof(buffer),
380
        nbytes = apr_snprintf(buffer, sizeof(buffer),
342
                              "Proxy-agent: %s" CRLF CRLF,
381
                              "Proxy-agent: %s" CRLF CRLF,
343
                              ap_get_server_banner());
382
                              ap_get_server_banner());
344
        ap_xlate_proto_to_ascii(buffer, nbytes);
383
        ap_xlate_proto_to_ascii(buffer, nbytes);
345
        ap_fwrite(c->output_filters, bb_front, buffer, nbytes);
384
        ap_fwrite(client->c->output_filters, client->bb, buffer, nbytes);
346
        ap_fflush(c->output_filters, bb_front);
385
        ap_fflush(client->c->output_filters, client->bb);
347
#if 0
386
#if 0
348
        /* This is safer code, but it doesn't work yet.  I'm leaving it
387
        /* This is safer code, but it doesn't work yet.  I'm leaving it
349
         * here so that I can fix it later.
388
         * here so that I can fix it later.
Lines 357-362 static int proxy_connect_handler(request_rec *r, p Link Here
357
396
358
    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "setting up poll()");
397
    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "setting up poll()");
359
398
399
    rv = apr_pollset_create(&pollset, 2, r->pool, APR_POLLSET_NOCOPY);
400
    if (rv != APR_SUCCESS) {
401
        apr_socket_close(backend->pfd.desc.s);
402
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01020)
403
                      "error apr_pollset_create()");
404
        return HTTP_INTERNAL_SERVER_ERROR;
405
    }
406
    apr_pollset_add(pollset, &client->pfd);
407
    apr_pollset_add(pollset, &backend->pfd);
408
360
    /*
409
    /*
361
     * Step Four: Handle Data Transfer
410
     * Step Four: Handle Data Transfer
362
     *
411
     *
Lines 364-386 static int proxy_connect_handler(request_rec *r, p Link Here
364
     */
413
     */
365
414
366
    /* we are now acting as a tunnel - the input/output filter stacks should
415
    /* we are now acting as a tunnel - the input/output filter stacks should
367
     * not contain any non-connection filters.
416
     * not contain any non-connection or coalescing filters.
368
     */
417
     */
418
    ap_remove_output_filter_byhandle(client->c->output_filters,
419
                                     "SSL/TLS Coalescing Filter");
420
    ap_remove_output_filter_byhandle(backend->c->output_filters,
421
                                     "SSL/TLS Coalescing Filter");
369
    r->output_filters = c->output_filters;
422
    r->output_filters = c->output_filters;
370
    r->proto_output_filters = c->output_filters;
423
    r->proto_output_filters = c->output_filters;
371
    r->input_filters = c->input_filters;
424
    r->input_filters = c->input_filters;
372
    r->proto_input_filters = c->input_filters;
425
    r->proto_input_filters = c->input_filters;
373
/*    r->sent_bodyct = 1;*/
426
    /* r->sent_bodyct = 1;*/
374
427
428
    client->core_filter = client->c->output_filters;
429
    while (client->core_filter->next) {
430
        client->core_filter = client->core_filter->next;
431
    }
432
    client->core_output = client->core_filter->frec->filter_func.out_func;
433
434
    backend->core_filter = backend->c->output_filters;
435
    while (backend->core_filter->next) {
436
        backend->core_filter = backend->core_filter->next;
437
    }
438
    backend->core_output = backend->core_filter->frec->filter_func.out_func;
439
440
    apr_socket_timeout_get(client->pfd.desc.s, &client->timeout);
441
    apr_socket_timeout_get(backend->pfd.desc.s, &backend->timeout);
442
    timeout = client->timeout < backend->timeout ? client->timeout
443
                                                 : backend->timeout;
444
375
    do { /* Loop until done (one side closes the connection, or an error) */
445
    do { /* Loop until done (one side closes the connection, or an error) */
376
        rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled);
446
        rv = apr_pollset_poll(pollset, timeout, &pollcnt, &signalled);
377
        if (rv != APR_SUCCESS) {
447
        if (rv != APR_SUCCESS) {
378
            if (APR_STATUS_IS_EINTR(rv)) {
448
            if (APR_STATUS_IS_EINTR(rv)) {
379
                continue;
449
                continue;
380
            }
450
            }
381
            apr_socket_close(sock);
451
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01023) "polling");
382
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01023) "error apr_poll()");
452
            break;
383
            return HTTP_INTERNAL_SERVER_ERROR;
384
        }
453
        }
385
#ifdef DEBUGGING
454
#ifdef DEBUGGING
386
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01024)
455
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01024)
Lines 390-447 static int proxy_connect_handler(request_rec *r, p Link Here
390
        for (pi = 0; pi < pollcnt; pi++) {
459
        for (pi = 0; pi < pollcnt; pi++) {
391
            const apr_pollfd_t *cur = &signalled[pi];
460
            const apr_pollfd_t *cur = &signalled[pi];
392
461
393
            if (cur->desc.s == sock) {
462
            if (cur->desc.s != client->pfd.desc.s
394
                pollevent = cur->rtnevents;
463
                    && cur->desc.s != backend->pfd.desc.s) {
395
                if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
464
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01028)
465
                              "unknown socket in pollset");
466
                done = 1;
467
                break;
468
            }
469
470
            if (!(cur->rtnevents & (APR_POLLIN | APR_POLLHUP | APR_POLLOUT))) {
471
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01026)
472
                              "polling failed (0x%x)", cur->rtnevents);
473
                if (cur->desc.s == client->pfd.desc.s) {
474
                    client->c->aborted = 1;
475
                }
476
                else {
477
                    backend->c->aborted = 1;
478
                }
479
                done = 1;
480
                break;
481
            }
482
483
            if (cur->rtnevents & (APR_POLLIN | APR_POLLHUP)) {
484
                int in = (cur->desc.s != client->pfd.desc.s), out = !in;
396
#ifdef DEBUGGING
485
#ifdef DEBUGGING
397
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01025)
486
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01025)
398
                                  "sock was readable");
487
                              "%s was readable", conns[in].name);
399
#endif
488
#endif
400
                    done |= ap_proxy_transfer_between_connections(r, backconn,
489
                rv = ap_proxy_transfer_between_connections(r,
401
                                                                  c, bb_back,
490
                                               conns[in].c, conns[out].c,
402
                                                                  bb_front,
491
                                               conns[in].bb, conns[out].bb,
403
                                                                  "sock", NULL,
492
                                               conns[in].name,
404
                                                                  CONN_BLKSZ, 1)
493
                                               NULL, read_buf_size,
405
                                                                 != APR_SUCCESS;
494
                                               AP_PROXY_TRANSFER_FLUSH_NEVER |
495
                                               AP_PROXY_TRANSFER_UNBUFFERED);
496
                if (rv != APR_SUCCESS) {
497
                    if (!APR_STATUS_IS_EOF(rv)) {
498
                        /* Real failure, bail out */
499
                        done = 1;
500
                    }
501
                    else {
502
                        /* Stop reading, wait for POLLOUT on the other side to
503
                         * shut it down.
504
                         */
505
#ifdef DEBUGGING
506
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
507
                                      "%s read shutdown", conns[in].name);
508
#endif
509
                        conns[in].shutdown |= PROXY_SHUTDOWN_READ;
510
                        pollset_del_conn(pollset, &conns[in], APR_POLLIN);
511
                        pollset_add_conn(pollset, &conns[out], APR_POLLOUT);
512
                    }
406
                }
513
                }
407
                else if (pollevent & APR_POLLERR) {
514
                else if (conns[out].c->data_in_output_filters) {
408
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026)
515
                    /* While waiting for POLLOUT on the other side, pause
409
                                  "err on backconn");
516
                     * POLLIN on the this side to avoid filling the output
410
                    backconn->aborted = 1;
517
                     * filters even more and hence blocking there.
411
                    done = 1;
518
                     */
519
#ifdef DEBUGGING
520
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
521
                                  "%s wait writable", conns[out].name);
522
#endif
523
                    pollset_del_conn(pollset, &conns[in], APR_POLLIN);
524
                    pollset_add_conn(pollset, &conns[out], APR_POLLOUT);
412
                }
525
                }
413
            }
526
            }
414
            else if (cur->desc.s == client_socket) {
527
415
                pollevent = cur->rtnevents;
528
            if (cur->rtnevents & APR_POLLOUT) {
416
                if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
529
                int out = (cur->desc.s != client->pfd.desc.s), in = !out;
417
#ifdef DEBUGGING
530
#ifdef DEBUGGING
418
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01027)
531
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
419
                                  "client was readable");
532
                              "%s was writable", conns[out].name);
420
#endif
533
#endif
421
                    done |= ap_proxy_transfer_between_connections(r, c,
534
                rv = conns[out].core_output(conns[out].core_filter, NULL);
422
                                                                  backconn,
535
                if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
423
                                                                  bb_front,
536
                    /* Real failure, bail out */
424
                                                                  bb_back,
425
                                                                  "client",
426
                                                                  NULL,
427
                                                                  CONN_BLKSZ, 1)
428
                                                                 != APR_SUCCESS;
429
                }
430
                else if (pollevent & APR_POLLERR) {
431
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02827)
432
                                  "err on client");
433
                    c->aborted = 1;
434
                    done = 1;
537
                    done = 1;
435
                }
538
                }
539
                else if (!conns[out].c->data_in_output_filters) {
540
                    /* Pending data now flushed, stop POLLOUT and restore
541
                     * POLLIN on the other side (unless it's shutdown for read
542
                     * already in which case we simply propagate the shutdown).
543
                     */
544
                    if (conns[in].shutdown & PROXY_SHUTDOWN_READ) {
545
#ifdef DEBUGGING
546
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
547
                                      "%s write shutdown", conns[out].name);
548
#endif
549
                        apr_socket_shutdown(conns[out].pfd.desc.s, 1);
550
                        conns[out].shutdown |= PROXY_SHUTDOWN_WRITE;
551
                    }
552
                    else {
553
                        pollset_add_conn(pollset, &conns[in], APR_POLLIN);
554
                    }
555
                    pollset_del_conn(pollset, &conns[out], APR_POLLOUT);
556
                }
436
            }
557
            }
437
            else {
438
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01028)
439
                              "unknown socket in pollset");
440
                done = 1;
441
            }
442
443
        }
558
        }
444
    } while (!done);
559
    } while (!done && (client->pfd.reqevents || backend->pfd.reqevents));
445
560
446
    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
561
    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
447
                  "finished with poll() - cleaning up");
562
                  "finished with poll() - cleaning up");
Lines 451-464 static int proxy_connect_handler(request_rec *r, p Link Here
451
     *
566
     *
452
     * Close the socket and clean up
567
     * Close the socket and clean up
453
     */
568
     */
569
    apr_pollset_remove(pollset, &client->pfd);
570
    apr_pollset_remove(pollset, &backend->pfd);
571
    apr_socket_close(backend->pfd.desc.s);
572
    c->aborted = 1;
454
573
455
    if (backconn->aborted)
456
        apr_socket_close(sock);
457
    else
458
        ap_lingering_close(backconn);
459
460
    c->keepalive = AP_CONN_CLOSE;
461
462
    return OK;
574
    return OK;
463
}
575
}
464
576
(-)modules/proxy/proxy_util.c (-4 / +6 lines)
Lines 3774-3780 PROXY_DECLARE(apr_status_t) ap_proxy_transfer_betw Link Here
3774
                                                       const char *name,
3774
                                                       const char *name,
3775
                                                       int *sent,
3775
                                                       int *sent,
3776
                                                       apr_off_t bsize,
3776
                                                       apr_off_t bsize,
3777
                                                       int after)
3777
                                                       int flags)
3778
{
3778
{
3779
    apr_status_t rv;
3779
    apr_status_t rv;
3780
#ifdef DEBUGGING
3780
#ifdef DEBUGGING
Lines 3804-3810 PROXY_DECLARE(apr_status_t) ap_proxy_transfer_betw Link Here
3804
                *sent = 1;
3804
                *sent = 1;
3805
            }
3805
            }
3806
            ap_proxy_buckets_lifetime_transform(r, bb_i, bb_o);
3806
            ap_proxy_buckets_lifetime_transform(r, bb_i, bb_o);
3807
            if (!after) {
3807
            /* No AP_PROXY_TRANSFER_FLUSH_ flag means flush each */
3808
            if (!(flags & AP_PROXY_TRANSFER_FLUSH_MASK)) {
3808
                apr_bucket *b;
3809
                apr_bucket *b;
3809
3810
3810
                /*
3811
                /*
Lines 3833-3841 PROXY_DECLARE(apr_status_t) ap_proxy_transfer_betw Link Here
3833
                          "error on %s - ap_get_brigade",
3834
                          "error on %s - ap_get_brigade",
3834
                          name);
3835
                          name);
3835
        }
3836
        }
3836
    } while (rv == APR_SUCCESS);
3837
    } while (rv == APR_SUCCESS && (!(flags & AP_PROXY_TRANSFER_UNBUFFERED)
3838
                                   || !c_o->data_in_output_filters));
3837
3839
3838
    if (after) {
3840
    if (flags & AP_PROXY_TRANSFER_FLUSH_AFTER) {
3839
        ap_fflush(c_o->output_filters, bb_o);
3841
        ap_fflush(c_o->output_filters, bb_o);
3840
    }
3842
    }
3841
3843

Return to bug 61616