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

(-)httpd-2.2.0/modules/proxy/mod_proxy_connect.c (-162 / +174 lines)
Lines 21-29 Link Here
21
#include "mod_proxy.h"
21
#include "mod_proxy.h"
22
#include "apr_poll.h"
22
#include "apr_poll.h"
23
23
24
#define CONN_BLKSZ AP_IOBUFSIZE
25
24
module AP_MODULE_DECLARE_DATA proxy_connect_module;
26
module AP_MODULE_DECLARE_DATA proxy_connect_module;
25
27
26
/*  
28
/*
27
 * This handles Netscape CONNECT method secure proxy requests.
29
 * This handles Netscape CONNECT method secure proxy requests.
28
 * A connection is opened to the specified host and data is
30
 * A connection is opened to the specified host and data is
29
 * passed through between the WWW site and the browser.
31
 * passed through between the WWW site and the browser.
Lines 32-39 Link Here
32
 * "Tunneling SSL Through a WWW Proxy" currently at
34
 * "Tunneling SSL Through a WWW Proxy" currently at
33
 * http://www.mcom.com/newsref/std/tunneling_ssl.html.
35
 * http://www.mcom.com/newsref/std/tunneling_ssl.html.
34
 *
36
 *
35
 * If proxyhost and proxyport are set, we send a CONNECT to 
37
 * If proxyhost and proxyport are set, we send a CONNECT to
36
 * the specified proxy..  
38
 * the specified proxy..
37
 *
39
 *
38
 * FIXME: this doesn't log the number of bytes sent, but
40
 * FIXME: this doesn't log the number of bytes sent, but
39
 *        that may be okay, since the data is supposed to
41
 *        that may be okay, since the data is supposed to
Lines 52-59 Link Here
52
    int *list = (int *) conf->allowed_connect_ports->elts;
54
    int *list = (int *) conf->allowed_connect_ports->elts;
53
55
54
    for(i = 0; i < conf->allowed_connect_ports->nelts; i++) {
56
    for(i = 0; i < conf->allowed_connect_ports->nelts; i++) {
55
    if(port == list[i])
57
	if(port == list[i])
56
        return 1;
58
	    return 1;
57
    }
59
    }
58
    return 0;
60
    return 0;
59
}
61
}
Lines 63-80 Link Here
63
{
65
{
64
66
65
    if (r->method_number != M_CONNECT) {
67
    if (r->method_number != M_CONNECT) {
66
    return DECLINED;
68
	return DECLINED;
67
    }
69
    }
68
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
70
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
69
         "proxy: CONNECT: canonicalising URL %s", url);
71
		  "proxy: CONNECT: canonicalising URL %s", url);
70
72
71
    return OK;
73
    return OK;
72
}
74
}
73
75
76
/* read available data (in blocks of CONN_BLKSZ) from c_i and copy to c_o */
77
static int proxy_connect_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o,
78
				  apr_bucket_brigade *bb, char *name)
79
{
80
    int rv;
81
#ifdef DEBUGGING
82
    apr_off_t len;
83
#endif
84
85
    do {
86
	apr_brigade_cleanup(bb);
87
	rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES,
88
			    APR_NONBLOCK_READ, CONN_BLKSZ);
89
	if (rv == APR_SUCCESS) {
90
	    if (APR_BRIGADE_EMPTY(bb))
91
		break;
92
#ifdef DEBUGGING
93
	    len = -1;
94
	    apr_brigade_length(bb, 0, &len);
95
	    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
96
			  "proxy: CONNECT: read %" APR_OFF_T_FMT
97
			  " bytes from %s", len, name);
98
#endif
99
	    rv = ap_pass_brigade(c_o->output_filters, bb);
100
	    if (rv == APR_SUCCESS) {
101
		ap_fflush(c_o->output_filters, bb);
102
	    } else {
103
		ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
104
			      "proxy: CONNECT: error on %s - ap_pass_brigade",
105
			      name);
106
	    }
107
	} else if (!APR_STATUS_IS_EAGAIN(rv)) {
108
	    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r,
109
			  "proxy: CONNECT: error on %s - ap_get_brigade",
110
			  name);
