tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hgo...@apache.org
Subject cvs commit: jakarta-tomcat/proposals/web-connector/native/iis isapi.def isapi.dsp isapi.dsw jk_isapi_plugin.c
Date Thu, 03 May 2001 14:39:44 GMT
hgomez      01/05/03 07:39:44

  Added:       proposals/web-connector/native/iis isapi.def isapi.dsp
                        isapi.dsw jk_isapi_plugin.c
  Log:
  ISA stuff
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat/proposals/web-connector/native/iis/isapi.def
  
  Index: isapi.def
  ===================================================================
  LIBRARY	     "isapi_redirect"
  
  EXPORTS
  	HttpFilterProc
  	GetFilterVersion
  	GetExtensionVersion
  	HttpExtensionProc	
  	TerminateFilter
  	TerminateExtension
  
  
  
  1.1                  jakarta-tomcat/proposals/web-connector/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 "..\common" /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 "..\common" /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=..\common\jk_ajp12_worker.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_ajp13.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_ajp13_worker.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_connect.c
  # End Source File
  # Begin Source File
  
  SOURCE=.\jk_isapi_plugin.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_jni_worker.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_lb_worker.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_map.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_msg_buff.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_pool.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_sockbuf.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_uri_worker_map.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_util.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_worker.c
  # End Source File
  # End Group
  # Begin Group "Header Files"
  
  # PROP Default_Filter "h;hpp;hxx;hm;inl"
  # Begin Source File
  
  SOURCE=..\common\jk_ajp12_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_ajp13.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_ajp13_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_ajp23_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_connect.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_global.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_jni_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_lb_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_logger.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_map.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_msg_buff.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_mt.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_pool.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_service.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_sockbuf.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_uri_worker_map.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_util.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_worker_list.h
  # End Source File
  # 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/proposals/web-connector/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/proposals/web-connector/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 <shachor@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"
  
  /*
   * We use special two headers 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.
   *
   */
  #define URI_HEADER_NAME         ("TOMCATURI:")
  #define WORKER_HEADER_NAME      ("TOMCATWORKER:")
  
  #define HTTP_URI_HEADER_NAME     ("HTTP_TOMCATURI")
  #define HTTP_WORKER_HEADER_NAME  ("HTTP_TOMCATWORKER")
  
  #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;  \
      }           \
  }\
  
  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 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 uri_is_web_inf(char *uri)
  {
      char *c = uri;
      while(*c) {
          *c = tolower(*c);
          c++;
      }                    
      if(strstr(uri, "web-inf")) {
          return JK_TRUE;
      }
  
      return JK_FALSE;
  }
  
  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' };
  
      jk_log(logger, JK_LOG_DEBUG, 
             "Into jk_ws_service_t::start_response\n");
  
      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 += 4; /* extra for colon, space 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)
  {
      jk_log(logger, JK_LOG_DEBUG, 
             "Into jk_ws_service_t::read\n");
  
      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)
  {
      jk_log(logger, JK_LOG_DEBUG, 
             "Into jk_ws_service_t::write\n");
  
      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);
  
          jk_log(logger, JK_LOG_DEBUG, 
                 "HttpFilterProc started\n");
  
          /*
           * Just in case somebody set these headers in the request!
           */
          p->SetHeader(pfc, URI_HEADER_NAME, NULL);
  	    p->SetHeader(pfc, WORKER_HEADER_NAME, NULL);
          
          if(!p->GetHeader(pfc, "url", (LPVOID)uri, (LPDWORD)&sz)) {
              jk_log(logger, JK_LOG_ERROR, 
                     "HttpFilterProc error while getting the url\n");
              return SF_STATUS_REQ_ERROR;
          }
  
          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 ... */
                  jk_log(logger, JK_LOG_DEBUG, 
                         "HttpFilterProc [%s] is a servlet url - should redirect to %s\n",

                         uri, worker);
  
                  
  				if(!p->AddHeader(pfc, URI_HEADER_NAME, uri) || 
                     !p->AddHeader(pfc, WORKER_HEADER_NAME, worker) ||
                     !p->SetHeader(pfc, "url", extension_uri)) {
                      jk_log(logger, JK_LOG_ERROR, 
                             "HttpFilterProc error while adding request headers\n");
                      return SF_STATUS_REQ_ERROR;
                  }
              } else {
                  jk_log(logger, JK_LOG_DEBUG, 
                         "HttpFilterProc [%s] is not a servlet url\n", 
                         uri);
              }
  
              /*
               * Check if somebody is feading us with his own TOMCAT data headers.
               * We reject such postings !
               */
              jk_log(logger, JK_LOG_DEBUG, 
                     "HttpFilterProc check if [%s] is points to the web-inf directory\n",

                     uri);
  
              if(uri_is_web_inf(uri)) {
                  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);
  
                  jk_log(logger, JK_LOG_EMERG, 
                         "HttpFilterProc [%s] points to the web-inf directory.\nSomebody try
to hack into the site!!!\n", 
                         uri);
  
                  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;
  
      jk_log(logger, JK_LOG_DEBUG, 
             "HttpExtensionProc started\n");
  
      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_init_ws_service(&s);
          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);
  
              jk_log(logger, JK_LOG_DEBUG, 
                     "HttpExtensionProc %s a worker for name %s\n", 
                     worker ? "got" : "could not get",
                     worker_name);
  
              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;
                          jk_log(logger, JK_LOG_DEBUG, 
                                 "HttpExtensionProc service() returned OK\n");
                      } else {
                          jk_log(logger, JK_LOG_ERROR, 
                                 "HttpExtensionProc error, service() failed\n");
                      }
                      e->done(&e, logger);
                  }
              } else {
                  jk_log(logger, JK_LOG_ERROR, 
                         "HttpExtensionProc error, could not get a worker for name %s\n",
                         worker_name);
              }
          }
          jk_close_pool(&private_data.p);     
      } else {
          jk_log(logger, JK_LOG_ERROR, 
                 "HttpExtensionProc error, not initialized\n");
      }
  
      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_DETACH:
              __try {
                  TerminateFilter(HSE_TERM_MUST_UNLOAD);
              } __except(1) {
              }
          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;
  
      s->jvm_route = NULL;
  
      s->start_response = start_response;
      s->read = read;
      s->write = write;
  
      GET_SERVER_VARIABLE_VALUE(HTTP_WORKER_HEADER_NAME, (*worker_name));           
      GET_SERVER_VARIABLE_VALUE(HTTP_URI_HEADER_NAME, s->req_uri);     
  
      if(s->req_uri) {
          char *t = strchr(s->req_uri, '?');
          if(t) {
              *t = '\0';
              t++;
              if(!strlen(t)) {
                  t = NULL;
              }
          }
          s->query_string = t;
      } else {
          s->query_string = private_data->lpEcb->lpszQueryString;
          *worker_name    = JK_AJP12_WORKER_NAME;
          GET_SERVER_VARIABLE_VALUE("URL", s->req_uri);       
      }
      
      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;
  
      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;
      
      /*
       * Add SSL IIS environment
       */
      if(s->is_ssl) {         
          char *ssl_env_names[9] = {
              "CERT_ISSUER", 
              "CERT_SUBJECT", 
              "CERT_COOKIE", 
              "HTTPS_SERVER_SUBJECT", 
              "CERT_FLAGS", 
              "HTTPS_SECRETKEYSIZE", 
              "CERT_SERIALNUMBER", 
              "HTTPS_SERVER_ISSUER", 
              "HTTPS_KEYSIZE"
          };
          char *ssl_env_values[9] = {
              NULL, 
              NULL, 
              NULL, 
              NULL, 
              NULL, 
              NULL, 
              NULL, 
              NULL, 
              NULL
          };
          unsigned i;
          unsigned num_of_vars = 0;
  
          for(i = 0 ; i < 9 ; i++) {
              GET_SERVER_VARIABLE_VALUE(ssl_env_names[i], ssl_env_values[i]);
              if(ssl_env_values[i]) {
                  num_of_vars++;
              }
          }
          if(num_of_vars) {
              unsigned j;
  
              s->attributes_names = 
                  jk_pool_alloc(&private_data->p, num_of_vars * sizeof(char *));
              s->attributes_values = 
                  jk_pool_alloc(&private_data->p, num_of_vars * sizeof(char *));
  
              j = 0;
              for(i = 0 ; i < 9 ; i++) {                
                  if(ssl_env_values[i]) {
                      s->attributes_names[j] = ssl_env_names[i];
                      s->attributes_values[j] = ssl_env_values[i];
                      j++;
                  }
              }
              s->num_attributes = num_of_vars;
          }
      }
  
      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_");
              
              cnt -= 2; /* For our two special headers */
              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 ; ) {
                  int real_header = JK_TRUE;
  
                  /* Skipp the HTTP_ prefix to the beginning of th header name */
                  tmp += len_of_http_prefix;
  
                  if(!strnicmp(tmp, URI_HEADER_NAME, strlen(URI_HEADER_NAME)) ||
                     !strnicmp(tmp, WORKER_HEADER_NAME, strlen(WORKER_HEADER_NAME))) {
                      real_header = JK_FALSE;
                  } else {
                      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++;
                  }
  
                  if(real_header) {
                      s->headers_values[i]  = tmp;
                  }
                  
                  while(*tmp != '\n' && *tmp != '\r') {
                      tmp++;
                  }
                  *tmp = '\0';
                  tmp++;
  
                  /* skipp CR LF */
                  while(*tmp == '\n' || *tmp == '\r') {
                      tmp++;
                  }
  
                  if(real_header) {
                      i++;
                  }
              }
              s->num_headers = cnt;
          } else {
              /* We must have our two headers */
              return JK_FALSE;
          }
      } else {
          return JK_FALSE;
      }
      
      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;
  }
  
  

Mime
View raw message