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

(-)httpd-2.1.6-alpha/modules/proxy/mod_proxy_connect.c (-50 / +94 lines)
Lines 79-89 Link Here
79
{
79
{
80
    apr_pool_t *p = r->pool;
80
    apr_pool_t *p = r->pool;
81
    apr_socket_t *sock;
81
    apr_socket_t *sock;
82
    conn_rec *c = r->connection;
83
    conn_rec *backconn;
84
    apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
85
82
    apr_status_t err, rv;
86
    apr_status_t err, rv;
83
    apr_size_t i, o, nbytes;
87
    apr_size_t i, o, nbytes;
84
    char buffer[HUGE_STRING_LEN];
88
    char buffer[HUGE_STRING_LEN];
85
    apr_socket_t *client_socket = ap_get_module_config(r->connection->conn_config, &core_module);
89
    apr_socket_t *client_socket = ap_get_module_config(c->conn_config, &core_module);
86
    int failed;
90
    int failed, rc;
87
    apr_pollset_t *pollset;
91
    apr_pollset_t *pollset;
88
    apr_pollfd_t pollfd;
92
    apr_pollfd_t pollfd;
89
    const apr_pollfd_t *signalled;
93
    const apr_pollfd_t *signalled;
Lines 209-215 Link Here
209
     * We add the NULL filter to the stack to do this...
213
     * We add the NULL filter to the stack to do this...
210
     */
214
     */
211
    r->output_filters = NULL;
215
    r->output_filters = NULL;
212
    r->connection->output_filters = NULL;
216
217
    backconn = ap_run_create_connection(c->pool, r->server, sock,
218
					c->id, c->sbh, c->bucket_alloc);
219
    if (!backconn) {
220
	/* peer reset */
221
	ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
222
		     "proxy: an error occurred creating a new connection "
223
		     "to %pI (%s)", connect_addr, connectname);
224
	apr_socket_close(sock);
225
	return HTTP_INTERNAL_SERVER_ERROR;
226
    }
227
    ap_proxy_ssl_disable(backconn);
228
    rc = ap_run_pre_connection(backconn, sock);
229
    if (rc != OK && rc != DONE) {
230
      backconn->aborted = 1;
231
      ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
232
		   "proxy: CONNECT: pre_connection setup failed (%d)", rc);
233
      return HTTP_INTERNAL_SERVER_ERROR;
234
    }
235
236
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
237
		 "proxy: CONNECT: connection complete to %pI (%s)",
238
		 connect_addr, connectname);
213
239
214
240
215
    /* If we are connecting through a remote proxy, we need to pass
241
    /* If we are connecting through a remote proxy, we need to pass
Lines 220-231 Link Here
220
     */
246
     */
221
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
247
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
222
             "proxy: CONNECT: sending the CONNECT request to the remote proxy");
248
             "proxy: CONNECT: sending the CONNECT request to the remote proxy");
223
        nbytes = apr_snprintf(buffer, sizeof(buffer),
249
        ap_fprintf(backconn->output_filters, bb,
224
                  "CONNECT %s HTTP/1.0" CRLF, r->uri);
250
		   "CONNECT %s HTTP/1.0" CRLF, r->uri);
225
        apr_socket_send(sock, buffer, &nbytes);
251
        ap_fprintf(backconn->output_filters, bb,
226
        nbytes = apr_snprintf(buffer, sizeof(buffer),
252
		   "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
227
                  "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
253
        ap_fflush(backconn->output_filters, bb);
228
        apr_socket_send(sock, buffer, &nbytes);
229
    }
254
    }
