/* * 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 #include #include #include #include #include #include "axis2_iis_constants.h" #include "axis2_iis_worker.h" /* Axis headers */ #include #include #include #include #include #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[] = "\r\n" " An IIS server error occurred. \r\n" "

An IIS server error occurred

\r\n" "
\r\n" "An error occurred in IIS while processing this request."; axis2_char_t initializing_error[] = "\r\n" " An IIS server error occurred. \r\n" "

An IIS server error occurred

\r\n" "
\r\n" "An error occurred while initilizing Axis2/C."; /* * 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; }