111
	}
112
    } while (rv == APR_SUCCESS);
113
114
    if (APR_STATUS_IS_EAGAIN(rv)) {
115
	rv = APR_SUCCESS;
116
    }
117
    return rv;
118
}
119
74
/* CONNECT handler */
120
/* CONNECT handler */
75
static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
121
static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
76
                                 proxy_server_conf *conf, 
122
                                 proxy_server_conf *conf,
77
                                 char *url, const char *proxyname, 
123
                                 char *url, const char *proxyname,
78
                                 apr_port_t proxyport)
124
                                 apr_port_t proxyport)
79
{
125
{
80
    apr_pool_t *p = r->pool;
126
    apr_pool_t *p = r->pool;
Lines 84-90 Link Here
84
    apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
130
    apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
85
131
86
    apr_status_t err, rv;
132
    apr_status_t err, rv;
87
    apr_size_t i, o, nbytes;
133
    apr_size_t nbytes;
88
    char buffer[HUGE_STRING_LEN];
134
    char buffer[HUGE_STRING_LEN];
89
    apr_socket_t *client_socket = ap_get_module_config(c->conn_config, &core_module);
135
    apr_socket_t *client_socket = ap_get_module_config(c->conn_config, &core_module);
90
    int failed, rc;
136
    int failed, rc;
Lines 101-112 Link Here
101
147
102
    /* is this for us? */
148
    /* is this for us? */
103
    if (r->method_number != M_CONNECT) {
149
    if (r->method_number != M_CONNECT) {
104
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
150
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
105
             "proxy: CONNECT: declining URL %s", url);
151
		      "proxy: CONNECT: declining URL %s", url);
106
    return DECLINED;
152
	return DECLINED;
107
    }
153
    }
108
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
154
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
109
         "proxy: CONNECT: serving URL %s", url);
155
		  "proxy: CONNECT: serving URL %s", url);
110
156
111
157
112
    /*
158
    /*
Lines 117-166 Link Here
117
163
118
    /* we break the URL into host, port, uri */
164
    /* we break the URL into host, port, uri */
119
    if (APR_SUCCESS != apr_uri_parse_hostinfo(p, url, &uri)) {
165
    if (APR_SUCCESS != apr_uri_parse_hostinfo(p, url, &uri)) {
120
    return ap_proxyerror(r, HTTP_BAD_REQUEST,
166
	return ap_proxyerror(r, HTTP_BAD_REQUEST,
121
                 apr_pstrcat(p, "URI cannot be parsed: ", url, NULL));
167
                 apr_pstrcat(p, "URI cannot be parsed: ", url, NULL));
122
    }
168
    }
123
169
124
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
170
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
125
         "proxy: CONNECT: connecting %s to %s:%d", url, uri.hostname, uri.port);
171
		  "proxy: CONNECT: connecting %s to %s:%d",
172
		  url, uri.hostname, uri.port);
126
173
127
    /* do a DNS lookup for the destination host */
174
    /* do a DNS lookup for the destination host */
128
    err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port, 0, p);
175
    err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port,
176
				0, p);
129
177
130
    /* are we connecting directly, or via a proxy? */
178
    /* are we connecting directly, or via a proxy? */
131
    if (proxyname) {
179
    if (proxyname) {
132
    connectname = proxyname;
180
	connectname = proxyname;
133
    connectport = proxyport;
181
	connectport = proxyport;
134
        err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC, proxyport, 0, p);
182
        err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC, proxyport, 0, p);
135
    }
183
    }
136
    else {
184
    else {
137
    connectname = uri.hostname;
185
	connectname = uri.hostname;
138
    connectport = uri.port;
186
	connectport = uri.port;
139
    connect_addr = uri_addr;
187
	connect_addr = uri_addr;
140
    }
188
    }
141
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
189
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
142
         "proxy: CONNECT: connecting to remote proxy %s on port %d", connectname, connectport);
190
		  "proxy: CONNECT: connecting to remote proxy %s on port %d",
191
		  connectname, connectport);
143
192
144
    /* check if ProxyBlock directive on this host */
