diff options
Diffstat (limited to 'src/core/transport/http/server/IIS/axis2_isapi_plugin.c')
-rw-r--r-- | src/core/transport/http/server/IIS/axis2_isapi_plugin.c | 476 |
1 files changed, 476 insertions, 0 deletions
diff --git a/src/core/transport/http/server/IIS/axis2_isapi_plugin.c b/src/core/transport/http/server/IIS/axis2_isapi_plugin.c new file mode 100644 index 0000000..eccfd1c --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_isapi_plugin.c @@ -0,0 +1,476 @@ +
+/*
+ * 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; +} |