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 |
} |