You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by sh...@locus.apache.org on 2000/04/17 11:49:32 UTC
cvs commit: jakarta-tomcat/src/native/iis isapi.def isapi.dsp isapi.dsw jk_isapi_plugin.c
shachor 00/04/17 02:49:32
Added: src/native/iis isapi.def isapi.dsp isapi.dsw
jk_isapi_plugin.c
Log:
The IIS directory contains files that are part of the ISAPI plugin
Revision Changes Path
1.1 jakarta-tomcat/src/native/iis/isapi.def
Index: isapi.def
===================================================================
LIBRARY "isapi_redirect"
EXPORTS
HttpFilterProc
GetFilterVersion
GetExtensionVersion
HttpExtensionProc
TerminateFilter
TerminateExtension
1.1 jakarta-tomcat/src/native/iis/isapi.dsp
Index: isapi.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="isapi" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=isapi - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "isapi.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "isapi.mak" CFG="isapi - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "isapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "isapi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "isapi - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "isapi___Win32_Release"
# PROP BASE Intermediate_Dir "isapi___Win32_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "isapi_release"
# PROP Intermediate_Dir "isapi_release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\jk" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 wsock32.lib advapi32.lib /nologo /dll /machine:I386 /out:"isapi_release/isapi_redirect.dll"
!ELSEIF "$(CFG)" == "isapi - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "isapi___Win32_Debug"
# PROP BASE Intermediate_Dir "isapi___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "isapi_debug"
# PROP Intermediate_Dir "isapi_debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\jk" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 wsock32.lib advapi32.lib /nologo /dll /debug /machine:I386 /out:"isapi_debug/isapi_redirect.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "isapi - Win32 Release"
# Name "isapi - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\isapi.def
# End Source File
# Begin Source File
SOURCE=..\jk\jk_ajp12_worker.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_ajp23_worker.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_connect.c
# End Source File
# Begin Source File
SOURCE=.\jk_isapi_plugin.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_jni_worker.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_lb_worker.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_map.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_pool.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_sockbuf.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_uri_worker_map.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_util.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_worker.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
1.1 jakarta-tomcat/src/native/iis/isapi.dsw
Index: isapi.dsw
===================================================================
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "isapi"=".\isapi.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
1.1 jakarta-tomcat/src/native/iis/jk_isapi_plugin.c
Index: jk_isapi_plugin.c
===================================================================
/*
* Copyright (c) 1997-1999 The Java Apache Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* 4. The names "Apache JServ", "Apache JServ Servlet Engine" and
* "Java Apache Project" must not be used to endorse or promote products
* derived from this software without prior written permission.
*
* 5. Products derived from this software may not be called "Apache JServ"
* nor may "Apache" nor "Apache JServ" appear in their names without
* prior written permission of the Java Apache Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Java Apache Group. For more information
* on the Java Apache Project and the Apache JServ Servlet Engine project,
* please see <http://java.apache.org/>.
*
*/
/***************************************************************************
* Description: ISAPI plugin for IIS/PWS *
* Author: Gal Shachor <sh...@il.ibm.com> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
#include <httpext.h>
#include <httpfilt.h>
#include <wininet.h>
#include "jk_global.h"
#include "jk_util.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_service.h"
#include "jk_worker.h"
#include "jk_ajp12_worker.h"
#include "jk_uri_worker_map.h"
#define VERSION_STRING "Jakarta/ISAPI/1.0b1"
#define REGISTRY_LOCATION ("Software\\Apache Software Foundation\\Jakarta Isapi Redirector\\1.0")
#define EXTENSION_URI_TAG ("extension_uri")
#define GET_SERVER_VARIABLE_VALUE(name, place) { \
place = NULL; \
huge_buf_sz = sizeof(huge_buf); \
if(get_server_value(private_data->lpEcb, \
(name), \
huge_buf, \
huge_buf_sz, \
"")) { \
(place) = jk_pool_strdup(&private_data->p, huge_buf); \
} \
}\
#define GET_SERVER_VARIABLE_VALUE_INT(name, place, def) { \
huge_buf_sz = sizeof(huge_buf); \
if(get_server_value(private_data->lpEcb, \
(name), \
huge_buf, \
huge_buf_sz, \
"")) { \
(place) = atoi(huge_buf); \
if(0 == (place)) { \
(place) = def; \
} \
} else { \
(place) = def; \
} \
}\
/*
* We use a TLS to pass values from the filter to the
* extension. These values are:
*
* 1. The real URI before redirection took place
* 2. The name of the worker to be used.
*
*/
static DWORD tls_index = 0xFFFFFFFF;
static int is_inited = JK_FALSE;
static jk_uri_worker_map_t *uw_map = NULL;
static jk_logger_t *logger = NULL;
static char extension_uri[INTERNET_MAX_URL_LENGTH] = "/jakarta/isapi_redirect.dll";
static char log_file[MAX_PATH * 2];
static int log_level = JK_LOG_EMERG_LEVEL;
static char worker_file[MAX_PATH * 2];
static char worker_mount_file[MAX_PATH * 2];
struct filter_ext_record {
char *worker;
char *uri;
};
typedef struct filter_ext_record filter_ext_record_t;
struct isapi_private_data {
jk_pool_t p;
int request_started;
unsigned bytes_read_so_far;
LPEXTENSION_CONTROL_BLOCK lpEcb;
};
typedef struct isapi_private_data isapi_private_data_t;
static int JK_METHOD start_response(jk_ws_service_t *s,
int status,
const char *reason,
const char * const *header_names,
const char * const *header_values,
unsigned num_of_headers);
static int JK_METHOD read(jk_ws_service_t *s,
void *b,
unsigned l,
unsigned *a);
static int JK_METHOD write(jk_ws_service_t *s,
const void *b,
unsigned l);
static int init_ws_service(isapi_private_data_t *private_data,
jk_ws_service_t *s,
char **worker_name);
static int initialize_extension(void);
static int read_registry_init_data(void);
static int get_registry_config_parameter(HKEY hkey,
const char *tag,
char *b,
DWORD sz);
static int get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
char *name,
char *buf,
DWORD bufsz,
char *def_val);
static int JK_METHOD start_response(jk_ws_service_t *s,
int status,
const char *reason,
const char * const *header_names,
const char * const *header_values,
unsigned num_of_headers)
{
static char crlf[3] = { (char)13, (char)10, '\0' };
if(status < 100 || status > 1000) {
jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::start_response, invalid status %d\n", status);
return JK_FALSE;
}
if(s && s->ws_private) {
isapi_private_data_t *p = s->ws_private;
if(!p->request_started) {
DWORD len_of_status;
char *status_str;
char *headers_str;
p->request_started = JK_TRUE;
/*
* Create the status line
*/
if(!reason) {
reason = "";
}
status_str = (char *)_alloca((6 + strlen(reason)) * sizeof(char));
sprintf(status_str, "%d %s", status, reason);
len_of_status = strlen(status_str);
/*
* Create response headers string
*/
if(num_of_headers) {
unsigned i;
unsigned len_of_headers;
for(i = 0 , len_of_headers = 0 ; i < num_of_headers ; i++) {
len_of_headers += strlen(header_names[i]);
len_of_headers += strlen(header_values[i]);
len_of_headers += 3; /* extra for : and crlf */
}
len_of_headers += 3; /* crlf and terminating null char */
headers_str = (char *)_alloca(len_of_headers * sizeof(char));
headers_str[0] = '\0';
for(i = 0 ; i < num_of_headers ; i++) {
strcat(headers_str, header_names[i]);
strcat(headers_str, ":");
strcat(headers_str, header_values[i]);
strcat(headers_str, crlf);
}
strcat(headers_str, crlf);
} else {
headers_str = crlf;
}
if(!p->lpEcb->ServerSupportFunction(p->lpEcb->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER,
status_str,
(LPDWORD)&len_of_status,
(LPDWORD)headers_str)) {
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::start_response, ServerSupportFunction failed\n");
return JK_FALSE;
}
}
return JK_TRUE;
}
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::start_response, NULL parameters\n");
return JK_FALSE;
}
static int JK_METHOD read(jk_ws_service_t *s,
void *b,
unsigned l,
unsigned *a)
{
if(s && s->ws_private && b && a) {
isapi_private_data_t *p = s->ws_private;
*a = 0;
if(l) {
char *buf = b;
DWORD already_read = p->lpEcb->cbAvailable - p->bytes_read_so_far;
if(already_read >= l) {
memcpy(buf, p->lpEcb->lpbData + p->bytes_read_so_far, l);
p->bytes_read_so_far += l;
*a = l;
} else {
/*
* Try to copy what we already have
*/
if(already_read > 0) {
memcpy(buf, p->lpEcb->lpbData + p->bytes_read_so_far, already_read);
buf += already_read;
l -= already_read;
p->bytes_read_so_far = p->lpEcb->cbAvailable;
*a = already_read;
}
/*
* Now try to read from the client ...
*/
if(p->lpEcb->ReadClient(p->lpEcb->ConnID, buf, &l)) {
*a += l;
} else {
jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::read, ReadClient failed\n");
return JK_FALSE;
}
}
}
return JK_TRUE;
}
jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::read, NULL parameters\n");
return JK_FALSE;
}
static int JK_METHOD write(jk_ws_service_t *s,
const void *b,
unsigned l)
{
if(s && s->ws_private && b) {
isapi_private_data_t *p = s->ws_private;
if(l) {
unsigned written = 0;
char *buf = (char *)b;
if(!p->request_started) {
start_response(s, 200, NULL, NULL, NULL, 0);
}
while(written < l) {
DWORD try_to_write = l - written;
if(!p->lpEcb->WriteClient(p->lpEcb->ConnID,
buf + written,
&try_to_write,
0)) {
jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::write, WriteClient failed\n");
return JK_FALSE;
}
written += try_to_write;
}
}
return JK_TRUE;
}
jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::write, NULL parameters\n");
return JK_FALSE;
}
BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{
ULONG http_filter_revision = HTTP_FILTER_REVISION
pVer->dwFilterVersion = pVer->dwServerFilterVersion;
if(pVer->dwFilterVersion > http_filter_revision) {
pVer->dwFilterVersion = http_filter_revision;
}
pVer->dwFlags = SF_NOTIFY_ORDER_HIGH |
SF_NOTIFY_SECURE_PORT |
SF_NOTIFY_NONSECURE_PORT |
SF_NOTIFY_PREPROC_HEADERS;
strcpy(pVer->lpszFilterDesc, VERSION_STRING);
if(!is_inited) {
return initialize_extension();
}
return TRUE;
}
DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc,
DWORD dwNotificationType,
LPVOID pvNotification)
{
if(is_inited &&
(SF_NOTIFY_PREPROC_HEADERS == dwNotificationType)) {
PHTTP_FILTER_PREPROC_HEADERS p = (PHTTP_FILTER_PREPROC_HEADERS)pvNotification;
char uri[INTERNET_MAX_URL_LENGTH];
char *query;
DWORD sz = sizeof(uri);
if(p->GetHeader(pfc, "url", (LPVOID)uri, (LPDWORD)&sz)) {
if(strlen(uri)) {
char *worker;
query = strchr(uri, '?');
if(query) {
*query = '\0';
}
jk_log(logger, JK_LOG_DEBUG, "In HttpFilterProc test redirection of %s\n", uri);
worker = map_uri_to_worker(uw_map, uri, logger);
if(query) {
*query = '?';
}
if(worker) {
/* This is a servlet, should redirect ... */
filter_ext_record_t *rec;
jk_log(logger, JK_LOG_DEBUG,
"In HttpFilterProc %s should redirect to %s\n",
uri, worker);
rec = pfc->AllocMem(pfc, sizeof(filter_ext_record_t), 0);
if(rec) {
rec->uri = pfc->AllocMem(pfc, strlen(uri) + 1, 0);
rec->worker = pfc->AllocMem(pfc, strlen(worker) + 1, 0);
if(rec->uri && rec->worker && TlsSetValue(tls_index, rec)) {
strcpy(rec->uri, uri);
strcpy(rec->worker, worker);
p->SetHeader(pfc, "url", extension_uri);
}
}
} else {
/* check if asking for web-inf file */
char *c = uri;
while(*c) {
*c = tolower(*c);
c++;
}
if(strstr(uri, "web-inf")) {
char crlf[3] = { (char)13, (char)10, '\0' };
char ctype[30];
char *msg = "<HTML><BODY><H1>Access is Forbidden</H1></BODY></HTML>";
DWORD len = strlen(msg);
sprintf(ctype,
"Content-Type:text/html%s%s",
crlf,
crlf);
/* reject !!! */
pfc->ServerSupportFunction(pfc,
SF_REQ_SEND_RESPONSE_HEADER,
"403 Forbidden",
(DWORD)crlf,
(DWORD)ctype);
pfc->WriteClient(pfc, msg, &len, 0);
return SF_STATUS_REQ_FINISHED;
}
}
}
}
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
{
pVer->dwExtensionVersion = MAKELONG( HSE_VERSION_MINOR,
HSE_VERSION_MAJOR );
strcpy(pVer->lpszExtensionDesc, VERSION_STRING);
if(!is_inited) {
return initialize_extension();
}
return TRUE;
}
DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpEcb)
{
DWORD rc = HSE_STATUS_ERROR;
lpEcb->dwHttpStatusCode = HTTP_STATUS_SERVER_ERROR;
if(is_inited) {
isapi_private_data_t private_data;
jk_ws_service_t s;
jk_pool_atom_t buf[SMALL_POOL_SIZE];
char *worker_name;
jk_open_pool(&private_data.p, buf, sizeof(buf));
private_data.request_started = JK_FALSE;
private_data.bytes_read_so_far = 0;
private_data.lpEcb = lpEcb;
s.ws_private = &private_data;
s.pool = &private_data.p;
if(init_ws_service(&private_data, &s, &worker_name)) {
jk_worker_t *worker = wc_get_worker_for_name(worker_name, logger);
if(worker) {
jk_endpoint_t *e = NULL;
if(worker->get_endpoint(worker, &e, logger)) {
int recover = JK_FALSE;
if(e->service(e, &s, logger, &recover)) {
rc = HSE_STATUS_SUCCESS_AND_KEEP_CONN;
lpEcb->dwHttpStatusCode = HTTP_STATUS_OK;
}
e->done(&e, logger);
}
}
}
jk_close_pool(&private_data.p);
}
return rc;
}
BOOL WINAPI TerminateExtension(DWORD dwFlags)
{
return TerminateFilter(dwFlags);
}
BOOL WINAPI TerminateFilter(DWORD dwFlags)
{
if(is_inited) {
is_inited = JK_FALSE;
uri_worker_map_free(&uw_map, logger);
wc_close(logger);
if(logger) {
jk_close_file_logger(&logger);
}
}
return TRUE;
}
BOOL WINAPI DllMain(HINSTANCE hInst, // Instance Handle of the DLL
ULONG ulReason, // Reason why NT called this DLL
LPVOID lpReserved) // Reserved parameter for future use
{
BOOL fReturn = TRUE;
switch (ulReason) {
case DLL_PROCESS_ATTACH:
tls_index = TlsAlloc();
if(0xFFFFFFFF == tls_index) {
fReturn = FALSE;
}
TlsSetValue(tls_index, NULL);
break;
case DLL_PROCESS_DETACH:
__try {
TerminateFilter(HSE_TERM_MUST_UNLOAD);
} __except(1) {
}
if(0xFFFFFFFF != tls_index) {
TlsFree(tls_index);
tls_index = 0xFFFFFFFF;
}
break;
default:
break;
}
return fReturn;
}
static int initialize_extension(void)
{
int rc = JK_FALSE;
if(read_registry_init_data()) {
jk_map_t *map;
if(!jk_open_file_logger(&logger, log_file, log_level)) {
logger = NULL;
}
if(map_alloc(&map)) {
if(map_read_properties(map, worker_mount_file)) {
if(uri_worker_map_alloc(&uw_map, map, logger)) {
rc = JK_TRUE;
}
}
map_free(&map);
}
if(rc) {
rc = JK_FALSE;
if(map_alloc(&map)) {
if(map_read_properties(map, worker_file)) {
if(wc_open(map, logger)) {
rc = JK_TRUE;
}
}
map_free(&map);
}
}
}
if(rc) {
is_inited = JK_TRUE;
}
return rc;
}
static int read_registry_init_data(void)
{
char tmpbuf[INTERNET_MAX_URL_LENGTH];
HKEY hkey;
long rc;
int ok = JK_TRUE;
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGISTRY_LOCATION,
(DWORD)0,
KEY_READ,
&hkey);
if(ERROR_SUCCESS != rc) {
return JK_FALSE;
}
if(get_registry_config_parameter(hkey,
JK_LOG_FILE_TAG,
tmpbuf,
sizeof(log_file))) {
strcpy(log_file, tmpbuf);
} else {
ok = JK_FALSE;
}
if(get_registry_config_parameter(hkey,
JK_LOG_LEVEL_TAG,
tmpbuf,
sizeof(tmpbuf))) {
log_level = jk_parse_log_level(tmpbuf);
} else {
ok = JK_FALSE;
}
if(get_registry_config_parameter(hkey,
EXTENSION_URI_TAG,
tmpbuf,
sizeof(extension_uri))) {
strcpy(extension_uri, tmpbuf);
} else {
ok = JK_FALSE;
}
if(get_registry_config_parameter(hkey,
JK_WORKER_FILE_TAG,
tmpbuf,
sizeof(worker_file))) {
strcpy(worker_file, tmpbuf);
} else {
ok = JK_FALSE;
}
if(get_registry_config_parameter(hkey,
JK_MOUNT_FILE_TAG,
tmpbuf,
sizeof(worker_mount_file))) {
strcpy(worker_mount_file, tmpbuf);
} else {
ok = JK_FALSE;
}
RegCloseKey(hkey);
return ok;
}
static int get_registry_config_parameter(HKEY hkey,
const char *tag,
char *b,
DWORD sz)
{
DWORD type = 0;
LONG lrc;
lrc = RegQueryValueEx(hkey,
tag,
(LPDWORD)0,
&type,
(LPBYTE)b,
&sz);
if((ERROR_SUCCESS != lrc) || (type != REG_SZ)) {
return JK_FALSE;
}
b[sz] = '\0';
return JK_TRUE;
}
static int init_ws_service(isapi_private_data_t *private_data,
jk_ws_service_t *s,
char **worker_name)
{
char huge_buf[16 * 1024]; /* should be enough for all */
DWORD huge_buf_sz;
filter_ext_record_t *from_filt = (filter_ext_record_t *)TlsGetValue(tls_index);
s->jvm_route = NULL;
s->start_response = start_response;
s->read = read;
s->write = write;
GET_SERVER_VARIABLE_VALUE("AUTH_TYPE", s->auth_type);
GET_SERVER_VARIABLE_VALUE("REMOTE_USER", s->remote_user);
GET_SERVER_VARIABLE_VALUE("SERVER_PROTOCOL", s->protocol);
GET_SERVER_VARIABLE_VALUE("REMOTE_HOST", s->remote_host);
GET_SERVER_VARIABLE_VALUE("REMOTE_ADDR", s->remote_addr);
GET_SERVER_VARIABLE_VALUE("SERVER_NAME", s->server_name);
GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT", s->server_port, 80)
GET_SERVER_VARIABLE_VALUE("SERVER_SOFTWARE", s->server_software);
GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT_SECURE", s->is_ssl, 0);
s->method = private_data->lpEcb->lpszMethod;
s->content_length = private_data->lpEcb->cbTotalBytes;
if(from_filt) {
char *t = strchr(from_filt->uri, '?');
if(t) {
*t = '\0';
t++;
if(!strlen(t)) {
t = NULL;
}
}
s->query_string = t;
s->req_uri = from_filt->uri;
*worker_name = from_filt->worker;
} else {
s->query_string = private_data->lpEcb->lpszQueryString;
*worker_name = JK_AJP12_WORKER_NAME;
GET_SERVER_VARIABLE_VALUE("URL", s->req_uri);
}
TlsSetValue(tls_index, NULL);
s->ssl_cert = NULL;
s->ssl_cert_len = 0;
s->ssl_cipher = NULL;
s->ssl_session = NULL;
s->headers_names = NULL;
s->headers_values = NULL;
s->num_headers = 0;
huge_buf_sz = sizeof(huge_buf);
if(get_server_value(private_data->lpEcb,
"ALL_HTTP",
huge_buf,
huge_buf_sz,
"")) {
unsigned cnt = 0;
char *tmp;
for(tmp = huge_buf ; *tmp ; tmp++) {
if(*tmp == '\n'){
cnt++;
}
}
if(cnt) {
char *headers_buf = jk_pool_strdup(&private_data->p, huge_buf);
unsigned i;
unsigned len_of_http_prefix = strlen("HTTP_");
s->headers_names = jk_pool_alloc(&private_data->p, cnt * sizeof(char *));
s->headers_values = jk_pool_alloc(&private_data->p, cnt * sizeof(char *));
if(!s->headers_names || !s->headers_values || !headers_buf) {
return JK_FALSE;
}
for(i = 0, tmp = headers_buf ; *tmp && i < cnt ; i++) {
/* Skipp the HTTP_ prefix to the beginning of th header name */
tmp += len_of_http_prefix;
s->headers_names[i] = tmp;
while(':' != *tmp && *tmp) {
if('_' == *tmp) {
*tmp = '-';
} else {
*tmp = tolower(*tmp);
}
tmp++;
}
*tmp = '\0';
tmp++;
/* Skipp all the WS chars after the ':' to the beginning of th header value */
while(' ' == *tmp || '\t' == *tmp || '\v' == *tmp) {
tmp++;
}
s->headers_values[i] = tmp;
while(*tmp != '\n' && *tmp != '\r') {
tmp++;
}
*tmp = '\0';
tmp++;
/* skipp CR LF */
while(*tmp == '\n' || *tmp == '\r') {
tmp++;
}
}
s->num_headers = cnt;
}
}
return JK_TRUE;
}
static int get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
char *name,
char *buf,
DWORD bufsz,
char *def_val)
{
if(!lpEcb->GetServerVariable(lpEcb->ConnID,
name,
buf,
(LPDWORD)&bufsz)) {
strcpy(buf, def_val);
return JK_FALSE;
}
if(bufsz > 0) {
buf[bufsz - 1] = '\0';
}
return JK_TRUE;
}