]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Rewrite Cookies and other headers in mod_proxy_ajp as configured with
authorSander Striker <striker@apache.org>
Tue, 11 Jan 2005 08:35:46 +0000 (08:35 +0000)
committerSander Striker <striker@apache.org>
Tue, 11 Jan 2005 08:35:46 +0000 (08:35 +0000)
ProxyPassReverse and ProxyPassReverseCookiePath.

* modules/proxy/proxy_ajp.c

  (ap_proxy_ajp_request): Update call to ajp_parse_header().

* modules/proxy/ajp.h

  (ajp_msg_get_string): constify argument.

  (ajp_parse_header): Add conf argument.

* modules/proxy/proxy_util.c

  (ap_proxy_location_reverse_map): Promoted from mod_proxy_http.

  (ap_proxy_cookie_reverse_map): Promoted from mod_proxy_http;
    renamed from proxy_cookie_reverse_map.

* modules/proxy/ajp_msg.c

  (ajp_msg_get_string): constify argument.

* modules/proxy/proxy_http.c

  (ap_proxy_location_reverse_map, proxy_cookie_reverse_map: Removed.

  (process_proxy_header): Update header mapping table to reference the now
    public functions.

* modules/proxy/ajp_header.c

  (ajp_unmarshal_response): And conf argument.  Reverse map cookies and
    other headers.

  (ajp_parse_header): Update call to ajp_unmarshal_response().

* modules/proxy/mod_proxy.h

  (ap_proxy_location_reverse_map, ap_proxy_cookie_reverse_map): Declare
    functions that have been promoted to be public.

  (ap_proxy_header_reverse_map_fn): Typedef for the signature of the above
    two functions (currently used in mod_proxy_http).

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@124901 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/ajp.h
modules/proxy/ajp_header.c
modules/proxy/ajp_msg.c
modules/proxy/mod_proxy.h
modules/proxy/proxy_ajp.c
modules/proxy/proxy_http.c
modules/proxy/proxy_util.c

index c7978b8bb13b920bb63b438654e69522b27787df..dd5ccf12721142071a0165d87b91c69c09a7c591 100644 (file)
@@ -79,6 +79,8 @@
 #include "http_log.h"
 #endif
 
+#include "mod_proxy.h"
+
 
 /** AJP Specific error codes
  */
@@ -296,7 +298,7 @@ apr_status_t ajp_msg_peek_uint8(ajp_msg_t *msg, apr_byte_t *rvalue);
  * @param rvalue    Pointer where value will be returned
  * @return          APR_SUCCESS or error
  */
-apr_status_t ajp_msg_get_string(ajp_msg_t *msg, char **rvalue);
+apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue);
 
 
 /**
@@ -436,7 +438,8 @@ int ajp_parse_type(request_rec  *r, ajp_msg_t *msg);
  * @param msg       AJP message
  * @return          APR_SUCCESS or error
  */
-apr_status_t ajp_parse_header(request_rec  *r, ajp_msg_t *msg);
+apr_status_t ajp_parse_header(request_rec *r, proxy_server_conf *conf,
+                              ajp_msg_t *msg);
 
 /** 
  * Parse the message body and return data address and length 
index 30110e523f7d17313bb12a3a00d4b926c6bb6ad6..b41f0cc8edb578a83d18331f00165c36a9b5db6a 100644 (file)
@@ -446,8 +446,9 @@ body_chunk :=
  */
 
 