230
    else {
255
    else {
231
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
256
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
Lines 233-243 Link Here
233
        nbytes = apr_snprintf(buffer, sizeof(buffer),
258
        nbytes = apr_snprintf(buffer, sizeof(buffer),
234
                  "HTTP/1.0 200 Connection Established" CRLF);
259
                  "HTTP/1.0 200 Connection Established" CRLF);
235
        ap_xlate_proto_to_ascii(buffer, nbytes);
260
        ap_xlate_proto_to_ascii(buffer, nbytes);
236
        apr_socket_send(client_socket, buffer, &nbytes);
261
        ap_fwrite(c->output_filters, bb, buffer, nbytes);
237
        nbytes = apr_snprintf(buffer, sizeof(buffer),
262
        nbytes = apr_snprintf(buffer, sizeof(buffer),
238
                  "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
263
                  "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
239
        ap_xlate_proto_to_ascii(buffer, nbytes);
264
        ap_xlate_proto_to_ascii(buffer, nbytes);
240
        apr_socket_send(client_socket, buffer, &nbytes);
265
        ap_fwrite(c->output_filters, bb, buffer, nbytes);
266
        ap_fflush(c->output_filters, bb);
241
#if 0
267
#if 0
242
        /* This is safer code, but it doesn't work yet.  I'm leaving it 
268
        /* This is safer code, but it doesn't work yet.  I'm leaving it 
243
         * here so that I can fix it later.
269
         * here so that I can fix it later.
Lines 302-332 Link Here
302
                                 "proxy: CONNECT: sock was set");
328
                                 "proxy: CONNECT: sock was set");
303
#endif
329
#endif
304
                    nbytes = sizeof(buffer);
330
                    nbytes = sizeof(buffer);
305
                    rv = apr_socket_recv(sock, buffer, &nbytes);
331
                    apr_brigade_cleanup(bb);
306
                    if (rv == APR_SUCCESS) {
332
                    rv = ap_get_brigade(backconn->input_filters, bb,
307
                        o = 0;
333
                                        AP_MODE_READBYTES, APR_NONBLOCK_READ,
308
                        i = nbytes;
334
                                        nbytes);
309
                        while(i > 0)
335
                    if (APR_STATUS_IS_EAGAIN(rv)) {
310
                        {
336
                        rv = APR_SUCCESS;
311
                            nbytes = i;
337
                    } else if (rv != APR_SUCCESS) {
312
    /* This is just plain wrong.  No module should ever write directly
338
                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r,
313
     * to the client.  For now, this works, but this is high on my list of
339
                                      "proxy: CONNECT: error on backconn "
314
     * things to fix.  The correct line is:
340
                                      "- ap_get_brigade");
315
     * if ((nbytes = ap_rwrite(buffer + o, nbytes, r)) < 0)
316
     * rbb
317
     */
318
                            rv = apr_socket_send(client_socket, buffer + o, &nbytes);
319
                            if (rv != APR_SUCCESS)
320
                                break;
321
                            o += nbytes;
322
                            i -= nbytes;
323
                        }
324
                    }
325
                    else
326
                        break;
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
		    }
327
                }
352
                }
328
                else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP))
353
                if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) {
354
                    rv = APR_EPIPE;
355
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, rv, r,
356
                                  "proxy: CONNECT: err/hup on backconn");
329
                    break;
357
                    break;
358
		}
330
            }
359
            }
331
            else if (cur->desc.s == client_socket) {
360
            else if (cur->desc.s == client_socket) {
332
                pollevent = cur->rtnevents;
361
                pollevent = cur->rtnevents;
Lines 336-367 Link Here
336
                                 "proxy: CONNECT: client was set");
365
                                 "proxy: CONNECT: client was set");
337
#endif
366
#endif
338
                    nbytes = sizeof(buffer);
367
                    nbytes = sizeof(buffer);
339
                    rv = apr_socket_recv(client_socket, buffer, &nbytes);
368
		    apr_brigade_cleanup(bb);
369
		    rv = ap_get_brigade(c->input_filters, bb,
370
					AP_MODE_READBYTES, APR_NONBLOCK_READ,
371
					nbytes);
340
                    if (rv == APR_SUCCESS) {
372
                    if (rv == APR_SUCCESS) {
341
                        o = 0;
373
			i = nbytes;
342
                        i = nbytes;
343
#ifdef DEBUGGING
374
#ifdef DEBUGGING
344
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
375
                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
345
                                     "proxy: CONNECT: read %d from client", i);
376
                                     "proxy: CONNECT: read %d from client", i);
346
#endif
377
#endif
347
                        while(i > 0)
378
			rv = ap_pass_brigade(backconn->output_filters, bb);
348
                        {
379
			if (rv != APR_SUCCESS) {
349
                            nbytes = i;
380
			    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
350
                            rv = apr_socket_send(sock, buffer + o, &nbytes);
381
					  "proxy: CONNECT: error on client "
351
                            if (rv != APR_SUCCESS)
382
					  "ap_pass_brigade");
352
                                break;
383
			    break;
353
                            o += nbytes;
384
			}
354
                            i -= nbytes;
385
			ap_fflush(backconn->output_filters, bb);
355
                        }
386
		    }
356
                    }
387
		    else if (APR_STATUS_IS_EAGAIN(rv)) {
357
                    else
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");
358
                        break;
394
                        break;
395
		    }
359
                }
396
                }
360
                else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP))
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");
361
                    break;
401
                    break;
402
		}
362
            }
403
            }
363
            else
404
            else {
405
                ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
406
                             "proxy: CONNECT: unknown socket in pollset");
364
                break;
407
                break;
408
	    }
365
        }
409
        }
366
        if (rv != APR_SUCCESS) {
410
        if (rv != APR_SUCCESS) {
367
            break;
411
            break;
Lines 377-383 Link Here
377
     * Close the socket and clean up
421
     * Close the socket and clean up
378
     */
422
     */
379
423
380
    apr_socket_close(sock);
424
    ap_lingering_close(backconn);
381
425
382
    return OK;
426
    return OK;
383
}
427
}

Return to bug 29744