You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by mt...@apache.org on 2011/11/01 08:01:29 UTC

svn commit: r1195850 - /tomcat/jk/trunk/native/iis/jk_isapi_plugin.c

Author: mturk
Date: Tue Nov  1 07:01:29 2011
New Revision: 1195850

URL: http://svn.apache.org/viewvc?rev=1195850&view=rev
Log:
Refactor main filter handler. Do not limit the size of header data (fixes BZ50233) by using jk_pool for huge headers

Modified:
    tomcat/jk/trunk/native/iis/jk_isapi_plugin.c

Modified: tomcat/jk/trunk/native/iis/jk_isapi_plugin.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/iis/jk_isapi_plugin.c?rev=1195850&r1=1195849&r2=1195850&view=diff
==============================================================================
--- tomcat/jk/trunk/native/iis/jk_isapi_plugin.c (original)
+++ tomcat/jk/trunk/native/iis/jk_isapi_plugin.c Tue Nov  1 07:01:29 2011
@@ -167,7 +167,7 @@ static char HTTP_WORKER_HEADER_INDEX[RES
 
 #define BAD_REQUEST     -1
 #define BAD_PATH        -2
-#define MAX_SERVERNAME  128
+#define MAX_SERVERNAME  1024
 #define MAX_INSTANCEID  32
 #define MAX_PACKET_SIZE 65536
 
@@ -444,6 +444,8 @@ static struct error_reasons {
 #define JK_TOLOWER(x)   ((char)tolower((BYTE)(x)))
 #endif
 
+#define ISIZEOF(X)      (int)sizeof(X)
+
 #define GET_SERVER_VARIABLE_VALUE(name, place)          \
   do {                                                  \
     (place) = NULL;                                     \
@@ -589,9 +591,9 @@ static int get_registry_config_number(HK
                                       int *val);
 
 
-static int get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
-                            char *name,
-                            char *buf, DWORD bufsz);
+static BOOL get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
+                             char *name,
+                             char *buf, size_t bufsz);
 
 static int base64_encode_cert_len(int len);
 
@@ -882,7 +884,7 @@ static void write_error_response(PHTTP_F
     pfc->ServerSupportFunction(pfc,
                                SF_REQ_SEND_RESPONSE_HEADER,
                                status, 0, 0);
-    len = (DWORD)(sizeof(HTML_ERROR_HEAD) - 1);
+    len = ISIZEOF(HTML_ERROR_HEAD) - 1;
     pfc->WriteClient(pfc, HTML_ERROR_HEAD, &len,
                      HSE_IO_SYNC);
     StringCbPrintf(body, sizeof(body), HTML_ERROR_BODY_FMT,
@@ -891,7 +893,7 @@ static void write_error_response(PHTTP_F
     len = (DWORD)(strlen(body));
     pfc->WriteClient(pfc, body, &len,
                      HSE_IO_SYNC);
-    len = (DWORD)(sizeof(HTML_ERROR_TAIL) - 1);
+    len = ISIZEOF(HTML_ERROR_TAIL) - 1;
     pfc->WriteClient(pfc, HTML_ERROR_TAIL, &len,
                      HSE_IO_SYNC);
 }
@@ -928,7 +930,7 @@ static void write_error_message(LPEXTENS
                                  0,
                                  (LPDWORD)CONTENT_TYPE);
     /* First write the HEAD */
-    len = (DWORD)(sizeof(HTML_ERROR_HEAD) - 1);
+    len = ISIZEOF(HTML_ERROR_HEAD) - 1;
     lpEcb->WriteClient(lpEcb->ConnID,
                        HTML_ERROR_HEAD, &len,
                        HSE_IO_SYNC);
@@ -939,7 +941,7 @@ static void write_error_message(LPEXTENS
     lpEcb->WriteClient(lpEcb->ConnID,
                        body, &len,
                        HSE_IO_SYNC);
-    len = (DWORD)(sizeof(HTML_ERROR_TAIL) - 1);
+    len = ISIZEOF(HTML_ERROR_TAIL) - 1;
     lpEcb->WriteClient(lpEcb->ConnID,
                        HTML_ERROR_TAIL, &len,
                        HSE_IO_SYNC);
@@ -1778,27 +1780,25 @@ static char *ap_pregsub(const char *inpu
     return dest;
 }
 
-static int simple_rewrite(char *uri)
+static char *simple_rewrite(jk_pool_t *p, const char *uri)
 {
     if (rewrite_map) {
         int i;
-        char buf[8192];
         for (i = 0; i < jk_map_size(rewrite_map); i++) {
+            size_t len;
             const char *src = jk_map_name_at(rewrite_map, i);
             if (*src == '~')
                 continue;   /* Skip regexp rewrites */
-            if (strncmp(uri, src, strlen(src)) == 0) {
-                StringCbCopy(buf, sizeof(buf), jk_map_value_at(rewrite_map, i));
-                StringCbCat(buf,  sizeof(buf), uri + strlen(src));
-                StringCbCopy(uri, sizeof(buf), buf);
-                return 1;
+            len = strlen(src);
+            if (strncmp(uri, src, len) == 0) {
+                return jk_pool_strcat(p, jk_map_value_at(rewrite_map, i), uri + len);
             }
         }
     }
-    return 0;
+    return NULL;
 }
 
-static int rregex_rewrite(char *uri)
+static char *rregex_rewrite(jk_pool_t *p, const char *uri)
 {
     ap_regmatch_t regm[AP_MAX_REG_MATCH];
 
@@ -1810,19 +1810,315 @@ static int rregex_rewrite(char *uri)
                 char *subs = ap_pregsub(regexp->fake, uri,
                                        AP_MAX_REG_MATCH, regm);
                 if (subs) {
-                    char buf[8192];
-                    size_t diffsz = strlen(subs) - (regm[0].rm_eo - regm[0].rm_so);
-                    memcpy(&buf[0], uri, regm[0].rm_so);
-                    StringCbCopy(&buf[regm[0].rm_so], sizeof(buf) - regm[0].rm_so, subs);
-                    StringCbCat(&buf[0], sizeof(buf), uri + regm[0].rm_eo);
-                    StringCbCopy(uri, sizeof(buf), &buf[0]);
-                    free(subs);
-                    return 1;
+                    char *buf, *ptr;
+                    size_t orgsz = strlen(uri);
+                    size_t subsz = strlen(subs);
+                    size_t lefts = orgsz - regm[0].rm_eo;
+                    
+                    ptr = buf = jk_pool_alloc(p, regm[0].rm_so + subsz + lefts + 1);
+                    memcpy(buf, uri, regm[0].rm_so);
+                    ptr += regm[0].rm_so;
+                    memcpy(ptr, subs, subsz);
+                    ptr += subsz;
+                    memcpy(ptr, uri + regm[0].rm_eo, lefts);
+                    ptr[lefts] = '\0';
+                    return buf;
                 }
             }
         }
     }
-    return 0;
+    return NULL;
+}
+
+static __inline void clear_header(PHTTP_FILTER_PREPROC_HEADERS pfp,
+                                 PHTTP_FILTER_CONTEXT pfc,
+                                 LPSTR lpszName)
+{
+    pfp->SetHeader(pfc, lpszName, NIL);
+}
+
+static __inline LPSTR get_pheader(jk_pool_t *pool,
+                                  PHTTP_FILTER_PREPROC_HEADERS pfp,
+                                  PHTTP_FILTER_CONTEXT pfc,
+                                  LPSTR lpszName, LPSTR lpszBuf, size_t bsize)
+{
+    LPSTR rv    = lpszBuf;
+    DWORD dwLen = (DWORD)bsize;
+
+    if (!pfp->GetHeader(pfc, lpszName, lpszBuf, &dwLen)) {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            return NULL;   
+        if ((rv = jk_pool_alloc(pool, dwLen)) == NULL)
+            return NULL;
+        /* Try again with dynamic buffer */
+        if (!pfp->GetHeader(pfc, lpszName, rv, &dwLen)) {
+            return NULL;
+        }
+    }
+    return rv;
+}
+
+static DWORD handle_notify_event(PHTTP_FILTER_CONTEXT pfc,
+                                 PHTTP_FILTER_PREPROC_HEADERS pfp)
+{
+    int rc;
+    DWORD rv = SF_STATUS_REQ_NEXT_NOTIFICATION;
+    const char *worker = NULL;
+    rule_extension_t *extensions;
+    int worker_index = -1;
+    int port;
+    jk_pool_atom_t pbuf[HUGE_POOL_SIZE];
+    jk_pool_t pool;
+
+    char *uri_undec  = NULL;
+    char *uri  = NULL;
+    char *host = NULL;
+    char *translate = NULL;
+    char szHB[HDR_BUFFER_SIZE] = "/";
+    char szUB[HDR_BUFFER_SIZE] = "";
+    char szTB[16] = "";
+    char szPB[16] = "";
+    char swindex[32] = "";
+    char *query;
+    DWORD len;
+
+    if (JK_IS_DEBUG_LEVEL(logger))
+        jk_log(logger, JK_LOG_DEBUG, "Filter started");
+    jk_open_pool(&pool, pbuf, sizeof(jk_pool_atom_t) * HUGE_POOL_SIZE);
+    /*
+     * Just in case somebody set these headers in the request!
+     */
+    clear_header(pfp, pfc, URI_HEADER_NAME);
+    clear_header(pfp, pfc, QUERY_HEADER_NAME);
+    clear_header(pfp, pfc, WORKER_HEADER_NAME);
+    clear_header(pfp, pfc, WORKER_HEADER_INDEX);
+    clear_header(pfp, pfc, TOMCAT_TRANSLATE_HEADER_NAME);
+
+    /*
+     * Suppress logging of original uri/query when we don't map a URL
+     */
+    if (pfc->pFilterContext) {
+        isapi_log_data_t *ld = (isapi_log_data_t *)pfc->pFilterContext;
+        ld->request_matched = JK_FALSE;
+    }
+    uri = get_pheader(&pool, pfp, pfc, "url", szUB, sizeof(szUB));
+    if (uri == NULL) {        
+        jk_log(logger, JK_LOG_ERROR,
+               "error while getting the url");
+        return SF_STATUS_REQ_ERROR;
+    }
+    if (*uri == '\0') {
+        /* Empty url */
+        return SF_STATUS_REQ_NEXT_NOTIFICATION;
+    }
+    query = strchr(uri, '?');
+    if (query) {
+        *query++ = '\0';
+        if (*query)
+            query = jk_pool_strdup(&pool, query);
+        else
+            query = NULL;
+    }
+    if (uri_select_option == URI_SELECT_OPT_UNPARSED) {
+        /* Duplicate unparsed uri */
+        uri_undec = jk_pool_strdup(&pool, uri);
+    }   
+    rc = unescape_url(uri);
+    if (rc == BAD_REQUEST) {
+        jk_log(logger, JK_LOG_ERROR,
+               "[%s] contains one or more invalid escape sequences.",
+               uri);
+        write_error_response(pfc, 400);
+        rv = SF_STATUS_REQ_FINISHED;
+        goto cleanup;
+    }
+    else if (rc == BAD_PATH) {
+        jk_log(logger, JK_LOG_EMERG,
+               "[%s] contains forbidden escape sequences.",
+               uri);
+        write_error_response(pfc, 404);
+        rv = SF_STATUS_REQ_FINISHED;
+        goto cleanup;
+    }
+    getparents(uri);
+    len = ISIZEOF(szHB) - 1;    
+    if (pfc->GetServerVariable(pfc, "SERVER_NAME", &szHB[1], &len) && len > 1) {
+        len = ISIZEOF(szPB);
+        pfc->GetServerVariable(pfc, "SERVER_PORT", szPB, &len);
+        port = atoi(szPB);
+        if (port != 80 && port != 443) {
+            host = jk_pool_strcatv(&pool, szHB, ":", szPB, NULL);
+        }
+        else
+            host = szHB;
+    }
+    if (host) {
+        worker = map_uri_to_worker_ext(uw_map, uri, host,
+                                       &extensions, &worker_index, logger);
+    }
+    else {
+        worker = map_uri_to_worker_ext(uw_map, uri, NULL,
+                                       &extensions, &worker_index, logger);
+    }
+    /*
+     * Check if somebody is feading us with his own TOMCAT data headers.
+     * We reject such postings !
+     */
+    if (worker) {
+        char *forwardURI;
+        char *rewriteURI;
+        isapi_log_data_t *ld;
+        BOOL rs;
+
+        if (JK_IS_DEBUG_LEVEL(logger))
+            jk_log(logger, JK_LOG_DEBUG,
+                   "check if [%s] points to the web-inf directory",
+                    uri);
+
+        if (uri_is_web_inf(uri)) {
+            jk_log(logger, JK_LOG_EMERG,
+                   "[%s] points to the web-inf or meta-inf directory. "
+                   "Somebody tries to hack into the site!!!",
+                   uri);
+
+            write_error_response(pfc, 404);
+            rv = SF_STATUS_REQ_FINISHED;
+            goto cleanup;
+        }
+
+        /* This is a servlet, should redirect ... */
+        if (JK_IS_DEBUG_LEVEL(logger))
+            jk_log(logger, JK_LOG_DEBUG,
+                "[%s] is a servlet url - should redirect to %s",
+                uri, worker);
+
+        /* get URI we should forward */
+        if (uri_select_option == URI_SELECT_OPT_UNPARSED) {
+            /* get original unparsed URI */
+            forwardURI = uri_undec;
+        }
+        else if (uri_select_option == URI_SELECT_OPT_ESCAPED) {
+            size_t elen  = strlen(uri) * 4;
+            char *escuri = jk_pool_alloc(&pool, elen);
+            if (!escape_url(uri, escuri, elen)) {
+                jk_log(logger, JK_LOG_ERROR,
+                       "[%s] re-encoding request exceeds maximum buffer size.",
+                       uri);
+                write_error_response(pfc, 400);
+                rv = SF_STATUS_REQ_FINISHED;
+                goto cleanup;
+            }
+            if (JK_IS_DEBUG_LEVEL(logger))
+                jk_log(logger, JK_LOG_DEBUG,
+                       "fowarding escaped URI [%s]",
+                       escuri);
+            forwardURI = escuri;
+        }
+        else if (uri_select_option == URI_SELECT_OPT_PROXY) {
+            size_t clen  = strlen(uri) * 4;
+            char *canuri = jk_pool_alloc(&pool, clen);
+            if (!jk_canonenc(uri, canuri, clen)) {
+                jk_log(logger, JK_LOG_ERROR,
+                       "[%s] re-encoding request exceeds maximum buffer size.",
+                       uri);
+                write_error_response(pfc, 400);
+                rv = SF_STATUS_REQ_FINISHED;
+                goto cleanup;                
+            }
+            if (JK_IS_DEBUG_LEVEL(logger))
+                jk_log(logger, JK_LOG_DEBUG,
+                       "fowarding escaped URI [%s]",
+                       canuri);
+            forwardURI = canuri;
+        }
+        else {
+            forwardURI = uri;
+        }
+        /* Do a simple rewrite .
+         * Note that URI can be escaped, so thus the rule has
+         * to be in that case.
+         *
+         * TODO: Add more advanced regexp rewrite.
+         */
+        rewriteURI = simple_rewrite(&pool, forwardURI);
+        if (rewriteURI == NULL)
+            rewriteURI = rregex_rewrite(&pool, forwardURI);
+        if (rewriteURI) {
+            if (JK_IS_DEBUG_LEVEL(logger)) {
+                jk_log(logger, JK_LOG_DEBUG,
+                       "rewritten URI [%s]->[%s]",
+                       forwardURI, rewriteURI);
+            }
+            forwardURI = rewriteURI;
+        }
+        itoa(worker_index, swindex, 10);
+        rs = pfp->AddHeader(pfc, URI_HEADER_NAME, forwardURI); 
+        if (rs && query)
+            rs = pfp->AddHeader(pfc, QUERY_HEADER_NAME, query); 
+        rs = rs && pfp->AddHeader(pfc, WORKER_HEADER_NAME, (LPSTR)worker);
+        rs = rs && pfp->AddHeader(pfc, WORKER_HEADER_INDEX, swindex);
+        rs = rs && pfp->SetHeader(pfc, "url", extension_uri);
+            
+        if (!rs) {
+            jk_log(logger, JK_LOG_ERROR,
+                   "error while adding request headers");
+            SetLastError(ERROR_INVALID_PARAMETER);
+            rv = SF_STATUS_REQ_ERROR;
+            goto cleanup;
+        }
+
+        translate = get_pheader(&pool, pfp, pfc, TRANSLATE_HEADER,
+                                szTB, sizeof(szTB));
+        /* Move Translate: header to a temporary header so
+         * that the extension proc will be called.
+         * This allows the servlet to handle 'Translate: f'.
+         */
+        if (translate && &translate) {
+            if (!pfp->AddHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, translate)) {
+                jk_log(logger, JK_LOG_ERROR,
+                       "error while adding Tomcat-Translate headers");
+                rv = SF_STATUS_REQ_ERROR;
+                goto cleanup;
+            }
+            clear_header(pfp, pfc, TRANSLATE_HEADER);
+        }
+        ld = (isapi_log_data_t *)pfc->pFilterContext;
+        if (ld == NULL) {
+            ld = (isapi_log_data_t *)pfc->AllocMem(pfc, sizeof(isapi_log_data_t), 0);
+            if (ld == NULL) {
+                jk_log(logger, JK_LOG_ERROR,
+                       "error while allocating memory");
+                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                rv = SF_STATUS_REQ_ERROR;
+                goto cleanup;
+            }
+            pfc->pFilterContext = ld;
+        }
+        memset(ld, 0, sizeof(isapi_log_data_t));
+        StringCbCopy(ld->uri, sizeof(ld->uri), forwardURI);
+        if (query)
+            StringCbCopy(ld->query, sizeof(ld->query), query);
+        ld->request_matched = JK_TRUE;
+    }
+    else {
+        if (JK_IS_DEBUG_LEVEL(logger))
+            jk_log(logger, JK_LOG_DEBUG,
+                   "[%s] is not a servlet url", uri);
+        if (strip_session) {
+            char *jsessionid = strstr(uri, JK_PATH_SESSION_IDENTIFIER);
+            if (jsessionid) {
+                if (JK_IS_DEBUG_LEVEL(logger))
+                    jk_log(logger, JK_LOG_DEBUG,
+                           "removing session identifier [%s] for non servlet url [%s]",
+                           jsessionid, uri);
+                *jsessionid = '\0';
+                pfp->SetHeader(pfc, "url", uri);                
+            }
+        }
+    }
+cleanup:
+    jk_close_pool(&pool);
+    return rv;    
 }
 
 DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc,
@@ -1837,12 +2133,10 @@ DWORD WINAPI HttpFilterProc(PHTTP_FILTER
         DWORD dwLen = MAX_SERVERNAME - MAX_INSTANCEID - 1;
 
         if (pfc->GetServerVariable(pfc, "SERVER_NAME", serverName, &dwLen)) {
-            if (dwLen > 0) {
-                serverName[dwLen - 1] = '\0';
+            if (dwLen > 1) {
                 dwLen = MAX_INSTANCEID;
                 if (pfc->GetServerVariable(pfc, "INSTANCE_ID", instanceId, &dwLen)) {
-                    if (dwLen > 0) {
-                        instanceId[dwLen - 1] = '\0';
+                    if (dwLen > 1) {
                         StringCbCat(serverName, MAX_SERVERNAME, "_");
                         StringCbCat(serverName, MAX_SERVERNAME, instanceId);
                     }
@@ -1866,270 +2160,7 @@ DWORD WINAPI HttpFilterProc(PHTTP_FILTER
          return SF_STATUS_REQ_ERROR;
     }
     if (iis_info.filter_notify_event == dwNotificationType) {
-        char uri[INTERNET_MAX_URL_LENGTH];
-        char snuri[INTERNET_MAX_URL_LENGTH] = "/";
-        char Host[INTERNET_MAX_URL_LENGTH] = "";
-        char Translate[INTERNET_MAX_URL_LENGTH];
-        char squery[INTERNET_MAX_URL_LENGTH] = "";
-        char swindex[32] = "";
-        char Port[16] = "";
-        BOOL (WINAPI * GetHeader)(PHTTP_FILTER_CONTEXT, LPSTR, LPVOID, LPDWORD);
-        BOOL (WINAPI * SetHeader)(PHTTP_FILTER_CONTEXT, LPSTR, LPSTR);
-        BOOL (WINAPI * AddHeader)(PHTTP_FILTER_CONTEXT, LPSTR, LPSTR);
-        char *query;
-        DWORD sz = sizeof(uri);
-        DWORD szHost = sizeof(Host);
-        DWORD szPort = sizeof(Port);
-        DWORD szTranslate = sizeof(Translate);
-
-        /* This can be either HTTP_FILTER_PREPROC_HEADERS or
-         * HTTP_FILTER_AUTH_COMPLETE_INFO. In either case the
-         * requested functions are at the same structure offset
-         */
-        GetHeader = ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->GetHeader;
-        SetHeader = ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->SetHeader;
-        AddHeader = ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->AddHeader;
-
-        if (JK_IS_DEBUG_LEVEL(logger))
-            jk_log(logger, JK_LOG_DEBUG, "Filter started");
-
-        /*
-         * Just in case somebody set these headers in the request!
-         */
-        SetHeader(pfc, URI_HEADER_NAME, NIL);
-        SetHeader(pfc, QUERY_HEADER_NAME, NIL);
-        SetHeader(pfc, WORKER_HEADER_NAME, NIL);
-        SetHeader(pfc, WORKER_HEADER_INDEX, NIL);
-        SetHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, NIL);
-
-        /*
-         * Suppress logging of original uri/query when we don't map a URL
-         */
-        if (pfc->pFilterContext) {
-            isapi_log_data_t *ld = (isapi_log_data_t *)pfc->pFilterContext;
-            ld->request_matched = JK_FALSE;
-        }
-
-        if (!GetHeader(pfc, "url", uri, &sz)) {
-            
-            jk_log(logger, JK_LOG_ERROR,
-                   "error while getting the url");
-            return SF_STATUS_REQ_ERROR;
-        }
-
-        if (strlen(uri)) {
-            int rc;
-            const char *worker = NULL;
-            rule_extension_t *extensions;
-            int worker_index = -1;
-            query = strchr(uri, '?');
-            if (query) {
-                *query++ = '\0';
-                StringCbCopy(squery, INTERNET_MAX_URL_LENGTH, query);
-            }
-
-            rc = unescape_url(uri);
-            if (rc == BAD_REQUEST) {
-                jk_log(logger, JK_LOG_ERROR,
-                       "[%s] contains one or more invalid escape sequences.",
-                       uri);
-                write_error_response(pfc, 400);
-                return SF_STATUS_REQ_FINISHED;
-            }
-            else if (rc == BAD_PATH) {
-                jk_log(logger, JK_LOG_EMERG,
-                       "[%s] contains forbidden escape sequences.",
-                       uri);
-                write_error_response(pfc, 404);
-                return SF_STATUS_REQ_FINISHED;
-            }
-            getparents(uri);
-            if (pfc->GetServerVariable(pfc, "SERVER_NAME", Host, &szHost)) {
-                if (szHost > 0) {
-                    Host[szHost - 1] = '\0';
-                }
-            }
-            Port[0] = '\0';
-            if (pfc->GetServerVariable(pfc, "SERVER_PORT", Port, &szPort)) {
-                if (szPort > 0) {
-                    Port[szPort - 1] = '\0';
-                }
-            }
-            szPort = atoi(Port);
-            if (szPort != 80 && szPort != 443 && szHost > 0) {
-                StringCbCat(Host, INTERNET_MAX_URL_LENGTH, ":");
-                StringCbCat(Host, INTERNET_MAX_URL_LENGTH, Port);
-            }
-            if (szHost > 0) {
-                StringCbCat(snuri, INTERNET_MAX_URL_LENGTH, Host);
-                worker = map_uri_to_worker_ext(uw_map, uri, snuri,
-                                               &extensions, &worker_index, logger);
-            }
-            else {
-                worker = map_uri_to_worker_ext(uw_map, uri, NULL,
-                                               &extensions, &worker_index, logger);
-            }
-            /*
-             * Check if somebody is feading us with his own TOMCAT data headers.
-             * We reject such postings !
-             */
-            if (worker) {
-                char *forwardURI;
-
-                if (JK_IS_DEBUG_LEVEL(logger))
-                    jk_log(logger, JK_LOG_DEBUG,
-                           "check if [%s] points to the web-inf directory",
-                        uri);
-
-                if (uri_is_web_inf(uri)) {
-                    jk_log(logger, JK_LOG_EMERG,
-                           "[%s] points to the web-inf or meta-inf directory. "
-                           "Somebody tries to hack into the site!!!",
-                           uri);
-
-                    write_error_response(pfc, 404);
-                    return SF_STATUS_REQ_FINISHED;
-                }
-
-                /* This is a servlet, should redirect ... */
-                if (JK_IS_DEBUG_LEVEL(logger))
-                    jk_log(logger, JK_LOG_DEBUG,
-                        "[%s] is a servlet url - should redirect to %s",
-                        uri, worker);
-
-                /* get URI we should forward */
-                if (uri_select_option == URI_SELECT_OPT_UNPARSED) {
-                    /* get original unparsed URI */
-                    GetHeader(pfc, "url", uri, &sz);
-                    /* restore terminator for uri portion */
-                    if (query)
-                        *(query - 1) = '\0';
-                    if (JK_IS_DEBUG_LEVEL(logger))
-                        jk_log(logger, JK_LOG_DEBUG,
-                               "forwarding original URI [%s]",
-                               uri);
-                    forwardURI = uri;
-                }
-                else if (uri_select_option == URI_SELECT_OPT_ESCAPED) {
-                    if (!escape_url(uri, snuri, INTERNET_MAX_URL_LENGTH)) {
-                        jk_log(logger, JK_LOG_ERROR,
-                               "[%s] re-encoding request exceeds maximum buffer size.",
-                               uri);
-                        write_error_response(pfc, 400);
-                        return SF_STATUS_REQ_FINISHED;
-                    }
-                    if (JK_IS_DEBUG_LEVEL(logger))
-                        jk_log(logger, JK_LOG_DEBUG,
-                               "fowarding escaped URI [%s]",
-                               snuri);
-                    forwardURI = snuri;
-                }
-                else if (uri_select_option == URI_SELECT_OPT_PROXY) {
-                    if (!jk_canonenc(uri, snuri, INTERNET_MAX_URL_LENGTH)) {
-                        jk_log(logger, JK_LOG_ERROR,
-                               "[%s] re-encoding request exceeds maximum buffer size.",
-                               uri);
-                        write_error_response(pfc, 400);
-                        return SF_STATUS_REQ_FINISHED;
-                    }
-                    if (JK_IS_DEBUG_LEVEL(logger))
-                        jk_log(logger, JK_LOG_DEBUG,
-                               "fowarding escaped URI [%s]",
-                               snuri);
-                    forwardURI = snuri;
-                }
-                else {
-                    forwardURI = uri;
-                }
-                /* Do a simple rewrite .
-                 * Note that URI can be escaped, so thus the rule has
-                 * to be in that case.
-                 *
-                 * TODO: Add more advanced regexp rewrite.
-                 */
-                if (JK_IS_DEBUG_LEVEL(logger)) {
-                    char duri[INTERNET_MAX_URL_LENGTH];
-                    StringCbCopy(duri, INTERNET_MAX_URL_LENGTH, forwardURI);
-                    if (simple_rewrite(forwardURI)) {
-                        jk_log(logger, JK_LOG_DEBUG,
-                               "rewritten URI [%s]->[%s]",
-                               duri, forwardURI);
-                    }
-                    else if (rregex_rewrite(forwardURI)) {
-                        jk_log(logger, JK_LOG_DEBUG,
-                               "rewritten URI [%s]->[%s]",
-                               duri, forwardURI);
-                    }
-                }
-                else {
-                    if (!simple_rewrite(forwardURI))
-                        rregex_rewrite(forwardURI);
-                }
-
-                itoa(worker_index, swindex, 10);
-                if (!AddHeader(pfc, URI_HEADER_NAME, forwardURI) ||
-                    ((strlen(squery) > 0) ? !AddHeader(pfc, QUERY_HEADER_NAME, squery) : FALSE) ||
-                    !AddHeader(pfc, WORKER_HEADER_NAME, (LPSTR)worker) ||
-                    !AddHeader(pfc, WORKER_HEADER_INDEX, swindex) ||
-                    !SetHeader(pfc, "url", extension_uri)) {
-                    jk_log(logger, JK_LOG_ERROR,
-                           "error while adding request headers");
-                    SetLastError(ERROR_INVALID_PARAMETER);
-                    return SF_STATUS_REQ_ERROR;
-                }
-
-                /* Move Translate: header to a temporary header so
-                 * that the extension proc will be called.
-                 * This allows the servlet to handle 'Translate: f'.
-                 */
-                if (GetHeader(pfc, TRANSLATE_HEADER, Translate, &szTranslate) &&
-                              Translate != NULL && szTranslate > 0) {
-                    if (!AddHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, Translate)) {
-                        jk_log(logger, JK_LOG_ERROR,
-                               "error while adding Tomcat-Translate headers");
-                        return SF_STATUS_REQ_ERROR;
-                    }
-                    SetHeader(pfc, "Translate:", NIL);
-                }
-                if (!pfc->pFilterContext) {
-                    isapi_log_data_t *ld = (isapi_log_data_t *)pfc->AllocMem(pfc, sizeof(isapi_log_data_t), 0);
-                    if (!ld) {
-                        jk_log(logger, JK_LOG_ERROR,
-                               "error while allocating memory");
-                        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                        return SF_STATUS_REQ_ERROR;
-                    }
-                    memset(ld, 0, sizeof(isapi_log_data_t));
-                    StringCbCopy(ld->uri, INTERNET_MAX_URL_LENGTH, forwardURI);
-                    StringCbCopy(ld->query, INTERNET_MAX_URL_LENGTH, squery);
-                    ld->request_matched = JK_TRUE;
-                    pfc->pFilterContext = ld;
-                }
-                else {
-                    isapi_log_data_t *ld = (isapi_log_data_t *)pfc->pFilterContext;
-                    memset(ld, 0, sizeof(isapi_log_data_t));
-                    StringCbCopy(ld->uri, INTERNET_MAX_URL_LENGTH, forwardURI);
-                    StringCbCopy(ld->query, INTERNET_MAX_URL_LENGTH, squery);
-                    ld->request_matched = JK_TRUE;
-                }
-            }
-            else {
-                if (JK_IS_DEBUG_LEVEL(logger))
-                    jk_log(logger, JK_LOG_DEBUG,
-                           "[%s] is not a servlet url", uri);
-                if (strip_session) {
-                    char *jsessionid = strstr(uri, JK_PATH_SESSION_IDENTIFIER);
-                    if (jsessionid) {
-                        if (JK_IS_DEBUG_LEVEL(logger))
-                            jk_log(logger, JK_LOG_DEBUG,
-                                   "removing session identifier [%s] for non servlet url [%s]",
-                                   jsessionid, uri);
-                        *jsessionid = '\0';
-                        SetHeader(pfc, "url", uri);
-                    }
-                }
-            }
-        }
+        return handle_notify_event(pfc, pvNotification);
     }
     else if (dwNotificationType == SF_NOTIFY_LOG) {
         if (pfc->pFilterContext) {
@@ -2181,13 +2212,11 @@ DWORD WINAPI HttpExtensionProc(LPEXTENSI
         DWORD dwLen = MAX_SERVERNAME - MAX_INSTANCEID - 1;
         if (lpEcb->GetServerVariable(lpEcb->ConnID, "SERVER_NAME",
                                      serverName, &dwLen)) {
-            if (dwLen > 0) {
-                serverName[dwLen - 1] = '\0';
+            if (dwLen > 1) {
                 dwLen = MAX_INSTANCEID;
                 if (lpEcb->GetServerVariable(lpEcb->ConnID, "INSTANCE_ID",
                                              instanceId, &dwLen)) {
-                    if (dwLen > 0) {
-                        instanceId[dwLen - 1] = '\0';
+                    if (dwLen > 1) {
                         StringCbCat(serverName, MAX_SERVERNAME, "_");
                         StringCbCat(serverName, MAX_SERVERNAME, instanceId);
                     }
@@ -3001,6 +3030,14 @@ static int init_ws_service(isapi_private
     char  temp_buf[64];
     DWORD huge_buf_sz;
     BOOL  unknown_content_length = FALSE;
+#ifndef USE_CGI_HEADERS
+    char *all_hdrs = "ALL_RAW";
+#else
+    char *all_hdrs = "ALL_HTTP";
+#endif
+    unsigned int cnt = 0;
+    char *tmp;
+
 
     JK_TRACE_ENTER(logger);
 
@@ -3055,7 +3092,7 @@ static int init_ws_service(isapi_private
     if (get_server_value(private_data->lpEcb,
                          "HTTP_TRANSFER_ENCODING",
                          temp_buf,
-                         (DWORD)sizeof(temp_buf))) {
+                         sizeof(temp_buf))) {
         if (strcasecmp(temp_buf, TRANSFER_ENCODING_CHUNKED_VALUE) == 0) {
             s->is_chunked = JK_TRUE;
             if (JK_IS_DEBUG_LEVEL(logger)) {
@@ -3190,154 +3227,162 @@ static int init_ws_service(isapi_private
     }
 
     huge_buf_sz = MAX_PACKET_SIZE;
-    if (get_server_value(private_data->lpEcb,
-#ifndef USE_CGI_HEADERS
-                         "ALL_RAW", huge_buf, huge_buf_sz)) {
-#else
-                         "ALL_HTTP", huge_buf, huge_buf_sz)) {
-#endif
-        unsigned int cnt = 0;
-        char *tmp;
-
-        for (tmp = huge_buf; *tmp; tmp++) {
-            if (*tmp == '\n') {
-                cnt++;
-            }
+    if (!private_data->lpEcb->GetServerVariable(private_data->lpEcb,
+                                                all_hdrs,
+                                                huge_buf,
+                                                &huge_buf_sz)) {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+            JK_TRACE_EXIT(logger);
+            return JK_FALSE;                
+        }
+        /* User has more then 64K of headers.
+         * Resize initial buffer
+         */
+        if (!(huge_buf = jk_pool_alloc(&private_data->p, MAX_PACKET_SIZE))) {
+            JK_TRACE_EXIT(logger);
+            return JK_FALSE;
         }
+        if (!private_data->lpEcb->GetServerVariable(private_data->lpEcb,
+                                                    all_hdrs,
+                                                    huge_buf,
+                                                    &huge_buf_sz)) {
+            JK_TRACE_EXIT(logger);
+            return JK_FALSE;        
+        }
+    }
+    for (tmp = huge_buf; *tmp; tmp++) {
+        if (*tmp == '\n') {
+            cnt++;
+        }
+    }
 
-        if (cnt) {
-            char *headers_buf = huge_buf;
-            unsigned int i;
-            BOOL need_content_length_header = FALSE;
+    if (cnt) {
+        char *headers_buf = huge_buf;
+        unsigned int i;
+        BOOL need_content_length_header = FALSE;
 
-            if (s->content_length == 0 && unknown_content_length == FALSE) {
-                /* Add content-length=0 only if really zero
-                 */
-                need_content_length_header = TRUE;
-            }
+        if (s->content_length == 0 && unknown_content_length == FALSE) {
+            /* Add content-length=0 only if really zero
+             */
+            need_content_length_header = TRUE;
+        }
 
-            /* allocate an extra header slot in case we need to add a content-length header */
-            s->headers_names =
-                jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *));
-            s->headers_values =
-                jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *));
+        /* allocate an extra header slot in case we need to add a content-length header */
+        s->headers_names =
+            jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *));
+        s->headers_values =
+            jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *));
 
-            if (!s->headers_names || !s->headers_values || !headers_buf) {
-                JK_TRACE_EXIT(logger);
-                return JK_FALSE;
-            }
+        if (!s->headers_names || !s->headers_values || !headers_buf) {
+            JK_TRACE_EXIT(logger);
+            return JK_FALSE;
+        }
 
-            for (i = 0, tmp = headers_buf; *tmp && i < cnt;) {
-                int real_header = JK_TRUE;
+        for (i = 0, tmp = headers_buf; *tmp && i < cnt;) {
+            int real_header = JK_TRUE;
 
 #ifdef USE_CGI_HEADERS
-                /* Skip the HTTP_ prefix to the beginning of the header name */
-                tmp += HTTP_HEADER_PREFIX_LEN;
+            /* Skip the HTTP_ prefix to the beginning of the header name */
+            tmp += HTTP_HEADER_PREFIX_LEN;
 #endif
 
-                if (!strnicmp(tmp, URI_HEADER_NAME, strlen(URI_HEADER_NAME))
-                    || !strnicmp(tmp, WORKER_HEADER_NAME, strlen(WORKER_HEADER_NAME))
-                    || !strnicmp(tmp, WORKER_HEADER_INDEX, strlen(WORKER_HEADER_INDEX))
-                    || !strnicmp(tmp, QUERY_HEADER_NAME, strlen(QUERY_HEADER_NAME))) {
-                    /* Skip redirector headers */
+            if (!strnicmp(tmp, URI_HEADER_NAME, strlen(URI_HEADER_NAME)) ||
+                !strnicmp(tmp, WORKER_HEADER_NAME, strlen(WORKER_HEADER_NAME)) ||
+                !strnicmp(tmp, WORKER_HEADER_INDEX, strlen(WORKER_HEADER_INDEX)) ||
+                !strnicmp(tmp, QUERY_HEADER_NAME, strlen(QUERY_HEADER_NAME))) {
+                /* Skip redirector headers */
+                cnt--;
+                real_header = JK_FALSE;
+            }
+            else if (!strnicmp(tmp, CONTENT_LENGTH,
+                               sizeof(CONTENT_LENGTH) - 1)) {
+                need_content_length_header = FALSE;
+
+                /* If the content-length is unknown
+                 * or larger then 4Gb do not send it.
+                 * IIS can also create a synthetic Content-Length header to make
+                 * lpcbTotalBytes and the CONTENT_LENGTH server variable agree
+                 * on small requests where the entire chunk encoded message is
+                 * read into the available buffer.
+                 */
+                if (unknown_content_length || s->is_chunked) {
+                    if (JK_IS_DEBUG_LEVEL(logger)) {
+                        jk_log(logger, JK_LOG_DEBUG,
+                               "Disregarding Content-Length in request - content is %s",
+                               s->is_chunked ? "chunked" : "unknown length");
+                    }
                     cnt--;
                     real_header = JK_FALSE;
                 }
-                else if (!strnicmp(tmp, CONTENT_LENGTH,
-                                   sizeof(CONTENT_LENGTH) - 1)) {
-                    need_content_length_header = FALSE;
-
-                    /* If the content-length is unknown
-                     * or larger then 4Gb do not send it.
-                     * IIS can also create a synthetic Content-Length header to make
-                     * lpcbTotalBytes and the CONTENT_LENGTH server variable agree
-                     * on small requests where the entire chunk encoded message is
-                     * read into the available buffer.
-                     */
-                    if (unknown_content_length || s->is_chunked) {
-                        if (JK_IS_DEBUG_LEVEL(logger)) {
-                            jk_log(logger, JK_LOG_DEBUG,
-                                   "Disregarding Content-Length in request - content is %s",
-                                   s->is_chunked ? "chunked" : "unknown length");
-                        }
-                        cnt--;
-                        real_header = JK_FALSE;
-                    }
-                    else {
-                        s->headers_names[i] = tmp;
-                    }
-                }
-                else if (!strnicmp(tmp, TOMCAT_TRANSLATE_HEADER_NAME,
-                                   strlen(TOMCAT_TRANSLATE_HEADER_NAME))) {
-                    s->headers_names[i] = TRANSLATE_HEADER_NAME_LC;
-                }
                 else {
                     s->headers_names[i] = tmp;
                 }
+            }
+            else if (!strnicmp(tmp, TOMCAT_TRANSLATE_HEADER_NAME,
+                               strlen(TOMCAT_TRANSLATE_HEADER_NAME))) {
+                s->headers_names[i] = TRANSLATE_HEADER_NAME_LC;
+            }
+            else {
+                s->headers_names[i] = tmp;
+            }
 
-                while (':' != *tmp && *tmp) {
+            while (':' != *tmp && *tmp) {
 #ifdef USE_CGI_HEADERS
-                    if (real_header) {
-                        if ('_' == *tmp) {
-                            *tmp = '-';
-                        }
-                        else {
-                            *tmp = JK_TOLOWER(*tmp);
-                        }
+                if (real_header) {
+                    if ('_' == *tmp) {
+                        *tmp = '-';
+                    }
+                    else {
+                        *tmp = JK_TOLOWER(*tmp);
                     }
-#endif
-                    tmp++;
                 }
-                *tmp = '\0';
+#endif
                 tmp++;
+            }
+            *tmp = '\0';
+            tmp++;
 
-                /* Skip all the WS chars after the ':' to the beginning of the header value */
-                while (' ' == *tmp || '\t' == *tmp || '\v' == *tmp) {
-                    tmp++;
-                }
+            /* Skip all the WS chars after the ':' to the beginning of the header value */
+            while (' ' == *tmp || '\t' == *tmp || '\v' == *tmp) {
+                tmp++;
+            }
 
-                if (real_header) {
-                    s->headers_values[i] = tmp;
-                }
+            if (real_header) {
+                s->headers_values[i] = tmp;
+            }
 
-                while (*tmp && *tmp != '\n' && *tmp != '\r') {
-                    tmp++;
-                }
-                *tmp = '\0';
+            while (*tmp && *tmp != '\n' && *tmp != '\r') {
                 tmp++;
+            }
+            *tmp = '\0';
+            tmp++;
 
-                /* skip CR LF */
-                while (*tmp == '\n' || *tmp == '\r') {
-                    tmp++;
-                }
-
-                if (real_header) {
-                    if (JK_IS_DEBUG_LEVEL(logger)) {
-                        jk_log(logger, JK_LOG_DEBUG, "Forwarding request header %s : %s",
-                               s->headers_names[i], s->headers_values[i]);
-                    }
-                    i++;
-                }
+            /* skip CR LF */
+            while (*tmp == '\n' || *tmp == '\r') {
+                tmp++;
             }
-            /* Add a content-length = 0 header if needed.
-             * Ajp13 assumes an absent content-length header means an unknown,
-             * but non-zero length body.
-             */
-            if (need_content_length_header) {
+
+            if (real_header) {
                 if (JK_IS_DEBUG_LEVEL(logger)) {
-                    jk_log(logger, JK_LOG_DEBUG, "Incoming request needs explicit Content-Length: 0 in AJP13");
+                    jk_log(logger, JK_LOG_DEBUG, "Forwarding request header %s : %s",
+                           s->headers_names[i], s->headers_values[i]);
                 }
-                s->headers_names[cnt] = "Content-Length";
-                s->headers_values[cnt] = "0";
-                cnt++;
+                i++;
             }
-            s->num_headers = cnt;
         }
-        else {
-            /* We must have our two headers */
-            JK_TRACE_EXIT(logger);
-            return JK_FALSE;
+        /* Add a content-length = 0 header if needed.
+         * Ajp13 assumes an absent content-length header means an unknown,
+         * but non-zero length body.
+         */
+        if (need_content_length_header) {
+            if (JK_IS_DEBUG_LEVEL(logger)) {
+                jk_log(logger, JK_LOG_DEBUG, "Incoming request needs explicit Content-Length: 0 in AJP13");
+            }
+            s->headers_names[cnt] = "Content-Length";
+            s->headers_values[cnt] = "0";
+            cnt++;
         }
+        s->num_headers = cnt;
     }
     else {
         JK_TRACE_EXIT(logger);
@@ -3374,18 +3419,14 @@ static int init_ws_service(isapi_private
     return JK_TRUE;
 }
 
-static int get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
-                            char *name, char *buf, DWORD bufsz)
+static BOOL get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
+                            char *name, char *buf, size_t bufsz)
 {
-    DWORD sz = bufsz;
-    buf[0]   = '\0';
-    if (!lpEcb->GetServerVariable(lpEcb->ConnID, name,
-                                  buf, &sz))
-        return JK_FALSE;
+    DWORD sz = (DWORD)bufsz;
 
-    if (sz <= bufsz)
-        buf[sz-1] = '\0';
-    return JK_TRUE;
+    buf[0]   = '\0';
+    return lpEcb->GetServerVariable(lpEcb->ConnID, name,
+                                    buf, &sz);
 }
 
 static const char begin_cert[] = "-----BEGIN CERTIFICATE-----\r\n";



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org