-static apr_status_t ajp_unmarshal_response(ajp_msg_t   *msg,
-                                  request_rec  *r)
+static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg,
+                                           request_rec *r,
+                                           proxy_server_conf *conf)
 {
     apr_uint16_t status;
     apr_status_t rc;
@@ -491,8 +492,8 @@ static apr_status_t ajp_unmarshal_response(ajp_msg_t   *msg,
 
     for(i = 0 ; i < (int) num_headers ; i++) {
         apr_uint16_t name;
-        char *stringname;
-        char *value;
+        const char *stringname;
+        const char *value;
         rc  = ajp_msg_peek_uint16(msg, &name);
         if (rc != APR_SUCCESS) {
             return APR_EGENERAL;
@@ -500,7 +501,7 @@ static apr_status_t ajp_unmarshal_response(ajp_msg_t   *msg,
                 
         if ((name & 0XFF00) == 0XA000) {
             ajp_msg_peek_uint16(msg, &name);
-            stringname = (char *)long_res_header_for_sc(name);
+            stringname = long_res_header_for_sc(name);
             if (stringname == NULL) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
                        "Error ajp_unmarshal_response - "
@@ -530,12 +531,25 @@ static apr_status_t ajp_unmarshal_response(ajp_msg_t   *msg,
             return APR_EGENERAL;
         }
 
+        /* Set-Cookie need additional processing */
+        if (!strcasecmp(stringname, "Set-Cookie")) {
+            value = ap_proxy_cookie_reverse_map(r, conf, value);
+        }
+        /* Location, Content-Location and URI need additional processing */
+        else if (!strcasecmp(stringname, "Location")
+                 || !strcasecmp(stringname, "Content-Location")
+                 || !strcasecmp(stringname, "URI"))
+        {
+          value = ap_proxy_location_reverse_map(r, conf, value);
+        }
+
 #if defined(AS400) || defined(_OSD_POSIX)
         ap_xlate_proto_from_ascii(value, strlen(value));
 #endif
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                "ajp_unmarshal_response: Header[%d] [%s] = [%s]", 
                        i, stringname, value);
+
         apr_table_add(r->headers_out, stringname, value);
 
         /* Content-type needs an additional handling */
@@ -624,7 +638,8 @@ int ajp_parse_type(request_rec  *r, ajp_msg_t *msg)
 }
 
 /* parse the header */
-apr_status_t ajp_parse_header(request_rec  *r, ajp_msg_t *msg)
+apr_status_t ajp_parse_header(request_rec  *r, proxy_server_conf *conf,
+                              ajp_msg_t *msg)
 {
     apr_byte_t result;
     apr_status_t rc;
@@ -640,7 +655,7 @@ apr_status_t ajp_parse_header(request_rec  *r, ajp_msg_t *msg)
                "ajp_parse_headers: wrong type %02x expecting 0x04", result);
         return APR_EGENERAL;
     }
-    return ajp_unmarshal_response(msg, r);
+    return ajp_unmarshal_response(msg, r, conf);
 }
 
 /* parse the body and return data address and length */
index 19c07efea49200bcb2f4c6f57c2a761a4798a773..dec58502f49bdcd19777792c4334409680cd6ef0 100644 (file)
@@ -417,7 +417,7 @@ apr_status_t ajp_msg_get_uint8(ajp_msg_t *msg, apr_byte_t *rvalue)
  * @param rvalue    Pointer where value will be returned
  * @return          APR_SUCCESS or error
  */
-apr_status_t ajp_msg_get_string(ajp_msg_t *msg, char **rvalue)
+apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue)
 {
     apr_uint16_t size;
     apr_size_t   start;
@@ -433,7 +433,7 @@ apr_status_t ajp_msg_get_string(ajp_msg_t *msg, char **rvalue)
     msg->pos += (apr_size_t)size;
     msg->pos++;                   /* a String in AJP is NULL terminated */
 
-    *rvalue = (char *)(msg->buf + start);
+    *rvalue = (const char *)(msg->buf + start);
     return APR_SUCCESS;
 }
 
index b26265f4724ad11b47ab6a0793fd0975c2dbd9ed..db403d104f312ca2a6161f3b2c34647e7039a410 100644 (file)
@@ -399,6 +399,27 @@ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, ap
 PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
 PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
 
+/* Header mapping functions, and a typedef of their signature */
+PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_server_conf *conf, const char *url);
+PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_server_conf *conf, const char *str);
+
+#if !defined(WIN32)
+typedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *,
+                       proxy_server_conf *, const char *);
+#elif defined(PROXY_DECLARE_STATIC)
+typedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
+                                 proxy_server_conf *, const char *);
+#elif defined(PROXY_DECLARE_EXPORT)
+typedef __declspec(dllexport) const char *
+  (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
+               proxy_server_conf *, const char *);
+#else
+typedef __declspec(dllimport) const char *
+  (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
+               proxy_server_conf *, const char *);
+#endif
+
+
 /* Connection pool API */
 /**
  * Get the worker from proxy configuration
index 03903edaf36c55d2f0ac6ceb3828c06ef442dba6..7eec49b179cd8e6114426b8d54a7c3de7d2c6f09 100644 (file)
@@ -261,7 +261,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
                 break;
             case CMD_AJP13_SEND_HEADERS:
                 /* AJP13_SEND_HEADERS: process them */
-                status = ajp_parse_header(r, conn->data);
+                status = ajp_parse_header(r, conf, conn->data);
                 if (status != APR_SUCCESS) {
                     isok=0;
                 }
index 062dad1026a3d877a2c8ee4e8f8b565f6eba1bdd..57cfd6367dea0fb132e15d3c2fbbef948d50de67 100644 (file)
@@ -95,121 +95,6 @@ static int proxy_http_canon(request_rec *r, char *url)
             "/", path, (search) ? "?" : "", (search) ? search : "", NULL);
     return OK;
 }
-static const char *ap_proxy_location_reverse_map(request_rec *r, proxy_server_conf *conf, const char *url)
-{
-    struct proxy_alias *ent;
-    int i, l1, l2;
-    char *u;
-
-    /* XXX FIXME: Make sure this handled the ambiguous case of the :80
-     * after the hostname */
-
-    l1 = strlen(url);
-    ent = (struct proxy_alias *)conf->raliases->elts;
-    for (i = 0; i < conf->raliases->nelts; i++) {
-        l2 = strlen(ent[i].real);
-        if (l1 >= l2 && strncasecmp(ent[i].real, url, l2) == 0) {
-            u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
-            return ap_construct_url(r->pool, u, r);
-        }
-    }
-    return url;
-}
-/* cookies are a bit trickier to match: we've got two substrings to worry
- * about, and we can't just find them with strstr 'cos of case.  Regexp
- * matching would be an easy fix, but for better consistency with all the
- * other matches we'll refrain and use apr_strmatch to find path=/domain=
- * and stick to plain strings for the config values.
- */
-static const char *proxy_cookie_reverse_map(request_rec *r,
-                          proxy_server_conf *conf, const char *str)
-{
-    struct proxy_alias *ent;
-    size_t len = strlen(str);
-    const char* newpath = NULL ;
-    const char* newdomain = NULL ;
-    const char* pathp ;
-    const char* domainp ;
-    const char* pathe = NULL;
-    const char* domaine = NULL;
-    size_t l1, l2, poffs = 0, doffs = 0 ;
-    int i;
-    int ddiff = 0 ;
-    int pdiff = 0 ;
-    char* ret ;
-
-/* find the match and replacement, but save replacing until we've done
-   both path and domain so we know the new strlen
-*/
-    if ( pathp = apr_strmatch(conf->cookie_path_str, str, len) , pathp ) {
-        pathp += 5 ;
-        poffs = pathp - str ;
-        pathe = ap_strchr_c(pathp, ';') ;
-        l1 = pathe ? (pathe-pathp) : strlen(pathp) ;
-        pathe = pathp + l1 ;
-        ent = (struct proxy_alias *)conf->cookie_paths->elts;
-        for (i = 0; i < conf->cookie_paths->nelts; i++) {
-            l2 = strlen(ent[i].fake);
-            if (l1 >= l2 && strncmp(ent[i].fake, pathp, l2) == 0) {
-                newpath = ent[i].real ;
-                pdiff = strlen(newpath) - l1 ;
-                break ;
-            }
-        }
-    }
-    if ( domainp = apr_strmatch(conf->cookie_domain_str, str, len) , domainp ) {
-        domainp += 7 ;
-        doffs = domainp - str ;
-        domaine = ap_strchr_c(domainp, ';') ;
-        l1 = domaine ? (domaine-domainp) : strlen(domainp) ;
-        domaine = domainp + l1 ;
-        ent = (struct proxy_alias *)conf->cookie_domains->elts;
-        for (i = 0; i < conf->cookie_domains->nelts; i++) {
-            l2 = strlen(ent[i].fake);
-            if (l1 >= l2 && strncasecmp(ent[i].fake, domainp, l2) == 0) {
-                newdomain = ent[i].real ;
-                ddiff = strlen(newdomain) - l1 ;
-                break ;
-            }
-        }
-    }
-    if ( newpath ) {
-        ret = apr_palloc(r->pool, len+pdiff+ddiff+1) ;
-        l1 = strlen(newpath) ;
-        if ( newdomain ) {
-            l2 = strlen(newdomain) ;
-            if ( doffs > poffs ) {
-                memcpy(ret, str, poffs) ;
-                memcpy(ret+poffs, newpath, l1) ;
-                memcpy(ret+poffs+l1, pathe, domainp-pathe) ;
-                memcpy(ret+doffs+pdiff, newdomain, l2) ;
-                strcpy(ret+doffs+pdiff+l2, domaine) ;
-            } else {
-                memcpy(ret, str, doffs) ;
-                memcpy(ret+doffs, newdomain, l2) ;
-                memcpy(ret+doffs+l2, domaine, pathp-domaine) ;
-                memcpy(ret+poffs+ddiff, newpath, l1) ;
-                strcpy(ret+poffs+ddiff+l1, pathe) ;
-            }
-        } else {
-            memcpy(ret, str, poffs) ;
-            memcpy(ret+poffs, newpath, l1) ;
-            strcpy(ret+poffs+l1, pathe) ;
-        }
-    } else {
-        if ( newdomain ) {
-            ret = apr_palloc(r->pool, len+pdiff+ddiff+1) ;
-            l2 = strlen(newdomain) ;
-            memcpy(ret, str, doffs) ;
-            memcpy(ret+doffs, newdomain, l2) ;
-            strcpy(ret+doffs+l2, domaine) ;
-        } else {
-            ret = (char*) str ;        /* no change */
-        }
-    }
-    return ret ;
-}
 
 /* Clear all connection-based headers from the incoming headers table */
 static void ap_proxy_clear_connection(apr_pool_t *p, apr_table_t *headers)
