|
|
| /*
|
| * Licensed to the Apache Software Foundation (ASF) under one or more
|
| * contributor license agreements. See the NOTICE file distributed with
|
| * this work for additional information regarding copyright ownership.
|
| * The ASF licenses this file to You under the Apache License, Version 2.0
|
| * (the "License"); you may not use this file except in compliance with
|
| * the License. You may obtain a copy of the License at
|
| *
|
| * http://www.apache.org/licenses/LICENSE-2.0
|
| *
|
| * Unless required by applicable law or agreed to in writing, software
|
| * distributed under the License is distributed on an "AS IS" BASIS,
|
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| * See the License for the specific language governing permissions and
|
| * limitations under the License.
|
| */
|
|
|
| #include <windows.h>
|
| #include <stdio.h>
|
| #include <stdlib.h>
|
| #include <string.h>
|
| #include <httpfilt.h>
|
| #include <httpext.h>
|
|
|
| #include "axis2_iis_constants.h"
|
| #include "axis2_iis_worker.h"
|
|
|
| /* Axis headers */ |
| #include <axutil_error_default.h> |
| #include <axutil_log_default.h> |
| #include <axutil_thread_pool.h> |
| #include <axiom_xml_reader.h> |
| #include <axutil_log.h>
|
|
|
| #ifndef _WIN32_WINNT
|
| #define _WIN32_WINNT 0x0500
|
| #endif
|
|
|
| #define AXIS2_IIS_LOG_FILE_TAG "log_file" |
| #define AXIS2_IIS_LOG_LEVEL_TAG "log_level" |
| #define AXIS2_IIS_REPO_PATH_TAG "axis2c_home" |
| #define AXIS2_IIS_EXTENSION_URI_TAG "extension_uri" |
| #define AXIS2_IIS_REDIRECT_WORD_TAG "redirect_uri" |
| #define AXIS2_IIS_AXIS2_LOCATION "axis2_location" |
| #define AXIS2_IIS_SERVICE_URL_PREFIX "services_url_prefix" |
| |
| #define AXIS2_IIS_LOG_TRACE_VERB "trace" |
| #define AXIS2_IIS_LOG_ERROR_VERB "error" |
| #define AXIS2_IIS_LOG_INFO_VERB "info" |
| #define AXIS2_IIS_LOG_USER_VERB "user" |
| #define AXIS2_IIS_LOG_CRITICAL_VERB "critical" |
| #define AXIS2_IIS_LOG_WARN_VERB "warning" |
| #define AXIS2_IIS_LOG_DEBUG_VERB "debug" |
| |
| #define MAX_FILE_PATH 256 |
| #define REGISTRY_LOCATION "Software\\Apache Axis2c\\IIS ISAPI Redirector" |
| |
| static int is_inited = FALSE; |
| static axis2_iis_worker_t *axis2_worker = NULL; |
| static const axutil_env_t *axutil_env = NULL; |
| |
| /* Configuration parameters */ |
| axis2_char_t *axis2_location = "/axis2"; |
| static axis2_char_t *axis2_service_url_prefix= "/services"; |
| static axis2_char_t repo_path[MAX_FILE_PATH]; |
| static axis2_char_t log_file[MAX_FILE_PATH]; |
| static axutil_log_levels_t log_level = AXIS2_LOG_LEVEL_CRITICAL; |
| |
| /* Path variables */ |
| static char szOriginalPath[_MAX_PATH + 1];
|
| static char szPath[_MAX_PATH + 1]; |
| |
| axis2_char_t general_error[] = "<html>\r\n"
|
| "<head><title> An IIS server error occurred. </title></head>\r\n"
|
| "<h1> An IIS server error occurred </h1>\r\n"
|
| "<hr>\r\n"
|
| "An error occurred in IIS while processing this request.</hr></html>"; |
| |
| axis2_char_t initializing_error[] = "<html>\r\n"
|
| "<head><title> An IIS server error occurred. </title></head>\r\n"
|
| "<h1> An IIS server error occurred </h1>\r\n"
|
| "<hr>\r\n"
|
| "An error occurred while initilizing Axis2/C.</hr></html>"; |
| |
| |
| /* |
| * This is a utility functipn for reading configuration data from the registery. |
| */ |
| static axis2_status_t AXIS2_CALL |
| read_registery_init_data(); |
| |
| /* |
| * Utility function for reading |
| */ |
| static axis2_status_t AXIS2_CALL get_registry_config_parameter( |
| HKEY hkey, |
| const char *tag, |
| char *b, |
| DWORD sz); |
| |
| /* |
| * Parse the given string and return the corresponding log_level |
| */ |
| axutil_log_levels_t AXIS2_CALL axis2_iis_parse_log_level(char level[]); |
|
|
| /*
|
| * Initialize axis. This function is called in the begining of the module loading.
|
| * It initializes the axis by reading values from the configuration and creating the
|
| * required structures for the axis2c
|
| */
|
| axis2_status_t AXIS2_CALL init_axis2();
|
|
|
| /*
|
| * This is the function to be called after the processing
|
| * is over for non Axis2 requets
|
| */
|
| VOID
|
| WINAPI
|
| ExecUrlCompletion (
|
| EXTENSION_CONTROL_BLOCK * pecb,
|
| PVOID pContext,
|
| DWORD cbIO,
|
| DWORD dwError
|
| );
|
|
|
| /*
|
| * If somethign went wrong in the IIS server when
|
| * we are proccessing we send this
|
| */
|
| BOOL
|
| send_error(
|
| EXTENSION_CONTROL_BLOCK * pecb,
|
| CHAR error[]);
|
|
|
| axis2_status_t AXIS2_CALL init_axis2();
|
|
|
| BOOL
|
| WINAPI
|
| GetExtensionVersion(HSE_VERSION_INFO * pVer)
|
| {
|
| pVer->dwExtensionVersion = MAKELONG( HSE_VERSION_MINOR,
|
| HSE_VERSION_MAJOR);
|
| strncpy( pVer->lpszExtensionDesc,
|
| "WildCardMap Sample ISAPI Extension", HSE_MAX_EXT_DLL_NAME_LEN );
|
|
|
| pVer->lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN-1] = '\0';
|
| server_version = 5;
|
| return TRUE;
|
| }
|
|
|
| DWORD
|
| WINAPI
|
| HttpExtensionProc(EXTENSION_CONTROL_BLOCK * pecb)
|
|
|
| {
|
| HSE_EXEC_URL_INFO ExecUrlInfo;
|
| DWORD cbData = INTERNET_MAX_URL_LENGTH;
|
| char url[INTERNET_MAX_URL_LENGTH];
|
| axis2_bool_t is_for_us = AXIS2_TRUE;
|
|
|
| /* Get the URL */
|
| if ( pecb->GetServerVariable( pecb->ConnID,
|
| "URL",
|
| url,
|
| &cbData ) == FALSE )
|
| {
|
| return HSE_STATUS_ERROR;
|
| }
|
|
|
| if (!is_inited)
|
| {
|
| DWORD dwBufferSize = 0;
|
| axis2_char_t server_software[256];
|
| axis2_char_t *version = NULL;
|
|
|
| ZeroMemory(szOriginalPath, sizeof szOriginalPath);
|
| dwBufferSize = sizeof szOriginalPath;
|
|
|
| #if _WIN32_WINNT >= 0x0502
|
| GetDllDirectory( dwBufferSize, szOriginalPath );
|
| #else
|
| GetCurrentDirectory( dwBufferSize, szOriginalPath );
|
| #endif
|
| ZeroMemory(szPath, sizeof szPath);
|
| dwBufferSize = sizeof szPath;
|
| /* Get the current physical paht */
|
| if (pecb->GetServerVariable(pecb->ConnID, "APPL_PHYSICAL_PATH", szPath, &dwBufferSize) == FALSE)
|
| {
|
| send_error(pecb, initializing_error);
|
| return HSE_STATUS_ERROR;
|
| }
|
| /* Retrieve the server version */
|
| dwBufferSize = 32;
|
| if (pecb->GetServerVariable(pecb->ConnID, "SERVER_SOFTWARE", server_software, &dwBufferSize) == FALSE)
|
| {
|
| send_error(pecb, initializing_error);
|
| return HSE_STATUS_ERROR;
|
| }
|
| version = axutil_strchr(server_software, '/');
|
| if (version)
|
| {
|
| server_version = atoi(version + 1);
|
| }
|
| #if _WIN32_WINNT >= 0x0502
|
| SetDllDirectory( szPath );
|
| #else
|
| SetCurrentDirectory( szPath );
|
| #endif
|
| /* If we haven't initialized axis2/c before initialization failed */
|
| if (AXIS2_FAILURE == init_axis2())
|
| {
|
| send_error(pecb, initializing_error);
|
| return HSE_STATUS_ERROR;
|
| }
|
| #if _WIN32_WINNT >= 0x0502
|
| SetDllDirectory( szOriginalPath );
|
| #else
|
| SetCurrentDirectory( szOriginalPath );
|
| #endif
|
| }
|
|
|
| /* Check weather we have a request for Axis2/C */
|
| if (server_version >= 6 && strlen(url) >= strlen(axis2_location))
|
| {
|
| int i = 0;
|
| is_for_us = AXIS2_TRUE;
|
| while (axis2_location[i] != '\0')
|
| {
|
| if (axis2_location[i] != (url)[i]) {
|
| is_for_us = AXIS2_FALSE;
|
| break;
|
| }
|
| i++;
|
| }
|
| if (url[i] != '/' && url[i] != '\0')
|
| {
|
| is_for_us = AXIS2_FALSE;
|
| }
|
| }
|
|
|
| if (is_for_us)
|
| {
|
| /* Windows cannot find the correct dlls unless the path is set*/
|
| #if _WIN32_WINNT >= 0x0502
|
| SetDllDirectory( szPath );
|
| #else
|
| SetCurrentDirectory( szPath );
|
| #endif
|
| pecb->dwHttpStatusCode = HTTP_INTERNAL_SERVER_ERROR;
|
| /* We are sure that worker is not NULL since it is NULL init_axis2 would have failed */
|
| axis2_iis_worker_process_request(axis2_worker, axutil_env, pecb);
|
|
|
| /* Windows cannot find the correct dlls unless the dir is set
|
| but we want to reset to previous dir after the load */
|
| #if _WIN32_WINNT >= 0x0502
|
| SetDllDirectory( szOriginalPath );
|
| #else
|
| SetCurrentDirectory( szOriginalPath );
|
| #endif
|
| return HSE_STATUS_SUCCESS;
|
| }
|
| else if (server_version >= 6)
|
| {
|
| /* For IIS 5.1 or earlier this code is never executed. Since the URL is
|
| redirected to Axis2/C by the Filter */
|
|
|
| /* If not for Axis2/C let the request go to who ever wants it */
|
| ExecUrlInfo.pszUrl = NULL; /* Use original request URL */
|
| ExecUrlInfo.pszMethod = NULL; /* Use original request method */
|
| ExecUrlInfo.pszChildHeaders = NULL; /* Use original request headers */
|
| ExecUrlInfo.pUserInfo = NULL; /* Use original request user info */
|
| ExecUrlInfo.pEntity = NULL; /* Use original request entity */
|
|
|
| /* Provent recursion */
|
| ExecUrlInfo.dwExecUrlFlags = HSE_EXEC_URL_IGNORE_CURRENT_INTERCEPTOR;
|
|
|
| /* Associate the completion routine and the current URL with this request. */
|
| if ( pecb->ServerSupportFunction( pecb->ConnID,
|
| HSE_REQ_IO_COMPLETION,
|
| ExecUrlCompletion,
|
| NULL,
|
| NULL) == FALSE )
|
| {
|
| return HSE_STATUS_ERROR;
|
| }
|
|
|
| /* Ok, now that everything is set up, let's call the child request */
|
| if ( pecb->ServerSupportFunction( pecb->ConnID,
|
| HSE_REQ_EXEC_URL,
|
| &ExecUrlInfo,
|
| NULL,
|
| NULL ) == FALSE )
|
| {
|
| return HSE_STATUS_ERROR;
|
| }
|
| /* Return pending and let the completion clean up */
|
| return HSE_STATUS_PENDING;
|
| }
|
| return HSE_STATUS_ERROR;
|
| }
|
|
|
| VOID
|
| WINAPI
|
| ExecUrlCompletion (
|
| EXTENSION_CONTROL_BLOCK * pecb,
|
| PVOID pContext,
|
| DWORD cbIO,
|
| DWORD dwError
|
| )
|
| {
|
| /* We are done so notify */
|
| pecb->ServerSupportFunction(
|
| pecb->ConnID,
|
| HSE_REQ_DONE_WITH_SESSION,
|
| NULL,
|
| NULL,
|
| NULL);
|
| }
|
|
|
|
|
| BOOL
|
| send_error(
|
| EXTENSION_CONTROL_BLOCK * pecb,
|
| axis2_char_t error[])
|
| {
|
| DWORD cbData;
|
| pecb->dwHttpStatusCode = 500;
|
| /* Send headers and response */
|
| pecb->ServerSupportFunction( pecb->ConnID,
|
| HSE_REQ_SEND_RESPONSE_HEADER,
|
| "500 Server Error",
|
| NULL,
|
| (LPDWORD)"Content-Type: text/html\r\n\r\n" );
|
|
|
| cbData = axutil_strlen( error );
|
| return pecb->WriteClient( pecb->ConnID,
|
| error,
|
| &cbData,
|
| HSE_IO_SYNC );
|
| }
|
|
|
| axis2_status_t AXIS2_CALL read_registery_init_data() |
| { |
| long rc = 0; |
| axis2_status_t ok = TRUE; |
| char tmpbuf[INTERNET_MAX_URL_LENGTH]; |
| HKEY hkey; |
| AXIS2_IMPORT extern axis2_char_t *axis2_request_url_prefix; |
| |
| rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_LOCATION, (DWORD) 0, KEY_READ, &hkey); |
| if (ERROR_SUCCESS != rc) |
| { |
| return AXIS2_FAILURE; |
| } |
| if (get_registry_config_parameter(hkey, AXIS2_IIS_REPO_PATH_TAG, tmpbuf, sizeof(repo_path))) |
| { |
| strcpy(repo_path, tmpbuf); |
| } |
| else |
| { |
| return AXIS2_FAILURE; |
| } |
| if (get_registry_config_parameter(hkey, AXIS2_IIS_LOG_FILE_TAG, tmpbuf, sizeof(log_file))) |
| { |
| strcpy(log_file, tmpbuf); |
| } |
| else |
| { |
| return AXIS2_FAILURE; |
| } |
| if (get_registry_config_parameter(hkey, AXIS2_IIS_LOG_LEVEL_TAG, tmpbuf, sizeof(tmpbuf))) |
| { |
| log_level = axis2_iis_parse_log_level(tmpbuf); |
| } |
| else |
| { |
| return AXIS2_FAILURE; |
| } |
| if (get_registry_config_parameter(hkey, AXIS2_IIS_SERVICE_URL_PREFIX, tmpbuf, sizeof(tmpbuf))) |
| { |
| axis2_request_url_prefix = _strdup(tmpbuf); |
| } |
| if (get_registry_config_parameter(hkey, AXIS2_IIS_AXIS2_LOCATION, tmpbuf, sizeof(tmpbuf))) |
| { |
| axis2_location = _strdup(tmpbuf); |
| } |
| RegCloseKey(hkey); |
| return ok; |
| } |
| |
| axutil_log_levels_t AXIS2_CALL |
| axis2_iis_parse_log_level(char level[]) |
| { |
| if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_TRACE_VERB)) |
| { |
| return AXIS2_LOG_LEVEL_TRACE; |
| } |
| if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_DEBUG_VERB)) |
| { |
| return AXIS2_LOG_LEVEL_DEBUG; |
| } |
| if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_INFO_VERB)) |
| { |
| return AXIS2_LOG_LEVEL_INFO; |
| } |
| if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_USER_VERB)) |
| { |
| return AXIS2_LOG_LEVEL_USER; |
| } |
| if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_WARN_VERB)) |
| { |
| return AXIS2_LOG_LEVEL_WARNING; |
| } |
| if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_ERROR_VERB)) |
| { |
| return AXIS2_LOG_LEVEL_ERROR; |
| } |
| if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_CRITICAL_VERB)) |
| { |
| return AXIS2_LOG_LEVEL_CRITICAL; |
| } |
| return AXIS2_LOG_LEVEL_DEBUG; |
| } |
| |
| axis2_status_t AXIS2_CALL |
| 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 FALSE; |
| } |
| b[sz] = '\0'; |
| return TRUE; |
| } |
| |
| /** |
| * This method initializes the axis2 engine. All the required variables are set to |
| * their initial values in this method. |
| */ |
| axis2_status_t AXIS2_CALL init_axis2() |
| { |
| /* |
| * These are the varibles required to initialize axis. |
| */ |
| axis2_status_t status = FALSE; |
| /* We need to init xml readers before we go into threaded env */ |
| if (!is_inited) |
| { |
| axiom_xml_reader_init(); |
| status = read_registery_init_data(); |
| if (status == AXIS2_FAILURE) |
| { |
| return AXIS2_FAILURE; |
| } |
| axutil_error_init(); |
| /* Initialize the environement */ |
| axutil_env = axutil_env_create_all(log_file, log_level); |
| if (!axutil_env) |
| { |
| return AXIS2_FAILURE; |
| } |
| axis2_worker = axis2_iis_worker_create(axutil_env, repo_path); |
| if (!axis2_worker) |
| { |
| return AXIS2_FAILURE; |
| } |
| is_inited = AXIS2_TRUE; |
| return AXIS2_SUCCESS; |
| } |
| return AXIS2_FAILURE; |
| } |