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

(-)modules/proxy/mod_proxy_wstunnel.c (-19 / +35 lines)
Lines 39-45 typedef struct ws_baton_t { Link Here
39
39
40
static void proxy_wstunnel_callback(void *b);
40
static void proxy_wstunnel_callback(void *b);
41
41
42
static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout, int try_poll) {
42
static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout,
43
                               int try_poll, int *replied)
44
{
43
    request_rec *r = baton->r;
45
    request_rec *r = baton->r;
44
    conn_rec *c = r->connection;
46
    conn_rec *c = r->connection;
45
    proxy_conn_rec *conn = baton->proxy_connrec;
47
    proxy_conn_rec *conn = baton->proxy_connrec;
Lines 53-59 static void proxy_wstunnel_callback(void *b); Link Here
53
    apr_status_t rv;
55
    apr_status_t rv;
54
    apr_bucket_brigade *bb_i = baton->bb_i;
56
    apr_bucket_brigade *bb_i = baton->bb_i;
55
    apr_bucket_brigade *bb_o = baton->bb_o;
57
    apr_bucket_brigade *bb_o = baton->bb_o;
56
    int done = 0, replied = 0;
58
    int done = 0;
57
59
58
    do { 
60
    do { 
59
        rv = apr_pollset_poll(pollset, timeout, &pollcnt, &signalled);
61
        rv = apr_pollset_poll(pollset, timeout, &pollcnt, &signalled);
Lines 91-97 static void proxy_wstunnel_callback(void *b); Link Here
91
                    done |= ap_proxy_transfer_between_connections(r, backconn,
93
                    done |= ap_proxy_transfer_between_connections(r, backconn,
92
                                                                  c, bb_i, bb_o,
94
                                                                  c, bb_i, bb_o,
93
                                                                  "backend",
95
                                                                  "backend",
94
                                                                  &replied,
96
                                                                  replied,
95
                                                                  AP_IOBUFSIZE,
97
                                                                  AP_IOBUFSIZE,
96
                                                                  0)
98
                                                                  0)
97
                                                                 != APR_SUCCESS;
99
                                                                 != APR_SUCCESS;
Lines 143-155 static void proxy_wstunnel_callback(void *b); Link Here
143
145
144
    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
146
    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
145
            "finished with poll() - cleaning up");
147
            "finished with poll() - cleaning up");
146
148
    return OK;
147
    if (!replied) {
148
        return HTTP_BAD_GATEWAY;
149
    }
150
    else {
151
        return OK;
152
    }
153
}
149
}
154
150
155
static void proxy_wstunnel_finish(ws_baton_t *baton) { 
151
static void proxy_wstunnel_finish(ws_baton_t *baton) { 
Lines 181-192 static void proxy_wstunnel_cancel_callback(void *b Link Here
181
 *  We don't need the invoke_mtx, since we never put multiple callback events
177
 *  We don't need the invoke_mtx, since we never put multiple callback events
182
 *  in the queue.
178
 *  in the queue.
183
 */
179
 */
184
static void proxy_wstunnel_callback(void *b) { 
180
static void proxy_wstunnel_callback(void *b)
181
{ 
185
    int status;
182
    int status;
186
    ws_baton_t *baton = (ws_baton_t*)b;
183
    ws_baton_t *baton = (ws_baton_t*)b;
187
    proxyws_dir_conf *dconf = ap_get_module_config(baton->r->per_dir_config, &proxy_wstunnel_module);
184
    proxyws_dir_conf *dconf = ap_get_module_config(baton->r->per_dir_config, &proxy_wstunnel_module);
188
    apr_pool_clear(baton->subpool);
185
    apr_pool_clear(baton->subpool);
189
    status = proxy_wstunnel_pump(baton, dconf->async_delay, dconf->mpm_can_poll);
186
    status = proxy_wstunnel_pump(baton, dconf->async_delay,
187
                                 dconf->mpm_can_poll, NULL);
190
    if (status == SUSPENDED) {
188
    if (status == SUSPENDED) {
191
        apr_pollfd_t *pfd;
189
        apr_pollfd_t *pfd;
192
190
Lines 315-320 static int proxy_wstunnel_request(apr_pool_t *p, r Link Here
315
    int status;
313
    int status;
316
    proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_wstunnel_module);
314
    proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_wstunnel_module);
317
    const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
315
    const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
316
    ap_filter_t *saved_output_filters, *saved_proto_output_filters;
317
    int replied = 0;
318
318
319
    header_brigade = apr_brigade_create(p, backconn->bucket_alloc);
319
    header_brigade = apr_brigade_create(p, backconn->bucket_alloc);
320
320
Lines 367-372 static int proxy_wstunnel_request(apr_pool_t *p, r Link Here
367
    pollfd.desc.s = client_socket;
367
    pollfd.desc.s = client_socket;
368
    apr_pollset_add(pollset, &pollfd);
368
    apr_pollset_add(pollset, &pollfd);
369
369
370
    saved_output_filters = r->output_filters;
371
    saved_proto_output_filters = r->proto_output_filters;
370
    ap_remove_input_filter_byhandle(c->input_filters, "reqtimeout");
372
    ap_remove_input_filter_byhandle(c->input_filters, "reqtimeout");
371
373
372
    r->output_filters = c->output_filters;
374
    r->output_filters = c->output_filters;
Lines 389-398 static int proxy_wstunnel_request(apr_pool_t *p, r Link Here
389
    apr_pool_create(&baton->subpool, r->pool);
391
    apr_pool_create(&baton->subpool, r->pool);
390
392
391
    if (!dconf->mpm_can_poll) {
393
    if (!dconf->mpm_can_poll) {
392
        status = proxy_wstunnel_pump(baton, dconf->idle_timeout, dconf->mpm_can_poll);
394
        status = proxy_wstunnel_pump(baton, dconf->idle_timeout,
395
                                     dconf->mpm_can_poll, &replied);
393
    }  
396
    }  
394
    else { 
397
    else { 
395
        status = proxy_wstunnel_pump(baton, dconf->async_delay, dconf->mpm_can_poll);
398
        status = proxy_wstunnel_pump(baton, dconf->async_delay,
399
                                     dconf->mpm_can_poll, &replied);
396
        apr_pool_clear(baton->subpool);
400
        apr_pool_clear(baton->subpool);
397
        if (status == SUSPENDED) {
401
        if (status == SUSPENDED) {
398
            apr_pollfd_t *pfd;
402
            apr_pollfd_t *pfd;
Lines 420-438 static int proxy_wstunnel_request(apr_pool_t *p, r Link Here
420
                return SUSPENDED;
424
                return SUSPENDED;
421
            }
425
            }
422
            else if (APR_STATUS_IS_ENOTIMPL(rv)) { 
426
            else if (APR_STATUS_IS_ENOTIMPL(rv)) { 
423
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02544) "No async support");
427
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
424
                status = proxy_wstunnel_pump(baton, dconf->idle_timeout, 0); /* force no async */
428
                              APLOGNO(02544) "No async support");
429
                status = proxy_wstunnel_pump(baton, dconf->idle_timeout,
430
                                             0, /* force no async */
431
                                             &replied);
425
            }
432
            }
426
            else { 
433
            else { 
427
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
434
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
428
                              APLOGNO(02543) "error creating websockets tunnel");
435
                              APLOGNO(02543) "error creating websockets tunnel");
429
                return HTTP_INTERNAL_SERVER_ERROR;
436
                if (!replied) {
437
                    status = HTTP_INTERNAL_SERVER_ERROR;
438
                }
430
            }
439
            }
431
        }
440
        }
432
    }
441
    }
433
442
434
    if (status != OK) { 
443
    /* Avoid sending error pages down an upgraded connection */
435
        /* Avoid sending error pages down an upgraded connection */
444
    if (!replied) {
445
        r->output_filters = saved_output_filters;
446
        r->proto_output_filters = saved_proto_output_filters;
447
        if (status == OK) {
448
            status = HTTP_BAD_GATEWAY;
449
        }
450
    }
451
    else if (status != OK) { 
436
        if (status != HTTP_REQUEST_TIME_OUT) {
452
        if (status != HTTP_REQUEST_TIME_OUT) {
437
            r->status = status;
453
            r->status = status;
438
        }
454
        }

Return to bug 61284