proxy_connect.c revision a2f9f38db0931e6edf7b71378dd680c3c5fa5841
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* ====================================================================
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * The Apache Software License, Version 1.1
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Copyright (c) 2000 The Apache Software Foundation. All rights
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * reserved.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Redistribution and use in source and binary forms, with or without
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * modification, are permitted provided that the following conditions
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * are met:
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 1. Redistributions of source code must retain the above copyright
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * notice, this list of conditions and the following disclaimer.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 2. Redistributions in binary form must reproduce the above copyright
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * notice, this list of conditions and the following disclaimer in
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the documentation and/or other materials provided with the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * distribution.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 3. The end-user documentation included with the redistribution,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * if any, must include the following acknowledgment:
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * "This product includes software developed by the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Apache Software Foundation (http://www.apache.org/)."
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Alternately, this acknowledgment may appear in the software itself,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * if and wherever such third-party acknowledgments normally appear.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 4. The names "Apache" and "Apache Software Foundation" must
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * not be used to endorse or promote products derived from this
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * software without prior written permission. For written
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * permission, please contact apache@apache.org.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 5. Products derived from this software may not be called "Apache",
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * nor may "Apache" appear in their name, without prior written
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * permission of the Apache Software Foundation.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * SUCH DAMAGE.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ====================================================================
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This software consists of voluntary contributions made by many
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * individuals on behalf of the Apache Software Foundation. For more
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * information on the Apache Software Foundation, please see
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * <http://www.apache.org/>.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Portions of this software are based upon public domain software
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * originally written at the National Center for Supercomputing Applications,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * University of Illinois, Urbana-Champaign.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* CONNECT method for Apache proxy */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "apr_strings.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "mod_proxy.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "http_log.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "http_main.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#ifdef HAVE_BSTRING_H
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This handles Netscape CONNECT method secure proxy requests.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * A connection is opened to the specified host and data is
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * passed through between the WWW site and the browser.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This code is based on the INTERNET-DRAFT document
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * "Tunneling SSL Through a WWW Proxy" currently at
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * http://www.mcom.com/newsref/std/tunneling_ssl.html.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * If proxyhost and proxyport are set, we send a CONNECT to
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the specified proxy..
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * FIXME: this is bad, because it does its own socket I/O
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * instead of using the I/O in buff.c. However,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the I/O in buff.c blocks on reads, and because
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * this function doesn't know how much data will
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * be sent either way (or when) it can't use blocking
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * I/O. This may be very implementation-specific
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * (to Linux). Any suggestions?
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * FIXME: this doesn't log the number of bytes sent, but
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * that may be okay, since the data is supposed to
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * be transparent. In fact, this doesn't log at all
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * yet. 8^)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * FIXME: doesn't check any headers initally sent from the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * client.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * FIXME: should allow authentication, but hopefully the
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe * generic proxy authentication is good enough.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * FIXME: no check for r->assbackwards, whatever that is.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic int
b38846b15c8891c6dec44dcc4f96ca40721bf663rbballowed_port(proxy_server_conf *conf, int port)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b45c1c292ff1fa635004ae81fa691f8cb3cdda85rbb int i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int *list = (int *) conf->allowed_connect_ports->elts;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for(i = 0; i < conf->allowed_connect_ports->nelts; i++) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if(port == list[i])
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe return 1;
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return 0;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbint ap_proxy_connect_handler(request_rec *r, ap_cache_el *c, char *url,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *proxyhost, int proxyport)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb struct in_addr destaddr;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *host;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *p;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int port;
c3e342e5b0b9fea6617ee16d2da02c3ef2108126dougm apr_socket_t *sock;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char buffer[HUGE_STRING_LEN];
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe int nbytes, i;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe BUFF *sock_buff;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_socket_t *client_sock=NULL;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_pollfd_t *pollfd;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar apr_int32_t pollcnt;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_int16_t pollevent;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar void *sconf = r->server->module_config;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe proxy_server_conf *conf =
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* Break the URL into host:port pairs */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe host = url;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe p = strchr(url, ':');
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (p == NULL)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe port = DEFAULT_HTTPS_PORT;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe port = atoi(p + 1);
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames *p = '\0';
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/* check if ProxyBlock directive on this host */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe destaddr.s_addr = apr_inet_addr(host);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe for (i = 0; i < conf->noproxies->nelts; i++) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if ((npent[i].name != NULL && ap_strstr_c(host, npent[i].name) != NULL)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*')
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return ap_proxyerror(r, HTTP_FORBIDDEN,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe "Connect to remote machine blocked");
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* Check if it is an allowed port */
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames if (conf->allowed_connect_ports->nelts == 0) {
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames /* Default setting if not overridden by AllowCONNECT */
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames switch (port) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe case DEFAULT_HTTPS_PORT:
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar case DEFAULT_SNEWS_PORT:
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe break;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe default:
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe return HTTP_FORBIDDEN;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe } else if(!allowed_port(conf, port))
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe return HTTP_FORBIDDEN;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (proxyhost) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe else {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe "CONNECT to %s on port %d", host, port);
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
4775dfc34c90fada8c7c4d6a57ed8a3114d55c2dtrawick if ((apr_create_tcp_socket(&sock, r->pool)) != APR_SUCCESS) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe "proxy: error creating socket");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe return HTTP_INTERNAL_SERVER_ERROR;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (ap_proxy_doconnect(sock, (char *)(proxyhost ? proxyhost : host), proxyport ? proxyport : port, r) == -1) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_close_socket(sock);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_pstrcat(r->pool, "Could not connect to remote machine:<br>",
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe strerror(errno), NULL));
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* If we are connecting through a remote proxy, we need to pass
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * the CONNECT request on to it.
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (proxyport) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* FIXME: We should not be calling write() directly, but we currently
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * have no alternative. Error checking ignored. Also, we force
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * a HTTP/1.0 request to keep things simple.
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe */
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe "Sending the CONNECT request to the remote proxy");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe nbytes = apr_snprintf(buffer, sizeof(buffer), "CONNECT %s HTTP/1.0" CRLF, r->uri);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_send(sock, buffer, &nbytes);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe nbytes = apr_snprintf(buffer, sizeof(buffer),"Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_send(sock, buffer, &nbytes);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe else {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe "Returning 200 OK Status");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_rvputs(r, "HTTP/1.0 200 Connection established" CRLF, NULL);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_rvputs(r, "Proxy-agent: ", ap_get_server_version(), CRLF CRLF, NULL);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar ap_bflush(r->connection->client);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe sock_buff = ap_bcreate(r->pool, B_RDWR);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_bpush_socket(sock_buff, sock);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if(apr_setup_poll(&pollfd, 2, r->pool) != APR_SUCCESS)
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: error apr_setup_poll()");
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return HTTP_INTERNAL_SERVER_ERROR;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
c2cf53a40a9814eb91db2cdf820f97d943f21628coar /* Add client side to the poll */
c2cf53a40a9814eb91db2cdf820f97d943f21628coar#if 0
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe/* FIXME !!!! SDM !!! If someone can figure out how to turn a conn_rec into a ap_sock_t or something
c2cf53a40a9814eb91db2cdf820f97d943f21628coar this code might work. However if we must we can change r->connection->client to non-blocking and
c2cf53a40a9814eb91db2cdf820f97d943f21628coar just see if a recv gives us anything and do the same to sock (server) side, I'll leave this as TBD so
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe one can decide the best path to take
c2cf53a40a9814eb91db2cdf820f97d943f21628coar*/
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if(apr_put_os_sock(&client_sock, (apr_os_sock_t *)get_socket(r->connection->client),
c2cf53a40a9814eb91db2cdf820f97d943f21628coar r->pool) != APR_SUCCESS)
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: error creating client apr_socket_t");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe return HTTP_INTERNAL_SERVER_ERROR;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe apr_add_poll_socket(pollfd, client_sock, APR_POLLIN);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe#endif
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
c2cf53a40a9814eb91db2cdf820f97d943f21628coar /* Add the server side to the poll */
c2cf53a40a9814eb91db2cdf820f97d943f21628coar apr_add_poll_socket(pollfd, sock, APR_POLLIN);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
c2cf53a40a9814eb91db2cdf820f97d943f21628coar while (1) { /* Infinite loop until error (one side closes the connection) */
c2cf53a40a9814eb91db2cdf820f97d943f21628coar ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, "Going to sleep (poll)");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if(apr_poll(pollfd, &pollcnt, -1) != APR_SUCCESS)
c2cf53a40a9814eb91db2cdf820f97d943f21628coar {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: error apr_poll()");
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return HTTP_INTERNAL_SERVER_ERROR;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
c2cf53a40a9814eb91db2cdf820f97d943f21628coar "Woke from select(), i=%d", pollcnt);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (pollcnt) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar apr_get_revents(&pollevent, sock, pollfd);
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (pollevent & APR_POLLIN) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe "sock was set");
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if(ap_bread(sock_buff, buffer, HUGE_STRING_LEN, &nbytes) == APR_SUCCESS) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe int o = 0;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe while(nbytes)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_bwrite(r->connection->client, buffer + o, nbytes, &i);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe o += i;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe nbytes -= i;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe "Wrote %d bytes to client", nbytes);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe break;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_get_revents(&pollevent, client_sock, pollfd);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (pollevent & APR_POLLIN) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe "client was set");
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if(ap_bread(r->connection->client, buffer, HUGE_STRING_LEN, &nbytes) == APR_SUCCESS) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe int o = 0;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe while(nbytes)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_bwrite(sock_buff, buffer + o, nbytes, &i);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe o += i;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe nbytes -= i;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe "Wrote %d bytes to server", nbytes);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe else
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe break;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe else
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe break;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
0540a0b469147b52e858587270dba31c2aaa9e09wrowe apr_close_socket(sock);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe return OK;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe}
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe