dgaudet     98/03/01 22:51:28

  Modified:    src      CHANGES
               src/include http_vhost.h httpd.h util_uri.h
               src/main http_config.c http_core.c http_main.c
                        http_protocol.c http_request.c http_vhost.c
                        util_uri.c
               src/modules/proxy mod_proxy.c mod_proxy.h proxy_util.c
               src/modules/standard mod_log_config.c mod_rewrite.c
                        mod_rewrite.h
               src/test/vhtest/bin test1 test1d test2 test2d test3 test4
                        test5 vhget
  Added:       src/modules/test mod_test_util_uri.c
  Log:
  This is a huge commit, I apologize for that.  It's been posted in
  fragments to new-httpd already though, and I've run it through a lot
  of tests.  There's still a few TODOs but what's here should work for
  almost everyone.
  
  general:
  - remove check_fulluri, replace parse_uri with a much simplified version
      based on util_uri functions
  - remove r->hostlen, add r->unparsed_uri (mmn bump coming up shortly)
  - move r->proxyreq calculation to the translate_names phase
  
  vhosting:
  - fix absoluteURI problems with vhosting
  - update vhtest suite to test absoluteURI vhosting
  - serveralias support tweaked to consume less memory/run faster (submitted
      by Chia-liang Kao <[EMAIL PROTECTED]>)
  - add matches_request_vhost() function which can be used to ask http_vhost
      if a hostname:port pair would match r->server
  
  util_uri:
  - remove WITH_UTIL_URI, make WITH_UTIL_URI the default
  - remove the has_foo fields since they're inferred by testing the strings for
      NULL vs. non-NULL
  - #if 0 Martin's hand-coded parse_uri_components because it doesn't pass my
      test suite (see below)
  - change parse_uri_components_regex to parse_uri_components -- so the
      implementation is hidden from everyone's view
  - write mod_test_util_uri which does various exhaustive tests on
      parse_uri_components
  
  Revision  Changes    Path
  1.676     +35 -12    apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.675
  retrieving revision 1.676
  diff -u -r1.675 -r1.676
  --- CHANGES   1998/03/01 00:31:47     1.675
  +++ CHANGES   1998/03/02 06:51:01     1.676
  @@ -1,5 +1,31 @@
   Changes with Apache 1.3b6
   
  +  *) mod_test_util_uri.c created which tests the logic in util_uri.c.
  +     [Dean Gaudet]
  +
  +  *) Rewrite of absoluteURI handling, and in particular how absoluteURIs
  +     match vhosts.  Unless a request is a proxy request, a "http://host";
  +     url is treated as if a similar "Host:" header had been supplied.
  +     This change was made to support future HTTP/1.x protocols which
  +     may require clients to send absoluteURIs for all requests.
  +
  +     In order to achieve this change subtle changes were made to the API.  
