From 0425aadc78680e53000fd0108b540d6eca048516 Mon Sep 17 00:00:00 2001 From: gmcdonald Date: Sat, 13 Feb 2010 01:32:03 +0000 Subject: Moving axis svn, part of TLP move INFRA-2441 git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68 --- src/core/transport/http/server/IIS/README | 61 +++ .../http/server/IIS/axis2_iis_constants.h | 51 ++ .../http/server/IIS/axis2_iis_out_transport_info.c | 153 ++++++ .../http/server/IIS/axis2_iis_out_transport_info.h | 61 +++ .../transport/http/server/IIS/axis2_iis_regedit.js | 84 +++ .../transport/http/server/IIS/axis2_iis_stream.c | 313 +++++++++++ .../transport/http/server/IIS/axis2_iis_stream.h | 45 ++ .../transport/http/server/IIS/axis2_iis_worker.c | 607 +++++++++++++++++++++ .../transport/http/server/IIS/axis2_iis_worker.h | 62 +++ .../transport/http/server/IIS/axis2_isapi_plugin.c | 476 ++++++++++++++++ .../IIS/iis_iaspi_plugin_51/axis2_isapi_51.c | 153 ++++++ src/core/transport/http/server/IIS/mod_axis2.def | 7 + 12 files changed, 2073 insertions(+) create mode 100644 src/core/transport/http/server/IIS/README create mode 100644 src/core/transport/http/server/IIS/axis2_iis_constants.h create mode 100644 src/core/transport/http/server/IIS/axis2_iis_out_transport_info.c create mode 100644 src/core/transport/http/server/IIS/axis2_iis_out_transport_info.h create mode 100644 src/core/transport/http/server/IIS/axis2_iis_regedit.js create mode 100644 src/core/transport/http/server/IIS/axis2_iis_stream.c create mode 100644 src/core/transport/http/server/IIS/axis2_iis_stream.h create mode 100644 src/core/transport/http/server/IIS/axis2_iis_worker.c create mode 100644 src/core/transport/http/server/IIS/axis2_iis_worker.h create mode 100644 src/core/transport/http/server/IIS/axis2_isapi_plugin.c create mode 100644 src/core/transport/http/server/IIS/iis_iaspi_plugin_51/axis2_isapi_51.c create mode 100644 src/core/transport/http/server/IIS/mod_axis2.def (limited to 'src/core/transport/http/server/IIS') 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 +#include +#include + +#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 +#include +#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 +#include +#include "axis2_iis_stream.h" +#include + +/** + * @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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "axis2_iis_out_transport_info.h" +#include "axis2_iis_stream.h" +#include "axis2_iis_worker.h" + +/* Files from iis */ +#include +#include + +#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 +#include +#include +#include + +#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 +#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; +} 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#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 -- cgit v1.1-32-gdbae