You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by fi...@apache.org on 2001/05/22 03:07:45 UTC

cvs commit: apr-util/uri apr_uri.c gen_uri_delims.c gen_uri_delims.dsp gen_uri_delims.mak

fielding    01/05/21 18:07:45

  Added:       include  apr_uri.h
               uri      apr_uri.c gen_uri_delims.c gen_uri_delims.dsp
                        gen_uri_delims.mak
  Log:
  Moved from httpd-2.0 without any changes
  
     httpd-2.0/include/util_uri.h       --> include/apr_uri.h
     httpd-2.0/server/util_uri.c        --> uri/apr_uri.c
     httpd-2.0/server/gen_uri_delims.*  --> uri/gen_uri_delims.*
  
  Obtained from: Apache httpd 2.0.18
  
  Revision  Changes    Path
  1.1                  apr-util/include/apr_uri.h
  
  Index: apr_uri.h
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  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. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * util_uri.h: External Interface of util_uri.c
   */
  
  #ifndef UTIL_URI_H
  #define UTIL_URI_H
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  /**
   * @package Apache URI library
   */
  
  typedef struct schemes_t schemes_t;
  
  /** Structure to store various schemes and their default ports */
  struct schemes_t {
      /** The name of the scheme */
      const char *name;
      /** The default port for the scheme */
      apr_port_t default_port;
  };
  
  #define	DEFAULT_FTP_DATA_PORT	20
  #define	DEFAULT_FTP_PORT	21
  #define	DEFAULT_GOPHER_PORT	70
  #define	DEFAULT_NNTP_PORT	119
  #define	DEFAULT_WAIS_PORT	210
  #define	DEFAULT_SNEWS_PORT	563
  #define	DEFAULT_PROSPERO_PORT	1525	/* WARNING: conflict w/Oracle */
  
  /* Flags passed to unparse_uri_components(): */
  #define UNP_OMITSITEPART	(1U<<0)	/* suppress "scheme://user@site:port" */
  #define	UNP_OMITUSER		(1U<<1)	/* Just omit user */
  #define	UNP_OMITPASSWORD	(1U<<2)	/* Just omit password */
  #define	UNP_OMITUSERINFO	(UNP_OMITUSER|UNP_OMITPASSWORD)	/* omit "user:password@" part */
  #define	UNP_REVEALPASSWORD	(1U<<3)	/* Show plain text password (default: show XXXXXXXX) */
  #define UNP_OMITPATHINFO	(1U<<4)	/* Show "scheme://user@site:port" only */
  #define UNP_OMITQUERY	        (1U<<5)	/* Omit the "?queryarg" from the path */
  
  typedef struct uri_components uri_components;
  
  /**
   * A structure to encompass all of the fields in a uri
   */
  struct uri_components {
      /** scheme ("http"/"ftp"/...) */
      char *scheme;
      /** combined [user[:password]@]host[:port] */
      char *hostinfo;
      /** user name, as in http://user:passwd@host:port/ */
      char *user;
      /** password, as in http://user:passwd@host:port/ */
      char *password;
      /** hostname from URI (or from Host: header) */
      char *hostname;
      /** port string (integer representation is in "port") */
      char *port_str;
      /** the request path (or "/" if only scheme://host was given) */
      char *path;
      /** Everything after a '?' in the path, if present */
      char *query;
      /** Trailing "#fragment" string, if present */
      char *fragment;
  
      /** structure returned from gethostbyname() 
       *  @defvar struct hostent *hostent */
      struct hostent *hostent;
  
      /** The port number, numeric, valid only if port_str != NULL */
      apr_port_t port;
      
      /** has the structure been initialized */
      unsigned is_initialized:1;
  
      /** has the DNS been looked up yet */
      unsigned dns_looked_up:1;
      /** has the dns been resolved yet */
      unsigned dns_resolved:1;
  };
  
  /* util_uri.c */
  /**
   * Return the default port for a given scheme.  The schemes recognized are
   * http, ftp, https, gopher, wais, nntp, snews, and prospero
   * @param scheme_str The string that contains the current scheme
   * @return The default port for this scheme
   * @deffunc apr_port_t ap_default_port_for_scheme(const char *scheme_str)
   */ 
  AP_DECLARE(apr_port_t) ap_default_port_for_scheme(const char *scheme_str);
  
  /**
   * Return the default for the current request
   * @param r The current request
   * @return The default port
   * @deffunc apr_port_t ap_default_port_for_request(const request_rec *r)
   */
  AP_DECLARE(apr_port_t) ap_default_port_for_request(const request_rec *r);
  
  /**
   * Unparse a uri_components structure to an URI string.  Optionally suppress 
   * the password for security reasons.
   * @param p The pool to allocate out of
   * @param uri_components All of the parts of the uri
   * @param flags How to unparse the uri.  One of:
   * <PRE>
   *    UNP_OMITSITEPART        suppress "scheme://user@site:port" 
   *    UNP_OMITUSER            Just omit user 
   *    UNP_OMITPASSWORD        Just omit password 
   *    UNP_OMITUSERINFO        omit "user:password@" part 
   *    UNP_REVEALPASSWORD      Show plain text password (default: show XXXXXXXX) 
   *    UNP_OMITPATHINFO        Show "scheme://user@site:port" only 
   *    UNP_OMITQUERY           Omit the "?queryarg" from the path 
   * </PRE>
   * @return The uri as a string
   * @deffunc char * ap_unparse_uri_components(apr_pool_t *p, const uri_components *uptr, unsigned flags)
   */
  AP_DECLARE(char *) ap_unparse_uri_components(apr_pool_t *p, const uri_components *uptr,
      unsigned flags);
  
  /**
   * 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.
   * @param p The pool to allocate out of
   * @param uri The uri to parse
   * @param uptr The uri_components to fill out
   * @return An HTTP status code
   * @deffunc int ap_parse_uri_components(apr_pool_t *p, const char *uri, uri_components *uptr)
   */
  AP_DECLARE(int) ap_parse_uri_components(apr_pool_t *p, const char *uri, uri_components *uptr);
  
  /**
   * Special case for CONNECT parsing: it comes with the hostinfo part only
   * @param p The pool to allocate out of
   * @param hostinfo The hostinfo string to parse
   * @param uptr The uri_components to fill out
   * @return An HTTP status code
   * @deffunc int ap_parse_hostinfo_components(apr_pool_t *p, const char *hostinfo, uri_components *uptr)
   */
  AP_DECLARE(int) ap_parse_hostinfo_components(apr_pool_t *p, const char *hostinfo, uri_components *uptr);
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif /*UTIL_URI_H*/
  
  
  
  1.1                  apr-util/uri/apr_uri.c
  
  Index: apr_uri.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  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. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * util_uri.c: URI related utility things
   * 
   */
  
  #include "apr.h"
  #include "apr_strings.h"
  
  #define APR_WANT_STRFUNC
  #include "apr_want.h"
  
  #include "ap_config.h"
  #include "httpd.h"
  #include "http_log.h"
  #include "util_uri.h"
  
  /* Some WWW schemes and their default ports; this is basically /etc/services */
  /* This will become global when the protocol abstraction comes */
  /* As the schemes are searched by a linear search, */
  /* they are sorted by their expected frequency */
  static schemes_t schemes[] =
  {
      {"http",   DEFAULT_HTTP_PORT},
      {"ftp",    DEFAULT_FTP_PORT},
      {"https",  DEFAULT_HTTPS_PORT},
      {"gopher", DEFAULT_GOPHER_PORT},
      {"wais",   DEFAULT_WAIS_PORT},
      {"nntp",   DEFAULT_NNTP_PORT},
      {"snews",  DEFAULT_SNEWS_PORT},
      {"prospero", DEFAULT_PROSPERO_PORT},
      { NULL, 0xFFFF }			/* unknown port */
  };
  
  
  AP_DECLARE(apr_port_t) ap_default_port_for_scheme(const char *scheme_str)
  {
      schemes_t *scheme;
  
      for (scheme = schemes; scheme->name != NULL; ++scheme)
  	if (strcasecmp(scheme_str, scheme->name) == 0)
  	    return scheme->default_port;
  
      return 0;
  }
  
  AP_DECLARE(apr_port_t) ap_default_port_for_request(const request_rec *r)
  {
      return (r->parsed_uri.scheme)
  	? ap_default_port_for_scheme(r->parsed_uri.scheme)
  	: 0;
  }
  
  /* Unparse a uri_components structure to an URI string.
   * Optionally suppress the password for security reasons.
   */
  AP_DECLARE(char *) ap_unparse_uri_components(apr_pool_t *p, const uri_components *uptr, unsigned flags)
  {
      char *ret = "";
  
      /* If suppressing the site part, omit both user name & scheme://hostname */
      if (!(flags & UNP_OMITSITEPART)) {
  
  	/* Construct a "user:password@" string, honoring the passed UNP_ flags: */
  	if (uptr->user||uptr->password)
  	    ret = apr_pstrcat (p,
  			(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->hostname) {
  	    int is_default_port;
  
  	    is_default_port =
  		(uptr->port_str == NULL ||
  		 uptr->port == 0 ||
  		 uptr->port == ap_default_port_for_scheme(uptr->scheme));
  
  	    ret = apr_pstrcat (p,
  			uptr->scheme, "://", ret, 
  			uptr->hostname ? uptr->hostname : "",
  			is_default_port ? "" : ":",
  			is_default_port ? "" : uptr->port_str,
  			NULL);
  	}
      }
  
      /* Should we suppress all path info? */
      if (!(flags & UNP_OMITPATHINFO)) {
  	/* Append path, query and fragment strings: */
  	ret = apr_pstrcat (p,
  		ret,
  		uptr->path ? uptr->path : "",
  		(uptr->query    && !(flags & UNP_OMITQUERY)) ? "?" : "",
  		(uptr->query    && !(flags & UNP_OMITQUERY)) ? uptr->query : "",
  		(uptr->fragment && !(flags & UNP_OMITQUERY)) ? "#" : NULL,
  		(uptr->fragment && !(flags & UNP_OMITQUERY)) ? uptr->fragment : NULL,
  		NULL);
      }
      return ret;
  }
  
  /* Here is the hand-optimized parse_uri_components().  There are some wild
   * tricks we could pull in assembly language that we don't pull here... like we
   * can do word-at-time scans for delimiter characters using the same technique
   * that fast memchr()s use.  But that would be way non-portable. -djg
   */
  
  /* We have a apr_table_t that we can index by character and it tells us if the
   * character is one of the interesting delimiters.  Note that we even get
   * compares for NUL for free -- it's just another delimiter.
   */
  
  #define T_COLON		0x01	/* ':' */
  #define T_SLASH		0x02	/* '/' */
  #define T_QUESTION	0x04	/* '?' */
  #define T_HASH		0x08	/* '#' */
  #define T_NUL		0x80	/* '\0' */
  
  /* the uri_delims.h file is autogenerated by gen_uri_delims.c */
  #include "uri_delims.h"
  
  /* it works like this:
      if (uri_delims[ch] & NOTEND_foobar) {
  	then we're not at a delimiter for foobar
      }
  */
  
  /* Note that we optimize the scheme scanning here, we cheat and let the
   * compiler know that it doesn't have to do the & masking.
   */
  #define NOTEND_SCHEME	(0xff)
  #define NOTEND_HOSTINFO	(T_SLASH | T_QUESTION | T_HASH | T_NUL)
  #define NOTEND_PATH	(T_QUESTION | T_HASH | T_NUL)
  
  /* parse_uri_components():
   * Parse a given URI, fill in all supplied fields of a uri_components
   * structure. This eliminates the necessity of extracting host, port,
   * path, query info repeatedly in the modules.
   * Side effects:
   *  - fills in fields of uri_components *uptr
   *  - none on any of the r->* fields
   */
  AP_DECLARE(int) ap_parse_uri_components(apr_pool_t *p, const char *uri, uri_components *uptr)
  {
      const char *s;
      const char *s1;
      const char *hostinfo;
      char *endstr;
      int port;
  
      /* Initialize the structure. parse_uri() and parse_uri_components()
       * can be called more than once per request.
       */
      memset (uptr, '\0', sizeof(*uptr));
      uptr->is_initialized = 1;
  
      /* We assume the processor has a branch predictor like most --
       * it assumes forward branches are untaken and backwards are taken.  That's
       * the reason for the gotos.  -djg
       */
      if (uri[0] == '/') {
  deal_with_path:
  	/* we expect uri to point to first character of path ... remember
  	 * that the path could be empty -- http://foobar?query for example
  	 */
  	s = uri;
  	while ((uri_delims[*(unsigned char *)s] & NOTEND_PATH) == 0) {
  	    ++s;
  	}
  	if (s != uri) {
  	    uptr->path = apr_pstrndup(p, uri, s - uri);
  	}
  	if (*s == 0) {
  	    return HTTP_OK;
  	}
  	if (*s == '?') {
  	    ++s;
  	    s1 = ap_strchr_c(s, '#');
  	    if (s1) {
  		uptr->fragment = apr_pstrdup(p, s1 + 1);
  		uptr->query = apr_pstrndup(p, s, s1 - s);
  	    }
  	    else {
  		uptr->query = apr_pstrdup(p, s);
  	    }
  	    return HTTP_OK;
  	}
  	/* otherwise it's a fragment */
  	uptr->fragment = apr_pstrdup(p, s + 1);
  	return HTTP_OK;
      }
  
      /* find the scheme: */
      s = uri;
      while ((uri_delims[*(unsigned char *)s] & NOTEND_SCHEME) == 0) {
  	++s;
      }
      /* scheme must be non-empty and followed by :// */
      if (s == uri || s[0] != ':' || s[1] != '/' || s[2] != '/') {
  	goto deal_with_path;	/* backwards predicted taken! */
      }
  
      uptr->scheme = apr_pstrndup(p, uri, s - uri);
      s += 3;
      hostinfo = s;
      while ((uri_delims[*(unsigned char *)s] & NOTEND_HOSTINFO) == 0) {
  	++s;
      }
      uri = s;	/* whatever follows hostinfo is start of uri */
      uptr->hostinfo = apr_pstrndup(p, hostinfo, uri - hostinfo);
  
      /* If there's a username:password@host:port, the @ we want is the last @...
       * too bad there's no memrchr()... For the C purists, note that hostinfo
       * is definately not the first character of the original uri so therefore
       * &hostinfo[-1] < &hostinfo[0] ... and this loop is valid C.
       */
      do {
  	--s;
      } while (s >= hostinfo && *s != '@');
      if (s < hostinfo) {
  	/* again we want the common case to be fall through */
  deal_with_host:
  	/* We expect hostinfo to point to the first character of
  	 * the hostname.  If there's a port it is the first colon.
  	 */
  	s = memchr(hostinfo, ':', uri - hostinfo);
  	if (s == NULL) {
  	    /* we expect the common case to have no port */
  	    uptr->hostname = apr_pstrndup(p, hostinfo, uri - hostinfo);
  	    goto deal_with_path;
  	}
  	uptr->hostname = apr_pstrndup(p, hostinfo, s - hostinfo);
  	++s;
  	uptr->port_str = apr_pstrndup(p, s, uri - s);
  	if (uri != s) {
  	    port = strtol(uptr->port_str, &endstr, 10);
  	    uptr->port = port;
  	    if (*endstr == '\0') {
  		goto deal_with_path;
  	    }
  	    /* Invalid characters after ':' found */
  	    return HTTP_BAD_REQUEST;
  	}
  	uptr->port = ap_default_port_for_scheme(uptr->scheme);
  	goto deal_with_path;
      }
  
      /* first colon delimits username:password */
      s1 = memchr(hostinfo, ':', s - hostinfo);
      if (s1) {
  	uptr->user = apr_pstrndup(p, hostinfo, s1 - hostinfo);
  	++s1;
  	uptr->password = apr_pstrndup(p, s1, s - s1);
      }
      else {
  	uptr->user = apr_pstrndup(p, hostinfo, s - hostinfo);
      }
      hostinfo = s + 1;
      goto deal_with_host;
  }
  
  /* Special case for CONNECT parsing: it comes with the hostinfo part only */
  /* See the INTERNET-DRAFT document "Tunneling SSL Through a WWW Proxy"
   * currently at http://www.mcom.com/newsref/std/tunneling_ssl.html
   * for the format of the "CONNECT host:port HTTP/1.0" request
   */
  AP_DECLARE(int) ap_parse_hostinfo_components(apr_pool_t *p, const char *hostinfo, uri_components *uptr)
  {
      const char *s;
      char *endstr;
  
      /* Initialize the structure. parse_uri() and parse_uri_components()
       * can be called more than once per request.
       */
      memset (uptr, '\0', sizeof(*uptr));
      uptr->is_initialized = 1;
      uptr->hostinfo = apr_pstrdup(p, hostinfo);
  
      /* We expect hostinfo to point to the first character of
       * the hostname.  There must be a port, separated by a colon
       */
      s = ap_strchr_c(hostinfo, ':');
      if (s == NULL) {
  	return HTTP_BAD_REQUEST;
      }
      uptr->hostname = apr_pstrndup(p, hostinfo, s - hostinfo);
      ++s;
      uptr->port_str = apr_pstrdup(p, s);
      if (*s != '\0') {
  	uptr->port = (unsigned short) strtol(uptr->port_str, &endstr, 10);
  	if (*endstr == '\0') {
  	    return HTTP_OK;
  	}
  	/* Invalid characters after ':' found */
      }
      return HTTP_BAD_REQUEST;
  }
  
  
  
  1.1                  apr-util/uri/gen_uri_delims.c
  
  Index: gen_uri_delims.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  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. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  #include <stdio.h>
  
  /* generate a apr_table_t of 256 values, where certain characters are
   * marked "interesting"... for the uri parsing process.
   */
  
  int main(int argc, char *argv[])
  {
      int i;
      char *value;
  
      printf("/* this file is automatically generated by "
  	    "gen_uri_delims, do not edit */\n");
      printf("static const unsigned char uri_delims[256] = {");
      for (i = 0; i < 256; ++i) {
  	if (i % 20 == 0)
  	    printf("\n    ");
  	switch (i) {
  	case ':': 	value = "T_COLON";	break;
  	case '/': 	value = "T_SLASH";	break;
  	case '?': 	value = "T_QUESTION";	break;
  	case '#': 	value = "T_HASH";	break;
  	case '\0': 	value = "T_NUL";	break;
  	default:	value = "0";		break;
  	}
  	printf("%s%c", value, (i < 255) ? ',' : ' ');
      }
      printf("\n};\n");
  
      return 0;
  }
  
  
  
  1.1                  apr-util/uri/gen_uri_delims.dsp
  
  Index: gen_uri_delims.dsp
  ===================================================================
  # Microsoft Developer Studio Project File - Name="gen_uri_delims" - Package Owner=<4>
  # Microsoft Developer Studio Generated Build File, Format Version 6.00
  # ** DO NOT EDIT **
  
  # TARGTYPE "Win32 (x86) Console Application" 0x0103
  
  CFG=gen_uri_delims - Win32 Debug
  !MESSAGE This is not a valid makefile. To build this project using NMAKE,
  !MESSAGE use the Export Makefile command and run
  !MESSAGE 
  !MESSAGE NMAKE /f "gen_uri_delims.mak".
  !MESSAGE 
  !MESSAGE You can specify a configuration when running NMAKE
  !MESSAGE by defining the macro CFG on the command line. For example:
  !MESSAGE 
  !MESSAGE NMAKE /f "gen_uri_delims.mak" CFG="gen_uri_delims - Win32 Debug"
  !MESSAGE 
  !MESSAGE Possible choices for configuration are:
  !MESSAGE 
  !MESSAGE "gen_uri_delims - Win32 Release" (based on "Win32 (x86) Console Application")
  !MESSAGE "gen_uri_delims - Win32 Debug" (based on "Win32 (x86) Console Application")
  !MESSAGE 
  
  # Begin Project
  # PROP AllowPerConfigDependencies 0
  # PROP Scc_ProjName ""
  # PROP Scc_LocalPath ""
  CPP=cl.exe
  RSC=rc.exe
  
  !IF  "$(CFG)" == "gen_uri_delims - Win32 Release"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 0
  # PROP BASE Output_Dir ""
  # PROP BASE Intermediate_Dir "Release"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 0
  # PROP Output_Dir ""
  # PROP Intermediate_Dir "Release"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
  # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Release\gen_uri_delims" /FD /c
  # ADD BASE RSC /l 0x809 /d "NDEBUG"
  # ADD RSC /l 0x809 /d "NDEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Release\gen_uri_delims.pdb" /machine:I386
  # ADD LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Release\gen_uri_delims.pdb" /machine:I386
  
  !ELSEIF  "$(CFG)" == "gen_uri_delims - Win32 Debug"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 1
  # PROP BASE Output_Dir ""
  # PROP BASE Intermediate_Dir "Debug"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 1
  # PROP Output_Dir ""
  # PROP Intermediate_Dir "Debug"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MDd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
  # ADD CPP /nologo /MDd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Debug\gen_uri_delims" /FD /c
  # ADD BASE RSC /l 0x809 /d "_DEBUG"
  # ADD RSC /l 0x809 /d "_DEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\gen_uri_delims.pdb" /debug /machine:I386
  # ADD LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\gen_uri_delims.pdb" /debug /machine:I386
  
  !ENDIF 
  
  # Begin Target
  
  # Name "gen_uri_delims - Win32 Release"
  # Name "gen_uri_delims - Win32 Debug"
  # Begin Source File
  
  SOURCE=.\gen_uri_delims.c
  # End Source File
  # End Target
  # End Project
  
  
  
  1.1                  apr-util/uri/gen_uri_delims.mak
  
  Index: gen_uri_delims.mak
  ===================================================================
  # Microsoft Developer Studio Generated NMAKE File, Based on gen_uri_delims.dsp
  !IF "$(CFG)" == ""
  CFG=gen_uri_delims - Win32 Debug
  !MESSAGE No configuration specified. Defaulting to gen_uri_delims - Win32\
   Debug.
  !ENDIF 
  
  !IF "$(CFG)" != "gen_uri_delims - Win32 Release" && "$(CFG)" !=\
   "gen_uri_delims - Win32 Debug"
  !MESSAGE Invalid configuration "$(CFG)" specified.
  !MESSAGE You can specify a configuration when running NMAKE
  !MESSAGE by defining the macro CFG on the command line. For example:
  !MESSAGE 
  !MESSAGE NMAKE /f "gen_uri_delims.mak" CFG="gen_uri_delims - Win32 Debug"
  !MESSAGE 
  !MESSAGE Possible choices for configuration are:
  !MESSAGE 
  !MESSAGE "gen_uri_delims - Win32 Release" (based on\
   "Win32 (x86) Console Application")
  !MESSAGE "gen_uri_delims - Win32 Debug" (based on\
   "Win32 (x86) Console Application")
  !MESSAGE 
  !ERROR An invalid configuration is specified.
  !ENDIF 
  
  !IF "$(OS)" == "Windows_NT"
  NULL=
  !ELSE 
  NULL=nul
  !ENDIF 
  
  !IF  "$(CFG)" == "gen_uri_delims - Win32 Release"
  
  OUTDIR=.
  INTDIR=.\Release
  # Begin Custom Macros
  OutDir=.
  # End Custom Macros
  
  !IF "$(RECURSE)" == "0" 
  
  ALL : "$(OUTDIR)\gen_uri_delims.exe"
  
  !ELSE 
  
  ALL : "$(OUTDIR)\gen_uri_delims.exe"
  
  !ENDIF 
  
  CLEAN :
  	-@erase "$(INTDIR)\gen_uri_delims.idb"
  	-@erase "$(INTDIR)\gen_uri_delims.obj"
  	-@erase "$(OUTDIR)\gen_uri_delims.exe"
  
  "$(INTDIR)" :
      if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
  
  CPP=cl.exe
  CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS"\
   /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\gen_uri_delims" /FD /c 
  CPP_OBJS=.\Release/
  CPP_SBRS=.
  
  .c{$(CPP_OBJS)}.obj::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .cpp{$(CPP_OBJS)}.obj::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .cxx{$(CPP_OBJS)}.obj::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .c{$(CPP_SBRS)}.sbr::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .cpp{$(CPP_SBRS)}.sbr::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .cxx{$(CPP_SBRS)}.sbr::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  RSC=rc.exe
  BSC32=bscmake.exe
  BSC32_FLAGS=/nologo /o"$(OUTDIR)\gen_uri_delims.bsc" 
  BSC32_SBRS= \
  	
  LINK32=link.exe
  LINK32_FLAGS=kernel32.lib /nologo /subsystem:console /incremental:no\
   /pdb:"$(OUTDIR)\Release\gen_uri_delims.pdb" /machine:I386\
   /out:"$(OUTDIR)\gen_uri_delims.exe" 
  LINK32_OBJS= \
  	"$(INTDIR)\gen_uri_delims.obj"
  
  "$(OUTDIR)\gen_uri_delims.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
      $(LINK32) @<<
    $(LINK32_FLAGS) $(LINK32_OBJS)
  <<
  
  !ELSEIF  "$(CFG)" == "gen_uri_delims - Win32 Debug"
  
  OUTDIR=.
  INTDIR=.\Debug
  # Begin Custom Macros
  OutDir=.
  # End Custom Macros
  
  !IF "$(RECURSE)" == "0" 
  
  ALL : "$(OUTDIR)\gen_uri_delims.exe"
  
  !ELSE 
  
  ALL : "$(OUTDIR)\gen_uri_delims.exe"
  
  !ENDIF 
  
  CLEAN :
  	-@erase "$(INTDIR)\gen_uri_delims.idb"
  	-@erase "$(INTDIR)\gen_uri_delims.obj"
  	-@erase "$(OUTDIR)\Debug\gen_uri_delims.pdb"
  	-@erase "$(OUTDIR)\gen_uri_delims.exe"
  
  "$(INTDIR)" :
      if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
  
  CPP=cl.exe
  CPP_PROJ=/nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D\
   "_MBCS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\gen_uri_delims" /FD /c 
  CPP_OBJS=.\Debug/
  CPP_SBRS=.
  
  .c{$(CPP_OBJS)}.obj::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .cpp{$(CPP_OBJS)}.obj::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .cxx{$(CPP_OBJS)}.obj::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .c{$(CPP_SBRS)}.sbr::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .cpp{$(CPP_SBRS)}.sbr::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  .cxx{$(CPP_SBRS)}.sbr::
     $(CPP) @<<
     $(CPP_PROJ) $< 
  <<
  
  RSC=rc.exe
  BSC32=bscmake.exe
  BSC32_FLAGS=/nologo /o"$(OUTDIR)\gen_uri_delims.bsc" 
  BSC32_SBRS= \
  	
  LINK32=link.exe
  LINK32_FLAGS=kernel32.lib /nologo /subsystem:console /incremental:no\
   /pdb:"$(OUTDIR)\Debug\gen_uri_delims.pdb" /debug /machine:I386\
   /out:"$(OUTDIR)\gen_uri_delims.exe" 
  LINK32_OBJS= \
  	"$(INTDIR)\gen_uri_delims.obj"
  
  "$(OUTDIR)\gen_uri_delims.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
      $(LINK32) @<<
    $(LINK32_FLAGS) $(LINK32_OBJS)
  <<
  
  !ENDIF 
  
  
  !IF "$(CFG)" == "gen_uri_delims - Win32 Release" || "$(CFG)" ==\
   "gen_uri_delims - Win32 Debug"
  SOURCE=.\gen_uri_delims.c
  
  "$(INTDIR)\gen_uri_delims.obj" : $(SOURCE) "$(INTDIR)"
  
  
  
  !ENDIF