tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From na...@apache.org
Subject cvs commit: jakarta-tomcat-connectors/jk/native2/server/isapi iis.h isapi.dsp jk2_isapi_plugin.c jk_service_iis.c
Date Thu, 18 Apr 2002 15:03:32 GMT
nacho       02/04/18 08:03:32

  Added:       jk/native2/server/isapi iis.h isapi.dsp jk2_isapi_plugin.c
                        jk_service_iis.c
  Log:
  * Initial commit for jk2 isapi plugin, mostly broken and doesnt compile.
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat-connectors/jk/native2/server/isapi/iis.h
  
  Index: iis.h
  ===================================================================
  //static jk_worker_env_t worker_env;
  #define _WIN32_WINNT 0x0400
  
  #include <httpext.h>
  #include <httpfilt.h>
  #include <wininet.h>
  
  #include "jk_global.h"
  //#include "jk_util.h"
  #include "jk_pool.h"
  
  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_env_t *env, jk_ws_service_t *s );
  
  static int JK_METHOD read(jk_env_t *env, jk_ws_service_t *s,
                            void *b, unsigned len,
                            unsigned *actually_read);
  
  static int JK_METHOD write(jk_env_t *env,jk_ws_service_t *s,
                             const void *b,
                             unsigned l);
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/isapi/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 "Release"
  # PROP BASE Intermediate_Dir "Release"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 0
  # PROP Output_Dir "Release"
  # PROP Intermediate_Dir "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 /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 0xc0a /d "NDEBUG"
  # ADD RSC /l 0xc0a /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 libapr.lib libaprutil.lib kernel32.lib user32.lib advapi32.lib wsock32.lib /nologo /dll /machine:I386 /out:"Release/isapi_redirector2.dll"
  
  !ELSEIF  "$(CFG)" == "isapi - Win32 Debug"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 1
  # PROP BASE Output_Dir "Debug"
  # PROP BASE Intermediate_Dir "Debug"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 1
  # PROP Output_Dir "Debug"
  # PROP Intermediate_Dir "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 "..\..\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "$(APACHE20_HOME)\include" /I "$(APR_HOME)\apr\include" /I "$(APR_HOME)\apr-util\include" /I "$(APACHE20_HOME)\os\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /FR /YX /FD /GZ /c
  # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
  # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
  # ADD BASE RSC /l 0xc0a /d "_DEBUG"
  # ADD RSC /l 0xc0a /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 libapr.lib libaprutil.lib kernel32.lib user32.lib advapi32.lib wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/isapi_redirector2.dll" /pdbtype:sept /libpath:"$(APACHE20_HOME)\Release" /libpath:"$(APR_HOME)\apr\Release" /libpath:"$(APR_HOME)\apr-util\Release"
  
  !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=..\..\common\jk_channel_apr_socket.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_channel_socket.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_config.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_endpoint.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_env.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_handler_logon.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_handler_response.c
  # End Source File
  # Begin Source File
  
  SOURCE=.\jk_isapi_plugin.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_logger_file.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_map.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_md5.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_msg_ajp.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_nwmain.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_objCache.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_pool.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_pool_apr.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_registry.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_registry.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_requtil.c
  # End Source File
  # Begin Source File
  
  SOURCE=.\jk_service_iis.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_shm.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_uriEnv.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_uriMap.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_vm_default.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_ajp13.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_jni.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_lb.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_run.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_status.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_workerEnv.c
  # End Source File
  # End Group
  # Begin Group "Header Files"
  
  # PROP Default_Filter "h;hpp;hxx;hm;inl"
  # Begin Source File
  
  SOURCE=.\iis.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_channel.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_config.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_endpoint.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_env.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_global.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_handler.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_logger.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_map.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_md5.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_msg.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_mt.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_objCache.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_pool.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_requtil.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_service.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_shm.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_uriEnv.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_uriMap.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_vm.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_workerEnv.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-connectors/jk/native2/server/isapi/jk2_isapi_plugin.c
  
  Index: jk2_isapi_plugin.c
  ===================================================================
  /* ========================================================================= *
   *                                                                           *
   *                 The Apache Software License,  Version 1.1                 *
   *                                                                           *
   *          Copyright (c) 1999-2001 The Apache Software Foundation.          *
   *                           All rights reserved.                            *
   *                                                                           *
   * ========================================================================= *
   *                                                                           *
   * Redistribution and use in source and binary forms,  with or without modi- *
   * fication, are permitted provided that the following conditions are met:   *
   *                                                                           *
   * 1. Redistributions of source code  must retain the above copyright notice *
   *    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. The end-user documentation  included with the redistribution,  if any, *
   *    must include the following acknowlegement:                             *
   *                                                                           *
   *       "This product includes  software developed  by the Apache  Software *
   *        Foundation <http://www.apache.org/>."                              *
   *                                                                           *
   *    Alternately, this acknowlegement may appear in the software itself, if *
   *    and wherever such third-party acknowlegements normally appear.         *
   *                                                                           *
   * 4. The names  "The  Jakarta  Project",  "Jk",  and  "Apache  Software     *
   *    Foundation"  must not be used  to endorse or promote  products derived *
   *    from this  software without  prior  written  permission.  For  written *
   *    permission, please contact <apache@apache.org>.                        *
   *                                                                           *
   * 5. Products derived from this software may not be called "Apache" nor may *
   *    "Apache" appear in their names without prior written permission of the *
   *    Apache Software Foundation.                                            *
   *                                                                           *
   * THIS SOFTWARE IS PROVIDED "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 APACHE  SOFTWARE  FOUNDATION 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 indivi- *
   * duals on behalf of the  Apache Software Foundation.  For more information *
   * on the Apache Software Foundation, please see <http://www.apache.org/>.   *
   *                                                                           *
   * ========================================================================= */
  
  /***************************************************************************
   * Description: Apache 2 plugin for Jakarta/Tomcat                         *
   * Author:      Gal Shachor <shachor@il.ibm.com>                           *
   *                 Henri Gomez <hgomez@slib.fr>                               *
   * Version:     $Revision: 1.1 $                                           *
   ***************************************************************************/
  
  /*
   * mod_jk: keeps all servlet/jakarta related ramblings together.
   */
  #include "apu_compat.h"
  #include "ap_config.h"
  #include "apr_lib.h"
  #include "apr_date.h"
  #include "apr_strings.h"
  
  #include "httpd.h"
  #include "http_config.h"
  #include "http_request.h"
  #include "http_core.h"
  #include "http_protocol.h"
  #include "http_main.h"
  #include "http_log.h"
  
  #include "util_script.h"
  
  /*
   * Jakarta (jk_) include files
   */
  #include "jk_global.h"
  #include "jk_map.h"
  #include "jk_pool.h"
  #include "jk_env.h"
  #include "jk_service.h"
  #include "jk_worker.h"
  #include "jk_workerEnv.h"
  #include "jk_uriMap.h"
  #include "jk_requtil.h"
  
  #include "jk_apache2.h"
  
  #define JK_HANDLER          ("jakarta-servlet2")
  #define JK_MAGIC_TYPE       ("application/x-jakarta-servlet2")
  
  module AP_MODULE_DECLARE_DATA jk2_module;
  
  /* In apache1.3 this is reset when the module is reloaded ( after
   * config. No good way to discover if it's the first time or not.
   */
  static jk_workerEnv_t *workerEnv;
  
  
  /* ==================== Options setters ==================== */
  
  /*
   * The JK2 module command processors. The options can be specified
   * in a properties file or in httpd.conf, depending on user's taste.
   *
   * There is absolutely no difference from the point of view of jk,
   * but apache config tools might prefer httpd.conf and the extra
   * information included in the command descriptor. It also have
   * a 'natural' feel, and is consistent with all other apache
   * settings and modules. 
   *
   * Properties file are easier to parse/generate from java, and
   * allow identical configuration for all servers. We should have
   * code to generate the properties file or use the wire protocol,
   * and make all those properties part of server.xml or jk's
   * java-side configuration. This will give a 'natural' feel for
   * those comfortable with the java side.
   *
   * The only exception is webapp definition, where in the near
   * future you can expect a scalability difference between the
   * 2 choices. If you have a large number of apps/vhosts you
   * _should_ use the apache style, that makes use of the
   * internal apache mapper ( known to scale to very large number
   * of hosts ). The internal jk mapper uses linear search, ( will
   * eventually use hash tables, when we add support for apr_hash ),
   * and is nowhere near the apache mapper.
   */
  
  /*
   * JkSet name value
   *
   * Set jk options. Same as using workers.properties.
   * Common properties: see workers.properties documentation
   */
  static const char *jk2_set2(cmd_parms *cmd,void *per_dir,
                              const char *name,  char *value)
  {
      server_rec *s = cmd->server;
      jk_uriEnv_t *serverEnv=(jk_uriEnv_t *)
          ap_get_module_config(s->module_config, &jk2_module);
      jk_env_t *env=workerEnv->globalEnv;
      int rc;
      
      rc=workerEnv->config->setPropertyString( env, workerEnv->config, name, value );
      if( rc!=JK_TRUE ) {
          fprintf( stderr, "mod_jk2: Unrecognized option %s %s\n", name, value);
      }
  
      return NULL;
  }
  
  /**
   * Set a property associated with a URI, using native <Location> 
   * directives.
   *
   * This is used if you want to use the native mapping and
   * integrate better into apache.
   *
   * Same behavior can be achieved by using uri.properties and/or JkSet.
   * 
   * Example:
   *   <VirtualHost foo.com>
   *      <Location /examples>
   *         JkUriSet worker ajp13
   *      </Location>
   *   </VirtualHost>
   *
   * This is the best way to define a webapplication in apache. It is
   * scalable ( using apache native optimizations, you can have hundreds
   * of hosts and thousands of webapplications ), 'natural' to any
   * apache user.
   *
   * XXX This is a special configuration, for most users just use
   * the properties files.
   */
  static const char *jk2_uriSet(cmd_parms *cmd, void *per_dir, 
                                const char *name, const char *val)
  {
      jk_uriEnv_t *uriEnv=(jk_uriEnv_t *)per_dir;
  
      uriEnv->mbean->setAttribute( workerEnv->globalEnv, uriEnv->mbean, name, val );
      
      fprintf(stderr, "JkUriSet  %s %s dir=%s args=%s\n",
              uriEnv->workerName, cmd->path,
              cmd->directive->directive,
              cmd->directive->args);
  
      return NULL;
  }
  
  /* Command table.
   */
  static const command_rec jk2_cmds[] =
      {
          /* This is the 'main' directive for tunning jk2. It takes 2 parameters,
             and it behaves _identically_ as a setting in workers.properties.
          */
      AP_INIT_TAKE2(
          "JkSet", jk2_set2, NULL, RSRC_CONF,
          "Set a jk property, same syntax and rules as in JkWorkersFile"),
      AP_INIT_TAKE2(
          "JkUriSet", jk2_uriSet, NULL, ACCESS_CONF,
          "Defines a jk property associated with a Location"),
      NULL
      };
  
  static void *jk2_create_dir_config(apr_pool_t *p, char *path)
  {
      /* We don't know the vhost yet - so path is not
       * unique. We'll have to generate a unique name
       */
      jk_bean_t *jkb=workerEnv->globalEnv->createBean2( workerEnv->globalEnv,
                                                        workerEnv->pool, "uri", path );
      jk_uriEnv_t *newUri = jkb->object;
      newUri->workerEnv=workerEnv;
      newUri->mbean->setAttribute( workerEnv->globalEnv, newUri->mbean, "path", path );
      return newUri;
  }
  
  
  static void *jk2_merge_dir_config(apr_pool_t *p, void *basev, void *addv)
  {
      jk_uriEnv_t *base =(jk_uriEnv_t *)basev;
      jk_uriEnv_t *add = (jk_uriEnv_t *)addv; 
      jk_uriEnv_t *new = (jk_uriEnv_t *)apr_pcalloc(p,sizeof(jk_uriEnv_t));
      
      
      /* XXX */
      fprintf(stderr, "XXX Merged dir config %p %p %s %s %p %p\n",
              base, new, base->uri, add->uri, base->webapp, add->webapp);
  
      if( add->webapp == NULL ) {
          add->webapp=base->webapp;
      }
      
      return add;
  }
  
  /** Basic initialization for jk2.
   */
  static void jk2_create_workerEnv(apr_pool_t *p, server_rec *s) {
      jk_env_t *env;
      jk_logger_t *l;
      jk_pool_t *globalPool;
      jk_bean_t *jkb;
      
      /** First create a pool. Compile time option
       */
  #ifdef NO_APACHE_POOL
      jk2_pool_create( NULL, &globalPool, NULL, 2048 );
  #else
      jk2_pool_apr_create( NULL, &globalPool, NULL, p );
  #endif
  
      /** Create the global environment. This will register the default
          factories
      */
      env=jk2_env_getEnv( NULL, globalPool );
  
      /* Optional. Register more factories ( or replace existing ones ) */
      /* Init the environment. */
      
      /* Create the logger */
  #ifdef NO_APACHE_LOGGER
      jkb=env->createBean2( env, env->globalPool, "logger.file", "");
      env->alias( env, "logger.file:", "logger");
      l = jkb->object;
  #else
      env->registerFactory( env, "logger.apache2",    jk2_logger_apache2_factory );
      jkb=env->createBean2( env, env->globalPool, "logger.apache2", "");
      env->alias( env, "logger.apache2:", "logger");
      l = jkb->object;
      l->logger_private=s;
  #endif
      
      env->l=l;
      
      /* We should make it relative to JK_HOME or absolute path.
         ap_server_root_relative(cmd->pool,opt); */
      
      /* Create the workerEnv */
      jkb=env->createBean2( env, env->globalPool,"workerEnv", "");
      workerEnv= jkb->object;
      env->alias( env, "workerEnv:" , "workerEnv");
      
      if( workerEnv==NULL ) {
          env->l->jkLog(env, env->l, JK_LOG_ERROR, "Error creating workerEnv\n");
          return;
      }
  
      workerEnv->initData->add( env, workerEnv->initData, "serverRoot",
                                workerEnv->pool->pstrdup( env, workerEnv->pool, ap_server_root));
      env->l->jkLog(env, env->l, JK_LOG_ERROR, "Set serverRoot %s\n", ap_server_root);
      
      /* Local initialization */
      workerEnv->_private = s;
  }
  
  /** Create default jk_config. XXX This is mostly server-independent,
      all servers are using something similar - should go to common.
  
      This is the first thing called ( or should be )
   */
  static void *jk2_create_config(apr_pool_t *p, server_rec *s)
  {
      jk_uriEnv_t *newUri;
      jk_bean_t *jkb;
  
      if(  workerEnv==NULL ) {
          jk2_create_workerEnv(p, s );
      }
      if( s->is_virtual == 1 ) {
          /* Virtual host */
          fprintf( stderr, "Create config for virtual host\n");
      } else {
          /* Default host */
          fprintf( stderr, "Create config for main host\n");        
      }
  
      jkb = workerEnv->globalEnv->createBean2( workerEnv->globalEnv,
                                               workerEnv->pool,
                                               "uri", NULL );
     newUri=jkb->object;
     
     newUri->workerEnv=workerEnv;
      
     return newUri;
  }
  
  
  
  /** Standard apache callback, merge jk options specified in 
      <Host> context. Used to set per virtual host configs
   */
  static void *jk2_merge_config(apr_pool_t *p, 
                                void *basev, 
                                void *overridesv)
  {
      jk_uriEnv_t *base = (jk_uriEnv_t *) basev;
      jk_uriEnv_t *overrides = (jk_uriEnv_t *)overridesv;
      
      fprintf(stderr,  "Merging workerEnv \n" );
      
      /* The 'mountcopy' option should be implemented in common.
       */
      return overrides;
  }
  
  
  /** Standard apache callback, initialize jk.
   */
  static void jk2_child_init(apr_pool_t *pconf, 
                             server_rec *s)
  {
      jk_uriEnv_t *serverEnv=(jk_uriEnv_t *)
          ap_get_module_config(s->module_config, &jk2_module);
      jk_env_t *env;
          
      if( workerEnv==NULL )
          workerEnv = serverEnv->workerEnv;
  
      env=workerEnv->globalEnv;
  
      env->l->jkLog(env, env->l, JK_LOG_INFO, "mod_jk child init\n" );
      
      /* jk2_init( pconf, conf, s );
         do we need jk2_child_init? For ajp14? */
  }
  
  /** Initialize jk, using worker.properties. 
      We also use apache commands ( JkWorker, etc), but this use is 
      deprecated, as we'll try to concentrate all config in
      workers.properties, urimap.properties, and ajp14 autoconf.
      
      Apache config will only be used for manual override, using 
      SetHandler and normal apache directives ( but minimal jk-specific
      stuff )
  */
  static char * jk2_init(jk_env_t *env, apr_pool_t *pconf,
                         jk_workerEnv_t *workerEnv, server_rec *s )
  {
      workerEnv->init(env, workerEnv );
      workerEnv->server_name   = (char *)ap_get_server_version();
      ap_add_version_component(pconf, JK_EXPOSED_VERSION);
      return NULL;
  }
  
  /* Apache will first validate the config then restart.
     That will unload all .so modules - including ourself.
     Keeping 'was_initialized' in workerEnv is pointless, since both
     will disapear.
  */
  static int jk2_apache2_isValidating(apr_pool_t *gPool, apr_pool_t **mainPool) {
      apr_pool_t *tmpPool=NULL;
      void *data=NULL;
      int i;
      
      for( i=0; i<10; i++ ) {
          tmpPool=apr_pool_get_parent( gPool );
          if( tmpPool == NULL ) {
              break;
          }
          gPool=tmpPool;
      }
  
      if( tmpPool == NULL ) {
          /* We can't detect the root pool */
          return JK_FALSE;
      }
      if(mainPool != NULL )
          *mainPool=gPool;
      
      /* We have a global pool ! */
      apr_pool_userdata_get( &data, "mod_jk_init", gPool );
      if( data==NULL ) {
          return JK_TRUE;
      } else {
          return JK_FALSE;
      }
  }
  
  static int jk2_post_config(apr_pool_t *pconf, 
                             apr_pool_t *plog, 
                             apr_pool_t *ptemp, 
                             server_rec *s)
  {
      apr_pool_t *gPool=NULL;
      void *data=NULL;
      int rc;
      jk_env_t *env;
      
      if(s->is_virtual) 
          return OK;
  
      env=workerEnv->globalEnv;
      
      rc=jk2_apache2_isValidating( plog, &gPool );
  
      if( rc == JK_TRUE ) {
          /* This is the first step */
          env->l->jkLog(env, env->l, JK_LOG_INFO,
                        "mod_jk.post_config() first invocation\n");
          apr_pool_userdata_set( "INITOK", "mod_jk_init", NULL, gPool );
          return OK;
      }
          
      env->l->jkLog(env, env->l, JK_LOG_INFO,
                    "mod_jk.post_config() second invocation\n" ); 
      
      if(!workerEnv->was_initialized) {
          workerEnv->was_initialized = JK_TRUE;        
          jk2_init( env, pconf, workerEnv, s );
      }
      return OK;
  }
  
  /* ========================================================================= */
  /* The JK module handlers                                                    */
  /* ========================================================================= */
  
  /** Main service method, called to forward a request to tomcat
   */
  static int jk2_handler(request_rec *r)
  {   
      const char       *worker_name;
      jk_logger_t      *l=NULL;
      int              rc;
      jk_worker_t *worker=NULL;
      jk_endpoint_t *end = NULL;
      jk_uriEnv_t *uriEnv;
      jk_uriEnv_t *dirEnv;
      jk_env_t *env;
      jk_workerEnv_t *workerEnv;
  
      uriEnv=ap_get_module_config( r->request_config, &jk2_module );
  
      /* not for me, try next handler */
      if(uriEnv==NULL || strcmp(r->handler,JK_HANDLER)!= 0 )
        return DECLINED;
      
      /* If this is a proxy request, we'll notify an error */
      if(r->proxyreq) {
          return HTTP_INTERNAL_SERVER_ERROR;
      }
  
      workerEnv = uriEnv->workerEnv;
  
      /* Get an env instance */
      env = workerEnv->globalEnv->getEnv( workerEnv->globalEnv );
  
      /* Set up r->read_chunked flags for chunked encoding, if present */
      if(rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) {
          env->l->jkLog(env, env->l, JK_LOG_INFO,
                        "mod_jk.handler() Can't setup client block %d\n", rc);
          workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
          return rc;
      }
  
      if( uriEnv == NULL ) {
          /* SetHandler case - per_dir config should have the worker*/
          worker =  workerEnv->defaultWorker;
          env->l->jkLog(env, env->l, JK_LOG_INFO, 
                        "mod_jk.handler() Default worker for %s %s\n",
                        r->uri, worker->mbean->name); 
      } else {
          worker=uriEnv->worker;
          env->l->jkLog(env, env->l, JK_LOG_INFO, 
                        "mod_jk.handler() per dir worker for %p %p\n",
                        worker, uriEnv->webapp );
          
          if( worker==NULL && uriEnv->workerName != NULL ) {
               worker=env->getByName( env, uriEnv->workerName);
              env->l->jkLog(env, env->l, JK_LOG_INFO, 
                            "mod_jk.handler() finding worker for %p %p\n",
                            worker, uriEnv );
              uriEnv->worker=worker;
          }
      }
  
      if(worker==NULL ) {
          env->l->jkLog(env, env->l, JK_LOG_ERROR, 
                        "mod_jk.handle() No worker for %s\n", r->uri); 
          workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
          return 500;
      }
  
      {
          jk_ws_service_t sOnStack;
          jk_ws_service_t *s=&sOnStack;
          jk_pool_t *rPool=NULL;
          int rc1;
  
          /* Get a pool for the request XXX move it in workerEnv to
             be shared with other server adapters */
          rPool= worker->rPoolCache->get( env, worker->rPoolCache );
          if( rPool == NULL ) {
              rPool=worker->pool->create( env, worker->pool, HUGE_POOL_SIZE );
              env->l->jkLog(env, env->l, JK_LOG_INFO,
                            "mod_jk.handler(): new rpool\n");
          }
  
          /* XXX we should reuse the request itself !!! */
          jk2_service_apache2_init( env, s );
  
          s->pool = rPool;
          
          s->is_recoverable_error = JK_FALSE;
          s->init( env, s, worker, r );
  
          env->l->jkLog(env, env->l, JK_LOG_INFO, 
                        "modjk.handler() Calling %s\n", worker->mbean->name); 
          rc = worker->service(env, worker, s);
  
          s->afterRequest(env, s);
  
          rPool->reset(env, rPool);
          
          rc1=worker->rPoolCache->put( env, worker->rPoolCache, rPool );
          if( rc1 == JK_TRUE ) {
              rPool=NULL;
          }
          if( rPool!=NULL ) {
              rPool->close(env, rPool);
          }
      }
  
      if(rc==JK_TRUE) {
          workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
          return OK;    /* NOT r->status, even if it has changed. */
      }
  
      env->l->jkLog(env, env->l, JK_LOG_ERROR,
                    "mod_jk.handler() Error connecting to tomcat %d\n", rc);
      workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
      return 500;
  }
  
  /** Use the internal mod_jk mappings to find if this is a request for
   *    tomcat and what worker to use. 
   */
  static int jk2_translate(request_rec *r)
  {
      jk_workerEnv_t *workerEnv;
      jk_uriEnv_t *uriEnv;
      jk_env_t *env;
              
      if(r->proxyreq) {
          return DECLINED;
      }
      
      uriEnv=ap_get_module_config( r->per_dir_config, &jk2_module );
      workerEnv=uriEnv->workerEnv;
      
      /* get_env() */
      env = workerEnv->globalEnv->getEnv( workerEnv->globalEnv );
          
      /* This has been mapped to a location by apache
       * In a previous ( experimental ) version we had a sub-map,
       * but that's too complex for now.
       */
      if( uriEnv!= NULL && uriEnv->workerName != NULL) {
          env->l->jkLog(env, env->l, JK_LOG_INFO, 
                        "PerDir mapping  %s=%s\n",
                        r->uri, uriEnv->workerName);
          
          ap_set_module_config( r->request_config, &jk2_module, uriEnv );        
          r->handler=JK_HANDLER;
          workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
          return OK;
      }
  
      /* One idea was to use "SetHandler jakarta-servlet". This doesn't
         allow the setting of the worker. Having a specific SetWorker directive
         at location level is more powerfull. If anyone can figure any reson
         to support SetHandler, we can add it back easily */
  
      /* Check JkMount directives, if any */
      if( workerEnv->uriMap->size == 0 ) {
          workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
          return DECLINED;
      }
      
      /* XXX TODO: Split mapping, similar with tomcat. First step will
         be a quick test ( the context mapper ), with no allocations.
         If positive, we'll fill a ws_service_t and do the rewrite and
         the real mapping. 
      */
      uriEnv = workerEnv->uriMap->mapUri(env, workerEnv->uriMap,NULL,r->uri );
  
      if( uriEnv== NULL || uriEnv->workerName == NULL) {
          workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
          return DECLINED;
      }
  
      ap_set_module_config( r->request_config, &jk2_module, uriEnv );
      r->handler=JK_HANDLER;
  
      env->l->jkLog(env, env->l, JK_LOG_INFO, 
                    "mod_jk.translate(): uriMap %s %s\n",
                    r->uri, uriEnv->workerName);
  
      workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env );
      return OK;
  }
  
  /* XXX Can we use type checker step to set our stuff ? */
  
  /* bypass the directory_walk and file_walk for non-file requests */
  static int jk2_map_to_storage(request_rec *r)
  {
      jk_uriEnv_t *uriEnv=ap_get_module_config( r->request_config, &jk2_module );
      
      if( uriEnv != NULL ) {
          r->filename = (char *)apr_filename_of_pathname(r->uri);
          if( uriEnv->debug > 0 ) {
              /*   env->l->jkLog(env, env->l, JK_LOG_INFO,  */
              /*     "mod_jk.map_to_storage(): map %s %s\n", */
              /*                  r->uri, r->filename); */
          }
          return OK;
      }
      return DECLINED;
  }
  
  static void jk2_register_hooks(apr_pool_t *p)
  {
      ap_hook_handler(jk2_handler, NULL, NULL, APR_HOOK_MIDDLE);
      ap_hook_post_config(jk2_post_config,NULL,NULL,APR_HOOK_MIDDLE);
      ap_hook_child_init(jk2_child_init,NULL,NULL,APR_HOOK_MIDDLE);
      ap_hook_translate_name(jk2_translate,NULL,NULL,APR_HOOK_FIRST);
      ap_hook_map_to_storage(jk2_map_to_storage, NULL, NULL, APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA jk2_module =
  {
      STANDARD20_MODULE_STUFF,
      jk2_create_dir_config, /*  dir config creater */
      jk2_merge_dir_config,  /* dir merger --- default is to override */
      jk2_create_config,     /* server config */
      jk2_merge_config,      /* merge server config */
      jk2_cmds,              /* command ap_table_t */
      jk2_register_hooks     /* register hooks */
  };
  
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/isapi/jk_service_iis.c
  
  Index: jk_service_iis.c
  ===================================================================
  /* ========================================================================= *
   *                                                                           *
   *                 The Apache Software License,  Version 1.1                 *
   *                                                                           *
   *          Copyright (c) 1999-2001 The Apache Software Foundation.          *
   *                           All rights reserved.                            *
   *                                                                           *
   * ========================================================================= *
   *                                                                           *
   * Redistribution and use in source and binary forms,  with or without modi- *
   * fication, are permitted provided that the following conditions are met:   *
   *                                                                           *
   * 1. Redistributions of source code  must retain the above copyright notice *
   *    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. The end-user documentation  included with the redistribution,  if any, *
   *    must include the following acknowlegement:                             *
   *                                                                           *
   *       "This product includes  software developed  by the Apache  Software *
   *        Foundation <http://www.apache.org/>."                              *
   *                                                                           *
   *    Alternately, this acknowlegement may appear in the software itself, if *
   *    and wherever such third-party acknowlegements normally appear.         *
   *                                                                           *
   * 4. The names  "The  Jakarta  Project",  "Jk",  and  "Apache  Software     *
   *    Foundation"  must not be used  to endorse or promote  products derived *
   *    from this  software without  prior  written  permission.  For  written *
   *    permission, please contact <apache@apache.org>.                        *
   *                                                                           *
   * 5. Products derived from this software may not be called "Apache" nor may *
   *    "Apache" appear in their names without prior written permission of the *
   *    Apache Software Foundation.                                            *
   *                                                                           *
   * THIS SOFTWARE IS PROVIDED "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 APACHE  SOFTWARE  FOUNDATION 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 indivi- *
   * duals on behalf of the  Apache Software Foundation.  For more information *
   * on the Apache Software Foundation, please see <http://www.apache.org/>.   *
   *                                                                           *
   * ========================================================================= */
  
  /**
   * Description: IIS Jk2 Service 
   * Author:      Gal Shachor <shachor@il.ibm.com>                           
   *              Henri Gomez <hgomez@slib.fr> 
   *				Ignacio J. Ortega <nacho@apache.org>
   * Version:     $Revision: 1.1 $                                           
   */
  
  // This define is needed to include wincrypt,h, needed to get client certificates
  #define _WIN32_WINNT 0x0400
  
  #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_env.h"
  #include "jk_service.h"
  #include "jk_worker.h"
  
  #include "iis.h"
  //#include "jk_uri_worker_map.h"
  
  #define jk_log(a,b,c)
  
  
  static void write_error_response(PHTTP_FILTER_CONTEXT pfc,char *status,char * msg)
  {
      char crlf[3] = { (char)13, (char)10, '\0' };
      char ctype[30];
      DWORD len = strlen(msg);
  
      sprintf(ctype, 
              "Content-Type:text/html%s%s", 
              crlf, 
              crlf);
  
      /* reject !!! */
      pfc->ServerSupportFunction(pfc, 
                                 SF_REQ_SEND_RESPONSE_HEADER,
                                 status,
                                 (DWORD)crlf,
                                 (DWORD)ctype);
      pfc->WriteClient(pfc, msg, &len, 0);
  }
  
  static int JK_METHOD jk2_service_iis_head(jk_env_t *env, jk_ws_service_t *s ){
      static char crlf[3] = { (char)13, (char)10, '\0' };
  	char *reason;
      env->l->jkLog(env,env->l, JK_LOG_DEBUG, 
             "Into jk_ws_service_t::start_response\n");
  
      if (s->status< 100 || s->status > 1000) {
          env->l->jkLog(env,env->l, JK_LOG_ERROR, 
                 "jk_ws_service_t::start_response, invalid status %d\n", s->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 (!s->msg) {
                  reason = "";
              } else {
  				reason = s->msg;
  			}
              status_str = (char *)_alloca((6 + strlen(reason)) * sizeof(char));
              sprintf(status_str, "%d %s", s->status, reason);
              len_of_status = strlen(status_str); 
          
              /*
               * Create response headers string
               */
              if (s->headers_out->size) {
                  int i;
                  unsigned len_of_headers;
                  for(i = 0 , len_of_headers = 0 ; i < s->headers_out->size(env,s->headers_out) ; i++) {
                      len_of_headers += strlen(s->headers_out->nameAt(env,s->headers_out,i));
                      len_of_headers += strlen(s->headers_out->valueAt(env,s->headers_out,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 < s->headers_out->size(env,s->headers_out) ; i++) {
                      strcat(headers_str, s->headers_out->nameAt(env,s->headers_out,i));
                      strcat(headers_str, ": ");
                      strcat(headers_str, s->headers_out->valueAt(env,s->headers_out,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 jk2_service_iis_read(jk_env_t *env, 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 jk2_service_iis_write(jk_env_t *env,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(env, s );
              }
  
              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;
  }
  
  
  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->head = 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);     
      GET_SERVER_VARIABLE_VALUE(HTTP_QUERY_HEADER_NAME, s->query_string);     
  
      if (s->req_uri == NULL) {
          s->query_string = private_data->lpEcb->lpszQueryString;
          *worker_name    = DEFAULT_WORKER_NAME;
          GET_SERVER_VARIABLE_VALUE("URL", s->req_uri);       
          if (unescape_url(s->req_uri) < 0)
              return JK_FALSE;
          getparents(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->ssl_key_size = -1;
  
      s->headers_in  = 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=NULL;
  				_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;
   			if (ssl_env_values[4] && ssl_env_values[4][0] == '1') {
  				CERT_CONTEXT_EX cc;
  				DWORD cc_sz = sizeof(cc);
  				cc.cbAllocated = sizeof(huge_buf);
  				cc.CertContext.pbCertEncoded = (BYTE*) huge_buf;
  				cc.CertContext.cbCertEncoded = 0;
  
  				if (private_data->lpEcb->ServerSupportFunction(private_data->lpEcb->ConnID,
  											 (DWORD)HSE_REQ_GET_CERT_INFO_EX,                               
  											 (LPVOID)&cc,NULL,NULL) != FALSE)
  				{
  					jk_log(logger, JK_LOG_DEBUG,"Client Certificate encoding:%d sz:%d flags:%ld\n",
  								cc.CertContext.dwCertEncodingType & X509_ASN_ENCODING ,
  								cc.CertContext.cbCertEncoded,
  								cc.dwCertificateFlags);
                      s->ssl_cert=jk_pool_alloc(&private_data->p,
                                  base64_encode_cert_len(cc.CertContext.cbCertEncoded));
  
                      s->ssl_cert_len = base64_encode_cert(s->ssl_cert,
                                  huge_buf,cc.CertContext.cbCertEncoded) - 1;
  				}
  			}
          }
      }
  
  */
  	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_");
              BOOL need_content_length_header = (s->content_length == 0);
              
              cnt -= 2; /* For our two special headers */
              /* 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) {
                  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 if(need_content_length_header &&
                     !strnicmp(tmp, CONTENT_LENGTH, strlen(CONTENT_LENGTH))) {
                      need_content_length_header = FALSE;
                      s->headers_names[i]  = tmp;
                  } else if (!strnicmp(tmp, TOMCAT_TRANSLATE_HEADER_NAME,
                                            strlen(TOMCAT_TRANSLATE_HEADER_NAME))) {
                      tmp += 6; /* TOMCAT */
                      s->headers_names[i]  = tmp;
                  } else {
                      s->headers_names[i]  = tmp;
                  }
  
                  while(':' != *tmp && *tmp) {
                      if ('_' == *tmp) {
                          *tmp = '-';
                      } else {
                          *tmp = tolower(*tmp);
                      }
                      tmp++;
                  }
                  *tmp = '\0';
                  tmp++;
  
                  /* Skip 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++;
                  }
              }
              /* 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) {
                  s->headers_names[cnt] = "content-length";
                  s->headers_values[cnt] = "0";
                  cnt++;
              }
              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;
  }
  
  static const char begin_cert [] = 
  	"-----BEGIN CERTIFICATE-----\r\n";
  
  static const char end_cert [] = 
  	"-----END CERTIFICATE-----\r\n";
  
  static const char basis_64[] =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  
  static int base64_encode_cert_len(int len)
  {
  	int n = ((len + 2) / 3 * 4) + 1; // base64 encoded size
  	n += (n + 63 / 64) * 2; // add CRLF's
  	n += sizeof(begin_cert) + sizeof(end_cert) - 2;  // add enclosing strings.
      return n;
  }
  
  static int base64_encode_cert(char *encoded,
                                const unsigned char *string, int len)
  {
      int i,c;
      char *p;
  	const char *t;
  
      p = encoded;
  
  	t = begin_cert;
  	while (*t != '\0')
  		*p++ = *t++;
  
      c = 0;
      for (i = 0; i < len - 2; i += 3) {
          *p++ = basis_64[(string[i] >> 2) & 0x3F];
          *p++ = basis_64[((string[i] & 0x3) << 4) |
                          ((int) (string[i + 1] & 0xF0) >> 4)];
          *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
                          ((int) (string[i + 2] & 0xC0) >> 6)];
          *p++ = basis_64[string[i + 2] & 0x3F];
          c += 4;
          if ( c >= 64 ) {
              *p++ = '\r';
              *p++ = '\n';
              c = 0;
  		}
      }
      if (i < len) {
          *p++ = basis_64[(string[i] >> 2) & 0x3F];
          if (i == (len - 1)) {
              *p++ = basis_64[((string[i] & 0x3) << 4)];
              *p++ = '=';
          }
          else {
              *p++ = basis_64[((string[i] & 0x3) << 4) |
                              ((int) (string[i + 1] & 0xF0) >> 4)];
              *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
          }
          *p++ = '=';
          c++;
      }
      if ( c != 0 ) {
          *p++ = '\r';
          *p++ = '\n';
      }
  
  	t = end_cert;
  	while (*t != '\0')
  		*p++ = *t++;
  
      *p++ = '\0';
      return p - encoded;
  }
  
  int jk2_service_iis_init(jk_env_t *env, jk_ws_service_t *s)
  {
      if(s==NULL ) {
          return JK_FALSE;
      }
  
      s->head   = jk2_service_iis_head;
      s->read   = jk2_service_iis_read;
      s->write  = jk2_service_iis_write;
      s->init   = jk2_init_ws_service;
      s->afterRequest     = jk2_service_apache2_afterRequest;
      
      return JK_TRUE;
  }
  
  
  
  

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


Mime
View raw message