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