martin 98/02/27 07:15:30
Modified: src CHANGES
src/include httpd.h
src/main Makefile.tmpl http_main.c http_protocol.c
http_request.c http_vhost.c
src/modules/proxy mod_proxy.c mod_proxy.h proxy_http.c
proxy_util.c
src/modules/standard mod_log_config.c
Added: src/include util_uri.h
src/main util_uri.c
Log:
For testing purposes, I added a new source called main/util_uri.c;
It contains a routine parse_uri_components_regex() and friends which
tries to break an URI into its parts. These parts are stored in a new
uri_components structure within each request_rec and are therefore
available to all routines which act on a request.
Additionally, an unparse routine is supplied which re-assembles the
URI components back to an URI, optionally hiding the username:password@
part from ftp proxy requests, and other useful routines.
Within the structure, you find on a ready-for-use basis:
scheme; /* scheme ("http"/"ftp"/...) */
hostinfo; /* combined [user[:[EMAIL PROTECTED]:port] */
user; /* user name, as in http://user:[EMAIL PROTECTED]:port/ */
password; /* password, as in http://user:[EMAIL PROTECTED]:port/ */
hostname; /* hostname from URI (or from Host: header) */
port_str; /* port string (integer representation is in "port") */
path; /* the request path (or "/" if only scheme://host was given) */
query; /* Everything after a '?' in the path, if present */
fragment; /* Trailing "#fragment" string, if present */
plus flags to indicate whether the strings have valid values.
This is meant to serve as the platform for *BIG* savings in
code complexity for the proxy module (and maybe the vhost logic).
NOTE: This code is enabled only if the WITH_UTIL_URI define is set;
currently this is not enabled by default. [Martin Kraemer]
Reviewed by: Dean Gaudet (on a previous occasion)
Revision Changes Path
1.671 +24 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.670
retrieving revision 1.671
diff -u -u -r1.670 -r1.671
--- CHANGES 1998/02/27 14:55:02 1.670
+++ CHANGES 1998/02/27 15:15:13 1.671
@@ -1,5 +1,29 @@
Changes with Apache 1.3b6
+ *) For testing purposes, I added a new source called main/util_uri.c;
+ It contains a routine parse_uri_components_regex() and friends which
+ tries to break an URI into its parts. These parts are stored in a new
+ uri_components structure within each request_rec and are therefore
+ available to all routines which act on a request.
+ Additionally, an unparse routine is supplied which re-assembles the
+ URI components back to an URI, optionally hiding the username:password@
+ part from ftp proxy requests, and other useful routines.
+ Within the structure, you find on a ready-for-use basis:
+ scheme; /* scheme ("http"/"ftp"/...) */
+ hostinfo; /* combined [user[:[EMAIL PROTECTED]:port] */
+ user; /* user name, as in http://user:[EMAIL PROTECTED]:port/ */
+ password; /* password, as in http://user:[EMAIL PROTECTED]:port/ */
+ hostname; /* hostname from URI (or from Host: header) */
+ port_str; /* port string (integer representation is in "port") */
+ path; /* the request path (or "/" if only scheme://host was
given) */
+ query; /* Everything after a '?' in the path, if present */
+ fragment; /* Trailing "#fragment" string, if present */
+ plus flags to indicate whether the strings have valid values.
+ This is meant to serve as the platform for *BIG* savings in
+ code complexity for the proxy module (and maybe the vhost logic).
+ NOTE: This code is enabled only if the WITH_UTIL_URI define is set;
+ currently this is not enabled by default. [Martin Kraemer]
+
*) Make all possible meta-construct expansions ($N, %N, %{NAME} and
${map:key}) available for all location where a string is created in
mod_rewrite rewriting rulesets: 1st arg of RewriteCond, 2nd arg of
1.188 +7 -0 apache-1.3/src/include/httpd.h
Index: httpd.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/httpd.h,v
retrieving revision 1.187
retrieving revision 1.188
diff -u -u -r1.187 -r1.188
--- httpd.h 1998/02/18 08:39:21 1.187
+++ httpd.h 1998/02/27 15:15:15 1.188
@@ -537,6 +537,10 @@
typedef struct request_rec request_rec;
typedef struct listen_rec listen_rec;
+#ifdef WITH_UTIL_URI
+#include "util_uri.h"
+#endif
+
struct request_rec {
pool *pool;
@@ -656,6 +660,9 @@
char *path_info;
char *args; /* QUERY_ARGS, if any */
struct stat finfo; /* ST_MODE set to zero if no such file
*/
+#ifdef WITH_UTIL_URI
+ uri_components parsed_uri; /* components of uri, dismantled */
+#endif
/* Various other config info which may change with .htaccess files
* These are config vectors, with one void* pointer for each module
1.1 apache-1.3/src/include/util_uri.h
Index: util_uri.h
===================================================================
/* ====================================================================
* Copyright (c) 1995-1997 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission.
*
* 5. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* util_uri.h: External Interface of util_uri.c
*/
#ifndef UTIL_URI_H
#define UTIL_URI_H
typedef struct {
const char *name;
unsigned short default_port;
} schemes_t;
#define DEFAULT_FTP_DATA_PORT 20
#define DEFAULT_FTP_PORT 21
#define DEFAULT_GOPHER_PORT 70
#define DEFAULT_NNTP_PORT 119
#define DEFAULT_WAIS_PORT 210
#define DEFAULT_HTTPS_PORT 443
#define DEFAULT_SNEWS_PORT 563
#define DEFAULT_PROSPERO_PORT 1525 /* WARNING: conflict w/Oracle */
/* Flags passed to unparse_uri_components(): */
#define UNP_OMITSITEPART (1U<<0) /* suppress "scheme://[EMAIL
PROTECTED]:port" */
#define UNP_OMITUSER (1U<<1) /* Just omit user */
#define UNP_OMITPASSWORD (1U<<2) /* Just omit password */
#define UNP_OMITUSERINFO (UNP_OMITUSER|UNP_OMITPASSWORD) /* omit
"user:password@" part */
#define UNP_REVEALPASSWORD (1U<<3) /* Show plain text password
(default: show XXXXXXXX) */
typedef struct {
char *scheme; /* scheme ("http"/"ftp"/...) */
char *hostinfo; /* combined [user[:[EMAIL PROTECTED]:port] */
char *user; /* user name, as in http://user:[EMAIL
PROTECTED]:port/ */
char *password; /* password, as in http://user:[EMAIL
PROTECTED]:port/ */
char *hostname; /* hostname from URI (or from Host: header) */
char *port_str; /* port string (integer representation is in
"port") */
char *path; /* the request path (or "/" if only
scheme://host was given) */
char *query; /* Everything after a '?' in the path, if
present */
char *fragment; /* Trailing "#fragment" string, if present */
struct hostent *hostent;
unsigned hostlen; /* strlen("scheme://[user[:[EMAIL
PROTECTED]:port]") */
unsigned short port; /* The port number, numeric */
unsigned is_initialized:1;
unsigned has_scheme:1;
unsigned has_hostinfo:1;
unsigned has_user:1;
unsigned has_password:1;
unsigned has_hostname:1;
unsigned has_port:1;
unsigned has_path:1;
unsigned has_query:1;
unsigned has_fragment:1;
unsigned dns_looked_up:1;
unsigned dns_resolved:1;
} uri_components;
/* util_uri.c */
extern unsigned short default_port_for_scheme(const char *scheme_str);
extern unsigned short default_port_for_request(const request_rec *r);
extern struct hostent *pduphostent(pool *p, struct hostent *hp);
extern struct hostent *pgethostbyname(pool *p, const char *hostname);
extern char *unparse_uri_components(pool *p, const uri_components *uptr,
int *pHostlen, unsigned flags);
extern int parse_uri_components(pool *p, const char *uri, uri_components
*uptr,
int *pHostlen);
extern int parse_uri_components_regex(pool *p, const char *uri,
uri_components *uptr);
#endif /*UTIL_URI_H*/
1.13 +1 -1 apache-1.3/src/main/Makefile.tmpl
Index: Makefile.tmpl
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/Makefile.tmpl,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -u -r1.12 -r1.13
--- Makefile.tmpl 1998/02/23 00:04:43 1.12
+++ Makefile.tmpl 1998/02/27 15:15:18 1.13
@@ -11,7 +11,7 @@
OBJS= alloc.o http_main.o http_core.o http_config.o http_request.o \
http_log.o http_protocol.o rfc1413.o util.o util_script.o buff.o \
- md5c.o util_md5.o http_bprintf.o util_date.o \
+ md5c.o util_md5.o http_bprintf.o util_date.o util_uri.o \
fnmatch.o http_vhost.o
.c.o:
1.296 +3 -0 apache-1.3/src/main/http_main.c
Index: http_main.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.295
retrieving revision 1.296
diff -u -u -r1.295 -r1.296
--- http_main.c 1998/02/24 12:27:19 1.295
+++ http_main.c 1998/02/27 15:15:19 1.296
@@ -2886,6 +2886,9 @@
#ifdef NEED_HASHBANG_EMUL
printf(" -D NEED_HASHBANG_EMUL\n");
#endif
+#ifdef WITH_UTIL_URI
+ printf(" -D WITH_UTIL_URI\n");
+#endif
printf("\n");
}
1.192 +134 -0 apache-1.3/src/main/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
retrieving revision 1.191
retrieving revision 1.192
diff -u -u -r1.191 -r1.192
--- http_protocol.c 1998/02/22 21:37:47 1.191
+++ http_protocol.c 1998/02/27 15:15:20 1.192
@@ -570,8 +570,71 @@
return total;
}
+
+/* parse_uri: check uri, determine whether proxy request, TRACE, or local
request
+ * Side Effects:
+ * - sets r->proxyreq if "scheme://host:port" found
+ * - sets r->args to rest after '?' (or NULL if no '?') unless TRACE or
proxy req.
+ * - sets r->uri to request uri (without r->args part unless TRACE or proxy
req.)
+ *#ifdef WITH_UTIL_URI
+ * - sets r->hostname (if not set already) from request (scheme://host:port)
+ * - sets r->hostlen to length of "scheme://...host:port" prefix
+ *#endif
+ */
void parse_uri(request_rec *r, const char *uri)
{
+#ifdef WITH_UTIL_URI
+ int hostlen = 0;
+ int status = HTTP_OK;
+
+ /* If an identical uri was parsed before, return without action */
+ if (r->parsed_uri.is_initialized && r->uri && strcmp(uri, r->uri) == 0)
+ return;
+
+ /* Simple syntax Errors in URLs are trapped by parse_uri_components(). */
+ status = parse_uri_components_regex(r->pool, uri, &r->parsed_uri);
+
+ if (is_HTTP_SUCCESS(status)) {
+
+ r->hostlen = r->parsed_uri.hostlen;
+
+ /* if hostlen is 0, it's not a proxy request */
+ r->proxyreq = (r->hostlen > 0);
+
+ if (!r->proxyreq) {
+ r->hostname = NULL;
+
+ if (r->method && !strcmp(r->method, "TRACE")) {
+ /* don't split into path & args for TRACE requests */
+ r->args = NULL;
+ r->uri = pstrdup(r->pool, uri);
+ }
+ else {
+ r->uri = r->parsed_uri.has_path ? r->parsed_uri.path : "/";
+ r->args = r->parsed_uri.query;
+ }
+ }
+ else {
+ if (r->hostlen == strlen(uri))
+ /* the request is just http://hostname - no trailing slash.
+ * Provide one:
+ */
+ r->uri = pstrcat(r->pool, uri, "/", NULL);
+ else
+ r->uri = pstrdup(r->pool, uri);
+ r->hostname = r->parsed_uri.hostname;
+ /* no args splitting for proxy requests */
+ r->args = NULL;
+ }
+ }
+ else {
+ r->args = NULL;
+ r->hostlen = 0;
+ r->hostname = NULL;
+ r->status = status; /* set error status */
+ r->uri = pstrdup(r->pool, uri);
+ }
+#else /*WITH_UTIL_URI*/
const char *s;
#if defined(__EMX__) || defined(WIN32)
@@ -621,8 +684,16 @@
else
r->args = NULL;
}
+#endif /*WITH_UTIL_URI*/
}
+/* check_fulluri: check full uri against main server names/addresses
+ * Side Effects:
+ *#ifndef WITH_UTIL_URI
+ * - sets r->hostname (if not set already) from request (scheme://host:port)
+ * - sets r->hostlen to length of "scheme://host:port" part
+ *#endif
+ */
const char *check_fulluri(request_rec *r, const char *uri)
{
char *host, *proto, *slash, *colon;
@@ -630,6 +701,63 @@
unsigned port;
const char *res_uri;
+#ifdef WITH_UTIL_URI
+ if (!r->parsed_uri.has_hostname
+ || !r->parsed_uri.has_scheme
+ || strcasecmp(r->parsed_uri.scheme, "http") != 0)
+ return uri;
+
+ /* Note: There's no use comparing against
ntohs(r->connection->local_addr.sin_port)
+ * here, because in a proxy request, the two have nothing in common.
+ */
+ /* Make sure ports match */
+ port = (r->parsed_uri.has_port) ? r->parsed_uri.port :
default_port_for_request(r);
+ if (port != r->server->port)
+ return uri;
+
+ host = r->parsed_uri.hostname;
+
+ /* Easy simplification: If main server host name and port match,
+ * then this request is rewritten from a net_path to an abs_path
+ * and reduced from a proxyreq to a local request.
+ */
+ if (strcasecmp(host, r->server->server_hostname) == 0
+ || strcmp(host, inet_ntoa(r->connection->local_addr.sin_addr)) == 0)
+ {
+ r->proxyreq = 0;
+ r->uri += r->hostlen;
+ r->hostlen = 0;
+ }
+ else {
+ /* Now things get a bit trickier - check the IP address(es) of
+ * the host they gave, see if it matches ours.
+ */
+ struct hostent *hp;
+ int n;
+ if (r->parsed_uri.dns_looked_up)
+ /* looked up earlier; re-use: */
+ hp = r->parsed_uri.hostent;
+ else {
+ hp = pgethostbyname(r->pool, host);
+ r->parsed_uri.dns_looked_up = 1;
+ r->parsed_uri.dns_resolved = (hp != NULL);
+ r->parsed_uri.hostent = hp;
+ }
+
+ if (r->parsed_uri.dns_resolved) {
+ for (n = 0; hp->h_addr_list[n] != NULL; n++) {
+ if (r->connection->local_addr.sin_addr.s_addr ==
+ (((struct in_addr *) (hp->h_addr_list[n]))->s_addr)) {
+ r->proxyreq = 0;
+ r->uri += r->hostlen;
+ r->hostlen = 0;
+ break;
+ }
+ }
+ }
+ }
+ return r->uri;
+#else /*WITH_UTIL_URI*/
/* This routine parses full URLs, if they match the server */
proto = http_method(r);
plen = strlen(proto);
@@ -698,6 +826,7 @@
}
return uri;
+#endif /*WITH_UTIL_URI*/
}
int read_request_line(request_rec *r)
@@ -746,8 +875,13 @@
r->the_request = pstrdup(r->pool, l);
r->method = getword_white(r->pool, &ll);
uri = getword_white(r->pool, &ll);
+#ifdef WITH_UTIL_URI
+ parse_uri(r, uri);
+ r->uri = pstrdup(r->pool, check_fulluri(r, r->uri)); /* r->uri isn't
const, so copy */
+#else
uri = check_fulluri(r, uri);
parse_uri(r, uri);
+#endif
r->assbackwards = (ll[0] == '\0');
r->protocol = pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");
1.108 +8 -1 apache-1.3/src/main/http_request.c
Index: http_request.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_request.c,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -u -r1.107 -r1.108
--- http_request.c 1998/02/18 10:01:14 1.107
+++ http_request.c 1998/02/27 15:15:21 1.108
@@ -749,6 +749,9 @@
rnew->uri = make_full_path(rnew->pool, udir, new_file);
rnew->filename = make_full_path(rnew->pool, fdir, new_file);
+#ifdef WITH_UTIL_URI
+ parse_uri(rnew, rnew->uri); /* fill in parsed_uri values */
+#endif
if (stat(rnew->filename, &rnew->finfo) < 0) {
rnew->finfo.st_mode = 0;
}
@@ -794,6 +797,10 @@
}
}
else {
+#ifdef WITH_UTIL_URI
+ /* XXX: @@@: What should be done with the parsed_uri values? */
+ parse_uri(rnew, new_file); /* fill in parsed_uri values */
+#endif
/*
* XXX: this should be set properly like it is in the same-dir case
* but it's actually sometimes to impossible to do it... because the
@@ -1196,7 +1203,7 @@
new->pool = r->pool;
/*
- * A whole lot of this really ought to be shared with protocol.c...
+ * A whole lot of this really ought to be shared with http_protocol.c...
* another missing cleanup. It's particularly inappropriate to be
* setting header_only, etc., here.
*/
1.7 +4 -0 apache-1.3/src/main/http_vhost.c
Index: http_vhost.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_vhost.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -u -r1.6 -r1.7
--- http_vhost.c 1998/02/01 21:19:30 1.6
+++ http_vhost.c 1998/02/27 15:15:21 1.7
@@ -329,6 +329,9 @@
* whack of /24s. This is probably the most common configuration for
* ISPs with large virtual servers.
*
+ * NOTE: This function is symmetric (i.e. collapses all 4 octets
+ * into one), so machine byte order (big/little endianness) does not matter.
+ *
* Hash function provided by David Hankins.
*/
static ap_inline unsigned hash_inaddr(unsigned key)
@@ -689,6 +692,7 @@
r->server = r->connection->server = s;
if (r->hostlen && !strncasecmp(r->uri, "http://", 7)) {
r->uri += r->hostlen;
+ r->proxyreq = 0;
parse_uri(r, r->uri);
}
}
1.1 apache-1.3/src/main/util_uri.c
Index: util_uri.c
===================================================================
/* ====================================================================
* Copyright (c) 1995-1997 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission.
*
* 5. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* util_uri.c: URI related utility things
*
*/
#include "httpd.h"
#include "http_log.h"
#include "http_conf_globals.h" /* for user_id & group_id */
#include "util_uri.h"
/* Some WWW schemes and their default ports; this is basically /etc/services
*/
/* This will become global when the protocol abstraction comes */
static schemes_t schemes[] =
{
{"ftp", DEFAULT_FTP_PORT},
{"gopher", DEFAULT_GOPHER_PORT},
{"http", DEFAULT_HTTP_PORT},
{"nntp", DEFAULT_NNTP_PORT},
{"wais", DEFAULT_WAIS_PORT},
{"https", DEFAULT_HTTPS_PORT},
{"snews", DEFAULT_SNEWS_PORT},
{"prospero", DEFAULT_PROSPERO_PORT},
{ NULL, 0xFFFF } /* unknown port */
};
unsigned short default_port_for_scheme(const char *scheme_str)
{
schemes_t *scheme;
for (scheme = schemes; scheme->name != NULL; ++scheme)
if (strcasecmp(scheme_str, scheme->name) == 0)
return scheme->default_port;
return 0;
}
#ifdef WITH_UTIL_URI
unsigned short default_port_for_request(const request_rec *r)
{
return (r->parsed_uri.has_scheme)
? default_port_for_scheme(r->parsed_uri.scheme)
: 0;
}
#endif /*WITH_UTIL_URI*/
static unsigned short default_port_for_uri_components(const uri_components
*uri_p)
{
return (uri_p->has_scheme)
? default_port_for_scheme(uri_p->scheme)
: 0;
}
/* Create a copy of a "struct hostent" record; it was presumably returned
* from a call to gethostbyname() and lives in static storage.
* By creating a copy we can tuck it away for later use.
*/
struct hostent *pduphostent(pool *p, struct hostent *hp)
{
struct hostent *newent;
char **ptrs;
char **aliases;
struct in_addr *addrs;
int i = 0, j = 0;
if (hp == NULL)
return hp;
/* Count number of alias entries */
if (hp->h_aliases != NULL)
for (; hp->h_aliases[j] != NULL; ++j)
continue;
/* Count number of in_addr entries */
if (hp->h_addr_list != NULL)
for (; hp->h_addr_list[i] != NULL; ++i)
continue;
/* Allocate hostent structure, alias ptrs, addr ptrs, addrs */
newent = (struct hostent *) palloc(p, sizeof(*hp));
aliases = (char **) palloc(p, (j+1) * sizeof(char*));
ptrs = (char **) palloc(p, (i+1) * sizeof(char*));
addrs = (struct in_addr *) palloc(p, (i+1) * sizeof(struct in_addr));
*newent = *hp;
newent->h_name = pstrdup(p, hp->h_name);
newent->h_aliases = aliases;
newent->h_addr_list = (char**) ptrs;
/* Copy Alias Names: */
for (j = 0; hp->h_aliases[j] != NULL; ++j) {
aliases[j] = pstrdup(p, hp->h_aliases[j]);
}
aliases[j] = NULL;
/* Copy address entries */
for (i = 0; hp->h_addr_list[i] != NULL; ++i) {
ptrs[i] = (char*) &addrs[i];
addrs[i] = *(struct in_addr *) hp->h_addr_list[i];
}
ptrs[i] = NULL;
return newent;
}
/* pgethostbyname(): resolve hostname, if successful return an ALLOCATED
* COPY OF the hostent structure, intended to be stored and used later.
* (gethostbyname() uses static storage that would be overwritten on each
call)
*/
struct hostent *pgethostbyname(pool *p, const char *hostname)
{
struct hostent *hp = gethostbyname(hostname);
return (hp == NULL) ? NULL : pduphostent(p, hp);
}
/* Unparse a uri_components structure to an URI string.
* Optionally suppress the password for security reasons.
*/
char *unparse_uri_components(pool *p, const uri_components *uptr, int
*pHostlen, unsigned flags)
{
char *ret = "";
/* Construct a "user:password@" string, honoring the passed UNP_ flags: */
if (uptr->has_user||uptr->has_password)
ret = pstrcat (p,
(uptr->has_user && !(flags & UNP_OMITUSER)) ? uptr->user :
"",
(uptr->has_password && !(flags & UNP_OMITPASSWORD)) ? ":" : "",
(uptr->has_password && !(flags & UNP_OMITPASSWORD))
? ((flags & UNP_REVEALPASSWORD) ? uptr->password :
"XXXXXXXX")
: "",
"@", NULL);
/* Construct scheme://site string */
if (uptr->has_hostname && !(flags & UNP_OMITSITEPART)) {
ret = pstrcat (p,
uptr->scheme, "://", ret,
uptr->has_hostname ? uptr->hostname : "",
uptr->has_port ? ":" : "",
uptr->has_port ? uptr->port_str : "",
NULL);
}
/* Return length constructed so far (the famous "hostlen") */
if (pHostlen != NULL)
*pHostlen = strlen(ret);
/* Append path, query and fragment strings: */
ret = pstrcat (p,
ret,
uptr->path,
uptr->has_query ? "?" : "",
uptr->has_query ? uptr->query : "",
uptr->has_fragment ? "#" : NULL,
uptr->has_fragment ? uptr->fragment : NULL,
NULL);
return ret;
}
/* parse_uri_components():
* Parse a given URI, fill in all supplied fields of a uri_components
* structure. This eliminates the necessity of extracting host, port,
* path, query info repeatedly in the modules.
* Side effects:
* - fills in fields of uri_components *uptr
* - none on any of the r->* fields
*/
int parse_uri_components(pool *p, const char *uri, uri_components *uptr, int
*pHostlen)
{
const char *s;
int ret = HTTP_OK;
int hostlen = 0;
/* Initialize the structure. parse_uri() and parse_uri_components()
* can be called more than once per request.
*/
memset (uptr, '\0', sizeof(*uptr));
uptr->is_initialized = 1;
/* A proxy request contains a ':' early on (after the scheme),
* but not as first character. RFC1738 allows [a-zA-Z0-9-+.]:
*/
for (s = uri; s != '\0'; s++)
if (!isalnum(*s) && *s != '+' && *s != '-' && *s != '.')
break;
if (s == uri || s[0] != ':' || s[1] == '\0') {
/* not a full URL (not: scheme://host/path), so no proxy request: */
/* Store path, without the optional "?query" argument: */
uptr->has_path = 1;
uptr->path = getword (p, &uri, '?');
uptr->has_query = (uri[0] != '\0');
uptr->query = (uptr->has_query) ? pstrdup(p, uri) : NULL;
#if defined(__EMX__) || defined(WIN32)
/* Handle path translations for OS/2 and plug security hole.
* This will prevent "http://www.wherever.com/..\..\/" from
* returning a directory for the root drive.
*/
for (s = uptr->path; (s = strchr(s, '\\')) != NULL; )
*s = '/';
#ifndef WIN32 /* for OS/2 only: */
/* Fix OS/2 HPFS filename case problem. */
uptr->path = strlwr(uptr->path);
#endif
#endif /* __EMX__ || WIN32 */
}
else {
/* Yes, it is a proxy request. We've detected the scheme, now
* we split the URI's components and mark what we've found:
* - scheme
* followed by "://", then:
* - [ username [ ":" password ] "@" ]
* - hostname
* [ ":" port ]
* [ "/" path ... [ "?" query ] ]
*/
/* As per RFC1738:
* The generic form of a URL is:
* genericurl = scheme ":" schemepart
*
* the scheme is in lower case; interpreters should use case-ignore
* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ]
*
* Extract the scheme:
*/
s = uri;
uptr->scheme = getword(p, &s, ':');
uptr->has_scheme = 1;
/* URL schemeparts for ip based protocols:
*
* ip-schemepart = "//" login [ "/" urlpath ]
*
* login = [ user [ ":" password ] "@" ] hostport
* hostport = host [ ":" port ]
* host = hostname | hostnumber
* hostname = *[ domainlabel "." ] toplabel
* domainlabel = alphadigit | alphadigit *[ alphadigit | "-" ]
alphadigit
* toplabel = alpha | alpha *[ alphadigit | "-" ] alphadigit
* alphadigit = alpha | digit
* hostnumber = digits "." digits "." digits "." digits
* port = digits
* user = *[ uchar | ";" | "?" | "&" | "=" ]
* password = *[ uchar | ";" | "?" | "&" | "=" ]
* urlpath = *xchar
*/
/* if IP-schemepart follows, extract host, port etc. */
if (s[0] == '/' && s[1] == '/') {
char *tmp;
s += 2;
if ((tmp = strchr(s, '/')) != NULL) {
hostlen = (tmp - uri);
/* In the request_rec structure, the uri is not
* separated into path & query for proxy requests.
* But here, we want maximum knowledge about the request,
* so we still split them. */
uptr->has_path = 1;
uptr->path = getword_nc(p, &tmp, '?');
uptr->has_query = (tmp[0] != '\0');
uptr->query = (uptr->has_query) ? pstrdup(p, tmp) : NULL;
}
else {
/* the request is just http://hostname - no trailing slash.
* Provide one:
*/
uptr->path = "/";
uptr->has_path = 1;
uptr->has_query = 0;
hostlen = strlen(uri);
}
uptr->hostname = getword (p, &s, '/');
uptr->has_hostname = uptr->hostname[0] != '\0';
/* disintegrate "[EMAIL PROTECTED]" */
/* NOTE: using reverse search here because user:password might
* contain a '@' as well (ftp login: user=ftp : [EMAIL PROTECTED])
*/
if ((tmp = strrchr(uptr->hostname, '@')) != NULL) {
uptr->user = uptr->hostname;
uptr->has_user = 1;
*tmp++ = '\0';
uptr->hostname = tmp;
/* disintegrate "user:password" */
if ((tmp = strchr(uptr->user, ':')) != NULL) {
*tmp++ = '\0';
uptr->password = tmp;
uptr->has_password = 1;
}
}
/* disintegrate "host:port" */
if ((tmp = strchr(uptr->hostname, ':')) != NULL) {
*tmp++ = '\0';
uptr->port_str = tmp;
uptr->port = (unsigned short) strtol(tmp, &tmp, 10);
uptr->has_port = 1;
/* Catch possible problem: http://www.apache.org:80@@@/dist/ */
if (*tmp != '\0')
ret = HTTP_BAD_REQUEST;
}
/* Strip any trailing dots in hostname */
tmp = &uptr->hostname[strlen(uptr->hostname)-1];
for (; *tmp == '.' && tmp > uptr->hostname; --tmp)
*tmp = '\0';
/* This name hasn't been looked up yet */
uptr->dns_looked_up = 0;
}
/* If the ip-schemepart doesn't start with "//", deny: */
else
ret = HTTP_BAD_REQUEST;
}
/* If caller is interested in the length of the scheme://...host:port
prefix: */
if (pHostlen != NULL)
*pHostlen = hostlen;
return ret;
}
/* parse_uri_components_regex():
* Parse a given URI, fill in all supplied fields of a uri_components
* structure. This eliminates the necessity of extracting host, port,
* path, query info repeatedly in the modules.
* Side effects:
* - fills in fields of uri_components *uptr
* - none on any of the r->* fields
*/
int parse_uri_components_regex(pool *p, const char *uri, uri_components *uptr)
{
int ret = HTTP_OK;
static struct {
regex_t uri;
regex_t hostpart;
regmatch_t match[10]; /* This must have at least as much elements
* as there are braces in the re_strings */
unsigned is_initialized:1;
} re = { 0, 0, 0 };
ap_assert (uptr != NULL);
/* Initialize the structure. parse_uri() and parse_uri_components()
* can be called more than once per request.
*/
memset (uptr, '\0', sizeof(*uptr));
uptr->is_initialized = 1;
if (!re.is_initialized) {
const char *re_str;
re.is_initialized = 1;
/* This is a modified version of the regex that appeared in
* http://www.ics.uci.edu/~fielding/url/url.txt
* It doesnt allow the uri to contain a scheme but no hostinfo
* or vice versa.
* $ 12 3 4 5 6 7 8 */
re_str = "^(([^:/?#]+)://([^/?#]+))?([^?#]*)(\\?([^#]*))?(#(.*))?";
/* ^^scheme^^://^^site^^^ ^^path^^ ?^query^ #frag */
if ((ret = regcomp(&re.uri, re_str, REG_EXTENDED)) != 0)
{
char line[1024];
/* Make a readable error message */
ret = regerror(ret, &re.uri, line, sizeof line);
aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"Internal error: regcomp(\"%s\") returned non-zero (%s) -
"
"possibly due to broken regex lib! "
"Did you define WANTHSREGEX=yes?",
re_str, line);
return HTTP_INTERNAL_SERVER_ERROR;
}
/* This is a sub-RE which will break down the hostinfo part,
* i.e., user, password, hostname and port.
* $ 12 3 4 5 6 */
re_str = "^(([^:]*):(.*)?@)?([^@:]*)(:(.*))?$";
/* ^^user^ :pw ^host^ port */
if ((ret = regcomp(&re.hostpart, re_str, REG_EXTENDED|REG_ICASE)) != 0)
{
char line[1024];
/* Make a readable error message */
ret = regerror(ret, &re.hostpart, line, sizeof line);
aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"Internal error: regcomp(\"%s\") returned non-zero (%s) -
"
"possibly due to broken regex lib! "
"Did you define WANTHSREGEX=yes?",
re_str, line);
return HTTP_INTERNAL_SERVER_ERROR;
}
}
ret = regexec(&re.uri, uri, re.uri.re_nsub, re.match, 0);
if (ret != 0) {
aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"regexec() could not parse uri (\"%s\")",
uri);
return HTTP_BAD_REQUEST;
}
/* if hostlen is 0, it's not a proxy request */
uptr->hostlen = (re.match[1].rm_eo - re.match[1].rm_so);
uptr->has_scheme = (re.match[2].rm_so != re.match[2].rm_eo);
uptr->has_hostinfo = (re.match[3].rm_so != re.match[3].rm_eo);
uptr->has_path = (re.match[4].rm_so != re.match[4].rm_eo);
uptr->has_query = (re.match[5].rm_so != re.match[5].rm_eo);
uptr->has_fragment = (re.match[7].rm_so != re.match[7].rm_eo);
if (uptr->has_scheme)
uptr->scheme = pstrndup (p, uri+re.match[2].rm_so, re.match[2].rm_eo -
re.match[2].rm_so);
if (uptr->has_hostinfo)
uptr->hostinfo = pstrndup (p, uri+re.match[3].rm_so, re.match[3].rm_eo
- re.match[3].rm_so);
if (uptr->has_path)
uptr->path = pstrndup (p, uri+re.match[4].rm_so, re.match[4].rm_eo -
re.match[4].rm_so);
if (uptr->has_query)
uptr->query = pstrndup (p, uri+re.match[6].rm_so, re.match[6].rm_eo -
re.match[6].rm_so);
if (uptr->has_fragment)
uptr->fragment = pstrndup (p, uri+re.match[7].rm_so, re.match[7].rm_eo
- re.match[7].rm_so);
if (uptr->has_hostinfo) {
/* Parse the hostinfo part to extract user, password, host, and port */
ret = regexec(&re.hostpart, uptr->hostinfo, re.hostpart.re_nsub,
re.match, 0);
if (ret != 0) {
aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"regexec() could not parse (\"%s\") as host part",
uptr->hostinfo);
return HTTP_BAD_REQUEST;
}
/* $ 12 3 4 5 6 */
/* = "^(([^:]*):(.*)?@)?([^@:]*)(:([0-9]*))?$" */
/* ^^user^ :pw ^host^ port */
if (uptr->has_user = (re.match[2].rm_so != re.match[2].rm_eo))
uptr->user = pstrndup (p, uptr->hostinfo+re.match[2].rm_so,
re.match[2].rm_eo - re.match[2].rm_so);
if (uptr->has_password = (re.match[3].rm_so != re.match[3].rm_eo))
uptr->password = pstrndup (p, uptr->hostinfo+re.match[3].rm_so,
re.match[3].rm_eo - re.match[3].rm_so);
if (uptr->has_hostname = (re.match[4].rm_so != re.match[4].rm_eo))
uptr->hostname = pstrndup (p, uptr->hostinfo+re.match[4].rm_so,
re.match[4].rm_eo - re.match[4].rm_so);
if (uptr->has_port = (re.match[5].rm_so != re.match[5].rm_eo)) {
uptr->port_str = pstrndup (p, uptr->hostinfo+re.match[5].rm_so+1,
re.match[5].rm_eo - re.match[5].rm_so-1);
/* Note that the port string can be empty.
* If it is, we use the default port associated with the scheme
*/
if (uptr->port_str[0] != '\0') {
char *endstr;
uptr->port = strtoul(uptr->port_str, &endstr, 10);
if (*endstr != '\0')
/* Invalid characters after ':' found */
return HTTP_BAD_REQUEST;
} else
uptr->port = default_port_for_scheme(uptr->scheme);
}
}
#if defined(__EMX__) || defined(WIN32)
/* Handle path translations for OS/2 and plug security hole.
* This will prevent "http://www.wherever.com/..\..\/" from
* returning a directory for the root drive.
*/
{
char *s;
for (s = uptr->path; (s = strchr(s, '\\')) != NULL; )
*s = '/';
}
#ifndef WIN32 /* for OS/2 only: */
/* Fix OS/2 HPFS filename case problem. */
str_tolower(uptr->path);
#endif
#endif /* __EMX__ || WIN32 */
if (ret == 0)
ret = HTTP_OK;
return ret;
}
1.41 +70 -8 apache-1.3/src/modules/proxy/mod_proxy.c
Index: mod_proxy.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/proxy/mod_proxy.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -u -r1.40 -r1.41
--- mod_proxy.c 1998/02/27 14:47:15 1.40
+++ mod_proxy.c 1998/02/27 15:15:24 1.41
@@ -164,14 +164,31 @@
char *url, *p;
int i;
- if (strncmp(r->filename, "proxy:", 6) != 0)
+ if (!r->proxyreq || strncmp(r->filename, "proxy:", 6) != 0)
return DECLINED;
url = &r->filename[6];
+
+#ifdef WITH_UTIL_URI
+
+ if (!r->parsed_uri.has_scheme) {
+ return DECLINED;
+ }
+
+/* canonicalise each specific scheme */
+ if (strcasecmp(r->parsed_uri.scheme, "http") == 0)
+ return proxy_http_canon(r, url + 5, "http",
default_port_for_scheme(r->parsed_uri.scheme));
+ else if (strcasecmp(r->parsed_uri.scheme, "ftp") == 0)
+ return proxy_ftp_canon(r, url + 4);
+ else
+ return OK; /* otherwise; we've done the best we can */
+
+#else /*WITH_UTIL_URI*/
+
/* lowercase the scheme */
p = strchr(url, ':');
if (p == NULL || p == url)
- return BAD_REQUEST;
+ return HTTP_BAD_REQUEST;
for (i = 0; i != p - url; i++)
url[i] = tolower(url[i]);
@@ -182,6 +199,8 @@
return proxy_ftp_canon(r, url + 4);
else
return OK; /* otherwise; we've done the best we can */
+
+#endif /*WITH_UTIL_URI*/
}
static void proxy_init(server_rec *r, pool *p)
@@ -199,6 +218,42 @@
/* The "ProxyDomain" directive determines what domain will be appended */
static int proxy_needsdomain(request_rec *r, const char *url, const char
*domain)
{
+#ifdef WITH_UTIL_URI
+ char *nuri, *ref;
+ char strport[10];
+
+ /* We only want to worry about GETs */
+ if (!r->proxyreq || r->method_number != M_GET
+ || !r->parsed_uri.has_hostname)
+ return DECLINED;
+
+ /* If host does contain a dot already, or it is "localhost", decline */
+ if (strchr(r->parsed_uri.hostname, '.') != NULL
+ || strcasecmp(r->parsed_uri.hostname, "localhost") == 0)
+ return DECLINED; /* host name has a dot already */
+
+ ref = table_get(r->headers_in, "Referer");
+
+ /* Reassemble the request, but insert the domain after the host name */
+ /* Note that the domain name always starts with a dot */
+ r->parsed_uri.hostname = pstrcat(r->pool, r->parsed_uri.hostname,
+ domain, NULL);
+ nuri = unparse_uri_components(r->pool,
+ &r->parsed_uri,
+ &r->parsed_uri.hostlen,
+ UNP_REVEALPASSWORD);
+
+ table_set(r->headers_out, "Location", nuri);
+ aplog_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server,
+ "Domain missing: %s sent to %s%s%s", r->uri,
+ unparse_uri_components(r->pool, &r->parsed_uri,
+ &r->parsed_uri.hostlen, UNP_OMITUSERINFO),
+ ref ? " from " : "", ref ? ref : "");
+
+ return HTTP_MOVED_PERMANENTLY;
+
+#else /*WITH_UTIL_URI*/
+
char *scheme = pstrdup(r->pool, url);
char *url_copy, *user = NULL, *password = NULL, *path, *err, *host;
int port = -1;
@@ -258,6 +313,8 @@
return HTTP_MOVED_PERMANENTLY;
}
+
+#endif /*WITH_UTIL_URI*/
}
/* -------------------------------------------------------------- */
@@ -275,7 +332,7 @@
struct cache_req *cr;
int direct_connect = 0;
- if (strncmp(r->filename, "proxy:", 6) != 0)
+ if (!r->proxyreq || strncmp(r->filename, "proxy:", 6) != 0)
return DECLINED;
if ((rc = setup_client_block(r, REQUEST_CHUNKED_ERROR)))
@@ -284,16 +341,18 @@
url = r->filename + 6;
p = strchr(url, ':');
if (p == NULL)
- return BAD_REQUEST;
+ return HTTP_BAD_REQUEST;
rc = proxy_cache_check(r, url, &conf->cache, &cr);
if (rc != DECLINED)
return rc;
/* If the host doesn't have a domain name, add one and redirect. */
- if (conf->domain != NULL
- && proxy_needsdomain(r, url, conf->domain) == REDIRECT)
- return REDIRECT;
+ if (conf->domain != NULL) {
+ rc = proxy_needsdomain(r, url, conf->domain);
+ if (is_HTTP_REDIRECT(rc))
+ return HTTP_MOVED_PERMANENTLY;
+ }
*p = '\0';
scheme = pstrdup(r->pool, url);
@@ -348,7 +407,7 @@
rc = DECLINED;
/* an error or success */
- if (rc != DECLINED && rc != BAD_GATEWAY)
+ if (rc != DECLINED && rc != HTTP_BAD_GATEWAY)
return rc;
/* we failed to talk to the upstream proxy */
}
@@ -523,6 +582,9 @@
if (!found) {
New = push_array(conf->dirconn);
New->name = arg;
+#ifdef WITH_UTIL_URI
+ New->hostentry = NULL;;
+#endif /*WITH_UTIL_URI*/
if (proxy_is_ipaddr(New, parms->pool)) {
#if DEBUGGING
1.30 +4 -0 apache-1.3/src/modules/proxy/mod_proxy.h
Index: mod_proxy.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/proxy/mod_proxy.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -u -r1.29 -r1.30
--- mod_proxy.h 1998/02/27 10:18:39 1.29
+++ mod_proxy.h 1998/02/27 15:15:25 1.30
@@ -162,7 +162,11 @@
struct dirconn_entry {
char *name;
struct in_addr addr, mask;
+#ifdef WITH_UTIL_URI
+ struct hostent *hostentry;
+#else /*WITH_UTIL_URI*/
struct hostent hostlist;
+#endif /*WITH_UTIL_URI*/
int (*matcher) (struct dirconn_entry * This, request_rec *r);
};
1.40 +4 -4 apache-1.3/src/modules/proxy/proxy_http.c
Index: proxy_http.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_http.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -u -r1.39 -r1.40
--- proxy_http.c 1998/02/23 08:04:11 1.39
+++ proxy_http.c 1998/02/27 15:15:26 1.40
@@ -77,7 +77,7 @@
port = def_port;
err = proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
if (err)
- return 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_
@@ -94,13 +94,13 @@
/* process path */
path = proxy_canonenc(r->pool, url, strlen(url), enc_path, r->proxyreq);
if (path == NULL)
- return BAD_REQUEST;
+ return HTTP_BAD_REQUEST;
/* process search */
if (p != NULL) {
search = p;
if (search == NULL)
- return BAD_REQUEST;
+ return HTTP_BAD_REQUEST;
}
else
search = NULL;
@@ -252,7 +252,7 @@
if (sock == -1) {
aplog_error(APLOG_MARK, APLOG_ERR, r->server,
"proxy: error creating socket");
- return SERVER_ERROR;
+ return HTTP_INTERNAL_SERVER_ERROR;
}
if (conf->recv_buffer_size) {
1.45 +17 -15 apache-1.3/src/modules/proxy/proxy_util.c
Index: proxy_util.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_util.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -u -r1.44 -r1.45
--- proxy_util.c 1998/02/27 10:18:40 1.44
+++ proxy_util.c 1998/02/27 15:15:26 1.45
@@ -58,6 +58,9 @@
#include "md5.h"
#include "multithread.h"
#include "http_log.h"
+#ifdef WITH_UTIL_URI
+#include "util_uri.h"
+#endif /*WITH_UTIL_URI*/
static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
static int proxy_match_domainname(struct dirconn_entry *This, request_rec
*r);
@@ -836,7 +839,7 @@
hp = &hpbuf;
}
}
- memcpy(reqhp, hp, sizeof(struct hostent));
+ *reqhp = *hp;
return NULL;
}
@@ -886,16 +889,9 @@
/* Parse IP addr manually, optionally allowing */
/* abbreviated net addresses like 192.168. */
-/* quads = sscanf(what, "%d.%d.%d.%d", &ip_addr[0], &ip_addr[1],
- &ip_addr[2], &ip_addr[3]);
- commented out: use of strtok() allows arbitrary base, like in:
- 139.25.113.10 == 0x8b.0x19.0x71.0x0a
- (yes, inet_addr() can parse that, too!)
- */
-
/* Iterate over up to 4 (dotted) quads. */
for (quads = 0; quads < 4 && *addr != '\0'; ++quads) {
- char *tmp;
+ const char *tmp;
if (*addr == '/' && quads > 0) /* netmask starts here. */
break;
@@ -923,7 +919,7 @@
This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
if (addr[0] == '/' && isdigit(addr[1])) { /* net mask follows: */
- char *tmp;
+ const char *tmp;
++addr;
@@ -1048,8 +1044,6 @@
}
}
- /* Use net math to determine if a host lies in a subnet */
- /*return This->addr.s_addr ==
(r->connection->remote_addr.sin_addr.s_addr & This->mask.s_addr); */
return 0;
}
@@ -1064,7 +1058,8 @@
return 0;
/* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
- for (i = 0; isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i);
+ for (i = 0; isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i)
+ continue;
#if 0
if (addr[i] == ':') {
@@ -1108,6 +1103,7 @@
/* Return TRUE if addr represents a host name */
int proxy_is_hostname(struct dirconn_entry *This, pool *p)
{
+ struct hostent host;
char *addr = This->name;
int i;
@@ -1125,9 +1121,15 @@
}
#endif
- if (addr[i] != '\0' || proxy_host2addr(addr, &This->hostlist) != NULL)
+ if (addr[i] != '\0' || proxy_host2addr(addr, &host) != NULL)
return 0;
+#ifdef WITH_UTIL_URI
+ This->hostentry = pduphostent (p, &host);
+#else /*WITH_UTIL_URI*/
+ This->hostlist = host; /*XXX: FIXME: This points to overwritten
static storage!!! */
+#endif /*WITH_UTIL_URI*/
+
/* Strip trailing dots */
for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
addr[i] = '\0';
@@ -1148,7 +1150,7 @@
unsigned long *ip_list;
/* Try to deal with multiple IP addr's for a host */
- for (ip_list = *This->hostlist.h_addr_list; *ip_list != 0UL; ++ip_list)
+ for (ip_list = *This->hostentry->h_addr_list; *ip_list != 0UL; ++ip_list)
if (*ip_list == ? ? ? ? ? ? ? ? ? ? ? ? ?)
return 1;
#endif
1.44 +12 -0 apache-1.3/src/modules/standard/mod_log_config.c
Index: mod_log_config.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_log_config.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -u -r1.43 -r1.44
--- mod_log_config.c 1998/01/26 19:50:21 1.43
+++ mod_log_config.c 1998/02/27 15:15:28 1.44
@@ -296,7 +296,19 @@
static char *log_request_line(request_rec *r, char *a)
{
+#ifdef WITH_UTIL_URI
+ /* NOTE: If the original request contained a password, we
+ * re-write the request line here to contain XXXXXX instead:
+ * (note the truncation before the protocol string for HTTP/0.9
requests)
+ * (note also that r->the_request contains the unmodified request)
+ */
+ return (r->parsed_uri.has_password) ? pstrcat(r->pool, r->method, " ",
+ unparse_uri_components(r->pool,
&r->parsed_uri, NULL, 0),
+ r->assbackwards ? NULL : " ",
r->protocol, NULL)
+ : r->the_request;
+#else /*WITH_UTIL_URI*/
return r->the_request;
+#endif /*WITH_UTIL_URI*/
}
static char *log_request_file(request_rec *r, char *a)