On Thu, 30 Oct 2003, Nick Kew wrote:

> I've just hacked a couple of patches that fill gaps in Apache's
> URI manipulation, sufficient to construct HTTP requests for external
> resources.  May I submit these for inclusion?

The only response to this was "where is it?", so here goes.
See attached.

-- 
Nick Kew
--- server/protocol.c   2003-09-10 13:13:51.000000000 +0100
+++ server/protocol.c.new       2003-11-01 14:57:20.000000000 +0000
@@ -555,8 +555,10 @@
         }
 
         r->args = r->parsed_uri.query;
-        r->uri = r->parsed_uri.path ? r->parsed_uri.path
-                 : apr_pstrdup(r->pool, "/");
+        if ( ! r->parsed_uri.path ) {
+           r->parsed_uri.path = apr_pstrdup(r->pool, "/");
+        }
+        r->uri = r->parsed_uri.path ;
 
 #if defined(OS2) || defined(WIN32)
         /* Handle path translations for OS/2 and plug security hole.
@@ -578,6 +580,21 @@
         r->uri = apr_pstrdup(r->pool, uri);
     }
 }
+/* Fill in fields of parsed_uri even where not required by httpd core.
+   Assumes ap_parse_uri has already been run
+
+   Would best be merged into ap_parse_uri if that doesn't risk
+   breaking something obscure
+*/
+AP_CORE_DECLARE(void) ap_fill_parsed_uri(request_rec *r)
+{
+  r->parsed_uri.scheme = r->parsed_uri.scheme ? r->parsed_uri.scheme : 
apr_pstrdup(r->pool, "http") ;
+  r->parsed_uri.user = r->parsed_uri.user ? r->parsed_uri.user : r->user ;
+  r->parsed_uri.hostname = r->parsed_uri.hostname ? r->parsed_uri.hostname : 
(char*)r->hostname ;
+  r->parsed_uri.port = r->parsed_uri.port ? r->parsed_uri.port : 
r->connection->local_addr->port ;
+  r->parsed_uri.port_str = r->parsed_uri.port_str ? r->parsed_uri.port_str : 
apr_psprintf(r->pool, "%d", r->parsed_uri.port) ;
+/* r->parsed_uri.path = r->parsed_uri.path ? r->parsed_uri.path : r->uri ? 
r->uri : apr_pstrdup(r->pool, "/") ;*/
+}
 
 static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
 {
--- include/http_protocol.h     2003-02-03 17:31:29.000000000 +0000
+++ include/http_protocol.h.new 2003-11-01 14:53:41.000000000 +0000
@@ -552,6 +552,15 @@
 AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri);
 
 /**
+ * fill_parsed_uri: fill in fields available in request that parse_uri
+ * may have left null.  Saves making too many special cases when
+ * using the parsed_uri.
+ * @param r The current request
+ * @deffunc void ap_fill_parsed_uri(request_rec *r)
+ */
+AP_CORE_DECLARE(void) ap_fill_parsed_uri(request_rec *r) ;
+
+/**
  * Get the next line of input for the request
  * @param s The buffer into which to read the line
  * @param n The size of the buffer
--- srclib/apr-util/uri/apr_uri.c       2003-03-03 18:31:58.000000000 +0000
+++ srclib/apr-util/uri/apr_uri.c.new   2003-11-01 14:58:31.000000000 +0000
@@ -448,3 +448,94 @@
     }
     return APR_EGENERAL;
 }
+/* Resolve relative to a base.  This means host/etc, and (crucially) path */
+APU_DECLARE(int) apr_uri_resolve_relative(apr_pool_t* pool,
+                                         const apr_uri_t* base,
+                                         apr_uri_t* uptr)
+{
+  if ( uptr == NULL
+       || base == NULL
+       || ! base->is_initialized
+       || ! uptr->is_initialized ) {
+       return APR_EGENERAL;
+  }
+/* The interesting bit is the path.  */
+  if ( uptr->path == NULL ) {
+    if ( uptr->hostname == NULL ) {
+       /* is this compatible with is_initialised?  Harmless in any case */
+       uptr->path = base->path ? base->path : apr_pstrdup(pool, "/") ;
+    }
+    else {
+       /* deal with the idiosyncracy of APR allowing path==NULL
+       ** without risk of breaking back-compatibility
+       */
+       uptr->path = apr_pstrdup(pool, "/") ;
+    }
+  }
+  else if ( uptr->path[0] != '/' ) {
+    size_t baselen ;
+    const char* basepath = base->path ? base->path :"/" ;
+    const char* path = uptr->path ;
+    const char* base_end = strrchr(basepath, '/') ;
+
+    /* if base is nonsensical, bail out */
+    if ( basepath[0] != '/' ) {
+       return APR_EGENERAL;
+    }
+    /* munch "up" components at the start, and chop them from base path */
+    while ( !strncmp(path, "../", 3) ) {
+      while ( base_end > basepath ) {
+       if ( *--base_end == '/' ) {
+         break ;
+       }
+      }
+      path += 3 ;
+    }
+    /* munch "here" components at the start */
+    while ( !strncmp(path, "./", 2) ) {
+      path += 2 ;
+    }
+    baselen = base_end-basepath+1 ;
+    uptr->path = apr_palloc(pool, baselen + strlen(path) + 1 ) ;
+    memcpy(uptr->path, basepath, baselen) ;
+    strcpy(uptr->path+baselen, path) ;
+  }
+
+/* The trivial bits are everything-but-path */
+  if ( uptr->scheme == NULL ) {
+       uptr->scheme = base->scheme ;
+  }
+  if ( uptr->hostinfo == NULL ) {
+       uptr->hostinfo = base->hostinfo ;
+  }
+  if ( uptr->user == NULL ) {
+       uptr->user = base->user ;
+  }
+  if ( uptr->password == NULL ) {
+       uptr->password = base->password ;
+  }
+  if ( uptr->hostname == NULL ) {
+       uptr->hostname = base->hostname ;
+  }
+  if ( uptr->port_str == NULL ) {
+       uptr->port_str = base->port_str ;
+  }
+  if ( uptr->hostent == NULL ) {
+       uptr->hostent = base->hostent ;
+  }
+  if ( ! uptr->port ) {
+       uptr->port = base->port ;
+  }
+  return APR_SUCCESS ;
+}
+APU_DECLARE(int) apr_uri_parse_relative(apr_pool_t* p,
+                                       const apr_uri_t* base,
+                                       const char* uri,
+                                       apr_uri_t* uptr)
+{
+  int ret = apr_uri_parse(p, uri, uptr) ;
+  if ( ret != APR_SUCCESS ) {
+       return ret ;
+  }
+  return apr_uri_resolve_relative(p, base, uptr) ;
+}
--- srclib/apr-util/include/apr_uri.h   2003-03-03 23:41:11.000000000 +0000
+++ srclib/apr-util/include/apr_uri.h.new       2003-11-01 15:00:12.000000000 
+0000
@@ -205,6 +205,33 @@
                                apr_uri_t *uptr);
 
 /**
+ * Resolve an already-initialised but possibly-relative URL
+ * against a given base URL.
+ * @param p The pool to allocate out of
+ * @param base The base to resolve against
+ * @param uptr The apr_uri_t to resolve
+ * @return An HTTP status code
+ */
+APU_DECLARE(int) apr_uri_resolve_relative(apr_pool_t *p,
+                                         const apr_uri_t *base, 
+                                         apr_uri_t *uptr);
+
+/**
+ * Parse a given URI, fill in all supplied fields of a apr_uri_t structure.
+ * If the given URI is relative, then resolve it using a supplied base
+ * @param p The pool to allocate out of
+ * @param base The base to resolve against
+ * @param uri The uri to parse
+ * @param uptr The apr_uri_t to fill out
+ * @return An HTTP status code
+ */
+APU_DECLARE(int) apr_uri_parse_relative(apr_pool_t *p,
+                                       const apr_uri_t *base,
+                                       const char* uri,
+                                       apr_uri_t* 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

Reply via email to