In a
  +     request_rec, r->hostlen has been removed.  r->unparsed_uri now exists so
  +     that the unmodified uri can be retrieved easily.  r->proxyreq is not set
  +     until the translate_names phase. 
  +
  +     Plus changes to the virtualhost test suite for absoluteURI testing.
  +     [Dean Gaudet]
  +
  +  *) Cleanup of code in http_vhost.c, and remove vhost matching code from
  +     mod_rewrite.  The vhost matching is now performed by a globally
  +     available function matches_request_vhost().  [Dean Gaudet]
  +
  +  *) Reduce memory usage, and speed up ServerAlias support.  As a
  +     side-effect users can list multiple ServerAlias directives
  +     and they're all considered.
  +     [Chia-liang Kao <[EMAIL PROTECTED]>] PR#1531
  +
     *) The "poly" directive in image maps did not include the borders of the
        polygon, whereas the "rect" directive does.  Fix this inconsistency.
        [Konstantin Morshnev <[EMAIL PROTECTED]>] PR#1771
  @@ -13,15 +39,14 @@
     *) Add the `%a' construct to LogFormat and CustomLog to log the client IP
        address. [Todd Eigenschink <[EMAIL PROTECTED]>, PR#1885]
   
  -  *) 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:
  +  *) A new source module main/util_uri.c; It contains a routine
  +     parse_uri_components() and friends which breaks a URI into its component
  +     parts.  These parts are stored in a uri_components structure called
  +     parsed_uri within each request_rec, and are available to all modules.
  +     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/ */
  @@ -31,11 +56,9 @@
        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]
  +     [Martin Kraemer]
   
     *) Make all possible meta-construct expansions ($N, %N, %{NAME} and
        ${map:key}) available for all location where a string is created in
  
  
  
  1.6       +6 -0      apache-1.3/src/include/http_vhost.h
  
  Index: http_vhost.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/include/http_vhost.h,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- http_vhost.h      1998/01/21 19:17:40     1.5
  +++ http_vhost.h      1998/03/02 06:51:03     1.6
  @@ -74,4 +74,10 @@
    */
   void update_vhost_from_headers(request_rec *r);
   
  +/* return 1 if the host:port matches any of the aliases of r->server
  + * return 0 otherwise
  + */
  +API_EXPORT(int) matches_request_vhost(request_rec *r, const char *host,
  +    unsigned port);
  +
   #endif       /* !APACHE_HTTP_VHOST_H */
  
  
  
  1.189     +6 -10     apache-1.3/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/include/httpd.h,v
  retrieving revision 1.188
  retrieving revision 1.189
  diff -u -r1.188 -r1.189
  --- httpd.h   1998/02/27 15:15:15     1.188
  +++ httpd.h   1998/03/02 06:51:04     1.189
  @@ -537,9 +537,7 @@
   typedef struct request_rec request_rec;
   typedef struct listen_rec listen_rec;
   
  -#ifdef WITH_UTIL_URI
   #include "util_uri.h"
  -#endif
   
   struct request_rec {
   
  @@ -564,12 +562,11 @@
   
       char *the_request;               /* First line of request, so we can log 
it */
       int assbackwards;                /* HTTP/0.9, "simple" request */
  -    int proxyreq;            /* A proxy request */
  +    int proxyreq;            /* A proxy request (calculated during 
translate_name) */
       int header_only;         /* HEAD request, as opposed to GET */
       char *protocol;          /* Protocol, as given to us, or HTTP/0.9 */
       int proto_num;           /* Number version of protocol; 1.1 = 1001 */
       char *hostname;          /* Host, as set by full URI or Host: */
  -    int hostlen;             /* Length of http://host:port in full URI */
   
       time_t request_time;     /* When the request started */
   
  @@ -654,15 +651,13 @@
        * or content-negotiation mapping).
        */
   
  -    char *uri;                       /* complete URI for a proxy req, or
  -                                URL path for a non-proxy req */
  +    char *unparsed_uri;              /* the uri without any parsing 
performed */
  +    char *uri;                       /* the path portion of the URI */
       char *filename;
       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
  +    uri_components parsed_uri;       /* components of uri, dismantled */
   
       /* Various other config info which may change with .htaccess files
        * These are config vectors, with one void* pointer for each module
  @@ -782,7 +777,8 @@
       char *path;                      /* Pathname for ServerPath */
       int pathlen;             /* Length of path */
   
  -    char *names;             /* Wildcarded names for ServerAlias servers */
  +    array_header *names;     /* Normal names for ServerAlias servers */
  +    array_header *wild_names;        /* Wildcarded names for ServerAlias 
servers */
   
       uid_t server_uid;                /* effective user id when calling exec 
wrapper */
       gid_t server_gid;                /* effective group id when calling exec 
wrapper */
  
  
  
  1.4       +3 -18     apache-1.3/src/include/util_uri.h
  
  Index: util_uri.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/include/util_uri.h,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- util_uri.h        1998/02/28 10:31:55     1.3
  +++ util_uri.h        1998/03/02 06:51:04     1.4
  @@ -91,21 +91,10 @@
   
       struct hostent *hostent;
   
  -    unsigned hostlen;                /* strlen("scheme://[user[:[EMAIL 
PROTECTED]:port]") */
  -    unsigned short port;     /* The port number, numeric */
  +    unsigned short port;     /* The port number, numeric, valid only if 
port_str != NULL */
       
       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;
   
  @@ -117,12 +106,8 @@
   API_EXPORT(struct hostent *) pduphostent(pool *p, struct hostent *hp);
   API_EXPORT(struct hostent *) pgethostbyname(pool *p, const char *hostname);
   API_EXPORT(char *) unparse_uri_components(pool *p, const uri_components 
*uptr,
  -     int *pHostlen, unsigned flags);
  -API_EXPORT(int) parse_uri_components(pool *p, const char *uri, 
uri_components *uptr,
  -     int *pHostlen);
  -API_EXPORT(int) parse_uri_components_regex(pool *p, const char *uri,
  -     uri_components *uptr);
  -
  +    unsigned flags);
  +API_EXPORT(int) parse_uri_components(pool *p, const char *uri, 
uri_components *uptr);
   /* called by the core in main() */
   extern void util_uri_init(void);
   
  
  
  
  1.100     +3 -1      apache-1.3/src/main/http_config.c
  
  Index: http_config.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_config.c,v
  retrieving revision 1.99
  retrieving revision 1.100
  diff -u -r1.99 -r1.100
  --- http_config.c     1998/02/25 09:36:12     1.99
  +++ http_config.c     1998/03/02 06:51:06     1.100
  @@ -1175,7 +1175,8 @@
       s->next = NULL;
   
       s->is_virtual = 1;
  -    s->names = NULL;
  +    s->names = make_array(p, 4, sizeof(char **));
  +    s->wild_names = make_array(p, 4, sizeof(char **));
   
       s->module_config = create_empty_config(p);
       s->lookup_defaults = create_per_dir_config(p);
  @@ -1284,6 +1285,7 @@
       /* NOT virtual host; don't match any real network interface */
       s->addrs->host_addr.s_addr = htonl(INADDR_ANY);
       s->addrs->host_port = 0; /* matches any port */
  +    s->names = s->wild_names = NULL;
   
       s->module_config = create_server_config(p, s);
       s->lookup_defaults = create_default_per_dir_config(p);
  
  
  
  1.165     +17 -3     apache-1.3/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_core.c,v
  retrieving revision 1.164
  retrieving revision 1.165
  diff -u -r1.164 -r1.165
  --- http_core.c       1998/02/23 00:05:38     1.164
  +++ http_core.c       1998/03/02 06:51:07     1.165
  @@ -1222,6 +1222,21 @@
       return errmsg;
   }
   
  +const char *set_server_alias(cmd_parms *cmd, void *dummy, const char *arg)
  +{
  +    if (!cmd->server->names)
  +     return "ServerAlias only used in <VirtualHost>";
  +    while (*arg) {
  +     char **item, *name = getword_conf(cmd->pool, &arg);
  +     if (is_matchexp(name))
  +         item = (char **) push_array(cmd->server->wild_names);
  +     else
  +         item = (char **) push_array(cmd->server->names);
  +     *item = name;
  +    }
  +    return NULL;
  +}
  +
   const char *add_module_command (cmd_parms *cmd, void *dummy, char *arg)
   {
       const char *err = check_cmd_context(cmd, GLOBAL_ONLY);
  @@ -1872,9 +1887,8 @@
   { "ResourceConfig", set_server_string_slot,
     (void *)XtOffsetOf (server_rec, srm_confname), RSRC_CONF, TAKE1,
     "The filename of the resource config file" },
  -{ "ServerAlias", set_server_string_slot,
  -   (void *)XtOffsetOf (server_rec, names), RSRC_CONF, RAW_ARGS,
  -   "A name or names alternately used to access the server" },
  +{ "ServerAlias", set_server_alias, NULL, RSRC_CONF, RAW_ARGS,
  +  "A name or names alternately used to access the server" },
   { "ServerPath", set_serverpath, NULL, RSRC_CONF, TAKE1,
     "The pathname the server can be reached at" },
   { "Timeout", set_timeout, NULL, RSRC_CONF, TAKE1, "Timeout duration (sec)"},
  
  
  
  1.298     +0 -3      apache-1.3/src/main/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_main.c,v
  retrieving revision 1.297
  retrieving revision 1.298
  diff -u -r1.297 -r1.298
  --- http_main.c       1998/02/28 10:31:58     1.297
  +++ http_main.c       1998/03/02 06:51:08     1.298
  @@ -2887,9 +2887,6 @@
   #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.193     +11 -243   apache-1.3/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_protocol.c,v
  retrieving revision 1.192
  retrieving revision 1.193
  diff -u -r1.192 -r1.193
  --- http_protocol.c   1998/02/27 15:15:20     1.192
  +++ http_protocol.c   1998/03/02 06:51:09     1.193
  @@ -570,263 +570,37 @@
       return total;
   }
   
  -
  -/* parse_uri: check uri, determine whether proxy request, TRACE, or local 
request
  +/* parse_uri: break apart the uri
    * 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->args to rest after '?' (or NULL if no '?')
  + * - sets r->uri to request uri (without r->args part)
    * - 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;
  +    r->unparsed_uri = pstrdup(r->pool, uri);
   
       /* Simple syntax Errors in URLs are trapped by parse_uri_components(). */
  -    status = parse_uri_components_regex(r->pool, uri, &r->parsed_uri);
  +    status = parse_uri_components(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);
  +     /* if it has a scheme we may need to do absoluteURI vhost stuff */
  +     if (r->parsed_uri.scheme
  +         && !strcasecmp(r->parsed_uri.scheme, http_method(r))) {
            r->hostname = r->parsed_uri.hostname;
  -         /* no args splitting for proxy requests */
  -         r->args = NULL;
        }
  +     r->args = r->parsed_uri.query;
  +     r->uri = r->parsed_uri.path ? r->parsed_uri.path
  +                                 : pstrdup(r->pool, "/");
       }
       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)
  -    /* Variable for OS/2 fix below. */
  -    size_t loop, uri_len;
  -#endif
  -
  -    /* A proxy request contains a ':' early on, but not as first character */
  -
  -    for (s = uri; s != '\0'; s++)
  -        if (!isalnum(*s) && *s != '+' && *s != '-' && *s != '.')
  -            break;
  -
  -    if (*s == ':' && s != uri) {
  -        r->proxyreq = 1;
  -        r->uri = pstrdup(r->pool, uri);
  -        r->args = NULL;
  -    }
  -    else if (r->method && !strcmp(r->method, "TRACE")) {
  -        r->proxyreq = 0;
  -        r->uri = pstrdup(r->pool, uri);
  -        r->args = NULL;
  -    }
  -    else {
  -        r->proxyreq = 0;
  -        r->uri = getword(r->pool, &uri, '?');
  -
  -#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.
  -         */
  -        uri_len = strlen(r->uri);
  -        for (loop = 0; loop < uri_len; ++loop) {
  -            if (r->uri[loop] == '\\')
  -                r->uri[loop] = '/';
  -        };
  -#endif
  -#ifdef __EMX__
  -        /* Fix OS/2 HPFS filename case problem. */
  -        r->uri = strlwr(r->uri);
  -#endif
  -
  -        if (*uri)
  -            r->args = pstrdup(r->pool, uri);
  -        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;
  -    int plen;
  -    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);
  -    
  -    if (strncasecmp(uri, proto, plen) || strncasecmp(uri + plen, "://", 3))
  -        return uri;
  -    host = pstrdup(r->pool, uri + plen + 3);
  -
  -    /* Find the hostname, assuming a valid request */
  -    slash = strchr(host, '/');
  -    if (slash) {
  -        *slash = 0;
  -    }
  -    else {
  -        slash = host + strlen(host);
  -    }
  -
  -    /* Find the port */
  -    colon = strchr(host, ':');
  -    if (colon) {
  -        *colon = '\0';
  -        port = atoi(colon+1);
  -        if (port == 0) {
  -            return uri;
  -        }
  -    }
  -    else {
  -        port = default_port(r);
  -    }
  -
  -    /* Make sure ports match */
  -    if (port != r->server->port)
  -        return uri;
  -
  -    /* Save it for later use */
  -    r->hostname = host;
  -    r->hostlen = plen + 3 + slash - host;
  -    res_uri = uri + r->hostlen;
  -    /* deal with "http://host"; */
  -    if (*res_uri == '\0') {
  -     res_uri = "/";
  -    }
  -
  -    /* The easy cases first */
  -    if (!strcasecmp(host, r->server->server_hostname)) {
  -        return res_uri;
  -    }
  -    else if (!strcmp(host, inet_ntoa(r->connection->local_addr.sin_addr))) {
  -        return res_uri;
  -    }
  -    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 ((hp = gethostbyname(host))) {
  -            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)) {
  -                    return res_uri;
  -                }
  -            }
  -        }
  -    }
  -
  -    return uri;
  -#endif /*WITH_UTIL_URI*/
   }
   
   int read_request_line(request_rec *r)
  @@ -875,13 +649,7 @@
       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.109     +20 -25    apache-1.3/src/main/http_request.c
  
  Index: http_request.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_request.c,v
  retrieving revision 1.108
  retrieving revision 1.109
  diff -u -r1.108 -r1.109
  --- http_request.c    1998/02/27 15:15:21     1.108
  +++ http_request.c    1998/03/02 06:51:10     1.109
  @@ -749,9 +749,7 @@
   
           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;
           }
  @@ -797,10 +795,8 @@
           }
       }
       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
  @@ -1017,28 +1013,14 @@
           return;
       }
   
  -    if (!r->proxyreq) {
  -        /*
  -         * We don't want TRACE to run through the normal handler set, we
  -         * handle it specially.
  -         */
  -        if (r->method_number == M_TRACE) {
  -            if ((access_status = send_http_trace(r)))
  -                die(access_status, r);
  -            else
  -                finalize_request_protocol(r);
  -            return;
  -        }
  -
  -        access_status = unescape_url(r->uri);
  -        if (access_status) {
  -            die(access_status, r);
  -            return;
  -        }
  -
  -        getparents(r->uri);     /* OK --- shrinking transformations... */
  +    access_status = unescape_url(r->uri);
  +    if (access_status) {
  +     die(access_status, r);
  +     return;
       }
   
  +    getparents(r->uri);     /* OK --- shrinking transformations... */
  +
       if ((access_status = location_walk(r))) {
           die(access_status, r);
           return;
  @@ -1049,6 +1031,20 @@
           return;
       }
   
  +    if (!r->proxyreq) {
  +     /*
  +      * We don't want TRACE to run through the normal handler set, we
  +      * handle it specially.
  +      */
  +     if (r->method_number == M_TRACE) {
  +         if ((access_status = send_http_trace(r)))
  +             die(access_status, r);
  +         else
  +             finalize_request_protocol(r);
  +         return;
  +     }
  +    }
  +
       if (r->proto_num > HTTP_VERSION(1,0) && table_get(r->subprocess_env, 
"downgrade-1.0")) {
           r->proto_num = HTTP_VERSION(1,0);
       }
  @@ -1229,7 +1225,6 @@
       new->protocol        = r->protocol;
       new->proto_num       = r->proto_num;
       new->hostname        = r->hostname;
  -    new->hostlen         = r->hostlen;
       new->request_time    = r->request_time;
       new->main            = r->main;
   
  
  
  
  1.8       +98 -41    apache-1.3/src/main/http_vhost.c
  
  Index: http_vhost.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_vhost.c,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- http_vhost.c      1998/02/27 15:15:21     1.7
  +++ http_vhost.c      1998/03/02 06:51:11     1.8
  @@ -368,17 +368,19 @@
   }
   
   
  -static ap_inline ipaddr_chain *find_ipaddr(struct in_addr server_ip,
  +static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
       unsigned port)
   {
       unsigned bucket;
       ipaddr_chain *trav;
  +    unsigned s_addr;
   
       /* scan the hash table for an exact match first */
  -    bucket = hash_inaddr(server_ip.s_addr);
  +    s_addr = server_ip->s_addr;
  +    bucket = hash_inaddr(s_addr);
       for (trav = iphash_table[bucket]; trav; trav = trav->next) {
        server_addr_rec *sar = trav->sar;
  -     if ((sar->host_addr.s_addr == server_ip.s_addr)
  +     if ((sar->host_addr.s_addr == s_addr)
            && (sar->host_port == 0 || sar->host_port == port
                || port == 0)) {
            return trav;
  @@ -475,7 +477,7 @@
            }
            else {
                /* see if it matches something we've already got */
  -             ic = find_ipaddr(sar->host_addr, sar->host_port);
  +             ic = find_ipaddr(&sar->host_addr, sar->host_port);
   
                /* the first time we encounter a NameVirtualHost address
                 * ic->server will be NULL, on subsequent encounters
  @@ -608,6 +610,89 @@
       r->hostname = host;
   }
   
  +
  +/* return 1 if host matches ServerName or ServerAliases */
  +static int matches_aliases(server_rec *s, const char *host)
  +{
  +    int i;
  +    array_header *names;
  +
  +    /* match ServerName */
  +    if (!strcasecmp(host, s->server_hostname)) {
  +     return 1;
  +    }
  +
  +    /* search all the aliases from ServerAlias directive */
  +    names = s->names;
  +    if (names) {
  +     char **name = (char **) names->elts;
  +     for (i = 0; i < names->nelts; ++i) {
  +         if(!name[i]) continue;
  +         if (!strcasecmp(host, name[i]))
  +             return 1;
  +     }
  +    }
  +    names = s->wild_names;
  +    if (names) {
  +     char **name = (char **) names->elts;
  +     for (i = 0; i < names->nelts; ++i) {
  +         if(!name[i]) continue;
  +         if (!strcasecmp_match(host, name[i]))
  +             return 1;
  +     }
  +    }
  +    return 0;
  +}
  +
  +
  +/* Suppose a request came in on the same socket as this r, and included
  + * a header "Host: host:port", would it map to r->server?  It's more
  + * than just that though.  When we do the normal matches for each request
  + * we don't even bother considering Host: etc on non-namevirtualhosts,
  + * we just call it a match.  But here we require the host:port to match
  + * the ServerName and/or ServerAliases.
  + */
  +API_EXPORT(int) matches_request_vhost(request_rec *r, const char *host,
  +    unsigned port)
  +{
  +    server_rec *s;
  +    server_addr_rec *sar;
  +
  +    s = r->server;
  +
  +    /* search all the <VirtualHost> values */
  +    /* XXX: If this is a NameVirtualHost then we may not be doing the Right 
Thing
  +     * consider: 
  +     *
  +     *     NameVirtualHost 10.1.1.1
  +     *     <VirtualHost 10.1.1.1>
  +     *     ServerName v1
  +     *     </VirtualHost>
  +     *     <VirtualHost 10.1.1.1>
  +     *     ServerName v2
  +     *     </VirtualHost>
  +     *
  +     * Suppose r->server is v2, and we're asked to match "10.1.1.1".  We'll 
say
  +     * "yup it's v2", when really it isn't... if a request came in for 
10.1.1.1
  +     * it would really go to v1.
  +     */
  +    for (sar = s->addrs; sar; sar = sar->next) {
  +     if ((sar->host_port == 0 || port == sar->host_port)
  +         && !strcasecmp(host, sar->virthost)) {
  +         return 1;
  +     }
  +    }
  +
  +    /* the Port has to match now, because the rest don't have ports 
associated
  +     * with them. */
  +    if (port != s->port) {
  +     return 0;
  +    }
  +
  +    return matches_aliases(s, host);
  +}
  +
  +
   static void check_hostalias(request_rec *r)
   {
       /*
  @@ -641,7 +726,6 @@
        */
   
       for (src = r->connection->vhost_lookup_data; src; src = src->next) {
  -        const char *names;
           server_addr_rec *sar;
   
        /* We only consider addresses on the name_chain which have a matching
  @@ -667,34 +751,15 @@
        }
        last_s = s;
   
  -     /* match ServerName */
  -        if (!strcasecmp(host, s->server_hostname)) {
  +     if (matches_aliases(s, host)) {
            goto found;
  -        }
  -
  -        /* search all the aliases from ServerAlias directive */
  -        names = s->names;
  -        if (names) {
  -            while (*names) {
  -                char *name = getword_conf(r->pool, &names);
  -
  -                if ((is_matchexp(name) && !strcasecmp_match(host, name)) ||
  -                    (!strcasecmp(host, name))) {
  -                 goto found;
  -                }
  -            }
  -        }
  +     }
       }
       return;
   
   found:
       /* s is the first matching server, we're done */
       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);
  -    }
   }
   
   
  @@ -709,7 +774,7 @@
        * This is in conjunction with the ServerPath code in http_core, so we
        * get the right host attached to a non- Host-sending request.
        *
  -     * See the comment in check_hostaliases about how each vhost can be
  +     * See the comment in check_hostalias about how each vhost can be
        * listed multiple times.
        */
   
  @@ -760,24 +825,16 @@
    */
   void update_vhost_given_ip(conn_rec *conn)
   {
  -    server_addr_rec *sar;
       ipaddr_chain *trav;
  -    unsigned bucket;
  -    struct in_addr server_ip = conn->local_addr.sin_addr;
       unsigned port = ntohs(conn->local_addr.sin_port);
   
       /* scan the hash table for an exact match first */
  -    bucket = hash_inaddr(server_ip.s_addr);
  -    for (trav = iphash_table[bucket]; trav; trav = trav->next) {
  -     sar = trav->sar;
  -     if ((sar->host_addr.s_addr == server_ip.s_addr)
  -         && (sar->host_port == 0 || sar->host_port == port)) {
  -
  -         /* save the name_chain for later in case this is a name-vhost */
  -         conn->vhost_lookup_data = trav->names;
  -         conn->server = trav->server;
  -         return;
  -     }
  +    trav = find_ipaddr(&conn->local_addr.sin_addr, port);
  +    if (trav) {
  +     /* save the name_chain for later in case this is a name-vhost */
  +     conn->vhost_lookup_data = trav->names;
  +     conn->server = trav->server;
  +     return;
       }
   
       /* There's certainly no name-vhosts with this address, they would have
  
  
  
  1.6       +88 -93    apache-1.3/src/main/util_uri.c
  
  Index: util_uri.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/util_uri.c,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- util_uri.c        1998/03/01 00:15:41     1.5
  +++ util_uri.c        1998/03/02 06:51:11     1.6
  @@ -87,21 +87,12 @@
       return 0;
   }
   
  -#ifdef WITH_UTIL_URI
   API_EXPORT(unsigned short) default_port_for_request(const request_rec *r)
   {
  -    return (r->parsed_uri.has_scheme)
  +    return (r->parsed_uri.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.
  @@ -170,46 +161,49 @@
   /* Unparse a uri_components structure to an URI string.
    * Optionally suppress the password for security reasons.
    */
  -API_EXPORT(char *) unparse_uri_components(pool *p, const uri_components 
*uptr, int *pHostlen, unsigned flags)
  +API_EXPORT(char *) unparse_uri_components(pool *p, const uri_components 
*uptr, unsigned flags)
   {
       char *ret = "";
   
       /* Construct a "user:password@" string, honoring the passed UNP_ flags: 
*/
  -    if (uptr->has_user||uptr->has_password)
  +    if (uptr->user||uptr->password)
        ret = pstrcat (p,
  -             (uptr->has_user     && !(flags & UNP_OMITUSER)) ? uptr->user : 
"",
  -             (uptr->has_password && !(flags & UNP_OMITPASSWORD)) ? ":" : "",
  -             (uptr->has_password && !(flags & UNP_OMITPASSWORD))
  +             (uptr->user     && !(flags & UNP_OMITUSER)) ? uptr->user : "",
  +             (uptr->password && !(flags & UNP_OMITPASSWORD)) ? ":" : "",
  +             (uptr->password && !(flags & UNP_OMITPASSWORD))
                   ? ((flags & UNP_REVEALPASSWORD) ? uptr->password : 
"XXXXXXXX")
                   : "",
                "@", NULL);
   
       /* Construct scheme://site string */
  -    if (uptr->has_hostname && !(flags & UNP_OMITSITEPART)) {
  +    if (uptr->hostname && !(flags & UNP_OMITSITEPART)) {
        ret = pstrcat (p,
                uptr->scheme, "://", ret, 
  -             uptr->has_hostname ? uptr->hostname : "",
  -                    uptr->has_port ? ":" : "",
  -                    uptr->has_port ? uptr->port_str : "",
  +             uptr->hostname ? uptr->hostname : "",
  +                    uptr->port_str ? ":" : "",
  +                    uptr->port_str ? 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,
  +                uptr->query ? "?" : "",
  +                uptr->query ? uptr->query : "",
  +                uptr->fragment ? "#" : NULL,
  +                uptr->fragment ? uptr->fragment : NULL,
                   NULL);
       return ret;
   }
   
   
  +
  +/* This will serve as the basis for an optimized parse_uri_components, sorry
  + * about the if 0
  + */
  +
  +#if 0
   /* 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,
  @@ -218,11 +212,10 @@
    *  - fills in fields of uri_components *uptr
    *  - none on any of the r->* fields
    */
  -API_EXPORT(int) parse_uri_components(pool *p, const char *uri, 
uri_components *uptr, int *pHostlen)
  +API_EXPORT(int) parse_uri_components(pool *p, const char *uri, 
uri_components *uptr)
   {
       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.
  @@ -241,11 +234,14 @@
        /* 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, '?');
  +     if (uptr->path[0] == '\0') {
  +         uptr->path = NULL;
  +     }
   
  -     uptr->has_query = (uri[0] != '\0');
  -     uptr->query = (uptr->has_query) ? pstrdup(p, uri) : NULL;
  +     if (uri[0] != '\0') {
  +         uptr->query = pstrdup(p, uri);
  +     }
   
   #if defined(__EMX__) || defined(WIN32)
        /* Handle path translations for OS/2 and plug security hole.
  @@ -282,7 +278,9 @@
         */
        s = uri;
        uptr->scheme = getword(p, &s, ':');
  -     uptr->has_scheme = 1;
  +     if (uptr->scheme[0] == '\0') {
  +         uptr->scheme = NULL;
  +     }
   
        /*  URL schemeparts for ip based protocols:
         *
  @@ -307,31 +305,30 @@
   
            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, '?');
  +             if (uptr->path[0] == '\0') {
  +                 uptr->path = NULL;
  +             }
   
  -             uptr->has_query = (tmp[0] != '\0');
  -             uptr->query = (uptr->has_query) ? pstrdup(p, tmp) : NULL;
  +             if (tmp[0] != '\0') {
  +                 uptr->query = pstrdup(p, tmp);
  +             }
            }
            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';
  +         if (uptr->hostname[0] == '\0') {
  +             uptr->hostname = NULL;
  +         }
   
            /* disintegrate "[EMAIL PROTECTED]" */
            /* NOTE: using reverse search here because user:password might
  @@ -339,7 +336,6 @@
             */
            if ((tmp = strrchr(uptr->hostname, '@')) != NULL) {
                uptr->user = uptr->hostname;
  -             uptr->has_user = 1;
                *tmp++ = '\0';
                uptr->hostname = tmp;
   
  @@ -347,7 +343,6 @@
                if ((tmp = strchr(uptr->user, ':')) != NULL) {
                    *tmp++ = '\0';
                    uptr->password = tmp;
  -                 uptr->has_password = 1;
                }
            }
   
  @@ -356,7 +351,6 @@
                *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;
  @@ -376,12 +370,9 @@
   
       }
   
  -    /* If caller is interested in the length of the scheme://...host:port 
prefix: */
  -    if (pHostlen != NULL)
  -     *pHostlen = hostlen;
  -
       return ret;
   }
  +#endif
   
   static regex_t re_uri;
   static regex_t re_hostpart;
  @@ -395,9 +386,9 @@
        * 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  */
  +     *         12            3  4          5       6   7        8 9 */
  +    re_str = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$";
  +    /*          ^scheme--^      ^site---^  ^path--^   ^query^    ^frag */
       if ((ret = regcomp(&re_uri, re_str, REG_EXTENDED)) != 0) {
        char line[1024];
   
  @@ -414,10 +405,10 @@
   
       /* 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    = "^(([^:]*):(.*)?@)?([^@:]*)(:(.*))?$";
  +     * $          12      3 4        5       6 7    */
  +    re_str    = "^(([^:]*)(:(.*))?@)?([^@:]*)(:(.*))?$";
       /*             ^^user^ :pw      ^host^   port */
  -    if ((ret = regcomp(&re_hostpart, re_str, REG_EXTENDED|REG_ICASE)) != 0) {
  +    if ((ret = regcomp(&re_hostpart, re_str, REG_EXTENDED)) != 0) {
        char line[1024];
   
        /* Make a readable error message */
  @@ -432,7 +423,7 @@
       }
   }
   
  -/* parse_uri_components_regex():
  +/* 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.
  @@ -440,7 +431,7 @@
    *  - fills in fields of uri_components *uptr
    *  - none on any of the r->* fields
    */
  -API_EXPORT(int) parse_uri_components_regex(pool *p, const char *uri, 
uri_components *uptr)
  +API_EXPORT(int) parse_uri_components(pool *p, const char *uri, 
uri_components *uptr)
   {
       int ret;
       regmatch_t match[10];    /* This must have at least as much elements
  @@ -454,8 +445,7 @@
       memset (uptr, '\0', sizeof(*uptr));
       uptr->is_initialized = 1;
   
  -
  -    ret = regexec(&re_uri, uri, re_uri.re_nsub, match, 0);
  +    ret = regexec(&re_uri, uri, re_uri.re_nsub + 1, match, 0);
   
       if (ret != 0) {
        aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
  @@ -465,31 +455,27 @@
        return HTTP_BAD_REQUEST;
       }
   
  -    /* if hostlen is 0, it's not a proxy request */
  -    uptr->hostlen = (match[1].rm_eo - match[1].rm_so);
  -
  -    uptr->has_scheme = (match[2].rm_so != match[2].rm_eo);
  -    uptr->has_hostinfo = (match[3].rm_so != match[3].rm_eo);
  -    uptr->has_path = (match[4].rm_so != match[4].rm_eo);
  -    uptr->has_query = (match[5].rm_so != match[5].rm_eo);
  -    uptr->has_fragment = (match[7].rm_so != match[7].rm_eo);
  -
  -    if (uptr->has_scheme)
  +    if (match[2].rm_so != match[2].rm_eo)
        uptr->scheme = pstrndup (p, uri+match[2].rm_so, match[2].rm_eo - 
match[2].rm_so);
  -    if (uptr->has_hostinfo)
  -     uptr->hostinfo = pstrndup (p, uri+match[3].rm_so, match[3].rm_eo - 
match[3].rm_so);
  -    if (uptr->has_path)
  -     uptr->path = pstrndup (p, uri+match[4].rm_so, match[4].rm_eo - 
match[4].rm_so);
  -    if (uptr->has_query)
  -     uptr->query = pstrndup (p, uri+match[6].rm_so, match[6].rm_eo - 
match[6].rm_so);
  -    if (uptr->has_fragment)
  -     uptr->fragment = pstrndup (p, uri+match[7].rm_so, match[7].rm_eo - 
match[7].rm_so);
   
  +    /* empty hostinfo is valid, that's why we test $3 but use $4 */
  +    if (match[3].rm_so != match[3].rm_eo)
  +     uptr->hostinfo = pstrndup (p, uri+match[4].rm_so, match[4].rm_eo - 
match[4].rm_so);
  +
  +    if (match[5].rm_so != match[5].rm_eo)
  +     uptr->path = pstrndup (p, uri+match[5].rm_so, match[5].rm_eo - 
match[5].rm_so);
  +
  +    /* empty query string is valid, that's why we test $6 but use $7 */
  +    if (match[6].rm_so != match[6].rm_eo)
  +     uptr->query = pstrndup (p, uri+match[7].rm_so, match[7].rm_eo - 
match[7].rm_so);
  +
  +    /* empty fragment is valid, test $8 use $9 */
  +    if (match[8].rm_so != match[8].rm_eo)
  +     uptr->fragment = pstrndup (p, uri+match[9].rm_so, match[9].rm_eo - 
match[9].rm_so);
   
  -    if (uptr->has_hostinfo) {
  -
  +    if (uptr->hostinfo) {
        /* Parse the hostinfo part to extract user, password, host, and port */
  -     ret = regexec(&re_hostpart, uptr->hostinfo, re_hostpart.re_nsub, match, 
0);
  +     ret = regexec(&re_hostpart, uptr->hostinfo, re_hostpart.re_nsub + 1, 
match, 0);
        if (ret != 0) {
            aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
                       "regexec() could not parse (\"%s\") as host part",
  @@ -498,29 +484,38 @@
            return HTTP_BAD_REQUEST;
        }
   
  -     /* $      12       3       4       5 6    */
  -     /*    = "^(([^:]*):(.*)?@)?([^@:]*)(:([0-9]*))?$" */
  -     /*         ^^user^ :pw      ^host^   port */
  -     if ((uptr->has_user = (match[2].rm_so != match[2].rm_eo)))
  +     /* $          12      3 4        5       6 7    */
  +     /*        = "^(([^:]*)(:(.*))?@)?([^@:]*)(:(.*))?$" */
  +     /*             ^^user^ :pw      ^host^   port */
  +
  +     /* empty user is valid, that's why we test $1 but use $2 */
  +     if (match[1].rm_so != match[1].rm_eo)
            uptr->user = pstrndup (p, uptr->hostinfo+match[2].rm_so, 
match[2].rm_eo - match[2].rm_so);
  -     if ((uptr->has_password = (match[3].rm_so != match[3].rm_eo)))
  -         uptr->password = pstrndup (p, uptr->hostinfo+match[3].rm_so, 
match[3].rm_eo - match[3].rm_so);
  -     if ((uptr->has_hostname = (match[4].rm_so != match[4].rm_eo)))
  -         uptr->hostname = pstrndup (p, uptr->hostinfo+match[4].rm_so, 
match[4].rm_eo - match[4].rm_so);
  -     if ((uptr->has_port = (match[5].rm_so != match[5].rm_eo))) {
  -         uptr->port_str = pstrndup (p, uptr->hostinfo+match[5].rm_so+1, 
match[5].rm_eo - match[5].rm_so-1);
  +
  +     /* empty password is valid, test $3 but use $4 */
  +     if (match[3].rm_so != match[3].rm_eo)
  +         uptr->password = pstrndup (p, uptr->hostinfo+match[4].rm_so, 
match[4].rm_eo - match[4].rm_so);
  +
  +     /* empty hostname is valid, and implied by the existence of hostinfo */
  +     uptr->hostname = pstrndup (p, uptr->hostinfo+match[5].rm_so, 
match[5].rm_eo - match[5].rm_so);
  +
  +     if (match[6].rm_so != match[6].rm_eo) {
            /* Note that the port string can be empty.
             * If it is, we use the default port associated with the scheme
             */
  +         uptr->port_str = pstrndup (p, uptr->hostinfo+match[7].rm_so, 
match[7].rm_eo - match[7].rm_so);
            if (uptr->port_str[0] != '\0') {
                char *endstr;
   
                uptr->port = strtoul(uptr->port_str, &endstr, 10);
  -             if (*endstr != '\0')
  +             if (*endstr != '\0') {
                    /* Invalid characters after ':' found */
                    return HTTP_BAD_REQUEST;
  -         } else
  -             uptr->port = default_port_for_scheme(uptr->scheme);
  +             }
  +         }
  +         else {
  +             uptr->port = uptr->scheme ? 
default_port_for_scheme(uptr->scheme) : DEFAULT_HTTP_PORT;
  +         }
        }
       }
   
  
  
  
  1.42      +23 -101   apache-1.3/src/modules/proxy/mod_proxy.c
  
  Index: mod_proxy.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/mod_proxy.c,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- mod_proxy.c       1998/02/27 15:15:24     1.41
  +++ mod_proxy.c       1998/03/02 06:51:15     1.42
  @@ -53,6 +53,7 @@
   
   #include "mod_proxy.h"
   #include "http_log.h"
  +#include "http_vhost.h"
   
   /* Some WWW schemes and their default ports; this is basically /etc/services 
*/
   /* This will become global when the protocol abstraction comes */
  @@ -126,15 +127,28 @@
       proxy_server_conf *conf =
       (proxy_server_conf *) get_module_config(sconf, &proxy_module);
   
  -    if (r->proxyreq) {
  -     if (!conf->req)
  -         return DECLINED;
  -
  +    if (conf->req) {
  +     if (!r->parsed_uri.scheme) {
  +         return DECLINED; /* definately not a proxy request */
  +     }
  +     /* but it might be something vhosted */
  +     if (r->parsed_uri.hostname
  +         && !strcasecmp(r->parsed_uri.scheme, http_method(r))
  +         && matches_request_vhost(r, r->parsed_uri.hostname,
  +             r->parsed_uri.port_str ? r->parsed_uri.port : default_port(r))) 
{
  +         return DECLINED; /* it's a vhost request */
  +     }
  +     r->proxyreq = 1;
  +     r->uri = r->unparsed_uri;
        r->filename = pstrcat(r->pool, "proxy:", r->uri, NULL);
        r->handler = "proxy-server";
        return OK;
       }
       else {
  +     /* XXX: since r->uri has been manipulated already we're not really
  +      * compliant with RFC1945 at this point.  But this probably isn't
  +      * an issue because this is a hybrid proxy/origin server.
  +      */
        int i, len;
        struct proxy_alias *ent = (struct proxy_alias *) conf->aliases->elts;
   
  @@ -161,17 +175,14 @@
    */
   static int proxy_fixup(request_rec *r)
   {
  -    char *url, *p;
  -    int i;
  +    char *url;
   
       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) {
  +    if (!r->parsed_uri.scheme) {
        return DECLINED;
       }
   
  @@ -182,25 +193,6 @@
        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 HTTP_BAD_REQUEST;
  -    for (i = 0; i != p - url; i++)
  -     url[i] = tolower(url[i]);
  -
  -/* canonicalise each specific scheme */
  -    if (strncmp(url, "http:", 5) == 0)
  -     return proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT);
  -    else if (strncmp(url, "ftp:", 4) == 0)
  -     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)
  @@ -218,13 +210,10 @@
   /* 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)
  +    if (!r->proxyreq || r->method_number != M_GET || !r->parsed_uri.hostname)
        return DECLINED;
   
       /* If host does contain a dot already, or it is "localhost", decline */
  @@ -240,81 +229,16 @@
                                     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),
  +                   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;
  -
  -    /* We only want to worry about GETs */
  -    if (r->method_number != M_GET)
  -     return DECLINED;
  -
  -    /* Set url to the first char after "scheme://" */
  -    if ((url_copy = strchr(scheme, ':')) == NULL
  -     || url_copy[1] != '/' || url_copy[2] != '/')
  -     return DECLINED;
  -
  -    *url_copy++ = '\0';              /* delimit scheme, make url_copy point 
to "//", which is what proxy_canon_netloc expects */
  -
  -    /* Save the path - it will be re-appended for the redirection later */
  -    path = strchr(&url_copy[2], '/');
  -    if (path != NULL)
  -     ++path;                 /* leading '/' will be overwritten by 
proxy_canon_netloc */
  -    else
  -     path = "";
  -
  -    /* Split request into user, password, host, port */
  -    err = proxy_canon_netloc(r->pool, &url_copy, &user, &password, &host, 
&port);
  -
  -    if (err != NULL) {
  -     aplog_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server, err);
  -     return DECLINED;
  -    }
  -
  -    /* If host does contain a dot already, or it is "localhost", decline */
  -    if (strchr(host, '.') != NULL || strcasecmp(host, "localhost") == 0)
  -     return DECLINED;        /* host name has a dot already */
  -    else {
  -     char *nuri;
  -     char *ref = table_get(r->headers_in, "Referer");
  -     char strport[10];
  -
  -     /* now, rebuild URL */
  -     if (port == -1)
  -         strcpy(strport, "");
  -     else
  -         ap_snprintf(strport, sizeof(strport), ":%d", port);
  -
  -     /* Reassemble the request, but insert the domain after the host name */
  -     nuri = pstrcat(r->pool, scheme, "://", (user != NULL) ? user : "",
  -                         (password != NULL) ? ":" : "",
  -                         (password != NULL) ? password : "",
  -                         (user != NULL) ? "@" : "",
  -                    host, domain, strport, "/", path,
  -                    NULL);
  -
  -     table_setn(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, nuri,
  -                 ref ? " from " : "", ref ? ref : "");
  -
  -     return HTTP_MOVED_PERMANENTLY;
  -    }
  -
  -#endif /*WITH_UTIL_URI*/
   }
   
   /* -------------------------------------------------------------- */
  @@ -582,9 +506,7 @@
       if (!found) {
        New = push_array(conf->dirconn);
        New->name = arg;
  -#ifdef WITH_UTIL_URI
  -     New->hostentry = NULL;;
  -#endif /*WITH_UTIL_URI*/
  +     New->hostentry = NULL;
   
        if (proxy_is_ipaddr(New, parms->pool)) {
   #if DEBUGGING
  
  
  
  1.31      +0 -4      apache-1.3/src/modules/proxy/mod_proxy.h
  
  Index: mod_proxy.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/mod_proxy.h,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- mod_proxy.h       1998/02/27 15:15:25     1.30
  +++ mod_proxy.h       1998/03/02 06:51:15     1.31
  @@ -162,11 +162,7 @@
   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.47      +0 -6      apache-1.3/src/modules/proxy/proxy_util.c
  
  Index: proxy_util.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_util.c,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- proxy_util.c      1998/02/28 10:32:01     1.46
  +++ proxy_util.c      1998/03/02 06:51:16     1.47
  @@ -58,9 +58,7 @@
   #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);
  @@ -1124,11 +1122,7 @@
       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)
  
  
  
  1.46      +2 -6      apache-1.3/src/modules/standard/mod_log_config.c
  
  Index: mod_log_config.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_log_config.c,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -r1.45 -r1.46
  --- mod_log_config.c  1998/02/28 08:12:49     1.45
  +++ mod_log_config.c  1998/03/02 06:51:18     1.46
  @@ -302,19 +302,15 @@
   
   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),
  +    return (r->parsed_uri.password) ? pstrcat(r->pool, r->method, " ",
  +                                      unparse_uri_components(r->pool, 
&r->parsed_uri, 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)
  
  
  
  1.78      +2 -134    apache-1.3/src/modules/standard/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v
  retrieving revision 1.77
  retrieving revision 1.78
  diff -u -r1.77 -r1.78
  --- mod_rewrite.c     1998/02/27 14:47:46     1.77
  +++ mod_rewrite.c     1998/03/02 06:51:19     1.78
  @@ -109,6 +109,7 @@
   #include "http_request.h"
   #include "http_core.h"
   #include "http_log.h"
  +#include "http_vhost.h"
   
       /* now our own stuff ... */
   #include "mod_rewrite.h"
  @@ -2211,7 +2212,7 @@
           }
   
           /* now check whether we could reduce it to a local path... */
  -        if (is_this_our_host(r, host) && port == r->server->port) {
  +     if (matches_request_vhost(r, host, port)) {
               /* this is our host, so only the URL remains */
               r->filename = pstrdup(r->pool, url);
               rewritelog(r, 3, "reduce %s -> %s", olduri, r->filename);
  @@ -3730,139 +3731,6 @@
       else
           return 0;
   }
  -
  -
  -/*
  -**
  -**  special DNS lookup functions
  -**
  -*/
  -
  -static int is_this_our_host(request_rec *r, char *testhost)
  -{
  -    char **cppHNLour;
  -    char **cppHNLtest;
  -    char *ourhostname;
  -    char *ourhostip;
  -    const char *names;
  -    char *name;
  -    int i, j;
  -    server_addr_rec *sar;
  -
  -    /* we can check:
  -       r->
  -            char *hostname            Host, as set by full URI or Host:
  -            int hostlen               Length of http://host:port in full URI
  -       r->server->
  -            int is_virtual            0=main, 1=ip-virtual, 2=non-ip-virtual
  -            char *server_hostname     used on compare to r->hostname
  -            inet_ntoa(r->connection->local_addr.sin_addr)
  -                                      used on compare to r->hostname
  -            unsigned short port       for redirects
  -            char *path                name of ServerPath
  -            int pathlen               len of ServerPath
  -            char *names               Wildcarded names for ServerAlias 
servers
  -       r->server->addrs->
  -            struct in_addr host_addr  The bound address, for this server
  -            short host_port           The bound port, for this server
  -            char *virthost            The name given in <VirtualHost>
  -    */
  -
  -    ourhostname = r->server->server_hostname;
  -    ourhostip   = inet_ntoa(r->connection->local_addr.sin_addr);
  -
  -    /* just a simple common case */
  -    if (strcmp(testhost, ourhostname) == 0 ||
  -        strcmp(testhost, ourhostip)   == 0   )
  -       return YES;
  -
  -    /* now the complicated cases */
  -    if (!r->server->is_virtual) {
  -        /* main servers */
  -
  -        /* check for the alternative IP addresses */
  -        if ((cppHNLour = resolv_ipaddr_list(r, ourhostname)) == NULL)
  -            return NO;
  -        if ((cppHNLtest = resolv_ipaddr_list(r, testhost)) == NULL)
  -            return NO;
  -        for (i = 0; cppHNLtest[i] != NULL; i++) {
  -            for (j = 0; cppHNLour[j] != NULL; j++) {
  -                if (strcmp(cppHNLtest[i], cppHNLour[j]) == 0) {
  -                    return YES;
  -                }
  -            }
  -        }
  -    }
  -    else if (r->server->is_virtual) {
  -        /* virtual servers */
  -
  -        /* check for the names supplied in the VirtualHost directive */
  -        for(sar = r->server->addrs; sar != NULL; sar = sar->next) {
  -            if(strcasecmp(sar->virthost, testhost) == 0)
  -                return YES;
  -        }
  -
  -        /* check for the virtual-server aliases */
  -        if (r->server->names != NULL && r->server->names[0] != '\0') {
  -            names = r->server->names;
  -            while (*names != '\0') {
  -                name = getword_conf(r->pool, &names);
  -                if ((is_matchexp(name) &&
  -                    !strcasecmp_match(testhost, name)) ||
  -                    (strcasecmp(testhost, name) == 0)    ) {
  -                    return YES;
  -                }
  -            }
  -        }
  -    }
  -    return NO;
  -}
  -
  -static int isaddr(char *host)
  -{
  -    char *cp;
  -
  -    /* Null pointers and empty strings
  -       are not addresses. */
  -    if (host == NULL)
  -        return NO;
  -    if (*host == '\0')
  -        return NO;
  -    /* Make sure it has only digits and dots. */
  -    for (cp = host; *cp; cp++) {
  -        if (!isdigit(*cp) && *cp != '.')
  -            return NO;
  -    }
  -    /* If it has a trailing dot,
  -       don't treat it as an address. */
  -    if (*(cp-1) == '.')
  -       return NO;
  -    return YES;
  -}
  -
  -static char **resolv_ipaddr_list(request_rec *r, char *name)
  -{
  -    char **cppHNL;
  -    struct hostent *hep;
  -    int i;
  -
  -    if (isaddr(name))
  -        hep = gethostbyaddr(name, sizeof(struct in_addr), AF_INET);
  -    else
  -        hep = gethostbyname(name);
  -    if (hep == NULL)
  -        return NULL;
  -    for (i = 0; hep->h_addr_list[i]; i++)
  -        ;
  -    cppHNL = (char **)palloc(r->pool, sizeof(char *)*(i+1));
  -    for (i = 0; hep->h_addr_list[i]; i++)
  -        cppHNL[i] = pstrdup(r->pool,
  -                            inet_ntoa(*((struct in_addr *)
  -                            (hep->h_addr_list[i]))));
  -    cppHNL[i] = NULL;
  -    return cppHNL;
  -}
  -
   
   /*
   **
  
  
  
  1.40      +0 -5      apache-1.3/src/modules/standard/mod_rewrite.h
  
  Index: mod_rewrite.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.h,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- mod_rewrite.h     1998/02/24 16:40:52     1.39
  +++ mod_rewrite.h     1998/03/02 06:51:20     1.40
  @@ -430,11 +430,6 @@
   static int    prefix_stat(const char *path, struct stat *sb);
   static void   add_env_variable(request_rec *r, char *s);
   
  -    /* DNS functions */
  -static int    is_this_our_host(request_rec *r, char *testhost);
  -static int    isaddr(char *host);
  -static char **resolv_ipaddr_list(request_rec *r, char *name);
  -
       /* Proxy Module check */
   static int is_proxy_available(server_rec *s);
   
  
  
  
  1.1                  apache-1.3/src/modules/test/mod_test_util_uri.c
  
  Index: mod_test_util_uri.c
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1998 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. For written permission, please contact
   *    [EMAIL PROTECTED]
   *
   * 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/>.
   *
   */
  
  /*
   * This module is intended to test the util_uri routines by parsing a
   * bunch of urls and comparing the results with what we expect to
   * see.
   *
   * Usage:
   *
   * <Location /test-util-uri>
   * SetHandler test-util-uri
   * </Location>
   *
   * Then make a request to /test-util-uri.  An html table of errors will
   * be output... and a total count of errors.
   */
  
  #include "httpd.h"
  #include "http_protocol.h"
  #include "http_config.h"
  #include "http_main.h"
  
  typedef struct {
      const char *scheme;
      const char *user;
      const char *password;
      const char *hostname;
      const char *port_str;
      const char *path;
      const char *query;
      const char *fragment;
  } test_uri_t;
  
  #define T_scheme      0x01
  #define T_user                0x02
  #define T_password    0x04
  #define T_hostname    0x08
  #define T_port_str    0x10
  #define T_path                0x20
  #define T_query               0x40
  #define T_fragment    0x80
  #define T_MAX         0x100
  
  /* The idea is that we list here a bunch of url pieces that we want
   * stitched together in every way that's valid.
   */
  static const test_uri_t uri_tests[] = {
      { "http", "userid", "passwd", "hostname.goes.here", "80", 
"/path/goes/here", "query-here", "frag-here" },
      { "http", "", "passwd", "hostname.goes.here", "80", "/path/goes/here", 
"query-here", "frag-here" },
      { "http", "userid", "", "hostname.goes.here", "80", "/path/goes/here", 
"query-here", "frag-here" },
      { "http", "userid", "passwd", "", "80", "/path/goes/here", "query-here", 
"frag-here" },
      { "http", "userid", "passwd", "hostname.goes.here", "", 
"/path/goes/here", "query-here", "frag-here" },
  #if 0
      /* An empty path means two different things depending on whether this is a
       * relative or an absolute uri... consider <a href="#frag"> versus "GET
       * http://hostname HTTP/1.1".  So this is why parse_uri_components returns
       * a NULL for path when it doesn't find one, instead of returning an empty
       * string.
       *
       * We don't really need to test it explicitly since path has no explicit
       * character that indicates its precense, and so we test empty paths all
       * the time by varying T_path in the loop.  It would just cost us extra
       * code to special case the empty path string...
       */
      { "http", "userid", "passwd", "hostname.goes.here", "80", "", 
"query-here", "frag-here" },
  #endif
      { "http", "userid", "passwd", "hostname.goes.here", "80", 
"/path/goes/here", "", "frag-here" },
      { "http", "userid", "passwd", "hostname.goes.here", "80", 
"/path/goes/here", "query-here", "" },
      { "https", "[EMAIL PROTECTED]", "pa:swd", "hostname.goes.here.", "", 
"/~path/goes/here", "query&query?crud", "frag-here?baby" }
  
  };
  
  static char *my_stpcpy(char *d, const char *s)
  {
      while((*d = *s)) {
        ++d;
        ++s;
      }
      return d;
  }
  
  /* return the number of failures */
  static unsigned iterate_pieces(request_rec *r, const test_uri_t *pieces, int 
row)
  {
      unsigned u;
      pool *sub;
      char *input_uri;
      char *strp;
      uri_components result;
      unsigned expect;
      int status;
      unsigned failures;
  
      failures = 0;
  
      input_uri = palloc(r->pool,
        strlen(pieces->scheme) + 3
        + strlen(pieces->user) + 1
        + strlen(pieces->password) + 1
        + strlen(pieces->hostname) + 1
        + strlen(pieces->port_str) + 1
        + strlen(pieces->path) +
        + strlen(pieces->query) + 1
        + strlen(pieces->fragment) + 1
        + 1);
  
      for (u = 0; u < T_MAX; ++u) {
        strp = input_uri;
        expect = 0;
  
        if (u & T_scheme) {
            expect |= T_scheme;
            strp = my_stpcpy(strp, pieces->scheme);
            *strp++ = ':';
        }
        /* can't have hostinfo without hostname */
        if (u & (T_user|T_password|T_hostname|T_port_str)) {
            *strp++ = '/';
            *strp++ = '/';
            /* can't have password without user */
            if (u & (T_user|T_password)) {
                expect |= T_user;
                strp = my_stpcpy(strp, pieces->user);
                if (u & T_password) {
                    expect |= T_password;
                    *strp++ = ':';
                    strp = my_stpcpy(strp, pieces->password);
                }
                *strp++ = '@';
            }
            expect |= T_hostname;
            strp = my_stpcpy(strp, pieces->hostname);
            if (u & T_port_str) {
                expect |= T_port_str;
                *strp++ = ':';
                strp = my_stpcpy(strp, pieces->port_str);
            }
        }
        if (u & T_path) {
            expect |= T_path;
            strp = my_stpcpy(strp, pieces->path);
        }
        if (u & T_query) {
            expect |= T_query;
            *strp++ = '?';
            strp = my_stpcpy(strp, pieces->query);
        }
        if (u & T_fragment) {
            expect |= T_fragment;
            *strp++ = '#';
            strp = my_stpcpy(strp, pieces->fragment);
        }
        *strp = 0;
  
        sub = make_sub_pool(r->pool);
        status = parse_uri_components(sub, input_uri, &result);
        if (status == HTTP_OK) {
  #define CHECK(f)                                                      \
            if ((expect & T_##f)                                        \
                && (result.f == NULL || strcmp(result.f, pieces->f))) { \
                status = HTTP_INTERNAL_SERVER_ERROR;                    \
            }                                                           \
            else if (!(expect & T_##f) && result.f != NULL) {           \
                status = HTTP_INTERNAL_SERVER_ERROR;                    \
            }
            CHECK(scheme)
            CHECK(user)
            CHECK(password)
            CHECK(hostname)
            CHECK(port_str)
            CHECK(path)
            CHECK(query)
            CHECK(fragment)
  #undef CHECK
        }
        if (status != HTTP_OK) {
            rprintf(r, 
"<tr><td>%d</td><td>0x%02x</td><td>0x%02x</td><td>%d</td><td>\"%s\"</td>", row, 
u, expect, status, input_uri);
  #define DUMP(f)                                                       \
            if (result.f) {                                             \
                rvputs(r, "<td>\"", result.f, "\"<br>", NULL);          \
            }                                                           \
            else {                                                      \
                rputs("<td>NULL<br>", r);                               \
            }                                                           \
            if (expect & T_##f) {                                       \
                rvputs(r, "\"", pieces->f, "\"</td>", NULL);            \
            }                                                           \
            else {                                                      \
                rputs("NULL</td>", r);                                  \
            }
            DUMP(scheme);
            DUMP(user);
            DUMP(password);
            DUMP(hostname);
            DUMP(port_str);
            DUMP(path);
            DUMP(query);
            DUMP(fragment);
  #undef DUMP
            rputs("</tr>\n", r);
            ++failures;
        }
        destroy_pool(sub);
      }
      return failures;
  }
  
  static int test_util_uri(request_rec *r)
  {
      unsigned total_failures;
      int i;
  
      r->allowed |= (1 << M_GET);
      if (r->method_number != M_GET)
        return DECLINED;
  
      r->content_type = "text/html";            
      send_http_header(r);
      if(r->header_only) {
        return 0;
      }
      hard_timeout("test_util_uri", r);
  
      rputs("
  <html><body>
  <p>Key:
  <dl>
  <dt>row
  <dd>entry number in the uri_tests array
  <dt>u
  <dd>fields under test
  <dt>expected
  <dd>fields expected in the result
  <dt>status
  <dd>response from parse_uri_components, or 500 if unexpected results
  <dt>input uri
  <dd>the uri given to parse_uri_components
  </dl>
  <p>The remaining fields are the pieces returned from parse_uri_components, and
  the values we expected for each piece (resp.).
  <p>Only failures are displayed.
  <p>
  <table><tr><th>row</th><th>u</th><th>expect</th><th>status</th><th>input 
uri</th>", r);
  #define HEADER(f) rprintf(r, "<th>" #f "<br>0x%02x</th>", T_##f)
      HEADER(scheme);
      HEADER(user);
      HEADER(password);
      HEADER(hostname);
      HEADER(port_str);
      HEADER(path);
      HEADER(query);
      HEADER(fragment);
  #undef HEADER
  
      total_failures = 0;
      for (i = 0; i < sizeof(uri_tests) / sizeof(uri_tests[0]); ++i) {
        total_failures += iterate_pieces(r, &uri_tests[i], i);
      }
      rprintf(r, "</table>\nTOTAL FAILURES = %u\n", total_failures);
  
      return OK;
  }
  
  static handler_rec test_util_uri_handlers[] =
  {
      {"test-util-uri", test_util_uri},
      {NULL}
  };
  
  module test_util_uri_module = {
      STANDARD_MODULE_STUFF,
      NULL,                       /* initializer */
      NULL,                     /* dir config creater */
      NULL,                       /* dir merger --- default is to override */
      NULL,                       /* server config */
      NULL,                       /* merge server config */
      NULL,                     /* command table */
      test_util_uri_handlers,   /* handlers */
      NULL,                       /* filename translation */
      NULL,                       /* check_user_id */
      NULL,                       /* check auth */
      NULL,                       /* check access */
      NULL,                       /* type_checker */
      NULL,                       /* fixups */
      NULL,                       /* logger */
      NULL                        /* header parser */
  };
  
  
  
  1.2       +26 -12    apache-1.3/src/test/vhtest/bin/test1
  
  Index: test1
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/test/vhtest/bin/test1,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- test1     1997/11/10 02:11:42     1.1
  +++ test1     1998/03/02 06:51:23     1.2
  @@ -1,15 +1,29 @@
  -bin/vhget 127.0.0.1 8080 '' vhost1
  -bin/vhget 127.0.0.1 8080 vhost1:8080 vhost1
  -bin/vhget 127.0.0.1 8080 vhost2:8080 vhost1
  +bin/vhget 127.0.0.1 8080 '' '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 'vhost1:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 'vhost2:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost2:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost1:8080' vhost1
   
  -bin/vhget 127.0.0.2 8080 '' vhost2
  -bin/vhget 127.0.0.2 8080 vhost2:8080 vhost2
  -bin/vhget 127.0.0.2 8080 vhost1:8080 vhost2
  +bin/vhget 127.0.0.2 8080 '' '' vhost2
  +bin/vhget 127.0.0.2 8080 vhost2:8080 '' vhost2
  +bin/vhget 127.0.0.2 8080 vhost1:8080 '' vhost2
  +bin/vhget 127.0.0.2 8080 vhost1:8080 'vhost1:8080' vhost2
  +bin/vhget 127.0.0.2 8080 vhost1:8080 'vhost2:8080' vhost2
  +bin/vhget 127.0.0.2 8080 vhost2:8080 'vhost2:8080' vhost2
  +bin/vhget 127.0.0.2 8080 vhost2:8080 'vhost1:8080' vhost2
   
  -bin/vhget 127.0.0.3 8080 '' vhost3
  -bin/vhget 127.0.0.3 8080 vhost3:8080 vhost3
  -bin/vhget 127.0.0.3 8080 vhost4:8080 vhost4
  +bin/vhget 127.0.0.3 8080 '' '' vhost3
  +bin/vhget 127.0.0.3 8080 vhost3:8080 '' vhost3
  +bin/vhget 127.0.0.3 8080 vhost3:8080 'vhost3:8080' vhost3
  +bin/vhget 127.0.0.3 8080 vhost3:8080 'vhost4:8080' vhost4
  +bin/vhget 127.0.0.3 8080 vhost4:8080 '' vhost4
  +bin/vhget 127.0.0.3 8080 vhost4:8080 'vhost3:8080' vhost3
  +bin/vhget 127.0.0.3 8080 vhost4:8080 'vhost4:8080' vhost4
   
  -bin/vhget 127.0.0.4 8080 '' main
  -bin/vhget 127.0.0.4 8080 'vhost1' main
  -bin/vhget 127.0.0.4 8080 'vhost2' main
  +bin/vhget 127.0.0.4 8080 '' '' main
  +bin/vhget 127.0.0.4 8080 'vhost1' '' main
  +bin/vhget 127.0.0.4 8080 'vhost1' 'vhost1:8080' main
  +bin/vhget 127.0.0.4 8080 'vhost2' '' main
  +bin/vhget 127.0.0.4 8080 'vhost2' 'vhost2:8080' main
  
  
  
  1.2       +26 -12    apache-1.3/src/test/vhtest/bin/test1d
  
  Index: test1d
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/test/vhtest/bin/test1d,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- test1d    1997/11/10 02:11:42     1.1
  +++ test1d    1998/03/02 06:51:23     1.2
  @@ -1,15 +1,29 @@
  -bin/vhget 127.0.0.1 8080 '' vhost1
  -bin/vhget 127.0.0.1 8080 vhost1:8080 vhost1
  -bin/vhget 127.0.0.1 8080 vhost2:8080 vhost1
  +bin/vhget 127.0.0.1 8080 '' '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 'vhost1:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 'vhost2:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost2:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost1:8080' vhost1
   
  -bin/vhget 127.0.0.2 8080 '' vhost2
  -bin/vhget 127.0.0.2 8080 vhost2:8080 vhost2
  -bin/vhget 127.0.0.2 8080 vhost1:8080 vhost2
  +bin/vhget 127.0.0.2 8080 '' '' vhost2
  +bin/vhget 127.0.0.2 8080 vhost2:8080 '' vhost2
  +bin/vhget 127.0.0.2 8080 vhost1:8080 '' vhost2
  +bin/vhget 127.0.0.2 8080 vhost1:8080 'vhost1:8080' vhost2
  +bin/vhget 127.0.0.2 8080 vhost1:8080 'vhost2:8080' vhost2
  +bin/vhget 127.0.0.2 8080 vhost2:8080 'vhost2:8080' vhost2
  +bin/vhget 127.0.0.2 8080 vhost2:8080 'vhost1:8080' vhost2
   
  -bin/vhget 127.0.0.3 8080 '' vhost3
  -bin/vhget 127.0.0.3 8080 vhost3:8080 vhost3
  -bin/vhget 127.0.0.3 8080 vhost4:8080 vhost4
  +bin/vhget 127.0.0.3 8080 '' '' vhost3
  +bin/vhget 127.0.0.3 8080 vhost3:8080 '' vhost3
  +bin/vhget 127.0.0.3 8080 vhost3:8080 'vhost3:8080' vhost3
  +bin/vhget 127.0.0.3 8080 vhost3:8080 'vhost4:8080' vhost4
  +bin/vhget 127.0.0.3 8080 vhost4:8080 '' vhost4
  +bin/vhget 127.0.0.3 8080 vhost4:8080 'vhost3:8080' vhost3
  +bin/vhget 127.0.0.3 8080 vhost4:8080 'vhost4:8080' vhost4
   
  -bin/vhget 127.0.0.4 8080 '' default1
  -bin/vhget 127.0.0.4 8080 'vhost1' default1
  -bin/vhget 127.0.0.4 8080 'vhost2' default1
  +bin/vhget 127.0.0.4 8080 '' '' default1
  +bin/vhget 127.0.0.4 8080 'vhost1' '' default1
  +bin/vhget 127.0.0.4 8080 'vhost1' 'vhost1:8080' default1
  +bin/vhget 127.0.0.4 8080 'vhost2' '' default1
  +bin/vhget 127.0.0.4 8080 'vhost2' 'vhost2:8080' default1
  
  
  
  1.2       +40 -23    apache-1.3/src/test/vhtest/bin/test2
  
  Index: test2
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/test/vhtest/bin/test2,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- test2     1997/11/10 02:11:43     1.1
  +++ test2     1998/03/02 06:51:23     1.2
  @@ -1,28 +1,45 @@
  -bin/vhget 127.0.0.1 8080 '' vhost1
  -bin/vhget 127.0.0.1 8080 vhost1:8080 vhost1
  -bin/vhget 127.0.0.1 8080 vhost2:8080 vhost1
  +bin/vhget 127.0.0.1 8080 '' '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost1:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 'vhost2:8080' vhost1
   
  -bin/vhget 127.0.0.1 8081 '' vhost2
  -bin/vhget 127.0.0.1 8081 vhost2:8081 vhost2
  -bin/vhget 127.0.0.1 8081 vhost1:8081 vhost2
  +bin/vhget 127.0.0.1 8081 '' '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost2:8081 '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost1:8081 'vhost2:8081' vhost2
  +bin/vhget 127.0.0.1 8081 vhost1:8081 '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost2:8081 'vhost1:8081' vhost2
   
  -bin/vhget 127.0.0.2 8080 '' vhost3
  -bin/vhget 127.0.0.2 8080 vhost3:8080 vhost3
  -bin/vhget 127.0.0.2 8080 vhost1:8080 vhost3
  -bin/vhget 127.0.0.2 8081 '' vhost3
  -bin/vhget 127.0.0.2 8081 vhost3:8081 vhost3
  -bin/vhget 127.0.0.2 8081 vhost1:8081 vhost3
  +bin/vhget 127.0.0.2 8080 '' '' vhost3
  +bin/vhget 127.0.0.2 8080 vhost3:8080 '' vhost3
  +bin/vhget 127.0.0.2 8080 vhost1:8080 'vhost3:8080' vhost3
  +bin/vhget 127.0.0.2 8080 vhost1:8080 '' vhost3
  +bin/vhget 127.0.0.2 8080 vhost3:8080 'vhost1:8080' vhost3
  +bin/vhget 127.0.0.2 8081 '' '' vhost3
  +bin/vhget 127.0.0.2 8081 vhost3:8081 '' vhost3
  +bin/vhget 127.0.0.2 8081 vhost3:8081 'vhost1:8081' vhost3
  +bin/vhget 127.0.0.2 8081 vhost1:8081 '' vhost3
  +bin/vhget 127.0.0.2 8081 vhost1:8081 'vhost3:8081' vhost3
   
  -bin/vhget 127.0.0.3 8080 '' vhost4
  -bin/vhget 127.0.0.3 8080 'vhost4:8080' vhost4
  -bin/vhget 127.0.0.3 8080 'vhost5:8080' vhost5
  +bin/vhget 127.0.0.3 8080 '' '' vhost4
  +bin/vhget 127.0.0.3 8080 'vhost4:8080' '' vhost4
  +bin/vhget 127.0.0.3 8080 'vhost5:8080' 'vhost4:8080' vhost4
  +bin/vhget 127.0.0.3 8080 'vhost5:8080' 'bogus:8080' vhost4
  +bin/vhget 127.0.0.3 8080 'vhost5:8080' '' vhost5
  +bin/vhget 127.0.0.3 8080 'vhost4:8080' 'vhost5:8080' vhost5
   
  -bin/vhget 127.0.0.3 8081 '' vhost5
  -bin/vhget 127.0.0.3 8081 'vhost4:8081' vhost5
  -bin/vhget 127.0.0.3 8081 'vhost5:8081' vhost5
  -bin/vhget 127.0.0.3 8081 'alt5:8081' vhost5
  +bin/vhget 127.0.0.3 8081 '' '' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost4:8081' '' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost4:8081' 'vhost4:8081' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost4:8081' 'bogus:8081' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost4:8081' 'alt5:8081' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost5:8081' '' vhost5
  +bin/vhget 127.0.0.3 8081 'alt5:8081' '' vhost5
   
  -bin/vhget 127.0.0.4 8080 '' main
  -bin/vhget 127.0.0.4 8080 'vhost1:8080' main
  -bin/vhget 127.0.0.4 8081 '' main
  -bin/vhget 127.0.0.4 8081 'vhost1:8081' main
  +bin/vhget 127.0.0.4 8080 '' '' main
  +bin/vhget 127.0.0.4 8080 'asdf' 'bogus' main
  +bin/vhget 127.0.0.4 8080 'vhost1:8080' '' main
  +bin/vhget 127.0.0.4 8080 'vhost1:8080' 'vhost2:8081' main
  +bin/vhget 127.0.0.4 8081 '' '' main
  +bin/vhget 127.0.0.4 8081 'asdf' 'bogus:8080' main
  +bin/vhget 127.0.0.4 8081 'vhost1:8081' '' main
  
  
  
  1.2       +40 -23    apache-1.3/src/test/vhtest/bin/test2d
  
  Index: test2d
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/test/vhtest/bin/test2d,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- test2d    1997/11/10 02:11:43     1.1
  +++ test2d    1998/03/02 06:51:24     1.2
  @@ -1,28 +1,45 @@
  -bin/vhget 127.0.0.1 8080 '' vhost1
  -bin/vhget 127.0.0.1 8080 vhost1:8080 vhost1
  -bin/vhget 127.0.0.1 8080 vhost2:8080 vhost1
  +bin/vhget 127.0.0.1 8080 '' '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost1:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 'vhost2:8080' vhost1
   
  -bin/vhget 127.0.0.1 8081 '' vhost2
  -bin/vhget 127.0.0.1 8081 vhost2:8081 vhost2
  -bin/vhget 127.0.0.1 8081 vhost1:8081 vhost2
  +bin/vhget 127.0.0.1 8081 '' '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost2:8081 '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost1:8081 'vhost2:8081' vhost2
  +bin/vhget 127.0.0.1 8081 vhost1:8081 '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost2:8081 'vhost1:8081' vhost2
   
  -bin/vhget 127.0.0.2 8080 '' vhost3
  -bin/vhget 127.0.0.2 8080 vhost3:8080 vhost3
  -bin/vhget 127.0.0.2 8080 vhost1:8080 vhost3
  -bin/vhget 127.0.0.2 8081 '' vhost3
  -bin/vhget 127.0.0.2 8081 vhost3:8081 vhost3
  -bin/vhget 127.0.0.2 8081 vhost1:8081 vhost3
  +bin/vhget 127.0.0.2 8080 '' '' vhost3
  +bin/vhget 127.0.0.2 8080 vhost3:8080 '' vhost3
  +bin/vhget 127.0.0.2 8080 vhost1:8080 'vhost3:8080' vhost3
  +bin/vhget 127.0.0.2 8080 vhost1:8080 '' vhost3
  +bin/vhget 127.0.0.2 8080 vhost3:8080 'vhost1:8080' vhost3
  +bin/vhget 127.0.0.2 8081 '' '' vhost3
  +bin/vhget 127.0.0.2 8081 vhost3:8081 '' vhost3
  +bin/vhget 127.0.0.2 8081 vhost3:8081 'vhost1:8081' vhost3
  +bin/vhget 127.0.0.2 8081 vhost1:8081 '' vhost3
  +bin/vhget 127.0.0.2 8081 vhost1:8081 'vhost3:8081' vhost3
   
  -bin/vhget 127.0.0.3 8080 '' vhost4
  -bin/vhget 127.0.0.3 8080 'vhost4:8080' vhost4
  -bin/vhget 127.0.0.3 8080 'vhost5:8080' vhost5
  +bin/vhget 127.0.0.3 8080 '' '' vhost4
  +bin/vhget 127.0.0.3 8080 'vhost4:8080' '' vhost4
  +bin/vhget 127.0.0.3 8080 'vhost5:8080' 'vhost4:8080' vhost4
  +bin/vhget 127.0.0.3 8080 'vhost5:8080' 'bogus:8080' vhost4
  +bin/vhget 127.0.0.3 8080 'vhost5:8080' '' vhost5
  +bin/vhget 127.0.0.3 8080 'vhost4:8080' 'vhost5:8080' vhost5
   
  -bin/vhget 127.0.0.3 8081 '' vhost5
  -bin/vhget 127.0.0.3 8081 'vhost4:8081' vhost5
  -bin/vhget 127.0.0.3 8081 'vhost5:8081' vhost5
  -bin/vhget 127.0.0.3 8081 'alt5:8081' vhost5
  +bin/vhget 127.0.0.3 8081 '' '' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost4:8081' '' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost4:8081' 'vhost4:8081' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost4:8081' 'bogus:8081' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost4:8081' 'alt5:8081' vhost5
  +bin/vhget 127.0.0.3 8081 'vhost5:8081' '' vhost5
  +bin/vhget 127.0.0.3 8081 'alt5:8081' '' vhost5
   
  -bin/vhget 127.0.0.4 8080 '' default1
  -bin/vhget 127.0.0.4 8080 'vhost1:8080' default1
  -bin/vhget 127.0.0.4 8081 '' default2
  -bin/vhget 127.0.0.4 8081 'vhost1:8081' default2
  +bin/vhget 127.0.0.4 8080 '' '' default1
  +bin/vhget 127.0.0.4 8080 'asdf' 'bogus' default1
  +bin/vhget 127.0.0.4 8080 'vhost1:8080' '' default1
  +bin/vhget 127.0.0.4 8080 'vhost1:8080' 'vhost2:8081' default1
  +bin/vhget 127.0.0.4 8081 '' '' default2
  +bin/vhget 127.0.0.4 8081 'asdf' 'bogus:8080' default2
  +bin/vhget 127.0.0.4 8081 'vhost1:8081' '' default2
  
  
  
  1.2       +17 -12    apache-1.3/src/test/vhtest/bin/test3
  
  Index: test3
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/test/vhtest/bin/test3,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- test3     1997/11/10 02:11:43     1.1
  +++ test3     1998/03/02 06:51:24     1.2
  @@ -1,13 +1,18 @@
  -bin/vhget 127.0.0.1 8080 '' vhost1
  -bin/vhget 127.0.0.1 8080 vhost1:8080 vhost1
  -bin/vhget 127.0.0.1 8080 vhost2:8080 vhost2
  -bin/vhget 127.0.0.1 8080 vhost3:8080 vhost3
  -bin/vhget 127.0.0.1 8080 vhost4:8080 vhost1
  -bin/vhget 127.0.0.1 8080 vhost5:8080 vhost5
  +bin/vhget 127.0.0.1 8080 '' '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost1:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost1:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 '' vhost2
  +bin/vhget 127.0.0.1 8080 vhost1:8080 'vhost2:8080' vhost2
  +bin/vhget 127.0.0.1 8080 vhost3:8080 '' vhost3
  +bin/vhget 127.0.0.1 8080 vhost4:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost5:8080 'vhost4:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost5:8080 '' vhost5
   
  -bin/vhget 127.0.0.1 8081 '' vhost2
  -bin/vhget 127.0.0.1 8081 vhost1:8081 vhost2
  -bin/vhget 127.0.0.1 8081 vhost2:8081 vhost2
  -bin/vhget 127.0.0.1 8081 vhost3:8081 vhost3
  -bin/vhget 127.0.0.1 8081 vhost4:8081 vhost4
  -bin/vhget 127.0.0.1 8081 vhost5:8081 vhost5
  +bin/vhget 127.0.0.1 8081 '' '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost1:8081 '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost3:8081 'vhost1:8081' vhost2
  +bin/vhget 127.0.0.1 8081 vhost2:8081 '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost3:8081 '' vhost3
  +bin/vhget 127.0.0.1 8081 vhost4:8081 '' vhost4
  +bin/vhget 127.0.0.1 8081 vhost5:8081 '' vhost5
  
  
  
  1.2       +12 -8     apache-1.3/src/test/vhtest/bin/test4
  
  Index: test4
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/test/vhtest/bin/test4,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- test4     1997/11/10 02:11:44     1.1
  +++ test4     1998/03/02 06:51:25     1.2
  @@ -1,9 +1,13 @@
  -bin/vhget 127.0.0.1 8080 '' vhost1
  -bin/vhget 127.0.0.1 8080 vhost1:8080 vhost1
  -bin/vhget 127.0.0.1 8080 vhost2:8080 vhost2
  -bin/vhget 127.0.0.1 8080 vhost3:8080 vhost1
  +bin/vhget 127.0.0.1 8080 '' '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost1:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost3:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 '' vhost2
  +bin/vhget 127.0.0.1 8080 vhost3:8080 '' vhost1
   
  -bin/vhget 127.0.0.1 8081 '' vhost1
  -bin/vhget 127.0.0.1 8081 vhost1:8081 vhost1
  -bin/vhget 127.0.0.1 8081 vhost2:8081 vhost2
  -bin/vhget 127.0.0.1 8081 vhost3:8081 vhost1
  +bin/vhget 127.0.0.1 8081 '' '' vhost1
  +bin/vhget 127.0.0.1 8081 vhost1:8081 '' vhost1
  +bin/vhget 127.0.0.1 8081 vhost2:8081 'vhost1:8081' vhost1
  +bin/vhget 127.0.0.1 8081 vhost2:8081 'vhost3:8081' vhost1
  +bin/vhget 127.0.0.1 8081 vhost2:8081 '' vhost2
  +bin/vhget 127.0.0.1 8081 vhost3:8081 '' vhost1
  
  
  
  1.2       +26 -18    apache-1.3/src/test/vhtest/bin/test5
  
  Index: test5
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/test/vhtest/bin/test5,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- test5     1997/11/10 02:11:44     1.1
  +++ test5     1998/03/02 06:51:25     1.2
  @@ -1,23 +1,31 @@
  -bin/vhget 127.0.0.1 8080 '' vhost1
  -bin/vhget 127.0.0.1 8080 vhost1:8080 vhost1
  -bin/vhget 127.0.0.1 8080 vhost2:8080 vhost2
  -bin/vhget 127.0.0.1 8080 vhost3:8080 vhost1
  +bin/vhget 127.0.0.1 8080 '' '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost1:8080 '' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'bogus' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 'vhost1:8080' vhost1
  +bin/vhget 127.0.0.1 8080 vhost2:8080 '' vhost2
  +bin/vhget 127.0.0.1 8080 vhost1:8080 'vhost2:8080' vhost2
  +bin/vhget 127.0.0.1 8080 vhost3:8080 '' vhost1
   
  -bin/vhget 127.0.0.2 8080 '' vhost3
  -bin/vhget 127.0.0.2 8080 'vhost3:8080' vhost3
  -bin/vhget 127.0.0.2 8080 'vhost1:8080' vhost3
  +bin/vhget 127.0.0.2 8080 '' '' vhost3
  +bin/vhget 127.0.0.2 8080 'vhost3:8080' '' vhost3
  +bin/vhget 127.0.0.2 8080 'vhost1:8080' 'bogus' vhost3
  +bin/vhget 127.0.0.2 8080 'vhost1:8080' '' vhost3
   
  -bin/vhget 127.0.0.3 8080 '' default1
  -bin/vhget 127.0.0.3 8080 'vhost1:8080' default1
  +bin/vhget 127.0.0.3 8080 '' '' default1
  +bin/vhget 127.0.0.3 8080 'vhost1:8080' '' default1
  +bin/vhget 127.0.0.3 8080 'asdf' 'bogus' default1
   
  -bin/vhget 127.0.0.1 8081 '' vhost4
  -bin/vhget 127.0.0.1 8081 vhost1:8081 vhost4
  -bin/vhget 127.0.0.1 8081 vhost2:8081 vhost4
  -bin/vhget 127.0.0.1 8081 vhost3:8081 vhost4
  +bin/vhget 127.0.0.1 8081 '' '' vhost4
  +bin/vhget 127.0.0.1 8081 vhost1:8081 '' vhost4
  +bin/vhget 127.0.0.1 8081 vhost2:8081 'vhost1:8080' vhost4
  +bin/vhget 127.0.0.1 8081 vhost2:8081 '' vhost4
  +bin/vhget 127.0.0.1 8081 vhost3:8081 '' vhost4
   
  -bin/vhget 127.0.0.2 8081 '' vhost5
  -bin/vhget 127.0.0.2 8081 'vhost3:8081' vhost5
  -bin/vhget 127.0.0.2 8081 'vhost1:8081' vhost5
  +bin/vhget 127.0.0.2 8081 '' '' vhost5
  +bin/vhget 127.0.0.2 8081 'vhost3:8081' '' vhost5
  +bin/vhget 127.0.0.2 8081 'vhost1:8081' 'vhost3:8081' vhost5
  +bin/vhget 127.0.0.2 8081 'vhost1:8081' '' vhost5
   
  -bin/vhget 127.0.0.3 8081 '' default2
  -bin/vhget 127.0.0.3 8081 'vhost1:8081' default2
  +bin/vhget 127.0.0.3 8081 '' '' default2
  +bin/vhget 127.0.0.3 8081 'bogus' 'asdf' default2
  +bin/vhget 127.0.0.3 8081 'vhost1:8081' '' default2
  
  
  
  1.2       +16 -11    apache-1.3/src/test/vhtest/bin/vhget
  
  Index: vhget
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/test/vhtest/bin/vhget,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- vhget     1997/11/10 02:11:45     1.1
  +++ vhget     1998/03/02 06:51:26     1.2
  @@ -4,18 +4,20 @@
   use strict;
   use Socket;
   
  -# vhget ipaddr port hostheader expect
  +# vhget ipaddr port hostheader absurihost expect
   
  -$#ARGV == 3 || die "usage: $0 ipaddr port hostheader expect\n";
  +$#ARGV == 4 || die "usage: $0 ipaddr port hostheader absurihost expect\n";
   
   my ($remote,$port, $iaddr, $paddr, $proto, $line);
   
  -$remote = shift;
  -$port = shift;
  -my $hostheader = shift;
  -my $expect = shift;
  +my ($hostheader, $expect, $absurihost);
   
  -printf "%-20s %-20s %-15s: ", "$remote:$port", "'$hostheader'", "'$expect'";
  +($remote, $port, $hostheader, $absurihost, $expect) = @ARGV;
  +if ($absurihost ne '') {
  +    $absurihost = "http://$absurihost";;
  +}
  +
  +printf "%-20s %-20s %-20s %-15s: ", "$remote:$port", "'$hostheader'", 
"'$absurihost'", "'$expect'";
   
   if ($port =~ /\D/) {
       $port = getservbyname($port, 'tcp');
  @@ -29,16 +31,18 @@
   
   my $oldfh = select(SOCK); $| = 1; select($oldfh);
   
  +$proto = ($absurihost ne '') ? "HTTP/1.1" : "HTTP/1.0";
  +
   if ($hostheader ne '') {
       print SOCK <<EOR;
  -GET /vhost.txt HTTP/1.0\r
  +GET $absurihost/vhost.txt $proto\r
   Host: $hostheader\r
   Connection: close\r
   \r
   EOR
   } else {
       print SOCK <<EOR;
  -GET /vhost.txt HTTP/1.0\r
  +GET $absurihost/vhost.txt $proto\r
   Connection: close\r
   \r
   EOR
  @@ -56,8 +60,9 @@
   
   chomp($line);
   
  -my $death = "$remote:$port with " .
  -     ( $hostheader eq '' ? "no Host:" : "Host: $hostheader" )
  +my $death = "$remote:$port with "
  +     . ( $hostheader eq '' ? "no Host:" : "Host: $hostheader" )
  +     . ( $absurihost eq '' ? " no absuri" : " and absuri $absurihost" )
        . " expected $expect, but got $line\n";
   if ($line eq $expect) {
       print "passed\n";
  
  
  

Reply via email to