193
    /* check if ProxyBlock directive on this host */
145
    if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) {
194
    if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) {
146
    return ap_proxyerror(r, HTTP_FORBIDDEN,
195
	return ap_proxyerror(r, HTTP_FORBIDDEN,
147
                 "Connect to remote machine blocked");
196
			     "Connect to remote machine blocked");
148
    }
197
    }
149
198
150
    /* Check if it is an allowed port */
199
    /* Check if it is an allowed port */
151
    if (conf->allowed_connect_ports->nelts == 0) {
200
    if (conf->allowed_connect_ports->nelts == 0) {
152
    /* Default setting if not overridden by AllowCONNECT */
201
	/* Default setting if not overridden by AllowCONNECT */
153
    switch (uri.port) {
202
	switch (uri.port) {
154
        case APR_URI_HTTPS_DEFAULT_PORT:
203
        case APR_URI_HTTPS_DEFAULT_PORT:
155
        case APR_URI_SNEWS_DEFAULT_PORT:
204
        case APR_URI_SNEWS_DEFAULT_PORT:
156
        break;
205
	    break;
157
        default:
206
        default:
158
                /* XXX can we call ap_proxyerror() here to get a nice log message? */
207
	    return ap_proxyerror(r, HTTP_FORBIDDEN,
159
        return HTTP_FORBIDDEN;
208
				 "Connect to remote machine blocked");
160
    }
209
	}
161
    } else if(!allowed_port(conf, uri.port)) {
210
    } else if(!allowed_port(conf, uri.port)) {
162
        /* XXX can we call ap_proxyerror() here to get a nice log message? */
211
	return ap_proxyerror(r, HTTP_FORBIDDEN,
163
    return HTTP_FORBIDDEN;
212
			     "Connect to remote machine blocked");
164
    }
213
    }
165
214
166
    /*
215
    /*
Lines 173-179 Link Here
173
     * until we get a successful connection
222
     * until we get a successful connection
174
     */
223
     */
175
    if (APR_SUCCESS != err) {
224
    if (APR_SUCCESS != err) {
176
    return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p,
225
	return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p,
177
                             "DNS lookup failure for: ",
226
                             "DNS lookup failure for: ",
178
                             connectname, NULL));
227
                             connectname, NULL));
179
    }
228
    }
Lines 198-241 Link Here
198
            return DECLINED;
247
            return DECLINED;
199
        }
248
        }
200
        else {
249
        else {
201
            return HTTP_BAD_GATEWAY;
250
	    return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p,
251
                                 "connect failure for: ",
252
                                 connectname, NULL));
202
        }
253
        }
203
    }
254
    }
204
255
256
    /* setup polling for connection */
257
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
258
		  "proxy: CONNECT: setting up poll()");
259
260
    if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) {
261
	apr_socket_close(sock);
262
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
263
            "proxy: CONNECT: error apr_pollset_create()");
264
        return HTTP_INTERNAL_SERVER_ERROR;
265
    }
266
267
    /* Add client side to the poll */
268
    pollfd.p = r->pool;
269
    pollfd.desc_type = APR_POLL_SOCKET;
270
    pollfd.reqevents = APR_POLLIN;
271
    pollfd.desc.s = client_socket;
272
    pollfd.client_data = NULL;
273
    apr_pollset_add(pollset, &pollfd);
274
275
    /* Add the server side to the poll */
276
    pollfd.desc.s = sock;
277
    apr_pollset_add(pollset, &pollfd);
278
205
    /*
279
    /*
206
     * Step Three: Send the Request
280
     * Step Three: Send the Request
207
     *
281
     *
208
     * Send the HTTP/1.1 CONNECT request to the remote server
282
     * Send the HTTP/1.1 CONNECT request to the remote server
209
     */
283
     */
210
284
211
    /* we are acting as a tunnel - the output filter stack should
212
     * be completely empty, because when we are done here we are done completely.
213
     * We add the NULL filter to the stack to do this...
214
     */
215
    r->output_filters = NULL;
