ASF Bugzilla – Attachment 20379 Details for
Bug 29744
CONNECT does not work over existing SSL connection
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Port of the patch from 2.2.2 to 2.2.4
connect_ssh_over_https.patch (text/plain), 15.02 KB, created by
David GENCE
on 2007-06-21 06:00:37 UTC
(
hide
)
Description:
Port of the patch from 2.2.2 to 2.2.4
Filename:
MIME Type:
Creator:
David GENCE
Created:
2007-06-21 06:00:37 UTC
Size:
15.02 KB
patch
obsolete
>diff -cr httpd-2.2.4.ori/modules/proxy/mod_proxy_connect.c httpd-2.2.4/modules/proxy/mod_proxy_connect.c >*** httpd-2.2.4.ori/modules/proxy/mod_proxy_connect.c 2006-09-15 15:19:25.000000000 +0200 >--- httpd-2.2.4/modules/proxy/mod_proxy_connect.c 2007-06-21 14:30:42.000000000 +0200 >*************** >*** 21,26 **** >--- 21,28 ---- > #include "mod_proxy.h" > #include "apr_poll.h" > >+ #define CONN_BLKSZ AP_IOBUFSIZE >+ > module AP_MODULE_DECLARE_DATA proxy_connect_module; > > /* >*************** >*** 71,76 **** >--- 73,122 ---- > return OK; > } > >+ /* read available data (in blocks of CONN_BLKSZ) from c_i and copy to c_o */ >+ static int proxy_connect_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o, >+ apr_bucket_brigade *bb, char *name) >+ { >+ int rv; >+ #ifdef DEBUGGING >+ apr_off_t len; >+ #endif >+ >+ do { >+ apr_brigade_cleanup(bb); >+ rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES, >+ APR_NONBLOCK_READ, CONN_BLKSZ); >+ if (rv == APR_SUCCESS) { >+ if (APR_BRIGADE_EMPTY(bb)) >+ break; >+ #ifdef DEBUGGING >+ len = -1; >+ apr_brigade_length(bb, 0, &len); >+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, >+ "proxy: CONNECT: read %" APR_OFF_T_FMT >+ " bytes from %s", len, name); >+ #endif >+ rv = ap_pass_brigade(c_o->output_filters, bb); >+ if (rv == APR_SUCCESS) { >+ ap_fflush(c_o->output_filters, bb); >+ } else { >+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, >+ "proxy: CONNECT: error on %s - ap_pass_brigade", >+ name); >+ } >+ } else if (!APR_STATUS_IS_EAGAIN(rv)) { >+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, >+ "proxy: CONNECT: error on %s - ap_get_brigade", >+ name); >+ } >+ } while (rv == APR_SUCCESS); >+ >+ if (APR_STATUS_IS_EAGAIN(rv)) { >+ rv = APR_SUCCESS; >+ } >+ return rv; >+ } >+ > /* CONNECT handler */ > static int proxy_connect_handler(request_rec *r, proxy_worker *worker, > proxy_server_conf *conf, >*************** >*** 79,89 **** > { > apr_pool_t *p = r->pool; > apr_socket_t *sock; > apr_status_t err, rv; >! apr_size_t i, o, nbytes; > char buffer[HUGE_STRING_LEN]; >! apr_socket_t *client_socket = ap_get_module_config(r->connection->conn_config, &core_module); >! int failed; > apr_pollset_t *pollset; > apr_pollfd_t pollfd; > const apr_pollfd_t *signalled; >--- 125,139 ---- > { > apr_pool_t *p = r->pool; > apr_socket_t *sock; >+ conn_rec *c = r->connection; >+ conn_rec *backconn; >+ >+ apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc); > apr_status_t err, rv; >! apr_size_t nbytes; > char buffer[HUGE_STRING_LEN]; >! apr_socket_t *client_socket = ap_get_module_config(c->conn_config, &core_module); >! int failed, rc; > apr_pollset_t *pollset; > apr_pollfd_t pollfd; > const apr_pollfd_t *signalled; >*************** >*** 151,162 **** > case APR_URI_SNEWS_DEFAULT_PORT: > break; > default: >! /* XXX can we call ap_proxyerror() here to get a nice log message? */ >! return HTTP_FORBIDDEN; > } > } else if(!allowed_port(conf, uri.port)) { >! /* XXX can we call ap_proxyerror() here to get a nice log message? */ >! return HTTP_FORBIDDEN; > } > > /* >--- 201,210 ---- > case APR_URI_SNEWS_DEFAULT_PORT: > break; > default: >! return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); > } > } else if(!allowed_port(conf, uri.port)) { >! return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); > } > > /* >*************** >*** 198,215 **** > } > } > > /* > * Step Three: Send the Request > * > * Send the HTTP/1.1 CONNECT request to the remote server > */ > >! /* we are acting as a tunnel - the output filter stack should >! * be completely empty, because when we are done here we are done completely. >! * We add the NULL filter to the stack to do this... >! */ >! r->output_filters = NULL; >! r->connection->output_filters = NULL; > > > /* If we are connecting through a remote proxy, we need to pass >--- 246,302 ---- > } > } > >+ /* setup polling for connection */ >+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, >+ "proxy: CONNECT: setting up poll()"); >+ >+ if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) { >+ apr_socket_close(sock); >+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, >+ "proxy: CONNECT: error apr_pollset_create()"); >+ return HTTP_INTERNAL_SERVER_ERROR; >+ } >+ >+ /* Add client side to the poll */ >+ pollfd.p = r->pool; >+ pollfd.desc_type = APR_POLL_SOCKET; >+ pollfd.reqevents = APR_POLLIN; >+ pollfd.desc.s = client_socket; >+ pollfd.client_data = NULL; >+ apr_pollset_add(pollset, &pollfd); >+ >+ /* Add the server side to the poll */ >+ pollfd.desc.s = sock; >+ apr_pollset_add(pollset, &pollfd); >+ > /* > * Step Three: Send the Request > * > * Send the HTTP/1.1 CONNECT request to the remote server > */ > >! backconn = ap_run_create_connection(c->pool, r->server, sock, >! c->id, c->sbh, c->bucket_alloc); >! if (!backconn) { >! /* peer reset */ >! ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, >! "proxy: an error occurred creating a new connection " >! "to %pI (%s)", connect_addr, connectname); >! apr_socket_close(sock); >! return HTTP_INTERNAL_SERVER_ERROR; >! } >! ap_proxy_ssl_disable(backconn); >! rc = ap_run_pre_connection(backconn, sock); >! if (rc != OK && rc != DONE) { >! backconn->aborted = 1; >! ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, >! "proxy: CONNECT: pre_connection setup failed (%d)", rc); >! return HTTP_INTERNAL_SERVER_ERROR; >! } >! >! ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, >! "proxy: CONNECT: connection complete to %pI (%s)", >! connect_addr, connectname); > > > /* If we are connecting through a remote proxy, we need to pass >*************** >*** 220,231 **** > */ > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, > "proxy: CONNECT: sending the CONNECT request to the remote proxy"); >! nbytes = apr_snprintf(buffer, sizeof(buffer), > "CONNECT %s HTTP/1.0" CRLF, r->uri); >! apr_socket_send(sock, buffer, &nbytes); >! nbytes = apr_snprintf(buffer, sizeof(buffer), >! "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); >! apr_socket_send(sock, buffer, &nbytes); > } > else { > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >--- 307,317 ---- > */ > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, > "proxy: CONNECT: sending the CONNECT request to the remote proxy"); >! ap_fprintf(backconn->output_filters, bb, > "CONNECT %s HTTP/1.0" CRLF, r->uri); >! ap_fprintf(backconn->output_filters, bb, >! "Proxy-agent: %s" CRLF CRLF, ap_get_server_version()); >! ap_fflush(backconn->output_filters, bb); > } > else { > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >*************** >*** 233,243 **** > nbytes = apr_snprintf(buffer, sizeof(buffer), > "HTTP/1.0 200 Connection Established" CRLF); > ap_xlate_proto_to_ascii(buffer, nbytes); >! apr_socket_send(client_socket, buffer, &nbytes); > nbytes = apr_snprintf(buffer, sizeof(buffer), > "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); > ap_xlate_proto_to_ascii(buffer, nbytes); >! apr_socket_send(client_socket, buffer, &nbytes); > #if 0 > /* This is safer code, but it doesn't work yet. I'm leaving it > * here so that I can fix it later. >--- 319,330 ---- > nbytes = apr_snprintf(buffer, sizeof(buffer), > "HTTP/1.0 200 Connection Established" CRLF); > ap_xlate_proto_to_ascii(buffer, nbytes); >! ap_fwrite(c->output_filters, bb, buffer, nbytes); > nbytes = apr_snprintf(buffer, sizeof(buffer), > "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); > ap_xlate_proto_to_ascii(buffer, nbytes); >! ap_fwrite(c->output_filters, bb, buffer, nbytes); >! ap_fflush(c->output_filters, bb); > #if 0 > /* This is safer code, but it doesn't work yet. I'm leaving it > * here so that I can fix it later. >*************** >*** 258,284 **** > * Handle two way transfer of data over the socket (this is a tunnel). > */ > >! /* r->sent_bodyct = 1;*/ >! >! if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) >! { >! apr_socket_close(sock); >! ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, >! "proxy: CONNECT: error apr_pollset_create()"); >! return HTTP_INTERNAL_SERVER_ERROR; >! } >! >! /* Add client side to the poll */ >! pollfd.p = r->pool; >! pollfd.desc_type = APR_POLL_SOCKET; >! pollfd.reqevents = APR_POLLIN; >! pollfd.desc.s = client_socket; >! pollfd.client_data = NULL; >! apr_pollset_add(pollset, &pollfd); >! >! /* Add the server side to the poll */ >! pollfd.desc.s = sock; >! apr_pollset_add(pollset, &pollfd); > > while (1) { /* Infinite loop until error (one side closes the connection) */ > if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) { >--- 345,358 ---- > * Handle two way transfer of data over the socket (this is a tunnel). > */ > >! /* we are now acting as a tunnel - the input/output filter stacks should >! * not contain any non-connection filters. >! */ >! r->output_filters = c->output_filters; >! r->proto_output_filters = c->output_filters; >! r->input_filters = c->input_filters; >! r->proto_input_filters = c->input_filters; >! /* r->sent_bodyct = 1;*/ > > while (1) { /* Infinite loop until error (one side closes the connection) */ > if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) { >*************** >*** 288,294 **** > } > #ifdef DEBUGGING > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >! "proxy: CONNECT: woke from select(), i=%d", pollcnt); > #endif > > for (pi = 0; pi < pollcnt; pi++) { >--- 362,368 ---- > } > #ifdef DEBUGGING > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >! "proxy: CONNECT: woke from poll(), i=%d", pollcnt); > #endif > > for (pi = 0; pi < pollcnt; pi++) { >*************** >*** 298,369 **** > pollevent = cur->rtnevents; > if (pollevent & APR_POLLIN) { > #ifdef DEBUGGING >! ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >! "proxy: CONNECT: sock was set"); > #endif >! nbytes = sizeof(buffer); >! rv = apr_socket_recv(sock, buffer, &nbytes); >! if (rv == APR_SUCCESS) { >! o = 0; >! i = nbytes; >! while(i > 0) >! { >! nbytes = i; >! /* This is just plain wrong. No module should ever write directly >! * to the client. For now, this works, but this is high on my list of >! * things to fix. The correct line is: >! * if ((nbytes = ap_rwrite(buffer + o, nbytes, r)) < 0) >! * rbb >! */ >! rv = apr_socket_send(client_socket, buffer + o, &nbytes); >! if (rv != APR_SUCCESS) >! break; >! o += nbytes; >! i -= nbytes; >! } >! } >! else >! break; > } >! else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) >! break; > } > else if (cur->desc.s == client_socket) { > pollevent = cur->rtnevents; > if (pollevent & APR_POLLIN) { > #ifdef DEBUGGING >! ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >! "proxy: CONNECT: client was set"); > #endif >! nbytes = sizeof(buffer); >! rv = apr_socket_recv(client_socket, buffer, &nbytes); >! if (rv == APR_SUCCESS) { >! o = 0; >! i = nbytes; >! #ifdef DEBUGGING >! ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >! "proxy: CONNECT: read %d from client", i); >! #endif >! while(i > 0) >! { >! nbytes = i; >! rv = apr_socket_send(sock, buffer + o, &nbytes); >! if (rv != APR_SUCCESS) >! break; >! o += nbytes; >! i -= nbytes; >! } >! } >! else >! break; >! } >! else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) { >! rv = APR_EOF; >! break; > } > } >! else >! break; > } > if (rv != APR_SUCCESS) { > break; >--- 372,403 ---- > pollevent = cur->rtnevents; > if (pollevent & APR_POLLIN) { > #ifdef DEBUGGING >! ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, >! "proxy: CONNECT: sock was readable"); > #endif >! rv = proxy_connect_transfer(r, backconn, c, bb, "sock"); > } >! else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) { >! rv = APR_EPIPE; >! ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "proxy: CONNECT: err/hup on backconn"); >! } > } > else if (cur->desc.s == client_socket) { > pollevent = cur->rtnevents; > if (pollevent & APR_POLLIN) { > #ifdef DEBUGGING >! ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, >! "proxy: CONNECT: client was readable"); > #endif >! rv = proxy_connect_transfer(r, c, backconn, bb, "client"); > } > } >! else { >! rv = APR_EBADF; >! ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, >! "proxy: CONNECT: unknown socket in pollset"); >! } >! > } > if (rv != APR_SUCCESS) { > break; >*************** >*** 379,385 **** > * Close the socket and clean up > */ > >! apr_socket_close(sock); > > return OK; > } >--- 413,421 ---- > * Close the socket and clean up > */ > >! ap_lingering_close(backconn); >! >! c->aborted = 1; > > return OK; > } >Seulement dans httpd-2.2.4/modules/proxy: mod_proxy_connect.c.orig
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 29744
:
13393
|
14066
|
16105
|
18222
|
19504
|
19723
|
20331
| 20379 |
20911
|
20946
|
21628
|
21703
|
22248
|
22877
|
23840
|
24252
|
24615
|
24616
|
26225
|
29072
|
30144