@@ -643,19 +528,20 @@ apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r,
     apr_brigade_cleanup(body_brigade);
     return APR_SUCCESS;
 }
+
 static void process_proxy_header(request_rec* r, proxy_server_conf* c,
                       const char* key, const char* value)
 {
     static const char* date_hdrs[]
         = { "Date", "Expires", "Last-Modified", NULL } ;
     static const struct {
-        const char* name ;
-        const char* (*func)(request_rec*, proxy_server_conf*, const char*) ;
+        const char* name;
+        ap_proxy_header_reverse_map_fn func;
     } transform_hdrs[] = {
         { "Location", ap_proxy_location_reverse_map } ,
         { "Content-Location", ap_proxy_location_reverse_map } ,
         { "URI", ap_proxy_location_reverse_map } ,
-        { "Set-Cookie", proxy_cookie_reverse_map } ,
+        { "Set-Cookie", ap_proxy_cookie_reverse_map } ,
         { NULL, NULL }
     } ;
     int i ;
index 5defd0c7ded2f0fdae424fb031155f7c6fc49c09..5c43fdee85ee699649377616b9c9813088e1b5b7 100644 (file)
@@ -997,6 +997,131 @@ PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *
     apr_table_add(t, key, value + offset);
 }
 
+PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r,
+                              proxy_server_conf *conf, const char *url)
+{
+    struct proxy_alias *ent;
+    int i, l1, l2;
+    char *u;
+
+    /* XXX FIXME: Make sure this handled the ambiguous case of the :<PORT>
+     * after the hostname */
+
+    l1 = strlen(url);
+    ent = (struct proxy_alias *)conf->raliases->elts;
+    for (i = 0; i < conf->raliases->nelts; i++) {
+        l2 = strlen(ent[i].real);
+        if (l1 >= l2 && strncasecmp(ent[i].real, url, l2) == 0) {
+            u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
+            return ap_construct_url(r->pool, u, r);
+        }
+    }
+
+    return url;
+}
+
+/* Cookies are a bit trickier to match: we've got two substrings to worry
+ * about, and we can't just find them with strstr 'cos of case.  Regexp
+ * matching would be an easy fix, but for better consistency with all the
+ * other matches we'll refrain and use apr_strmatch to find path=/domain=
+ * and stick to plain strings for the config values.
+ */
+PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r,
+                              proxy_server_conf *conf, const char *str)
+{
+    struct proxy_alias *ent;
+    size_t len = strlen(str);
+    const char *newpath = NULL;
+    const char *newdomain = NULL;
+    const char *pathp;
+    const char *domainp;
+    const char *pathe = NULL;
+    const char *domaine = NULL;
+    size_t l1, l2, poffs = 0, doffs = 0;
+    int i;
+    int ddiff = 0;
+    int pdiff = 0;
+    char *ret;
+
+   /* Find the match and replacement, but save replacing until we've done
+    * both path and domain so we know the new strlen
+    */
+    if (pathp = apr_strmatch(conf->cookie_path_str, str, len) ,pathp) {
+        pathp += 5 ;
+        poffs = pathp - str;
+        pathe = ap_strchr_c(pathp, ';');
+        l1 = pathe ? (pathe - pathp) : strlen(pathp);
+        pathe = pathp + l1 ;
+        ent = (struct proxy_alias *)conf->cookie_paths->elts;
+        for (i = 0; i < conf->cookie_paths->nelts; i++) {
+            l2 = strlen(ent[i].fake);
+            if (l1 >= l2 && strncmp(ent[i].fake, pathp, l2) == 0) {
+                newpath = ent[i].real;
+                pdiff = strlen(newpath) - l1;
+                break;
+            }
+        }
+    }
+    
+    if (domainp = apr_strmatch(conf->cookie_domain_str, str, len), domainp) {
+        domainp += 7;
+        doffs = domainp - str;
+        domaine = ap_strchr_c(domainp, ';');
+        l1 = domaine ? (domaine - domainp) : strlen(domainp);
+        domaine = domainp + l1;
+        ent = (struct proxy_alias *)conf->cookie_domains->elts;
+        for (i = 0; i < conf->cookie_domains->nelts; i++) {
+            l2 = strlen(ent[i].fake);
+            if (l1 >= l2 && strncasecmp(ent[i].fake, domainp, l2) == 0) {
+                newdomain = ent[i].real;
+                ddiff = strlen(newdomain) - l1;
+                break;
+            }
+        }
+    }
+
+    if (newpath) {
+        ret = apr_palloc(r->pool, len + pdiff + ddiff + 1);
+        l1 = strlen(newpath);
+        if (newdomain) {
+            l2 = strlen(newdomain);
+            if (doffs > poffs) {
+                memcpy(ret, str, poffs);
+                memcpy(ret + poffs, newpath, l1);
+                memcpy(ret + poffs + l1, pathe, domainp - pathe);
+                memcpy(ret + doffs + pdiff, newdomain, l2);
+                strcpy(ret + doffs + pdiff + l2, domaine);
+            }
+            else {
+                memcpy(ret, str, doffs) ;
+                memcpy(ret + doffs, newdomain, l2);
+                memcpy(ret + doffs + l2, domaine, pathp - domaine);
+                memcpy(ret + poffs + ddiff, newpath, l1);
+                strcpy(ret + poffs + ddiff + l1, pathe);
+            }
+        }
+        else {
+            memcpy(ret, str, poffs);
+            memcpy(ret + poffs, newpath, l1);
+            strcpy(ret + poffs + l1, pathe);
+        }
+    }
+    else {
+        if (newdomain) {
+            ret = apr_palloc(r->pool, len + pdiff + ddiff + 1);
+            l2 = strlen(newdomain);
+            memcpy(ret, str, doffs);
+            memcpy(ret + doffs, newdomain, l2);
+            strcpy(ret + doffs+l2, domaine);
+        }
+        else {
+            ret = (char *)str; /* no change */
+        }
+    }
+    
+    return ret;
+}
+
 PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
                                                       proxy_server_conf *conf,
                                                       const char *url)