216
217
    backconn = ap_run_create_connection(c->pool, r->server, sock,
285
    backconn = ap_run_create_connection(c->pool, r->server, sock,
218
					c->id, c->sbh, c->bucket_alloc);
286
					c->id, c->sbh, c->bucket_alloc);
219
    if (!backconn) {
287
    if (!backconn) {
220
	/* peer reset */
288
	/* peer reset */
221
	ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
289
	ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
222
		     "proxy: an error occurred creating a new connection "
290
		      "proxy: an error occurred creating a new connection "
223
		     "to %pI (%s)", connect_addr, connectname);
291
		      "to %pI (%s)", connect_addr, connectname);
224
	apr_socket_close(sock);
292
	apr_socket_close(sock);
225
	return HTTP_INTERNAL_SERVER_ERROR;
293
	return HTTP_INTERNAL_SERVER_ERROR;
226
    }
294
    }
227
    ap_proxy_ssl_disable(backconn);
295
    ap_proxy_ssl_disable(backconn);
228
    rc = ap_run_pre_connection(backconn, sock);
296
    rc = ap_run_pre_connection(backconn, sock);
229
    if (rc != OK && rc != DONE) {
297
    if (rc != OK && rc != DONE) {
230
      backconn->aborted = 1;
298
	backconn->aborted = 1;
231
      ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
299
	ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
232
		   "proxy: CONNECT: pre_connection setup failed (%d)", rc);
300
		      "proxy: CONNECT: pre_connection setup failed (%d)", rc);
233
      return HTTP_INTERNAL_SERVER_ERROR;
301
	return HTTP_INTERNAL_SERVER_ERROR;
234
    }
302
    }
235
303
236
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
304
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
237
		 "proxy: CONNECT: connection complete to %pI (%s)",
305
		  "proxy: CONNECT: connection complete to %pI (%s)",
238
		 connect_addr, connectname);
306
		  connect_addr, connectname);
239
307
240
308
241
    /* If we are connecting through a remote proxy, we need to pass
309
    /* If we are connecting through a remote proxy, we need to pass
Lines 244-250 Link Here
244
    if (proxyport) {
312
    if (proxyport) {
245
    /* FIXME: Error checking ignored.
313
    /* FIXME: Error checking ignored.
246
     */
314
     */
247
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
315
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
248
             "proxy: CONNECT: sending the CONNECT request to the remote proxy");
316
             "proxy: CONNECT: sending the CONNECT request to the remote proxy");
249
        ap_fprintf(backconn->output_filters, bb,
317
        ap_fprintf(backconn->output_filters, bb,
250
		   "CONNECT %s HTTP/1.0" CRLF, r->uri);
318
		   "CONNECT %s HTTP/1.0" CRLF, r->uri);
Lines 253-262 Link Here
253
        ap_fflush(backconn->output_filters, bb);
321
        ap_fflush(backconn->output_filters, bb);
254
    }
322
    }
255
    else {
323
    else {
256
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
324
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
257
             "proxy: CONNECT: Returning 200 OK Status");
325
		      "proxy: CONNECT: Returning 200 OK Status");
326
258
        nbytes = apr_snprintf(buffer, sizeof(buffer),
327
        nbytes = apr_snprintf(buffer, sizeof(buffer),
259
                  "HTTP/1.0 200 Connection Established" CRLF);
328
			      "HTTP/1.0 200 Connection Established" CRLF);
260
        ap_xlate_proto_to_ascii(buffer, nbytes);
329
        ap_xlate_proto_to_ascii(buffer, nbytes);
261
        ap_fwrite(c->output_filters, bb, buffer, nbytes);
330
        ap_fwrite(c->output_filters, bb, buffer, nbytes);
262
        nbytes = apr_snprintf(buffer, sizeof(buffer),
331
        nbytes = apr_snprintf(buffer, sizeof(buffer),
Lines 265-271 Link Here
265
        ap_fwrite(c->output_filters, bb, buffer, nbytes);
334
        ap_fwrite(c->output_filters, bb, buffer, nbytes);
266
        ap_fflush(c->output_filters, bb);
335
        ap_fflush(c->output_filters, bb);
267
#if 0
336
#if 0
268
        /* This is safer code, but it doesn't work yet.  I'm leaving it 
337
        /* This is safer code, but it doesn't work yet.  I'm leaving it
269
         * here so that I can fix it later.
338
         * here so that I can fix it later.
270
         */
339
         */
271
        r->status = HTTP_OK;
340
        r->status = HTTP_OK;
Lines 275-320 Link Here
275
#endif
344
#endif
276
    }
345
    }
