summaryrefslogtreecommitdiffstats
path: root/src/core/transport/http/server/IIS
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/transport/http/server/IIS')
-rw-r--r--src/core/transport/http/server/IIS/README61
-rw-r--r--src/core/transport/http/server/IIS/axis2_iis_constants.h51
-rw-r--r--src/core/transport/http/server/IIS/axis2_iis_out_transport_info.c153
-rw-r--r--src/core/transport/http/server/IIS/axis2_iis_out_transport_info.h61
-rw-r--r--src/core/transport/http/server/IIS/axis2_iis_regedit.js84
-rw-r--r--src/core/transport/http/server/IIS/axis2_iis_stream.c313
-rw-r--r--src/core/transport/http/server/IIS/axis2_iis_stream.h45
-rw-r--r--src/core/transport/http/server/IIS/axis2_iis_worker.c607
-rw-r--r--src/core/transport/http/server/IIS/axis2_iis_worker.h62
-rw-r--r--src/core/transport/http/server/IIS/axis2_isapi_plugin.c476
-rw-r--r--src/core/transport/http/server/IIS/iis_iaspi_plugin_51/axis2_isapi_51.c153
-rw-r--r--src/core/transport/http/server/IIS/mod_axis2.def7
12 files changed, 2073 insertions, 0 deletions
diff --git a/src/core/transport/http/server/IIS/README b/src/core/transport/http/server/IIS/README
new file mode 100644
index 0000000..1a47cc4
--- /dev/null
+++ b/src/core/transport/http/server/IIS/README
@@ -0,0 +1,61 @@
+How to Configure IIS Module for Axis2C
+________________________________________
+
+Use the Axis2/C VC project or makefile to build the component.
+
+In this document it is assumed that the mod_axis2_IIS.dll is in the directory
+c:\axis2c\lib\mod_axis2_IIS.dll and axis2c_home is c:\axis2c
+
+Add the following key to the registry.
+
+HKEY_LOCAL_MACHINE\SOFTWARE\Apache Axis2c\IIS ISAPI Redirector
+
+Add a string value with the name axis2c_home and a value of c:\axis2c
+
+Add a string value with the name log_file and a value of c:\axis2c\logs\axis2.log
+
+Add a string value with the name log_level. The value can be one of trace, error, info, critical, debug, warning
+
+You can add a string value with the name services_url_prefix. This is optional and defaults to "/services".
+As an example, if you have "/web_services" as the prefix, then all the services hosted would have the endpoint prefix of :
+http://localhost/axis2/web_services.
+Note: don't forget the / at the begining.
+
+If you wish, you can also change the location as well by adding a string value with the name axis2_location.
+This is also optional and defaults to /axis2. If you have /myserser as the value you can access your web
+services with a url like http://localhost/myserver/services.
+Note: Don't forget the / at the beginning.
+
+Now you can do all the registry editing using the JScript file axis2_iis_regedit.js
+provided with the distribution. When you build axis2/C with the IIS module the file
+is copied to the root directory of the binary distribution. Just double click it and
+everything will be set to the defaults. The axis2c_home is taken as the current directory,
+so make sure you run the file in the Axis2/C repository location (or root of the binary distribution).
+If you want to change the values you can manually edit the the .js file or give it as command line arguments
+to the script when running the script. To run the jscript from the command line use the command
+:\cscript axis2_iis_regedit.js optional arguments.
+We recomend the manual editing as it is the easiest way to specify the values
+
+IIS 5.1 or Below
+
+Using the IIS management console, add a new virtual directory to your IIS/PWS Web site.
+The name of the virtual directory must be axis2. Its physical path should be the directory
+where you placed mod_axis2_IIS.dll (in our example it is c:\axis2c\lib). When creating this new
+virtual directory, assign execute access to it.
+
+By Using the IIS management console, add mod_axis2_IIS.dll as a filter in your IIS/PWS web site and restart the IIS admin service.
+
+
+IIS 6 & 7
+
+Using the IIS management console, add the mod_axis2_IIS.dll as a Wildcard Script Map.
+ Executable should be the complete path to the mod_axis2_IIS.dll
+ You can put any name as the name of the Wildcard Script Map
+
+Please don't add the mod_axis2_IIS.dll as a filter to IIS as in the IIS 5.1 case.
+
+Note: If the Axis2/C failed to load, verify that Axis2/C and its dependent DLLs are in the System Path (not the user path).
+
+
+
+
diff --git a/src/core/transport/http/server/IIS/axis2_iis_constants.h b/src/core/transport/http/server/IIS/axis2_iis_constants.h
new file mode 100644
index 0000000..fb6929b
--- /dev/null
+++ b/src/core/transport/http/server/IIS/axis2_iis_constants.h
@@ -0,0 +1,51 @@
+
+/*
+ * 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.
+ */
+
+#ifndef AXIS2_IIS_CONSTANTS_H
+#define AXIS2_IIS_CONSTANTS_H
+
+#define INTERNET_MAX_PATH_LENGTH 2048
+#define INTERNET_MAX_SCHEME_LENGTH 32 /* longest protocol name length */
+#define INTERNET_MAX_URL_LENGTH (INTERNET_MAX_SCHEME_LENGTH +sizeof("://") +INTERNET_MAX_PATH_LENGTH)
+
+#define URI_MATCHED 1
+#define URI_UN_MATCHED 2
+
+#define EXTENSION_URL "/axis2/mod_axis2_IIS.dll\? "
+#define EXTENSION_URL_AXIS2 "/axis2/"
+#define EXTENSION_URL_MODIIS "mod_axis2_IIS.dll\? "
+
+
+#define MAX_SERVERNAME 128
+#define MAX_PORT_LEN 8
+
+#define MAX_HTTP_VERSION_LEN 16
+#define MAX_HTTP_CONTENT_TYPE_LEN 2048
+#define MAX_CONTENT_ENCODING_LEN 16
+#define MAX_HTTP_METHOD_LEN 8
+#define MAX_TCP_PORT_LEN 8
+#define MAX_CONTENT_LEN 16
+
+#define OK 200
+#define HTTP_INTERNAL_SERVER_ERROR 500
+#define HTTP_ACCEPTED 202
+
+#define AXIS2_STRICMP _stricmp
+
+#endif /*AXIS2_IIS_CONSTANTS_H*/
+
diff --git a/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.c b/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.c
new file mode 100644
index 0000000..fb7693b
--- /dev/null
+++ b/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.c
@@ -0,0 +1,153 @@
+/*
+ * 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 "axis2_iis_out_transport_info.h"
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <axutil_string.h>
+
+#include "axis2_iis_constants.h"
+
+/**
+ * @brief IIS Out transport info impl structure
+ * Axis2 iis_out_transport_info_impl
+ */
+
+typedef struct axis2_iis_out_transport_info_s
+{
+ axis2_http_out_transport_info_t out_transport_info;
+ axis2_char_t *encoding;
+ axis2_char_t content_type[MAX_HTTP_CONTENT_TYPE_LEN];
+} axis2_iis_out_transport_info_t;
+
+#define AXIS2_INTF_TO_IMPL(out_transport_info) \
+ ((axis2_iis_out_transport_info_t *)(out_transport_info))
+
+void AXIS2_CALL
+axis2_iis_out_transport_info_free(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env)
+{
+ axis2_iis_out_transport_info_t *info = NULL;
+ AXIS2_ENV_CHECK(env, void);
+
+ info = AXIS2_INTF_TO_IMPL(out_transport_info);
+
+ if(info->encoding)
+ {
+ AXIS2_FREE(env->allocator, info->encoding);
+ info->encoding = NULL;
+ }
+
+ AXIS2_FREE(env->allocator, info);
+ return;
+}
+
+void AXIS2_CALL
+axis2_iis_out_transport_info_free_void_arg(
+ void *transport_info,
+ const axutil_env_t * env)
+{
+ axis2_http_out_transport_info_t *transport_info_l = NULL;
+
+ AXIS2_ENV_CHECK(env, void);
+ transport_info_l = (axis2_http_out_transport_info_t *)transport_info;
+ axis2_http_out_transport_info_free(transport_info_l, env);
+ return;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_iis_out_transport_info_set_content_type(
+ axis2_http_out_transport_info_t * info,
+ const axutil_env_t * env,
+ const axis2_char_t * content_type)
+{
+ axis2_iis_out_transport_info_t *info_impl = NULL;
+
+ info_impl = AXIS2_INTF_TO_IMPL(info);
+ info_impl->content_type[0] = '\0';
+ if(info_impl->encoding)
+ {
+ sprintf(info_impl->content_type, "%s%s%s", content_type, ";charser:", info_impl->encoding);
+ }
+ else
+ {
+ strcat(info_impl->content_type, content_type);
+ }
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_iis_out_transport_info_set_char_encoding(
+ axis2_http_out_transport_info_t * info,
+ const axutil_env_t * env,
+ const axis2_char_t * encoding)
+{
+ axis2_iis_out_transport_info_t *info_impl = NULL;
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE);
+
+ info_impl = AXIS2_INTF_TO_IMPL(info);
+
+ if(info_impl->encoding)
+ {
+ AXIS2_FREE(env->allocator, info_impl->encoding);
+ }
+ info_impl->encoding = axutil_strdup(env, encoding);
+
+ return AXIS2_SUCCESS;
+}
+
+axis2_http_out_transport_info_t *AXIS2_CALL
+axis2_iis_out_transport_info_create(
+ const axutil_env_t * env,
+ LPEXTENSION_CONTROL_BLOCK lpECB)
+{
+ axis2_iis_out_transport_info_t *info = NULL;
+ axis2_http_out_transport_info_t *http_out_info = NULL;
+ AXIS2_ENV_CHECK(env, NULL);
+
+ info = (axis2_iis_out_transport_info_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_iis_out_transport_info_t));
+
+ if(!info)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ info->encoding = NULL;
+
+ http_out_info = &(info->out_transport_info);
+
+ axis2_http_out_transport_info_set_content_type_func(http_out_info, env,
+ axis2_iis_out_transport_info_set_content_type);
+ axis2_http_out_transport_info_set_char_encoding_func(http_out_info, env,
+ axis2_iis_out_transport_info_set_char_encoding);
+ axis2_http_out_transport_info_set_free_func(http_out_info, env,
+ axis2_iis_out_transport_info_free);
+
+ return http_out_info;
+}
+
+axis2_char_t *
+axis2_iis_out_transport_get_content(
+ axis2_http_out_transport_info_t * info)
+{
+ axis2_iis_out_transport_info_t *info_impl = NULL;
+ info_impl = AXIS2_INTF_TO_IMPL(info);
+ return info_impl->content_type;
+}
diff --git a/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.h b/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.h
new file mode 100644
index 0000000..893ffdf
--- /dev/null
+++ b/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.h
@@ -0,0 +1,61 @@
+
+/*
+ * 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.
+ */
+
+#ifndef AXIS2_IIS_OUT_TRANSPORT_INFO_H
+#define AXIS2_IIS_OUT_TRANSPORT_INFO_H
+
+/**
+ * @ingroup axis2_core_transport_http
+ * @{
+ */
+
+/**
+ * @file axis2_iis_out_transport_info.h
+ * @brief axis2 IIS Out Transport Info
+ */
+
+#include <axis2_http_out_transport_info.h>
+#include <httpext.h>
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ axis2_http_out_transport_info_t *AXIS2_CALL
+
+ axis2_iis_out_transport_info_create(
+ const axutil_env_t * env,
+ LPEXTENSION_CONTROL_BLOCK lpECB);
+
+ /**
+ * Free http_out_transport_info passed as void pointer. This will be
+ * cast into appropriate type and then pass the cast object
+ * into the http_out_transport_info structure's free method
+ */
+ void AXIS2_CALL
+ axis2_iis_out_transport_info_free_void_arg(
+ void *transport_info,
+ const axutil_env_t * env);
+
+ axis2_char_t *axis2_iis_out_transport_get_content(
+ axis2_http_out_transport_info_t * out_transport_info);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* AXIS2_IIS_OUT_TRANSPORT_INFO_H */
diff --git a/src/core/transport/http/server/IIS/axis2_iis_regedit.js b/src/core/transport/http/server/IIS/axis2_iis_regedit.js
new file mode 100644
index 0000000..3889c1e
--- /dev/null
+++ b/src/core/transport/http/server/IIS/axis2_iis_regedit.js
@@ -0,0 +1,84 @@
+var WshShell = WScript.CreateObject("WScript.Shell");
+
+/* You can change the following values to suite your requirements */
+/* Axis2/C repo location. axis2.xml, modules folder and services folder should be in this dir */
+var axis2c_home = WshShell.CurrentDirectory;
+/* Log level. Possible values are trace, error, info, critical, user, debug and warning */
+var log_level = "debug";
+/* Full path to the log file */
+var log_file = axis2c_home + "/logs/axis2.log";
+/* Services URL prefix. This is the folder where services are hosted. Optional */
+var services_url_prefix;
+/* Max log file size */
+var max_log_file_size;
+/* Axis2 location */
+var axis2_location;
+
+/* Don't change anything below */
+var axis2c_home_str = "axis2c_home";
+var log_level_str = "log_level";
+var log_file_str = "log_file";
+var services_url_prefix_str = "services_url_prefix";
+var max_log_file_size_str = "max_log_file_size";
+var axis2_location_str = "axis2_location"
+
+var reg_location = "HKLM\\Software\\Apache Axis2C\\IIS ISAPI Redirector\\"
+/* If specified get the values from the command prompt */
+var args = WScript.Arguments;
+if (args.length > 0) {
+ axis2c_home = args.Item(0);
+ if (axis2c_home) {
+ log_file = axis2c_home + "/logs/axis2.log";
+ }
+}
+if (args.length > 1) {
+ log_level = args.Item(1);
+}
+if (args.length > 2) {
+ log_file = args.Item(2);
+}
+if (args.length > 3) {
+ services_url_prefix = args.Item(3);
+}
+if (args.length > 4) {
+ max_log_file_size = args.Item(4);
+}
+if (args.length > 5) {
+ axis2_location = args.Item(5);
+}
+/* Write the axis2c_home entry. This is used by Axis2/C to find the repo location */
+WshShell.RegWrite (reg_location + axis2c_home_str, axis2c_home, "REG_SZ");
+/* Write the log_level registry entry */
+WshShell.RegWrite (reg_location + log_level_str, log_level, "REG_SZ");
+/* Write the log file name */
+WshShell.RegWrite (reg_location + log_file_str, log_file, "REG_SZ");
+/* Write the services url prefix. We write this only if specified */
+try {
+ var services_url_prefix_key = WshShell.RegRead (reg_location + services_url_prefix_str);
+ if (services_url_prefix_key) {
+ WshShell.RegDelete (reg_location + services_url_prefix_str);
+ }
+} catch (e) {}
+if (services_url_prefix) {
+ WshShell.RegWrite (reg_location + services_url_prefix_str, services_url_prefix, "REG_SZ");
+}
+/* We write max_log_file_size only if specified */
+try {
+ var max_log_file_size_key = WshShell.RegRead (reg_location + max_log_file_size_str);
+ if (max_log_file_size_key) {
+ WshShell.RegDelete (reg_location + max_log_file_size_str);
+ }
+} catch (e) {}
+if (max_log_file_size) {
+ WshShell.RegWrite (reg_location + max_log_file_size_str, max_log_file_size, "REG_SZ");
+}
+
+try{
+ var axis2_location_key = WshShell.RegRead (reg_location + axis2_location_str);
+ if (axis2_location_key) {
+ WshShell.RegDelete (reg_location + axis2_location_str);
+ }
+} catch (e) {}
+if (axis2_location) {
+ WshShell.RegWrite (reg_location + axis2_location_str, axis2_location, "REG_SZ");
+} \ No newline at end of file
diff --git a/src/core/transport/http/server/IIS/axis2_iis_stream.c b/src/core/transport/http/server/IIS/axis2_iis_stream.c
new file mode 100644
index 0000000..90fc8ba
--- /dev/null
+++ b/src/core/transport/http/server/IIS/axis2_iis_stream.c
@@ -0,0 +1,313 @@
+/*
+ * 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 <string.h>
+#include <stdlib.h>
+#include "axis2_iis_stream.h"
+#include <httpext.h>
+
+/**
+ * @brief Stream struct impl
+ * Streaming mechanisms for iis web server
+ */
+
+typedef struct iis_stream_impl
+{
+ axutil_stream_t stream;
+ axutil_stream_type_t stream_type;
+ LPEXTENSION_CONTROL_BLOCK lpECB;
+ unsigned int cur_pos;
+ void *cur_position;
+} iis_stream_impl_t;
+
+#define AXIS2_INTF_TO_IMPL(stream) ((iis_stream_impl_t *)(stream))
+
+axutil_stream_type_t AXIS2_CALL
+iis_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+int AXIS2_CALL iis_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count);
+
+int AXIS2_CALL iis_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count);
+
+int AXIS2_CALL iis_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count);
+
+int AXIS2_CALL iis_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+axutil_stream_t *AXIS2_CALL
+axutil_stream_create_iis(
+ const axutil_env_t * env,
+ LPEXTENSION_CONTROL_BLOCK lpECB)
+{
+ iis_stream_impl_t *stream_impl = NULL;
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, lpECB, NULL);
+
+ stream_impl = (iis_stream_impl_t *)AXIS2_MALLOC(env->allocator, sizeof(iis_stream_impl_t));
+
+ if(!stream_impl)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ stream_impl->cur_pos = 0;
+ stream_impl->cur_position = NULL;
+ stream_impl->lpECB = lpECB;
+ stream_impl->stream_type = AXIS2_STREAM_MANAGED;
+
+ axutil_stream_set_read(&(stream_impl->stream), env, iis_stream_read);
+ axutil_stream_set_write(&(stream_impl->stream), env, iis_stream_write);
+ axutil_stream_set_skip(&(stream_impl->stream), env, iis_stream_skip);
+
+ return &(stream_impl->stream);
+}
+
+int AXIS2_CALL
+iis_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count)
+{
+ void *temp_buff = NULL;
+ unsigned int data_to_read = 0;
+ DWORD ret_val = TRUE;
+ DWORD read_bytes = (DWORD)count;
+ iis_stream_impl_t *stream_impl = NULL;
+ char *temp = NULL;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ stream_impl = (iis_stream_impl_t *)stream;
+
+ if(stream_impl->cur_pos == 0)
+ stream_impl->cur_position = stream_impl->lpECB->lpbData;
+
+ /* If this is the case all the bytes are in the lpECB->lpbData buffer*/
+ if(stream_impl->lpECB->cbAvailable == stream_impl->lpECB->cbTotalBytes)
+ {
+ /* Cannot read more than in the buffer.*/
+ if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable)
+ data_to_read = (unsigned)count;
+ else
+ data_to_read = stream_impl->lpECB->cbTotalBytes - stream_impl->cur_pos;
+
+ memcpy(buffer, stream_impl->cur_position, data_to_read);
+ temp = (char *)(stream_impl->cur_position);
+ temp += data_to_read;
+ stream_impl->cur_position = temp;
+ temp = NULL;
+ stream_impl->cur_pos += data_to_read;
+ read_bytes = data_to_read;
+ }
+ else if(stream_impl->lpECB->cbAvailable == -1)
+ {
+ ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, buffer, &read_bytes);
+ }
+ else if(stream_impl->lpECB->cbAvailable < stream_impl->lpECB->cbTotalBytes)
+ {
+ if(stream_impl->cur_pos > stream_impl->lpECB->cbAvailable)
+ {
+ ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, buffer,
+ &read_bytes);
+ }
+ else if(stream_impl->cur_pos + count > stream_impl->lpECB->cbAvailable
+ && stream_impl->cur_pos < stream_impl->lpECB->cbAvailable)
+ {
+ int read_length = 0;
+ if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable)
+ read_length = (unsigned)count;
+ else
+ read_length = stream_impl->lpECB->cbTotalBytes - stream_impl->cur_pos;
+ data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos;
+ memcpy(buffer, stream_impl->cur_position, data_to_read);
+
+ read_bytes = stream_impl->cur_pos + read_length - stream_impl->lpECB->cbAvailable;
+ temp_buff = malloc(read_bytes);
+
+ if(temp_buff == NULL)
+ return data_to_read;
+ ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff,
+ &read_bytes);
+ memcpy(((char *)buffer + data_to_read), temp_buff, read_bytes);
+ read_bytes += data_to_read;
+ temp = (char *)(stream_impl->cur_position);
+ temp += read_bytes;
+ stream_impl->cur_position = temp;
+ stream_impl->cur_pos += (unsigned)read_bytes;
+ }
+ else
+ {
+ memcpy(buffer, stream_impl->cur_position, count);
+ temp = (char *)(stream_impl->cur_position);
+ temp += count;
+ stream_impl->cur_position = temp;
+ temp = NULL;
+ stream_impl->cur_pos += (unsigned)count;
+ read_bytes = (int)count;
+ }
+ }
+ if(ret_val == TRUE)
+ return read_bytes;
+ else
+ return -1;
+}
+
+int AXIS2_CALL
+iis_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buf,
+ size_t count)
+{
+ DWORD ret_val = NO_ERROR;
+ unsigned long bytes_sent = 0;
+ iis_stream_impl_t *stream_impl = NULL;
+ axis2_char_t *buffer = NULL;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE);
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ buffer = (axis2_char_t *)buf;
+ bytes_sent = (unsigned)strlen(buffer);
+
+ if(count <= 0)
+ {
+ return (int)count;
+ }
+ /* assume that buffer is not null terminated */
+ ret_val = stream_impl->lpECB->WriteClient(stream_impl->lpECB->ConnID, buffer, &bytes_sent,
+ HSE_IO_SYNC);
+ if(ret_val == TRUE)
+ return (int)bytes_sent;
+ else
+ return -1;
+}
+
+int AXIS2_CALL
+iis_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count)
+{
+ DWORD ret_val = TRUE;
+ iis_stream_impl_t *stream_impl = NULL;
+ void *temp_buff = NULL;
+ int data_to_read = 0;
+ DWORD read_bytes = (DWORD)count;
+ char *temp = NULL;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ stream_impl = (iis_stream_impl_t *)stream;
+
+ if(stream_impl->cur_pos == 0)
+ stream_impl->cur_position = stream_impl->lpECB->lpbData;
+
+ if(stream_impl->lpECB->cbAvailable == stream_impl->lpECB->cbTotalBytes)
+ {
+ if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable)
+ data_to_read = count;
+ else
+ data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos;
+
+ temp = (char *)(stream_impl->cur_position);
+ temp += data_to_read;
+ stream_impl->cur_position = temp;
+ temp = NULL;
+ stream_impl->cur_pos += data_to_read;
+ read_bytes = data_to_read;
+ }
+ else if(stream_impl->lpECB->cbAvailable == -1)
+ {
+ temp_buff = malloc(read_bytes);
+ ret_val
+ = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff, &read_bytes);
+ free(temp_buff);
+ }
+ else if(stream_impl->lpECB->cbAvailable < stream_impl->lpECB->cbTotalBytes)
+ {
+ if(stream_impl->cur_pos > stream_impl->lpECB->cbAvailable)
+ {
+ temp_buff = malloc(read_bytes);
+ ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff,
+ &read_bytes);
+ free(temp_buff);
+ }
+ else if(stream_impl->cur_pos + count > stream_impl->lpECB->cbAvailable
+ && stream_impl->cur_pos < stream_impl->lpECB->cbAvailable)
+ {
+ data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos;
+ read_bytes = stream_impl->cur_pos + count - stream_impl->lpECB->cbAvailable;
+ temp_buff = malloc(read_bytes);
+
+ if(temp_buff == NULL)
+ return data_to_read;
+
+ ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff,
+ &read_bytes);
+ read_bytes += data_to_read;
+ free(temp_buff);
+ }
+ else
+ {
+ temp = (char *)(stream_impl->cur_position);
+ temp += count;
+ stream_impl->cur_position = temp;
+ temp = NULL;
+ stream_impl->cur_pos += count;
+ read_bytes = count;
+ }
+ }
+ if(ret_val == FALSE)
+ {
+ return -1;
+ }
+ return read_bytes;
+}
+
+int AXIS2_CALL
+iis_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ int ret = -1;
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+
+ return ret;
+}
+
+axutil_stream_type_t AXIS2_CALL
+iis_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ return AXIS2_INTF_TO_IMPL(stream)->stream_type;
+}
diff --git a/src/core/transport/http/server/IIS/axis2_iis_stream.h b/src/core/transport/http/server/IIS/axis2_iis_stream.h
new file mode 100644
index 0000000..091edb0
--- /dev/null
+++ b/src/core/transport/http/server/IIS/axis2_iis_stream.h
@@ -0,0 +1,45 @@
+
+/*
+ * 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.
+ */
+
+#ifndef IIS_STREAM_H
+#define IIS_STREAM_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+#include <httpext.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /** brief Constructor for creating IIS stream
+ * @return axutil_stream (IIS)
+ */
+ axutil_stream_t *AXIS2_CALL
+ axutil_stream_create_iis(
+ const axutil_env_t * env,
+ LPEXTENSION_CONTROL_BLOCK lpECB);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IIS_STREAM_H */
diff --git a/src/core/transport/http/server/IIS/axis2_iis_worker.c b/src/core/transport/http/server/IIS/axis2_iis_worker.c
new file mode 100644
index 0000000..51a6cc8
--- /dev/null
+++ b/src/core/transport/http/server/IIS/axis2_iis_worker.c
@@ -0,0 +1,607 @@
+/*
+ * 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 <axis2_http_transport.h>
+#include <axis2_conf.h>
+#include <axutil_string.h>
+#include <axis2_msg_ctx.h>
+#include <axis2_http_out_transport_info.h>
+#include <axis2_http_transport_utils.h>
+#include <axis2_op_ctx.h>
+#include <axis2_engine.h>
+#include <axutil_uuid_gen.h>
+#include <axis2_conf_init.h>
+#include <axutil_url.h>
+#include <axiom_soap.h>
+#include "axis2_iis_out_transport_info.h"
+#include "axis2_iis_stream.h"
+#include "axis2_iis_worker.h"
+
+/* Files from iis */
+#include <httpfilt.h>
+#include <httpext.h>
+
+#include "axis2_iis_constants.h"
+
+#define READ_SIZE 2048
+
+axis2_status_t AXIS2_CALL
+axis2_worker_get_original_url(
+ char url[],
+ char ret_url[]);
+
+axis2_char_t * AXIS2_CALL
+axis2_iis_worker_get_bytes(
+ const axutil_env_t * env,
+ axutil_stream_t * stream);
+
+axis2_status_t AXIS2_CALL
+start_response(
+ const axutil_env_t * env,
+ LPEXTENSION_CONTROL_BLOCK lpECB,
+ int status,
+ const char *reason,
+ axutil_array_list_t *headers);
+
+axis2_status_t
+write_response(
+ LPEXTENSION_CONTROL_BLOCK lpECB,
+ const void *b,
+ unsigned int l);
+
+axutil_hash_t *
+axis2_iis_worker_read_http_headers(
+ const axutil_env_t * env,
+ LPEXTENSION_CONTROL_BLOCK lpECB);
+
+AXIS2_IMPORT extern axis2_char_t *axis2_request_url_prefix;
+
+static struct reasons
+{
+ axis2_char_t * status_code;
+ int status_len;
+} reasons[] = { { "200 OK", 6 }, { "202 Accepted", 12 }, { "500 Internal Server Error", 25 } };
+
+struct axis2_iis_worker
+{
+ axis2_conf_ctx_t * conf_ctx;
+};
+
+char *
+status_reason(
+ int status);
+
+axis2_iis_worker_t * AXIS2_CALL
+axis2_iis_worker_create(
+ const axutil_env_t * env,
+ axis2_char_t * repo_path)
+{
+ axis2_iis_worker_t * iis_worker = NULL;
+
+ iis_worker = (axis2_iis_worker_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_iis_worker_t));
+ if(!iis_worker)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ iis_worker->conf_ctx = axis2_build_conf_ctx(env, repo_path);
+ if(!iis_worker->conf_ctx)
+ {
+ axis2_iis_worker_free((axis2_iis_worker_t *)iis_worker, env);
+ return NULL;
+ }
+ return iis_worker;
+}
+
+void AXIS2_CALL
+axis2_iis_worker_free(
+ axis2_iis_worker_t * iis_worker,
+ const axutil_env_t * env)
+{
+ if(iis_worker->conf_ctx)
+ {
+ axis2_conf_ctx_free(iis_worker->conf_ctx, env);
+ iis_worker->conf_ctx = NULL;
+ }
+ AXIS2_FREE(env->allocator, iis_worker);
+ return;
+}
+
+int AXIS2_CALL
+axis2_iis_worker_process_request(
+ axis2_iis_worker_t * iis_worker,
+ const axutil_env_t * env,
+ LPEXTENSION_CONTROL_BLOCK lpECB)
+{
+ axis2_conf_ctx_t * conf_ctx = NULL;
+ axutil_stream_t * out_stream = NULL;
+ axis2_transport_out_desc_t * out_desc = NULL;
+ axis2_transport_in_desc_t * in_desc = NULL;
+ axis2_char_t soap_action[INTERNET_MAX_URL_LENGTH];
+ axis2_char_t original_url[INTERNET_MAX_URL_LENGTH];
+ axis2_char_t req_url[INTERNET_MAX_URL_LENGTH];
+ DWORD cbSize = 0;
+ CHAR server_name[MAX_SERVERNAME];
+ axis2_char_t port[MAX_TCP_PORT_LEN];
+ axis2_char_t redirect_url[INTERNET_MAX_PATH_LENGTH];
+ axis2_char_t accept_language[INTERNET_MAX_PATH_LENGTH];
+ axutil_hash_t *headers = NULL;
+ axis2_char_t peer_ip[50];
+ axis2_char_t accept_header[INTERNET_MAX_URL_LENGTH];
+ axis2_char_t accept_charset[INTERNET_MAX_URL_LENGTH];
+ /*axutil_property_t *peer_property = NULL;*/
+
+ axis2_http_header_t *content_type_header = NULL;
+ axis2_http_header_t *content_length_header = NULL;
+
+ /* New Code variables */
+ axis2_http_transport_in_t request;
+ axis2_http_transport_out_t response;
+
+ /* initialize tranport in structure */
+ axis2_http_transport_utils_transport_in_init(&request, env);
+
+ /* initialize tranport out structure */
+ axis2_http_transport_utils_transport_out_init(&response, env);
+
+ soap_action[0] = '\0';
+
+ /*Check the parameters*/
+ if(!lpECB)
+ {
+ AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_INVALID_NULL_PARAM);
+ return AXIS2_FAILURE;
+ }
+ conf_ctx = iis_worker->conf_ctx;
+ if(!conf_ctx)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+
+ cbSize = INTERNET_MAX_PATH_LENGTH;
+ if(lpECB->GetServerVariable(lpECB->ConnID, "SERVER_NAME", server_name, &cbSize) == FALSE)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get server name from IIS.");
+ return AXIS2_FAILURE;
+ }
+ cbSize = MAX_TCP_PORT_LEN;
+ if(lpECB->GetServerVariable(lpECB->ConnID, "SERVER_PORT", port, &cbSize) == FALSE)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get server port from IIS.");
+ return AXIS2_FAILURE;
+ }
+ request.svr_port = port;
+
+ cbSize = INTERNET_MAX_PATH_LENGTH;
+ if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_URL", redirect_url, &cbSize) == FALSE)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get server port from IIS.");
+ return AXIS2_FAILURE;
+ }
+
+ /* We have a mapped URL only when the server version is 5 or less than that. */
+ if(server_version <= 5)
+ {
+ axis2_worker_get_original_url(redirect_url, original_url);
+ /* create the url using the above variables */
+ sprintf(req_url, "%s%s%s%s%s", "http://", server_name, ":", port, original_url);
+ }
+ else
+ {
+ sprintf(req_url, "%s%s%s%s%s", "http://", server_name, ":", port, redirect_url);
+ }
+ /* Set the request url */
+ request.request_uri = req_url;
+
+ out_stream = axutil_stream_create_basic(env);
+ out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(iis_worker->conf_ctx, env),
+ env, AXIS2_TRANSPORT_ENUM_HTTP);
+ in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(iis_worker->conf_ctx, env), env,
+ AXIS2_TRANSPORT_ENUM_HTTP);
+
+ /* Create the in message context */
+ request.msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc);
+ axis2_msg_ctx_set_server_side(request.msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_transport_out_stream(request.msg_ctx, env, out_stream);
+
+ /* Get the SOAPAction Header */
+ cbSize = INTERNET_MAX_URL_LENGTH;
+ if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_SOAPAction", soap_action, &cbSize))
+ {
+ request.soap_action = soap_action;
+ }
+
+ /* Create the in stream */
+ request.in_stream = axutil_stream_create_iis(env, lpECB);
+ if(!request.in_stream)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in creating input stream.");
+ return AXIS2_FAILURE;
+ }
+
+ /* Get the Remote Adrress */
+ if(lpECB->GetServerVariable(lpECB->ConnID, "REMOTE_ADDR", peer_ip, &cbSize))
+ {
+ request.remote_ip = peer_ip;
+ }
+
+ /* Set the http headers into the message context */
+ headers = axis2_iis_worker_read_http_headers(env, lpECB);
+ if(axis2_msg_ctx_set_transport_headers(request.msg_ctx, env, headers) == AXIS2_FAILURE)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "IIS: Error occured in setting transport headers.");
+ }
+ /* Set the content length */
+ request.content_length = lpECB->cbTotalBytes;
+ /* Set the HTTP method */
+ if(axutil_strcasecmp(lpECB->lpszMethod, "POST") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_POST;
+ }
+ else if(axutil_strcasecmp(lpECB->lpszMethod, "GET") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_GET;
+ }
+ else if(axutil_strcasecmp(lpECB->lpszMethod, "HEAD") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_HEAD;
+ }
+ else if(axutil_strcasecmp(lpECB->lpszMethod, "PUT") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_PUT;
+ }
+ else if(axutil_strcasecmp(lpECB->lpszMethod, "DELETE") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_DELETE;
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "IIS: Unsupported HTTP Method.");
+ return AXIS2_FAILURE;
+ }
+ /* Set the URL prefix. axis2_request_url_prefix is a global variable set at the init time */
+ request.request_url_prefix = axis2_request_url_prefix;
+ /* Create the transport out info */
+ request.out_transport_info = axis2_iis_out_transport_info_create(env, lpECB);
+ /* Set the content type */
+ request.content_type = lpECB->lpszContentType;
+
+ /* Get accept headaer */
+ cbSize = INTERNET_MAX_PATH_LENGTH;
+ if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_Accept", accept_header, &cbSize))
+ {
+ request.accept_header = accept_header;
+ }
+
+ /* Get the accept langauge */
+ cbSize = INTERNET_MAX_PATH_LENGTH;
+ if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_Accept-Language", accept_language, &cbSize))
+ {
+ request.accept_language_header = accept_language;
+ }
+
+ cbSize = INTERNET_MAX_PATH_LENGTH;
+ if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_Accept-Charset", accept_charset, &cbSize))
+ {
+ request.accept_charset_header = accept_charset;
+ }
+
+ /* Now we have set everything. We can call process method to process the request */
+ if(axis2_http_transport_utils_process_request(env, conf_ctx, &request, &response)
+ == AXIS2_FAILURE)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ /* Write the response */
+ if(response.response_data && response.response_data_length > 0)
+ {
+ axis2_char_t content_length_str[16] = { 0 };
+ axis2_bool_t is_out_headers_created = AXIS2_FALSE;
+ if(!response.output_headers)
+ {
+ response.output_headers = axutil_array_list_create(env, 2);
+ is_out_headers_created = AXIS2_TRUE;
+ }
+ sprintf(content_length_str, "%d", response.response_data_length);
+ if(!response.content_type)
+ {
+ content_type_header = axis2_http_header_create(env, "Content-Type",
+ axis2_iis_out_transport_get_content(request.out_transport_info));
+ }
+ else
+ {
+ content_type_header = axis2_http_header_create(env, "Content-Type",
+ response.content_type);
+ }
+ content_length_header = axis2_http_header_create(env, "Content-Length", content_length_str);
+ axutil_array_list_add(response.output_headers, env, content_length_header);
+ axutil_array_list_add(response.output_headers, env, content_type_header);
+ /* Write the headers */
+ start_response(env, lpECB, response.http_status_code, response.http_status_code_name,
+ response.output_headers);
+ /* Write the response body */
+ if(write_response(lpECB, response.response_data, response.response_data_length)
+ == AXIS2_FAILURE)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "IIS: Writing data to IIS");
+ return AXIS2_FAILURE;
+ }
+ if(is_out_headers_created)
+ {
+ if(content_length_header)
+ {
+ axis2_http_header_free(content_length_header, env);
+ }
+ if(content_type_header)
+ {
+ axis2_http_header_free(content_type_header, env);
+ }
+ axutil_array_list_free(response.output_headers, env);
+ }
+ }
+ else
+ {
+ /* If we don't have a body we should write the HTTP headers */
+ start_response(env, lpECB, response.http_status_code, response.http_status_code_name,
+ response.output_headers);
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Response is NULL");
+ }
+
+ /* Do some cleaning */
+ axis2_http_transport_utils_transport_in_uninit(&request, env);
+ axis2_http_transport_utils_transport_out_uninit(&response, env);
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t
+write_response(
+ LPEXTENSION_CONTROL_BLOCK lpECB,
+ const void *b,
+ unsigned int l)
+{
+ if(lpECB && b)
+ {
+ if(l)
+ {
+ unsigned int written = 0;
+ char *buf = (char *)b;
+ /* If couldn't write the data at onece try again until all the data is written.*/
+ while(written < l)
+ {
+ DWORD try_to_write = l - written;
+ if(!lpECB-> WriteClient(lpECB->ConnID, buf + written, &try_to_write, 0))
+ {
+ return AXIS2_FAILURE;
+ }
+ written += try_to_write;
+ }
+ }
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+
+axis2_status_t AXIS2_CALL
+start_response(
+ const axutil_env_t *env,
+ LPEXTENSION_CONTROL_BLOCK lpECB,
+ int status,
+ const char *reason,
+ axutil_array_list_t *headers)
+{
+ static char crlf[3] = { (char)13, (char)10, '\0' };
+ unsigned int num_of_headers = 0;
+
+ if(status < 100 || status > 1000)
+ {
+ return AXIS2_FAILURE;
+ }
+ if(lpECB)
+ {
+ size_t len_of_status;
+ char *status_str;
+ char *headers_str;
+
+ /*
+ * Create the status line
+ */
+ if(reason)
+ {
+ status_str = (char *)_alloca((6 + strlen(reason)) * sizeof(char));
+ sprintf(status_str, "%d %s", status, reason);
+ len_of_status = strlen(status_str);
+ }
+ else
+ {
+ switch(status)
+ {
+ case 200:
+ status_str = reasons[0].status_code;
+ len_of_status = reasons[0].status_len;
+ break;
+ case 202:
+ status_str = reasons[1].status_code;
+ len_of_status = reasons[1].status_len;
+ break;
+ case 500:
+ status_str = reasons[2].status_code;
+ len_of_status = reasons[2].status_len;
+ break;
+ default:
+ status_str = reasons[0].status_code;
+ len_of_status = reasons[0].status_len;
+ break;
+ }
+ }
+ /*
+ * Create response headers string
+ */
+ if(headers && (num_of_headers = axutil_array_list_size(headers, env)) > 0)
+ {
+ size_t i, len_of_headers;
+ axis2_http_header_t *header = NULL;
+ for(i = 0, len_of_headers = 0; i < num_of_headers; i++)
+ {
+ header = axutil_array_list_get(headers, env, (int)i);
+ len_of_headers += strlen(axis2_http_header_get_name(header, env));
+ len_of_headers += strlen(axis2_http_header_get_value(header, env));
+ 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 < num_of_headers; i++)
+ {
+ header = axutil_array_list_get(headers, env, (int)i);
+ strcat(headers_str, axis2_http_header_get_name(header, env));
+ strcat(headers_str, ": ");
+ strcat(headers_str, axis2_http_header_get_value(header, env));
+ strcat(headers_str, "\r\n");
+ }
+ strcat(headers_str, "\r\n");
+ }
+ else
+ {
+ headers_str = crlf;
+ }
+ if(!lpECB-> ServerSupportFunction(lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, status_str,
+ (LPDWORD) & len_of_status, (LPDWORD)headers_str))
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_worker_get_original_url(
+ char url[],
+ char ret_url[])
+{
+ extern axis2_char_t *axis2_location;
+ strcpy(ret_url, axis2_location);
+ strcat(ret_url, &url[25]);
+ return URI_MATCHED;
+}
+
+axis2_char_t * AXIS2_CALL
+axis2_iis_worker_get_bytes(
+ const axutil_env_t * env,
+ axutil_stream_t * stream)
+{
+ axutil_stream_t * tmp_stream = NULL;
+ int return_size = -1;
+ axis2_char_t * buffer = NULL;
+ axis2_bool_t loop_state = AXIS2_TRUE;
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, stream, NULL);
+
+ tmp_stream = axutil_stream_create_basic(env);
+ while(loop_state)
+ {
+ int read = 0;
+ int write = 0;
+ char buf[READ_SIZE];
+
+ read = axutil_stream_read(stream, env, buf, READ_SIZE);
+ if(read < 0)
+ {
+ break;
+ }
+ write = axutil_stream_write(tmp_stream, env, buf, read);
+ if(read < (READ_SIZE - 1))
+ {
+ break;
+ }
+ }
+ return_size = axutil_stream_get_len(tmp_stream, env);
+ if(return_size > 0)
+ {
+ buffer = (char *)AXIS2_MALLOC(env->allocator, sizeof(char) * (return_size + 2));
+ return_size = axutil_stream_read(tmp_stream, env, buffer, return_size + 1);
+ buffer[return_size + 1] = '\0';
+ }
+ axutil_stream_free(tmp_stream, env);
+ return buffer;
+}
+
+/** Read all HTTP headers.
+ */
+axutil_hash_t *
+axis2_iis_worker_read_http_headers(
+ const axutil_env_t * env,
+ LPEXTENSION_CONTROL_BLOCK lpECB)
+{
+ const char szHTTP_[] = "HTTP_";
+ char szBuffer[4096];
+ DWORD dwBufferSize = sizeof szBuffer;
+ axutil_hash_t *headers = NULL;
+ axis2_http_header_t* http_header = NULL;
+
+ BOOL bGet = lpECB->GetServerVariable(lpECB->ConnID, "ALL_HTTP", szBuffer, &dwBufferSize);
+ if(bGet)
+ {
+ /* Find lines, split key/data pair and write them as output */
+ LPTSTR pOpts = NULL;
+ LPTSTR pEnd = NULL;
+ LPTSTR pChar = NULL;
+ char szTmpBuf[512];
+ char szTmpName[256];
+
+ headers = axutil_hash_make(env);
+ szTmpBuf[0] = 0;
+ for(pChar = szBuffer; '\0' != *pChar;)
+ {
+ if(*pChar == '\r' || *pChar == '\n')
+ {
+ pChar++;
+ continue;
+ }
+ pOpts = strchr(pChar, ':');/* findseparator */
+ if(pOpts && *pOpts)
+ {
+ pEnd = pOpts;
+ while(*pEnd && *pEnd != '\r' && *pEnd != '\n')
+ {
+ pEnd++;
+ }
+ *pOpts = '\0'; /* split the strings */
+ *pEnd = '\0';
+ if(0 == strncmp(pChar, szHTTP_, strlen(szHTTP_)))
+ {
+ pChar += strlen(szHTTP_);
+ }
+ strcpy(szTmpName, pChar);
+ axutil_string_replace(szTmpName, '_', '-');
+ http_header = axis2_http_header_create(env, szTmpName, pOpts + 1);
+ axutil_hash_set(headers, axutil_strdup(env, szTmpName), AXIS2_HASH_KEY_STRING,
+ http_header);
+ pChar = pEnd + 1;
+ }
+ }
+ }
+ else
+ {
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "axis2_iis_worker_read_http_headers: no http headers");
+ }
+ return headers;
+}
+
diff --git a/src/core/transport/http/server/IIS/axis2_iis_worker.h b/src/core/transport/http/server/IIS/axis2_iis_worker.h
new file mode 100644
index 0000000..f9b6292
--- /dev/null
+++ b/src/core/transport/http/server/IIS/axis2_iis_worker.h
@@ -0,0 +1,62 @@
+
+/*
+ * 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.
+ */
+
+#ifndef AXIS2_APACHE2_WORKER_H
+#define AXIS2_APACHE2_WORKER_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axis2_conf_ctx.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+
+#endif /*
+ */
+
+typedef struct axis2_iis_worker axis2_iis_worker_t;
+
+int server_version;
+
+int AXIS2_CALL
+ axis2_iis_worker_process_request(
+ axis2_iis_worker_t * iis_worker,
+ const axutil_env_t * env,
+ void *r);
+
+
+void AXIS2_CALL
+ axis2_iis_worker_free(
+ axis2_iis_worker_t * iis_worker,
+ const axutil_env_t * env);
+
+
+axis2_iis_worker_t * AXIS2_CALL
+ axis2_iis_worker_create(
+ const axutil_env_t * env,
+ axis2_char_t * repo_path);
+
+
+#ifdef __cplusplus
+}
+#endif /*
+ */
+
+#endif /* AXIS2_IIS_WORKER_H */
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;
+}
diff --git a/src/core/transport/http/server/IIS/iis_iaspi_plugin_51/axis2_isapi_51.c b/src/core/transport/http/server/IIS/iis_iaspi_plugin_51/axis2_isapi_51.c
new file mode 100644
index 0000000..49cd6d9
--- /dev/null
+++ b/src/core/transport/http/server/IIS/iis_iaspi_plugin_51/axis2_isapi_51.c
@@ -0,0 +1,153 @@
+/*
+ * 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 <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+
+#include "..\\axis2_iis_constants.h"
+
+#define REGISTRY_LOC "Software\\Apache Axis2c\\IIS ISAPI Redirector"
+#define AXIS2_IIS_AXIS2_LOC "axis2_location"
+static char *axis2_loc = "/axis2";
+
+static axis2_char_t redirect_word[INTERNET_MAX_URL_LENGTH] = "/axis2/mod_axis2_IIS.dll\?";
+/*
+ * Search a given uri to find weather it matches a uri for the axis2
+ * The uri format for axis2 is of the form
+ * scheme://server:port/axis2/other_parts
+ * This function search a give uri for the /axis2/. If a match
+ * is found it will replace the /axis2 part of the url with /axis2/mod_iis.dll?
+ */
+axis2_bool_t AXIS2_CALL
+get_extension_url(
+ char url[],
+ char ret_url[]);
+
+/*
+ * This function is called by the IIS server at the server
+ * initialization. So this is the ideal plcae for initializing
+ * axis2c.
+ */
+BOOL WINAPI
+GetFilterVersion(
+ PHTTP_FILTER_VERSION pVer)
+{
+ DWORD type = 0, size = 0;
+ LONG lrc = 0;
+ char tmpbuf[INTERNET_MAX_URL_LENGTH];
+ HKEY hkey;
+ ULONG http_filter_revision = HTTP_FILTER_REVISION;
+ pVer->dwFilterVersion = pVer->dwServerFilterVersion;
+ if(pVer->dwFilterVersion > http_filter_revision)
+ {
+ pVer->dwFilterVersion = http_filter_revision;
+ }
+
+ /*
+ Receive notifictions when
+ 1. Server preprocessed the headers.
+ 2. Log
+ 3. All the request coming in secure and none secure ports.
+ */
+ pVer->dwFlags = (SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_SECURE_PORT
+ | SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_AUTH_COMPLETE);
+
+ /* Give a short discription about the module.*/
+ strcpy(pVer->lpszFilterDesc, "axis2c filter");
+ /* Get the axis2 location from the registry configuration */
+ lrc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_LOC, (DWORD)0, KEY_READ, &hkey);
+ if(ERROR_SUCCESS != lrc)
+ {
+ return FALSE;
+ }
+ size = INTERNET_MAX_URL_LENGTH;
+ lrc = RegQueryValueEx(hkey, AXIS2_IIS_AXIS2_LOC, (LPDWORD)0, &type, (LPBYTE)tmpbuf, &size);
+ if((ERROR_SUCCESS == lrc) && (type == REG_SZ))
+ {
+ tmpbuf[size] = '\0';
+ axis2_loc = _strdup(tmpbuf);
+ }
+ RegCloseKey(hkey);
+ return TRUE;
+}
+
+/*
+ When a notification happens this function is called by the IIS.
+ */
+DWORD WINAPI
+HttpFilterProc(
+ PHTTP_FILTER_CONTEXT pfc,
+ DWORD notificationType,
+ LPVOID pvNotification)
+{
+ DWORD bufferLength = INTERNET_MAX_URL_LENGTH;
+ char url[INTERNET_MAX_URL_LENGTH];
+ char modified_url[INTERNET_MAX_URL_LENGTH];
+
+ if(notificationType == SF_NOTIFY_PREPROC_HEADERS)
+ {
+ pfc->GetServerVariable(pfc, "HTTP_URL", url, &bufferLength);
+ if(get_extension_url(url, modified_url))
+ {
+ ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->SetHeader(pfc, "url", modified_url);
+ return SF_STATUS_REQ_HANDLED_NOTIFICATION;
+ }
+ }
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+}
+
+axis2_bool_t AXIS2_CALL
+get_extension_url(
+ char url[],
+ char ret_url[])
+{
+ axis2_bool_t is_for_us = AXIS2_FALSE;
+ int i = 0;
+ /* Should contain "/axis2/"*/
+ ret_url[0] = '\0';
+ if(strlen(url) >= strlen(axis2_loc))
+ {
+ is_for_us = AXIS2_TRUE;
+ while(axis2_loc[i] != '\0')
+ {
+ if(axis2_loc[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)
+ {
+ strcpy(ret_url, redirect_word);
+ strcat(ret_url, &url[i]);
+ }
+ return is_for_us;
+}
diff --git a/src/core/transport/http/server/IIS/mod_axis2.def b/src/core/transport/http/server/IIS/mod_axis2.def
new file mode 100644
index 0000000..22205e7
--- /dev/null
+++ b/src/core/transport/http/server/IIS/mod_axis2.def
@@ -0,0 +1,7 @@
+LIBRARY "mod_axis2_IIS"
+
+EXPORTS
+ GetExtensionVersion
+ HttpExtensionProc
+ GetFilterVersion
+ HttpFilterProc \ No newline at end of file