summaryrefslogtreecommitdiffstats
path: root/src/core/transport/http/server/IIS/axis2_isapi_plugin.c
diff options
context:
space:
mode:
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.c476
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;
+}