277
346
278
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
279
         "proxy: CONNECT: setting up poll()");
280
281
    /*
347
    /*
282
     * Step Four: Handle Data Transfer
348
     * Step Four: Handle Data Transfer
283
     *
349
     *
284
     * Handle two way transfer of data over the socket (this is a tunnel).
350
     * Handle two way transfer of data over the socket (this is a tunnel).
285
     */
351
     */
286
352
287
/*    r->sent_bodyct = 1;*/
353
    /* we are now acting as a tunnel - the input/output filter stacks should
288
354
     * not contain any non-connection filters.
289
    if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS)
355
     */
290
    {
356
    r->output_filters = c->output_filters;
291
    apr_socket_close(sock);
357
    r->proto_output_filters = c->output_filters;
292
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
358
    r->input_filters = c->input_filters;
293
            "proxy: CONNECT: error apr_pollset_create()");
359
    r->proto_input_filters = c->input_filters;
294
        return HTTP_INTERNAL_SERVER_ERROR;
295
    }
296
297
    /* Add client side to the poll */
298
    pollfd.p = r->pool;
299
    pollfd.desc_type = APR_POLL_SOCKET;
300
    pollfd.reqevents = APR_POLLIN;
301
    pollfd.desc.s = client_socket;
302
    pollfd.client_data = NULL;
303
    apr_pollset_add(pollset, &pollfd);
304
360
305
    /* Add the server side to the poll */
361
/*    r->sent_bodyct = 1;*/
306
    pollfd.desc.s = sock;
307
    apr_pollset_add(pollset, &pollfd);
308
362
309
    while (1) { /* Infinite loop until error (one side closes the connection) */
363
    /* Infinite loop until error (one side closes the connection) */
310
        if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) {
364
    while (1) {
311
        apr_socket_close(sock);
365
	rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled);
312
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: CONNECT: error apr_poll()");
366
	if (rv != APR_SUCCESS) {
367
	    apr_socket_close(sock);
368
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
369
			  "proxy: CONNECT: error apr_poll()");
313
            return HTTP_INTERNAL_SERVER_ERROR;
370
            return HTTP_INTERNAL_SERVER_ERROR;
314
        }
371
        }
315
#ifdef DEBUGGING
372
#ifdef DEBUGGING
316
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
373
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
317
                     "proxy: CONNECT: woke from select(), i=%d", pollcnt);
374
		      "proxy: CONNECT: woke from poll(), i=%d", pollcnt);
318
#endif
375
#endif
319
376
320
        for (pi = 0; pi < pollcnt; pi++) {
377
        for (pi = 0; pi < pollcnt; pi++) {
Lines 322-410 Link Here
322
379
323
            if (cur->desc.s == sock) {
380
            if (cur->desc.s == sock) {
324
                pollevent = cur->rtnevents;
381
                pollevent = cur->rtnevents;
325
                if (pollevent & APR_POLLIN) {
326
#ifdef DEBUGGING
327
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
328
                                 "proxy: CONNECT: sock was set");
329
#endif
330
                    nbytes = sizeof(buffer);
331
                    apr_brigade_cleanup(bb);
332
                    rv = ap_get_brigade(backconn->input_filters, bb,
333
                                        AP_MODE_READBYTES, APR_NONBLOCK_READ,
334
                                        nbytes);
335
                    if (APR_STATUS_IS_EAGAIN(rv)) {
336
                        rv = APR_SUCCESS;
337
                    } else if (rv != APR_SUCCESS) {
338
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r,
339
                                      "proxy: CONNECT: error on backconn "
340
                                      "- ap_get_brigade");
341
                        break;
342
                    } else {
343
                        rv = ap_pass_brigade(c->output_filters, bb);
344
                        if (rv != APR_SUCCESS) {
345
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
346
                                          "proxy: CONNECT: error on backconn "
347
                                          "- ap_pass_brigade");
348
			    break;
349
			}
350
			ap_fflush(c->output_filters, bb);
351
		    }
352
                }
353
                if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) {
382
                if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) {
354
                    rv = APR_EPIPE;
383
                    rv = APR_EPIPE;
355
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, rv, r,
384
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
356
                                  "proxy: CONNECT: err/hup on backconn");
