in native/iis/jk_isapi_plugin.c [1710:2002]
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 = 0;
jk_pool_atom_t pbuf[HUGE_POOL_SIZE];
jk_pool_t pool;
char *uri_undec = NULL;
char *cleanuri = NULL;
char *uri = NULL;
char *host = NULL;
char *request_id = NULL;
char *translate = NULL;
char szHB[HDR_BUFFER_SIZE] = "/";
char szUB[HDR_BUFFER_SIZE] = "";
char szRIDB[512] = "";
char szTB[16] = "";
char szPB[16] = "";
char swindex[32] = "";
char *query;
DWORD len;
jk_log_context_t log_ctx;
jk_log_context_t *l = &log_ctx;
l->logger = logger;
l->id = "FILTER";
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, 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, REQUEST_ID_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(l, 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;
}
/* Duplicate unparsed uri */
uri_undec = jk_pool_strdup(&pool, uri);
rc = unescape_url(uri);
if (rc == BAD_REQUEST) {
jk_log(l, JK_LOG_ERROR,
"[%s] contains one or more invalid escape sequences.",
uri);
write_error_response(pfc, 400);
rv = SF_STATUS_REQ_FINISHED;
goto cleanup;
}
if (rc == BAD_PATH) {
jk_log(l, JK_LOG_EMERG,
"[%s] contains forbidden escape sequences.",
uri);
write_error_response(pfc, 404);
rv = SF_STATUS_REQ_FINISHED;
goto cleanup;
}
cleanuri = jk_pool_strdup(&pool, uri);
if (jk_servlet_normalize(cleanuri, l)) {
write_error_response(pfc, 404);
rv = SF_STATUS_REQ_FINISHED;
goto cleanup;
}
len = ISIZEOF(szHB) - 1;
if (pfc->GetServerVariable(pfc, "SERVER_NAME", &szHB[1], &len) && len > 1) {
len = ISIZEOF(szPB);
if (pfc->GetServerVariable(pfc, "SERVER_PORT", szPB, &len))
port = atoi(szPB);
if (port != 0 && port != 80 && port != 443) {
host = jk_pool_strcatv(&pool, szHB, ":", szPB, NULL);
}
else
host = szHB;
}
worker = map_uri_to_worker_ext(uw_map, cleanuri, host,
&extensions, &worker_index, l);
/*
* 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;
/* This is a servlet, should redirect ... */
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, 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) * 3 + 1;
char *escuri = jk_pool_alloc(&pool, elen);
if (!escape_url(uri, escuri, (int)elen)) {
jk_log(l, 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(l))
jk_log(l, JK_LOG_DEBUG,
"fowarding escaped URI [%s]",
escuri);
forwardURI = escuri;
}
else if (uri_select_option == URI_SELECT_OPT_PROXY) {
size_t elen = strlen(uri) * 3 + 1;
char *escuri = jk_pool_alloc(&pool, elen);
if (!jk_canonenc(uri, escuri, (int)elen)) {
jk_log(l, 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(l))
jk_log(l, JK_LOG_DEBUG,
"fowarding escaped URI [%s]",
escuri);
forwardURI = escuri;
}
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(l)) {
jk_log(l, 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);
request_id = get_pheader(&pool, pfp, pfc, request_id_header,
szRIDB, sizeof(szRIDB));
if (request_id == NULL || *request_id == '\0') {
char uuid[UUID_BUFFER_SIZE];
GUID guid;
HRESULT hr = CoCreateGuid(&guid);
if (FAILED(hr)) {
jk_log(l, JK_LOG_WARNING, "Could not create UUID for request id");
request_id = "NO-ID";
}
else {
_snprintf_s(uuid, sizeof(uuid), _TRUNCATE, UUID_TEMPLATE,
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
request_id = jk_pool_strdup(&pool, uuid);
l->id = request_id;
if (JK_IS_DEBUG_LEVEL(l)) {
jk_log(l, JK_LOG_DEBUG,
"Created request id [%s]", request_id);
}
}
}
else {
l->id = request_id;
if (JK_IS_DEBUG_LEVEL(l)) {
jk_log(l, JK_LOG_DEBUG,
"Received request id [%s]", request_id);
}
}
rs = rs && pfp->AddHeader(pfc, REQUEST_ID_HEADER_NAME, request_id);
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(l, 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 != NULL && *translate != '\0') {
if (!pfp->AddHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, translate)) {
jk_log(l, 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(l, 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;
if (JK_IS_DEBUG_LEVEL(l)) {
jk_log(l, JK_LOG_DEBUG,
"forwarding to : %s", extension_uri);
jk_log(l, JK_LOG_DEBUG,
"forward URI : %s%s", URI_HEADER_NAME, forwardURI);
if (query)
jk_log(l, JK_LOG_DEBUG,
"forward query : %s%s", QUERY_HEADER_NAME, query);
jk_log(l, JK_LOG_DEBUG,
"request id: %s%s", REQUEST_ID_HEADER_NAME, request_id);
jk_log(l, JK_LOG_DEBUG,
"forward worker: %s%s", WORKER_HEADER_NAME, worker);
jk_log(l, JK_LOG_DEBUG,
"worker index : %s%s", WORKER_HEADER_INDEX, swindex);
}
}
else {
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG, "[%s] is not a servlet url", uri_undec);
if (strip_session) {
if (jk_strip_session_id(uri_undec, JK_PATH_SESSION_IDENTIFIER, l)) {
pfp->SetHeader(pfc, "url", uri_undec);
}
}
}
cleanup:
jk_close_pool(&pool);
return rv;
}