/* CONNECT method for Apache proxy */
-#include "apr_strings.h"
#include "mod_proxy.h"
#include "http_log.h"
#include "http_main.h"
#ifdef HAVE_BSTRING_H
-#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
+#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
#endif
/*
int *list = (int *) conf->allowed_connect_ports->elts;
for(i = 0; i < conf->allowed_connect_ports->nelts; i++) {
- if(port == list[i])
- return 1;
+ if(port == list[i])
+ return 1;
}
return 0;
}
int ap_proxy_connect_handler(request_rec *r, ap_cache_el *c, char *url,
- const char *proxyhost, int proxyport)
+ const char *proxyhost, int proxyport)
{
struct in_addr destaddr;
const char *host;
int nbytes, i;
BUFF *sock_buff;
- apr_socket_t *client_sock=NULL;
+ apr_socket_t *client_sock = NULL;
apr_pollfd_t *pollfd;
apr_int32_t pollcnt;
apr_int16_t pollevent;
host = url;
p = strchr(url, ':');
if (p == NULL)
- port = DEFAULT_HTTPS_PORT;
+ port = DEFAULT_HTTPS_PORT;
else {
- port = atoi(p + 1);
- *p = '\0';
+ port = atoi(p + 1);
+ *p = '\0';
}
/* check if ProxyBlock directive on this host */
- destaddr.s_addr = apr_inet_addr(host);
+ destaddr.s_addr = ap_inet_addr(host);
for (i = 0; i < conf->noproxies->nelts; i++) {
- if ((npent[i].name != NULL && ap_strstr_c(host, npent[i].name) != NULL)
- || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*')
- return ap_proxyerror(r, HTTP_FORBIDDEN,
- "Connect to remote machine blocked");
+ if ((npent[i].name != NULL && ap_strstr_c(host, npent[i].name) != NULL)
+ || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*')
+ return ap_proxyerror(r, HTTP_FORBIDDEN,
+ "Connect to remote machine blocked");
}
/* Check if it is an allowed port */
if (conf->allowed_connect_ports->nelts == 0) {
- /* Default setting if not overridden by AllowCONNECT */
- switch (port) {
- case DEFAULT_HTTPS_PORT:
- case DEFAULT_SNEWS_PORT:
- break;
- default:
- return HTTP_FORBIDDEN;
- }
+ /* Default setting if not overridden by AllowCONNECT */
+ switch (port) {
+ case DEFAULT_HTTPS_PORT:
+ case DEFAULT_SNEWS_PORT:
+ break;
+ default:
+ return HTTP_FORBIDDEN;
+ }
} else if(!allowed_port(conf, port))
- return HTTP_FORBIDDEN;
+ return HTTP_FORBIDDEN;
if (proxyhost) {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
+ "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
}
else {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "CONNECT to %s on port %d", host, port);
+ "CONNECT to %s on port %d", host, port);
}
if ((apr_create_tcp_socket(&sock, r->pool)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error creating socket");
+ "proxy: error creating socket");
return HTTP_INTERNAL_SERVER_ERROR;
}
- if (ap_proxy_doconnect(sock, (char *)(proxyhost ? proxyhost : host), proxyport ? proxyport : port, r) == -1) {
+ if (ap_proxy_doconnect(sock, (char *)(proxyhost ? proxyhost : host),
+ proxyport ? proxyport : port, r) == -1) {
apr_close_socket(sock);
return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
- apr_pstrcat(r->pool, "Could not connect to remote machine:<br>",
- strerror(errno), NULL));
+ apr_pstrcat(r->pool, "Could not connect to remote machine:<br>",
+ strerror(errno), NULL));
}
/* If we are connecting through a remote proxy, we need to pass
* the CONNECT request on to it.
*/
if (proxyport) {
- /* FIXME: We should not be calling write() directly, but we currently
- * have no alternative. Error checking ignored. Also, we force
- * a HTTP/1.0 request to keep things simple.
- */
+ /* FIXME: We should not be calling write() directly, but we currently
+ * have no alternative. Error checking ignored. Also, we force
+ * a HTTP/1.0 request to keep things simple.
+ */
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "Sending the CONNECT request to the remote proxy");
- nbytes = apr_snprintf(buffer, sizeof(buffer), "CONNECT %s HTTP/1.0" CRLF, r->uri);
+ "Sending the CONNECT request to the remote proxy");
+ nbytes = apr_snprintf(buffer, sizeof(buffer),
+ "CONNECT %s HTTP/1.0" CRLF, r->uri);
apr_send(sock, buffer, &nbytes);
- nbytes = apr_snprintf(buffer, sizeof(buffer),"Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
+ nbytes = apr_snprintf(buffer, sizeof(buffer),
+ "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
apr_send(sock, buffer, &nbytes);
}
else {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "Returning 200 OK Status");
- ap_rvputs(r, "HTTP/1.0 200 Connection established" CRLF, NULL);
- ap_rvputs(r, "Proxy-agent: ", ap_get_server_version(), CRLF CRLF, NULL);
- ap_bflush(r->connection->client);
+ "Returning 200 OK Status");
+ ap_rvputs(r, "HTTP/1.0 200 Connection established" CRLF, NULL);
+ ap_rvputs(r, "Proxy-agent: ", ap_get_server_version(), CRLF CRLF, NULL);
+ ap_bflush(r->connection->client);
}
sock_buff = ap_bcreate(r->pool, B_RDWR);
if(apr_setup_poll(&pollfd, 2, r->pool) != APR_SUCCESS)
{
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: error apr_setup_poll()");
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "proxy: error apr_setup_poll()");
return HTTP_INTERNAL_SERVER_ERROR;
}
just see if a recv gives us anything and do the same to sock (server) side, I'll leave this as TBD so
one can decide the best path to take
*/
- if(apr_put_os_sock(&client_sock, (apr_os_sock_t *)get_socket(r->connection->client),
+ if(apr_put_os_sock(&client_sock,
+ (apr_os_sock_t *)get_socket(r->connection->client),
r->pool) != APR_SUCCESS)
{
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: error creating client apr_socket_t");
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "proxy: error creating client apr_socket_t");
return HTTP_INTERNAL_SERVER_ERROR;
}
apr_add_poll_socket(pollfd, client_sock, APR_POLLIN);
#endif
-
-
+
/* Add the server side to the poll */
apr_add_poll_socket(pollfd, sock, APR_POLLIN);
-
- while (1) { /* Infinite loop until error (one side closes the connection) */
+
+ while (1) { /* Infinite loop until error (one side closes the connection) */
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, "Going to sleep (poll)");
if(apr_poll(pollfd, &pollcnt, -1) != APR_SUCCESS)
{
o += i;
nbytes -= i;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "Wrote %d bytes to client", nbytes);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, "Wrote %d bytes to client", nbytes);
}
else
break;
if (pollevent & APR_POLLIN) {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
"client was set");
- if(ap_bread(r->connection->client, buffer, HUGE_STRING_LEN, &nbytes) == APR_SUCCESS) {
+ if(ap_bread(r->connection->client, buffer, HUGE_STRING_LEN,
+ &nbytes) == APR_SUCCESS) {
int o = 0;
while(nbytes)
{
o += i;
nbytes -= i;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "Wrote %d bytes to server", nbytes);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
+ NULL, "Wrote %d bytes to server", nbytes);
}
else
break;
else
break;
}
-
+
apr_close_socket(sock);
return OK;
/* HTTP routines for Apache proxy */
-#include "apr_strings.h"
#include "mod_proxy.h"
#include "http_log.h"
#include "http_main.h"
port = def_port;
err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
if (err)
- return HTTP_BAD_REQUEST;
+ return HTTP_BAD_REQUEST;
/* now parse path/search args, according to rfc1738 */
/* N.B. if this isn't a true proxy request, then the URL _path_
* == r->unparsed_uri, and no others have that property.
*/
if (r->uri == r->unparsed_uri) {
- search = strchr(url, '?');
- if (search != NULL)
- *(search++) = '\0';
+ search = strchr(url, '?');
+ if (search != NULL)
+ *(search++) = '\0';
}
else
- search = r->args;
+ search = r->args;
/* process path */
path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, r->proxyreq);
if (path == NULL)
- return HTTP_BAD_REQUEST;
+ return HTTP_BAD_REQUEST;
if (port != def_port)
- apr_snprintf(sport, sizeof(sport), ":%d", port);
+ apr_snprintf(sport, sizeof(sport), ":%d", port);
else
- sport[0] = '\0';
+ sport[0] = '\0';
r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "://", host, sport, "/",
- path, (search) ? "?" : "", (search) ? search : "", NULL);
+ path, (search) ? "?" : "", (search) ? search : "", NULL);
return OK;
}
return url;
}
-/* Clear all connection-based headers from the incoming headers apr_table_t */
+/* Clear all connection-based headers from the incoming headers table */
static void clear_connection(apr_pool_t *p, apr_table_t *headers)
{
const char *name;
apr_table_unset(headers, "Proxy-Connection");
if (!next)
- return;
+ return;
while (*next) {
- name = next;
- while (*next && !apr_isspace(*next) && (*next != ','))
- ++next;
- while (*next && (apr_isspace(*next) || (*next == ','))) {
- *next = '\0';
- ++next;
- }
- apr_table_unset(headers, name);
+ name = next;
+ while (*next && !apr_isspace(*next) && (*next != ','))
+ ++next;
+ while (*next && (apr_isspace(*next) || (*next == ','))) {
+ *next = '\0';
+ ++next;
+ }
+ apr_table_unset(headers, name);
}
apr_table_unset(headers, "Connection");
}
* we return DECLINED so that we can try another proxy. (Or the direct
* route.)
*/
-int ap_proxy_http_handler(request_rec *r, ap_cache_el *c, char *url,
- const char *proxyhost, int proxyport)
+int ap_proxy_http_handler(request_rec *r, ap_cache_el *c, char *url,
+ const char *proxyhost, int proxyport)
{
const char *strp;
char *strp2;
char *desthost;
apr_socket_t *sock;
- int i, len, backasswards, content_length=-1;
+ int i, len, backasswards, content_length = -1;
apr_array_header_t *reqhdrs_arr;
- apr_table_t *resp_hdrs=NULL;
+ apr_table_t *resp_hdrs = NULL;
apr_table_entry_t *reqhdrs;
struct sockaddr_in server;
struct in_addr destaddr;
BUFF *f;
- apr_file_t *cachefp=NULL;
char buffer[HUGE_STRING_LEN];
char portstr[32];
apr_pool_t *p = r->pool;
const long int zero = 0L;
int destport = 0;
- apr_ssize_t cntr;
char *destportstr = NULL;
const char *urlptr = NULL;
char *datestr, *clen;
+ apr_ssize_t cntr;
+ apr_file_t *cachefp = NULL;
void *sconf = r->server->module_config;
proxy_server_conf *conf =
- (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
+ (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts;
int nocache = 0;
urlptr = strstr(url, "://");
if (urlptr == NULL)
- return HTTP_BAD_REQUEST;
+ return HTTP_BAD_REQUEST;
urlptr += 3;
destport = DEFAULT_HTTP_PORT;
strp = ap_strchr_c(urlptr, '/');
if (strp == NULL) {
- desthost = apr_pstrdup(p, urlptr);
- urlptr = "/";
+ desthost = apr_pstrdup(p, urlptr);
+ urlptr = "/";
}
else {
- char *q = apr_palloc(p, strp - urlptr + 1);
- memcpy(q, urlptr, strp - urlptr);
- q[strp - urlptr] = '\0';
- urlptr = strp;
- desthost = q;
+ char *q = apr_palloc(p, strp - urlptr + 1);
+ memcpy(q, urlptr, strp - urlptr);
+ q[strp - urlptr] = '\0';
+ urlptr = strp;
+ desthost = q;
}
strp2 = ap_strchr(desthost, ':');
if (strp2 != NULL) {
- *(strp2++) = '\0';
- if (apr_isdigit(*strp2)) {
- destport = atoi(strp2);
- destportstr = strp2;
- }
+ *(strp2++) = '\0';
+ if (apr_isdigit(*strp2)) {
+ destport = atoi(strp2);
+ destportstr = strp2;
+ }
}
/* check if ProxyBlock directive on this host */
destaddr.s_addr = apr_inet_addr(desthost);
for (i = 0; i < conf->noproxies->nelts; i++) {
- if ((npent[i].name != NULL && ap_strstr_c(desthost, npent[i].name) != NULL)
- || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*')
- return ap_proxyerror(r, HTTP_FORBIDDEN,
- "Connect to remote machine blocked");
+ if ((npent[i].name != NULL
+ && ap_strstr_c(desthost, npent[i].name) != NULL)
+ || destaddr.s_addr == npent[i].addr.s_addr
+ || npent[i].name[0] == '*')
+ return ap_proxyerror(r, HTTP_FORBIDDEN,
+ "Connect to remote machine blocked");
}
if ((apr_create_tcp_socket(&sock, r->pool)) != APR_SUCCESS) {
return HTTP_INTERNAL_SERVER_ERROR;
}
- if (conf->recv_buffer_size > 0 && apr_setsocketopt(sock, APR_SO_RCVBUF,conf->recv_buffer_size)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
+#if !defined(TPF) && !defined(BEOS)
+ if (conf->recv_buffer_size > 0 && apr_setsocketopt(sock, APR_SO_RCVBUF,
+ conf->recv_buffer_size)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
}
-
+#endif
+
if (proxyhost != NULL) {
i = ap_proxy_doconnect(sock, (char *)proxyhost, proxyport, r);
}
}
if (i == -1) {
- if (proxyhost != NULL)
- return DECLINED; /* try again another way */
- else
- return ap_proxyerror(r, HTTP_BAD_GATEWAY,
- apr_pstrcat(r->pool, "Could not connect to remote machine: ",
- strerror(errno), NULL));
+ if (proxyhost != NULL)
+ return DECLINED; /* try again another way */
+ else
+ return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(r->pool,
+ "Could not connect to remote machine: ",
+ strerror(errno), NULL));
}
- clear_connection(r->pool, r->headers_in); /* Strip connection-based headers */
+ clear_connection(r->pool, r->headers_in); /* Strip connection-based headers */
f = ap_bcreate(p, B_RDWR);
ap_bpush_socket(f, sock);
ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF,
- NULL);
+ NULL);
if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
- ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
+ ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
else
- ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
+ ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
if (conf->viaopt == via_block) {
- /* Block all outgoing Via: headers */
- apr_table_unset(r->headers_in, "Via");
+ /* Block all outgoing Via: headers */
+ apr_table_unset(r->headers_in, "Via");
} else if (conf->viaopt != via_off) {
- /* Create a "Via:" request header entry and merge it */
- i = ap_get_server_port(r);
- if (ap_is_default_port(i,r)) {
- strcpy(portstr,"");
- } else {
- apr_snprintf(portstr, sizeof portstr, ":%d", i);
- }
- /* Generate outgoing Via: header with/without server comment: */
- apr_table_mergen(r->headers_in, "Via",
- (conf->viaopt == via_full)
- ? apr_psprintf(p, "%d.%d %s%s (%s)",
- HTTP_VERSION_MAJOR(r->proto_num),
- HTTP_VERSION_MINOR(r->proto_num),
- ap_get_server_name(r), portstr,
- AP_SERVER_BASEVERSION)
- : apr_psprintf(p, "%d.%d %s%s",
- HTTP_VERSION_MAJOR(r->proto_num),
- HTTP_VERSION_MINOR(r->proto_num),
- ap_get_server_name(r), portstr)
- );
+ /* Create a "Via:" request header entry and merge it */
+ i = ap_get_server_port(r);
+ if (ap_is_default_port(i,r)) {
+ strcpy(portstr,"");
+ } else {
+ apr_snprintf(portstr, sizeof portstr, ":%d", i);
+ }
+ /* Generate outgoing Via: header with/without server comment: */
+ ap_table_mergen(r->headers_in, "Via",
+ (conf->viaopt == via_full)
+ ? apr_psprintf(p, "%d.%d %s%s (%s)",
+ HTTP_VERSION_MAJOR(r->proto_num),
+ HTTP_VERSION_MINOR(r->proto_num),
+ ap_get_server_name(r), portstr,
+ AP_SERVER_BASEVERSION)
+ : apr_psprintf(p, "%d.%d %s%s",
+ HTTP_VERSION_MAJOR(r->proto_num),
+ HTTP_VERSION_MINOR(r->proto_num),
+ ap_get_server_name(r), portstr)
+ );
}
reqhdrs_arr = apr_table_elts(r->headers_in);
reqhdrs = (apr_table_entry_t *) reqhdrs_arr->elts;
for (i = 0; i < reqhdrs_arr->nelts; i++) {
- if (reqhdrs[i].key == NULL || reqhdrs[i].val == NULL
- /* Clear out headers not to send */
- || !strcasecmp(reqhdrs[i].key, "Host") /* Already sent */
- /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be
- * suppressed if THIS server requested the authentication,
- * not when a frontend proxy requested it!
- */
- || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization"))
- continue;
- ap_bvputs(f, reqhdrs[i].key, ": ", reqhdrs[i].val, CRLF, NULL);
+ if (reqhdrs[i].key == NULL || reqhdrs[i].val == NULL
+ /* Clear out headers not to send */
+ || !strcasecmp(reqhdrs[i].key, "Host") /* Already sent */
+ /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be
+ * suppressed if THIS server requested the authentication,
+ * not when a frontend proxy requested it!
+ */
+ || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization"))
+ continue;
+ ap_bvputs(f, reqhdrs[i].key, ": ", reqhdrs[i].val, CRLF, NULL);
}
ap_bputs(CRLF, f);
/* send the request data, if any. */
if (ap_should_client_block(r)) {
- while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0)
- ap_bwrite(f, buffer, i, &cntr);
+ while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0)
+ ap_bwrite(f, buffer, i, &cntr);
}
ap_bflush(f);
len = ap_bgets(buffer, sizeof buffer - 1, f);
if (len == -1) {
- ap_bclose(f);
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "ap_bgets() - proxy receive - Error reading from remote server %s (length %d)",
- proxyhost ? proxyhost : desthost, len);
- return ap_proxyerror(r, HTTP_BAD_GATEWAY,
- "Error reading from remote server");
+ ap_bclose(f);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "ap_bgets() - proxy receive - Error reading from remote server %s (length %d)",
+ proxyhost ? proxyhost : desthost, len);
+ return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+ "Error reading from remote server");
} else if (len == 0) {
- ap_bclose(f);
- return ap_proxyerror(r, HTTP_BAD_GATEWAY,
- "Document contains no data");
+ ap_bclose(f);
+ return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+ "Document contains no data");
}
/* Is it an HTTP/1 response? This is buggy if we ever see an HTTP/1.10 */
if (ap_checkmask(buffer, "HTTP/#.# ###*")) {
- int major, minor;
- if (2 != sscanf(buffer, "HTTP/%u.%u", &major, &minor)) {
- major = 1;
- minor = 0;
- }
+ int major, minor;
+ if (2 != sscanf(buffer, "HTTP/%u.%u", &major, &minor)) {
+ major = 1;
+ minor = 0;
+ }
/* If not an HTTP/1 message or if the status line was > 8192 bytes */
- if (buffer[5] != '1' || buffer[len - 1] != '\n') {
- ap_bclose(f);
- return HTTP_BAD_GATEWAY;
- }
- backasswards = 0;
- buffer[--len] = '\0';
-
- buffer[12] = '\0';
- r->status = atoi(&buffer[9]);
- buffer[12] = ' ';
- r->status_line = apr_pstrdup(p, &buffer[9]);
+ if (buffer[5] != '1' || buffer[len - 1] != '\n') {
+ ap_bclose(f);
+ return HTTP_BAD_GATEWAY;
+ }
+ backasswards = 0;
+ buffer[--len] = '\0';
+
+ buffer[12] = '\0';
+ r->status = atoi(&buffer[9]);
+ buffer[12] = ' ';
+ r->status_line = apr_pstrdup(p, &buffer[9]);
/* read the headers. */
/* N.B. for HTTP/1.0 clients, we have to fold line-wrapped headers */
/* Also, take care with headers with multiple occurences. */
- resp_hdrs = ap_proxy_read_headers(r, buffer, HUGE_STRING_LEN, f);
- if (resp_hdrs == NULL) {
- ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
- "proxy: Bad HTTP/%d.%d header returned by %s (%s)",
- major, minor, r->uri, r->method);
- nocache = 1; /* do not cache this broken file */
- }
+
+ resp_hdrs = ap_proxy_read_headers(r, buffer, HUGE_STRING_LEN, f);
+ if (resp_hdrs == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
+ "proxy: Bad HTTP/%d.%d header returned by %s (%s)",
+ major, minor, r->uri, r->method);
+ nocache = 1; /* do not cache this broken file */
+ }
else
{
clear_connection(p, resp_hdrs); /* Strip Connection hdrs */
ap_cache_el_header_merge(c, resp_hdrs);
}
-
- if (conf->viaopt != via_off && conf->viaopt != via_block) {
- /* Create a "Via:" response header entry and merge it */
- i = ap_get_server_port(r);
- if (ap_is_default_port(i,r)) {
- strcpy(portstr,"");
- } else {
- apr_snprintf(portstr, sizeof portstr, ":%d", i);
- }
+
+ if (conf->viaopt != via_off && conf->viaopt != via_block) {
+ /* Create a "Via:" response header entry and merge it */
+ i = ap_get_server_port(r);
+ if (ap_is_default_port(i,r)) {
+ strcpy(portstr,"");
+ } else {
+ apr_snprintf(portstr, sizeof portstr, ":%d", i);
+ }
ap_cache_el_header_add(c, "Via", (conf->viaopt == via_full)
- ? apr_psprintf(p, "%d.%d %s%s (%s)", major, minor,
- ap_get_server_name(r), portstr, AP_SERVER_BASEVERSION)
- : apr_psprintf(p, "%d.%d %s%s", major, minor, ap_get_server_name(r), portstr)
- );
- }
+ ? apr_psprintf(p, "%d.%d %s%s (%s)", major, minor,
+ ap_get_server_name(r), portstr, AP_SERVER_BASEVERSION)
+ : apr_psprintf(p, "%d.%d %s%s", major, minor,
+ ap_get_server_name(r), portstr));
+ }
}
else {
/* an http/0.9 response */
- backasswards = 1;
- r->status = 200;
- r->status_line = "200 OK";
+ backasswards = 1;
+ r->status = 200;
+ r->status_line = "200 OK";
}
/*
content_length = atoi(clen ? clen : "-1");
for (i = 0; i < conf->nocaches->nelts; i++) {
- if ((ncent[i].name != NULL && ap_strstr_c(desthost, ncent[i].name) != NULL)
- || destaddr.s_addr == ncent[i].addr.s_addr || ncent[i].name[0] == '*')
- nocache = 1;
+ if ((ncent[i].name != NULL && ap_strstr_c(desthost, ncent[i].name) != NULL)
+ || destaddr.s_addr == ncent[i].addr.s_addr || ncent[i].name[0] == '*')
+ nocache = 1;
}
if(nocache || !ap_proxy_cache_should_cache(r, resp_hdrs, !backasswards))
ap_proxy_cache_error(&c);
else
ap_cache_el_data(c, &cachefp);
-
+
/* write status line */
if (!r->assbackwards)
- ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL);
- if (cachefp && apr_puts(apr_pstrcat(r->pool, "HTTP/1.0 ", r->status_line, CRLF, NULL), cachefp) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error writing status line to cache");
- ap_proxy_cache_error(&c);
- cachefp = NULL;
+ ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL);
+ if (cachefp && apr_puts(apr_pstrcat(r->pool, "HTTP/1.0 ",
+ r->status_line, CRLF, NULL), cachefp) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "proxy: error writing status line to cache");
+ ap_proxy_cache_error(&c);
+ cachefp = NULL;
}
/* send headers */
ap_cache_el_header_walk(c, ap_proxy_send_hdr_line, r, NULL);
if (!r->assbackwards)
- ap_rputs(CRLF, r);
+ ap_rputs(CRLF, r);
ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
-/* Is it an HTTP/0.9 respose? If so, send the extra data */
+/* Is it an HTTP/0.9 response? If so, send the extra data */
if (backasswards) {
- ap_bwrite(r->connection->client, buffer, len, &cntr);
+ ap_bwrite(r->connection->client, buffer, len, &cntr);
cntr = len;
if (cachefp && apr_write(cachefp, buffer, &cntr) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error writing extra data to cache %ld",
- (long)cachefp);
- ap_proxy_cache_error(&c);
- }
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "proxy: error writing extra data to cache");
+ ap_proxy_cache_error(&c);
+ }
}
#ifdef CHARSET_EBCDIC
ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
#endif
- /* send body */
- /* if header only, then cache will be NULL */
- /* HTTP/1.0 tells us to read to EOF, rather than content-length bytes */
+ /* send body */
+ /* if header only, then cache will be NULL */
+ /* HTTP/1.0 tells us to read to EOF, rather than content-length bytes */
if (!r->header_only) {
- proxy_completion pc;
- pc.content_length = content_length;
- pc.cache_completion = conf->cache_completion;
- ap_proxy_send_fb(&pc, f, r, c);
+ proxy_completion pc;
+ pc.content_length = content_length;
+ pc.cache_completion = conf->cache_completion;
+ ap_proxy_send_fb(&pc, f, r, c);
}
ap_bclose(f);
*/
/* Utility routines for Apache proxy */
-#include "apr_strings.h"
#include "mod_proxy.h"
#include "http_main.h"
-#include "apr_md5.h"
#include "http_log.h"
#include "util_uri.h"
-#include "util_date.h" /* get ap_checkmask() decl. */
-
-#include <pthread.h>
+#include "util_date.h" /* get ap_checkmask() decl. */
+#include "apr_md5.h"
static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r);
static int proxy_match_word(struct dirconn_entry *This, request_rec *r);
-
+static struct per_thread_data *get_per_thread_data(void);
/* already called in the knowledge that the characters are hex digits */
int ap_proxy_hex2c(const char *x)
{
#ifndef CHARSET_EBCDIC
ch = x[0];
if (apr_isdigit(ch))
- i = ch - '0';
+ i = ch - '0';
else if (apr_isupper(ch))
- i = ch - ('A' - 10);
+ i = ch - ('A' - 10);
else
- i = ch - ('a' - 10);
+ i = ch - ('a' - 10);
i <<= 4;
ch = x[1];
if (apr_isdigit(ch))
- i += ch - '0';
+ i += ch - '0';
else if (apr_isupper(ch))
- i += ch - ('A' - 10);
+ i += ch - ('A' - 10);
else
- i += ch - ('a' - 10);
+ i += ch - ('a' - 10);
return i;
#else /*CHARSET_EBCDIC*/
return (1 == sscanf(x, "%2x", &i)) ? os_toebcdic[i&0xFF] : 0;
x[0] = '%';
i = (ch & 0xF0) >> 4;
if (i >= 10)
- x[1] = ('A' - 10) + i;
+ x[1] = ('A' - 10) + i;
else
- x[1] = '0' + i;
+ x[1] = '0' + i;
i = ch & 0x0F;
if (i >= 10)
- x[2] = ('A' - 10) + i;
+ x[2] = ('A' - 10) + i;
else
- x[2] = '0' + i;
+ x[2] = '0' + i;
#else /*CHARSET_EBCDIC*/
static const char ntoa[] = { "0123456789ABCDEF" };
ch &= 0xFF;
* and encodes those which must be encoded, and does not touch
* those which must not be touched.
*/
-char *
- ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, int isenc)
+char *ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
+ int isenc)
{
int i, j, ch;
char *y;
- char *allowed; /* characters which should not be encoded */
- char *reserved; /* characters which much not be en/de-coded */
+ char *allowed; /* characters which should not be encoded */
+ char *reserved; /* characters which much not be en/de-coded */
/* N.B. in addition to :@&=, this allows ';' in an http path
* and '?' in an ftp path -- this may be revised
* it only permits ; / ? : @ = & as reserved chars.)
*/
if (t == enc_path)
- allowed = "$-_.+!*'(),;:@&=";
+ allowed = "$-_.+!*'(),;:@&=";
else if (t == enc_search)
- allowed = "$-_.!*'(),;:@&=";
+ allowed = "$-_.!*'(),;:@&=";
else if (t == enc_user)
- allowed = "$-_.+!*'(),;@&=";
+ allowed = "$-_.+!*'(),;@&=";
else if (t == enc_fpath)
- allowed = "$-_.+!*'(),?:@&=";
- else /* if (t == enc_parm) */
- allowed = "$-_.+!*'(),?/:@&=";
+ allowed = "$-_.+!*'(),?:@&=";
+ else /* if (t == enc_parm) */
+ allowed = "$-_.+!*'(),?/:@&=";
if (t == enc_path)
- reserved = "/";
+ reserved = "/";
else if (t == enc_search)
- reserved = "+";
+ reserved = "+";
else
- reserved = "";
+ reserved = "";
y = apr_palloc(p, 3 * len + 1);
for (i = 0, j = 0; i < len; i++, j++) {
/* always handle '/' first */
- ch = x[i];
- if (strchr(reserved, ch)) {
- y[j] = ch;
- continue;
- }
+ ch = x[i];
+ if (strchr(reserved, ch)) {
+ y[j] = ch;
+ continue;
+ }
/* decode it if not already done */
- if (isenc && ch == '%') {
- if (!apr_isxdigit(x[i + 1]) || !apr_isxdigit(x[i + 2]))
- return NULL;
- ch = ap_proxy_hex2c(&x[i + 1]);
- i += 2;
- if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */
- ap_proxy_c2hex(ch, &y[j]);
- j += 2;
- continue;
- }
- }
+ if (isenc && ch == '%') {
+ if (!ap_isxdigit(x[i + 1]) || !ap_isxdigit(x[i + 2]))
+ return NULL;
+ ch = ap_proxy_hex2c(&x[i + 1]);
+ i += 2;
+ if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */
+ ap_proxy_c2hex(ch, &y[j]);
+ j += 2;
+ continue;
+ }
+ }
/* recode it, if necessary */
- if (!apr_isalnum(ch) && !strchr(allowed, ch)) {
- ap_proxy_c2hex(ch, &y[j]);
- j += 2;
- }
- else
- y[j] = ch;
+ if (!apr_isalnum(ch) && !strchr(allowed, ch)) {
+ ap_proxy_c2hex(ch, &y[j]);
+ j += 2;
+ }
+ else
+ y[j] = ch;
}
y[j] = '\0';
return y;
*/
char *
ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
- char **passwordp, char **hostp, int *port)
+ char **passwordp, char **hostp, int *port)
{
int i;
char *strp, *host, *url = *urlp;
char *user = NULL, *password = NULL;
if (url[0] != '/' || url[1] != '/')
- return "Malformed URL";
+ return "Malformed URL";
host = url + 2;
url = strchr(host, '/');
if (url == NULL)
- url = "";
+ url = "";
else
- *(url++) = '\0'; /* skip seperating '/' */
+ *(url++) = '\0'; /* skip seperating '/' */
/* find _last_ '@' since it might occur in user/password part */
strp = strrchr(host, '@');
if (strp != NULL) {
- *strp = '\0';
- user = host;
- host = strp + 1;
+ *strp = '\0';
+ user = host;
+ host = strp + 1;
/* find password */
- strp = strchr(user, ':');
- if (strp != NULL) {
- *strp = '\0';
- password = ap_proxy_canonenc(p, strp + 1, strlen(strp + 1), enc_user, 1);
- if (password == NULL)
- return "Bad %-escape in URL (password)";
- }
-
- user = ap_proxy_canonenc(p, user, strlen(user), enc_user, 1);
- if (user == NULL)
- return "Bad %-escape in URL (username)";
+ strp = strchr(user, ':');
+ if (strp != NULL) {
+ *strp = '\0';
+ password = ap_proxy_canonenc(p, strp + 1, strlen(strp + 1), enc_user, 1);
+ if (password == NULL)
+ return "Bad %-escape in URL (password)";
+ }
+
+ user = ap_proxy_canonenc(p, user, strlen(user), enc_user, 1);
+ if (user == NULL)
+ return "Bad %-escape in URL (username)";
}
if (userp != NULL) {
- *userp = user;
+ *userp = user;
}
if (passwordp != NULL) {
- *passwordp = password;
+ *passwordp = password;
}
strp = strrchr(host, ':');
if (strp != NULL) {
- *(strp++) = '\0';
-
- for (i = 0; strp[i] != '\0'; i++)
- if (!apr_isdigit(strp[i]))
- break;
-
- /* if (i == 0) the no port was given; keep default */
- if (strp[i] != '\0') {
- return "Bad port number in URL";
- } else if (i > 0) {
- *port = atoi(strp);
- if (*port > 65535)
- return "Port number in URL > 65535";
- }
+ *(strp++) = '\0';
+
+ for (i = 0; strp[i] != '\0'; i++)
+ if (!apr_isdigit(strp[i]))
+ break;
+
+ /* if (i == 0) the no port was given; keep default */
+ if (strp[i] != '\0') {
+ return "Bad port number in URL";
+ } else if (i > 0) {
+ *port = atoi(strp);
+ if (*port > 65535)
+ return "Port number in URL > 65535";
+ }
}
- ap_str_tolower(host); /* DNS names are case insensitive */
+ ap_str_tolower(host); /* DNS names are case-insensitive */
if (*host == '\0')
- return "Missing host in URL";
+ return "Missing host in URL";
/* check hostname syntax */
for (i = 0; host[i] != '\0'; i++)
- if (!apr_isdigit(host[i]) && host[i] != '.')
- break;
+ if (!apr_isdigit(host[i]) && host[i] != '.')
+ break;
/* must be an IP address */
-#ifdef WIN32
+#if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
if (host[i] == '\0' && (inet_addr(host) == -1))
#else
- if (host[i] == '\0' && (apr_inet_addr(host) == -1 || inet_network(host) == -1))
+ if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
#endif
{
- return "Bad IP address in URL";
+ return "Bad IP address in URL";
}
/* if (strchr(host,'.') == NULL && domain != NULL)
q = strchr(x, ',');
/* check for RFC 850 date */
if (q != NULL && q - x > 3 && q[1] == ' ') {
- *q = '\0';
- for (wk = 0; wk < 7; wk++)
- if (strcmp(x, lwday[wk]) == 0)
- break;
- *q = ',';
- if (wk == 7)
- return x; /* not a valid date */
- if (q[4] != '-' || q[8] != '-' || q[11] != ' ' || q[14] != ':' ||
- q[17] != ':' || strcmp(&q[20], " GMT") != 0)
- return x;
- if (sscanf(q + 2, "%u-%3s-%u %u:%u:%u %3s", &mday, month, &year,
- &hour, &min, &sec, zone) != 7)
- return x;
- if (year < 70)
- year += 2000;
- else
- year += 1900;
+ *q = '\0';
+ for (wk = 0; wk < 7; wk++)
+ if (strcmp(x, lwday[wk]) == 0)
+ break;
+ *q = ',';
+ if (wk == 7)
+ return x; /* not a valid date */
+ if (q[4] != '-' || q[8] != '-' || q[11] != ' ' || q[14] != ':' ||
+ q[17] != ':' || strcmp(&q[20], " GMT") != 0)
+ return x;
+ if (sscanf(q + 2, "%u-%3s-%u %u:%u:%u %3s", &mday, month, &year,
+ &hour, &min, &sec, zone) != 7)
+ return x;
+ if (year < 70)
+ year += 2000;
+ else
+ year += 1900;
}
else {
/* check for acstime() date */
- if (x[3] != ' ' || x[7] != ' ' || x[10] != ' ' || x[13] != ':' ||
- x[16] != ':' || x[19] != ' ' || x[24] != '\0')
- return x;
- if (sscanf(x, "%3s %3s %u %u:%u:%u %u", week, month, &mday, &hour,
- &min, &sec, &year) != 7)
- return x;
- for (wk = 0; wk < 7; wk++)
- if (strcmp(week, apr_day_snames[wk]) == 0)
- break;
- if (wk == 7)
- return x;
+ if (x[3] != ' ' || x[7] != ' ' || x[10] != ' ' || x[13] != ':' ||
+ x[16] != ':' || x[19] != ' ' || x[24] != '\0')
+ return x;
+ if (sscanf(x, "%3s %3s %u %u:%u:%u %u", week, month, &mday, &hour,
+ &min, &sec, &year) != 7)
+ return x;
+ for (wk = 0; wk < 7; wk++)
+ if (strcmp(week, ap_day_snames[wk]) == 0)
+ break;
+ if (wk == 7)
+ return x;
}
/* check date */
for (mon = 0; mon < 12; mon++)
- if (strcmp(month, apr_month_snames[mon]) == 0)
- break;
+ if (strcmp(month, ap_month_snames[mon]) == 0)
+ break;
if (mon == 12)
- return x;
+ return x;
q = apr_palloc(p, 30);
- apr_snprintf(q, 30, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", apr_day_snames[wk], mday,
- apr_month_snames[mon], year, hour, min, sec);
+ apr_snprintf(q, 30, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", ap_day_snames[wk],
+ mday, ap_month_snames[mon], year, hour, min, sec);
return q;
}
char *value, *end;
char field[MAX_STRING_LEN];
- resp_hdrs = apr_make_table(r->pool, 20);
+ resp_hdrs = ap_make_table(r->pool, 20);
/*
* Read header lines until we get the empty separator line, a read error,
* the connection closes (EOF), or we timeout.
*/
while ((len = proxy_getline(buffer, size, f, 1)) > 0) {
-
- if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */
-
- /* Buggy MS IIS servers sometimes return invalid headers
- * (an extra "HTTP/1.0 200, OK" line sprinkled in between
- * the usual MIME headers). Try to deal with it in a sensible
- * way, but log the fact.
- * XXX: The mask check is buggy if we ever see an HTTP/1.10 */
-
- if (!ap_checkmask(buffer, "HTTP/#.# ###*")) {
- /* Nope, it wasn't even an extra HTTP header. Give up. */
- return NULL;
- }
-
- ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
- "proxy: Ignoring duplicate HTTP header "
- "returned by %s (%s)", r->uri, r->method);
- continue;
- }
+
+ if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */
+
+ /* Buggy MS IIS servers sometimes return invalid headers
+ * (an extra "HTTP/1.0 200, OK" line sprinkled in between
+ * the usual MIME headers). Try to deal with it in a sensible
+ * way, but log the fact.
+ * XXX: The mask check is buggy if we ever see an HTTP/1.10 */
+
+ if (!ap_checkmask(buffer, "HTTP/#.# ###*")) {
+ /* Nope, it wasn't even an extra HTTP header. Give up. */
+ return NULL;
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
+ "proxy: Ignoring duplicate HTTP header "
+ "returned by %s (%s)", r->uri, r->method);
+ continue;
+ }
*value = '\0';
++value;
- /* XXX: RFC2068 defines only SP and HT as whitespace, this test is
- * wrong... and so are many others probably.
- */
+ /* XXX: RFC2068 defines only SP and HT as whitespace, this test is
+ * wrong... and so are many others probably.
+ */
while (apr_isspace(*value))
++value; /* Skip to start of value */
- /* should strip trailing whitespace as well */
- for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)
- *end = '\0';
-
- apr_table_add(resp_hdrs, buffer, value);
-
- /* the header was too long; at the least we should skip extra data */
- if (len >= size - 1) {
- while ((len = proxy_getline(field, MAX_STRING_LEN, f, 1))
- >= MAX_STRING_LEN - 1) {
- /* soak up the extra data */
- }
- if (len == 0) /* time to exit the larger loop as well */
- break;
- }
+ /* should strip trailing whitespace as well */
+ for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)
+ *end = '\0';
+
+ ap_table_add(resp_hdrs, buffer, value);
+
+ /* the header was too long; at the least we should skip extra data */
+ if (len >= size - 1) {
+ while ((len = proxy_getline(field, MAX_STRING_LEN, f, 1))
+ >= MAX_STRING_LEN - 1) {
+ /* soak up the extra data */
+ }
+ if (len == 0) /* time to exit the larger loop as well */
+ break;
+ }
}
return resp_hdrs;
}
-long int ap_proxy_send_fb(proxy_completion *completion, BUFF *f, request_rec *r, ap_cache_el *c)
+long int ap_proxy_send_fb(proxy_completion *completion, BUFF *f, request_rec *r, ap_cache_el *c)
{
int ok;
char buf[IOBUFSIZE];
apr_ssize_t cntr;
register int n, o;
conn_rec *con = r->connection;
- int alternate_timeouts = 1; /* 1 if we alternate between soft & hard timeouts */
+ int alternate_timeouts = 1; /* 1 if we alternate between soft & hard timeouts */
apr_file_t *cachefp = NULL;
int written = 0, wrote_to_cache;
-
+
total_bytes_rcvd = 0;
if (c) ap_cache_el_data(c, &cachefp);
/* The cache copy is ASCII, not EBCDIC, even for text/html) */
ap_bsetflag(f, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
if (c != NULL && c->fp != NULL)
- ap_bsetflag(c->fp, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
+ ap_bsetflag(c->fp, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
ap_bsetflag(con->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
#endif
* has its own timeout handler which can set both buffers to EOUT.
*/
-#ifdef WIN32
+#if defined(WIN32) || defined(TPF) || defined(NETWARE)
/* works fine under win32, so leave it */
+ alternate_timeouts = 0;
#else
/* CHECKME! Since hard_timeout won't work in unix on sends with partial
* cache completion, we have to alternate between hard_timeout
* for reads, and soft_timeout for send. This is because we need
* to get a return from ap_bwrite to be able to continue caching.
* BUT, if we *can't* continue anyway, just use hard_timeout.
+ * (Also, if no cache file is written, use hard timeouts)
*/
- if (!completion || completion->content_length > 0 || completion->cache_completion == 1.0) {
+ if (!completion || completion->content_length > 0
+ || completion->cache_completion == 1.0) {
alternate_timeouts = 0;
}
#endif
* or (after the client aborted) while we can successfully
* read and finish the configured cache_completion.
*/
- for (ok = 1; ok; cntr=0) {
- /* Read block from server */
- if(ap_bread(f, buf, IOBUFSIZE, &cntr) != APR_SUCCESS && !cntr)
+ for (ok = 1; ok; cntr = 0) {
+ /* Read block from server */
+ if (ap_bread(f, buf, IOBUFSIZE, &cntr) != APR_SUCCESS && !cntr)
{
if (c != NULL) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error reading from %s", c->name);
+ "proxy: error reading from %s", c->name);
ap_proxy_cache_error(&c);
}
break;
- }
+ }
else if(cntr == 0) break;
-
-
- /* Write to cache first. */
- /*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */
+
+ /* Write to cache first. */
+ /*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */
wrote_to_cache = cntr;
if (cachefp && apr_write(cachefp, &buf[0], &wrote_to_cache) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error writing to cache");
+ "proxy: error writing to cache");
ap_proxy_cache_error(&c);
- cachefp = NULL;
} else {
written += n;
}
total_bytes_rcvd += cntr;
in_buffer = cntr;
- /* Write the block to the client, detect aborted transfers */
+ /* Write the block to the client, detect aborted transfers */
while (!con->aborted && in_buffer > 0) {
if (ap_bwrite(con->client, &buf[o], in_buffer, &cntr) != APR_SUCCESS) {
if (completion) {
} /* loop and ap_bread while "ok" */
if (!con->aborted)
- ap_bflush(con->client);
+ ap_bflush(con->client);
return total_bytes_rcvd;
}
*/
void ap_proxy_send_headers(request_rec *r, const char *respline, apr_table_t *t)
{
- int i;
- BUFF *fp = r->connection->client;
- apr_table_entry_t *elts = (apr_table_entry_t *) apr_table_elts(t)->elts;
+ int i;
+ BUFF *fp = r->connection->client;
+ apr_table_entry_t *elts = (apr_table_entry_t *) apr_table_elts(t)->elts;
- ap_bvputs(fp, respline, CRLF, NULL);
+ ap_bvputs(fp, respline, CRLF, NULL);
- for (i = 0; i < apr_table_elts(t)->nelts; ++i) {
- if (elts[i].key != NULL) {
- ap_bvputs(fp, elts[i].key, ": ", elts[i].val, CRLF, NULL);
- apr_table_addn(r->headers_out, elts[i].key, elts[i].val);
- }
- }
+ for (i = 0; i < ap_table_elts(t)->nelts; ++i) {
+ if (elts[i].key != NULL) {
+ ap_bvputs(fp, elts[i].key, ": ", elts[i].val, CRLF, NULL);
+ apr_table_addn(r->headers_out, elts[i].key, elts[i].val);
+ }
+ }
- ap_bputs(CRLF, fp);
+ ap_bputs(CRLF, fp);
}
/*
- * list is a comma-separated list of case insensitive tokens, with
+ * list is a comma-separated list of case-insensitive tokens, with
* optional whitespace around the tokens.
* The return returns 1 if the token val is found in the list, or 0
* otherwise.
len = strlen(val);
while (list != NULL) {
- p = ap_strchr_c(list, ',');
- if (p != NULL) {
- i = p - list;
- do
- p++;
- while (apr_isspace(*p));
- }
- else
- i = strlen(list);
-
- while (i > 0 && apr_isspace(list[i - 1]))
- i--;
- if (i == len && strncasecmp(list, val, len) == 0)
- return 1;
- list = p;
+ p = ap_strchr_c(list, ',');
+ if (p != NULL) {
+ i = p - list;
+ do
+ p++;
+ while (apr_isspace(*p));
+ }
+ else
+ i = strlen(list);
+
+ while (i > 0 && apr_isspace(list[i - 1]))
+ i--;
+ if (i == len && strncasecmp(list, val, len) == 0)
+ return 1;
+ list = p;
}
return 0;
}
-
/*
* Converts 8 hex digits to a time integer
*/
unsigned int j;
for (i = 0, j = 0; i < 8; i++) {
- ch = x[i];
- j <<= 4;
- if (apr_isdigit(ch))
- j |= ch - '0';
- else if (apr_isupper(ch))
- j |= ch - ('A' - 10);
- else
- j |= ch - ('a' - 10);
+ ch = x[i];
+ j <<= 4;
+ if (apr_isdigit(ch))
+ j |= ch - '0';
+ else if (apr_isupper(ch))
+ j |= ch - ('A' - 10);
+ else
+ j |= ch - ('a' - 10);
}
if (j == 0xffffffff)
- return -1; /* so that it works with 8-byte ints */
+ return -1; /* so that it works with 8-byte ints */
else
- return j;
+ return j;
}
/*
unsigned int j = t;
for (i = 7; i >= 0; i--) {
- ch = j & 0xF;
- j >>= 4;
- if (ch >= 10)
- y[i] = ch + ('A' - 10);
- else
- y[i] = ch + '0';
+ ch = j & 0xF;
+ j >>= 4;
+ if (ch >= 10)
+ y[i] = ch + ('A' - 10);
+ else
+ y[i] = ch + '0';
}
y[8] = '\0';
}
-void ap_proxy_cache_error(ap_cache_el **c)
+void ap_proxy_cache_error(ap_cache_el **c)
{
if (c && *c) {
const char *name = (*c)->name;
int ap_proxyerror(request_rec *r, int statuscode, const char *message)
{
apr_table_setn(r->notes, "error-notes",
- apr_pstrcat(r->pool,
- "The proxy server could not handle the request "
- "<EM><A HREF=\"", ap_escape_uri(r->pool, r->uri),
- "\">", ap_escape_html(r->pool, r->method),
- " ",
- ap_escape_html(r->pool, r->uri), "</A></EM>.<P>\n"
- "Reason: <STRONG>",
- ap_escape_html(r->pool, message),
- "</STRONG>", NULL));
+ apr_pstrcat(r->pool,
+ "The proxy server could not handle the request "
+ "<EM><A HREF=\"", ap_escape_uri(r->pool, r->uri),
+ "\">", ap_escape_html(r->pool, r->method),
+ " ",
+ ap_escape_html(r->pool, r->uri), "</A></EM>.<P>\n"
+ "Reason: <STRONG>",
+ ap_escape_html(r->pool, message),
+ "</STRONG>", NULL));
/* Allow "error-notes" string to be printed by ap_send_error_response() */
apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*"));
{
int i;
struct hostent *hp;
-/* XXX - Either get rid of TLS, or use pthread/APR functions */
-#define APACHE_TLS
- static APACHE_TLS struct hostent hpbuf;
- static APACHE_TLS u_long ipaddr;
- static APACHE_TLS char *charpbuf[2];
+ struct per_thread_data *ptd = get_per_thread_data();
for (i = 0; host[i] != '\0'; i++)
- if (!apr_isdigit(host[i]) && host[i] != '.')
- break;
+ if (!apr_isdigit(host[i]) && host[i] != '.')
+ break;
if (host[i] != '\0') {
- hp = gethostbyname(host);
- if (hp == NULL)
- return "Host not found";
+ hp = gethostbyname(host);
+ if (hp == NULL)
+ return "Host not found";
}
else {
- ipaddr = apr_inet_addr(host);
- hp = gethostbyaddr((char *) &ipaddr, sizeof(u_long), AF_INET);
- if (hp == NULL) {
- memset(&hpbuf, 0, sizeof(hpbuf));
- hpbuf.h_name = 0;
- hpbuf.h_addrtype = AF_INET;
- hpbuf.h_length = sizeof(u_long);
- hpbuf.h_addr_list = charpbuf;
- hpbuf.h_addr_list[0] = (char *) &ipaddr;
- hpbuf.h_addr_list[1] = 0;
- hp = &hpbuf;
- }
+ ptd->ipaddr = ap_inet_addr(host);
+ hp = gethostbyaddr((char *) &ptd->ipaddr, sizeof(ptd->ipaddr), AF_INET);
+ if (hp == NULL) {
+ memset(&ptd->hpbuf, 0, sizeof(ptd->hpbuf));
+ ptd->hpbuf.h_name = 0;
+ ptd->hpbuf.h_addrtype = AF_INET;
+ ptd->hpbuf.h_length = sizeof(ptd->ipaddr);
+ ptd->hpbuf.h_addr_list = ptd->charpbuf;
+ ptd->hpbuf.h_addr_list[0] = (char *) &ptd->ipaddr;
+ ptd->hpbuf.h_addr_list[1] = 0;
+ hp = &ptd->hpbuf;
+ }
}
*reqhp = *hp;
return NULL;
int port = -1;
if (r->hostname != NULL)
- return r->hostname;
+ return r->hostname;
/* Set url to the first char after "scheme://" */
if ((url = strchr(r->uri, ':')) == NULL
- || url[1] != '/' || url[2] != '/')
- return NULL;
+ || url[1] != '/' || url[2] != '/')
+ return NULL;
- url = apr_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */
+ url = apr_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */
err = ap_proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port);
if (err != NULL)
- ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
- "%s", err);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
+ "%s", err);
r->hostname = host;
- return host; /* ought to return the port, too */
+ return host; /* ought to return the port, too */
}
/* Return TRUE if addr represents an IP address (or an IP network address) */
long bits;
/* if the address is given with an explicit netmask, use that */
- /* Due to a deficiency in apr_inet_addr(), it is impossible to parse */
+ /* Due to a deficiency in ap_inet_addr(), it is impossible to parse */
/* "partial" addresses (with less than 4 quads) correctly, i.e. */
/* 192.168.123 is parsed as 192.168.0.123, which is not what I want. */
/* I therefore have to parse the IP address manually: */
/* Iterate over up to 4 (dotted) quads. */
for (quads = 0; quads < 4 && *addr != '\0'; ++quads) {
- char *tmp;
+ char *tmp;
- if (*addr == '/' && quads > 0) /* netmask starts here. */
- break;
+ if (*addr == '/' && quads > 0) /* netmask starts here. */
+ break;
- if (!apr_isdigit(*addr))
- return 0; /* no digit at start of quad */
+ if (!apr_isdigit(*addr))
+ return 0; /* no digit at start of quad */
- ip_addr[quads] = strtol(addr, &tmp, 0);
+ ip_addr[quads] = strtol(addr, &tmp, 0);
- if (tmp == addr) /* expected a digit, found something else */
- return 0;
+ if (tmp == addr) /* expected a digit, found something else */
+ return 0;
- if (ip_addr[quads] < 0 || ip_addr[quads] > 255) {
- /* invalid octet */
- return 0;
- }
+ if (ip_addr[quads] < 0 || ip_addr[quads] > 255) {
+ /* invalid octet */
+ return 0;
+ }
- addr = tmp;
+ addr = tmp;
- if (*addr == '.' && quads != 3)
- ++addr; /* after the 4th quad, a dot would be illegal */
+ if (*addr == '.' && quads != 3)
+ ++addr; /* after the 4th quad, a dot would be illegal */
}
for (This->addr.s_addr = 0, i = 0; i < quads; ++i)
- This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
+ This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
- if (addr[0] == '/' && apr_isdigit(addr[1])) { /* net mask follows: */
- char *tmp;
+ if (addr[0] == '/' && apr_isdigit(addr[1])) { /* net mask follows: */
+ char *tmp;
- ++addr;
+ ++addr;
- bits = strtol(addr, &tmp, 0);
+ bits = strtol(addr, &tmp, 0);
- if (tmp == addr) /* expected a digit, found something else */
- return 0;
+ if (tmp == addr) /* expected a digit, found something else */
+ return 0;
- addr = tmp;
+ addr = tmp;
- if (bits < 0 || bits > 32) /* netmask must be between 0 and 32 */
- return 0;
+ if (bits < 0 || bits > 32) /* netmask must be between 0 and 32 */
+ return 0;
}
else {
- /* Determine (i.e., "guess") netmask by counting the */
- /* number of trailing .0's; reduce #quads appropriately */
- /* (so that 192.168.0.0 is equivalent to 192.168.) */
- while (quads > 0 && ip_addr[quads - 1] == 0)
- --quads;
-
- /* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */
- if (quads < 1)
- return 0;
-
- /* every zero-byte counts as 8 zero-bits */
- bits = 8 * quads;
-
- if (bits != 32) /* no warning for fully qualified IP address */
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
- "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld",
- inet_ntoa(This->addr), bits);
+ /* Determine (i.e., "guess") netmask by counting the */
+ /* number of trailing .0's; reduce #quads appropriately */
+ /* (so that 192.168.0.0 is equivalent to 192.168.) */
+ while (quads > 0 && ip_addr[quads - 1] == 0)
+ --quads;
+
+ /* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */
+ if (quads < 1)
+ return 0;
+
+ /* every zero-byte counts as 8 zero-bits */
+ bits = 8 * quads;
+
+ if (bits != 32) /* no warning for fully qualified IP address */
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld\n",
+ inet_ntoa(This->addr), bits);
}
- This->mask.s_addr = htonl(APR_INADDR_NONE << (32 - bits));
+ This->mask.s_addr = htonl(INADDR_NONE << (32 - bits));
if (*addr == '\0' && (This->addr.s_addr & ~This->mask.s_addr) != 0) {
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "Warning: NetMask and IP-Addr disagree in %s/%ld",
- inet_ntoa(This->addr), bits);
- This->addr.s_addr &= This->mask.s_addr;
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
- " Set to %s/%ld",
- inet_ntoa(This->addr), bits);
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ "Warning: NetMask and IP-Addr disagree in %s/%ld\n",
+ inet_ntoa(This->addr), bits);
+ This->addr.s_addr &= This->mask.s_addr;
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ " Set to %s/%ld\n",
+ inet_ntoa(This->addr), bits);
}
if (*addr == '\0') {
- This->matcher = proxy_match_ipaddr;
- return 1;
+ This->matcher = proxy_match_ipaddr;
+ return 1;
}
else
- return (*addr == '\0'); /* okay iff we've parsed the whole string */
+ return (*addr == '\0'); /* okay iff we've parsed the whole string */
}
/* Return TRUE if addr represents an IP address (or an IP network address) */
memset(ip_addr, '\0', sizeof ip_addr);
if (4 == sscanf(host, "%d.%d.%d.%d", &ip_addr[0], &ip_addr[1], &ip_addr[2], &ip_addr[3])) {
- for (addr.s_addr = 0, i = 0; i < 4; ++i)
- addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
+ for (addr.s_addr = 0, i = 0; i < 4; ++i)
+ addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
- if (This->addr.s_addr == (addr.s_addr & This->mask.s_addr)) {
+ if (This->addr.s_addr == (addr.s_addr & This->mask.s_addr)) {
#if DEBUGGING
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr));
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"%s/", inet_ntoa(This->addr));
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"%s", inet_ntoa(This->mask));
#endif
- return 1;
- }
+ return 1;
+ }
#if DEBUGGING
- else {
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ else {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr));
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"%s/", inet_ntoa(This->addr));
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"%s", inet_ntoa(This->mask));
- }
+ }
#endif
}
else {
- struct hostent the_host;
+ struct hostent the_host;
- memset(&the_host, '\0', sizeof the_host);
- found = ap_proxy_host2addr(host, &the_host);
+ memset(&the_host, '\0', sizeof the_host);
+ found = ap_proxy_host2addr(host, &the_host);
- if (found != NULL) {
+ if (found != NULL) {
#if DEBUGGING
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"2)IP-NoMatch: hostname=%s msg=%s", host, found);
#endif
- return 0;
- }
-
- if (the_host.h_name != NULL)
- found = the_host.h_name;
- else
- found = host;
-
- /* Try to deal with multiple IP addr's for a host */
- for (ip_listptr = the_host.h_addr_list; *ip_listptr; ++ip_listptr) {
- ip_list = (struct in_addr *) *ip_listptr;
- if (This->addr.s_addr == (ip_list->s_addr & This->mask.s_addr)) {
+ return 0;
+ }
+
+ if (the_host.h_name != NULL)
+ found = the_host.h_name;
+ else
+ found = host;
+
+ /* Try to deal with multiple IP addr's for a host */
+ for (ip_listptr = the_host.h_addr_list; *ip_listptr; ++ip_listptr) {
+ ip_list = (struct in_addr *) *ip_listptr;
+ if (This->addr.s_addr == (ip_list->s_addr & This->mask.s_addr)) {
#if DEBUGGING
ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"3)IP-Match: %s[%s] <-> ", found, inet_ntoa(*ip_list));
ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"%s", inet_ntoa(This->mask));
#endif
- return 1;
- }
+ return 1;
+ }
#if DEBUGGING
- else {
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ else {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"3)IP-NoMatch: %s[%s] <-> ", found, inet_ntoa(*ip_list));
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"%s/", inet_ntoa(This->addr));
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"%s", inet_ntoa(This->mask));
- }
+ }
#endif
- }
+ }
}
return 0;
/* Domain name must start with a '.' */
if (addr[0] != '.')
- return 0;
+ return 0;
/* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i)
- continue;
+ continue;
#if 0
if (addr[i] == ':') {
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"@@@@ handle optional port in proxy_is_domainname()");
- /* @@@@ handle optional port */
+ /* @@@@ handle optional port */
}
#endif
if (addr[i] != '\0')
- return 0;
+ return 0;
/* Strip trailing dots */
for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
- addr[i] = '\0';
+ addr[i] = '\0';
This->matcher = proxy_match_domainname;
return 1;
const char *host = proxy_get_host_of_request(r);
int d_len = strlen(This->name), h_len;
- if (host == NULL) /* some error was logged already */
- return 0;
+ if (host == NULL) /* some error was logged already */
+ return 0;
h_len = strlen(host);
/* @@@ do this within the setup? */
/* Ignore trailing dots in domain comparison: */
while (d_len > 0 && This->name[d_len - 1] == '.')
- --d_len;
+ --d_len;
while (h_len > 0 && host[h_len - 1] == '.')
- --h_len;
+ --h_len;
return h_len > d_len
- && strncasecmp(&host[h_len - d_len], This->name, d_len) == 0;
+ && strncasecmp(&host[h_len - d_len], This->name, d_len) == 0;
}
/* Return TRUE if addr represents a host name */
/* Host names must not start with a '.' */
if (addr[0] == '.')
- return 0;
+ return 0;
/* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i);
#if 0
if (addr[i] == ':') {
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"@@@@ handle optional port in proxy_is_hostname()");
- /* @@@@ handle optional port */
+ /* @@@@ handle optional port */
}
#endif
if (addr[i] != '\0' || ap_proxy_host2addr(addr, &host) != NULL)
- return 0;
+ return 0;
This->hostentry = ap_pduphostent (p, &host);
/* Strip trailing dots */
for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
- addr[i] = '\0';
+ addr[i] = '\0';
This->matcher = proxy_match_hostname;
return 1;
/* Try to deal with multiple IP addr's for a host */
for (ip_list = *This->hostentry->h_addr_list; *ip_list != 0UL; ++ip_list)
- if (*ip_list == ? ? ? ? ? ? ? ? ? ? ? ? ?)
- return 1;
+ if (*ip_list == ? ? ? ? ? ? ? ? ? ? ? ? ?)
+ return 1;
#endif
/* Ignore trailing dots in host2 comparison: */
while (h2_len > 0 && host2[h2_len - 1] == '.')
- --h2_len;
+ --h2_len;
while (h1_len > 0 && host[h1_len - 1] == '.')
- --h1_len;
+ --h1_len;
return h1_len == h2_len
- && strncasecmp(host, host2, h1_len) == 0;
+ && strncasecmp(host, host2, h1_len) == 0;
}
/* Return TRUE if addr is to be matched as a word */
int ap_proxy_doconnect(apr_socket_t *sock, char *host, apr_uint32_t port, request_rec *r)
{
int i;
+
for (i = 0; host[i] != '\0'; i++)
if (!apr_isdigit(host[i]) && host[i] != '.')
break;
else if (rv == APR_SUCCESS)
return 0;
else {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy connect to %s port %d failed", host, port);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ "proxy connect to %s port %d failed", host, port);
return -1;
}
}
return -1;
}
-/* This function is called by apr_table_do() for all header lines */
+/* This function is called by ap_table_do() for all header lines */
/* (from proxy_http.c and proxy_ftp.c) */
/* It is passed a table_do_args struct pointer and a MIME field and value pair */
int ap_proxy_send_hdr_line(void *p, const char *key, const char *value)
return 1;
if (!r->assbackwards)
ap_rvputs(r, key, ": ", value, CRLF, NULL);
- return 1; /* tell apr_table_do() to continue calling us for more headers */
+ return 1; /* tell ap_table_do() to continue calling us for more headers */
}
/* send a text line to one or two BUFF's; return line length */
-unsigned ap_proxy_bputs2(const char *data, BUFF *client, ap_cache_el *cache)
+unsigned ap_proxy_bputs2(const char *data, BUFF *client, ap_cache_el *cache)
{
unsigned len = ap_bputs(data, client);
apr_file_t *cachefp = NULL;
-
+
if (ap_cache_el_data(cache, &cachefp) == APR_SUCCESS)
- apr_puts(data, cachefp);
+ apr_puts(data, cachefp);
return len;
}
+#if defined WIN32
+
+static DWORD tls_index;
+
+BOOL WINAPI DllMain (HINSTANCE dllhandle, DWORD reason, LPVOID reserved)
+{
+ LPVOID memptr;
+
+ switch (reason) {
+ case DLL_PROCESS_ATTACH:
+ tls_index = TlsAlloc();
+ case DLL_THREAD_ATTACH: /* intentional no break */
+ TlsSetValue (tls_index, malloc (sizeof (struct per_thread_data)));
+ break;
+ case DLL_THREAD_DETACH:
+ memptr = TlsGetValue (tls_index);
+ if (memptr) {
+ free (memptr);
+ TlsSetValue (tls_index, 0);
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+#endif
+
+static struct per_thread_data *get_per_thread_data(void)
+{
+#if 0
+#if defined(WIN32)
+
+ return (struct per_thread_data *) TlsGetValue (tls_index);
+
+#else
+
+ static APACHE_TLS struct per_thread_data sptd;
+ return &sptd;
+
+#endif
+#endif
+ return NULL;
+}
+
int ap_proxy_cache_send(request_rec *r, ap_cache_el *c)
{
apr_file_t *cachefp = NULL;