385
                                  "proxy: CONNECT: err/hup on backconn");
357
                    break;
358
		}
386
		}
387
                if (pollevent & APR_POLLIN) {
388
#ifdef DEBUGGING
389
		    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
390
				  "proxy: CONNECT: sock was readable");
391
#endif
392
		    rv = proxy_connect_transfer(r, backconn, c, bb, "sock");
393
                }
359
            }
394
            }
360
            else if (cur->desc.s == client_socket) {
395
            else if (cur->desc.s == client_socket) {
361
                pollevent = cur->rtnevents;
396
                pollevent = cur->rtnevents;
397
                if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) {
398
                    rv = APR_EOF;
399
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
400
                                  "proxy: CONNECT: err/hup on client socket");
401
                }
362
                if (pollevent & APR_POLLIN) {
402
                if (pollevent & APR_POLLIN) {
363
#ifdef DEBUGGING
403
#ifdef DEBUGGING
364
                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
404
		    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
365
                                 "proxy: CONNECT: client was set");
405
				  "proxy: CONNECT: client was readable");
366
#endif
406
#endif
367
                    nbytes = sizeof(buffer);
407
		    rv = proxy_connect_transfer(r, c, backconn, bb, "client");
368
		    apr_brigade_cleanup(bb);
369
		    rv = ap_get_brigade(c->input_filters, bb,
370
					AP_MODE_READBYTES, APR_NONBLOCK_READ,
371
					nbytes);
372
                    if (rv == APR_SUCCESS) {
373
			i = nbytes;
374
#ifdef DEBUGGING
375
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
376
                                     "proxy: CONNECT: read %d from client", i);
377
#endif
378
			rv = ap_pass_brigade(backconn->output_filters, bb);
379
			if (rv != APR_SUCCESS) {
380
			    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
381
					  "proxy: CONNECT: error on client "
382
					  "ap_pass_brigade");
383
			    break;
384
			}
385
			ap_fflush(backconn->output_filters, bb);
386
		    }
387
		    else if (APR_STATUS_IS_EAGAIN(rv)) {
388
			rv = APR_SUCCESS;
389
		    }
390
		    else {
391
			ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r,
392
				      "proxy: CONNECT: error on client "
393
				      "- ap_get_brigade");
394
                        break;
395
		    }
396
                }
408
                }
397
                if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) {
398
                    rv = APR_EPIPE;
399
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, rv, r,
400
                                  "proxy: CONNECT: err/hup on client socket");
401
                    break;
402
		}
403
            }
409
            }
404
            else {
410
            else {
405
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
411
		rv = APR_EBADF;
406
                             "proxy: CONNECT: unknown socket in pollset");
412
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
407
                break;
413
			      "proxy: CONNECT: unknown socket in pollset");
414
	    }
415
416
	    if (rv != APR_SUCCESS) {
417
		break;
408
	    }
418
	    }
409
        }
419
        }
410
        if (rv != APR_SUCCESS) {
420
        if (rv != APR_SUCCESS) {
Lines 412-419 Link Here
412
        }
422
        }
413
    }
423
    }
414
424
415
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
425
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
416
         "proxy: CONNECT: finished with poll() - cleaning up");
426
		  "proxy: CONNECT: finished with poll() - cleaning up");
417
427
418
    /*
428
    /*
419
     * Step Five: Clean Up
429
     * Step Five: Clean Up
Lines 423-428 Link Here
423
433
424
    ap_lingering_close(backconn);
434
    ap_lingering_close(backconn);
425
435
436
    c->aborted = 1;
437
426
    return OK;
438
    return OK;
427
}
439
}
428
440

Return to bug 29744