summaryrefslogtreecommitdiffstats
path: root/src/core/transport/http
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/transport/http')
-rw-r--r--src/core/transport/http/Makefile.am1
-rw-r--r--src/core/transport/http/common/Makefile.am29
-rw-r--r--src/core/transport/http/common/http_accept_record.c165
-rw-r--r--src/core/transport/http/common/http_header.c168
-rw-r--r--src/core/transport/http/common/http_out_transport_info.c353
-rw-r--r--src/core/transport/http/common/http_request_line.c227
-rw-r--r--src/core/transport/http/common/http_response_writer.c176
-rw-r--r--src/core/transport/http/common/http_simple_request.c433
-rw-r--r--src/core/transport/http/common/http_simple_response.c615
-rw-r--r--src/core/transport/http/common/http_status_line.c267
-rw-r--r--src/core/transport/http/common/http_worker.c2064
-rw-r--r--src/core/transport/http/common/simple_http_svr_conn.c504
-rw-r--r--src/core/transport/http/receiver/Makefile.am21
-rw-r--r--src/core/transport/http/receiver/http_receiver.c508
-rw-r--r--src/core/transport/http/receiver/http_svr_thread.c315
-rw-r--r--src/core/transport/http/sender/Makefile.am51
-rw-r--r--src/core/transport/http/sender/http_client.c965
-rw-r--r--src/core/transport/http/sender/http_sender.c3332
-rw-r--r--src/core/transport/http/sender/http_transport_sender.c859
-rw-r--r--src/core/transport/http/sender/libcurl/Makefile.am2
-rw-r--r--src/core/transport/http/sender/libcurl/axis2_libcurl.c1169
-rw-r--r--src/core/transport/http/sender/libcurl/axis2_libcurl.h53
-rw-r--r--src/core/transport/http/sender/libcurl/libcurl_stream.c192
-rw-r--r--src/core/transport/http/sender/libcurl/libcurl_stream.h51
-rw-r--r--src/core/transport/http/sender/ssl/Makefile.am2
-rw-r--r--src/core/transport/http/sender/ssl/ssl_stream.c239
-rw-r--r--src/core/transport/http/sender/ssl/ssl_stream.h50
-rw-r--r--src/core/transport/http/sender/ssl/ssl_utils.c227
-rw-r--r--src/core/transport/http/sender/ssl/ssl_utils.h56
-rw-r--r--src/core/transport/http/server/CGI/Makefile.am31
-rw-r--r--src/core/transport/http/server/CGI/axis2_cgi_main.c280
-rw-r--r--src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.c160
-rw-r--r--src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.h62
-rw-r--r--src/core/transport/http/server/CGI/axis2_cgi_stream.c164
-rw-r--r--src/core/transport/http/server/CGI/axis2_cgi_stream.h44
-rw-r--r--src/core/transport/http/server/CGI/axis2_cgi_types.h34
-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
-rw-r--r--src/core/transport/http/server/Makefile.am2
-rw-r--r--src/core/transport/http/server/apache2/Makefile.am40
-rw-r--r--src/core/transport/http/server/apache2/apache2_out_transport_info.c191
-rw-r--r--src/core/transport/http/server/apache2/apache2_stream.c292
-rw-r--r--src/core/transport/http/server/apache2/apache2_stream.h46
-rw-r--r--src/core/transport/http/server/apache2/apache2_worker.c1687
-rw-r--r--src/core/transport/http/server/apache2/axis2_apache2_out_transport_info.h61
-rw-r--r--src/core/transport/http/server/apache2/axis2_apache2_worker.h78
-rw-r--r--src/core/transport/http/server/apache2/mod_axis2.c844
-rw-r--r--src/core/transport/http/server/simple_axis2_server/Makefile.am30
-rw-r--r--src/core/transport/http/server/simple_axis2_server/http_server_main.c310
-rw-r--r--src/core/transport/http/util/Makefile.am14
-rw-r--r--src/core/transport/http/util/http_transport_utils.c3885
61 files changed, 23422 insertions, 0 deletions
diff --git a/src/core/transport/http/Makefile.am b/src/core/transport/http/Makefile.am
new file mode 100644
index 0000000..cc23d78
--- /dev/null
+++ b/src/core/transport/http/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = sender receiver server
diff --git a/src/core/transport/http/common/Makefile.am b/src/core/transport/http/common/Makefile.am
new file mode 100644
index 0000000..8aaa2c6
--- /dev/null
+++ b/src/core/transport/http/common/Makefile.am
@@ -0,0 +1,29 @@
+lib_LTLIBRARIES = libaxis2_http_common.la
+
+libaxis2_http_common_la_LIBADD=$(top_builddir)/util/src/libaxutil.la\
+ $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la
+
+libaxis2_http_common_la_SOURCES = http_header.c\
+ http_out_transport_info.c\
+ http_request_line.c\
+ http_simple_request.c\
+ http_simple_response.c\
+ http_status_line.c\
+ http_accept_record.c\
+ http_response_writer.c\
+ simple_http_svr_conn.c\
+ http_worker.c
+
+
+libaxis2_http_common_la_LDFLAGS = -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport\
+ -I$(top_builddir)/src/core/transport/http \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
diff --git a/src/core/transport/http/common/http_accept_record.c b/src/core/transport/http/common/http_accept_record.c
new file mode 100644
index 0000000..25f15b1
--- /dev/null
+++ b/src/core/transport/http/common/http_accept_record.c
@@ -0,0 +1,165 @@
+/*
+ * 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_accept_record.h>
+#include <axutil_string.h>
+#include <axutil_types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <axis2_http_transport.h>
+
+struct axis2_http_accept_record
+{
+ axis2_char_t *name;
+ float quality;
+ int level;
+ axis2_char_t *record;
+};
+
+AXIS2_EXTERN axis2_http_accept_record_t *AXIS2_CALL
+axis2_http_accept_record_create(
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ axis2_char_t *tmp_accept_record = NULL;
+ axis2_char_t *tmp = NULL;
+ axis2_http_accept_record_t *accept_record = NULL;
+ float quality = 1.0;
+ int level = -1;
+ axis2_char_t *name = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, str, NULL);
+
+ tmp_accept_record = (axis2_char_t *)axutil_strdup(env, str);
+ if(!tmp_accept_record)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to strdup string %s", str);
+ return NULL;
+ }
+
+ accept_record = (axis2_http_accept_record_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_accept_record_t));
+
+ if(!accept_record)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ memset((void *)accept_record, 0, sizeof(axis2_http_accept_record_t));
+ accept_record->record = axutil_strtrim(env, tmp_accept_record, AXIS2_SPACE_COMMA);
+
+ tmp = strchr(tmp_accept_record, AXIS2_Q);
+ if(tmp)
+ {
+ *tmp = AXIS2_ESC_NULL;
+ tmp++;
+ tmp = axutil_strtrim(env, tmp, AXIS2_EQ_N_SEMICOLON);
+ if(tmp)
+ {
+ sscanf(tmp, "%f", &quality);
+ AXIS2_FREE(env->allocator, tmp);
+ }
+ }
+
+ tmp = strstr(tmp_accept_record, AXIS2_LEVEL);
+ if(tmp)
+ {
+ *tmp = AXIS2_ESC_NULL;
+ tmp++;
+ tmp = axutil_strtrim(env, tmp, AXIS2_EQ_N_SEMICOLON);
+ if(tmp)
+ {
+ sscanf(tmp, "%d", &level);
+ AXIS2_FREE(env->allocator, tmp);
+ }
+ }
+
+ tmp = axutil_strtrim(env, tmp_accept_record, AXIS2_SPACE_SEMICOLON);
+ if(tmp)
+ {
+ name = tmp;
+ }
+
+ if(!name || quality > 1.0 || quality < 0.0)
+ {
+ axis2_http_accept_record_free(accept_record, env);
+ return NULL;
+ }
+
+ accept_record->name = name;
+ accept_record->quality = quality;
+ accept_record->level = level;
+
+ AXIS2_FREE(env->allocator, tmp_accept_record);
+ return accept_record;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_accept_record_free(
+ axis2_http_accept_record_t * accept_record,
+ const axutil_env_t * env)
+{
+
+ if(!accept_record)
+ {
+ return;
+ }
+
+ if(accept_record->name)
+ {
+ AXIS2_FREE(env->allocator, accept_record->name);
+ }
+ if(accept_record->record)
+ {
+ AXIS2_FREE(env->allocator, accept_record->record);
+ }
+ AXIS2_FREE(env->allocator, accept_record);
+ return;
+}
+
+AXIS2_EXTERN float AXIS2_CALL
+axis2_http_accept_record_get_quality_factor(
+ const axis2_http_accept_record_t * accept_record,
+ const axutil_env_t * env)
+{
+ return accept_record->quality;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_accept_record_get_name(
+ const axis2_http_accept_record_t * accept_record,
+ const axutil_env_t * env)
+{
+ return accept_record->name;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_http_accept_record_get_level(
+ const axis2_http_accept_record_t * accept_record,
+ const axutil_env_t * env)
+{
+ return accept_record->level;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_accept_record_to_string(
+ axis2_http_accept_record_t * accept_record,
+ const axutil_env_t * env)
+{
+ return accept_record->record;
+}
diff --git a/src/core/transport/http/common/http_header.c b/src/core/transport/http/common/http_header.c
new file mode 100644
index 0000000..3ea2ffc
--- /dev/null
+++ b/src/core/transport/http/common/http_header.c
@@ -0,0 +1,168 @@
+/*
+ * 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_header.h>
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <stdio.h>
+#include <string.h>
+
+struct axis2_http_header
+{
+ axis2_char_t *name;
+ axis2_char_t *value;
+};
+
+AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL
+axis2_http_header_create(
+ const axutil_env_t * env,
+ const axis2_char_t * name,
+ const axis2_char_t * value)
+{
+ axis2_http_header_t *http_header = NULL;
+ http_header = (axis2_http_header_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_header_t));
+ if(!http_header)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset((void *)http_header, 0, sizeof(axis2_http_header_t));
+ http_header->name = (axis2_char_t *)axutil_strdup(env, name);
+ http_header->value = (axis2_char_t *)axutil_strdup(env, value);
+
+ return http_header;
+}
+
+/**
+ * Creates http header object from a string having format "header_name: header_value"
+ * (e.g. "SOAPAction: urn:hello")
+ * @param env pointer to environment struct
+ * @param str pointer to str
+ */
+AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL
+axis2_http_header_create_by_str(
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ axis2_char_t *tmp_str = NULL;
+ axis2_char_t *ch = NULL;
+ axis2_char_t *ch2 = NULL;
+ axis2_http_header_t *ret = NULL;
+ int tmp_str_len = 0;
+ AXIS2_PARAM_CHECK(env->error, str, NULL);
+
+ /*
+ tmp_str = axutil_strdup(env, str);
+ if(!tmp_str)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to strdup string, %s", str);
+ return NULL;
+ }
+ */
+ /*
+ * strdup is removed to increase the performance. This method is called from
+ * axis2_simple_http_svr_conn_read_request and axis2_http_client_recieve_header and both of them
+ * passes a temporary string. hence we can modify the contents without doing a strdup.
+ * Above code is commented after 1.6.0 . If no issue is found until 1.8.0, above can be removed
+ */
+ tmp_str = (axis2_char_t *)str;
+
+ /* remove trailing \r\n */
+ tmp_str_len = axutil_strlen(tmp_str);
+ if((tmp_str_len >= 2) && (AXIS2_RETURN == tmp_str[tmp_str_len - 2]))
+ {
+ tmp_str[tmp_str_len - 2] = AXIS2_ESC_NULL;
+ }
+
+ /* get http header */
+ ch = strchr((const char *)tmp_str, AXIS2_COLON);
+ if(!ch)
+ {
+ /*AXIS2_FREE(env->allocator, tmp_str);*/
+ return NULL;
+ }
+ *ch = AXIS2_ESC_NULL;
+
+ /* get http header value */
+ ch2 = ++ch;
+
+ /* skip spaces */
+ while(AXIS2_SPACE == *ch2)
+ {
+ ++ch2;
+ }
+
+ ret = axis2_http_header_create(env, tmp_str, ch2);
+ /*AXIS2_FREE(env->allocator, tmp_str);*/
+ return ret;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_header_free(
+ axis2_http_header_t * http_header,
+ const axutil_env_t * env)
+{
+
+ if(!http_header)
+ {
+ return;
+ }
+
+ if(http_header->name)
+ {
+ AXIS2_FREE(env->allocator, http_header->name);
+ }
+ if(http_header->value)
+ {
+ AXIS2_FREE(env->allocator, http_header->value);
+ }
+
+ AXIS2_FREE(env->allocator, http_header);
+ return;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_header_to_external_form(
+ axis2_http_header_t * http_header,
+ const axutil_env_t * env)
+{
+ axis2_ssize_t len = 0;
+ axis2_char_t *external_form = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, http_header, NULL);
+
+ len = axutil_strlen(http_header->name) + axutil_strlen(http_header->value) + 8;
+ external_form = (axis2_char_t *)AXIS2_MALLOC(env->allocator, len);
+ sprintf(external_form, "%s: %s%s", http_header->name, http_header->value, AXIS2_HTTP_CRLF);
+ return external_form;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_header_get_name(
+ const axis2_http_header_t * http_header,
+ const axutil_env_t * env)
+{
+ return http_header->name;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_header_get_value(
+ const axis2_http_header_t * http_header,
+ const axutil_env_t * env)
+{
+ return http_header->value;
+}
diff --git a/src/core/transport/http/common/http_out_transport_info.c b/src/core/transport/http/common/http_out_transport_info.c
new file mode 100644
index 0000000..b70ee6c
--- /dev/null
+++ b/src/core/transport/http/common/http_out_transport_info.c
@@ -0,0 +1,353 @@
+/*
+ * 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_out_transport_info.h>
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <axutil_string.h>
+
+#define AXIS2_INTF_TO_IMPL(out_transport_info) \
+ ((axis2_http_out_transport_info_t *) \
+ (out_transport_info))
+
+axis2_status_t AXIS2_CALL
+axis2_out_transport_info_impl_set_content_type(
+ axis2_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * content_type)
+{
+ axis2_http_out_transport_info_t *http_transport_info = NULL;
+ http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info);
+ return axis2_http_out_transport_info_set_content_type(http_transport_info, env, content_type);
+}
+
+axis2_status_t AXIS2_CALL
+axis2_out_transport_info_impl_set_char_encoding(
+ axis2_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * encoding)
+{
+ axis2_http_out_transport_info_t *http_transport_info = NULL;
+ http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info);
+ return axis2_http_out_transport_info_set_char_encoding(http_transport_info, env, encoding);
+}
+
+axis2_status_t AXIS2_CALL
+axis2_out_transport_info_impl_set_cookie_header(
+ axis2_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * set_cookie)
+{
+ axis2_http_out_transport_info_t *http_transport_info = NULL;
+ http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info);
+ return axis2_http_out_transport_info_set_cookie_header(http_transport_info, env, set_cookie);
+}
+
+axis2_status_t AXIS2_CALL
+axis2_out_transport_info_impl_set_session(
+ axis2_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * session_id,
+ const axis2_char_t * session_value)
+{
+ axis2_http_out_transport_info_t *http_transport_info = NULL;
+ http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info);
+ return axis2_http_out_transport_info_set_session(http_transport_info, env, session_id,
+ session_value);
+}
+
+void AXIS2_CALL
+axis2_out_transport_info_impl_free(
+ axis2_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env)
+{
+ axis2_http_out_transport_info_t *http_transport_info = NULL;
+ http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info);
+ axis2_http_out_transport_info_free(http_transport_info, env);
+ return;
+}
+
+static const axis2_out_transport_info_ops_t ops_var = {
+ axis2_out_transport_info_impl_set_content_type,
+ axis2_out_transport_info_impl_set_char_encoding,
+ axis2_out_transport_info_impl_set_cookie_header,
+ axis2_out_transport_info_impl_set_session,
+ axis2_out_transport_info_impl_free };
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_out_transport_info_impl_set_content_type(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * content_type)
+{
+ axis2_char_t *tmp1 = NULL;
+ axis2_char_t *tmp2 = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE);
+ if(http_out_transport_info->encoding)
+ {
+ axis2_char_t *charset_pos = axutil_strcasestr(content_type, AXIS2_CHARSET);
+ if(!charset_pos)
+ {
+ /* if "charset" not found in content_type string */
+ tmp1 = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_CHARSET);
+ tmp2 = axutil_stracat(env, tmp1, http_out_transport_info->encoding);
+ axis2_http_simple_response_set_header(http_out_transport_info-> response, env,
+ axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, tmp2));
+ AXIS2_FREE(env->allocator, tmp1);
+ AXIS2_FREE(env->allocator, tmp2);
+ }
+ else
+ {
+ /* "charset" is found in content_type string */
+ axis2_http_simple_response_set_header(http_out_transport_info-> response, env,
+ axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, content_type));
+ }
+ }
+ else
+ {
+ /* no http_out_transport_info->encoding */
+ if(http_out_transport_info->response)
+ {
+ axis2_http_simple_response_set_header(http_out_transport_info-> response, env,
+ axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, content_type));
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_out_transport_info_impl_set_char_encoding(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * encoding)
+{
+ AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE);
+ if(http_out_transport_info->encoding)
+ {
+ AXIS2_FREE(env->allocator, http_out_transport_info->encoding);
+ }
+ http_out_transport_info->encoding = axutil_strdup(env, encoding);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_out_transport_info_impl_set_cookie_header(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * set_cookie)
+{
+ AXIS2_PARAM_CHECK(env->error, set_cookie, AXIS2_FAILURE);
+ if(http_out_transport_info->response)
+ {
+ axis2_http_simple_response_set_header(http_out_transport_info-> response, env,
+ axis2_http_header_create(env, AXIS2_HTTP_HEADER_SET_COOKIE, set_cookie));
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_out_transport_info_impl_set_session(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * session_id,
+ const axis2_char_t * session_value)
+{
+ AXIS2_PARAM_CHECK(env->error, session_id, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, session_value, AXIS2_FAILURE);
+ if(http_out_transport_info->server)
+ {
+ env->set_session_fn((void *) http_out_transport_info->server, session_id, session_value);
+ }
+ return AXIS2_SUCCESS;
+}
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_out_transport_info_impl_free(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env)
+{
+
+ if(!http_out_transport_info)
+ {
+ return;
+ }
+
+ if(http_out_transport_info->response)
+ {
+ axis2_http_simple_response_free(http_out_transport_info->response, env);
+ }
+ if(http_out_transport_info->encoding)
+ {
+ AXIS2_FREE(env->allocator, http_out_transport_info->encoding);
+ }
+ AXIS2_FREE(env->allocator, http_out_transport_info);
+ return;
+}
+
+AXIS2_EXTERN axis2_http_out_transport_info_t *AXIS2_CALL
+axis2_http_out_transport_info_create(
+ const axutil_env_t * env,
+ axis2_http_simple_response_t * response)
+{
+ axis2_http_out_transport_info_t *http_out_transport_info = NULL;
+
+ http_out_transport_info = (axis2_http_out_transport_info_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_out_transport_info_t));
+
+ if(!http_out_transport_info)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset((void *)http_out_transport_info, 0, sizeof(axis2_http_out_transport_info_t));
+ http_out_transport_info->out_transport.ops = &ops_var;
+ http_out_transport_info->response = response;
+ http_out_transport_info->encoding = NULL;
+ http_out_transport_info->set_char_encoding = NULL;
+ http_out_transport_info->set_content_type = NULL;
+ http_out_transport_info->set_cookie_header = NULL;
+ http_out_transport_info->set_session = NULL;
+ http_out_transport_info->free_function = NULL;
+
+ http_out_transport_info->set_char_encoding
+ = axis2_http_out_transport_info_impl_set_char_encoding;
+ http_out_transport_info->set_content_type = axis2_http_out_transport_info_impl_set_content_type;
+ http_out_transport_info->set_cookie_header = axis2_http_out_transport_info_impl_set_cookie_header;
+ http_out_transport_info->set_session = axis2_http_out_transport_info_impl_set_session;
+ http_out_transport_info->free_function = axis2_http_out_transport_info_impl_free;
+
+ return http_out_transport_info;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_out_transport_info_free(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env)
+{
+ http_out_transport_info->free_function(http_out_transport_info, env);
+ return;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_out_transport_info_free_void_arg(
+ void *transport_info,
+ const axutil_env_t * env)
+{
+ axis2_http_out_transport_info_t *transport_info_l = NULL;
+
+ transport_info_l = AXIS2_INTF_TO_IMPL(transport_info);
+ axis2_http_out_transport_info_free(transport_info_l, env);
+ return;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_out_transport_info_set_content_type(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * content_type)
+{
+ return http_out_transport_info->set_content_type(http_out_transport_info, env, content_type);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_out_transport_info_set_char_encoding(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * encoding)
+{
+ return http_out_transport_info->set_char_encoding(http_out_transport_info, env, encoding);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_out_transport_info_set_cookie_header(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * set_cookie)
+{
+ return http_out_transport_info->set_cookie_header(http_out_transport_info, env, set_cookie);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_out_transport_info_set_session(
+ axis2_http_out_transport_info_t * http_out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * session_id,
+ const axis2_char_t * session_value)
+{
+ return http_out_transport_info->set_session(http_out_transport_info, env, session_id,
+ session_value);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_out_transport_info_set_char_encoding_func(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ axis2_status_t(AXIS2_CALL * set_char_encoding)
+ (axis2_http_out_transport_info_t *,
+ const axutil_env_t *,
+ const axis2_char_t *))
+{
+ out_transport_info->set_char_encoding = set_char_encoding;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_out_transport_info_set_content_type_func(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ axis2_status_t(AXIS2_CALL *
+ set_content_type) (axis2_http_out_transport_info_t *,
+ const axutil_env_t *,
+ const axis2_char_t *))
+{
+ out_transport_info->set_content_type = set_content_type;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_out_transport_info_set_cookie_header_func(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ axis2_status_t(AXIS2_CALL *
+ set_cookie_header) (axis2_http_out_transport_info_t *,
+ const axutil_env_t *,
+ const axis2_char_t *))
+{
+ out_transport_info->set_cookie_header = set_cookie_header;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_out_transport_info_set_session_func(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ axis2_status_t(AXIS2_CALL *
+ set_session) (axis2_http_out_transport_info_t *,
+ const axutil_env_t *,
+ const axis2_char_t *,
+ const axis2_char_t *))
+{
+ out_transport_info->set_session = set_session;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_out_transport_info_set_free_func(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ void (AXIS2_CALL * free_function) (axis2_http_out_transport_info_t *,
+ const axutil_env_t *))
+{
+ out_transport_info->free_function = free_function;
+}
+
diff --git a/src/core/transport/http/common/http_request_line.c b/src/core/transport/http/common/http_request_line.c
new file mode 100644
index 0000000..f12cbba
--- /dev/null
+++ b/src/core/transport/http/common/http_request_line.c
@@ -0,0 +1,227 @@
+/*
+ * 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_request_line.h>
+#include <axutil_string.h>
+#include <string.h>
+#include <axis2_http_transport.h>
+#include <stdio.h>
+
+struct axis2_http_request_line
+{
+ axis2_char_t *http_version;
+ axis2_char_t *method;
+ axis2_char_t *uri;
+};
+
+AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL
+axis2_http_request_line_create(
+ const axutil_env_t * env,
+ const axis2_char_t * method,
+ const axis2_char_t * uri,
+ const axis2_char_t * http_version)
+{
+ axis2_http_request_line_t *request_line = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, method, NULL);
+ AXIS2_PARAM_CHECK(env->error, uri, NULL);
+ AXIS2_PARAM_CHECK(env->error, http_version, NULL);
+
+ request_line = (axis2_http_request_line_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_request_line_t));
+
+ if(!request_line)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset((void *)request_line, 0, sizeof(axis2_http_request_line_t));
+ request_line->method = (axis2_char_t *)axutil_strdup(env, method);
+ request_line->uri = (axis2_char_t *)axutil_strdup(env, uri);
+ request_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version);
+
+ return request_line;
+}
+
+void AXIS2_CALL
+axis2_http_request_line_free(
+ axis2_http_request_line_t * request_line,
+ const axutil_env_t * env)
+{
+
+ if(!request_line)
+ {
+ return;
+ }
+
+ if(request_line->method)
+ {
+ AXIS2_FREE(env->allocator, request_line->method);
+ }
+ if(request_line->uri)
+ {
+ AXIS2_FREE(env->allocator, request_line->uri);
+ }
+ if(request_line->http_version)
+ {
+ AXIS2_FREE(env->allocator, request_line->http_version);
+ }
+
+ AXIS2_FREE(env->allocator, request_line);
+ return;
+}
+
+/**
+ * Parses a line "<http method> <uri location> <http version>CRLF" and creates http_request_line
+ * object. E.g "POST /axis2/services/echo HTTP/1.1\r\n"
+ * @param env pointer to environment struct
+ * @param str pointer to the line to be parsed
+ * @return created object if success. NULL otherwise
+ */
+AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL
+axis2_http_request_line_parse_line(
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ /*axis2_char_t *req_line = NULL;*/
+ axis2_char_t *method = NULL;
+ axis2_char_t *uri = NULL;
+ axis2_char_t *http_version = NULL;
+ axis2_http_request_line_t *ret = NULL;
+ axis2_char_t *tmp = NULL;
+ int i = 0;
+
+ if(!str)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid parameter is given to parse");
+ return NULL;
+ }
+
+ tmp = axutil_strstr(str, AXIS2_HTTP_CRLF);
+ if(!tmp)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ i = (int)(tmp - str); /* We are sure that the difference lies within the int range */
+
+ /*
+ req_line = AXIS2_MALLOC(env->allocator, i * sizeof(axis2_char_t) + 1);
+ if(!req_line)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memcpy(req_line, str, i * sizeof(axis2_char_t));
+ req_line[i] = AXIS2_ESC_NULL;
+ tmp = req_line;
+ */
+ /* we don't need to do a malloc and memcpy, because this method is only used by
+ * axis2_simple_http_svr_conn_read_request and it passes a temporary string. So, we can just
+ * set it as req_line and set the escape characters. this is done after 1.6.0 and if no issues
+ * found until 1.8.0, above code comment can be removed after 1.8.0
+ */
+
+ tmp = (axis2_char_t *)str;
+ tmp[i] = AXIS2_ESC_NULL;
+
+ /* find http method */
+ method = tmp;
+ tmp = strchr(tmp, AXIS2_SPACE);
+ if(!tmp)
+ {
+ /*AXIS2_FREE(env->allocator, req_line);*/
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ *tmp++ = AXIS2_ESC_NULL;
+
+ /* find URI */
+ uri = tmp;
+ tmp = strrchr(tmp, AXIS2_SPACE);
+ if(!tmp)
+ {
+ /*AXIS2_FREE(env->allocator, req_line);*/
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ *tmp++ = AXIS2_ESC_NULL;
+
+ /* find HTTP version */
+ http_version = tmp;
+ ret = axis2_http_request_line_create(env, method, uri, http_version);
+ /*AXIS2_FREE(env->allocator, req_line);*/
+
+ return ret;
+}
+
+axis2_char_t *AXIS2_CALL
+axis2_http_request_line_get_method(
+ const axis2_http_request_line_t * request_line,
+ const axutil_env_t * env)
+{
+ return request_line->method;
+}
+
+axis2_char_t *AXIS2_CALL
+axis2_http_request_line_get_http_version(
+ const axis2_http_request_line_t * request_line,
+ const axutil_env_t * env)
+{
+ return request_line->http_version;
+}
+
+axis2_char_t *AXIS2_CALL
+axis2_http_request_line_get_uri(
+ const axis2_http_request_line_t * request_line,
+ const axutil_env_t * env)
+{
+ return request_line->uri;
+}
+
+axis2_char_t *AXIS2_CALL
+axis2_http_request_line_to_string(
+ axis2_http_request_line_t * request_line,
+ const axutil_env_t * env)
+{
+ int alloc_len = 0;
+ axis2_char_t *ret = NULL;
+
+ alloc_len = axutil_strlen(request_line->method) + axutil_strlen(request_line->uri)
+ + axutil_strlen(request_line->http_version) + 6;
+ /* 5 = 2 * spaces + '/' +CR + LF + '\0' */
+
+ ret = AXIS2_MALLOC(env->allocator, alloc_len * sizeof(axis2_char_t));
+ if(!ret)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ if(request_line->uri[0] != AXIS2_F_SLASH)
+ {
+ sprintf(ret, "%s /%s %s%s", request_line->method, request_line->uri,
+ request_line->http_version, AXIS2_HTTP_CRLF);
+ }
+ else
+ {
+ sprintf(ret, "%s %s %s%s", request_line->method, request_line->uri,
+ request_line->http_version, AXIS2_HTTP_CRLF);
+ }
+ return ret;
+}
diff --git a/src/core/transport/http/common/http_response_writer.c b/src/core/transport/http/common/http_response_writer.c
new file mode 100644
index 0000000..eec2422
--- /dev/null
+++ b/src/core/transport/http/common/http_response_writer.c
@@ -0,0 +1,176 @@
+/*
+ * 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_response_writer.h>
+#include <axutil_array_list.h>
+#include <axis2_http_transport.h>
+#include <axutil_string.h>
+
+struct axis2_http_response_writer
+{
+ axutil_stream_t *stream;
+ axis2_char_t *encoding;
+};
+
+AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL
+axis2_http_response_writer_create(
+ const axutil_env_t * env,
+ axutil_stream_t * stream)
+{
+ return axis2_http_response_writer_create_with_encoding(env, stream,
+ AXIS2_HTTP_DEFAULT_CONTENT_CHARSET);
+}
+
+AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL
+axis2_http_response_writer_create_with_encoding(
+ const axutil_env_t * env,
+ axutil_stream_t * stream,
+ const axis2_char_t * encoding)
+{
+ axis2_http_response_writer_t *response_writer = NULL;
+ response_writer = (axis2_http_response_writer_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_response_writer_t));
+ if(!response_writer)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ response_writer->stream = stream;
+ response_writer->encoding = (axis2_char_t *)axutil_strdup(env, encoding);
+ return response_writer;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_response_writer_free(
+ axis2_http_response_writer_t * response_writer,
+ const axutil_env_t * env)
+{
+ AXIS2_FREE(env->allocator, response_writer->encoding);
+ AXIS2_FREE(env->allocator, response_writer);
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_response_writer_get_encoding(
+ const axis2_http_response_writer_t * response_writer,
+ const axutil_env_t * env)
+{
+ return response_writer->encoding;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_response_writer_write_char(
+ axis2_http_response_writer_t * response_writer,
+ const axutil_env_t * env,
+ char c)
+{
+ int write = -1;
+ if(!response_writer->stream)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ write = axutil_stream_write(response_writer->stream, env, &c, 1);
+ if(write < 0)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_response_writer_write_buf(
+ axis2_http_response_writer_t * response_writer,
+ const axutil_env_t * env,
+ char *buf,
+ int offset,
+ axis2_ssize_t len)
+{
+ int write = -1;
+
+ AXIS2_PARAM_CHECK(env->error, response_writer, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE);
+
+ if(!response_writer->stream)
+ {
+ return AXIS2_FAILURE;
+ }
+ write = axutil_stream_write(response_writer->stream, env, buf, len);
+ if(write < 0)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_response_writer_print_str(
+ axis2_http_response_writer_t * response_writer,
+ const axutil_env_t * env,
+ const char *str)
+{
+ int write = -1;
+ int len = -1;
+
+ len = axutil_strlen(str);
+ if(!response_writer->stream)
+ {
+ return AXIS2_FAILURE;
+ }
+ write = axutil_stream_write(response_writer->stream, env, str, len);
+
+ if(write < 0)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "failed to write to stream string %s of length %d", str, len);
+ return AXIS2_FAILURE;
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_response_writer_print_int(
+ axis2_http_response_writer_t * response_writer,
+ const axutil_env_t * env,
+ int i)
+{
+ axis2_char_t int_str[10];
+ sprintf(int_str, "%10d", i);
+ return axis2_http_response_writer_print_str(response_writer, env, int_str);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_response_writer_println_str(
+ axis2_http_response_writer_t * response_writer,
+ const axutil_env_t * env,
+ const char *str)
+{
+ if(AXIS2_SUCCESS == axis2_http_response_writer_print_str(response_writer, env, str))
+ {
+ return axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF);
+ }
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_response_writer_println(
+ axis2_http_response_writer_t * response_writer,
+ const axutil_env_t * env)
+{
+ return axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF);
+}
diff --git a/src/core/transport/http/common/http_simple_request.c b/src/core/transport/http/common/http_simple_request.c
new file mode 100644
index 0000000..9e10ce1
--- /dev/null
+++ b/src/core/transport/http/common/http_simple_request.c
@@ -0,0 +1,433 @@
+/*
+ * 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_simple_request.h>
+#include <axutil_array_list.h>
+#include <axis2_http_transport.h>
+#include <axutil_string.h>
+#include <string.h>
+#include <axutil_types.h>
+
+struct axis2_http_simple_request
+{
+ axis2_http_request_line_t *request_line;
+ axutil_array_list_t *header_group;
+ axutil_stream_t *stream;
+ axis2_bool_t owns_stream;
+};
+
+AXIS2_EXTERN axis2_http_simple_request_t *AXIS2_CALL
+axis2_http_simple_request_create(
+ const axutil_env_t * env,
+ axis2_http_request_line_t * request_line,
+ axis2_http_header_t ** http_headers,
+ axis2_ssize_t http_hdr_count,
+ axutil_stream_t * content)
+{
+ axis2_http_simple_request_t *simple_request = NULL;
+ simple_request = (axis2_http_simple_request_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_simple_request_t));
+ if(!simple_request)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ memset((void *)simple_request, 0, sizeof(axis2_http_simple_request_t));
+ simple_request->request_line = request_line;
+ simple_request->stream = content;
+
+ if(!(simple_request->stream))
+ {
+ simple_request->stream = axutil_stream_create_basic(env);
+ if(!simple_request->stream)
+ {
+ axis2_http_simple_request_free(simple_request, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ simple_request->owns_stream = AXIS2_TRUE;
+ }
+
+ if((http_hdr_count > 0) && http_headers)
+ {
+ int i = 0;
+ simple_request->header_group = axutil_array_list_create(env, http_hdr_count);
+
+ for(i = 0; i < (int)http_hdr_count; i++)
+ /* We are sure that the difference lies within the int range */
+ {
+ axutil_array_list_add(simple_request->header_group, env, (void *)http_headers[i]);
+ }
+ }
+
+ return simple_request;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_simple_request_free(
+ axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env)
+{
+ /* free the stream only if we own it. Otherwise shouldn't free the stream
+ * since it belongs to the socket
+ */
+ if(simple_request->owns_stream)
+ {
+ axutil_stream_free(simple_request->stream, env);
+ }
+
+ if(simple_request->request_line)
+ {
+ axis2_http_request_line_free(simple_request->request_line, env);
+ }
+
+ if(simple_request->header_group)
+ {
+ int i = 0;
+ axis2_http_header_t *tmp = NULL;
+ for(i = 0; i < axutil_array_list_size(simple_request->header_group, env); i++)
+ {
+ tmp = (axis2_http_header_t*)axutil_array_list_get(simple_request->header_group, env, i);
+ axis2_http_header_free(tmp, env);
+ }
+ axutil_array_list_free(simple_request->header_group, env);
+ }
+ AXIS2_FREE(env->allocator, simple_request);
+}
+
+AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL
+axis2_http_simple_request_get_request_line(
+ const axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env)
+{
+ return simple_request->request_line;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_simple_request_set_request_line(
+ axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env,
+ axis2_http_request_line_t * request_line)
+{
+ AXIS2_PARAM_CHECK(env->error, request_line, AXIS2_FAILURE);
+ simple_request->request_line = request_line;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_simple_request_contains_header(
+ axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env,
+ const axis2_char_t * name)
+{
+ int i = 0;
+ axis2_char_t *header_name = NULL;
+ int count = 0;
+
+ AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE);
+
+ if(!simple_request->header_group)
+ {
+ AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI,
+ "http simple request \
+does not contain headers, unable to find: %s header", name);
+ return AXIS2_FALSE;
+ }
+
+ count = axutil_array_list_size(simple_request->header_group, env);
+
+ if(0 == count)
+ {
+ AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI,
+ "http simple request \
+contains zero headers, unable to find: %s header", name);
+ return AXIS2_FALSE;
+ }
+
+ for(i = 0; i < count; i++)
+ {
+ header_name = axis2_http_header_get_name((axis2_http_header_t *)axutil_array_list_get(
+ simple_request->header_group, env, i), env);
+ if(0 == axutil_strcasecmp(name, header_name))
+ {
+ return AXIS2_TRUE;
+ }
+ }
+ return AXIS2_FALSE;
+}
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axis2_http_simple_request_get_headers(
+ const axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env)
+{
+ return simple_request->header_group;
+}
+
+AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL
+axis2_http_simple_request_get_first_header(
+ const axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ axutil_array_list_t *header_group = NULL;
+ int i = 0;
+ int count = 0;
+
+ AXIS2_PARAM_CHECK(env->error, str, NULL);
+
+ header_group = simple_request->header_group;
+ if(!simple_request->header_group)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "http simple request does not contain any headers; unable to find: %s header", str);
+ return NULL;
+ }
+
+ if(0 == axutil_array_list_size(header_group, env))
+ {
+ AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI,
+ "http simple request contain zero headers, unable to find: %s header", str);
+ return NULL;
+ }
+
+ count = axutil_array_list_size(header_group, env);
+ for(i = 0; i < count; i++)
+ {
+ axis2_http_header_t *tmp_header = NULL;
+ axis2_char_t *tmp_name = NULL;
+ tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i);
+ tmp_name = axis2_http_header_get_name(tmp_header, env);
+ if(0 == axutil_strcasecmp(str, tmp_name))
+ {
+ return tmp_header;
+ }
+ }
+ return NULL;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_simple_request_remove_headers(
+ axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ axis2_http_header_t *tmp_header = NULL;
+ axis2_char_t *tmp_name = NULL;
+ int i = 0;
+ int count = 0;
+ axutil_array_list_t *header_group = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE);
+
+ header_group = simple_request->header_group;
+
+ if(!header_group)
+ {
+ /* Even though we couldn't complete the op, we are sure that the
+ * requred header is no more in the request. So we can proceed without a
+ * problem.
+ */
+ return AXIS2_SUCCESS;
+ }
+
+ count = axutil_array_list_size(header_group, env);
+
+ for(i = 0; i < count; i++)
+ {
+ tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i);
+ tmp_name = axis2_http_header_get_name(tmp_header, env);
+ if(0 == axutil_strcasecmp(str, tmp_name))
+ {
+ axis2_http_header_free(tmp_header, env);
+ axutil_array_list_remove(header_group, env, i);
+ break;
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_simple_request_add_header(
+ axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env,
+ axis2_http_header_t * header)
+{
+ AXIS2_PARAM_CHECK(env->error, header, AXIS2_FAILURE);
+
+ if(!simple_request->header_group)
+ {
+ simple_request->header_group = axutil_array_list_create(env, 1);
+ }
+ return axutil_array_list_add(simple_request->header_group, env, header);
+}
+
+AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
+axis2_http_simple_request_get_content_type(
+ const axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env)
+{
+ axis2_http_header_t *tmp_header = NULL;
+
+ tmp_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if(tmp_header)
+ {
+ return axis2_http_header_get_value(tmp_header, env);
+ }
+
+ return AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN;
+}
+
+AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
+axis2_http_simple_request_get_charset(
+ const axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env)
+{
+ axis2_http_header_t *tmp_header = NULL;
+
+ tmp_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if(tmp_header)
+ {
+ axis2_char_t *value = axis2_http_header_get_value(tmp_header, env);
+ axis2_char_t *charset = (axis2_char_t *)strstr((char *)value,
+ (char *)AXIS2_HTTP_CHAR_SET_ENCODING);
+ if(charset)
+ {
+ charset = strchr((char *)charset, AXIS2_EQ);
+ return charset;
+ }
+ }
+
+ return AXIS2_HTTP_DEFAULT_CONTENT_CHARSET;
+}
+
+AXIS2_EXTERN axis2_ssize_t AXIS2_CALL
+axis2_http_simple_request_get_content_length(
+ const axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env)
+{
+ axis2_http_header_t *tmp_header = NULL;
+ int error_return = -1;
+
+ tmp_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH);
+ if(tmp_header)
+ {
+ return AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env));
+ }
+ return error_return;
+}
+
+AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+axis2_http_simple_request_get_body(
+ const axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env)
+{
+ return simple_request->stream;
+}
+
+AXIS2_EXTERN axis2_ssize_t AXIS2_CALL
+axis2_http_simple_request_get_body_bytes(
+ const axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env,
+ char **buf)
+{
+ axutil_stream_t *body = NULL;
+ char *tmp_buf = NULL;
+ char *tmp_buf2 = NULL;
+ char *tmp_buf3 = NULL;
+ int length = 0;
+ int read_len = 0;
+
+ body = simple_request->stream;
+ if(!body)
+ {
+ *buf = (char *)AXIS2_MALLOC(env->allocator, 1);
+ *buf[0] = '\0';
+ return 0;
+ }
+
+ length = axis2_http_simple_request_get_content_length(simple_request, env);
+ if(length > 0)
+ {
+ *buf = (char *)AXIS2_MALLOC(env->allocator, length + 1);
+ read_len = axutil_stream_read(body, env, *buf, length + 1);
+ return read_len;
+ }
+
+ tmp_buf2 = AXIS2_MALLOC(env->allocator, 128 * sizeof(char));
+ while(axutil_stream_read(body, env, tmp_buf2, 128) > 0)
+ {
+ tmp_buf3 = axutil_stracat(env, tmp_buf, tmp_buf2);
+ if(tmp_buf)
+ {
+ AXIS2_FREE(env->allocator, tmp_buf);
+ tmp_buf = NULL;
+ }
+ tmp_buf = tmp_buf3;
+
+ }
+
+ if(tmp_buf2)
+ {
+ AXIS2_FREE(env->allocator, tmp_buf2);
+ tmp_buf2 = NULL;
+ }
+
+ if(tmp_buf)
+ {
+ *buf = tmp_buf;
+ return axutil_strlen(tmp_buf);
+ }
+
+ *buf = (char *)AXIS2_MALLOC(env->allocator, 1);
+ *buf[0] = AXIS2_ESC_NULL;
+ return 0;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_simple_request_set_body_string(
+ axis2_http_simple_request_t * simple_request,
+ const axutil_env_t * env,
+ void *str,
+ unsigned int str_len)
+{
+ axutil_stream_t *body_stream = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE);
+
+ body_stream = simple_request->stream;
+ if(!body_stream)
+ {
+ body_stream = axutil_stream_create_basic(env);
+ if(!body_stream)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "unable to create stream\
+for stream %s of %d length", (axis2_char_t *)str, str_len);
+ return AXIS2_FAILURE;
+ }
+ simple_request->stream = body_stream;
+ simple_request->owns_stream = AXIS2_TRUE;
+ }
+
+ axutil_stream_write(body_stream, env, str, str_len);
+ return AXIS2_SUCCESS;
+}
diff --git a/src/core/transport/http/common/http_simple_response.c b/src/core/transport/http/common/http_simple_response.c
new file mode 100644
index 0000000..74acb80
--- /dev/null
+++ b/src/core/transport/http/common/http_simple_response.c
@@ -0,0 +1,615 @@
+/*
+ * 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_simple_response.h>
+#include <axis2_http_transport.h>
+#include <axutil_string.h>
+#include <stdio.h>
+#include <string.h>
+#include <axutil_types.h>
+#include <axiom_mime_part.h>
+
+#define AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE 2048
+
+struct axis2_http_simple_response
+{
+ axis2_http_status_line_t *status_line;
+ axutil_array_list_t *header_group;
+ axutil_stream_t *stream;
+ axutil_array_list_t *mime_parts;
+ axis2_char_t *mtom_sending_callback_name;
+};
+
+AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL
+axis2_http_simple_response_create(
+ const axutil_env_t * env,
+ axis2_http_status_line_t * status_line,
+ const axis2_http_header_t ** http_headers,
+ const axis2_ssize_t http_hdr_count,
+ axutil_stream_t * content)
+{
+ axis2_http_simple_response_t *ret = NULL;
+ ret = axis2_http_simple_response_create_default(env);
+ if(!ret)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 http simple response creation failed");
+ return NULL;
+ }
+
+ ret->status_line = status_line;
+ if(http_hdr_count > 0 && http_headers)
+ {
+ int i = 0;
+ ret->header_group = axutil_array_list_create(env, http_hdr_count);
+
+ for(i = 0; i < (int)http_hdr_count; i++)
+ /* We are sure that the difference lies within the int range */
+ {
+ axutil_array_list_add(ret->header_group, env, (void *)http_headers[i]);
+ }
+ }
+ ret->stream = content;
+ return ret;
+}
+
+AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL
+axis2_http_simple_response_create_default(
+ const axutil_env_t * env)
+{
+ axis2_http_simple_response_t *simple_response = NULL;
+ simple_response = (axis2_http_simple_response_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_simple_response_t));
+ if(!simple_response)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ memset((void *)simple_response, 0, sizeof(axis2_http_simple_response_t));
+ return simple_response;
+}
+
+void AXIS2_CALL
+axis2_http_simple_response_free(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ if(simple_response->status_line)
+ {
+ axis2_http_status_line_free(simple_response->status_line, env);
+ }
+
+ if(simple_response->header_group)
+ {
+ int i = 0;
+ for(i = 0; i < axutil_array_list_size(simple_response->header_group, env); i++)
+ {
+ void *tmp = NULL;
+ tmp = axutil_array_list_get(simple_response-> header_group, env, i);
+ if(tmp)
+ {
+ axis2_http_header_free((axis2_http_header_t *)tmp, env);
+ }
+ }
+ axutil_array_list_free(simple_response->header_group, env);
+ }
+
+ if(simple_response->mime_parts)
+ {
+ int i = 0;
+ for(i = 0; i < axutil_array_list_size(simple_response->mime_parts, env); i++)
+ {
+ void *mime_part = NULL;
+ mime_part = axutil_array_list_get(simple_response->mime_parts, env, i);
+ if(mime_part)
+ {
+ axiom_mime_part_free((axiom_mime_part_t *)mime_part, env);
+ }
+ }
+ axutil_array_list_free(simple_response->mime_parts, env);
+ }
+
+ /* Stream is not freed. Assumption : stream doesn't belong to the response */
+
+ AXIS2_FREE(env->allocator, simple_response);
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_simple_response_set_status_line(
+ struct axis2_http_simple_response * simple_response,
+ const axutil_env_t * env,
+ const axis2_char_t * http_ver,
+ const int status_code,
+ const axis2_char_t * phrase)
+{
+ if(!http_ver || !phrase || !status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "invalid parameter given");
+ return AXIS2_FAILURE;
+ }
+
+ if(simple_response->status_line)
+ {
+ axis2_http_status_line_free(simple_response->status_line, env);
+ }
+
+ simple_response->status_line = axis2_http_status_line_create_with_values(
+ env, http_ver, status_code, phrase);
+ if(!simple_response->status_line)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "http status line creation failed for string %s %3d %s", http_ver, status_code, phrase);
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+axis2_char_t *AXIS2_CALL
+axis2_http_simple_response_get_phrase(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ if(!(simple_response->status_line))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "axis2 simple response , status line is not available");
+ return NULL;
+ }
+
+ return axis2_http_status_line_get_reason_phrase(simple_response-> status_line, env);
+}
+
+int AXIS2_CALL
+axis2_http_simple_response_get_status_code(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ if(!(simple_response->status_line))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "axis2 simple response , status line is not available");
+ return -1;
+ }
+ return axis2_http_status_line_get_status_code(simple_response->status_line, env);
+}
+
+axis2_char_t *AXIS2_CALL
+axis2_http_simple_response_get_http_version(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ if(!(simple_response->status_line))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "axis2 simple response , status line is not available");
+
+ return NULL;
+ }
+ return axis2_http_status_line_get_http_version(simple_response->status_line, env);
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_simple_response_set_http_version(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ axis2_char_t *http_version)
+{
+ if(!(simple_response->status_line))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "axis2 simple response , status line is not available");
+
+ return AXIS2_FAILURE;
+ }
+ axis2_http_status_line_set_http_version(simple_response->status_line, env, http_version);
+ return AXIS2_SUCCESS;
+}
+
+axis2_char_t *AXIS2_CALL
+axis2_http_simple_response_get_status_line(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+
+ if(!(simple_response->status_line))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "axis2 simple response , status line is not available");
+
+ return NULL;
+ }
+ return axis2_http_status_line_to_string(simple_response->status_line, env);
+}
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axis2_http_simple_response_get_headers(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ return simple_response->header_group;
+}
+
+axutil_array_list_t *AXIS2_CALL
+axis2_http_simple_response_extract_headers(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ axutil_array_list_t *temp = NULL;
+ temp = simple_response->header_group;
+ if(temp)
+ {
+ simple_response->header_group = NULL;
+ }
+ return temp;
+}
+
+axis2_http_header_t *AXIS2_CALL
+axis2_http_simple_response_get_first_header(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ axis2_http_header_t *tmp_header = NULL;
+ axis2_char_t *tmp_name = NULL;
+ int i = 0;
+ int count = 0;
+ axutil_array_list_t *header_group = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, str, NULL);
+
+ header_group = simple_response->header_group;
+ if(!simple_response->header_group)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 simple response , headers not available");
+ return NULL;
+ }
+
+ if(0 == axutil_array_list_size(header_group, env))
+ {
+ AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "axis2 simple response , contains zero headers");
+
+ return NULL;
+ }
+
+ count = axutil_array_list_size(header_group, env);
+
+ for(i = 0; i < count; i++)
+ {
+ tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i);
+ tmp_name = axis2_http_header_get_name(tmp_header, env);
+ if(0 == axutil_strcasecmp(str, tmp_name))
+ {
+ return tmp_header;
+ }
+ }
+ return NULL;
+
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_simple_response_remove_headers(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ axutil_array_list_t *header_group = NULL;
+ int i = 0;
+ int count = 0;
+
+ AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE);
+
+ header_group = simple_response->header_group;
+ if(!header_group)
+ {
+ /* Even though we couldn't complete the op, we are sure that the
+ * required header is no more in the request. So we can proceed without a
+ * problem.
+ */
+ return AXIS2_SUCCESS;
+ }
+
+ count = axutil_array_list_size(header_group, env);
+ for(i = 0; i < count; i++)
+ {
+ axis2_http_header_t *tmp_header = NULL;
+ axis2_char_t *tmp_name = NULL;
+ tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i);
+ tmp_name = axis2_http_header_get_name(tmp_header, env);
+ if(0 == axutil_strcasecmp(str, tmp_name))
+ {
+ axis2_http_header_free(tmp_header, env);
+ axutil_array_list_remove(header_group, env, i);
+ break;
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_simple_response_set_header(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ axis2_http_header_t * header)
+{
+ int i = 0;
+ int count = 0;
+ axutil_array_list_t *header_group = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, header, AXIS2_FAILURE);
+
+ if(!simple_response->header_group)
+ {
+ simple_response->header_group = axutil_array_list_create(env, 10);
+ axutil_array_list_add(simple_response->header_group, env, header);
+ return AXIS2_SUCCESS;
+ }
+
+ /* If a header with the same name exists search and remove the old header */
+ header_group = simple_response->header_group;
+ count = axutil_array_list_size(header_group, env);
+ for(i = 0; i < count; i++)
+ {
+ axis2_http_header_t *tmp_header = NULL;
+ axis2_char_t *tmp_name = NULL;
+ tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i);
+ tmp_name = axis2_http_header_get_name(tmp_header, env);
+ if(0 == axutil_strcasecmp(axis2_http_header_get_name(header, env), tmp_name))
+ {
+ axis2_http_header_free(tmp_header, env);
+ axutil_array_list_set(header_group, env, i, header);
+ return AXIS2_SUCCESS;
+ }
+ }
+
+ /* if header is not found, then we have to add it */
+ axutil_array_list_add(header_group, env, header);
+ return AXIS2_SUCCESS;
+}
+
+const axis2_char_t *AXIS2_CALL
+axis2_http_simple_response_get_charset(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ axis2_http_header_t *tmp_header = NULL;
+
+ tmp_header = axis2_http_simple_response_get_first_header(simple_response, env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if(tmp_header)
+ {
+ axis2_char_t *value = axis2_http_header_get_value(tmp_header, env);
+ axis2_char_t *charset = (axis2_char_t *)strstr((char *)value,
+ (char *)AXIS2_HTTP_CHAR_SET_ENCODING);
+ if(charset)
+ {
+ charset = strchr((char *)charset, AXIS2_EQ);
+ return charset;
+ }
+ }
+
+ return AXIS2_HTTP_DEFAULT_CONTENT_CHARSET;
+}
+
+axis2_ssize_t AXIS2_CALL
+axis2_http_simple_response_get_content_length(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ axis2_http_header_t *tmp_header = NULL;
+ int error_return = -1;
+
+ tmp_header = axis2_http_simple_response_get_first_header(simple_response, env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH);
+ if(tmp_header)
+ {
+ return AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env));
+ }
+ return error_return;
+}
+
+const axis2_char_t *AXIS2_CALL
+axis2_http_simple_response_get_content_type(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ axis2_http_header_t *tmp_header = NULL;
+
+ tmp_header = axis2_http_simple_response_get_first_header(simple_response, env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if(tmp_header)
+ {
+ return axis2_http_header_get_value(tmp_header, env);
+ }
+
+ return AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_simple_response_set_body_string(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ axis2_char_t * str)
+{
+ axutil_stream_t *body_stream = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE);
+
+ body_stream = simple_response->stream;
+ if(!body_stream)
+ {
+ body_stream = axutil_stream_create_basic(env);
+ if(!body_stream)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to create basic stream for string %s",
+ str);
+ return AXIS2_FAILURE;
+ }
+ simple_response->stream = body_stream;
+ }
+ axutil_stream_write(body_stream, env, str, axutil_strlen(str));
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_simple_response_set_body_stream(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ axutil_stream_t * stream)
+{
+ /*
+ * We don't free the stream
+ * Problem in freeing is most of the time the stream doesn't belong
+ * to the http_simple_response
+ */
+ simple_response->stream = stream;
+ return AXIS2_SUCCESS;
+}
+
+axutil_stream_t *AXIS2_CALL
+axis2_http_simple_response_get_body(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ return simple_response->stream;
+}
+
+axis2_ssize_t AXIS2_CALL
+axis2_http_simple_response_get_body_bytes(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ axis2_char_t ** buffer)
+{
+ axutil_stream_t *tmp_stream = NULL;
+ axis2_bool_t loop_state = AXIS2_TRUE;
+ int return_size = -1;
+
+ if(!simple_response->stream)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_BODY, AXIS2_FAILURE);
+ return return_size;
+ }
+ tmp_stream = axutil_stream_create_basic(env);
+ while(loop_state)
+ {
+ int read = 0;
+ int write = 0;
+ char buf[AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE];
+
+ read = axutil_stream_read(simple_response->stream, env, buf,
+ AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE);
+ if(read < 0)
+ {
+ break;
+ }
+ write = axutil_stream_write(tmp_stream, env, buf, read);
+ if(read < (AXIS2_HTTP_SIMPLE_RESPONSE_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 + 1));
+
+ if(!buffer)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return -1;
+ }
+
+ return_size = axutil_stream_read(tmp_stream, env, *buffer, return_size + 1);
+ }
+ axutil_stream_free(tmp_stream, env);
+ return return_size;
+}
+
+axis2_bool_t AXIS2_CALL
+axis2_http_simple_response_contains_header(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ const axis2_char_t * name)
+{
+ axis2_char_t *header_name = NULL;
+ int count = 0;
+ int i = 0;
+
+ AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE);
+ if(!simple_response->header_group)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 simple response , headers not available");
+ return AXIS2_FALSE;
+ }
+
+ count = axutil_array_list_size(simple_response->header_group, env);
+ if(0 == count)
+ {
+ AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "axis2 simple response , contains zero headers");
+ return AXIS2_FALSE;
+ }
+
+ for(i = 0; i < count; i++)
+ {
+ axis2_http_header_t *header = (axis2_http_header_t *)axutil_array_list_get(
+ simple_response->header_group, env, i);
+ header_name = axis2_http_header_get_name(header, env);
+ if(0 == axutil_strcasecmp(name, header_name))
+ {
+ return AXIS2_TRUE;
+ }
+ }
+ return AXIS2_FALSE;
+}
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axis2_http_simple_response_get_mime_parts(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+
+ return simple_response->mime_parts;
+
+}
+
+void AXIS2_EXTERN AXIS2_CALL
+axis2_http_simple_response_set_mime_parts(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ axutil_array_list_t *mime_parts)
+{
+
+ simple_response->mime_parts = mime_parts;
+
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_simple_response_get_mtom_sending_callback_name(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env)
+{
+ return simple_response->mtom_sending_callback_name;
+}
+
+void AXIS2_EXTERN AXIS2_CALL
+axis2_http_simple_response_set_mtom_sending_callback_name(
+ axis2_http_simple_response_t * simple_response,
+ const axutil_env_t * env,
+ axis2_char_t *mtom_sending_callback_name)
+{
+ simple_response->mtom_sending_callback_name =
+ mtom_sending_callback_name;
+}
diff --git a/src/core/transport/http/common/http_status_line.c b/src/core/transport/http/common/http_status_line.c
new file mode 100644
index 0000000..fdf0fea
--- /dev/null
+++ b/src/core/transport/http/common/http_status_line.c
@@ -0,0 +1,267 @@
+/*
+ * 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_status_line.h>
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <string.h>
+#include <stdio.h>
+#include <axutil_types.h>
+
+struct axis2_http_status_line
+{
+ axis2_char_t *line;
+ axis2_char_t *http_version;
+ axis2_char_t *status_code;
+ axis2_char_t *reason_phrase;
+};
+
+AXIS2_EXTERN axis2_http_status_line_t *AXIS2_CALL
+axis2_http_status_line_create(
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ axis2_char_t *tmp_status_line = NULL;
+ axis2_char_t *reason_phrase = NULL;
+ axis2_char_t *status_code = NULL;
+ axis2_char_t *http_version = NULL;
+ int i = 0;
+ axis2_char_t *tmp = NULL;
+ axis2_http_status_line_t *status_line = NULL;
+
+ status_line = (axis2_http_status_line_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_status_line_t));
+
+ if(!status_line)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset((void *)status_line, 0, sizeof(axis2_http_status_line_t));
+ status_line->line = (axis2_char_t *)axutil_strdup(env, str);
+
+ /* extract status code, phrase and version from given string */
+ tmp = strstr(str, AXIS2_HTTP_CRLF);
+ if(!tmp)
+ {
+ axis2_http_status_line_free(status_line, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ i = (int)(tmp - str); /* We are sure that the difference lies within the int range */
+
+ tmp_status_line = AXIS2_MALLOC(env->allocator, i * sizeof(axis2_char_t) + 1);
+ if(!tmp_status_line)
+ {
+ axis2_http_status_line_free(status_line, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memcpy(tmp_status_line, str, i * sizeof(axis2_char_t));
+ tmp_status_line[i] = AXIS2_ESC_NULL;
+ tmp = tmp_status_line;
+
+ /* get HTTP version */
+ http_version = tmp;
+ tmp = strchr(tmp, AXIS2_SPACE);
+ if(!tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp_status_line);
+ axis2_http_status_line_free(status_line, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ *tmp++ = AXIS2_ESC_NULL;
+
+ /* get status code */
+ status_code = tmp;
+ tmp = strchr(tmp, AXIS2_SPACE);
+ if(!tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp_status_line);
+ axis2_http_status_line_free(status_line, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ *tmp++ = AXIS2_ESC_NULL;
+
+ /* get reason phrase */
+ reason_phrase = tmp;
+
+ /* populate values */
+ status_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version);
+ status_line->status_code = (axis2_char_t *)axutil_strdup(env, status_code);
+ status_line->reason_phrase = (axis2_char_t *)axutil_strdup(env, reason_phrase);
+ AXIS2_FREE(env->allocator, tmp_status_line);
+
+ if(!status_line->http_version || !status_line->reason_phrase || !status_line->status_code)
+ {
+ axis2_http_status_line_free(status_line, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ return status_line;
+}
+
+AXIS2_EXTERN axis2_http_status_line_t *AXIS2_CALL
+axis2_http_status_line_create_with_values(
+ const axutil_env_t * env,
+ const axis2_char_t * http_ver,
+ const int status_code,
+ const axis2_char_t * phrase)
+{
+ axis2_http_status_line_t *status_line = NULL;
+ status_line = (axis2_http_status_line_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_status_line_t));
+ if(!status_line)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset((void *)status_line, 0, sizeof(axis2_http_status_line_t));
+
+ status_line->status_code = AXIS2_MALLOC(env->allocator, 6 * sizeof(axis2_char_t *));
+ if(!status_line->status_code)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ axis2_http_status_line_free(status_line, env);
+ return NULL;
+ }
+ sprintf(status_line->status_code, "%3d", status_code);
+
+ status_line->http_version = axutil_strdup(env, http_ver);
+ status_line->reason_phrase = axutil_strdup(env, phrase);
+ if(!status_line->http_version || !status_line->reason_phrase)
+ {
+ axis2_http_status_line_free(status_line, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ status_line->line = axutil_strcat(env, http_ver, " ", status_line->status_code, " ", phrase,
+ AXIS2_HTTP_CRLF, NULL);
+ if(!status_line->line)
+ {
+ axis2_http_status_line_free(status_line, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ return status_line;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_status_line_free(
+ axis2_http_status_line_t * status_line,
+ const axutil_env_t * env)
+{
+
+ if(!status_line)
+ {
+ return;
+ }
+
+ if(status_line->line)
+ {
+ AXIS2_FREE(env->allocator, status_line->line);
+ }
+ if(status_line->http_version)
+ {
+ AXIS2_FREE(env->allocator, status_line->http_version);
+ }
+ if(status_line->status_code)
+ {
+ AXIS2_FREE(env->allocator, status_line->status_code);
+ }
+ if(status_line->reason_phrase)
+ {
+ AXIS2_FREE(env->allocator, status_line->reason_phrase);
+ }
+
+ AXIS2_FREE(env->allocator, status_line);
+ return;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_http_status_line_get_status_code(
+ const axis2_http_status_line_t * status_line,
+ const axutil_env_t * env)
+{
+ if(status_line->status_code)
+ {
+ return AXIS2_ATOI(status_line->status_code);
+ }
+ else
+ {
+ return AXIS2_CRITICAL_FAILURE;
+ }
+
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_status_line_get_http_version(
+ const axis2_http_status_line_t * status_line,
+ const axutil_env_t * env)
+{
+ return status_line->http_version;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_status_line_set_http_version(
+ axis2_http_status_line_t * status_line,
+ const axutil_env_t * env,
+ axis2_char_t *http_version)
+{
+ if(status_line->http_version)
+ {
+ AXIS2_FREE(env->allocator, status_line->http_version);
+ status_line->http_version = NULL;
+ }
+
+ status_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version);
+
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_status_line_get_reason_phrase(
+ const axis2_http_status_line_t * status_line,
+ const axutil_env_t * env)
+{
+ return status_line->reason_phrase;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_status_line_starts_with_http(
+ axis2_http_status_line_t * status_line,
+ const axutil_env_t * env)
+{
+ if(0 == axutil_strncasecmp(status_line->line, AXIS2_HTTP, 4))
+ {
+ return AXIS2_TRUE;
+ }
+ return AXIS2_FALSE;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_status_line_to_string(
+ axis2_http_status_line_t * status_line,
+ const axutil_env_t * env)
+{
+ return status_line->line;
+}
diff --git a/src/core/transport/http/common/http_worker.c b/src/core/transport/http/common/http_worker.c
new file mode 100644
index 0000000..26ccce3
--- /dev/null
+++ b/src/core/transport/http/common/http_worker.c
@@ -0,0 +1,2064 @@
+/*
+ * 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_worker.h>
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <axis2_conf.h>
+#include <axutil_string.h>
+#include <axis2_msg_ctx.h>
+#include <axis2_http_request_line.h>
+#include <axis2_http_out_transport_info.h>
+#include <axis2_http_transport_utils.h>
+#include <axis2_http_accept_record.h>
+#include <axis2_op_ctx.h>
+#include <axis2_engine.h>
+#include <axutil_uuid_gen.h>
+#include <axutil_url.h>
+#include <axutil_property.h>
+#include <axiom_soap.h>
+#include <string.h>
+#include <axutil_string_util.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <platforms/axutil_platform_auto_sense.h>
+
+struct axis2_http_worker
+{
+ axis2_conf_ctx_t *conf_ctx;
+ int svr_port;
+ axis2_bool_t is_application_client_side;
+};
+
+static axis2_status_t
+axis2_http_worker_set_response_headers(
+ axis2_http_worker_t * http_worker,
+ const axutil_env_t * env,
+ axis2_simple_http_svr_conn_t * svr_conn,
+ axis2_http_simple_request_t * simple_request,
+ axis2_http_simple_response_t * simple_response,
+ axis2_ssize_t content_length);
+
+static axutil_hash_t *
+axis2_http_worker_get_headers(
+ axis2_http_worker_t * http_worker,
+ const axutil_env_t * env,
+ axis2_http_simple_request_t * request);
+
+static axis2_http_simple_response_t *
+axis2_http_worker_create_simple_response(
+ axis2_http_worker_t *http_worker,
+ const axutil_env_t *env);
+
+AXIS2_EXTERN axis2_http_worker_t *AXIS2_CALL
+axis2_http_worker_create(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ axis2_http_worker_t *http_worker = NULL;
+
+ http_worker = (axis2_http_worker_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_worker_t));
+
+ if(!http_worker)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ http_worker->conf_ctx = conf_ctx;
+ http_worker->svr_port = 9090; /* default - must set later */
+ http_worker->is_application_client_side = AXIS2_FALSE; /* default is creating for application
+ server side */
+
+ return http_worker;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_worker_free(
+ axis2_http_worker_t * http_worker,
+ const axutil_env_t * env)
+{
+ http_worker->conf_ctx = NULL;
+ AXIS2_FREE(env->allocator, http_worker);
+ return;
+}
+
+/* Each in-coming request is passed into this function for process. Basically http method to deliver
+ * is deduced here and call appropriate http processing function.
+ * eg. transport_utils_process_http_post_request() function. Once this function call done it will go
+ * through engine inflow phases and finally hit the message receiver for the operation.
+ */
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_worker_process_request(
+ axis2_http_worker_t * http_worker,
+ const axutil_env_t * env,
+ axis2_simple_http_svr_conn_t * svr_conn,
+ axis2_http_simple_request_t * simple_request)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axutil_stream_t *request_body = NULL;
+
+ /* Creating out_stream as basic stream */
+ axutil_stream_t *out_stream = axutil_stream_create_basic(env);
+ axis2_http_simple_response_t *response = NULL;
+
+ /* Transport in and out descriptions */
+ axis2_transport_out_desc_t *out_desc = NULL;
+ axis2_transport_in_desc_t *in_desc = NULL;
+
+ axis2_char_t *http_version = NULL;
+ axis2_char_t *soap_action = NULL;
+ axutil_string_t *soap_action_str = NULL;
+ axis2_bool_t processed = AXIS2_FALSE;
+ axis2_status_t status = AXIS2_FAILURE;
+ int content_length = -1;
+ axis2_http_header_t *encoding_header = NULL;
+ axis2_char_t *encoding_header_value = NULL;
+ axis2_op_ctx_t *op_ctx = NULL;
+ axis2_char_t *svr_ip = NULL;
+ axis2_char_t *peer_ip = NULL;
+ axutil_url_t *request_url = NULL;
+ axis2_http_out_transport_info_t *http_out_transport_info = NULL;
+ axutil_hash_t *headers = NULL;
+ axis2_char_t *url_external_form = NULL;
+ axis2_char_t *svc_grp_uuid = NULL;
+ axis2_char_t *path = NULL;
+ axutil_property_t *peer_property = NULL;
+
+ /* REST processing variables */
+ axis2_bool_t is_get = AXIS2_FALSE;
+ axis2_bool_t is_head = AXIS2_FALSE;
+ axis2_bool_t is_put = AXIS2_FALSE;
+ axis2_bool_t is_delete = AXIS2_FALSE;
+ axis2_bool_t request_handled = AXIS2_FALSE;
+
+ /* HTTP and Proxy authentication */
+ axis2_char_t *cookie_header_value = NULL;
+ /*axis2_char_t *set_cookie_header_value = NULL;
+ axis2_http_header_t *set_cookie_header = NULL;
+ axis2_http_header_t *connection_header = NULL;*/
+ axis2_http_header_t *cookie_header = NULL;
+ axis2_char_t *accept_header_value = NULL;
+ axis2_http_header_t *accept_header = NULL;
+ axis2_char_t *accept_charset_header_value = NULL;
+ axis2_http_header_t *accept_charset_header = NULL;
+ axis2_char_t *accept_language_header_value = NULL;
+ axis2_http_header_t *accept_language_header = NULL;
+
+ axis2_char_t *http_method = NULL;
+ axis2_http_request_line_t *request_line = NULL;
+
+ axutil_hash_t *request_params = NULL;
+ axis2_char_t *request_uri = NULL;
+ axis2_char_t *url_ext_form = NULL;
+ const axis2_char_t *content_type = NULL;
+
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svr_conn, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, simple_request, AXIS2_FALSE);
+
+ conf_ctx = http_worker->conf_ctx;
+ if(!conf_ctx)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE);
+ return AXIS2_FALSE;
+ }
+
+ content_length = axis2_http_simple_request_get_content_length(simple_request, env);
+ request_line = axis2_http_simple_request_get_request_line(simple_request, env);
+ http_method = axis2_http_request_line_get_method(request_line, env);
+
+ http_version = axis2_http_request_line_get_http_version(request_line, env);
+ if(!http_version)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE);
+ return AXIS2_FALSE;
+ }
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Client HTTP version %s", http_version);
+
+ encoding_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING);
+ if(encoding_header)
+ {
+ encoding_header_value = axis2_http_header_get_value(encoding_header, env);
+ }
+
+ response = axis2_http_worker_create_simple_response(http_worker, env);
+ if(!response)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot create http simple response");
+ return AXIS2_FALSE;
+ }
+
+ /* if length is not given and it is not chunked, then return error to client */
+ if((content_length < 0) && encoding_header_value
+ && (0 != axutil_strcmp(encoding_header_value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)))
+ {
+ if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_POST)
+ || 0 == axutil_strcasecmp(http_method, AXIS2_HTTP_PUT))
+ {
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_LENGTH_REQUIRED_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_LENGTH_REQUIRED_CODE_NAME);
+
+ status = axis2_simple_http_svr_conn_write_response(svr_conn, env, response);
+ axis2_http_simple_response_free(response, env);
+ return status;
+ }
+ }
+
+ request_body = axis2_http_simple_request_get_body(simple_request, env);
+
+ out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(conf_ctx, env), env,
+ AXIS2_TRANSPORT_ENUM_HTTP);
+ in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(conf_ctx, env), env,
+ AXIS2_TRANSPORT_ENUM_HTTP);
+
+ msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc);
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+ cookie_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_COOKIE);
+ if(cookie_header)
+ {
+ char *session_str = NULL;
+ axis2_char_t *session_id = NULL;
+
+ cookie_header_value = axis2_http_header_get_value(cookie_header, env);
+ session_id = axis2_http_transport_utils_get_session_id_from_cookie(env,
+ cookie_header_value);
+ if(session_id)
+ session_str = env->get_session_fn((void *) conf_ctx, session_id);
+ if(session_str)
+ axis2_http_transport_utils_set_session(env, msg_ctx, session_str);
+ }
+
+ /*connection_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_CONNECTION);
+ if(connection_header)
+ {
+ axutil_property_t *connection_header_property = NULL;
+ axis2_char_t *connection_header_value = NULL;
+ connection_header_value = axis2_http_header_get_value(connection_header, env);
+ connection_header_property = axutil_property_create_with_args(env,
+ AXIS2_SCOPE_REQUEST, 0, 0, connection_header_value);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONNECTION,
+ connection_header_property);
+ }*/
+
+ /* Server and Peer IP's */
+ svr_ip = axis2_simple_http_svr_conn_get_svr_ip(svr_conn, env);
+ peer_ip = axis2_simple_http_svr_conn_get_peer_ip(svr_conn, env);
+
+ if(peer_ip)
+ {
+ peer_property = axutil_property_create(env);
+ axutil_property_set_value(peer_property, env, axutil_strdup(env, peer_ip));
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_SVR_PEER_IP_ADDR, peer_property);
+ }
+
+ path = axis2_http_request_line_get_uri(request_line, env);
+
+ request_url = axutil_url_create(env, AXIS2_HTTP_PROTOCOL, svr_ip, http_worker->svr_port, path);
+ if(request_url)
+ {
+ url_external_form = axutil_url_to_external_form(request_url, env);
+ }
+
+ if(!url_external_form)
+ {
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL, AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME);
+ status = axis2_simple_http_svr_conn_write_response(svr_conn, env, response);
+ axis2_http_simple_response_free(response, env);
+ response = NULL;
+ return status;
+ }
+
+ accept_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_ACCEPT);
+ if(accept_header)
+ {
+ accept_header_value = axis2_http_header_get_value(accept_header, env);
+ }
+ if(accept_header_value)
+ {
+ axutil_array_list_t *accept_header_field_list = NULL;
+ axutil_array_list_t *accept_record_list = NULL;
+ accept_header_field_list = axutil_tokenize(env, accept_header_value, AXIS2_COMMA);
+ if(accept_header_field_list && axutil_array_list_size(accept_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_header_field_list, env, 0);
+ }
+ while(token);
+ }
+ if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0)
+ {
+ axis2_msg_ctx_set_http_accept_record_list(msg_ctx, env, accept_record_list);
+ }
+ }
+
+ accept_charset_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_ACCEPT_CHARSET);
+ if(accept_charset_header)
+ {
+ accept_charset_header_value = axis2_http_header_get_value(accept_charset_header, env);
+ }
+ if(accept_charset_header_value)
+ {
+ axutil_array_list_t *accept_charset_header_field_list = NULL;
+ axutil_array_list_t *accept_charset_record_list = NULL;
+ accept_charset_header_field_list = axutil_tokenize(env, accept_charset_header_value,
+ AXIS2_COMMA);
+ if(accept_charset_header_field_list && axutil_array_list_size(
+ accept_charset_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_charset_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_charset_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_charset_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_charset_header_field_list,
+ env, 0);
+ }
+ while(token);
+ }
+
+ if(accept_charset_record_list && axutil_array_list_size(accept_charset_record_list, env)
+ > 0)
+ {
+ axis2_msg_ctx_set_http_accept_charset_record_list(msg_ctx, env,
+ accept_charset_record_list);
+ }
+ }
+
+ accept_language_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_ACCEPT_LANGUAGE);
+ if(accept_language_header)
+ {
+ accept_language_header_value = axis2_http_header_get_value(accept_language_header, env);
+ }
+
+ if(accept_language_header_value)
+ {
+ axutil_array_list_t *accept_language_header_field_list = NULL;
+ axutil_array_list_t *accept_language_record_list = NULL;
+ accept_language_header_field_list = axutil_tokenize(env, accept_language_header_value,
+ AXIS2_COMMA);
+ if(accept_language_header_field_list && axutil_array_list_size(
+ accept_language_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_language_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_language_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_language_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_language_header_field_list,
+ env, 0);
+ }
+ while(token);
+ }
+ if(accept_language_record_list && axutil_array_list_size(accept_language_record_list, env)
+ > 0)
+ {
+ axis2_msg_ctx_set_http_accept_language_record_list(msg_ctx, env,
+ accept_language_record_list);
+ }
+ }
+
+ /* Here out_stream is set into the in message context. out_stream is copied from in message context
+ * into the out message context later in core_utils_create_out_msg_ctx() function. The buffer in
+ * out_stream is finally filled with the soap envelope in http_transport_sender_invoke() function.
+ * To avoid double freeing of out_stream we reset the out message context at the end of engine
+ * receive function.
+ */
+ axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream);
+
+ headers = axis2_http_worker_get_headers(http_worker, env, simple_request);
+ axis2_msg_ctx_set_transport_headers(msg_ctx, env, headers);
+
+ svc_grp_uuid = axutil_uuid_gen(env);
+ if(svc_grp_uuid)
+ {
+ axutil_string_t *svc_grp_uuid_str = axutil_string_create_assume_ownership(env,
+ &svc_grp_uuid);
+ axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, svc_grp_uuid_str);
+ axutil_string_free(svc_grp_uuid_str, env);
+ }
+
+ http_out_transport_info = axis2_http_out_transport_info_create(env, response);
+ axis2_msg_ctx_set_out_transport_info(msg_ctx, env, &(http_out_transport_info->out_transport));
+
+ if(axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_SOAP_ACTION))
+ {
+ soap_action = axis2_http_header_get_value(axis2_http_simple_request_get_first_header(
+ simple_request, env, AXIS2_HTTP_HEADER_SOAP_ACTION), env);
+ soap_action_str = axutil_string_create(env, soap_action);
+ }
+
+ if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_GET))
+ {
+ is_get = AXIS2_TRUE;
+ }
+ else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_HEAD))
+ {
+ is_head = AXIS2_TRUE;
+ }
+ else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_DELETE))
+ {
+ is_delete = AXIS2_TRUE;
+ }
+ else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_PUT))
+ {
+ is_put = AXIS2_TRUE;
+ }
+
+ request_uri = axis2_http_request_line_get_uri(request_line, env);
+ request_params = axis2_http_transport_utils_get_request_params(env, request_uri);
+ url_ext_form = axutil_url_to_external_form(request_url, env);
+
+ content_type = axis2_http_simple_request_get_content_type(simple_request, env);
+
+ if(is_get || is_head || is_delete)
+ {
+
+ if(is_get)
+ {
+ /* HTTP GET */
+ processed = axis2_http_transport_utils_process_http_get_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx,
+ request_params);
+ }
+ else if(is_delete)
+ {
+ /* HTTP DELETE */
+ processed = axis2_http_transport_utils_process_http_delete_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx,
+ request_params);
+ }
+ else if(is_head)
+ {
+ /* HTTP HEAD */
+ processed = axis2_http_transport_utils_process_http_head_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx,
+ request_params);
+ }
+
+ if(AXIS2_FALSE == processed)
+ {
+ axis2_http_header_t *cont_len = NULL;
+ axis2_http_header_t *cont_type = NULL;
+ axis2_char_t *body_string = NULL;
+ axis2_char_t *wsdl = NULL;
+ axis2_bool_t is_services_path = AXIS2_FALSE;
+
+ if(!is_delete)
+ {
+ axis2_char_t *temp = NULL;
+ /* check whether request url have "/services" */
+ temp = strstr(axutil_url_get_path(request_url, env), AXIS2_REQUEST_URL_PREFIX);
+ if(temp)
+ {
+ temp += strlen(AXIS2_REQUEST_URL_PREFIX);
+ if(*temp == AXIS2_F_SLASH)
+ {
+ temp++;
+ }
+ if(!*temp || *temp == AXIS2_Q_MARK || *temp == AXIS2_H_MARK)
+ {
+ is_services_path = AXIS2_TRUE;
+ }
+ }
+
+ }
+
+ /* processing request for WSDL via "?wsdl" */
+ wsdl = strstr(url_external_form, AXIS2_REQUEST_WSDL);
+ if(is_services_path)
+ {
+ /* request for service */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_OK_CODE_VAL, AXIS2_HTTP_RESPONSE_OK_CODE_NAME);
+ body_string = axis2_http_transport_utils_get_services_html(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(!is_delete && wsdl)
+ {
+ /* Request is not for delete and ask for wsdl */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_OK_CODE_VAL, AXIS2_HTTP_RESPONSE_OK_CODE_NAME);
+ body_string = axis2_http_transport_utils_get_services_static_wsdl(env, conf_ctx,
+ url_external_form);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_APPLICATION_XML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND)
+ {
+
+ /* Processing SVC or Operation Not found case */
+ axutil_array_list_t *method_list = NULL;
+ int size = 0;
+ method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env);
+ size = axutil_array_list_size(method_list, env);
+ if(method_list && size)
+ {
+ axis2_http_header_t *allow_header = NULL;
+ axis2_char_t *method_list_str = NULL;
+ axis2_char_t *temp;
+ int i = 0;
+ method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29);
+
+ if(!method_list_str)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FALSE);
+ }
+
+ temp = method_list_str;
+ for(i = 0; i < size; i++)
+ {
+ if(i)
+ {
+ sprintf(temp, AXIS2_COMMA_SPACE_STR);
+ temp += 2;
+ }
+ sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env,
+ i));
+ temp += strlen(temp);
+ }
+ *temp = AXIS2_ESC_NULL;
+
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx);
+ allow_header = axis2_http_header_create(env, AXIS2_HTTP_HEADER_ALLOW,
+ method_list_str);
+ axis2_http_simple_response_set_header(response, env, allow_header);
+ AXIS2_FREE(env->allocator, method_list_str);
+ }
+ else
+ {
+ /* 404 Not Found */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx);
+ }
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL)
+ {
+ /* 400 Bad Request */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL)
+ {
+
+ /* 408 , Request Time Out */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL)
+ {
+ /* 409, Conflict */
+
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL, AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL)
+ {
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_GONE_CODE_VAL, AXIS2_HTTP_RESPONSE_GONE_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_gone(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL)
+ {
+ /* 412 Precondition failed */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL)
+ {
+ /* 413 entity too large */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME);
+
+ body_string
+ = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL)
+ {
+ /* 503, Service Unavailable*/
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else
+ {
+ /* 500 Internal Server Error */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+
+ if(body_string)
+ {
+ axis2_char_t str_len[10];
+ if(!is_head)
+ {
+ axis2_http_simple_response_set_body_string(response, env, body_string);
+ }
+ sprintf(str_len, "%d", axutil_strlen(body_string));
+ cont_len = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, str_len);
+ axis2_http_simple_response_set_header(response, env, cont_len);
+ }
+
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn, simple_request,
+ response, 0);
+
+ axis2_simple_http_svr_conn_write_response(svr_conn, env, response);
+ request_handled = AXIS2_TRUE;
+ status = AXIS2_TRUE;
+ }
+ }
+ else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_POST) || is_put)
+ {
+ if(is_put)
+ {
+ axutil_property_t *property = NULL;
+ if(http_worker->is_application_client_side)
+ {
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE, 0,
+ AXIS2_VALUE_TRUE);
+ }
+ else
+ {
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE,
+ 0, AXIS2_VALUE_FALSE);
+ }
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE,
+ property);
+ status = axis2_http_transport_utils_process_http_put_request(env, msg_ctx,
+ request_body, out_stream, content_type, content_length, soap_action_str,
+ url_ext_form);
+
+ }
+ else
+ {
+ axutil_property_t *property = NULL;
+ if(http_worker->is_application_client_side)
+ {
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE, 0,
+ AXIS2_VALUE_TRUE);
+ }
+ else
+ {
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE,
+ 0, AXIS2_VALUE_FALSE);
+ }
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE,
+ property);
+ status = axis2_http_transport_utils_process_http_post_request(env, msg_ctx,
+ request_body, out_stream, content_type, content_length, soap_action_str,
+ url_ext_form);
+
+ }
+ if(url_ext_form)
+ AXIS2_FREE(env->allocator, url_ext_form);
+ if(AXIS2_FAILURE == status && (is_put || axis2_msg_ctx_get_doing_rest(msg_ctx, env)))
+ {
+ /* Failure Occur while processing REST */
+
+ axis2_http_header_t *cont_len = NULL;
+ axis2_http_header_t *cont_type = NULL;
+ axis2_char_t *body_string = NULL;
+ if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND)
+ {
+ axutil_array_list_t *method_list = NULL;
+ int size = 0;
+ method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env);
+ size = axutil_array_list_size(method_list, env);
+ if(method_list && size)
+ {
+ axis2_http_header_t *allow_header = NULL;
+ axis2_char_t *method_list_str = NULL;
+ axis2_char_t *temp;
+ int i = 0;
+ method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29);
+ if(!method_list_str)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FALSE);
+ }
+
+ temp = method_list_str;
+ for(i = 0; i < size; i++)
+ {
+ if(i)
+ {
+ sprintf(temp, AXIS2_COMMA_SPACE_STR);
+ temp += 2;
+ }
+ sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env,
+ i));
+ temp += strlen(temp);
+ }
+ *temp = AXIS2_ESC_NULL;
+
+ /* 405 Method Not Allowed */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx);
+ allow_header = axis2_http_header_create(env, AXIS2_HTTP_HEADER_ALLOW,
+ method_list_str);
+ axis2_http_simple_response_set_header(response, env, allow_header);
+ AXIS2_FREE(env->allocator, method_list_str);
+ }
+ else
+ {
+ /* 404 Not Found */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx);
+ }
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL)
+ {
+ /* 400, Bad Request */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL)
+ {
+ /* 408, Request Timeout */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL)
+ {
+ /* 409, Conflict Types */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL, AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL)
+ {
+ /* 410, Gone. Resource no longer available */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_GONE_CODE_VAL, AXIS2_HTTP_RESPONSE_GONE_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_gone(env, conf_ctx);
+
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL)
+ {
+ /*410, Precondition for the url failed */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL)
+ {
+ /* 413, Request entity too large */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME);
+
+ body_string
+ = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL)
+ {
+ /* 513, Service Unavailable */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx);
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+ else
+ {
+ /* 500, Internal Server Error */
+ axis2_http_simple_response_set_status_line(response, env, http_version,
+ AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME);
+
+ body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx);
+
+ cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ }
+
+ if(body_string)
+ {
+ axis2_char_t str_len[10];
+ if(!is_head)
+ {
+ axis2_http_simple_response_set_body_string(response, env, body_string);
+ }
+ sprintf(str_len, "%d", axutil_strlen(body_string));
+ cont_len = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, str_len);
+ axis2_http_simple_response_set_header(response, env, cont_len);
+ }
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn, simple_request,
+ response, 0);
+ axis2_simple_http_svr_conn_write_response(svr_conn, env, response);
+ request_handled = AXIS2_TRUE;
+ status = AXIS2_TRUE;
+ }
+ else if(status == AXIS2_FAILURE)
+ {
+ axis2_msg_ctx_t *fault_ctx = NULL;
+ axis2_engine_t *engine = axis2_engine_create(env, conf_ctx);
+ axis2_http_request_line_t *req_line = NULL;
+ axis2_http_status_line_t *tmp_stat_line = NULL;
+ axis2_char_t status_line_str[100];
+ axutil_property_t *http_error_property = NULL;
+ axis2_char_t *http_error_value = NULL;
+ axis2_char_t *fault_code = NULL;
+ int status_code = 0;
+ axis2_char_t *reason_phrase = NULL;
+ int stream_len = 0;
+
+ if(!engine)
+ {
+ return AXIS2_FALSE;
+ }
+
+ http_error_property = axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_HTTP_TRANSPORT_ERROR);
+
+ if(http_error_property)
+ http_error_value = (axis2_char_t *)axutil_property_get_value(http_error_property,
+ env);
+
+ if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX AXIS2_COLON_STR
+ AXIOM_SOAP11_FAULT_CODE_SENDER;
+ }
+ else
+ {
+ fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX AXIS2_COLON_STR
+ AXIOM_SOAP12_SOAP_FAULT_VALUE_SENDER;
+ }
+
+ fault_ctx = axis2_engine_create_fault_msg_ctx(engine, env, msg_ctx,
+ fault_code,
+ axutil_error_get_message
+ (env->error));
+ req_line =
+ axis2_http_simple_request_get_request_line(simple_request, env);
+ if (req_line)
+ {
+ if (!http_error_value)
+ {
+ sprintf(status_line_str, "%s %s\r\n",
+ http_version,
+ AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR);
+ }
+ else
+ {
+ sprintf(status_line_str, "%s %s",
+ http_version,
+ http_error_value);
+ }
+ }
+ else
+ {
+ sprintf(status_line_str, "%s %s\r\n",
+ AXIS2_HTTP_HEADER_PROTOCOL_11,
+ AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR);
+ }
+
+ tmp_stat_line = axis2_http_status_line_create(env, status_line_str);
+
+ if (!http_error_value)
+ {
+ axis2_engine_send_fault(engine, env, fault_ctx);
+ }
+
+ status_code = axis2_http_status_line_get_status_code(tmp_stat_line, env);
+ reason_phrase = axis2_http_status_line_get_reason_phrase(tmp_stat_line, env);
+
+ axis2_http_simple_response_set_status_line(response, env,
+ http_version,
+ status_code,
+ reason_phrase);
+
+ axis2_http_simple_response_set_body_stream(response, env,
+ out_stream);
+
+ stream_len = axutil_stream_get_len (out_stream, env);
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn,
+ simple_request, response,
+ stream_len);
+
+ status = axis2_simple_http_svr_conn_write_response(svr_conn, env,
+ response);
+ request_handled = AXIS2_TRUE;
+ if(tmp_stat_line)
+ {
+ axis2_http_status_line_free(tmp_stat_line, env);
+ tmp_stat_line = NULL;
+ }
+ }
+ }
+ else
+ {
+ /* Other case than, PUT, DELETE, HEAD, GET and POST */
+ /* 501, Request method is not implemented */
+ axis2_http_header_t *cont_len = NULL;
+ axis2_http_header_t *cont_type = NULL;
+ axis2_char_t *body_string = NULL;
+ axis2_http_simple_response_set_status_line(
+ response, env,
+ http_version,
+ AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_NAME);
+
+ body_string =
+ axis2_http_transport_utils_get_not_implemented(env,
+ conf_ctx);
+ cont_type = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+ axis2_http_simple_response_set_header(response, env, cont_type);
+
+ if (body_string)
+ {
+ axis2_char_t str_len[10];
+ axis2_http_simple_response_set_body_string(response, env,
+ body_string);
+ sprintf(str_len, "%d", axutil_strlen(body_string));
+ cont_len = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH,
+ str_len);
+ axis2_http_simple_response_set_header(response, env, cont_len);
+ }
+
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn,
+ simple_request, response, 0);
+ axis2_simple_http_svr_conn_write_response(svr_conn, env, response);
+ request_handled = AXIS2_TRUE;
+ status = AXIS2_TRUE;
+ }
+
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+ if (op_ctx)
+ {
+ /*axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;*/
+ axis2_char_t *language_str = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ if (out_msg_ctx)
+ {
+ language_str = axis2_msg_ctx_get_content_language(out_msg_ctx, env);
+ }
+
+ if (language_str && *language_str && !request_handled)
+ {
+ axis2_http_header_t *language = NULL;
+ language = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_LANGUAGE,
+ language_str);
+ axis2_http_simple_response_set_header(response, env, language);
+ }
+ }
+
+ if (!request_handled)
+ {
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ axis2_bool_t response_written = AXIS2_FALSE;
+ if (is_get || is_head || is_put || is_delete ||
+ axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ do_rest = AXIS2_TRUE;
+ }
+
+ if ((accept_header_value || accept_charset_header_value ||
+ accept_language_header_value) && do_rest)
+ {
+ axis2_char_t *content_type_header_value = NULL;
+ axis2_http_header_t *content_type_header = NULL;
+ axis2_char_t *temp = NULL;
+ axis2_char_t *language_header_value = NULL;
+ axis2_http_header_t *language_header = NULL;
+ content_type_header = axis2_http_simple_response_get_first_header(
+ response,
+ env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+
+ language_header = axis2_http_simple_response_get_first_header(
+ response,
+ env,
+ AXIS2_HTTP_HEADER_CONTENT_LANGUAGE);
+
+ if (content_type_header)
+ {
+ content_type_header_value = axis2_http_header_get_value(content_type_header,
+ env);
+ }
+
+ if (content_type_header_value)
+ {
+ temp = axutil_strdup(env, content_type_header_value);
+ }
+
+ if (language_header)
+ {
+ language_header_value = axis2_http_header_get_value(language_header,
+ env);
+ }
+
+ if (temp)
+ {
+ axis2_char_t *content_type = NULL;
+ axis2_char_t *char_set = NULL;
+ axis2_char_t *temp2 = NULL;
+
+ temp2 = strchr(temp, AXIS2_SEMI_COLON);
+ if (temp2)
+ {
+ *temp2 = AXIS2_ESC_NULL;
+ temp2++;
+ char_set = axutil_strcasestr(temp2, AXIS2_HTTP_CHAR_SET_ENCODING);
+ }
+
+ if (char_set)
+ {
+ char_set = axutil_strltrim(env, char_set, AXIS2_SPACE_TAB_EQ);
+ }
+
+ content_type = axutil_strtrim(env, temp, NULL);
+
+ if (temp)
+ {
+ AXIS2_FREE(env->allocator, temp);
+ temp = NULL;
+ }
+
+ if (content_type && accept_header_value &&
+ !axutil_strcasestr(accept_header_value, content_type))
+ {
+ temp2 = strchr(content_type, AXIS2_F_SLASH);
+ if (temp2)
+ {
+ *temp2 = AXIS2_ESC_NULL;
+ temp = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) *
+ ((int)strlen(content_type) + 3));
+ if (!temp)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return AXIS2_FALSE;
+ }
+
+ sprintf(temp, "%s/*", content_type);
+ if (!axutil_strcasestr(accept_header_value, temp) &&
+ !strstr(accept_header_value, AXIS2_HTTP_HEADER_ACCEPT_ALL))
+ {
+ /* 406, Not Acceptable */
+ axis2_http_header_t *cont_len = NULL;
+ axis2_http_header_t *cont_type = NULL;
+ axis2_char_t *body_string = NULL;
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME);
+
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env,
+ conf_ctx);
+ cont_type =
+ axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ if (body_string)
+ {
+ axis2_char_t str_len[10];
+ axis2_http_simple_response_set_body_string(response, env,
+ body_string);
+ sprintf(str_len, "%d", axutil_strlen(body_string));
+ cont_len =
+ axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH,
+ str_len);
+
+ axis2_http_simple_response_set_header(response,
+ env,
+ cont_len);
+ }
+
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn,
+ simple_request, response, 0);
+ axis2_simple_http_svr_conn_write_response(svr_conn, env, response);
+ request_handled = AXIS2_TRUE;
+ status = AXIS2_TRUE;
+ response_written = AXIS2_TRUE;
+ }
+ AXIS2_FREE(env->allocator, temp);
+ }
+ }
+
+ if (content_type)
+ {
+ AXIS2_FREE(env->allocator, content_type);
+ }
+
+ if (char_set)
+ {
+ temp2 = strchr(char_set, AXIS2_EQ);
+ }
+
+ if (temp2)
+ {
+ ++temp2;
+ }
+
+ if (char_set && accept_charset_header_value &&
+ !axutil_strcasestr(accept_charset_header_value, char_set) &&
+ !axutil_strcasestr(accept_charset_header_value, temp2))
+ {
+ /* 406, Not Acceptable */
+ axis2_http_header_t *cont_len = NULL;
+ axis2_http_header_t *cont_type = NULL;
+ axis2_char_t *body_string = NULL;
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME);
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env,
+ conf_ctx);
+ cont_type =
+ axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ if (body_string)
+ {
+ axis2_char_t str_len[10];
+ axis2_http_simple_response_set_body_string(response, env,
+ body_string);
+ sprintf(str_len, "%d", axutil_strlen(body_string));
+ cont_len = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH,
+ str_len);
+ axis2_http_simple_response_set_header(response, env, cont_len);
+ }
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn,
+ simple_request, response, 0);
+ axis2_simple_http_svr_conn_write_response(svr_conn, env, response);
+ request_handled = AXIS2_TRUE;
+ status = AXIS2_TRUE;
+ response_written = AXIS2_TRUE;
+ }
+ if (char_set)
+ {
+ AXIS2_FREE(env->allocator, char_set);
+ }
+ }
+
+ if (language_header_value)
+ {
+ if (accept_language_header_value &&
+ !axutil_strcasestr(accept_language_header_value,
+ language_header_value))
+ {
+ /* 406, Not acceptable */
+ axis2_http_header_t *cont_len = NULL;
+ axis2_http_header_t *cont_type = NULL;
+ axis2_char_t *body_string = NULL;
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME);
+
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env,
+ conf_ctx);
+ cont_type =
+ axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML);
+
+ axis2_http_simple_response_set_header(response, env, cont_type);
+ axis2_http_simple_response_remove_headers(
+ response,
+ env,
+ AXIS2_HTTP_HEADER_CONTENT_LANGUAGE);
+
+ if (body_string)
+ {
+ axis2_char_t str_len[10];
+ axis2_http_simple_response_set_body_string(response, env,
+ body_string);
+ sprintf(str_len, "%d", axutil_strlen(body_string));
+ cont_len = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH,
+ str_len);
+ axis2_http_simple_response_set_header(response, env, cont_len);
+ }
+
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn,
+ simple_request, response, 0);
+ axis2_simple_http_svr_conn_write_response(svr_conn, env, response);
+ request_handled = AXIS2_TRUE;
+ status = AXIS2_TRUE;
+ response_written = AXIS2_TRUE;
+ }
+ }
+ }
+
+ if (!response_written)
+ {
+ /* If in there is a soap message is to to be sent in the back channel then we go inside this
+ * block. Somewhere in the receiveing end axis2_op_ctx_set_response_written() function has
+ * been called by this time to indicate to append the message into the http back channel.
+ */
+ if (op_ctx && axis2_op_ctx_get_response_written(op_ctx, env))
+ {
+ if (do_rest)
+ {
+ /*axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;*/
+
+ /*msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];*/
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+ if (in_msg_ctx)
+ {
+ /* TODO: Add neccessary handling */
+ }
+ if (out_msg_ctx)
+ {
+ int size = 0;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list =
+ axis2_msg_ctx_get_http_output_headers(out_msg_ctx,
+ env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list,
+ env);
+ }
+ while (size)
+ {
+ axis2_http_header_t *simple_header = NULL;
+ size--;
+ simple_header = (axis2_http_header_t *)
+ axutil_array_list_get(output_header_list,
+ env, size);
+ axis2_http_simple_response_set_header(response,
+ env,
+ simple_header);
+ }
+
+ if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = 0;
+ axis2_char_t *status_code_str = NULL;
+ status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_CONTINUE_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_ACK_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_ACK_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_GONE_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME;
+ break;
+ default:
+ status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL;
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_OK_CODE_NAME;
+ break;
+ }
+
+ axis2_http_simple_response_set_status_line(response, env,
+ http_version,
+ status_code,
+ status_code_str);
+ request_handled = AXIS2_TRUE;
+ }
+ }
+ }
+
+ if (!request_handled)
+ {
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ AXIS2_HTTP_RESPONSE_OK_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_OK_CODE_NAME);
+
+ if (!is_head)
+ {
+ /* This is where we append the message into the http back channel.*/
+ axis2_http_simple_response_set_body_stream(response, env, out_stream);
+ }
+ }
+ }
+ else if (op_ctx)
+ {
+ /* If response is not written */
+ if (do_rest)
+ {
+ /*axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;*/
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+ if (in_msg_ctx)
+ {
+ /* TODO: Add neccssary handling */
+ }
+ if (out_msg_ctx)
+ {
+ int size = 0;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list =
+ axis2_msg_ctx_get_http_output_headers(out_msg_ctx,
+ env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list,
+ env);
+ }
+
+ while (size)
+ {
+ axis2_http_header_t *simeple_header = NULL;
+ size--;
+ simeple_header = (axis2_http_header_t *)
+ axutil_array_list_get(output_header_list,
+ env, size);
+ axis2_http_simple_response_set_header(response, env,
+ simeple_header);
+ }
+
+ if (axis2_msg_ctx_get_no_content(out_msg_ctx, env))
+ {
+ if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ axis2_char_t *status_code_str = NULL;
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME;
+ break;
+ default:
+ status_code =
+ AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL;
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_NAME;
+ break;
+ }
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ status_code,
+ status_code_str);
+ }
+ else
+ {
+ /* status code not available in msg_ctx */
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_NAME);
+ }
+
+ request_handled = AXIS2_TRUE;
+ }
+ else if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ axis2_char_t *status_code_str = NULL;
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_CONTINUE_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_OK_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_OK_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_GONE_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME;
+ break;
+ default:
+ status_code = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL;
+ status_code_str =
+ AXIS2_HTTP_RESPONSE_ACK_CODE_NAME;
+ break;
+ }
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ status_code,
+ status_code_str);
+
+ request_handled = AXIS2_TRUE;
+ }
+ }
+ }
+ if (!request_handled)
+ {
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ AXIS2_HTTP_RESPONSE_ACK_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_ACK_CODE_NAME);
+ }
+ }
+ else
+ {
+ axis2_http_simple_response_set_status_line(
+ response, env, http_version,
+ AXIS2_HTTP_RESPONSE_ACK_CODE_VAL,
+ AXIS2_HTTP_RESPONSE_ACK_CODE_NAME);
+ }
+
+ if (!response_written)
+ {
+ int stream_len = 0;
+ stream_len = axutil_stream_get_len(out_stream, env);
+
+ /*axis2_http_worker_set_response_headers(http_worker, env, svr_conn,
+ simple_request, response,
+ stream_len);*/
+
+ /* This is where it actually write to the wire in the http back channel
+ * append case. */
+ if(out_msg_ctx)
+ {
+ axutil_array_list_t *mime_parts = NULL;
+ mime_parts = axis2_msg_ctx_get_mime_parts(out_msg_ctx, env);
+ /* If mime_parts is there then that means we send MTOM. So
+ * in order to send MTOM we are enabling HTTP1.1 and cunk transfer
+ * encoding */
+
+ if(mime_parts)
+ {
+ axis2_http_header_t *transfer_enc_header = NULL;
+ axutil_param_t *callback_name_param = NULL;
+ axis2_char_t *mtom_sending_callback_name = NULL;
+
+ /* Getting the sender callback name paramter if it is
+ * specified in the configuration file */
+
+ callback_name_param = axis2_msg_ctx_get_parameter(out_msg_ctx, env ,
+ AXIS2_MTOM_SENDING_CALLBACK);
+ if(callback_name_param)
+ {
+ mtom_sending_callback_name =
+ (axis2_char_t *) axutil_param_get_value (callback_name_param, env);
+ if(mtom_sending_callback_name)
+ {
+ axis2_http_simple_response_set_mtom_sending_callback_name(
+ response, env, mtom_sending_callback_name);
+ }
+ }
+
+ axis2_http_simple_response_set_mime_parts(response, env, mime_parts);
+
+ axis2_http_simple_response_set_http_version(response, env,
+ AXIS2_HTTP_HEADER_PROTOCOL_11);
+
+ transfer_enc_header = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED);
+
+ axis2_http_simple_response_set_header(response, env,
+ transfer_enc_header);
+
+ /* In the chunking case content-length is zero */
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn,
+ simple_request, response,
+ 0);
+ }
+ else
+ {
+ axis2_http_worker_set_response_headers(http_worker, env, svr_conn,
+ simple_request, response,
+ stream_len);
+ }
+ }
+ status = axis2_simple_http_svr_conn_write_response(svr_conn,
+ env,
+ response);
+ }
+ }
+ }
+
+ if (url_external_form)
+ {
+ AXIS2_FREE(env->allocator, url_external_form);
+ url_external_form = NULL;
+ }
+ if (op_ctx)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+ axis2_char_t *msg_id = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+
+ if (out_msg_ctx)
+ {
+ axis2_msg_ctx_free(out_msg_ctx, env);
+ out_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
+ }
+
+ if (in_msg_ctx)
+ {
+ msg_id = axutil_strdup(env, axis2_msg_ctx_get_msg_id(in_msg_ctx, env));
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(in_msg_ctx, env);
+
+ axis2_msg_ctx_free(in_msg_ctx, env);
+ in_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL;
+ }
+
+ if (!axis2_op_ctx_is_in_use(op_ctx, env))
+ {
+ axis2_op_ctx_destroy_mutex(op_ctx, env);
+ if (conf_ctx && msg_id)
+ {
+ axis2_conf_ctx_register_op_ctx(conf_ctx, env, msg_id, NULL);
+
+ AXIS2_FREE(env->allocator, msg_id);
+ }
+ axis2_op_ctx_free(op_ctx, env);
+ }
+
+ } /* Done freeing message contexts */
+
+ msg_ctx = NULL;
+ axutil_url_free(request_url, env);
+ axutil_string_free(soap_action_str, env);
+ request_url = NULL;
+ return status;
+}
+
+static axis2_status_t
+axis2_http_worker_set_response_headers(
+ axis2_http_worker_t * http_worker,
+ const axutil_env_t * env,
+ axis2_simple_http_svr_conn_t * svr_conn,
+ axis2_http_simple_request_t * simple_request,
+ axis2_http_simple_response_t * simple_response,
+ axis2_ssize_t content_length)
+{
+ axis2_http_header_t *conn_header = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svr_conn, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, simple_request, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, simple_response, AXIS2_FAILURE);
+
+ if(AXIS2_FALSE == axis2_http_simple_response_contains_header(simple_response, env,
+ AXIS2_HTTP_HEADER_CONNECTION))
+ {
+ conn_header = axis2_http_simple_request_get_first_header(simple_request, env,
+ AXIS2_HTTP_HEADER_CONNECTION);
+ if(conn_header)
+ {
+ axis2_char_t *value = NULL;
+ value = axis2_http_header_get_value(conn_header, env);
+
+ if(0 == axutil_strcasecmp(value, AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE))
+ {
+ /* Comment these until keep alive support is completed for simple Axis2/C server */
+ /*axis2_http_header_t *header = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE);
+
+ axis2_http_simple_response_set_header(simple_response, env, header);
+ axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_TRUE);*/
+ }
+
+ if(0 == axutil_strcasecmp(value, AXIS2_HTTP_HEADER_CONNECTION_CLOSE))
+ {
+ axis2_http_header_t *header = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_CLOSE);
+
+ axis2_http_simple_response_set_header(simple_response, env, header);
+ axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE);
+ }
+ }
+ else
+ { /* Connection Header not available */
+ axis2_char_t *http_version = NULL;
+ http_version = axis2_http_simple_response_get_http_version(simple_response, env);
+ if(http_version && !axutil_strcasecmp(http_version, AXIS2_HTTP_HEADER_PROTOCOL_11))
+ {
+ /* Comment these until keep alive support is completed for simple Axis2/C server */
+ /*axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_TRUE);*/
+ /* Instead add following to always send close connection header to indicate that
+ * we don't support http keep alive yet in simple Axis2/C server
+ */
+ axis2_http_header_t *header = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_CLOSE);
+
+ axis2_http_simple_response_set_header(simple_response, env, header);
+ /*axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE);*/
+ }
+ else
+ {
+ axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE);
+ }
+ }
+
+ if(!axis2_http_simple_response_contains_header(simple_response, env,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING))
+ {
+ if(AXIS2_FALSE == axis2_http_simple_request_contains_header(simple_request, env,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING))
+ {
+ if(0 != content_length)
+ {
+ axis2_char_t content_len_str[10];
+ axis2_http_header_t *content_len_hdr = NULL;
+
+ sprintf(content_len_str, "%d", content_length);
+ content_len_hdr = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH, content_len_str);
+ axis2_http_simple_response_set_header(simple_response, env, content_len_hdr);
+ }
+ }
+ else
+ {
+ /* Having Transfer encoding Header */
+ axis2_http_header_t *transfer_enc_header = axis2_http_header_create(env,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED);
+
+ axis2_http_simple_response_set_header(simple_response, env, transfer_enc_header);
+ }
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+static axutil_hash_t *
+axis2_http_worker_get_headers(
+ axis2_http_worker_t * http_worker,
+ const axutil_env_t * env,
+ axis2_http_simple_request_t * request)
+{
+ axutil_array_list_t *header_list = NULL;
+ int hdr_count = 0;
+ int i = 0;
+ axutil_hash_t *header_map = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, request, NULL);
+
+ header_list = axis2_http_simple_request_get_headers(request, env);
+ if(!header_list)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "http simple request"
+ "doesn't contain a header list");
+ return NULL;
+ }
+ hdr_count = axutil_array_list_size(header_list, env);
+ if(0 == hdr_count)
+ {
+ AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "http simple request , "
+ "header list contains zero headers");
+ return NULL;
+ }
+
+ for(i = 0; i < hdr_count; i++)
+ {
+ axis2_http_header_t *tmp_hdr = NULL;
+ tmp_hdr = axutil_array_list_get(header_list, env, i);
+ if(!tmp_hdr)
+ {
+ continue;
+ }
+ if(!header_map)
+ {
+ header_map = axutil_hash_make(env);
+ if(!header_map)
+ {
+ return NULL;
+ }
+ }
+ axutil_hash_set(header_map, axis2_http_header_get_name(tmp_hdr, env),
+ AXIS2_HASH_KEY_STRING, tmp_hdr);
+ }
+ return header_map;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_worker_set_svr_port(
+ axis2_http_worker_t * worker,
+ const axutil_env_t * env,
+ int port)
+{
+ worker->svr_port = port;
+ return AXIS2_SUCCESS;
+}
+#if 0
+static axis2_char_t *
+axis2_http_worker_get_server_time(
+ axis2_http_worker_t * http_worker,
+ const axutil_env_t * env)
+{
+ time_t tp;
+ char *time_str;
+ tp = time(&tp);
+ time_str = ctime(&tp);
+ if(!time_str)
+ {
+ return NULL;
+ }
+ if(AXIS2_NEW_LINE == time_str[strlen(time_str) - 1])
+ {
+ time_str[strlen(time_str) - 1] = AXIS2_ESC_NULL;
+ }
+ /* We use the ANSI C Date Format, which is Legal according to RFC2616,
+ * Section 3.3.1. We are not a HTTP/1.1 only server, and thus, it suffices.
+ */
+ return time_str;
+}
+#endif
+
+static axis2_http_simple_response_t *
+axis2_http_worker_create_simple_response(
+ axis2_http_worker_t *http_worker,
+ const axutil_env_t *env)
+{
+ axis2_http_simple_response_t *response = NULL;
+ response = axis2_http_simple_response_create_default(env);
+ if(response)
+ {
+ axis2_http_header_t *server = NULL;
+ axis2_http_header_t *server_date = NULL;
+ axis2_char_t *date_str = NULL;
+ char *date_str_tmp = NULL;
+ time_t tp;
+ size_t date_str_len = 0;
+
+ /* create "Date: xxxx GMT" HTTP header */
+ tp = time(&tp);
+ date_str_tmp = ctime(&tp);
+ if(!date_str_tmp)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot get server time");
+ return NULL;
+ }
+
+ date_str_len = strlen(date_str_tmp);
+ if(AXIS2_NEW_LINE == date_str_tmp[date_str_len - 1])
+ {
+ date_str_len -= 1;
+ date_str_tmp[date_str_len] = AXIS2_ESC_NULL;
+ }
+ /* We use the ANSI C Date Format, which is Legal according to RFC2616,
+ * Section 3.3.1. We are not a HTTP/1.1 only server, and thus, it suffices.
+ */
+
+ date_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (date_str_len + 5));
+ if(!date_str)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+
+ }
+ sprintf(date_str, "%s GMT", date_str_tmp);
+ server_date = axis2_http_header_create(env, AXIS2_HTTP_HEADER_DATE, date_str);
+ AXIS2_FREE(env->allocator, date_str);
+ axis2_http_simple_response_set_header(response, env, server_date);
+
+ /* create "Server: Axis2C/x.x.x (Simple Axis2 HTTP Server)" HTTP Header */
+ server = axis2_http_header_create(env, AXIS2_HTTP_HEADER_SERVER,
+ AXIS2_HTTP_HEADER_SERVER_AXIS2C AXIS2_HTTP_SERVER);
+ axis2_http_simple_response_set_header(response, env, server);
+ }
+ return response;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_worker_set_is_application_client_side(
+ axis2_http_worker_t *http_worker,
+ const axutil_env_t *env,
+ axis2_bool_t application_client_side)
+{
+ http_worker->is_application_client_side = application_client_side;
+}
+
+
diff --git a/src/core/transport/http/common/simple_http_svr_conn.c b/src/core/transport/http/common/simple_http_svr_conn.c
new file mode 100644
index 0000000..a68c48e
--- /dev/null
+++ b/src/core/transport/http/common/simple_http_svr_conn.c
@@ -0,0 +1,504 @@
+/*
+ * 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_simple_http_svr_conn.h>
+#include <axis2_http_transport.h>
+#include <axutil_string.h>
+#include <axutil_network_handler.h>
+#include <axutil_http_chunked_stream.h>
+#include <platforms/axutil_platform_auto_sense.h>
+#include <string.h>
+#include <axis2_http_simple_response.h>
+#include <axis2_http_transport_utils.h>
+
+struct axis2_simple_http_svr_conn
+{
+ int socket;
+ axutil_stream_t *stream;
+ axis2_bool_t keep_alive;
+};
+
+static axis2_char_t *
+axis2_simple_http_svr_conn_read_line(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env);
+
+AXIS2_EXTERN axis2_simple_http_svr_conn_t *AXIS2_CALL
+axis2_simple_http_svr_conn_create(
+ const axutil_env_t * env,
+ int sockfd)
+{
+ axis2_simple_http_svr_conn_t *svr_conn = NULL;
+ svr_conn = (axis2_simple_http_svr_conn_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_simple_http_svr_conn_t));
+ if(!svr_conn)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "server connection failed. Insufficient memory");
+ return NULL;
+ }
+
+ memset((void *)svr_conn, 0, sizeof(axis2_simple_http_svr_conn_t));
+ svr_conn->socket = sockfd;
+
+ if(-1 != svr_conn->socket)
+ {
+ svr_conn->stream = axutil_stream_create_socket(env, svr_conn->socket);
+ if(!svr_conn->stream)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "socket creation failed, socket %d", sockfd);
+ axis2_simple_http_svr_conn_free(svr_conn, env);
+ return NULL;
+ }
+ }
+ return svr_conn;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_simple_http_svr_conn_free(
+ axis2_simple_http_svr_conn_t *svr_conn,
+ const axutil_env_t * env)
+{
+ axis2_simple_http_svr_conn_close(svr_conn, env);
+ AXIS2_FREE(env->allocator, svr_conn);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_simple_http_svr_conn_close(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ axutil_stream_free(svr_conn->stream, env);
+ if(-1 != svr_conn->socket)
+ {
+ axutil_network_handler_close_socket(env, svr_conn->socket);
+ svr_conn->socket = -1;
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_simple_http_svr_conn_is_open(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ if(-1 != svr_conn->socket)
+ {
+ return AXIS2_TRUE;
+ }
+ return AXIS2_FALSE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_simple_http_svr_conn_set_keep_alive(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env,
+ axis2_bool_t keep_alive)
+{
+ svr_conn->keep_alive = keep_alive;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_simple_http_svr_conn_is_keep_alive(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ return svr_conn->keep_alive;
+}
+
+AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+axis2_simple_http_svr_conn_get_stream(
+ const axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ return svr_conn->stream;
+}
+
+AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL
+axis2_simple_http_svr_conn_get_writer(
+ const axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ return axis2_http_response_writer_create(env, svr_conn->stream);
+}
+
+AXIS2_EXTERN axis2_http_simple_request_t *AXIS2_CALL
+axis2_simple_http_svr_conn_read_request(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ axis2_char_t* str_line = NULL;
+ axis2_bool_t end_of_headers = AXIS2_FALSE;
+ axis2_http_request_line_t *request_line = NULL;
+ axis2_http_simple_request_t *request = NULL;
+
+ /* read first line of the request (which is <HTTP METHOD> <URI> <HTTP VERSION> CRLF */
+ str_line = axis2_simple_http_svr_conn_read_line(svr_conn, env);
+ if(str_line)
+ {
+ request_line = axis2_http_request_line_parse_line(env, str_line);
+ AXIS2_FREE(env->allocator, str_line);
+ str_line = NULL;
+ }
+
+ if(!request_line)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ request = axis2_http_simple_request_create(env, request_line, NULL, 0, svr_conn->stream);
+
+ /* now read the headers until we find a line only having CRLF */
+ while(AXIS2_FALSE == end_of_headers)
+ {
+ str_line = axis2_simple_http_svr_conn_read_line(svr_conn, env);
+ if(!str_line)
+ {
+ /*if nothing is read, this loop should be broken. Otherwise, going to be endless loop */
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "reading http header failed");
+ break;
+ }
+
+ if(0 == axutil_strcmp(str_line, AXIS2_HTTP_CRLF))
+ {
+ /* line contains only CRLF, so should be end of headers */
+ end_of_headers = AXIS2_TRUE;
+ }
+ else
+ {
+ axis2_http_header_t *tmp_header = axis2_http_header_create_by_str(env, str_line);
+ if(tmp_header)
+ {
+ axis2_http_simple_request_add_header(request, env, tmp_header);
+ }
+ }
+
+ AXIS2_FREE(env->allocator, str_line);
+ str_line = NULL;
+ }
+ return request;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_simple_http_svr_conn_write_response(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env,
+ axis2_http_simple_response_t * response)
+{
+ axis2_http_response_writer_t *response_writer = NULL;
+ axutil_array_list_t *headers = NULL;
+ axutil_stream_t *response_stream = NULL;
+ axis2_char_t *response_body = NULL;
+ int body_size = 0;
+
+ axis2_http_header_t *enc_header = NULL;
+ axis2_bool_t chuked_encoding = AXIS2_FALSE;
+ axis2_char_t *status_line = NULL;
+ axis2_bool_t binary_content = AXIS2_FALSE;
+ axis2_char_t *content_type = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE);
+
+ response_writer = axis2_http_response_writer_create(env, svr_conn->stream);
+ if(!response_writer)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create http response writer");
+ return AXIS2_FAILURE;
+ }
+
+ content_type = (axis2_char_t *)axis2_http_simple_response_get_content_type(response, env);
+ if(content_type)
+ {
+ if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED)
+ && strstr(content_type,AXIS2_HTTP_HEADER_ACCEPT_XOP_XML))
+ {
+ binary_content = AXIS2_TRUE;
+ }
+ }
+
+ enc_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING);
+ if(enc_header)
+ {
+ axis2_char_t *enc_value = axis2_http_header_get_value(enc_header, env);
+ if(enc_value && (0 == axutil_strcmp(enc_value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)))
+ {
+ chuked_encoding = AXIS2_TRUE;
+
+ /* remove the content length header */
+ axis2_http_simple_response_remove_headers(response, env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH);
+ }
+ }
+
+ /* print status line */
+ status_line = axis2_http_simple_response_get_status_line(response, env);
+ if(!status_line)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ axis2_http_response_writer_free(response_writer, env);
+ return AXIS2_FAILURE;
+ }
+ axis2_http_response_writer_print_str(response_writer, env, status_line);
+
+ headers = axis2_http_simple_response_get_headers(response, env);
+ if(headers)
+ {
+ int i = 0;
+ int count = axutil_array_list_size(headers, env);
+ for(; i < count; i++)
+ {
+ axis2_http_header_t *header =
+ (axis2_http_header_t *)axutil_array_list_get(headers, env, i);
+ if(header)
+ {
+ axis2_char_t *header_ext_form = axis2_http_header_to_external_form(header, env);
+ axis2_http_response_writer_print_str(response_writer, env, header_ext_form);
+ AXIS2_FREE(env->allocator, header_ext_form);
+ }
+ }
+ }
+
+ /* write empty line after http headers */
+ axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF);
+
+ /* write the body */
+ response_stream = axis2_http_simple_response_get_body(response, env);
+ if(response_stream)
+ {
+ body_size = axutil_stream_get_len(response_stream, env);
+ response_body = axutil_stream_get_buffer(response_stream, env);
+ axutil_stream_flush_buffer(response_stream, env);
+ response_body[body_size] = AXIS2_ESC_NULL;
+ }
+
+ if(body_size <= 0 && !binary_content)
+ {
+ /* no body available to write. Note that this is not an error. We might want to write only
+ * status information and hence, this is a valid case */
+ axis2_http_response_writer_free(response_writer, env);
+ return AXIS2_SUCCESS;
+ }
+
+ if(!chuked_encoding && !binary_content)
+ {
+ /* This sending a normal SOAP response without chunk transfer encoding */
+ axis2_status_t write_stat = AXIS2_FAILURE;
+ write_stat = axis2_http_response_writer_println_str(response_writer, env, response_body);
+ if(write_stat != AXIS2_SUCCESS)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_RESPONSE, AXIS2_FAILURE);
+ axis2_http_response_writer_free(response_writer, env);
+ return AXIS2_FAILURE;
+ }
+ }
+ else if(!binary_content)
+ {
+ /* Sending a normal SOAP response enabling http chunking */
+ axutil_http_chunked_stream_t *chunked_stream = NULL;
+ int left = body_size;
+ chunked_stream = axutil_http_chunked_stream_create(env, svr_conn->stream);
+ while(left > 0)
+ {
+ int len = -1;
+ len = axutil_http_chunked_stream_write(chunked_stream, env, response_body, body_size);
+ if(len <= 0)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot write data to chunked stream");
+ axutil_http_chunked_stream_free(chunked_stream, env);
+ axis2_http_response_writer_free(response_writer, env);
+ return AXIS2_FAILURE;
+ }
+ left -= len;
+ }
+ axutil_http_chunked_stream_write_last_chunk(chunked_stream, env);
+ axutil_http_chunked_stream_free(chunked_stream, env);
+ }
+ else
+ {
+ /* In the MTOM case we enable chunking in order to send the attachment */
+ axutil_http_chunked_stream_t *chunked_stream = NULL;
+ axis2_status_t write_stat = AXIS2_FAILURE;
+ axutil_array_list_t *mime_parts = NULL;
+ axis2_char_t *mtom_sending_callback_name = NULL;
+
+ mime_parts = axis2_http_simple_response_get_mime_parts(response, env);
+ if(!mime_parts)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No mime parts are given");
+ axis2_http_response_writer_free(response_writer, env);
+ return AXIS2_FAILURE;
+ }
+
+ /* If the callback name is not there, then we will check whether there
+ * is any mime_parts which has type callback. If we found then no point
+ * of continuing we should return a failure */
+ mtom_sending_callback_name = axis2_http_simple_response_get_mtom_sending_callback_name(
+ response, env);
+ if(!mtom_sending_callback_name)
+ {
+ if(axis2_http_transport_utils_is_callback_required(env, mime_parts))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Sender callback not specified");
+ axis2_http_response_writer_free(response_writer, env);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ chunked_stream = axutil_http_chunked_stream_create(env, svr_conn->stream);
+ write_stat = axis2_http_transport_utils_send_mtom_message(chunked_stream, env, mime_parts,
+ mtom_sending_callback_name);
+ axutil_http_chunked_stream_free(chunked_stream, env);
+
+ if(write_stat != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "writing mime parts failed");
+ axis2_http_response_writer_free(response_writer, env);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ axis2_http_response_writer_free(response_writer, env);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_simple_http_svr_conn_set_rcv_timeout(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env,
+ int timeout)
+{
+ return axutil_network_handler_set_sock_option(env, svr_conn->socket, SO_RCVTIMEO, timeout);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_simple_http_svr_conn_set_snd_timeout(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env,
+ int timeout)
+{
+ return axutil_network_handler_set_sock_option(env, svr_conn->socket, SO_SNDTIMEO, timeout);
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_simple_http_svr_conn_get_svr_ip(
+ const axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ return axutil_network_handler_get_svr_ip(env, svr_conn->socket);
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_simple_http_svr_conn_get_peer_ip(
+ const axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ return axutil_network_handler_get_peer_ip(env, svr_conn->socket);
+}
+
+static axis2_char_t *
+axis2_simple_http_svr_conn_read_line(
+ axis2_simple_http_svr_conn_t * svr_conn,
+ const axutil_env_t * env)
+{
+ axis2_char_t* str_line = NULL;
+ axis2_char_t tmp_buf[2048];
+ int read = -1;
+
+ /* peek for 2047 characters to verify whether it contains CRLF character */
+ while((read = axutil_stream_peek_socket(svr_conn->stream, env, tmp_buf, 2048 - 1)) > 0)
+ {
+ axis2_char_t *start = tmp_buf;
+ axis2_char_t *end = NULL;
+ tmp_buf[read] = AXIS2_ESC_NULL;
+ end = strstr(tmp_buf, AXIS2_HTTP_CRLF);
+ if(end)
+ {
+ axis2_char_t *buffer = NULL;
+ if(str_line)
+ {
+ /* header is more than 2048 character. this is not a common case, and not optimized
+ * for performance (reading in a temp buffer and then strcat to get final buffer */
+ buffer = tmp_buf;
+ }
+ else
+ {
+ /* header is less than 2048 characters, this is the common case. So to improve
+ * the performance, the buffer is malloc and then used to read the stream. */
+ buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, end - start + 3);
+ }
+
+ /* read the data including CRLF (hence the size = end - start + 2) */
+ read = axutil_stream_read(svr_conn->stream, env, buffer, end - start + 2);
+ if(read > 0)
+ {
+ buffer[read] = AXIS2_ESC_NULL;
+
+ if(str_line)
+ {
+ axis2_char_t* tmp_str_line = NULL;
+ tmp_str_line = axutil_stracat(env, str_line, buffer);
+ if(tmp_str_line)
+ {
+ AXIS2_FREE(env->allocator, str_line);
+ str_line = tmp_str_line;
+ }
+ }
+ else
+ {
+ str_line = buffer;
+ }
+ }
+ else
+ {
+ /* read returns 0 or negative value, this could be an error */
+ if(str_line)
+ {
+ AXIS2_FREE(env->allocator, str_line);
+ str_line = NULL;
+ }
+ else
+ {
+ AXIS2_FREE(env->allocator, buffer);
+ }
+ }
+ break;
+ }
+ else
+ {
+ /* not reached end yet */
+ read = axutil_stream_read(svr_conn->stream, env, tmp_buf, 2048 - 1);
+ if(read > 0)
+ {
+ axis2_char_t* tmp_str_line = NULL;
+ tmp_buf[read] = AXIS2_ESC_NULL;
+ tmp_str_line = axutil_stracat(env, str_line, tmp_buf);
+ if(tmp_str_line)
+ {
+ if(str_line)
+ {
+ AXIS2_FREE(env->allocator, str_line);
+ }
+ str_line = tmp_str_line;
+ }
+ }
+ }
+ }
+
+ return str_line;
+}
diff --git a/src/core/transport/http/receiver/Makefile.am b/src/core/transport/http/receiver/Makefile.am
new file mode 100644
index 0000000..0af4e22
--- /dev/null
+++ b/src/core/transport/http/receiver/Makefile.am
@@ -0,0 +1,21 @@
+lib_LTLIBRARIES = libaxis2_http_receiver.la
+libaxis2_http_receiver_la_LIBADD=$(top_builddir)/util/src/libaxutil.la\
+ $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la
+
+
+libaxis2_http_receiver_la_SOURCES = http_receiver.c\
+ http_svr_thread.c
+
+
+libaxis2_http_receiver_la_LDFLAGS = -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport\
+ -I$(top_builddir)/src/core/transport/http \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
diff --git a/src/core/transport/http/receiver/http_receiver.c b/src/core/transport/http/receiver/http_receiver.c
new file mode 100644
index 0000000..c8517b0
--- /dev/null
+++ b/src/core/transport/http/receiver/http_receiver.c
@@ -0,0 +1,508 @@
+/*
+ * 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_server.h>
+#include <axis2_http_transport.h>
+#include <axis2_http_svr_thread.h>
+#include <axis2_transport_in_desc.h>
+#include <axutil_param_container.h>
+#include <axutil_url.h>
+#include <axutil_network_handler.h>
+#include <axis2_conf_init.h>
+#include <stdlib.h>
+
+
+/**
+ * @brief HTTP Client struct impl
+ * Axis2 HTTP Client impl
+ */
+
+typedef struct axis2_http_server_impl
+{
+ axis2_transport_receiver_t http_server;
+ axis2_http_svr_thread_t *svr_thread;
+ int port;
+ axis2_char_t *svr_ip;
+ axis2_conf_ctx_t *conf_ctx;
+ axis2_conf_ctx_t *conf_ctx_private;
+ axis2_bool_t is_application_client_side;
+} axis2_http_server_impl_t;
+
+#define AXIS2_INTF_TO_IMPL(http_server) \
+ ((axis2_http_server_impl_t *)(http_server))
+
+/***************************** Function headers *******************************/
+
+static axis2_status_t AXIS2_CALL
+axis2_http_server_init(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_transport_in_desc_t * in_desc);
+
+static axis2_status_t AXIS2_CALL
+axis2_http_server_start(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env);
+
+axis2_status_t AXIS2_CALL
+axis2_http_server_stop(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env);
+
+static axis2_conf_ctx_t *AXIS2_CALL
+axis2_http_server_get_conf_ctx(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env);
+
+static axis2_endpoint_ref_t *AXIS2_CALL
+axis2_http_server_get_reply_to_epr(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env,
+ const axis2_char_t * svc_name);
+
+static axis2_endpoint_ref_t *AXIS2_CALL
+axis2_http_server_get_epr_for_service(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env,
+ const axis2_char_t * svc_name);
+
+static axis2_bool_t AXIS2_CALL
+axis2_http_server_is_running(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env);
+
+static void AXIS2_CALL
+axis2_http_server_set_is_application_client_side(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env,
+ axis2_bool_t is_application_client_side);
+
+static void AXIS2_CALL
+axis2_http_server_free(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env);
+
+static axis2_char_t* AXIS2_CALL
+axis2_http_server_get_server_ip(
+axis2_transport_receiver_t *transport_receiver,
+const axutil_env_t *env);
+
+static void AXIS2_CALL
+axis2_http_server_set_server_ip(
+axis2_transport_receiver_t *transport_receiver,
+const axutil_env_t *env,
+ axis2_char_t *serverip);
+
+static const axis2_transport_receiver_ops_t http_transport_receiver_ops_var = {
+ axis2_http_server_init,
+ axis2_http_server_start,
+ axis2_http_server_get_reply_to_epr,
+ axis2_http_server_get_epr_for_service,
+ axis2_http_server_get_server_ip,
+ axis2_http_server_set_server_ip,
+ axis2_http_server_get_conf_ctx,
+ axis2_http_server_is_running,
+ axis2_http_server_set_is_application_client_side,
+ axis2_http_server_stop,
+ axis2_http_server_free };
+
+AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL
+axis2_http_server_create(
+ const axutil_env_t * env,
+ const axis2_char_t * repo,
+ const int port)
+{
+ axis2_http_server_impl_t *server_impl = NULL;
+
+ server_impl = (axis2_http_server_impl_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_server_impl_t));
+
+ if(!server_impl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ server_impl->svr_thread = NULL;
+ server_impl->conf_ctx = NULL;
+ server_impl->conf_ctx_private = NULL;
+ server_impl->port = port;
+ server_impl->svr_ip = NULL;
+ server_impl->is_application_client_side = AXIS2_FALSE;
+
+ server_impl->http_server.ops = &http_transport_receiver_ops_var;
+
+ if(repo)
+ {
+ axis2_transport_in_desc_t *transport_in = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_receiver_t *receiver = NULL;
+ /**
+ * We first create a private conf ctx which is owned by this server
+ * we only free this private conf context. We should never free the
+ * server_impl->conf_ctx because it may own to any other object which
+ * may lead to double free
+ */
+ server_impl->conf_ctx_private = axis2_build_conf_ctx(env, repo);
+
+ if(!server_impl->conf_ctx_private)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "unable to create private configuration context for repo path %s", repo);
+ axis2_http_server_free((axis2_transport_receiver_t *)server_impl, env);
+ return NULL;
+ }
+ conf = axis2_conf_ctx_get_conf(server_impl->conf_ctx_private, env);
+ transport_in = axis2_conf_get_transport_in(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ receiver = axis2_transport_in_desc_get_recv(transport_in, env);
+ AXIS2_INTF_TO_IMPL(receiver)->port = port;
+
+ server_impl->conf_ctx = server_impl->conf_ctx_private;
+ }
+
+ return &(server_impl->http_server);
+}
+
+AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL
+axis2_http_server_create_with_file(
+ const axutil_env_t * env,
+ const axis2_char_t * file,
+ const int port)
+{
+ axis2_http_server_impl_t *server_impl = NULL;
+
+ server_impl = (axis2_http_server_impl_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_server_impl_t));
+
+ if(!server_impl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ server_impl->svr_thread = NULL;
+ server_impl->conf_ctx = NULL;
+ server_impl->conf_ctx_private = NULL;
+ server_impl->port = port;
+ server_impl->svr_ip = NULL;
+ server_impl->http_server.ops = &http_transport_receiver_ops_var;
+
+ if(file)
+ {
+ axis2_transport_in_desc_t *transport_in = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_receiver_t *receiver = NULL;
+ /**
+ * We first create a private conf ctx which is owned by this server
+ * we only free this private conf context. We should never free the
+ * server_impl->conf_ctx because it may own to any other object which
+ * may lead to double free
+ */
+ server_impl->conf_ctx_private = axis2_build_conf_ctx_with_file(env, file);
+
+ if(!server_impl->conf_ctx_private)
+ {
+ axis2_http_server_free((axis2_transport_receiver_t *)server_impl, env);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "unable to create configuration context for file %s", file);
+ return NULL;
+ }
+ conf = axis2_conf_ctx_get_conf(server_impl->conf_ctx_private, env);
+ transport_in = axis2_conf_get_transport_in(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ receiver = axis2_transport_in_desc_get_recv(transport_in, env);
+ AXIS2_INTF_TO_IMPL(receiver)->port = port;
+
+
+ server_impl->conf_ctx = server_impl->conf_ctx_private;
+ }
+
+ return &(server_impl->http_server);
+}
+
+static void AXIS2_CALL
+axis2_http_server_free(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env)
+{
+ axis2_http_server_impl_t *server_impl = NULL;
+
+ if(!server)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "failure, server value is null , nothing to free");
+ return;
+ }
+
+ server_impl = AXIS2_INTF_TO_IMPL(server);
+ if(server_impl->svr_thread)
+ {
+ axis2_http_svr_thread_destroy(server_impl->svr_thread, env);
+ axis2_http_svr_thread_free(server_impl->svr_thread, env);
+ server_impl->svr_thread = NULL;
+ }
+
+ if(server_impl->conf_ctx_private)
+ {
+ axis2_conf_ctx_free(server_impl->conf_ctx_private, env);
+ server_impl->conf_ctx_private = NULL;
+ }
+
+ /**
+ * Do not free this. It may own to some other object
+ */
+ server_impl->conf_ctx = NULL;
+
+ AXIS2_FREE(env->allocator, server_impl);
+}
+
+static axis2_status_t AXIS2_CALL
+axis2_http_server_init(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_transport_in_desc_t * in_desc)
+{
+ axis2_http_server_impl_t *server_impl = NULL;
+ axis2_char_t *port_str = NULL;
+ axutil_param_t *param = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, server, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, in_desc, AXIS2_FAILURE);
+
+ server_impl = AXIS2_INTF_TO_IMPL(server);
+
+ server_impl->conf_ctx = conf_ctx;
+ param = (axutil_param_t *)axutil_param_container_get_param(
+ axis2_transport_in_desc_param_container(in_desc, env), env, AXIS2_PORT_STRING);
+ if(param)
+ {
+ port_str = axutil_param_get_value(param, env);
+ }
+
+ if(port_str)
+ {
+ server_impl->port = atoi(port_str);
+ }
+ return AXIS2_SUCCESS;
+}
+
+static axis2_status_t AXIS2_CALL
+axis2_http_server_start(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env)
+{
+ axis2_http_server_impl_t *server_impl = NULL;
+ axis2_http_worker_t *worker = NULL;
+
+ server_impl = AXIS2_INTF_TO_IMPL(server);
+ server_impl->svr_thread = axis2_http_svr_thread_create(env, server_impl->port);
+ if(!server_impl->svr_thread)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to create server thread for port %d",
+ server_impl->port);
+ return AXIS2_FAILURE;
+ }
+
+ worker = axis2_http_worker_create(env, server_impl->conf_ctx);
+ if(!worker)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 http worker creation failed");
+ axis2_http_svr_thread_free(server_impl->svr_thread, env);
+ return AXIS2_FAILURE;
+ }
+ axis2_http_worker_set_is_application_client_side(worker, env,
+ server_impl->is_application_client_side);
+ axis2_http_worker_set_svr_port(worker, env, server_impl->port);
+ {/** Obtain server IP and set it
+ axis2_transport_in_desc_t *transport_in = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_receiver_t *receiver = NULL;
+ conf = axis2_conf_ctx_get_conf(server_impl->conf_ctx_private, env);
+ transport_in = axis2_conf_get_transport_in(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ receiver = axis2_transport_in_desc_get_recv(transport_in, env);
+ if(receiver)
+ {
+ int listen_socket = axis2_http_svr_thread_get_listen_socket(server_impl->svr_thread, env);
+ server_impl->svr_ip = axutil_network_handler_get_svr_ip(env, listen_socket);
+ AXIS2_INTF_TO_IMPL(receiver)->svr_ip = server_impl->svr_ip;
+ }
+ */
+ }
+ AXIS2_LOG_INFO(env->log, "Starting HTTP server thread");
+ axis2_http_svr_thread_set_worker(server_impl->svr_thread, env, worker);
+ axis2_http_svr_thread_run(server_impl->svr_thread, env);
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_server_stop(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env)
+{
+ AXIS2_LOG_INFO(env->log, "Terminating HTTP server thread");
+ if(AXIS2_INTF_TO_IMPL(server)->svr_thread)
+ {
+ axis2_http_svr_thread_destroy(AXIS2_INTF_TO_IMPL(server)->svr_thread, env);
+ }
+ AXIS2_LOG_INFO(env->log, "Successfully terminated HTTP server thread");
+ return AXIS2_SUCCESS;
+}
+
+static axis2_conf_ctx_t *AXIS2_CALL
+axis2_http_server_get_conf_ctx(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env)
+{
+ return AXIS2_INTF_TO_IMPL(server)->conf_ctx;
+}
+
+static axis2_endpoint_ref_t *AXIS2_CALL
+axis2_http_server_get_reply_to_epr(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env,
+ const axis2_char_t * svc_name)
+{
+ axis2_endpoint_ref_t *epr = NULL;
+ const axis2_char_t *host_address = NULL;
+ axis2_char_t *svc_path = NULL;
+ axutil_url_t *url = NULL;
+
+ host_address = AXIS2_DEFAULT_HOST_ADDRESS; /* TODO : get from axis2.xml */
+ svc_path = axutil_stracat(env, AXIS2_DEFAULT_SVC_PATH, svc_name);
+ url = axutil_url_create(env, AXIS2_HTTP_PROTOCOL, host_address,
+ AXIS2_INTF_TO_IMPL(server)->port, svc_path);
+
+ AXIS2_FREE(env->allocator, svc_path);
+ if(!url)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create reply to epr for service %s.",
+ svc_name);
+ return NULL;
+ }
+ epr = axis2_endpoint_ref_create(env, axutil_url_to_external_form(url, env));
+ axutil_url_free(url, env);
+ return epr;
+}
+
+static axis2_endpoint_ref_t *AXIS2_CALL
+axis2_http_server_get_epr_for_service(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env,
+ const axis2_char_t * svc_name)
+{
+ axis2_endpoint_ref_t *epr = NULL;
+ const axis2_char_t *host_address = NULL;
+ axis2_char_t *svc_path = NULL;
+ axutil_url_t *url = NULL;
+
+ if(AXIS2_INTF_TO_IMPL(server)->svr_ip)
+ {
+ host_address = AXIS2_INTF_TO_IMPL(server)->svr_ip;
+ }else
+ {
+ host_address = AXIS2_DEFAULT_HOST_ADDRESS; /* TODO : get from axis2.xml */
+ }
+ svc_path = axutil_stracat(env, AXIS2_DEFAULT_SVC_PATH, svc_name);
+
+ url = axutil_url_create(env, AXIS2_HTTP_PROTOCOL, host_address,
+ AXIS2_INTF_TO_IMPL(server)->port, svc_path);
+
+ AXIS2_FREE(env->allocator, svc_path);
+ if(!url)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create reply to epr for service %s.",
+ svc_name);
+ return NULL;
+ }
+ epr = axis2_endpoint_ref_create(env, axutil_url_to_external_form(url, env));
+ axutil_url_free(url, env);
+ return epr;
+}
+
+static axis2_bool_t AXIS2_CALL
+axis2_http_server_is_running(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env)
+{
+ axis2_http_server_impl_t *server_impl = NULL;
+ server_impl = AXIS2_INTF_TO_IMPL(server);
+ if(server_impl->svr_thread)
+ {
+ return axis2_http_svr_thread_is_running(server_impl->svr_thread, env);
+ }
+ return AXIS2_FALSE;
+}
+
+static void AXIS2_CALL
+axis2_http_server_set_is_application_client_side(
+ axis2_transport_receiver_t * server,
+ const axutil_env_t * env,
+ axis2_bool_t is_application_client_side)
+{
+ axis2_http_server_impl_t *server_impl = NULL;
+ server_impl = AXIS2_INTF_TO_IMPL(server);
+ server_impl->is_application_client_side = is_application_client_side;
+}
+
+static axis2_char_t* AXIS2_CALL
+axis2_http_server_get_server_ip(
+axis2_transport_receiver_t *server,
+const axutil_env_t *env)
+{
+ return AXIS2_INTF_TO_IMPL(server)->svr_ip;
+}
+
+static void AXIS2_CALL
+axis2_http_server_set_server_ip(
+axis2_transport_receiver_t *server,
+const axutil_env_t *env,
+ axis2_char_t *serverip)
+{
+ AXIS2_INTF_TO_IMPL(server)->svr_ip = serverip;
+}
+
+/**
+ * Following block distinguish the exposed part of the dll.
+ */
+AXIS2_EXPORT int
+axis2_get_instance(
+ struct axis2_transport_receiver **inst,
+ const axutil_env_t * env)
+{
+ *inst = axis2_http_server_create(env, NULL, -1);
+ if(!(*inst))
+ {
+ return AXIS2_FAILURE;
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXPORT int
+axis2_remove_instance(
+ axis2_transport_receiver_t * inst,
+ const axutil_env_t * env)
+{
+ if(inst)
+ {
+ axis2_transport_receiver_free(inst, env);
+ }
+ return AXIS2_SUCCESS;
+}
+
diff --git a/src/core/transport/http/receiver/http_svr_thread.c b/src/core/transport/http/receiver/http_svr_thread.c
new file mode 100644
index 0000000..1806815
--- /dev/null
+++ b/src/core/transport/http/receiver/http_svr_thread.c
@@ -0,0 +1,315 @@
+/*
+ * 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 <platforms/axutil_platform_auto_sense.h>
+#include <axis2_http_svr_thread.h>
+#include <axis2_http_server.h>
+#include <axis2_http_transport.h>
+#include <axutil_string.h>
+#include <axutil_network_handler.h>
+#include <axis2_http_simple_request.h>
+#include <axis2_simple_http_svr_conn.h>
+#include <axutil_url.h>
+#include <axutil_error_default.h>
+#include <axiom_xml_reader.h>
+#include <signal.h>
+
+AXIS2_EXPORT int axis2_http_socket_read_timeout = AXIS2_HTTP_DEFAULT_SO_TIMEOUT;
+
+struct axis2_http_svr_thread
+{
+ int listen_socket;
+ axis2_bool_t stopped;
+ axis2_http_worker_t *worker;
+ int port;
+};
+
+typedef struct axis2_http_svr_thd_args
+{
+ axutil_env_t *env;
+ axis2_socket_t socket;
+ axis2_http_worker_t *worker;
+ axutil_thread_t *thread;
+} axis2_http_svr_thd_args_t;
+
+static void *AXIS2_THREAD_FUNC
+axis2_svr_thread_worker_func(
+ axutil_thread_t * thd,
+ void *data);
+
+axis2_http_svr_thread_t *AXIS2_CALL
+axis2_http_svr_thread_create(
+ const axutil_env_t * env,
+ int port)
+{
+ axis2_http_svr_thread_t *svr_thread = NULL;
+
+ svr_thread = (axis2_http_svr_thread_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_svr_thread_t));
+
+ if(!svr_thread)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ memset((void *)svr_thread, 0, sizeof(axis2_http_svr_thread_t));
+
+ svr_thread->port = port;
+ svr_thread->listen_socket = (int)axutil_network_handler_create_server_socket(env,
+ svr_thread->port);
+ if(-1 == svr_thread->listen_socket)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Http server thread socket creation failed.");
+ axis2_http_svr_thread_free((axis2_http_svr_thread_t *)svr_thread, env);
+ return NULL;
+ }
+
+ return svr_thread;
+}
+
+void AXIS2_CALL
+axis2_http_svr_thread_free(
+ axis2_http_svr_thread_t * svr_thread,
+ const axutil_env_t * env)
+{
+ if(!svr_thread)
+ {
+ return;
+ }
+
+ if(svr_thread->worker)
+ {
+ axis2_http_worker_free(svr_thread->worker, env);
+ svr_thread->worker = NULL;
+ }
+ if(-1 != svr_thread->listen_socket)
+ {
+ axutil_network_handler_close_socket(env, svr_thread->listen_socket);
+ svr_thread->listen_socket = -1;
+ }
+ svr_thread->stopped = AXIS2_TRUE;
+
+ AXIS2_FREE(env->allocator, svr_thread);
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_svr_thread_run(
+ axis2_http_svr_thread_t * svr_thread,
+ const axutil_env_t * env)
+{
+ while(AXIS2_FALSE == svr_thread->stopped)
+ {
+ int socket = -1;
+ axis2_http_svr_thd_args_t *arg_list = NULL;
+#ifdef AXIS2_SVR_MULTI_THREADED
+ axutil_thread_t *worker_thread = NULL;
+#endif
+
+ socket = (int)axutil_network_handler_svr_socket_accept(env, svr_thread-> listen_socket);
+ if(!svr_thread->worker)
+ {
+ AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI,
+ "Worker not ready yet. Cannot serve the request");
+ axutil_network_handler_close_socket(env, socket);
+ continue;
+ }
+
+ arg_list = AXIS2_MALLOC(env->allocator, sizeof(axis2_http_svr_thd_args_t));
+ if(!arg_list)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Memory allocation error in the svr thread loop");
+ continue;
+ }
+
+ arg_list->env = (axutil_env_t *)env;
+ arg_list->socket = socket;
+ arg_list->worker = svr_thread->worker;
+#ifdef AXIS2_SVR_MULTI_THREADED
+ worker_thread = axutil_thread_pool_get_thread(env->thread_pool,
+ axis2_svr_thread_worker_func, (void *) arg_list);
+ if (!worker_thread)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Thread creation failed server thread loop");
+ continue;
+ }
+ axutil_thread_pool_thread_detach(env->thread_pool, worker_thread);
+#else
+ axis2_svr_thread_worker_func(NULL, (void *)arg_list);
+#endif
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_svr_thread_destroy(
+ axis2_http_svr_thread_t * svr_thread,
+ const axutil_env_t * env)
+{
+ if(AXIS2_TRUE == svr_thread->stopped)
+ {
+ return AXIS2_SUCCESS;
+ }
+
+ svr_thread->stopped = AXIS2_TRUE;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Terminating HTTP server thread.");
+ if(svr_thread->listen_socket)
+ {
+ axutil_network_handler_close_socket(env, svr_thread->listen_socket);
+ svr_thread->listen_socket = -1;
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_http_svr_thread_get_local_port(
+ const axis2_http_svr_thread_t * svr_thread,
+ const axutil_env_t * env)
+{
+ return svr_thread->port;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_svr_thread_is_running(
+ axis2_http_svr_thread_t * svr_thread,
+ const axutil_env_t * env)
+{
+ return !(svr_thread->stopped);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_svr_thread_set_worker(
+ axis2_http_svr_thread_t * svr_thread,
+ const axutil_env_t * env,
+ axis2_http_worker_t * worker)
+{
+ AXIS2_PARAM_CHECK(env->error, worker, AXIS2_FAILURE);
+ svr_thread->worker = worker;
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * Thread worker function.
+ */
+static void *AXIS2_THREAD_FUNC
+axis2_svr_thread_worker_func(
+ axutil_thread_t * thd,
+ void *data)
+{
+ struct AXIS2_PLATFORM_TIMEB t1, t2;
+ axis2_simple_http_svr_conn_t *svr_conn = NULL;
+ axis2_http_simple_request_t *request = NULL;
+ int millisecs = 0;
+ double secs = 0;
+ axis2_http_worker_t *tmp = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_env_t *env = NULL;
+ axis2_socket_t socket;
+ axutil_env_t *thread_env = NULL;
+ axis2_http_svr_thd_args_t *arg_list = NULL;
+
+#ifndef WIN32
+#ifdef AXIS2_SVR_MULTI_THREADED
+ signal(SIGPIPE, SIG_IGN);
+#endif
+#endif
+
+ if(!data)
+ {
+ return NULL;
+ }
+ arg_list = (axis2_http_svr_thd_args_t *)data;
+
+ env = arg_list->env;
+ thread_env = axutil_init_thread_env(env);
+
+ IF_AXIS2_LOG_DEBUG_ENABLED(env->log)
+ {
+ AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t1);
+ }
+
+ socket = arg_list->socket;
+ svr_conn = axis2_simple_http_svr_conn_create(thread_env, (int)socket);
+ if(!svr_conn)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "creating simple_http_svr_connection failed");
+ return NULL;
+ }
+
+ axis2_simple_http_svr_conn_set_rcv_timeout(svr_conn, thread_env, axis2_http_socket_read_timeout);
+
+ /* read HTTPMethod, URL, HTTP Version and http headers. Leave the remaining in the stream */
+ request = axis2_simple_http_svr_conn_read_request(svr_conn, thread_env);
+ if(!request)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create request");
+ return NULL;
+ }
+
+ tmp = arg_list->worker;
+ status = axis2_http_worker_process_request(tmp, thread_env, svr_conn, request);
+ axis2_simple_http_svr_conn_free(svr_conn, thread_env);
+ axis2_http_simple_request_free(request, thread_env);
+
+ IF_AXIS2_LOG_DEBUG_ENABLED(env->log)
+ {
+ AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t2);
+ millisecs = t2.millitm - t1.millitm;
+ secs = difftime(t2.time, t1.time);
+ if(millisecs < 0)
+ {
+ millisecs += 1000;
+ secs--;
+ }
+ secs += millisecs / 1000.0;
+
+#if defined(WIN32)
+ AXIS2_LOG_DEBUG(thread_env->log, AXIS2_LOG_SI, "Request processed...");
+#else
+ AXIS2_LOG_DEBUG(thread_env->log, AXIS2_LOG_SI, "Request processed in %.3f seconds", secs);
+#endif
+ }
+
+ if(status == AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_DEBUG(thread_env->log, AXIS2_LOG_SI, "Request served successfully");
+ }
+ else
+ {
+ AXIS2_LOG_WARNING(thread_env->log, AXIS2_LOG_SI, "Error occurred in processing request ");
+ }
+
+ AXIS2_FREE(thread_env->allocator, arg_list);
+ axutil_free_thread_env(thread_env);
+ thread_env = NULL;
+
+#ifdef AXIS2_SVR_MULTI_THREADED
+ axutil_thread_pool_exit_thread(env->thread_pool, thd);
+#endif
+
+ return NULL;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+ axis2_http_svr_thread_get_listen_socket(
+ axis2_http_svr_thread_t *svr_thread,
+ const axutil_env_t *env)
+{
+ return svr_thread->listen_socket;
+
+}
diff --git a/src/core/transport/http/sender/Makefile.am b/src/core/transport/http/sender/Makefile.am
new file mode 100644
index 0000000..399ed39
--- /dev/null
+++ b/src/core/transport/http/sender/Makefile.am
@@ -0,0 +1,51 @@
+SUBDIRS=ssl libcurl
+lib_LTLIBRARIES = libaxis2_http_sender.la
+
+
+
+if AXIS2_LIBCURL_ENABLED
+LIBCURL_SOURCES=libcurl/axis2_libcurl.c\
+ libcurl/libcurl_stream.c
+LIBCURL_LIBS=-lssl -lcrypto -lcurl -ldl -lz
+else
+LIBCURL_SOURCES=
+LIBCURL_LIBS=
+endif
+
+
+if AXIS2_SSL_ENABLED
+SSL_SOURCES = ssl/ssl_stream.c\
+ ssl/ssl_utils.c
+SSL_LIBS = -lssl -lcrypto
+else
+SSL_SOURCES=
+SSL_LIBS=
+endif
+
+libaxis2_http_sender_la_SOURCES = http_transport_sender.c \
+ http_sender.c \
+ http_client.c \
+ $(SSL_SOURCES) \
+ $(LIBCURL_SOURCES)
+
+libaxis2_http_sender_la_LIBADD = $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la\
+ $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la\
+ $(top_builddir)/axiom/src/om/libaxis2_axiom.la\
+ $(top_builddir)/util/src/libaxutil.la\
+ $(LIBCURL_LIBS)\
+ $(SSL_LIBS)
+
+
+libaxis2_http_sender_la_LDFLAGS = -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport\
+ -I$(top_builddir)/src/core/transport/http \
+ -I$(top_builddir)/src/core/transport/http/sender/libcurl \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
diff --git a/src/core/transport/http/sender/http_client.c b/src/core/transport/http/sender/http_client.c
new file mode 100644
index 0000000..80e7ee3
--- /dev/null
+++ b/src/core/transport/http/sender/http_client.c
@@ -0,0 +1,965 @@
+/*
+ * 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_client.h>
+#include <axis2_http_transport.h>
+#include <axutil_stream.h>
+#include <axutil_string.h>
+#include <axutil_network_handler.h>
+#include <axis2_http_request_line.h>
+#include <axis2_http_header.h>
+#include <axis2_http_status_line.h>
+#include <axutil_http_chunked_stream.h>
+#include <platforms/axutil_platform_auto_sense.h>
+#include <axiom_mime_part.h>
+#include <axis2_http_transport_utils.h>
+
+#ifdef AXIS2_SSL_ENABLED
+#include "ssl/ssl_stream.h"
+#endif
+
+struct axis2_http_client
+{
+ int sockfd;
+ axutil_stream_t *data_stream;
+ axutil_url_t *url;
+ axis2_http_simple_response_t *response;
+ axis2_bool_t request_sent;
+ int timeout;
+ axis2_bool_t proxy_enabled;
+ axis2_char_t *proxy_host;
+ int proxy_port;
+ axis2_char_t *proxy_host_port;
+ axis2_bool_t dump_input_msg;
+ axis2_char_t *server_cert;
+ axis2_char_t *key_file;
+ axis2_char_t *req_body;
+ int req_body_size;
+
+ /* These are for mtom case */
+ axutil_array_list_t *mime_parts;
+ axis2_bool_t doing_mtom;
+ axis2_char_t *mtom_sending_callback_name;
+};
+
+AXIS2_EXTERN axis2_http_client_t *AXIS2_CALL
+axis2_http_client_create(
+ const axutil_env_t * env,
+ axutil_url_t * url)
+{
+ axis2_http_client_t *http_client = NULL;
+
+ http_client = (axis2_http_client_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_client_t));
+
+ if(!http_client)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ memset(http_client, 0, sizeof(axis2_http_client_t));
+
+ http_client->url = url;
+ http_client->data_stream = NULL;
+ http_client->sockfd = -1;
+ http_client->response = NULL;
+ http_client->request_sent = AXIS2_FALSE;
+
+ /* default timeout is 60000 milliseconds */
+ http_client->timeout = AXIS2_HTTP_DEFAULT_CONNECTION_TIMEOUT;
+ http_client->proxy_enabled = AXIS2_FALSE;
+ http_client->proxy_port = 0;
+ http_client->proxy_host = NULL;
+ http_client->proxy_host_port = NULL;
+ http_client->dump_input_msg = AXIS2_FALSE;
+ http_client->server_cert = NULL;
+ http_client->key_file = NULL;
+ http_client->req_body = NULL;
+ http_client->req_body_size = 0;
+ http_client->mime_parts = NULL;
+ http_client->doing_mtom = AXIS2_FALSE;
+ http_client->mtom_sending_callback_name = NULL;
+
+ return http_client;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_client_free(
+ axis2_http_client_t * http_client,
+ const axutil_env_t * env)
+{
+ if(http_client->proxy_host)
+ {
+ AXIS2_FREE(env->allocator, http_client->proxy_host);
+ }
+ if(http_client->proxy_host_port)
+ {
+ AXIS2_FREE(env->allocator, http_client->proxy_host_port);
+ }
+ if(http_client->url)
+ {
+ axutil_url_free(http_client->url, env);
+ }
+ if(http_client->response)
+ {
+ axis2_http_simple_response_free(http_client->response, env);
+ }
+ if(-1 != http_client->sockfd)
+ {
+ axutil_network_handler_close_socket(env, http_client->sockfd);
+ http_client->sockfd = -1;
+ }
+
+ if(http_client->req_body)
+ {
+ AXIS2_FREE(env->allocator, http_client->req_body);
+ }
+
+ /* There is no other appropriate place to free the mime_part list when a
+ * particular client send requests. */
+
+ if(http_client->mime_parts)
+ {
+ int i = 0;
+ for(i = 0; i < axutil_array_list_size(http_client->mime_parts, env); i++)
+ {
+ axiom_mime_part_t *mime_part = NULL;
+ mime_part = (axiom_mime_part_t *)axutil_array_list_get(http_client->mime_parts, env, i);
+ if(mime_part)
+ {
+ axiom_mime_part_free(mime_part, env);
+ }
+ }
+ axutil_array_list_free(http_client->mime_parts, env);
+ }
+
+ AXIS2_FREE(env->allocator, http_client);
+ return;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_client_free_void_arg(
+ void *client,
+ const axutil_env_t * env)
+{
+ axis2_http_client_t *client_l = NULL;
+
+ client_l = (axis2_http_client_t *)client;
+ axis2_http_client_free(client_l, env);
+ return;
+}
+
+/* This is the main method which writes to the socket in the case of a client
+ * sends an http_request. Previously this method does not distinguish between a
+ * mtom request and non mtom request. Because what finally it had was the
+ * complete buffer with the request. But now MTOM invocations are done
+ * differently in order to support large attachments so this method should
+ * distinguish those invocations */
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_send(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * ssl_pp)
+{
+ char *wire_format = NULL;
+ axutil_array_list_t *headers = NULL;
+ char *str_header = NULL;
+ char *str_request_line = NULL;
+ int written = 0;
+ axis2_status_t status = AXIS2_FAILURE;
+ axis2_bool_t chunking_enabled = AXIS2_FALSE;
+ axis2_char_t *host = NULL;
+ unsigned int port = 0;
+
+ /* In the MTOM case request body is not set. Instead mime_parts
+ array_list is there */
+
+ if(client->req_body)
+ {
+ AXIS2_FREE(env->allocator, client->req_body);
+ client->req_body = NULL;
+ }
+ if(!client->req_body && !(client->doing_mtom))
+ {
+ client->req_body_size = axis2_http_simple_request_get_body_bytes(request, env,
+ &client->req_body);
+ }
+
+ if(client->dump_input_msg == AXIS2_TRUE)
+ {
+ return AXIS2_SUCCESS;
+ }
+
+ if(!client->url)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_URL, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Request url not set");
+ return AXIS2_FAILURE;
+ }
+
+ host = axutil_url_get_host(client->url, env);
+ port = axutil_url_get_port(client->url, env);
+
+ if(client->proxy_enabled)
+ {
+ if(!client->proxy_host || client->proxy_port <= 0)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy port or Host not set");
+ return AXIS2_FAILURE;
+ }
+
+ if(client->sockfd < 0)
+ {
+ client->sockfd = (int)axutil_network_handler_open_socket(env, client->proxy_host,
+ client->proxy_port);
+ }
+ }
+ else
+ {
+ /*Proxy is not enabled*/
+
+ if(client->sockfd < 0)
+ {
+ client->sockfd = (int)axutil_network_handler_open_socket(env, host, port);
+ }
+ }
+
+ if(client->sockfd < 0)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Socket Creation failed.");
+ return AXIS2_FAILURE;
+ }
+
+ if(client->timeout > 0)
+ {
+ /*Set the receiving time out*/
+ axutil_network_handler_set_sock_option(env, client->sockfd, SO_RCVTIMEO, client->timeout);
+ /*Set the sending time out*/
+
+ axutil_network_handler_set_sock_option(env, client->sockfd, SO_SNDTIMEO, client->timeout);
+ }
+
+ if(0 == axutil_strcasecmp(axutil_url_get_protocol(client->url, env), AXIS2_TRANSPORT_URL_HTTPS))
+ {
+#ifdef AXIS2_SSL_ENABLED
+ if (client->proxy_enabled)
+ {
+ if (AXIS2_SUCCESS != axis2_http_client_connect_ssl_host(client, env, host, port))
+ {
+ axutil_network_handler_close_socket(env, client->sockfd);
+ client->sockfd = -1;
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTPS connection creation failed");
+ return AXIS2_FAILURE;
+ }
+ }
+ client->data_stream =
+ axutil_stream_create_ssl(env, client->sockfd, axis2_http_client_get_server_cert(client,
+ env), axis2_http_client_get_key_file(client, env), ssl_pp);
+#else
+ axutil_network_handler_close_socket(env, client->sockfd);
+ client->sockfd = -1;
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_TRANSPORT_PROTOCOL, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Invalid Transport Protocol, HTTPS transport not enabled.");
+
+ return AXIS2_FAILURE;
+#endif
+ }
+ else
+ {
+ client->data_stream = axutil_stream_create_socket(env, client->sockfd);
+ }
+
+ if(!client->data_stream)
+ {
+ axutil_network_handler_close_socket(env, client->sockfd);
+ client->sockfd = -1;
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Data stream creation failed for Host %s and %d port", host, port);
+
+ return AXIS2_FAILURE;
+ }
+
+ /*Accessing HTTP headers*/
+
+ headers = axis2_http_simple_request_get_headers(request, env);
+ if(headers)
+ {
+ int header_count = axutil_array_list_size(headers, env);
+ int i = 0;
+ char *str_header2 = NULL;
+ for(i = 0; i < header_count; i++)
+ {
+ axis2_char_t *header_ext_form = NULL;
+ axis2_http_header_t *tmp_header = (axis2_http_header_t *)axutil_array_list_get(headers,
+ env, i);
+
+ if(!tmp_header)
+ {
+ /* This continue is added as a safey mechanism,
+ * However I see a problem with this logic, AFAIC
+ * see there can't be null headers in the headers
+ * array list, because number of headers in "headers"
+ * array list count with axutil_array_list_size,
+ * therefore this check and continue might not have a
+ * real effect.*/
+
+ continue;
+ }
+
+ /* check whether we have transfer encoding and then see whether the
+ * value is "chunked" */
+ if(!axutil_strcmp(axis2_http_header_get_name(tmp_header, env),
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING) && !axutil_strcmp(axis2_http_header_get_value(
+ tmp_header, env), AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ chunking_enabled = AXIS2_TRUE;
+ }
+
+ header_ext_form = axis2_http_header_to_external_form(tmp_header, env);
+
+ /* str_header2 is to hold intermediate value of str_header */
+ str_header2 = axutil_stracat(env, str_header, header_ext_form);
+ if(str_header)
+ {
+ AXIS2_FREE(env->allocator, str_header);
+ str_header = NULL;
+ }
+ if(header_ext_form)
+ {
+ AXIS2_FREE(env->allocator, header_ext_form);
+ header_ext_form = NULL;
+ }
+
+ /* str_header has all HTTP headers to send. */
+ str_header = str_header2;
+ }
+ }
+
+ if(AXIS2_FALSE == client->proxy_enabled)
+ {
+ str_request_line = axis2_http_request_line_to_string(
+ axis2_http_simple_request_get_request_line(request, env), env);
+ }
+ else
+ {
+ /* proxy enabled case */
+
+ /* we need the request line in the format
+ * POST http://host:port/path HTTP/1.x if we have enabled proxies
+ */
+ axis2_char_t *host_port_str = NULL;
+ axis2_char_t *host = axutil_url_get_host(client->url, env);
+ axis2_http_request_line_t *request_line = axis2_http_simple_request_get_request_line(
+ request, env);
+ axis2_char_t *path = axis2_http_request_line_get_uri(request_line, env);
+
+ host_port_str = AXIS2_MALLOC(env->allocator, axutil_strlen(host) + axutil_strlen(path) + 20
+ * sizeof(axis2_char_t));
+
+ if(!host_port_str)
+ {
+ axutil_network_handler_close_socket(env, client->sockfd);
+ client->sockfd = -1;
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Memory allocation failed for host %s and %s path", host, path);
+
+ return AXIS2_FAILURE;
+ }
+
+ sprintf(host_port_str, "http://%s:%d%s", host, axutil_url_get_port(client->url, env), path);
+ str_request_line = AXIS2_MALLOC(env->allocator, axutil_strlen(host_port_str) + 20
+ * sizeof(axis2_char_t));
+
+ if(!str_request_line)
+ {
+ axutil_network_handler_close_socket(env, client->sockfd);
+ client->sockfd = -1;
+ AXIS2_FREE(env->allocator, host_port_str);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "memory allocation failed for host %s and %s path", host, path);
+
+ return AXIS2_FAILURE;
+ }
+
+ sprintf(str_request_line, "%s %s %s\r\n", axis2_http_request_line_get_method(request_line,
+ env), host_port_str, axis2_http_request_line_get_http_version(request_line, env));
+
+ AXIS2_FREE(env->allocator, host_port_str);
+ host_port_str = NULL;
+
+ }
+
+ /* Here first we send the http header part */
+
+ wire_format = axutil_stracat(env, str_request_line, str_header);
+ AXIS2_FREE(env->allocator, str_header);
+ str_header = NULL;
+ AXIS2_FREE(env->allocator, str_request_line);
+ str_request_line = NULL;
+ written
+ = axutil_stream_write(client->data_stream, env, wire_format, axutil_strlen(wire_format));
+ AXIS2_FREE(env->allocator, wire_format);
+ wire_format = NULL;
+
+ /* Then we write the two new line charaters before the http body*/
+
+ written = axutil_stream_write(client->data_stream, env, AXIS2_HTTP_CRLF, 2);
+
+ /* When sending MTOM it is bit different. We keep the attachment + other
+ mime headers in an array_list and send them one by one */
+
+ if(client->doing_mtom)
+ {
+ axis2_status_t status = AXIS2_SUCCESS;
+ axutil_http_chunked_stream_t *chunked_stream = NULL;
+
+ /* If the callback name is not there, then we will check whether there
+ * is any mime_parts which has type callback. If we found then no point
+ * of continuing we should return a failure */
+
+ if(!(client->mtom_sending_callback_name))
+ {
+ if(axis2_http_transport_utils_is_callback_required(env, client->mime_parts))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Sender callback not specified");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ /* For MTOM we automatically enabled chunking */
+ chunked_stream = axutil_http_chunked_stream_create(env, client->data_stream);
+
+ /* This method will write the Attachment + data to the wire */
+
+ status = axis2_http_transport_utils_send_mtom_message(chunked_stream, env,
+ client->mime_parts, client->mtom_sending_callback_name);
+
+ axutil_http_chunked_stream_free(chunked_stream, env);
+ chunked_stream = NULL;
+
+ }
+ /* Non MTOM case */
+ else if(client->req_body_size > 0 && client->req_body)
+ {
+ int len = 0;
+ written = 0;
+
+ /* Keep on writing data in a loop until we finised
+ with all the data in the buffer */
+
+ if(!chunking_enabled)
+ {
+ status = AXIS2_SUCCESS;
+ while(written < client->req_body_size)
+ {
+ len = 0;
+ len = axutil_stream_write(client->data_stream, env, client->req_body + written,
+ client->req_body_size - written);
+ if(-1 == len)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ else
+ {
+ written += len;
+ }
+ }
+ }
+ else
+ {
+ /* Not MTOM but chunking is enabled */
+ axutil_http_chunked_stream_t *chunked_stream = NULL;
+ chunked_stream = axutil_http_chunked_stream_create(env, client->data_stream);
+ status = AXIS2_SUCCESS;
+ if(!chunked_stream)
+ {
+ axutil_network_handler_close_socket(env, client->sockfd);
+ client->sockfd = -1;
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creatoin of chunked stream failed");
+ return AXIS2_FAILURE;
+ }
+
+ while(written < client->req_body_size)
+ {
+ written = axutil_http_chunked_stream_write(chunked_stream, env, client->req_body,
+ client->req_body_size);
+
+ if(-1 == written)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ }
+
+ if(AXIS2_SUCCESS == status)
+ {
+ /* Writing the trailing null charactor */
+ axutil_http_chunked_stream_write_last_chunk(chunked_stream, env);
+ }
+
+ axutil_http_chunked_stream_free(chunked_stream, env);
+ }
+ }
+
+ client->request_sent = AXIS2_TRUE;
+ return status;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_http_client_recieve_header(
+ axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ int status_code = -1;
+ axis2_http_status_line_t *status_line = NULL;
+ axis2_char_t str_status_line[512];
+ axis2_char_t tmp_buf[3];
+ axis2_char_t str_header[512];
+ int read = 0;
+ int http_status = 0;
+ axis2_bool_t end_of_line = AXIS2_FALSE;
+ axis2_bool_t end_of_headers = AXIS2_FALSE;
+
+ if(-1 == client->sockfd || !client->data_stream || AXIS2_FALSE == client->request_sent)
+ {
+ axis2_char_t *host;
+ unsigned int port;
+ host = axutil_url_get_host(client->url, env);
+ port = axutil_url_get_port(client->url, env);
+
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "client data stream null or socket error for host \
+%s and %d port", host, port);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_REQUEST_NOT_SENT, AXIS2_FAILURE);
+ return -1;
+ }
+
+ /* read the status line */
+ do
+ {
+ memset(str_status_line, 0, 512);
+ while((read = axutil_stream_read(client->data_stream, env, tmp_buf, 1)) > 0)
+ {
+ /* "read" variable is number of characters read by stream */
+ tmp_buf[read] = '\0';
+ strcat(str_status_line, tmp_buf);
+ if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF))
+ {
+ end_of_line = AXIS2_TRUE;
+ break;
+ }
+ }
+
+ if(read < 0)
+ {
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "http client , response timed out");
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE);
+ return -1;
+ }
+ else if(read == 0)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_SERVER_SHUTDOWN, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response error, Server Shutdown");
+ return 0;
+ }
+
+ status_line = axis2_http_status_line_create(env, str_status_line);
+ if(!status_line)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "axis2_http_status_line_create failed for \
+str_status_line %s", str_status_line);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ http_status = 0;
+ continue;
+
+ }
+ http_status = axis2_http_status_line_get_status_code(status_line, env);
+
+ }
+ while(AXIS2_HTTP_RESPONSE_OK_CODE_VAL > http_status);
+
+ if(client->response)
+ axis2_http_simple_response_free(client->response, env);
+ client->response = axis2_http_simple_response_create_default(env);
+ axis2_http_simple_response_set_status_line(client->response, env,
+ axis2_http_status_line_get_http_version(status_line, env),
+ axis2_http_status_line_get_status_code(status_line, env),
+ axis2_http_status_line_get_reason_phrase(status_line, env));
+
+ /* now read the headers */
+ memset(str_header, 0, 512);
+ end_of_line = AXIS2_FALSE;
+ while(AXIS2_FALSE == end_of_headers)
+ {
+ while((read = axutil_stream_read(client->data_stream, env, tmp_buf, 1)) > 0)
+ {
+ tmp_buf[read] = '\0';
+ strcat(str_header, tmp_buf);
+ if(0 != strstr(str_header, AXIS2_HTTP_CRLF))
+ {
+ end_of_line = AXIS2_TRUE;
+ break;
+ }
+ }
+ if(AXIS2_TRUE == end_of_line)
+ {
+ if(0 == axutil_strcmp(str_header, AXIS2_HTTP_CRLF))
+ {
+ end_of_headers = AXIS2_TRUE;
+ }
+ else
+ {
+ axis2_http_header_t *tmp_header = axis2_http_header_create_by_str(env, str_header);
+ memset(str_header, 0, 512);
+ if(tmp_header)
+ {
+ axis2_http_simple_response_set_header(client->response, env, tmp_header);
+ }
+ }
+ }
+ end_of_line = AXIS2_FALSE;
+ }
+ axis2_http_simple_response_set_body_stream(client->response, env, client->data_stream);
+ if(status_line)
+ {
+ status_code = axis2_http_status_line_get_status_code(status_line, env);
+ axis2_http_status_line_free(status_line, env);
+ status_line = NULL;
+ }
+
+ if(AXIS2_FALSE == axis2_http_simple_response_contains_header(client->response, env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE) && 202 != status_code
+ && axis2_http_simple_response_get_content_length(client->response, env) > 0)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_CONTENT_TYPE_MISSING, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response does not contain" " Content-Type");
+ return -1;
+ }
+ return status_code;
+}
+
+AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL
+axis2_http_client_get_response(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ return client->response;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_url(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axutil_url_t * url)
+{
+ AXIS2_PARAM_CHECK(env->error, url, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
+
+ if(client->url)
+ {
+ axutil_url_free(client->url, env);
+ client->url = NULL;
+ }
+ client->url = url;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axutil_url_t *AXIS2_CALL
+axis2_http_client_get_url(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, client, NULL);
+ return client->url;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_timeout(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ int timeout_ms)
+{
+ AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
+ client->timeout = timeout_ms;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_http_client_get_timeout(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
+ return client->timeout;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_proxy(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_char_t * proxy_host,
+ int proxy_port)
+{
+ AXIS2_PARAM_CHECK(env->error, proxy_host, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
+
+ if(proxy_port <= 0)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ client->proxy_port = proxy_port;
+ if(client->proxy_host)
+ {
+ AXIS2_FREE(env->allocator, client->proxy_host);
+ client->proxy_host = NULL;
+ }
+
+ if(client->proxy_host_port)
+ {
+ AXIS2_FREE(env->allocator, client->proxy_host_port);
+ client->proxy_host_port = NULL;
+ }
+
+ client->proxy_host = axutil_strdup(env, proxy_host);
+ if(!client->proxy_host)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ client->proxy_host_port = AXIS2_MALLOC(env->allocator, axutil_strlen(proxy_host) + 10
+ * sizeof(axis2_char_t));
+
+ sprintf(client->proxy_host_port, "%s:%d", proxy_host, proxy_port);
+ client->proxy_enabled = AXIS2_TRUE;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_client_get_proxy(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, client, NULL);
+ return client->proxy_host_port;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_connect_ssl_host(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_char_t * host,
+ int port)
+{
+ axutil_stream_t *tmp_stream = NULL;
+ axis2_char_t *connect_string = NULL;
+ axis2_char_t str_status_line[512];
+ axis2_char_t tmp_buf[3];
+ int read = 0;
+ axis2_bool_t end_of_line = AXIS2_FALSE;
+ axis2_bool_t end_of_response = AXIS2_FALSE;
+ axis2_http_status_line_t *status_line = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, host, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, client->url, AXIS2_FAILURE);
+ /* This host and port will use for give undersandable log messages
+ * */
+
+ if(port <= 0)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ tmp_stream = axutil_stream_create_socket(env, client->sockfd);
+ if(!tmp_stream)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "unable to create open socket for ssl host %s and %d \
+port", host, port);
+ return AXIS2_FAILURE;
+ }
+
+ connect_string = AXIS2_MALLOC(env->allocator, axutil_strlen(host) * sizeof(axis2_char_t) + 30
+ * sizeof(axis2_char_t));
+ sprintf(connect_string, "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
+ axutil_stream_write(tmp_stream, env, connect_string, axutil_strlen(connect_string)
+ * sizeof(axis2_char_t));
+
+ memset(str_status_line, 0, 512);
+ while((read = axutil_stream_read(tmp_stream, env, tmp_buf, 1)) > 0)
+ {
+ tmp_buf[read] = '\0';
+ strcat(str_status_line, tmp_buf);
+ if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF))
+ {
+ end_of_line = AXIS2_TRUE;
+ break;
+ }
+ }
+ if(read < 0)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE);
+ AXIS2_FREE(env->allocator, connect_string);
+ axutil_stream_free(tmp_stream, env);
+ return AXIS2_FAILURE;
+ }
+ status_line = axis2_http_status_line_create(env, str_status_line);
+ if(!status_line)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
+ AXIS2_FREE(env->allocator, connect_string);
+ axutil_stream_free(tmp_stream, env);
+ return AXIS2_FAILURE;
+ }
+ if(200 != axis2_http_status_line_get_status_code(status_line, env))
+ {
+ AXIS2_FREE(env->allocator, connect_string);
+ axutil_stream_free(tmp_stream, env);
+ return AXIS2_FAILURE;
+ }
+ /* We need to empty the stream before we return
+ */
+ memset(str_status_line, 0, 512);
+ while(AXIS2_FALSE == end_of_response)
+ {
+ while((read = axutil_stream_read(tmp_stream, env, tmp_buf, 1)) > 0)
+ {
+ tmp_buf[read] = '\0';
+ strcat(str_status_line, tmp_buf);
+ if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF))
+ {
+ end_of_line = AXIS2_TRUE;
+ break;
+ }
+ }
+ if(AXIS2_TRUE == end_of_line)
+ {
+ if(0 == axutil_strcmp(str_status_line, AXIS2_HTTP_CRLF))
+ {
+ end_of_response = AXIS2_TRUE;
+ }
+ }
+ }
+ AXIS2_FREE(env->allocator, connect_string);
+ axutil_stream_free(tmp_stream, env);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_dump_input_msg(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_bool_t dump_input_msg)
+{
+ client->dump_input_msg = dump_input_msg;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_server_cert(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_char_t * server_cert)
+{
+ AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, server_cert, AXIS2_FAILURE);
+ client->server_cert = server_cert;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_client_get_server_cert(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ return client->server_cert;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_key_file(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_char_t * key_file)
+{
+ AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, key_file, AXIS2_FAILURE);
+ client->key_file = key_file;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_client_get_key_file(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ return client->key_file;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_mime_parts(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axutil_array_list_t *mime_parts)
+{
+ client->mime_parts = mime_parts;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axis2_http_client_get_mime_parts(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ return client->mime_parts;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_doing_mtom(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_bool_t doing_mtom)
+{
+ client->doing_mtom = doing_mtom;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_client_get_doing_mtom(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env)
+{
+ return client->doing_mtom;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_client_set_mtom_sending_callback_name(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_char_t *callback_name)
+{
+ client->mtom_sending_callback_name = callback_name;
+ return AXIS2_SUCCESS;
+}
diff --git a/src/core/transport/http/sender/http_sender.c b/src/core/transport/http/sender/http_sender.c
new file mode 100644
index 0000000..56f11e0
--- /dev/null
+++ b/src/core/transport/http/sender/http_sender.c
@@ -0,0 +1,3332 @@
+/*
+ * 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_sender.h>
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <axis2_http_transport_utils.h>
+#include <string.h>
+#include <axiom_output.h>
+#include <axis2_op_ctx.h>
+#include <axis2_ctx.h>
+#include <axis2_conf_ctx.h>
+#include <axis2_http_client.h>
+#include <axiom_xml_writer.h>
+#include <axutil_property.h>
+#include <axutil_param.h>
+#include <axutil_types.h>
+#include <axutil_generic_obj.h>
+#include <axutil_uuid_gen.h>
+#include <axutil_digest_calc.h>
+#include <axis2_const.h>
+#include <axis2_util.h>
+#include <axiom_soap.h>
+#include <axutil_version.h>
+
+#ifdef AXIS2_LIBCURL_ENABLED
+#include "libcurl/axis2_libcurl.h"
+#else
+#define CLIENT_NONCE_LENGTH 8
+#endif
+
+struct axis2_http_sender
+{
+ axis2_char_t *http_version;
+ axis2_bool_t chunked;
+ int so_timeout;
+ axiom_output_t *om_output;
+ axis2_http_client_t *client;
+ axis2_bool_t is_soap;
+ axis2_bool_t keep_alive;
+};
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static void
+axis2_http_sender_add_header_list(
+ axis2_http_simple_request_t * request,
+ const axutil_env_t * env,
+ axutil_array_list_t * array_list);
+
+static axis2_status_t
+axis2_http_sender_configure_proxy(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+static axis2_status_t
+axis2_http_sender_configure_server_cert(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+static axis2_status_t
+axis2_http_sender_configure_key_file(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+static axis2_status_t
+axis2_http_sender_configure_http_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_set_http_auth_type(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_set_proxy_auth_type(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_configure_http_basic_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_basic_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_configure_http_digest_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_data);
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_digest_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_data);
+
+
+
+#endif
+
+static axutil_hash_t *
+axis2_http_sender_connection_map_create(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx);
+
+static void
+axis2_http_sender_connection_map_remove(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_http_client_t *http_client);
+
+static void
+axis2_http_sender_connection_map_add(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_http_client_t *http_client);
+
+static axis2_http_client_t *
+axis2_http_sender_connection_map_get(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx);
+
+static void AXIS2_CALL
+axis2_http_sender_connection_map_free(
+ void *cm_void,
+ const axutil_env_t *env);
+
+AXIS2_EXTERN axis2_http_sender_t *AXIS2_CALL
+axis2_http_sender_create(
+ const axutil_env_t * env)
+{
+ axis2_http_sender_t *sender = NULL;
+
+ sender = (axis2_http_sender_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_sender_t));
+
+ if(!sender)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ memset(sender, 0, sizeof(axis2_http_sender_t));
+ sender->http_version = (axis2_char_t *)AXIS2_HTTP_HEADER_PROTOCOL_11;
+ sender->so_timeout = AXIS2_HTTP_DEFAULT_SO_TIMEOUT;
+ /* unlike the java impl we don't have a default om output
+ * it should be explicitly set and it's a MUST
+ */
+ sender->om_output = NULL;
+ sender->chunked = AXIS2_FALSE;
+ sender->client = NULL;
+ sender->keep_alive = AXIS2_TRUE;
+
+ return sender;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_sender_free(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env)
+{
+ if(sender->http_version)
+ {
+ AXIS2_FREE(env->allocator, sender->http_version);
+ }
+
+ /* Do not free this here since it will be required in later processing
+ * of the response soap message
+ */
+ sender->client = NULL;
+ AXIS2_FREE(env->allocator, sender);
+ return;
+}
+
+#ifndef AXIS2_LIBCURL_ENABLED
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_send(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axiom_soap_envelope_t * out,
+ const axis2_char_t * str_url,
+ const axis2_char_t * soap_action)
+{
+ axis2_http_simple_request_t *request = NULL;
+ axis2_http_request_line_t *request_line = NULL;
+
+ /* url is to hold url given in str_url */
+ axutil_url_t *url = NULL;
+ axiom_xml_writer_t *xml_writer = NULL;
+ axis2_char_t *buffer = NULL;
+ unsigned int buffer_size = 0;
+ const axis2_char_t *char_set_enc = NULL;
+ axutil_string_t *char_set_enc_str = NULL;
+ int status_code = -1;
+ axis2_http_simple_response_t *response = NULL;
+ axis2_char_t *content_type = NULL;
+ axis2_bool_t content_type_deepl_copy = AXIS2_TRUE;
+ axis2_byte_t *output_stream = NULL;
+ int output_stream_size = 0;
+ axis2_bool_t doing_mtom = AXIS2_FALSE;
+ axutil_property_t *dump_property = NULL;
+ axutil_param_t *ssl_pp_param = NULL;
+ /* ssl passphrase */
+ axis2_char_t *ssl_pp = NULL;
+ axutil_property_t *ssl_pp_property = NULL;
+ axutil_property_t *test_auth_property = NULL;
+ axis2_char_t *test_auth_property_value = NULL;
+ axis2_bool_t test_proxy_auth = AXIS2_FALSE;
+ axis2_bool_t test_http_auth = AXIS2_FALSE;
+
+ /* http proxy authentication */
+ axutil_property_t *proxy_auth_property = NULL;
+ axis2_char_t *proxy_auth_property_value = NULL;
+ axis2_bool_t force_proxy_auth = AXIS2_FALSE;
+ axis2_bool_t force_proxy_auth_with_head = AXIS2_FALSE;
+ axutil_property_t *http_auth_property = NULL;
+ axis2_char_t *http_auth_property_value = NULL;
+ axis2_bool_t force_http_auth = AXIS2_FALSE;
+ axis2_bool_t force_http_auth_with_head = AXIS2_FALSE;
+ axutil_property_t *content_type_property = NULL;
+ axutil_hash_t *content_type_hash = NULL;
+ axis2_char_t *content_type_value = NULL;
+ axutil_property_t *method = NULL;
+ axis2_char_t *method_value = NULL;
+
+ /* handling REST requests */
+ axis2_bool_t send_via_get = AXIS2_FALSE;
+ axis2_bool_t send_via_head = AXIS2_FALSE;
+ axis2_bool_t send_via_delete = AXIS2_FALSE;
+ axis2_bool_t send_via_put = AXIS2_FALSE;
+ axiom_node_t *data_out = NULL;
+ axiom_node_t *body_node = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axis2_bool_t is_soap = AXIS2_TRUE;
+ axis2_bool_t add_keepalive_header = AXIS2_FALSE;
+
+ /* http header property to get HTTP headers from msg_ctx and give
+ * it to http_sender */
+ axutil_property_t *http_property = NULL;
+ axutil_array_list_t *array_list;
+ axis2_bool_t http_auth_header_added = AXIS2_FALSE;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *write_xml_declaration_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+ axis2_bool_t write_xml_declaration = AXIS2_FALSE;
+ axutil_property_t *property = NULL;/* Property for holding http client */
+ /*axis2_char_t *header_value = NULL;*/
+ axis2_char_t *cookie_str = NULL;
+ axutil_hash_t *connection_map = NULL;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_sender_send");
+ soap_body = axiom_soap_envelope_get_body(out, env);
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, out, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, str_url, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, soap_action, AXIS2_FAILURE);
+
+ if(AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ is_soap = AXIS2_FALSE;
+ }
+ else
+ {
+ is_soap = AXIS2_TRUE;
+ }
+
+ url = axutil_url_parse_string(env, str_url);
+
+ if(!is_soap)
+ {
+ if(soap_body)
+ {
+ body_node = axiom_soap_body_get_base_node(soap_body, env);
+ }
+ if(body_node)
+ {
+ data_out = axiom_node_get_first_element(body_node, env);
+ }
+
+ method = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_METHOD);
+ if(method)
+ {
+ method_value = (axis2_char_t *)axutil_property_get_value(method, env);
+ }
+
+ /* The default is POST */
+ if(method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_GET))
+ {
+ send_via_get = AXIS2_TRUE;
+ }
+ else if(method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_HEAD))
+ {
+ send_via_head = AXIS2_TRUE;
+ }
+ else if(method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_PUT))
+ {
+ send_via_put = AXIS2_TRUE;
+ }
+ else if(method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_DELETE))
+ {
+ send_via_delete = AXIS2_TRUE;
+ }
+ }
+
+ if(!url)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "url is null for string %s", str_url);
+ return AXIS2_FAILURE;
+ }
+
+ /*if(sender->client)
+ {
+ axis2_http_client_free(sender->client, env);
+ sender->client = NULL;
+ }*/
+
+ /* This property may be set by the application client. This get the priority over the keep alive
+ * parameter set in the axix2.xml
+ */
+ property = (axutil_property_t *) axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE);
+ if(property)
+ {
+ axis2_char_t *keep_alive_value = NULL;
+
+ keep_alive_value = axutil_property_get_value(property, env);
+ if(!axutil_strcmp(keep_alive_value, AXIS2_VALUE_FALSE))
+ {
+ sender->keep_alive = AXIS2_FALSE;
+ }
+ }
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ }
+
+ /* Because keep alive is not still supported at callback receiver we check
+ * for client side
+ */
+ if(sender->keep_alive && !axis2_msg_ctx_get_server_side(msg_ctx, env))
+ {
+ axutil_property_t *connection_map_property = NULL;
+
+ connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_HTTP_CONNECTION_MAP);
+ if(!connection_map_property)
+ {
+ connection_map = axis2_http_sender_connection_map_create(env, msg_ctx);
+ if(!connection_map)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ connection_map = axutil_property_get_value(connection_map_property, env);
+ if(connection_map)
+ {
+ sender->client = axis2_http_sender_connection_map_get(connection_map, env, msg_ctx);
+ }
+ }
+ if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_10))
+ {
+ add_keepalive_header = AXIS2_TRUE;
+ }
+ } /* End if sender->keep_alive */
+ if(!sender->client)
+ {
+ sender->client = axis2_http_client_create(env, url);
+ }
+ if(!sender->client)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "sender->client creation failed for url %s", url);
+ return AXIS2_FAILURE;
+ }
+ /* configure proxy settings if we have set so
+ */
+
+ axis2_http_sender_configure_proxy(sender, env, msg_ctx);
+
+ if(conf)
+ {
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+
+ if(trans_desc)
+ {
+ /* get xml declaration details from axis2.xml */
+ write_xml_declaration_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_XML_DECLARATION);
+ }
+
+ if(write_xml_declaration_param)
+ {
+ /* accessing attributes of the HTTP transport's , xml
+ * declaration element from axis2.xml*/
+
+ transport_attrs = axutil_param_get_attributes(write_xml_declaration_param, env);
+ if(transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *write_xml_declaration_attr = NULL;
+ axis2_char_t *write_xml_declaration_attr_value = NULL;
+
+ obj
+ = axutil_hash_get(transport_attrs, AXIS2_ADD_XML_DECLARATION, AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ write_xml_declaration_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj,
+ env);
+ }
+
+ if(write_xml_declaration_attr)
+ {
+ write_xml_declaration_attr_value = axiom_attribute_get_value(
+ write_xml_declaration_attr, env);
+ }
+
+ if(write_xml_declaration_attr_value && 0 == axutil_strcasecmp(
+ write_xml_declaration_attr_value, AXIS2_VALUE_TRUE))
+ {
+ write_xml_declaration = AXIS2_TRUE;
+ }
+ }
+ }
+
+ if(write_xml_declaration)
+ {
+ axiom_output_write_xml_version_encoding(sender->om_output, env);
+ }
+
+ if(!send_via_get && !send_via_head && !send_via_delete)
+ {
+ /* processing POST and PUT methods */
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "msg_ctx_id:%s", axis2_msg_ctx_get_msg_id(msg_ctx,
+ env));
+
+ doing_mtom = axis2_msg_ctx_get_doing_mtom(msg_ctx, env);
+
+ if(!sender->om_output)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_OM_OUTPUT, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", AXIS2_ERROR_GET_MESSAGE(env->error));
+ return AXIS2_FAILURE;
+ }
+
+ xml_writer = axiom_output_get_xml_writer(sender->om_output, env);
+
+ char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env);
+
+ if(!char_set_enc_str)
+ {
+ /* if there is no character encoding details available
+ * use default one.
+ * #define AXIS2_DEFAULT_CHAR_SET_ENCODING "UTF-8"
+ */
+ char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING;
+ }
+ else
+ {
+ char_set_enc = axutil_string_get_buffer(char_set_enc_str, env);
+ }
+
+ if(!send_via_put && is_soap)
+ {
+ /* HTTP POST case */
+ /* dump property use to dump message without sending */
+ dump_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_DUMP_INPUT_MSG_TRUE);
+ if(dump_property)
+ {
+ axis2_char_t *dump_true = axutil_property_get_value(dump_property, env);
+ if(0 == axutil_strcmp(dump_true, AXIS2_VALUE_TRUE))
+ {
+ axis2_http_client_set_dump_input_msg(sender->client, env, AXIS2_TRUE);
+ }
+ }
+
+ axiom_output_set_do_optimize(sender->om_output, env, doing_mtom);
+ axiom_soap_envelope_serialize(out, env, sender->om_output, AXIS2_FALSE);
+ }
+ else if(is_soap)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Attempt to send SOAP message using HTTP PUT failed");
+ return AXIS2_FAILURE;
+ }
+ else
+ {
+ if(!data_out)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "body node payload is NULL");
+ return AXIS2_FAILURE;
+ }
+ axiom_node_serialize(data_out, env, sender->om_output);
+ }
+
+ if(doing_mtom)
+ {
+ axutil_param_t *callback_name_param = NULL;
+ axis2_status_t mtom_status = AXIS2_FAILURE;
+ axutil_array_list_t *mime_parts = NULL;
+ axis2_char_t *mtom_sending_callback_name = NULL;
+
+ /* Getting the sender callback name paramter if it is
+ * specified in the configuration file */
+
+ callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env,
+ AXIS2_MTOM_SENDING_CALLBACK);
+ if(callback_name_param)
+ {
+ mtom_sending_callback_name = (axis2_char_t *)axutil_param_get_value(
+ callback_name_param, env);
+ if(mtom_sending_callback_name)
+ {
+ axis2_http_client_set_mtom_sending_callback_name(sender->client, env,
+ mtom_sending_callback_name);
+ }
+ }
+
+ /* Here we put all the attachment related stuff in a array_list
+ After this method we have the message in parts */
+
+ mtom_status = axiom_output_flush(sender->om_output, env);
+ if(mtom_status == AXIS2_FAILURE)
+ {
+ return mtom_status;
+ }
+ /* HTTP client should distinguish an MTOM invocation because the way
+ of sending the message in MTOM case is different */
+ axis2_http_client_set_doing_mtom(sender->client, env, doing_mtom);
+
+ /* HTTP client will keep this mime_parts, which it will send in chunks at
+ th end */
+ mime_parts = axiom_output_get_mime_parts(sender->om_output, env);
+ if(mime_parts)
+ {
+ axis2_http_client_set_mime_parts(sender->client, env, mime_parts);
+ }
+ }
+ else
+ {
+ buffer = axiom_xml_writer_get_xml(xml_writer, env);
+ }
+
+ if(!(buffer || doing_mtom))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "NULL xml returned from xml writer");
+ return AXIS2_FAILURE;
+ }
+
+ if(!send_via_put)
+ {
+ /* HTTP POST */
+ axis2_char_t *path_with_query = NULL;
+
+ path_with_query = axutil_strcat(env, axutil_url_get_path(url, env),
+ axutil_url_get_query(url, env), NULL);
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_POST, path_with_query,
+ sender->http_version);
+ AXIS2_FREE(env->allocator, path_with_query);
+ }
+ else
+ {
+ /* HTTP PUT */
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_PUT, axutil_url_get_path(
+ url, env), sender->http_version);
+ }
+ }
+ else
+ {
+ /* Processing HTTP GET, HEAD and DELETE */
+
+ axis2_char_t *request_params = NULL;
+ axis2_char_t *path = NULL;
+
+ request_params = axis2_http_sender_get_param_string(sender, env, msg_ctx);
+
+ if(request_params)
+ {
+ /* substituting AXIS2_Q_MARK for "?" */
+ path = axutil_strcat(env, axutil_url_get_path(url, env), AXIS2_Q_MARK_STR,
+ request_params, NULL);
+ AXIS2_FREE(env->allocator, request_params);
+ request_params = NULL;
+ }
+ else
+ {
+ path = axutil_strdup(env, axutil_url_get_path(url, env));
+ }
+
+ if(send_via_get)
+ {
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_GET, path,
+ sender->http_version);
+ }
+ else if(send_via_head)
+ {
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD, path,
+ sender->http_version);
+ }
+ else if(send_via_delete)
+ {
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_DELETE, path,
+ sender->http_version);
+ }
+
+ if(path)
+ {
+ AXIS2_FREE(env->allocator, path);
+ path = NULL;
+ }
+ }
+
+ request = axis2_http_simple_request_create(env, request_line, NULL, 0, NULL);
+ if(add_keepalive_header)
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONNECTION,
+ AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE);
+ }
+ /**
+ * If there is a session related stuff handle it
+ */
+ /*header_value = axis2_http_transport_utils_get_session(env, msg_ctx);
+ if(header_value)
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SET_COOKIE, header_value);
+ }*/
+
+ /**
+ * In the client side sender if a cookie is sent by server add it to the http header
+ */
+ cookie_str = axis2_http_transport_utils_read_from_cookie_store(env, msg_ctx);
+ if(cookie_str)
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_COOKIE, cookie_str);
+ }
+
+ /* User-Agent:Axis2/C header */
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_USER_AGENT, AXIS2_USER_AGENT);
+
+ http_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_HEADER_PROPERTY);
+ if(http_property)
+ {
+ array_list = (axutil_array_list_t *)axutil_property_get_value(http_property, env);
+ axis2_http_sender_add_header_list(request, env, array_list);
+ }
+
+ if(!send_via_get && !send_via_head && !send_via_put && !send_via_delete && AXIS2_TRUE
+ == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ if(AXIS2_ESC_DOUBLE_QUOTE != *soap_action)
+ {
+ axis2_char_t *tmp_soap_action = NULL;
+ tmp_soap_action = AXIS2_MALLOC(env->allocator, (axutil_strlen(soap_action) + 5)
+ * sizeof(axis2_char_t));
+ sprintf(tmp_soap_action, "\"%s\"", soap_action);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SOAP_ACTION,
+ tmp_soap_action);
+ AXIS2_FREE(env->allocator, tmp_soap_action);
+ }
+ else
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SOAP_ACTION,
+ (const axis2_char_t *)soap_action);
+ }
+ }
+ else if(AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding of SOAP Action Failed for REST request");
+
+ return AXIS2_FAILURE;
+ }
+
+ if(!send_via_get && !send_via_head && !send_via_delete)
+ {
+ /* processing PUT and POST */
+ buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env);
+
+ if(AXIS2_FALSE == sender->chunked)
+ {
+ axis2_char_t tmp_buf[10];
+ if(!buffer)
+ {
+ buffer_size = output_stream_size;
+ }
+
+ if(buffer_size)
+ {
+ sprintf(tmp_buf, "%d", buffer_size);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONTENT_LENGTH,
+ tmp_buf);
+ }
+ }
+ else
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_TRANSFER_ENCODING,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED);
+ }
+
+ if(!send_via_put && is_soap)
+ {
+ /* HTTP POST */
+ if(doing_mtom)
+ {
+ content_type = (axis2_char_t *)axiom_output_get_content_type(sender-> om_output,
+ env);
+ if(AXIS2_TRUE != axis2_msg_ctx_get_is_soap_11(msg_ctx, env) && axutil_strcmp(
+ soap_action, ""))
+ {
+ /* handle SOAP action for SOAP 1.2 case */
+ axis2_char_t *temp_content_type = NULL;
+ temp_content_type
+ = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_ACTION);
+ content_type = temp_content_type;
+ temp_content_type = axutil_stracat(env, content_type, soap_action);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ temp_content_type = axutil_stracat(env, content_type,
+ AXIS2_ESC_DOUBLE_QUOTE_STR);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ }
+ else
+ {
+ content_type_deepl_copy = AXIS2_FALSE;
+ }
+ }
+ else if(AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ /* SOAP 1.1 without MTOM */
+ axis2_char_t *temp_content_type = NULL;
+ content_type = (axis2_char_t *)AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
+ content_type = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_CHARSET);
+ temp_content_type = axutil_stracat(env, content_type, char_set_enc);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ }
+ else
+ {
+ /* SOAP 1.2 without MTOM */
+ axis2_char_t *temp_content_type = NULL;
+ content_type = (axis2_char_t *)AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP;
+ content_type = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_CHARSET);
+ temp_content_type = axutil_stracat(env, content_type, char_set_enc);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ if(axutil_strcmp(soap_action, ""))
+ {
+ temp_content_type
+ = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_ACTION);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ temp_content_type = axutil_stracat(env, content_type, soap_action);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ temp_content_type = axutil_stracat(env, content_type,
+ AXIS2_ESC_DOUBLE_QUOTE_STR);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ }
+ }
+ }
+ else if(is_soap)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Attempt to send SOAP message using HTTP PUT failed");
+ return AXIS2_FAILURE;
+ }
+ else
+ {
+ content_type_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_USER_DEFINED_HTTP_HEADER_CONTENT_TYPE);
+
+ if(content_type_property)
+ {
+ content_type_hash = (axutil_hash_t *)axutil_property_get_value(
+ content_type_property, env);
+ if(content_type_hash)
+ {
+ content_type_value = (char *)axutil_hash_get(content_type_hash,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE, AXIS2_HASH_KEY_STRING);
+ }
+ }
+
+ if(content_type_value)
+ {
+ content_type = content_type_value;
+ }
+ else
+ {
+ content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
+ }
+
+ content_type_deepl_copy = AXIS2_FALSE;
+ }
+
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ content_type);
+
+ if(content_type_deepl_copy && content_type)
+ {
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = NULL;
+ }
+ /* Finished Processing PUT and POST */
+ }
+
+ if(0 == axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_11))
+ {
+ /* HTTP 1.1 */
+ axis2_char_t *header = NULL;
+ int host_len = 0;
+ host_len = axutil_strlen(axutil_url_get_host(url, env));
+ header = AXIS2_MALLOC(env->allocator, host_len + 10 * sizeof(axis2_char_t));
+ sprintf(header, "%s:%d", axutil_url_get_host(url, env), axutil_url_get_port(url, env));
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_HOST, header);
+ AXIS2_FREE(env->allocator, header);
+ header = NULL;
+ }
+
+ /* If this is a normal invocation the buffer has the full SOAP message
+ which needs to be send. In the MTOM case instead of this buffer
+ it has the mime_parts array_list */
+
+ if(!doing_mtom)
+ {
+ axis2_http_simple_request_set_body_string(request, env, buffer, buffer_size);
+ }
+
+ /* HTTPS request processing */
+ axis2_http_sender_configure_server_cert(sender, env, msg_ctx);
+
+ axis2_http_sender_configure_key_file(sender, env, msg_ctx);
+
+ axis2_http_sender_get_timeout_values(sender, env, msg_ctx);
+ axis2_http_client_set_timeout(sender->client, env, sender->so_timeout);
+
+ ssl_pp_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_PASSPHRASE);
+
+ if(ssl_pp_property)
+ {
+ ssl_pp = (axis2_char_t *)axutil_property_get_value(ssl_pp_property, env);
+ }
+ else
+ {
+ ssl_pp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_PASSPHRASE);
+
+ if(ssl_pp_param)
+ {
+ ssl_pp = axutil_param_get_value(ssl_pp_param, env);
+ }
+ }
+
+ test_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_TEST_PROXY_AUTH);
+ if(test_auth_property)
+ {
+ test_auth_property_value = (axis2_char_t *)axutil_property_get_value(test_auth_property,
+ env);
+ }
+
+ if(test_auth_property_value && 0 == axutil_strcmp(test_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ test_proxy_auth = AXIS2_TRUE;
+ }
+
+ test_auth_property = NULL;
+ test_auth_property_value = NULL;
+
+ test_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_TEST_HTTP_AUTH);
+ if(test_auth_property)
+ {
+ test_auth_property_value = (axis2_char_t *)axutil_property_get_value(test_auth_property,
+ env);
+ }
+
+ if(test_auth_property_value && 0 == axutil_strcmp(test_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ test_http_auth = AXIS2_TRUE;
+ }
+
+ if(!test_proxy_auth)
+ {
+ proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_FORCE_PROXY_AUTH);
+ }
+ if(proxy_auth_property)
+ {
+ proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property,
+ env);
+ }
+
+ if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ force_proxy_auth = AXIS2_TRUE;
+ }
+
+ proxy_auth_property = NULL;
+ proxy_auth_property_value = NULL;
+
+ if(force_proxy_auth)
+ {
+ proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_PROXY_AUTH_TYPE);
+ }
+
+ if(proxy_auth_property)
+ {
+ proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property,
+ env);
+ }
+
+ if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value,
+ AXIS2_PROXY_AUTH_TYPE_DIGEST))
+ {
+ force_proxy_auth = AXIS2_FALSE;
+ force_proxy_auth_with_head = AXIS2_TRUE;
+ }
+
+ if(!test_http_auth)
+ {
+ http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_FORCE_HTTP_AUTH);
+ }
+
+ if(http_auth_property)
+ {
+ http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property,
+ env);
+ }
+
+ if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ force_http_auth = AXIS2_TRUE;
+ }
+
+ http_auth_property = NULL;
+ http_auth_property_value = NULL;
+
+ if(force_http_auth)
+ {
+ http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_HTTP_AUTH_TYPE);
+ }
+
+ if(http_auth_property)
+ {
+ http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property,
+ env);
+ }
+
+ if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value,
+ AXIS2_HTTP_AUTH_TYPE_DIGEST))
+ {
+ force_http_auth = AXIS2_FALSE;
+ force_http_auth_with_head = AXIS2_TRUE;
+ }
+
+ axis2_msg_ctx_set_auth_type(msg_ctx, env, NULL);
+
+ if(force_proxy_auth || force_proxy_auth_with_head)
+ {
+ status_code = AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL;
+ }
+ else
+ {
+ /* NOT forcing proxy authentication */
+ if(force_http_auth)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP Authentication header");
+ }
+ http_auth_header_added = AXIS2_TRUE;
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+
+ else if(force_http_auth_with_head)
+ {
+ axis2_http_request_line_t *head_request_line = NULL;
+ axis2_http_request_line_t *temp = NULL;
+
+ temp = axis2_http_simple_request_get_request_line(request, env);
+ head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD,
+ axis2_http_request_line_get_uri(temp, env),
+ axis2_http_request_line_get_http_version(temp, env));
+ axis2_http_simple_request_set_request_line(request, env, head_request_line);
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ axis2_http_simple_request_set_request_line(request, env, temp);
+ axis2_http_request_line_free(head_request_line, env);
+
+ if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP Authentication\
+ header");
+ }
+ http_auth_header_added = AXIS2_TRUE;
+ }
+
+ if(status_code != AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL)
+ {
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+
+ if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+ http_auth_header_added = AXIS2_FALSE;
+ force_http_auth_with_head = AXIS2_FALSE;
+ }
+ }
+ }
+ else
+ {
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+ }
+
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code
+ && !test_proxy_auth)
+ {
+ if(force_proxy_auth_with_head)
+ {
+ axis2_http_request_line_t *head_request_line = NULL;
+ axis2_http_request_line_t *temp = NULL;
+
+ temp = axis2_http_simple_request_get_request_line(request, env);
+ head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD,
+ axis2_http_request_line_get_uri(temp, env),
+ axis2_http_request_line_get_http_version(temp, env));
+ axis2_http_simple_request_set_request_line(request, env, head_request_line);
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ axis2_http_simple_request_set_request_line(request, env, temp);
+ axis2_http_request_line_free(head_request_line, env);
+
+ if(status_code == AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_proxy_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting Proxy Authentication\
+ header");
+ }
+
+ if((force_http_auth_with_head || force_http_auth) && !http_auth_header_added)
+ {
+ status_code = AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL;
+ }
+ else
+ {
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+ }
+ else if(status_code != AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+
+ /* Proxies have no idea about HTTP Methods therefore, if
+ * it fails no need to re-check */
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE);
+ }
+ }
+ else
+ {
+
+ /* not forcing proxy auth with head */
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_proxy_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting Proxy Authentication \
+header");
+ }
+
+ if((force_http_auth_with_head || force_http_auth) && !http_auth_header_added)
+ {
+ status_code = AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL;
+ }
+ else
+ {
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE);
+ }
+ }
+ }
+ }
+ else if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE);
+ axis2_http_sender_set_proxy_auth_type(sender, env, msg_ctx, request);
+ }
+
+ if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code && !test_http_auth)
+ {
+ if(!http_auth_header_added)
+ {
+ if(force_proxy_auth_with_head)
+ {
+ axis2_http_request_line_t *head_request_line = NULL;
+ axis2_http_request_line_t *temp = NULL;
+
+ temp = axis2_http_simple_request_get_request_line(request, env);
+ head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD,
+ axis2_http_request_line_get_uri(temp, env),
+ axis2_http_request_line_get_http_version(temp, env));
+ axis2_http_simple_request_set_request_line(request, env, head_request_line);
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ axis2_http_simple_request_set_request_line(request, env, temp);
+ axis2_http_request_line_free(head_request_line, env);
+
+ if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx,
+ request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP Authentication \
+header");
+ }
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx,
+ request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP \
+Authentication header");
+ }
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+
+ }
+ }
+ else
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP Authentication \
+header");
+ }
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+
+ if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE);
+ }
+
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE);
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE);
+ }
+ }
+ else if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code)
+ {
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE);
+ axis2_http_sender_set_http_auth_type(sender, env, msg_ctx, request);
+ }
+
+ axis2_http_simple_request_free(request, env);
+ request = NULL;
+
+ if(output_stream)
+ {
+ AXIS2_FREE(env->allocator, output_stream);
+ output_stream = NULL;
+ }
+
+ if(status_code < 0)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "status_code < 0");
+ return AXIS2_FAILURE;
+ }
+
+ axis2_msg_ctx_set_status_code(msg_ctx, env, status_code);
+
+ /* Start processing response */
+ response = axis2_http_client_get_response(sender->client, env);
+ if(!is_soap)
+ {
+ return axis2_http_sender_process_response(sender, env, msg_ctx, response);
+ }
+ else if(AXIS2_HTTP_RESPONSE_OK_CODE_VAL == status_code || AXIS2_HTTP_RESPONSE_ACK_CODE_VAL
+ == status_code)
+ {
+ return axis2_http_sender_process_response(sender, env, msg_ctx, response);
+ }
+ else if(AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL == status_code)
+ {
+ axis2_http_header_t *tmp_header = NULL;
+ axis2_char_t *tmp_header_val = NULL;
+ axis2_op_t *op = NULL;
+
+ op = axis2_msg_ctx_get_op(msg_ctx, env);
+ if(op)
+ {
+ const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ /* handle one way case */
+
+ if(!axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "mep is AXIS2_MEP_URI_OUT_ONLY");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ /* set an error to indicate error code status */
+ tmp_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if(tmp_header)
+ {
+ tmp_header_val = axis2_http_header_get_value(tmp_header, env);
+ }
+
+ if(tmp_header_val && (axutil_strstr(tmp_header_val, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP)
+ || axutil_strstr(tmp_header_val, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML)))
+ {
+ return axis2_http_sender_process_response(sender, env, msg_ctx, response);
+ }
+ }
+
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_sender_send");
+ return AXIS2_FAILURE;
+}
+#endif
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_set_chunked(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_bool_t chunked)
+{
+ sender->chunked = chunked;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_set_om_output(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axiom_output_t * om_output)
+{
+ sender->om_output = om_output;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_get_header_info(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_response_t * response)
+{
+ axutil_array_list_t *headers = NULL;
+ axis2_char_t *charset = NULL;
+ int i = 0;
+ axis2_bool_t response_chunked = AXIS2_FALSE;
+ int *content_length = NULL;
+ axutil_property_t *property = NULL;
+ axis2_char_t *content_type = NULL;
+ int status_code = 0;
+ axis2_bool_t set_cookie_header_present = AXIS2_FALSE;
+ axis2_bool_t connection_header_present = AXIS2_FALSE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, sender, AXIS2_FAILURE);
+
+ headers = axis2_http_simple_response_get_headers(response, env);
+ if(headers == NULL)
+ {
+ return AXIS2_SUCCESS;
+ }
+
+ for(i = 0; i < axutil_array_list_size(headers, env); i++)
+ {
+ axis2_http_header_t *header = axutil_array_list_get(headers, env, i);
+ axis2_char_t *name = axis2_http_header_get_name((axis2_http_header_t *)header, env);
+ if(name)
+ {
+ if(0 == axutil_strcasecmp(name, AXIS2_HTTP_HEADER_TRANSFER_ENCODING) && 0
+ == axutil_strcasecmp(axis2_http_header_get_value(header, env),
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ axis2_char_t *transfer_encoding = NULL;
+ transfer_encoding = axutil_strdup(env, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED);
+ response_chunked = AXIS2_TRUE;
+ axis2_msg_ctx_set_transfer_encoding(msg_ctx, env, transfer_encoding);
+
+ }
+ if(0 != axutil_strcasecmp(name, AXIS2_HTTP_HEADER_CONTENT_TYPE))
+ {
+ axis2_char_t *tmp_charset = NULL;
+ axis2_char_t *content_type = axis2_http_header_get_value(header, env);
+ tmp_charset = strstr(content_type, AXIS2_HTTP_CHAR_SET_ENCODING);
+ if(charset)
+ {
+ charset = axutil_strdup(env, tmp_charset);
+ break;
+ }
+ }
+ if(!axutil_strcasecmp(name, AXIS2_HTTP_HEADER_SET_COOKIE))
+ {
+ axis2_char_t *cookie_str = axis2_http_header_get_value(header, env);
+ if(cookie_str)
+ {
+ axis2_http_transport_utils_store_cookie(env, msg_ctx, cookie_str);
+ }
+ set_cookie_header_present = AXIS2_TRUE;
+ }
+
+ if(!axutil_strcasecmp(name, AXIS2_HTTP_HEADER_CONNECTION))
+ {
+ axis2_char_t *connection_header_value = NULL;
+ axutil_property_t *connection_map_property = NULL;
+ axutil_hash_t *connection_map = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ connection_header_present = AXIS2_TRUE;
+ connection_header_value = axis2_http_header_get_value(header, env);
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_HTTP_CONNECTION_MAP);
+
+ if(connection_map_property)
+ {
+ connection_map = axutil_property_get_value(connection_map_property, env);
+ }
+ /**
+ * In HTTP1.1 if connection header has value close then drop the connection
+ */
+ if(connection_header_value && !axutil_strcasecmp(connection_header_value, "close"))
+ {
+ if(connection_map)
+ {
+ axis2_http_sender_connection_map_remove(connection_map, env,
+ msg_ctx, sender->client);
+ }
+ }
+ else if(connection_header_value && !axutil_strcasecmp(connection_header_value,
+ "Keep-Alive"))
+ {
+ if(connection_map)
+ {
+ axis2_http_sender_connection_map_add(connection_map, env,
+ msg_ctx, sender->client);
+ }
+ }
+ } /* End if name is connection */
+ } /* End if name of the header present */
+ }
+ if(!set_cookie_header_present) /* We need to remove any cookie set previously for this endpoint */
+ {
+ axis2_http_transport_utils_store_cookie(env, msg_ctx, NULL);
+ }
+ if(!connection_header_present) /* No connection header present */
+ {
+ /** In HTTP1.0 if there is no keep alive header sent back from server we drop the
+ * connection
+ */
+ axutil_property_t *connection_map_property = NULL;
+ axutil_hash_t *connection_map = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+
+ connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_HTTP_CONNECTION_MAP);
+ if(connection_map_property)
+ {
+ connection_map = axutil_property_get_value(connection_map_property, env);
+ } /* End if connectin_map_property */
+ if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_10))
+ {
+ if(connection_map)
+ {
+ axis2_http_sender_connection_map_remove(connection_map, env, msg_ctx,
+ sender->client);
+ }
+ } /* End if http version 1.0 */
+ else if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_11))
+ {
+ /**
+ * If keep alive enabled we store the http client for reuse.
+ */
+ if(connection_map)
+ {
+ axis2_http_sender_connection_map_add(connection_map, env, msg_ctx,
+ sender->client);
+ }
+ } /* End if http version 1.1 */
+ } /* End if !connection_header_present */
+
+ content_type = (axis2_char_t *)axis2_http_simple_response_get_content_type(response, env);
+ if(content_type)
+ {
+ if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED) && strstr(content_type,
+ AXIS2_HTTP_HEADER_ACCEPT_XOP_XML))
+ {
+ axis2_ctx_t *axis_ctx = axis2_op_ctx_get_base(axis2_msg_ctx_get_op_ctx(msg_ctx, env),
+ env);
+ property = axutil_property_create(env);
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value(property, env, axutil_strdup(env, content_type));
+ axis2_ctx_set_property(axis_ctx, env, MTOM_RECIVED_CONTENT_TYPE, property);
+ }
+ }
+
+ if(charset)
+ {
+ axis2_ctx_t *axis_ctx = axis2_op_ctx_get_base(axis2_msg_ctx_get_op_ctx(msg_ctx, env), env);
+ if(axis_ctx)
+ {
+ property = axutil_property_create(env);
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value(property, env, charset);
+ axis2_ctx_set_property(axis_ctx, env, AXIS2_CHARACTER_SET_ENCODING, property);
+ }
+ }
+
+ if(AXIS2_FALSE == response_chunked)
+ {
+ int tmp_len = 0;
+ content_length = AXIS2_MALLOC(env->allocator, sizeof(int));
+ if(!content_length)
+ {
+ return AXIS2_FAILURE;
+ }
+ tmp_len = axis2_http_simple_response_get_content_length(response, env);
+ memcpy(content_length, &tmp_len, sizeof(int));
+ property = axutil_property_create(env);
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value(property, env, content_length);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, property);
+ }
+
+ status_code = axis2_http_simple_response_get_status_code(response, env);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_process_response(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_response_t * response)
+{
+ axutil_stream_t *in_stream = NULL;
+ axutil_property_t *property = NULL;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_sender_process_response");
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE);
+
+ in_stream = axis2_http_simple_response_get_body(response, env);
+ if(!in_stream)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_STREAM_IN_RESPONSE_BODY, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+
+ axis2_http_sender_get_header_info(sender, env, msg_ctx, response);
+ axis2_msg_ctx_set_http_output_headers(msg_ctx, env, axis2_http_simple_response_extract_headers(
+ response, env));
+ property = axutil_property_create(env);
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_free_func(property, env, axutil_stream_free_void_arg);
+ axutil_property_set_value(property, env, in_stream);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property);
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_sender_process_response");
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_get_timeout_values(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_char_t *so_str = NULL;
+ axis2_char_t *connection_str = NULL;
+ axutil_param_t *tmp_param = NULL;
+ axutil_property_t *property = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, sender, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ /* check if timeout has been set by user using options
+ * with axis2_options_set_timeout_in_milli_seconds
+ */
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_CONNECTION_TIMEOUT);
+ if(property)
+ {
+ axis2_char_t *value = axutil_property_get_value(property, env);
+ if(value)
+ {
+ sender->so_timeout = AXIS2_ATOI(value);
+ return AXIS2_SUCCESS;
+ }
+ }
+
+ tmp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_HTTP_SO_TIMEOUT);
+
+ if(tmp_param)
+ {
+ so_str = (axis2_char_t *)axutil_param_get_value(tmp_param, env);
+ if(so_str)
+ {
+ sender->so_timeout = AXIS2_ATOI(so_str);
+ return AXIS2_SUCCESS;
+ }
+ }
+
+ tmp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_HTTP_CONNECTION_TIMEOUT);
+ if(tmp_param)
+ {
+ connection_str = (axis2_char_t *)axutil_param_get_value(tmp_param, env);
+ if(connection_str)
+ {
+ sender->so_timeout = AXIS2_ATOI(connection_str);
+ return AXIS2_SUCCESS;
+ }
+ }
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_set_http_version(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_char_t * version)
+{
+ sender->http_version = axutil_strdup(env, version);
+ if(!sender->http_version)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static void
+axis2_http_sender_add_header_list(
+ axis2_http_simple_request_t * request,
+ const axutil_env_t * env,
+ axutil_array_list_t * array_list)
+{
+ int ii = 0;
+ int kk = 0;
+ axis2_http_header_t *http_header = NULL;
+ ii = axutil_array_list_size(array_list, env);
+ for(; kk < ii; kk++)
+ {
+ http_header = (axis2_http_header_t *)axutil_array_list_get(array_list, env, kk);
+ axis2_http_simple_request_add_header(request, env, http_header);
+ }
+}
+
+static axis2_status_t
+axis2_http_sender_configure_proxy(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *proxy_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+ axis2_char_t *proxy_host = NULL;
+ axis2_char_t *proxy_port = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(!conf_ctx)
+ {
+ return AXIS2_FAILURE;
+ }
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(!conf)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ if(!trans_desc)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ proxy_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container(
+ trans_desc, env), env, AXIS2_HTTP_PROXY_API);
+ if(!proxy_param)
+ {
+ proxy_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container(
+ trans_desc, env), env, AXIS2_HTTP_PROXY);
+ }
+ if(proxy_param)
+ {
+ transport_attrs = axutil_param_get_attributes(proxy_param, env);
+ if(transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *host_attr = NULL;
+ axiom_attribute_t *port_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING);
+ if(!obj)
+ {
+ return AXIS2_FAILURE;
+ }
+ host_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ if(!host_attr)
+ {
+ return AXIS2_FAILURE;
+ }
+ proxy_host = axiom_attribute_get_value(host_attr, env);
+ if(!proxy_host)
+ {
+ return AXIS2_FAILURE;
+ }
+ /* Now we get the port */
+ obj = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING);
+ port_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ if(!port_attr)
+ {
+ return AXIS2_FAILURE;
+ }
+ proxy_port = axiom_attribute_get_value(port_attr, env);
+ if(!proxy_port)
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ }
+ if(proxy_port && proxy_host)
+ {
+ axis2_http_client_set_proxy(sender->client, env, proxy_host, AXIS2_ATOI(proxy_port));
+ }
+ return AXIS2_SUCCESS;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_server_cert(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axutil_property_t *server_cert_property = NULL;
+ axutil_param_t *server_cert_param = NULL;
+ axis2_char_t *server_cert = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ server_cert_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_SERVER_CERT);
+ if(server_cert_property)
+ {
+ server_cert = (axis2_char_t *)axutil_property_get_value(server_cert_property, env);
+ }
+ else
+ {
+ server_cert_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_SERVER_CERT);
+ if(server_cert_param)
+ {
+ server_cert = (axis2_char_t *)axutil_param_get_value(server_cert_param, env);
+ }
+ }
+
+ if(server_cert)
+ {
+ status = axis2_http_client_set_server_cert(sender->client, env, server_cert);
+ }
+
+ return status;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_key_file(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axutil_property_t *key_file_property = NULL;
+ axutil_param_t *key_file_param = NULL;
+ axis2_char_t *key_file = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ key_file_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_KEY_FILE);
+ if(key_file_property)
+ {
+ key_file = (axis2_char_t *)axutil_property_get_value(key_file_property, env);
+ }
+ else
+ {
+ key_file_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_KEY_FILE);
+ if(key_file_param)
+ {
+ key_file = (axis2_char_t *)axutil_param_get_value(key_file_param, env);
+ }
+ }
+
+ if(key_file)
+ {
+ status = axis2_http_client_set_key_file(sender->client, env, key_file);
+ }
+
+ return status;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_http_basic_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axutil_property_t *http_auth_un = NULL;
+ axutil_property_t *http_auth_pw = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+
+ http_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME);
+ http_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD);
+ if(http_auth_un && http_auth_pw)
+ {
+ uname = (axis2_char_t *)axutil_property_get_value(http_auth_un, env);
+ passwd = (axis2_char_t *)axutil_property_get_value(http_auth_pw, env);
+ }
+ if(!uname || !passwd)
+ {
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *http_auth_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(conf)
+ {
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+ }
+ if(trans_desc)
+ {
+ http_auth_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_HTTP_AUTHENTICATION);
+ if(http_auth_param)
+ {
+ transport_attrs = axutil_param_get_attributes(http_auth_param, env);
+ if(transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_USERNAME,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(username_attr)
+ {
+ uname = axiom_attribute_get_value(username_attr, env);
+ }
+ obj = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_PASSWORD,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(password_attr)
+ {
+ passwd = axiom_attribute_get_value(password_attr, env);
+ }
+ }
+ }
+ }
+ }
+ if(uname && passwd)
+ {
+ int elen;
+ int plen = axutil_strlen(uname) + axutil_strlen(passwd) + 1;
+ axis2_char_t *to_encode = (axis2_char_t *)(AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * plen + 1));
+ axis2_char_t *encoded = NULL;
+ axis2_char_t *auth_str = NULL;
+ sprintf(to_encode, "%s:%s", uname, passwd);
+ elen = axutil_base64_encode_len(plen);
+ encoded = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * elen));
+ auth_str
+ = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 6)));
+ axutil_base64_encode(encoded, to_encode, plen);
+ sprintf(auth_str, "%s %s", AXIS2_HTTP_AUTH_TYPE_BASIC, encoded);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_AUTHORIZATION, auth_str);
+
+ AXIS2_FREE(env->allocator, to_encode);
+ to_encode = NULL;
+ AXIS2_FREE(env->allocator, encoded);
+ encoded = NULL;
+ AXIS2_FREE(env->allocator, auth_str);
+ auth_str = NULL;
+
+ return AXIS2_SUCCESS;
+ }
+
+ return AXIS2_FAILURE;
+
+}
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_basic_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axutil_property_t *proxy_auth_un = NULL;
+ axutil_property_t *proxy_auth_pw = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+
+ proxy_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME);
+ proxy_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD);
+
+ if(proxy_auth_un && proxy_auth_pw)
+ {
+ uname = (axis2_char_t *)axutil_property_get_value(proxy_auth_un, env);
+ passwd = (axis2_char_t *)axutil_property_get_value(proxy_auth_pw, env);
+ }
+ if(!uname || !passwd)
+ {
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *proxy_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(conf)
+ {
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+ }
+ if(trans_desc)
+ {
+ proxy_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_HTTP_PROXY_API);
+ if(!proxy_param)
+ {
+ proxy_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_HTTP_PROXY);
+ }
+ if(proxy_param)
+ {
+ transport_attrs = axutil_param_get_attributes(proxy_param, env);
+ if(transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(username_attr)
+ {
+ uname = axiom_attribute_get_value(username_attr, env);
+ }
+ obj = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(password_attr)
+ {
+ passwd = axiom_attribute_get_value(password_attr, env);
+ }
+ }
+ }
+ }
+ }
+ if(uname && passwd)
+ {
+ int elen;
+ int plen = axutil_strlen(uname) + axutil_strlen(passwd) + 1;
+ axis2_char_t *to_encode = (axis2_char_t *)(AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * plen + 1));
+ axis2_char_t *encoded = NULL;
+ axis2_char_t *auth_str = NULL;
+ sprintf(to_encode, "%s:%s", uname, passwd);
+ elen = axutil_base64_encode_len(plen);
+ encoded = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * elen));
+ auth_str
+ = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 6)));
+ axutil_base64_encode(encoded, to_encode, plen);
+ sprintf(auth_str, "%s %s", AXIS2_PROXY_AUTH_TYPE_BASIC, encoded);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_PROXY_AUTHORIZATION,
+ auth_str);
+
+ AXIS2_FREE(env->allocator, to_encode);
+ to_encode = NULL;
+ AXIS2_FREE(env->allocator, encoded);
+ encoded = NULL;
+ AXIS2_FREE(env->allocator, auth_str);
+ auth_str = NULL;
+
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_http_digest_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_data)
+{
+ axutil_property_t *http_auth_un = NULL;
+ axutil_property_t *http_auth_pw = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+
+ if(!header_data || !*header_data)
+ return AXIS2_FAILURE;
+
+ http_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME);
+ http_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD);
+ if(http_auth_un && http_auth_pw)
+ {
+ uname = (axis2_char_t *)axutil_property_get_value(http_auth_un, env);
+ passwd = (axis2_char_t *)axutil_property_get_value(http_auth_pw, env);
+ }
+ if(!uname || !passwd)
+ {
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *http_auth_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(conf)
+ {
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+ }
+ if(trans_desc)
+ {
+ http_auth_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_HTTP_AUTHENTICATION);
+ if(http_auth_param)
+ {
+ transport_attrs = axutil_param_get_attributes(http_auth_param, env);
+ if(transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_USERNAME,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(username_attr)
+ {
+ uname = axiom_attribute_get_value(username_attr, env);
+ }
+ obj = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_PASSWORD,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(password_attr)
+ {
+ passwd = axiom_attribute_get_value(password_attr, env);
+ }
+ }
+ }
+ }
+ }
+ if(uname && passwd)
+ {
+ int elen = 0; /* length of header content */
+ int print_const = 5; /* constant accounts for printing the
+ quoatation marks, comma, and space */
+ int response_length = 32;
+ axis2_char_t *temp = NULL;
+ axis2_char_t *alloc_temp = NULL;
+ axis2_char_t *algo = AXIS2_HTTP_AUTHORIZATION_REQUEST_ALGORITHM_MD5;
+ axis2_char_t *realm = NULL;
+ axis2_char_t *qop = NULL;
+ axis2_char_t *nonce = NULL;
+ axis2_char_t *opaque = NULL;
+ axis2_char_t *cnonce = NULL;
+ axis2_char_t *nc = NULL;
+ axutil_digest_hash_hex_t h_a1;
+ axutil_digest_hash_hex_t h_a2;
+ axutil_digest_hash_hex_t response;
+ axis2_char_t *auth_str = NULL;
+ axutil_property_t *method = NULL;
+ axis2_char_t *method_value = NULL;
+ axis2_char_t *url = NULL;
+
+ url = axis2_http_request_line_get_uri(axis2_http_simple_request_get_request_line(request,
+ env), env);
+
+ if(!url)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI)
+ + axutil_strlen(url);
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME)
+ + axutil_strlen(uname);
+
+ method = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_METHOD);
+ if(method)
+ {
+ method_value = (axis2_char_t *)axutil_property_get_value(method, env);
+ }
+ else
+ {
+ method_value = AXIS2_HTTP_POST;
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM);
+ if(temp)
+ {
+ realm = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(realm)
+ {
+ realm++;
+ temp = axutil_strchr(realm, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - realm + 1)));
+ strncpy(alloc_temp, realm, (temp - realm));
+ if(alloc_temp)
+ alloc_temp[temp - realm] = AXIS2_ESC_NULL;
+ realm = alloc_temp;
+ alloc_temp = NULL;
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM)
+ + axutil_strlen(realm);
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP);
+ if(temp)
+ {
+ qop = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(qop)
+ {
+ qop++;
+ temp = axutil_strchr(qop, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - qop + 1)));
+ strncpy(alloc_temp, qop, (temp - qop));
+ if(alloc_temp)
+ alloc_temp[temp - qop] = AXIS2_ESC_NULL;
+ qop = alloc_temp;
+ alloc_temp = NULL;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE);
+ if(temp)
+ {
+ nonce = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(nonce)
+ {
+ nonce++;
+ temp = axutil_strchr(nonce, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - nonce + 1)));
+ strncpy(alloc_temp, nonce, (temp - nonce));
+ if(alloc_temp)
+ alloc_temp[temp - nonce] = AXIS2_ESC_NULL;
+ nonce = alloc_temp;
+ alloc_temp = NULL;
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE)
+ + axutil_strlen(nonce);
+ }
+ else
+ {
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE);
+ if(temp)
+ {
+ opaque = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(opaque)
+ {
+ opaque++;
+ temp = axutil_strchr(opaque, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - opaque + 1)));
+ strncpy(alloc_temp, opaque, (temp - opaque));
+ if(alloc_temp)
+ alloc_temp[temp - opaque] = AXIS2_ESC_NULL;
+ opaque = alloc_temp;
+ alloc_temp = NULL;
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE)
+ + axutil_strlen(opaque);
+ }
+ else
+ {
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ if(nonce)
+ AXIS2_FREE(env->allocator, nonce);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ if(qop)
+ {
+ nc = AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE;
+ temp = qop;
+ if(!axutil_strstr(temp, AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH))
+ {
+ return AXIS2_FAILURE;
+ }
+ AXIS2_FREE(env->allocator, qop);
+ qop = AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH;
+ temp = axutil_uuid_gen(env);
+ cnonce = temp;
+ temp += CLIENT_NONCE_LENGTH;
+ if(temp)
+ *temp = AXIS2_ESC_NULL;
+ elen += 11 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + CLIENT_NONCE_LENGTH
+ + axutil_strlen(qop);
+ }
+
+ axutil_digest_calc_get_h_a1(env, algo, uname, realm, passwd, cnonce, nonce, h_a1);
+ axutil_digest_calc_get_response(env, h_a1, nonce, nc, cnonce, qop, method_value, url, h_a2,
+ response);
+
+ elen += 4 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE) + axutil_strlen(
+ AXIS2_HTTP_AUTH_TYPE_DIGEST) + response_length;
+
+ auth_str
+ = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 1)));
+ temp = auth_str;
+ sprintf(temp, "%s %s=\"%s\", ", AXIS2_HTTP_AUTH_TYPE_DIGEST,
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME, uname);
+ temp += ((int)strlen(AXIS2_HTTP_AUTH_TYPE_DIGEST) + (int)strlen(
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME) + (int)strlen(uname) + 6);
+ if(realm)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM, realm);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM) + (int)strlen(realm)
+ + 5);
+ }
+ if(nonce)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE, nonce);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE) + (int)strlen(nonce)
+ + 5);
+ }
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI, url);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI) + (int)strlen(url) + 5);
+ if(qop)
+ {
+ sprintf(temp, "%s=%s, %s=%s, %s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP,
+ qop, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT, nc,
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE, cnonce);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + (int)strlen(qop)
+ + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT) + (int)strlen(nc)
+ + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE) + (int)strlen(
+ cnonce) + 11);
+ }
+ if(opaque)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE, opaque);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE) + (int)strlen(
+ opaque) + 5);
+ }
+ sprintf(temp, "%s=\"%s\"", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE, response);
+
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_AUTHORIZATION, auth_str);
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ if(nonce)
+ AXIS2_FREE(env->allocator, nonce);
+ if(cnonce)
+ AXIS2_FREE(env->allocator, cnonce);
+ if(opaque)
+ AXIS2_FREE(env->allocator, opaque);
+ if(auth_str)
+ AXIS2_FREE(env->allocator, auth_str);
+ auth_str = NULL;
+
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_digest_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_data)
+{
+ axutil_property_t *proxy_auth_un = NULL;
+ axutil_property_t *proxy_auth_pw = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+
+ if(!header_data || !*header_data)
+ return AXIS2_FAILURE;
+
+ proxy_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME);
+ proxy_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD);
+
+ if(proxy_auth_un && proxy_auth_pw)
+ {
+ uname = (axis2_char_t *)axutil_property_get_value(proxy_auth_un, env);
+ passwd = (axis2_char_t *)axutil_property_get_value(proxy_auth_pw, env);
+ }
+ if(!uname || !passwd)
+ {
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *proxy_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(conf)
+ {
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+ }
+ if(trans_desc)
+ {
+ proxy_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_HTTP_PROXY_API);
+ if(!proxy_param)
+ {
+ proxy_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_HTTP_PROXY);
+ }
+ if(proxy_param)
+ {
+ transport_attrs = axutil_param_get_attributes(proxy_param, env);
+
+ if(transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(username_attr)
+ {
+ uname = axiom_attribute_get_value(username_attr, env);
+ }
+
+ obj = NULL;
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(password_attr)
+ {
+ passwd = axiom_attribute_get_value(password_attr, env);
+ }
+ }
+ }
+ }
+ }
+ if(uname && passwd)
+ {
+ int elen = 0; /* length of header content */
+ int print_const = 5; /* constant accounts for printing the
+ quoatation marks, comma, and space */
+ int response_length = 32;
+ axis2_char_t *temp = NULL;
+ axis2_char_t *alloc_temp = NULL;
+ axis2_char_t *algo = AXIS2_HTTP_AUTHORIZATION_REQUEST_ALGORITHM_MD5;
+ axis2_char_t *realm = NULL;
+ axis2_char_t *qop = NULL;
+ axis2_char_t *nonce = NULL;
+ axis2_char_t *opaque = NULL;
+ axis2_char_t *cnonce = NULL;
+ axis2_char_t *nc = NULL;
+ axutil_digest_hash_hex_t h_a1;
+ axutil_digest_hash_hex_t h_a2;
+ axutil_digest_hash_hex_t response;
+ axis2_char_t *auth_str = NULL;
+ axutil_property_t *method = NULL;
+ axis2_char_t *method_value = NULL;
+ axis2_char_t *url = NULL;
+
+ url = axis2_http_request_line_get_uri(axis2_http_simple_request_get_request_line(request,
+ env), env);
+
+ if(!url)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI)
+ + axutil_strlen(url);
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME)
+ + axutil_strlen(uname);
+
+ method = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_METHOD);
+ if(method)
+ {
+ method_value = (axis2_char_t *)axutil_property_get_value(method, env);
+ }
+ else
+ {
+ method_value = AXIS2_HTTP_POST;
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM);
+ if(temp)
+ {
+ realm = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(realm)
+ {
+ realm++;
+ temp = axutil_strchr(realm, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - realm + 1)));
+ strncpy(alloc_temp, realm, (temp - realm));
+ if(alloc_temp)
+ alloc_temp[temp - realm] = AXIS2_ESC_NULL;
+ realm = alloc_temp;
+ alloc_temp = NULL;
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM)
+ + axutil_strlen(realm);
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP);
+ if(temp)
+ {
+ qop = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(qop)
+ {
+ qop++;
+ temp = axutil_strchr(qop, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - qop + 1)));
+ strncpy(alloc_temp, qop, (temp - qop));
+ if(alloc_temp)
+ alloc_temp[temp - qop] = AXIS2_ESC_NULL;
+ qop = alloc_temp;
+ alloc_temp = NULL;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE);
+ if(temp)
+ {
+ nonce = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(nonce)
+ {
+ nonce++;
+ temp = axutil_strchr(nonce, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - nonce + 1)));
+ strncpy(alloc_temp, nonce, (temp - nonce));
+ if(alloc_temp)
+ alloc_temp[temp - nonce] = AXIS2_ESC_NULL;
+ nonce = alloc_temp;
+ alloc_temp = NULL;
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE)
+ + axutil_strlen(nonce);
+ }
+ else
+ {
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE);
+ if(temp)
+ {
+ opaque = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(opaque)
+ {
+ opaque++;
+ temp = axutil_strchr(opaque, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - opaque + 1)));
+ strncpy(alloc_temp, opaque, (temp - opaque));
+ if(alloc_temp)
+ alloc_temp[temp - opaque] = AXIS2_ESC_NULL;
+ opaque = alloc_temp;
+ alloc_temp = NULL;
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE)
+ + axutil_strlen(opaque);
+ }
+ else
+ {
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ if(nonce)
+ AXIS2_FREE(env->allocator, nonce);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ if(qop)
+ {
+ nc = AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE;
+ temp = qop;
+ if(!axutil_strstr(temp, AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH))
+ {
+ return AXIS2_FAILURE;
+ }
+ AXIS2_FREE(env->allocator, qop);
+ qop = AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH;
+ temp = axutil_uuid_gen(env);
+ cnonce = temp;
+ temp += CLIENT_NONCE_LENGTH;
+ if(temp)
+ *temp = AXIS2_ESC_NULL;
+ elen += 11 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + CLIENT_NONCE_LENGTH
+ + axutil_strlen(qop);
+ }
+
+ axutil_digest_calc_get_h_a1(env, algo, uname, realm, passwd, cnonce, nonce, h_a1);
+ axutil_digest_calc_get_response(env, h_a1, nonce, nc, cnonce, qop, method_value, url, h_a2,
+ response);
+
+ elen += 4 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE) + axutil_strlen(
+ AXIS2_PROXY_AUTH_TYPE_DIGEST) + response_length;
+
+ auth_str
+ = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 1)));
+ temp = auth_str;
+ sprintf(temp, "%s %s=\"%s\", ", AXIS2_PROXY_AUTH_TYPE_DIGEST,
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME, uname);
+ temp += ((int)strlen(AXIS2_HTTP_AUTH_TYPE_DIGEST) + (int)strlen(
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME) + (int)strlen(uname) + 6);
+ if(realm)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM, realm);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM) + (int)strlen(realm)
+ + 5);
+ }
+ if(nonce)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE, nonce);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE) + (int)strlen(nonce)
+ + 5);
+ }
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI, url);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI) + (int)strlen(url) + 5);
+ if(qop)
+ {
+ sprintf(temp, "%s=%s, %s=%s, %s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP,
+ qop, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT, nc,
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE, cnonce);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + (int)strlen(qop)
+ + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT) + (int)strlen(nc)
+ + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE) + (int)strlen(
+ cnonce) + 11);
+ }
+ if(opaque)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE, opaque);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE) + (int)strlen(
+ opaque) + 5);
+ }
+ sprintf(temp, "%s=\"%s\"", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE, response);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_PROXY_AUTHORIZATION,
+ auth_str);
+ if(realm)
+ {
+ AXIS2_FREE(env->allocator, realm);
+ }
+
+ if(nonce)
+ {
+ AXIS2_FREE(env->allocator, nonce);
+ }
+
+ if(cnonce)
+ {
+ AXIS2_FREE(env->allocator, cnonce);
+ }
+
+ if(opaque)
+ {
+ AXIS2_FREE(env->allocator, opaque);
+ }
+
+ if(auth_str)
+ {
+ AXIS2_FREE(env->allocator, auth_str);
+ }
+
+ auth_str = NULL;
+
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_http_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axis2_char_t *auth_type = NULL;
+ axis2_status_t status = AXIS2_FALSE;
+ axutil_property_t *http_auth_property = NULL;
+ axis2_char_t *http_auth_property_value = NULL;
+ axis2_bool_t force_http_auth = AXIS2_FALSE;
+ axutil_property_t *http_auth_type_property = NULL;
+ axis2_char_t *http_auth_type_property_value = NULL;
+ axis2_char_t *auth_type_end = NULL;
+
+ http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_FORCE_HTTP_AUTH);
+ if(http_auth_property)
+ {
+ http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property,
+ env);
+ }
+
+ if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ force_http_auth = AXIS2_TRUE;
+ }
+
+ if(force_http_auth)
+ {
+ http_auth_type_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_HTTP_AUTH_TYPE);
+ if(http_auth_type_property)
+ {
+ http_auth_type_property_value = (axis2_char_t *)axutil_property_get_value(
+ http_auth_type_property, env);
+ }
+
+ if(http_auth_type_property_value)
+ {
+ auth_type = http_auth_type_property_value;
+ }
+ }
+ if(!force_http_auth || axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0)
+ {
+ axis2_http_header_t *auth_header = NULL;
+ axis2_http_simple_response_t *response = NULL;
+
+ response = axis2_http_client_get_response(sender->client, env);
+
+ if(response)
+ {
+ auth_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_WWW_AUTHENTICATE);
+ }
+
+ if(auth_header)
+ {
+ auth_type = axis2_http_header_get_value(auth_header, env);
+ }
+
+ if(auth_type)
+ {
+ auth_type_end = axutil_strchr(auth_type, ' ');
+ *auth_type_end = AXIS2_ESC_NULL;
+ auth_type_end++;
+ /*Read the realm and the rest stuff now from auth_type_end */
+ }
+ if(force_http_auth && axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) != 0)
+ {
+ auth_type = NULL;
+ }
+ }
+ if(auth_type)
+ {
+ if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0)
+ {
+ status = axis2_http_sender_configure_http_basic_auth(sender, env, msg_ctx, request);
+ }
+ else if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0)
+ {
+ status = axis2_http_sender_configure_http_digest_auth(sender, env, msg_ctx, request,
+ auth_type_end);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not"
+ "supported", auth_type);
+ }
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ }
+
+ return status;
+}
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axis2_char_t *auth_type = NULL;
+ axis2_status_t status = AXIS2_FALSE;
+ axutil_property_t *proxy_auth_property = NULL;
+ axis2_char_t *proxy_auth_property_value = NULL;
+ axis2_bool_t force_proxy_auth = AXIS2_FALSE;
+ axutil_property_t *proxy_auth_type_property = NULL;
+ axis2_char_t *proxy_auth_type_property_value = NULL;
+ axis2_char_t *auth_type_end = NULL;
+
+ proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_FORCE_PROXY_AUTH);
+ if(proxy_auth_property)
+ {
+ proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property,
+ env);
+ }
+
+ if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ force_proxy_auth = AXIS2_TRUE;
+ }
+
+ if(force_proxy_auth)
+ {
+ proxy_auth_type_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_PROXY_AUTH_TYPE);
+ if(proxy_auth_type_property)
+ {
+ proxy_auth_type_property_value = (axis2_char_t *)axutil_property_get_value(
+ proxy_auth_type_property, env);
+ }
+
+ if(proxy_auth_type_property_value)
+ {
+ auth_type = proxy_auth_type_property_value;
+ }
+ }
+ else
+ {
+ axis2_http_header_t *auth_header = NULL;
+ axis2_http_simple_response_t *response = NULL;
+
+ response = axis2_http_client_get_response(sender->client, env);
+
+ if(response)
+ {
+ auth_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_PROXY_AUTHENTICATE);
+ }
+
+ if(auth_header)
+ {
+ auth_type = axis2_http_header_get_value(auth_header, env);
+ }
+
+ if(auth_type)
+ {
+ auth_type_end = axutil_strchr(auth_type, ' ');
+ *auth_type_end = AXIS2_ESC_NULL;
+ auth_type_end++;
+ /*Read the realm and the rest stuff now from auth_type_end */
+ }
+ }
+ if(auth_type)
+ {
+ if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0)
+ {
+ status = axis2_http_sender_configure_proxy_basic_auth(sender, env, msg_ctx, request);
+ }
+ else if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0)
+ {
+ status = axis2_http_sender_configure_proxy_digest_auth(sender, env, msg_ctx, request,
+ auth_type_end);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type);
+ }
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ }
+
+ return status;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_set_http_auth_type(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axis2_char_t *auth_type = NULL;
+ axis2_status_t status = AXIS2_FALSE;
+ axis2_char_t *auth_type_end = NULL;
+ axis2_http_header_t *auth_header = NULL;
+ axis2_http_simple_response_t *response = NULL;
+
+ response = axis2_http_client_get_response(sender->client, env);
+
+ if(response)
+ {
+ auth_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_WWW_AUTHENTICATE);
+ }
+
+ if(auth_header)
+ {
+ auth_type = axis2_http_header_get_value(auth_header, env);
+ }
+
+ if(auth_type)
+ {
+ auth_type_end = axutil_strchr(auth_type, ' ');
+ *auth_type_end = AXIS2_ESC_NULL;
+ auth_type_end++;
+ /*Read the realm and the rest stuff now from auth_type_end */
+ }
+
+ if(auth_type)
+ {
+ if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0)
+ {
+ status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE_BASIC);
+ }
+ else if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0)
+ {
+ status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE_DIGEST);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type);
+ }
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ }
+ return status;
+}
+
+static axis2_status_t
+axis2_http_sender_set_proxy_auth_type(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axis2_char_t *auth_type = NULL;
+ axis2_status_t status = AXIS2_FALSE;
+ axis2_char_t *auth_type_end = NULL;
+ axis2_http_header_t *auth_header = NULL;
+ axis2_http_simple_response_t *response = NULL;
+
+ response = axis2_http_client_get_response(sender->client, env);
+
+ if(response)
+ {
+ auth_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_PROXY_AUTHENTICATE);
+ }
+
+ if(auth_header)
+ {
+ auth_type = axis2_http_header_get_value(auth_header, env);
+ }
+
+ if(auth_type)
+ {
+ auth_type_end = axutil_strchr(auth_type, ' ');
+ *auth_type_end = AXIS2_ESC_NULL;
+ auth_type_end++;
+ /*Read the realm and the rest stuff now from auth_type_end */
+ }
+
+ if(auth_type)
+ {
+ if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0)
+ {
+ status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_PROXY_AUTH_TYPE_BASIC);
+ }
+ else if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0)
+ {
+ status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_PROXY_AUTH_TYPE_DIGEST);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type);
+ }
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ }
+ return status;
+}
+#endif
+
+#ifdef AXIS2_LIBCURL_ENABLED
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_libcurl_http_send (axis2_libcurl_t * curl,
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axiom_soap_envelope_t * out,
+ const axis2_char_t * str_url,
+ const axis2_char_t * soap_action)
+{
+ return axis2_libcurl_send (curl, sender->om_output,
+ env, msg_ctx, out, str_url, soap_action);
+}
+#endif
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_sender_get_param_string(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axiom_soap_envelope_t *soap_env = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axiom_node_t *body_node = NULL;
+ axiom_node_t *data_node = NULL;
+ axiom_element_t *data_element = NULL;
+ axiom_child_element_iterator_t *iterator = NULL;
+ axutil_array_list_t *param_list = NULL;
+ axis2_char_t *param_string = NULL;
+ int i = 0;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL);
+
+ soap_env = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
+ if(!soap_env)
+ {
+ return NULL;
+ }
+ soap_body = axiom_soap_envelope_get_body(soap_env, env);
+ body_node = axiom_soap_body_get_base_node(soap_body, env);
+ if(!body_node)
+ {
+ /* This could be the situation where service client does not provide
+ * a xml payload and instead add url parameters to the endpoint url
+ */
+ return NULL;
+ }
+ data_node = axiom_node_get_first_child(body_node, env);
+ if(!data_node)
+ {
+ return NULL;
+ }
+
+ param_list = axutil_array_list_create(env, AXIS2_ARRAY_LIST_DEFAULT_CAPACITY);
+
+ data_element = axiom_node_get_data_element(data_node, env);
+
+ iterator = axiom_element_get_child_elements(data_element, env, data_node);
+
+ if(iterator)
+ {
+ while(AXIS2_TRUE == AXIOM_CHILD_ELEMENT_ITERATOR_HAS_NEXT(iterator, env))
+ {
+ axiom_node_t *node = NULL;
+ axiom_element_t *element = NULL;
+ axis2_char_t *name = NULL;
+ axis2_char_t *value = NULL;
+ axis2_char_t *encoded_value = NULL;
+
+ node = AXIOM_CHILD_ELEMENT_ITERATOR_NEXT(iterator, env);
+ element = axiom_node_get_data_element(node, env);
+ name = axiom_element_get_localname(element, env);
+ value = axiom_element_get_text(element, env, node);
+ if(value)
+ {
+ encoded_value = (axis2_char_t *)AXIS2_MALLOC(env->allocator, strlen(value));
+ memset(encoded_value, 0, strlen(value));
+ encoded_value = axutil_url_encode(env, encoded_value, value, (int)strlen(value));
+ /* We are sure that the difference lies within the int range */
+
+ axutil_array_list_add(param_list, env, axutil_strcat(env, name, "=", encoded_value,
+ NULL));
+ AXIS2_FREE(env->allocator, encoded_value);
+ encoded_value = NULL;
+ }
+ }
+ }
+ for(i = 0; i < axutil_array_list_size(param_list, env); i++)
+ {
+ axis2_char_t *tmp_string = NULL;
+ axis2_char_t *pair = NULL;
+
+ pair = axutil_array_list_get(param_list, env, i);
+ if(i == 0)
+ {
+ tmp_string = axutil_stracat(env, param_string, pair);
+ }
+ else
+ {
+ tmp_string = axutil_strcat(env, param_string, AXIS2_AND_SIGN, pair, NULL);
+ }
+
+ if(param_string)
+ {
+ AXIS2_FREE(env->allocator, param_string);
+ param_string = NULL;
+ }
+ AXIS2_FREE(env->allocator, pair);
+ param_string = tmp_string;
+ }
+ axutil_array_list_free(param_list, env);
+ return param_string;
+}
+
+void AXIS2_CALL
+axis2_http_sender_util_add_header(
+ const axutil_env_t * env,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_name,
+ const axis2_char_t * header_value)
+{
+ axis2_http_header_t *http_header;
+ http_header = axis2_http_header_create(env, header_name, header_value);
+ axis2_http_simple_request_add_header(request, env, http_header);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_sender_set_keep_alive(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_bool_t keep_alive)
+{
+ sender->keep_alive = keep_alive;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_sender_get_keep_alive(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env)
+{
+ return sender->keep_alive;
+}
+
+static axutil_hash_t *
+axis2_http_sender_connection_map_create(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx)
+{
+ axutil_hash_t *connection_map = NULL;
+ connection_map = axutil_hash_make(env);
+ if(!connection_map)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ }
+ else
+ {
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axutil_property_t *connection_map_property = NULL;
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ connection_map_property = axutil_property_create_with_args(env, AXIS2_SCOPE_SESSION,
+ AXIS2_TRUE, axis2_http_sender_connection_map_free, connection_map);
+ axis2_conf_ctx_set_property(conf_ctx, env, AXIS2_HTTP_CONNECTION_MAP,
+ connection_map_property);
+ }
+ return connection_map;
+}
+
+static void
+axis2_http_sender_connection_map_remove(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_http_client_t *http_client)
+{
+ axutil_property_t *property = NULL;
+ axis2_endpoint_ref_t *endpoint = NULL;
+ /**
+ * Put the http client into message context with own value true so that it will be freed
+ * after response processed
+ */
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE,
+ axis2_http_client_free_void_arg, http_client);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_CLIENT, property);
+ endpoint = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(endpoint)
+ {
+ const axis2_char_t *address = NULL;
+ address = axis2_endpoint_ref_get_address(endpoint, env);
+ if(address)
+ {
+ axutil_url_t *url = NULL;
+ url = axutil_url_parse_string(env, address);
+ if(url)
+ {
+ axis2_char_t *server = axutil_url_get_server(url, env);
+ if(server)
+ {
+ axutil_hash_set(connection_map, server, AXIS2_HASH_KEY_STRING, NULL);
+ }
+ axutil_url_free(url, env);
+ }
+ }
+ }
+}
+
+static void
+axis2_http_sender_connection_map_add(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_http_client_t *http_client)
+{
+ axutil_property_t *property = NULL;
+ axis2_endpoint_ref_t *endpoint = NULL;
+ /**
+ * Put the http client into message context. Is this neccessary?
+ */
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE,
+ axis2_http_client_free_void_arg, http_client);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_CLIENT, property);
+ endpoint = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(endpoint)
+ {
+ const axis2_char_t *address = NULL;
+ address = axis2_endpoint_ref_get_address(endpoint, env);
+ if(address)
+ {
+ axutil_url_t *url = NULL;
+ url = axutil_url_parse_string(env, address);
+ if(url)
+ {
+ axis2_char_t *server = axutil_url_get_server(url, env);
+ if(server)
+ {
+ axutil_hash_set(connection_map, axutil_strdup(env, server),
+ AXIS2_HASH_KEY_STRING, http_client);
+ }
+ axutil_url_free(url, env);
+ }
+ }
+ }
+}
+
+static axis2_http_client_t *
+axis2_http_sender_connection_map_get(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx)
+{
+ axis2_http_client_t *http_client = NULL;
+ axis2_endpoint_ref_t *endpoint = NULL;
+ endpoint = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(endpoint)
+ {
+ const axis2_char_t *address = NULL;
+ address = axis2_endpoint_ref_get_address(endpoint, env);
+ if(address)
+ {
+ axutil_url_t *url = NULL;
+ url = axutil_url_parse_string(env, address);
+ if(url)
+ {
+ axis2_char_t *server = axutil_url_get_server(url, env);
+ if(server)
+ {
+ http_client = axutil_hash_get(connection_map, server, AXIS2_HASH_KEY_STRING);
+ }
+ axutil_url_free(url, env);
+ }
+ }
+ }
+ return http_client;
+}
+
+static void AXIS2_CALL
+axis2_http_sender_connection_map_free(
+ void *cm_void,
+ const axutil_env_t *env)
+{
+ void *val = NULL;
+ const void *key = NULL;
+ axutil_hash_index_t *hi = NULL;
+ axutil_hash_t *ht = (axutil_hash_t *)cm_void;
+
+ for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ axis2_char_t *name = NULL;
+ axis2_http_client_t *value = NULL;
+
+ axutil_hash_this(hi, &key, NULL, &val);
+ name = (axis2_char_t *) key;
+ if(name)
+ {
+ AXIS2_FREE(env->allocator, name);
+ }
+ value = (axis2_http_client_t *) val;
+ if(value)
+ {
+ axis2_http_client_free(value, env);
+ }
+ }
+ axutil_hash_free(ht, env);
+}
+
diff --git a/src/core/transport/http/sender/http_transport_sender.c b/src/core/transport/http/sender/http_transport_sender.c
new file mode 100644
index 0000000..3ef55b0
--- /dev/null
+++ b/src/core/transport/http/sender/http_transport_sender.c
@@ -0,0 +1,859 @@
+/*
+ * 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_sender.h>
+#include <axutil_string.h>
+#include <axis2_endpoint_ref.h>
+#include <axis2_addr.h>
+#include <axiom_xml_writer.h>
+#include <axiom_output.h>
+#include <axis2_http_transport_utils.h>
+#include <axutil_generic_obj.h>
+#include <axis2_http_out_transport_info.h>
+#include <axis2_http_transport.h>
+#include <axis2_http_sender.h>
+#include <axiom_soap_body.h>
+#include <axutil_types.h>
+#include <axiom_soap_fault_detail.h>
+#include <axis2_msg_ctx.h>
+
+#ifdef AXIS2_LIBCURL_ENABLED
+#include "libcurl/axis2_libcurl.h"
+#endif
+
+/**
+ * HTTP Transport Sender struct impl
+ * Axis2 HTTP Transport Sender impl
+ */
+
+typedef struct axis2_http_transport_sender_impl
+{
+ axis2_transport_sender_t transport_sender;
+ axis2_char_t *http_version;
+ axis2_bool_t chunked;
+ int connection_timeout;
+ int so_timeout;
+ axis2_bool_t keep_alive;
+#ifdef AXIS2_LIBCURL_ENABLED
+ axis2_libcurl_t *libcurl;
+#endif
+} axis2_http_transport_sender_impl_t;
+
+#define AXIS2_WS_RM_ANONYMOUS_URL "http://docs.oasis-open.org/ws-rx/wsmc/200702/anonymous?id="
+#define AXIS2_INTF_TO_IMPL(transport_sender) \
+ ((axis2_http_transport_sender_impl_t *)\
+ (transport_sender))
+
+/***************************** Function headers *******************************/
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_invoke(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_clean_up(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_init(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_transport_out_desc_t * out_desc);
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_write_message(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_endpoint_ref_t * epr,
+ axiom_soap_envelope_t * out,
+ axiom_output_t * om_output);
+
+void AXIS2_CALL axis2_http_transport_sender_free(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env);
+
+static const axis2_transport_sender_ops_t http_transport_sender_ops_var = {
+ axis2_http_transport_sender_init, axis2_http_transport_sender_invoke,
+ axis2_http_transport_sender_clean_up, axis2_http_transport_sender_free };
+
+axis2_transport_sender_t *AXIS2_CALL
+axis2_http_transport_sender_create(
+ const axutil_env_t * env)
+{
+ axis2_http_transport_sender_impl_t *transport_sender_impl = NULL;
+
+ transport_sender_impl = (axis2_http_transport_sender_impl_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_transport_sender_impl_t));
+
+ if(!transport_sender_impl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset((void *)transport_sender_impl, 0, sizeof(axis2_http_transport_sender_impl_t));
+
+ transport_sender_impl->http_version = axutil_strdup(env, AXIS2_HTTP_HEADER_PROTOCOL_11);
+ transport_sender_impl->chunked = AXIS2_TRUE;
+ transport_sender_impl->connection_timeout = AXIS2_HTTP_DEFAULT_CONNECTION_TIMEOUT;
+ transport_sender_impl->so_timeout = AXIS2_HTTP_DEFAULT_SO_TIMEOUT;
+ transport_sender_impl->keep_alive = AXIS2_TRUE;
+ transport_sender_impl->transport_sender.ops = &http_transport_sender_ops_var;
+
+#ifdef AXIS2_LIBCURL_ENABLED
+ transport_sender_impl->libcurl = axis2_libcurl_create(env);
+ if (!transport_sender_impl->libcurl)
+ {
+ AXIS2_FREE(env->allocator, transport_sender_impl);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+#endif
+
+ return &(transport_sender_impl->transport_sender);
+}
+
+void AXIS2_CALL
+axis2_http_transport_sender_free(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env)
+{
+
+ axis2_http_transport_sender_impl_t *transport_sender_impl = NULL;
+ if(!transport_sender)
+ {
+ return;
+ }
+
+ transport_sender_impl = AXIS2_INTF_TO_IMPL(transport_sender);
+
+ if(transport_sender_impl->http_version)
+ {
+ AXIS2_FREE(env->allocator, transport_sender_impl->http_version);
+ transport_sender_impl->http_version = NULL;
+ }
+
+#ifdef AXIS2_LIBCURL_ENABLED
+ if (transport_sender_impl->libcurl)
+ {
+ axis2_libcurl_free(transport_sender_impl->libcurl, env);
+ }
+#endif
+
+ AXIS2_FREE(env->allocator, transport_sender_impl);
+ return;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_invoke(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ const axis2_char_t *char_set_enc = NULL;
+ axutil_string_t *char_set_enc_str = NULL;
+ axis2_endpoint_ref_t *epr = NULL;
+ axis2_char_t *transport_url = NULL;
+ axiom_xml_writer_t *xml_writer = NULL;
+ axiom_output_t *om_output = NULL;
+ axis2_char_t *buffer = NULL;
+ axiom_soap_envelope_t *soap_data_out = NULL;
+ axis2_bool_t do_mtom;
+ axutil_property_t *property = NULL;
+ axiom_node_t *data_out = NULL;
+ int buffer_size = 0;
+ axis2_status_t status = AXIS2_SUCCESS;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *write_xml_declaration_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+ axis2_bool_t write_xml_declaration = AXIS2_FALSE;
+ axis2_bool_t fault = AXIS2_FALSE;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_sender_invoke");
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env);
+ if(char_set_enc_str)
+ {
+ char_set_enc = axutil_string_get_buffer(char_set_enc_str, env);
+ }
+
+ if(!char_set_enc)
+ {
+ axis2_op_ctx_t *op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+ if(op_ctx)
+ {
+ axis2_ctx_t *ctx = axis2_op_ctx_get_base(op_ctx, env);
+ if(ctx)
+ {
+ property = axis2_ctx_get_property(ctx, env, AXIS2_CHARACTER_SET_ENCODING);
+ if(property)
+ {
+ char_set_enc = axutil_property_get_value(property, env);
+ property = NULL;
+ }
+ }
+ }
+ }
+
+ /**
+ * If we still can't find the char set enc we will
+ * use default
+ */
+ if(!char_set_enc)
+ {
+ char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING;
+ }
+
+ do_mtom = axis2_http_transport_utils_do_write_mtom(env, msg_ctx);
+
+ transport_url = axis2_msg_ctx_get_transport_url(msg_ctx, env);
+ if(transport_url)
+ {
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "transport_url:%s", transport_url);
+ epr = axis2_endpoint_ref_create(env, transport_url);
+ }
+ else
+ {
+ /* when transport url is not available in msg_ctx */
+ axis2_endpoint_ref_t *ctx_epr = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(ctx_epr)
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "ctx_epr:%s", axis2_endpoint_ref_get_address(
+ ctx_epr, env));
+
+ if(ctx_epr && axutil_strcmp(AXIS2_WSA_ANONYMOUS_URL_SUBMISSION,
+ axis2_endpoint_ref_get_address(ctx_epr, env)) && axutil_strcmp(AXIS2_WSA_ANONYMOUS_URL,
+ axis2_endpoint_ref_get_address(ctx_epr, env)) && !(axutil_strstr(
+ axis2_endpoint_ref_get_address(ctx_epr, env), AXIS2_WS_RM_ANONYMOUS_URL)))
+ {
+ epr = ctx_epr;
+ }
+ }
+
+ soap_data_out = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
+ if(!soap_data_out)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_SOAP_ENVELOPE_IN_MSG_CTX, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", AXIS2_ERROR_GET_MESSAGE(env->error));
+ return AXIS2_SUCCESS;
+ }
+
+ xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
+ AXIS2_XML_PARSER_TYPE_BUFFER);
+ if(!xml_writer)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Could not create xml_writer for \
+AXIS2_XML_PARSER_TYPE_BUFFER");
+ return AXIS2_FAILURE;
+ }
+
+ om_output = axiom_output_create(env, xml_writer);
+ if(!om_output)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Could not create om_output for xml writer of \
+AXIS2_XML_PARSER_TYPE_BUFFER");
+ axiom_xml_writer_free(xml_writer, env);
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ /* setting SOAP version for OM_OUTPUT. */
+ axiom_output_set_soap11(om_output, env, axis2_msg_ctx_get_is_soap_11(msg_ctx, env));
+
+ /* This is the case where normal client send the requet using a http_client*/
+
+ if(epr)
+ {
+ if(axutil_strcmp(AXIS2_WSA_NONE_URL_SUBMISSION, axis2_endpoint_ref_get_address(epr, env))
+ == 0 || axutil_strcmp(AXIS2_WSA_NONE_URL, axis2_endpoint_ref_get_address(epr, env))
+ == 0)
+ {
+ epr = NULL;
+ }
+ else
+ {
+ status = axis2_http_transport_sender_write_message(transport_sender, env, msg_ctx, epr,
+ soap_data_out, om_output);
+ }
+ }
+
+ /* If no endpoint reference could be derived from the the message context. It could well be the
+ * single channel two way scenario in the application server side send.
+ */
+ if(!epr)
+ {
+ axutil_stream_t *out_stream = axis2_msg_ctx_get_transport_out_stream(msg_ctx, env);
+
+ if(AXIS2_TRUE == axis2_msg_ctx_get_server_side(msg_ctx, env))
+ {
+ axis2_http_out_transport_info_t *out_info = NULL;
+ axis2_bool_t is_soap11 = AXIS2_FALSE;
+ axis2_op_ctx_t *op_ctx = NULL;
+ /*axis2_char_t *header_value = NULL;*/
+
+ out_info = (axis2_http_out_transport_info_t *)axis2_msg_ctx_get_out_transport_info(
+ msg_ctx, env);
+
+ if(!out_info)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_OUT_TRNSPORT_INFO_NULL, AXIS2_FAILURE);
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+ /*header_value = axis2_http_transport_utils_get_session(env, msg_ctx);
+ if(header_value)
+ {
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_COOKIE_HEADER(out_info, env, header_value);
+ }*/
+
+ is_soap11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env);
+
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CHAR_ENCODING(out_info, env, char_set_enc);
+ if(AXIS2_TRUE == is_soap11)
+ {
+ /* SOAP1.1 */
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML);
+ }
+ else
+ {
+ /* SOAP1.2 */
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env,
+ AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP);
+ }
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ }
+
+ if(conf)
+ {
+ /* get access to HTTP transport for sending */
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+
+ if(trans_desc)
+ {
+
+ /* accessing parameter in axis2.xml which set to have
+ * an ability to send xml versoin processing
+ * instruction <?xml version = "1.0"?> */
+ write_xml_declaration_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_XML_DECLARATION);
+ }
+
+ if(write_xml_declaration_param)
+ {
+ transport_attrs = axutil_param_get_attributes(write_xml_declaration_param, env);
+ if(transport_attrs)
+ {
+ /* Accessing attribute values */
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *write_xml_declaration_attr = NULL;
+ axis2_char_t *write_xml_declaration_attr_value = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_ADD_XML_DECLARATION,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ write_xml_declaration_attr
+ = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+
+ if(write_xml_declaration_attr)
+ {
+ write_xml_declaration_attr_value = axiom_attribute_get_value(
+ write_xml_declaration_attr, env);
+ }
+
+ if(write_xml_declaration_attr_value && 0 == axutil_strcasecmp(
+ write_xml_declaration_attr_value, AXIS2_VALUE_TRUE))
+ {
+ write_xml_declaration = AXIS2_TRUE;
+ }
+ }
+ }
+
+ if(write_xml_declaration)
+ {
+ axiom_output_write_xml_version_encoding(om_output, env);
+ }
+
+ if(AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ axiom_node_t *body_node = NULL;
+ /* axis2_bool_t fault = AXIS2_FALSE;*/
+ axiom_soap_fault_t *soap_fault;
+ axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_data_out, env);
+ axiom_soap_fault_detail_t *soap_fault_detial;
+
+ if(!soap_body)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL,
+ AXIS2_FAILURE);
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ fault = axiom_soap_body_has_fault(soap_body, env);
+
+ if(fault == AXIS2_TRUE)
+ {
+ soap_fault = axiom_soap_body_get_fault(soap_body, env);
+
+ if(!soap_fault)
+ {
+
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Rest fault has occur, error described below");
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ soap_fault_detial = axiom_soap_fault_get_detail(soap_fault, env);
+
+ if(!soap_fault_detial)
+ {
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "Returning failure to obtain soap_fault_detail from soap_fault");
+ return AXIS2_FAILURE;
+ }
+
+ body_node = axiom_soap_fault_detail_get_base_node(soap_fault_detial, env);
+ if(!body_node)
+ {
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "failure to get base node from soap_fault_detail.");
+ return AXIS2_FAILURE;
+ }
+
+ }
+ else
+ {
+
+ body_node = axiom_soap_body_get_base_node(soap_body, env);
+ if(!body_node)
+ {
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "failure to get base node from soap_body.");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ data_out = axiom_node_get_first_element(body_node, env);
+
+ if(!data_out || axiom_node_get_node_type(data_out, env) != AXIOM_ELEMENT)
+ {
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "unable to get first element from soap_body, base node.");
+ return AXIS2_FAILURE;
+ }
+
+ axiom_node_serialize(data_out, env, om_output);
+ buffer = (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env);
+ buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env);
+ axutil_stream_write(out_stream, env, buffer, buffer_size);
+ /* Finish Rest Processing */
+
+ }
+ else
+ {
+ axiom_soap_body_t *body = NULL;
+
+ body = axiom_soap_envelope_get_body(soap_data_out, env);
+ fault = axiom_soap_body_has_fault(body, env);
+
+ /* SOAP Processing */
+ axiom_output_set_do_optimize(om_output, env, do_mtom);
+ axiom_soap_envelope_serialize(soap_data_out, env, om_output, AXIS2_FALSE);
+ if(do_mtom && !fault)
+ {
+ axis2_status_t mtom_status = AXIS2_FAILURE;
+ axis2_char_t *content_type = NULL;
+ axutil_array_list_t *mime_parts = NULL;
+
+ /*Create the attachment related data and put them to an
+ *array_list */
+ mtom_status = axiom_output_flush(om_output, env);
+ if(mtom_status == AXIS2_SUCCESS)
+ {
+ mime_parts = axiom_output_get_mime_parts(om_output, env);
+ if(!mime_parts)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Unable to create the mime_part list from om_output");
+ return AXIS2_FAILURE;
+ }
+ else
+ {
+ axis2_msg_ctx_set_mime_parts(msg_ctx, env, mime_parts);
+ }
+ }
+ /*om_out put has the details of content_type */
+ content_type = (axis2_char_t *)axiom_output_get_content_type(om_output, env);
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env, content_type);
+ }
+ else
+ {
+ buffer = (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env);
+ buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env);
+
+ /* This is where it actually fill the buffer in out_stream. In application server
+ * side this is the out_stream passed to the in message context from http_worker
+ * function and then copied to the out message context.
+ */
+ axutil_stream_write(out_stream, env, buffer, buffer_size);
+ }
+ }
+
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+ axis2_op_ctx_set_response_written(op_ctx, env, AXIS2_TRUE);
+ }
+ }
+
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+
+ if(transport_url)
+ {
+ if(epr)
+ {
+ axis2_endpoint_ref_free(epr, env);
+ epr = NULL;
+ }
+ }
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_sender_invoke");
+ return status;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_clean_up(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE);
+ /*
+ * Clean up is not used. If the http sender needs
+ * to be cleaned up it should be done here.
+ */
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_init(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_transport_out_desc_t * out_desc)
+{
+ axutil_param_t *version_param = NULL;
+ axis2_char_t *version = NULL;
+ axis2_char_t *temp = NULL;
+ axutil_param_t *temp_param = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, out_desc, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE);
+
+ /* Getting HTTP version from axis2.xml */
+ version_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container(
+ out_desc, env), env, AXIS2_HTTP_PROTOCOL_VERSION);
+
+ if(version_param)
+ {
+ version = axutil_param_get_value(version_param, env);
+ }
+
+ if(version)
+ {
+ /* handling HTTP 1.1 */
+ if(0 == axutil_strcmp(version, AXIS2_HTTP_HEADER_PROTOCOL_11))
+ {
+ axis2_char_t *encoding = NULL;
+ axutil_param_t *encoding_param = NULL;
+ if(AXIS2_INTF_TO_IMPL(transport_sender)->http_version)
+ {
+ AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(transport_sender)->http_version);
+ }
+
+ AXIS2_INTF_TO_IMPL(transport_sender)->http_version = axutil_strdup(env, version);
+ AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive = AXIS2_TRUE;
+ encoding_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(out_desc, env), env,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING);
+
+ if(encoding_param)
+ {
+ encoding = axutil_param_get_value(encoding_param, env);
+ }
+
+ if(encoding && 0
+ == axutil_strcmp(encoding, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_TRUE;
+ }
+ else
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_FALSE;
+ }
+
+ }
+ else if(0 == axutil_strcmp(version, AXIS2_HTTP_HEADER_PROTOCOL_10))
+ {
+ axutil_param_t *keepalive_param = NULL;
+
+ /* Handling HTTP 1.0 */
+ if(AXIS2_INTF_TO_IMPL(transport_sender)->http_version)
+ {
+ AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(transport_sender)->http_version);
+ }
+ AXIS2_INTF_TO_IMPL(transport_sender)->http_version = axutil_strdup(env, version);
+ AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_FALSE;
+ keepalive_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(out_desc, env), env,
+ AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE);
+ if(keepalive_param)
+ {
+ axis2_char_t *keepalive_value = NULL;
+ keepalive_value = axutil_param_get_value(keepalive_param, env);
+ if(!axutil_strcmp(keepalive_value, AXIS2_VALUE_FALSE))
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive = AXIS2_FALSE;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* HTTP version is not available in axis2.xml */
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+
+ /* Getting HTTP_SO_TIMEOUT value from axis2.xml */
+ temp_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container(
+ out_desc, env), env, AXIS2_HTTP_SO_TIMEOUT);
+
+ if(temp_param)
+ {
+ temp = axutil_param_get_value(temp_param, env);
+ }
+
+ if(temp)
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->so_timeout = AXIS2_ATOI(temp);
+ }
+
+ /* Getting HTTP_CONNECTION_TIMEOUT from axis2.xml */
+ temp
+ = (axis2_char_t *)axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(out_desc, env), env,
+ AXIS2_HTTP_CONNECTION_TIMEOUT);
+ if(temp_param)
+ {
+ temp = axutil_param_get_value(temp_param, env);
+ }
+
+ /* set axis2.xml connection timeout value to http_sender */
+ if(temp)
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->connection_timeout = AXIS2_ATOI(temp);
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_write_message(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_endpoint_ref_t * epr,
+ axiom_soap_envelope_t * out,
+ axiom_output_t * om_output)
+{
+ const axis2_char_t *soap_action = NULL;
+ const axis2_char_t *url = NULL;
+ axis2_http_sender_t *sender = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ const axis2_char_t *soap_ns_uri = NULL;
+ axiom_soap_envelope_t *response_envelope = NULL;
+ axis2_op_t *op = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, epr, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, out, AXIS2_FAILURE);
+
+ /* epr is already passed NULL checking */
+ url = axis2_endpoint_ref_get_address(epr, env);
+
+ soap_action = axutil_string_get_buffer(axis2_msg_ctx_get_soap_action(msg_ctx, env), env);
+
+ if(!soap_action)
+ {
+ soap_action = "";
+ }
+
+ sender = axis2_http_sender_create(env);
+
+ if(!sender)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "http sender creation failed");
+ return AXIS2_FAILURE;
+ }
+ axis2_http_sender_set_keep_alive(sender, env, AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive);
+
+ /* For the MTOM case we should on chunking. And for chunking to work the
+ * protocol should be http 1.1*/
+
+ if(axis2_msg_ctx_get_doing_mtom(msg_ctx, env))
+ {
+ AXIS2_HTTP_SENDER_SET_CHUNKED(sender, env, AXIS2_TRUE);
+ AXIS2_HTTP_SENDER_SET_HTTP_VERSION(sender, env, AXIS2_HTTP_HEADER_PROTOCOL_11);
+ }
+ else
+ {
+ AXIS2_HTTP_SENDER_SET_CHUNKED(sender, env, AXIS2_INTF_TO_IMPL(transport_sender)->chunked);
+ AXIS2_HTTP_SENDER_SET_HTTP_VERSION(sender, env,
+ AXIS2_INTF_TO_IMPL(transport_sender)->http_version);
+ }
+ AXIS2_HTTP_SENDER_SET_OM_OUTPUT(sender, env, om_output);
+
+#ifdef AXIS2_LIBCURL_ENABLED
+ AXIS2_LOG_DEBUG (env->log, AXIS2_LOG_SI, "using axis2 libcurl http sender.");
+ status =
+ axis2_libcurl_http_send(AXIS2_INTF_TO_IMPL(transport_sender)->libcurl,
+ sender, env, msg_ctx, out, url, soap_action);
+#else
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "using axis2 native http sender.");
+ status = AXIS2_HTTP_SENDER_SEND(sender, env, msg_ctx, out, url, soap_action);
+#endif
+
+ AXIS2_HTTP_SENDER_FREE(sender, env);
+ sender = NULL;
+
+ /* if the send was not successful, do not process any response */
+ if(status != AXIS2_SUCCESS)
+ return status;
+
+ op = axis2_msg_ctx_get_op(msg_ctx, env);
+ if(op)
+ {
+ /* handle one way case */
+ const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env);
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "OP name axutil_qname_get_localpart = %s", mep);
+ if(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY) == 0 || axutil_strcmp(mep,
+ AXIS2_MEP_URI_ROBUST_OUT_ONLY) == 0 || axutil_strcmp(mep, AXIS2_MEP_URI_IN_ONLY) == 0)
+ {
+ return status;
+ }
+ else
+ {
+ /* AXIS2_MEP_URI_IN_OUT case , we have a response this
+ * time */
+ soap_ns_uri
+ = axis2_msg_ctx_get_is_soap_11(msg_ctx, env) ? AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI
+ : AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
+ response_envelope = axis2_http_transport_utils_create_soap_msg(env, msg_ctx,
+ soap_ns_uri);
+ if(response_envelope)
+ {
+ axis2_msg_ctx_set_response_soap_envelope(msg_ctx, env, response_envelope);
+ }
+ }
+ }
+
+ return status;
+}
+
+/**
+ * Following block distinguish the exposed part of the dll.
+ */
+
+/* When building for static deployment, give the get and remove methods
+ * unique names. This avoids having the linker fail with duplicate symbol
+ * errors.
+ */
+
+AXIS2_EXPORT int
+#ifndef AXIS2_STATIC_DEPLOY
+axis2_get_instance(
+#else
+ axis2_http_transport_sender_get_instance(
+#endif
+ struct axis2_transport_sender **inst,
+ const axutil_env_t * env)
+{
+ *inst = axis2_http_transport_sender_create(env);
+ if(!(*inst))
+ {
+ return AXIS2_FAILURE;
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXPORT int
+#ifndef AXIS2_STATIC_DEPLOY
+axis2_remove_instance(
+#else
+ axis2_http_transport_sender_remove_instance(
+#endif
+ axis2_transport_sender_t * inst,
+ const axutil_env_t * env)
+{
+ if(inst)
+ {
+ AXIS2_TRANSPORT_SENDER_FREE(inst, env);
+ }
+ return AXIS2_SUCCESS;
+}
+
diff --git a/src/core/transport/http/sender/libcurl/Makefile.am b/src/core/transport/http/sender/libcurl/Makefile.am
new file mode 100644
index 0000000..90e5ce6
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST= axis2_libcurl.h axis2_libcurl.c libcurl_stream.h libcurl_stream.c
+
diff --git a/src/core/transport/http/sender/libcurl/axis2_libcurl.c b/src/core/transport/http/sender/libcurl/axis2_libcurl.c
new file mode 100644
index 0000000..834e69b
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/axis2_libcurl.c
@@ -0,0 +1,1169 @@
+/*
+ * 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.
+ */
+#ifdef AXIS2_LIBCURL_ENABLED
+
+#include "axis2_libcurl.h"
+#include <axiom_soap.h>
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <axiom_output.h>
+#include <axis2_op_ctx.h>
+#include <axis2_ctx.h>
+#include <axis2_conf_ctx.h>
+#include <axis2_http_client.h>
+#include <axiom_xml_writer.h>
+#include <axutil_property.h>
+#include <axutil_param.h>
+#include <axutil_types.h>
+#include <axutil_generic_obj.h>
+#include <axis2_const.h>
+#include <axis2_util.h>
+#include <stdlib.h>
+#include <axis2_http_sender.h>
+#include <axis2_http_transport.h>
+#include "libcurl_stream.h"
+
+static int ref = 0;
+
+struct axis2_libcurl
+{
+ axis2_char_t *memory;
+ axutil_array_list_t *alist;
+ unsigned int size;
+ const axutil_env_t *env;
+ char errorbuffer[CURL_ERROR_SIZE];
+ CURL *handler;
+ axis2_bool_t cookies;
+};
+
+static size_t
+axis2_libcurl_write_memory_callback(
+ void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *data);
+
+static size_t
+axis2_libcurl_header_callback(
+ void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *data);
+
+static axis2_char_t *
+axis2_libcurl_get_content_type(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env);
+
+static int
+axis2_libcurl_get_content_length(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env);
+
+static axis2_http_header_t *
+axis2_libcurl_get_first_header(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env,
+ const axis2_char_t * str);
+
+static void
+axis2_libcurl_free_headers(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env);
+
+static axis2_status_t
+axis2_libcurl_set_options(
+ CURL *handler,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+axis2_status_t AXIS2_CALL
+axis2_libcurl_send(
+ axis2_libcurl_t *data,
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axiom_soap_envelope_t * out,
+ const axis2_char_t * str_url,
+ const axis2_char_t * soap_action)
+{
+ struct curl_slist *headers = NULL;
+ axiom_soap_body_t *soap_body;
+ axis2_bool_t is_soap = AXIS2_TRUE;
+ axis2_bool_t send_via_get = AXIS2_FALSE;
+ axis2_bool_t send_via_head = AXIS2_FALSE;
+ axis2_bool_t send_via_put = AXIS2_FALSE;
+ axis2_bool_t send_via_delete = AXIS2_FALSE;
+ axis2_bool_t doing_mtom = AXIS2_FALSE;
+ axiom_node_t *body_node = NULL;
+ axiom_node_t *data_out = NULL;
+ axutil_property_t *method = NULL;
+ axis2_char_t *method_value = NULL;
+ axiom_xml_writer_t *xml_writer = NULL;
+ axis2_char_t *buffer = NULL;
+ unsigned int buffer_size = 0;
+ int content_length = -1;
+ axis2_char_t *content_type = NULL;
+ axis2_char_t *content_len = AXIS2_HTTP_HEADER_CONTENT_LENGTH_;
+ const axis2_char_t *char_set_enc = NULL;
+ axis2_char_t *content = AXIS2_HTTP_HEADER_CONTENT_TYPE_;
+ axis2_char_t *soap_action_header = AXIS2_HTTP_HEADER_SOAP_ACTION_;
+ axutil_stream_t *in_stream;
+ axutil_property_t *trans_in_property;
+ axutil_string_t *char_set_enc_str;
+ axis2_byte_t *output_stream = NULL;
+ int output_stream_size = 0;
+ CURL *handler;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *write_xml_declaration_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+ axis2_bool_t write_xml_declaration = AXIS2_FALSE;
+ axutil_property_t *property;
+ int *response_length = NULL;
+ axis2_http_status_line_t *status_line = NULL;
+ axis2_char_t *status_line_str = NULL;
+ axis2_char_t *tmp_strcat = NULL;
+ int status_code = 0;
+
+ AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, data->handler, AXIS2_FAILURE);
+
+ handler = data->handler;
+ curl_easy_reset(handler);
+ curl_easy_setopt(handler, CURLOPT_ERRORBUFFER, &data->errorbuffer);
+ headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_USER_AGENT_AXIS2C);
+ headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_ACCEPT_);
+ headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_EXPECT_);
+
+ if(AXIS2_FAILURE == axis2_libcurl_set_options(handler, env, msg_ctx))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[axis2libcurl]Setting options in Libcurl failed");
+ return AXIS2_FAILURE;
+ }
+
+ if (AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ is_soap = AXIS2_FALSE;
+ }
+ else
+ {
+ is_soap = AXIS2_TRUE;
+ }
+
+ if (!is_soap)
+ {
+ soap_body = axiom_soap_envelope_get_body(out, env);
+ if (!soap_body)
+ {
+ AXIS2_HANDLE_ERROR(env,
+ AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL,
+ AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+
+ body_node = axiom_soap_body_get_base_node(soap_body, env);
+ if (!body_node)
+ {
+ AXIS2_HANDLE_ERROR(env,
+ AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL,
+ AXIS2_FAILURE);
+
+ return AXIS2_FAILURE;
+ }
+ data_out = axiom_node_get_first_element(body_node, env);
+
+ method = (axutil_property_t *) axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_HTTP_METHOD);
+
+ if (method)
+ {
+ method_value =
+ (axis2_char_t *) axutil_property_get_value(method, env);
+ }
+
+ /* The default is POST */
+ if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_GET))
+ {
+ send_via_get = AXIS2_TRUE;
+ }
+ else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_HEAD))
+ {
+ send_via_head = AXIS2_TRUE;
+ }
+ else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_PUT))
+ {
+ send_via_put = AXIS2_TRUE;
+ }
+ else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_DELETE))
+ {
+ send_via_delete = AXIS2_TRUE;
+ }
+ }
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx (msg_ctx, env);
+ if (conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf (conf_ctx, env);
+ }
+
+ if (conf)
+ {
+ trans_desc = axis2_conf_get_transport_out (conf,
+ env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+
+ if (trans_desc)
+ {
+ write_xml_declaration_param =
+ axutil_param_container_get_param
+ (axis2_transport_out_desc_param_container (trans_desc, env), env,
+ AXIS2_XML_DECLARATION);
+ }
+
+ if (write_xml_declaration_param)
+ {
+ transport_attrs =
+ axutil_param_get_attributes (write_xml_declaration_param, env);
+ if (transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *write_xml_declaration_attr = NULL;
+ axis2_char_t *write_xml_declaration_attr_value = NULL;
+
+ obj = axutil_hash_get (transport_attrs, AXIS2_ADD_XML_DECLARATION,
+ AXIS2_HASH_KEY_STRING);
+ if (obj)
+ {
+ write_xml_declaration_attr = (axiom_attribute_t *)
+ axutil_generic_obj_get_value (obj,
+ env);
+ }
+ if (write_xml_declaration_attr)
+ {
+ write_xml_declaration_attr_value =
+ axiom_attribute_get_value (write_xml_declaration_attr, env);
+ }
+ if (write_xml_declaration_attr_value &&
+ 0 == axutil_strcasecmp (write_xml_declaration_attr_value,
+ AXIS2_VALUE_TRUE))
+ {
+ write_xml_declaration = AXIS2_TRUE;
+ }
+ }
+ }
+
+ if (write_xml_declaration)
+ {
+ axiom_output_write_xml_version_encoding (om_output, env);
+ }
+
+ if (!send_via_get && !send_via_head && !send_via_delete)
+ {
+ xml_writer = axiom_output_get_xml_writer(om_output, env);
+
+ char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env);
+
+ if (!char_set_enc_str)
+ {
+ char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING;
+ }
+ else
+ {
+ char_set_enc = axutil_string_get_buffer(char_set_enc_str, env);
+ }
+
+ if (!send_via_put && is_soap)
+ {
+ doing_mtom = axis2_msg_ctx_get_doing_mtom(msg_ctx, env);
+
+ axiom_output_set_do_optimize(om_output, env, doing_mtom);
+ axiom_soap_envelope_serialize(out, env, om_output, AXIS2_FALSE);
+ if (AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ if (AXIS2_ESC_DOUBLE_QUOTE != *soap_action)
+ {
+ axis2_char_t *tmp_soap_action = NULL;
+ tmp_soap_action =
+ AXIS2_MALLOC(env->allocator,
+ (axutil_strlen(soap_action) +
+ 5) * sizeof(axis2_char_t));
+ sprintf(tmp_soap_action, "\"%s\"", soap_action);
+ tmp_strcat = axutil_stracat(env, soap_action_header,tmp_soap_action);
+ headers = curl_slist_append(headers, tmp_strcat);
+ AXIS2_FREE(env->allocator, tmp_strcat);
+ AXIS2_FREE(env->allocator, tmp_soap_action);
+ }
+ else
+ {
+ tmp_strcat = axutil_stracat(env, soap_action_header, soap_action);
+ headers = curl_slist_append(headers, tmp_strcat );
+ AXIS2_FREE(env->allocator, tmp_strcat);
+ }
+ }
+
+ if (doing_mtom)
+ {
+ /*axiom_output_flush(om_output, env, &output_stream,
+ &output_stream_size);*/
+ axiom_output_flush(om_output, env);
+ content_type =
+ (axis2_char_t *) axiom_output_get_content_type(om_output,
+ env);
+ if (AXIS2_TRUE != axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ if (axutil_strcmp(soap_action, ""))
+ {
+ /* handle SOAP action for SOAP 1.2 case */
+ axis2_char_t *temp_content_type = NULL;
+ temp_content_type = axutil_stracat (env,
+ content_type,
+ AXIS2_CONTENT_TYPE_ACTION);
+ content_type = temp_content_type;
+ temp_content_type = axutil_stracat (env,
+ content_type,
+ soap_action);
+ AXIS2_FREE (env->allocator, content_type);
+ content_type = temp_content_type;
+ temp_content_type =
+ axutil_stracat (env, content_type,
+ AXIS2_ESC_DOUBLE_QUOTE_STR);
+ AXIS2_FREE (env->allocator, content_type);
+ content_type = temp_content_type;
+ }
+ }
+ }
+ else if (AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ axis2_char_t *temp_content_type = NULL;
+ content_type =
+ (axis2_char_t *) AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
+ content_type = axutil_stracat(env, content_type,
+ AXIS2_CONTENT_TYPE_CHARSET);
+ temp_content_type =
+ axutil_stracat(env, content_type, char_set_enc);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ }
+ else
+ {
+ axis2_char_t *temp_content_type = NULL;
+ content_type =
+ (axis2_char_t *) AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP;
+ content_type = axutil_stracat(env, content_type,
+ AXIS2_CONTENT_TYPE_CHARSET);
+ temp_content_type =
+ axutil_stracat(env, content_type, char_set_enc);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ if (axutil_strcmp(soap_action, ""))
+ {
+ temp_content_type =
+ axutil_stracat(env, content_type,
+ AXIS2_CONTENT_TYPE_ACTION);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ temp_content_type =
+ axutil_stracat(env, content_type, soap_action);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ }
+ temp_content_type = axutil_stracat(env, content_type,
+ AXIS2_SEMI_COLON_STR);
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = temp_content_type;
+ }
+ }
+ else if (is_soap)
+ {
+ AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI, "Attempt to send SOAP"
+ "message using HTTP PUT failed");
+ return AXIS2_FAILURE;
+ }
+ else
+ {
+ axutil_property_t *content_type_property = NULL;
+ axutil_hash_t *content_type_hash = NULL;
+ axis2_char_t *content_type_value = NULL;
+
+ axiom_node_serialize(data_out, env, om_output);
+ content_type_property =
+ (axutil_property_t *)
+ axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_USER_DEFINED_HTTP_HEADER_CONTENT_TYPE);
+
+ if (content_type_property)
+ {
+ content_type_hash =
+ (axutil_hash_t *)
+ axutil_property_get_value(content_type_property, env);
+
+ if (content_type_hash)
+ {
+ content_type_value =
+ (char *) axutil_hash_get(content_type_hash,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ AXIS2_HASH_KEY_STRING);
+ }
+ }
+
+ if (content_type_value)
+ {
+ content_type = content_type_value;
+ }
+ else
+ {
+ content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
+ }
+
+ }
+
+ buffer = axiom_xml_writer_get_xml(xml_writer, env);
+ if (!doing_mtom)
+ {
+ buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env);
+ }
+ else
+ buffer_size = output_stream_size;
+ {
+ char tmp_buf[10];
+ sprintf(tmp_buf, "%d", buffer_size);
+ tmp_strcat = axutil_stracat(env, content_len, tmp_buf);
+ headers = curl_slist_append(headers, tmp_strcat);
+ AXIS2_FREE(env->allocator, tmp_strcat);
+ tmp_strcat = NULL;
+
+ tmp_strcat = axutil_stracat(env, content, content_type);
+ headers = curl_slist_append(headers, tmp_strcat);
+ AXIS2_FREE(env->allocator, tmp_strcat);
+ tmp_strcat = NULL;
+ }
+
+ if (!doing_mtom)
+ {
+ curl_easy_setopt(handler, CURLOPT_POSTFIELDSIZE, buffer_size);
+ curl_easy_setopt(handler, CURLOPT_POSTFIELDS, buffer);
+ }
+ else
+ {
+ curl_easy_setopt(handler, CURLOPT_POSTFIELDSIZE,
+ output_stream_size);
+ curl_easy_setopt(handler, CURLOPT_POSTFIELDS, output_stream);
+ }
+
+ if (send_via_put)
+ {
+ curl_easy_setopt(handler, CURLOPT_CUSTOMREQUEST, AXIS2_HTTP_PUT);
+ }
+ curl_easy_setopt(handler, CURLOPT_URL, str_url);
+ }
+ else
+ {
+ axis2_char_t *request_param;
+ axis2_char_t *url_encode;
+ request_param =
+ (axis2_char_t *) axis2_http_sender_get_param_string(NULL, env,
+ msg_ctx);
+ url_encode = axutil_strcat(env, str_url, AXIS2_Q_MARK_STR,
+ request_param, NULL);
+ if (send_via_get)
+ {
+ curl_easy_setopt(handler, CURLOPT_HTTPGET, 1);
+ }
+ else if (send_via_head)
+ {
+ curl_easy_setopt(handler, CURLOPT_NOBODY, 1);
+ }
+ else if (send_via_delete)
+ {
+ curl_easy_setopt(handler, CURLOPT_CUSTOMREQUEST, AXIS2_HTTP_DELETE);
+ }
+ curl_easy_setopt(handler, CURLOPT_URL, url_encode);
+ }
+
+ {
+ axis2_bool_t manage_session;
+ manage_session = axis2_msg_ctx_get_manage_session(msg_ctx, env);
+ if (manage_session == AXIS2_TRUE)
+ {
+ if (data->cookies == AXIS2_FALSE)
+ {
+ /* Ensure cookies enabled to manage session */
+ /* Pass empty cookie string to enable cookies */
+ curl_easy_setopt(handler, CURLOPT_COOKIEFILE, " ");
+ data->cookies = AXIS2_TRUE;
+ }
+ }
+ else if (data->cookies == AXIS2_TRUE)
+ {
+ /* Pass special string ALL to reset cookies if any have been enabled. */
+ /* If cookies have ever been enabled, we reset every time as long as
+ manage_session is false, as there is no clear curl option to
+ turn off the cookie engine once enabled. */
+ curl_easy_setopt(handler, CURLOPT_COOKIELIST, AXIS2_ALL);
+ }
+ }
+
+ curl_easy_setopt(handler, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(handler, CURLOPT_WRITEFUNCTION,
+ axis2_libcurl_write_memory_callback);
+ curl_easy_setopt(handler, CURLOPT_WRITEDATA, data);
+
+ curl_easy_setopt (handler, CURLOPT_HEADERFUNCTION, axis2_libcurl_header_callback);
+
+ curl_easy_setopt (handler, CURLOPT_WRITEHEADER, data);
+
+ /* Free response data from previous request */
+ if( data->size )
+ {
+ if (data->memory)
+ {
+ AXIS2_FREE(data->env->allocator, data->memory);
+ }
+ data->size = 0;
+ }
+
+ if (curl_easy_perform(handler))
+ {
+ AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI, "%s", &data->errorbuffer);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR,
+ AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+
+ in_stream = axutil_stream_create_libcurl(env, data->memory, data->size);
+ trans_in_property = axutil_property_create(env);
+ axutil_property_set_scope(trans_in_property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_free_func(trans_in_property, env,
+ libcurl_stream_free);
+ axutil_property_set_value(trans_in_property, env, in_stream);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN,
+ trans_in_property);
+
+ if (axutil_array_list_size(data->alist, env) > 0)
+ {
+ status_line_str = axutil_array_list_get(data->alist, env, 0);
+ if (status_line_str)
+ {
+ status_line = axis2_http_status_line_create(env, status_line_str);
+ }
+ }
+
+ if (status_line)
+ {
+ status_code = axis2_http_status_line_get_status_code(status_line, env);
+ }
+
+ axis2_msg_ctx_set_status_code (msg_ctx, env, status_code);
+ AXIS2_FREE(data->env->allocator, content_type);
+ content_type = axis2_libcurl_get_content_type(data, env);
+
+ if (content_type)
+ {
+ if (strstr (content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED)
+ && strstr (content_type, AXIS2_HTTP_HEADER_ACCEPT_XOP_XML))
+ {
+ axis2_ctx_t *axis_ctx =
+ axis2_op_ctx_get_base (axis2_msg_ctx_get_op_ctx (msg_ctx, env),
+ env);
+ property = axutil_property_create (env);
+ axutil_property_set_scope (property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value (property,
+ env, axutil_strdup (env, content_type));
+ axis2_ctx_set_property (axis_ctx,
+ env, MTOM_RECIVED_CONTENT_TYPE, property);
+ }
+ }
+
+ content_length = axis2_libcurl_get_content_length(data, env);
+ if (content_length >= 0)
+ {
+ response_length = AXIS2_MALLOC (env->allocator, sizeof (int));
+ memcpy (response_length, &content_length, sizeof (int));
+ property = axutil_property_create (env);
+ axutil_property_set_scope (property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value (property, env, response_length);
+ axis2_msg_ctx_set_property (msg_ctx, env,
+ AXIS2_HTTP_HEADER_CONTENT_LENGTH, property);
+ }
+
+ curl_slist_free_all (headers);
+ /* release the read http headers. */
+ /* (commenting out the call below is a clever way to force a premature EOF
+ condition in subsequent messages, as they will be read using the content-length
+ of the first message.) */
+ axis2_libcurl_free_headers(data, env);
+ AXIS2_FREE(data->env->allocator, content_type);
+ axis2_http_status_line_free( status_line, env);
+
+ return AXIS2_SUCCESS;
+}
+
+static size_t
+axis2_libcurl_write_memory_callback(
+ void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *data)
+{
+ size_t realsize = size * nmemb;
+ axis2_libcurl_t *curl = (axis2_libcurl_t *) data;
+ axis2_char_t *buffer =
+ (axis2_char_t *) AXIS2_MALLOC(curl->env->allocator,
+ curl->size + realsize + 1);
+ if (buffer)
+ {
+ if (curl->size)
+ {
+ memcpy(&(buffer[0]), curl->memory, curl->size);
+ AXIS2_FREE(curl->env->allocator, curl->memory);
+ }
+
+ memcpy(&(buffer[curl->size]), ptr, realsize);
+ curl->size += (int)realsize;
+ /* We are sure that the difference lies within the int range */
+ buffer[curl->size] = 0;
+ curl->memory = buffer;
+ }
+ return realsize;
+}
+
+static size_t
+axis2_libcurl_header_callback(
+ void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *data)
+{
+ axis2_char_t *memory;
+ size_t realsize = size * nmemb;
+ axis2_libcurl_t *curl = (axis2_libcurl_t *) data;
+ memory = (axis2_char_t *)AXIS2_MALLOC(curl->env->allocator, realsize + 1);
+ if (memory)
+ {
+ memcpy(&(memory[0]), ptr, realsize);
+ memory[realsize] = 0;
+ axutil_array_list_add(curl->alist, curl->env, memory);
+ }
+ return realsize;
+}
+
+axis2_libcurl_t * AXIS2_CALL
+axis2_libcurl_create(
+ const axutil_env_t * env)
+{
+ axis2_libcurl_t *curl = NULL;
+ CURLcode code;
+
+ if (!ref)
+ {
+ /* curl_global_init is not thread-safe so it would be better
+ to do this, as well as the test and increment of ref, under
+ mutex if one is available, or as part of an
+ axis2_initialize() if a global initialize is created.
+ Otherwise the client application should perform the the
+ curl_global_init itself in a thread-safe fashion.
+ */
+ code = curl_global_init(CURL_GLOBAL_ALL);
+ if (code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "libcurl curl_global_init failed, error: %d", code);
+ return NULL;
+ }
+ ref++;
+ }
+
+ curl =
+ (axis2_libcurl_t *) AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_libcurl_t));
+ if (curl)
+ {
+ curl->memory = 0;
+ curl->size = 0;
+ curl->alist = axutil_array_list_create(env, 15);
+ curl->env = env;
+ curl->handler = curl_easy_init();
+ curl->cookies = AXIS2_FALSE;
+ if ((!curl->alist) || (!curl->handler))
+ {
+ axis2_libcurl_free(curl, env);
+ curl = 0;
+ }
+ }
+ return curl;
+}
+
+void AXIS2_CALL
+axis2_libcurl_free(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env)
+{
+ if (!curl)
+ {
+ return;
+ }
+
+ if (curl->handler)
+ {
+ curl_easy_cleanup (curl->handler);
+ }
+ if (curl->alist)
+ {
+ axis2_libcurl_free_headers(curl, env);
+ axutil_array_list_free(curl->alist, env);
+ curl->alist = NULL;
+ }
+ if (curl->memory)
+ {
+ AXIS2_FREE(env->allocator, curl->memory);
+ }
+
+ AXIS2_FREE(env->allocator, curl);
+}
+
+static void
+axis2_libcurl_free_headers(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env)
+{
+ int count = 0;
+ axutil_array_list_t *header_group = curl->alist;
+ if (header_group)
+ {
+ while ((count = axutil_array_list_size(header_group, env)) > 0)
+ {
+ axis2_char_t *header = axutil_array_list_remove(header_group, env, count-1);
+ AXIS2_FREE(env->allocator, header);
+ }
+ }
+}
+
+static axis2_http_header_t *
+axis2_libcurl_get_first_header(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env,
+ const axis2_char_t * str)
+{
+ axis2_http_header_t *tmp_header = NULL;
+ axis2_char_t *tmp_header_str = NULL;
+ axis2_char_t *tmp_name = NULL;
+ int i = 0;
+ int count = 0;
+ axutil_array_list_t *header_group = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, curl, NULL);
+ AXIS2_PARAM_CHECK(env->error, str, NULL);
+
+ header_group = curl->alist;
+ if (!header_group)
+ {
+ return NULL;
+ }
+
+ if (0 == axutil_array_list_size(header_group, env))
+ {
+ return NULL;
+ }
+
+ count = axutil_array_list_size(header_group, env);
+
+ for (i = 0; i < count; i++)
+ {
+ tmp_header_str = (axis2_char_t *) axutil_array_list_get(header_group,
+ env, i);
+ if(!tmp_header_str)
+ {
+ continue;
+ }
+ tmp_header = (axis2_http_header_t *) axis2_http_header_create_by_str(env, tmp_header_str);
+ if(!tmp_header)
+ {
+ continue;
+ }
+
+ tmp_name = axis2_http_header_get_name(tmp_header, env);
+ if (0 == axutil_strcasecmp(str, tmp_name))
+ {
+ return tmp_header;
+ }
+ else
+ {
+ axis2_http_header_free( tmp_header, env );
+ }
+
+ }
+ return NULL;
+}
+
+static int
+axis2_libcurl_get_content_length(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env)
+{
+ axis2_http_header_t *tmp_header;
+ int rtn_value = -1;
+
+ tmp_header = axis2_libcurl_get_first_header
+ (curl, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH);
+ if (tmp_header)
+ {
+ rtn_value = AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env));
+ axis2_http_header_free( tmp_header, env );
+ }
+ return rtn_value;
+}
+
+static axis2_char_t *
+axis2_libcurl_get_content_type(
+ axis2_libcurl_t *curl,
+ const axutil_env_t * env)
+{
+ axis2_http_header_t *tmp_header;
+ axis2_char_t *rtn_value = NULL;
+
+ tmp_header = axis2_libcurl_get_first_header
+ (curl, env, AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if (tmp_header)
+ {
+ rtn_value = axutil_strdup (env, axis2_http_header_get_value(tmp_header, env) );
+ axis2_http_header_free( tmp_header, env );
+ }
+ else
+ {
+ rtn_value = axutil_strdup (env, AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN);
+ }
+
+ return rtn_value;
+}
+
+/**
+ * axis2_libcurl_set_auth_options maps authentication AXIS2/C options to
+ * libcURL options.
+ *
+ * CURLOPT_USERPWD - char * user:password for authentication
+ * CURLOPT_HTTPAUTH - long bitmask which authentication methods to use
+ */
+static axis2_status_t
+axis2_libcurl_set_auth_options(
+ CURL *handler,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axutil_property_t *property = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+ axis2_char_t *auth_type = NULL;
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME);
+ if (property)
+ {
+ uname = (axis2_char_t *) axutil_property_get_value(property, env);
+ }
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD);
+ if (property)
+ {
+ passwd = (axis2_char_t *) axutil_property_get_value(property, env);
+ }
+ if (uname && passwd)
+ {
+ axis2_char_t buffer[256];
+ strncpy(buffer, uname, 256);
+ strncat(buffer, ":", 256);
+ strncat(buffer, passwd, 256);
+ curl_easy_setopt(handler, CURLOPT_USERPWD, buffer);
+ }
+
+ property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE);
+
+ if (property)
+ {
+ auth_type = (axis2_char_t *) axutil_property_get_value(property, env);
+ }
+
+ if (auth_type && 0 == axutil_strcmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC))
+ {
+ curl_easy_setopt(handler, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ }
+ else
+ {
+ /* Uses anonymous connection.*/
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * axis2_libcurl_set_proxy_options maps proxy AXIS2/C options to
+ * libcURL options.
+ *
+ * CURLOPT_PROXY - char * proxy hostname
+ * CURLOPT_PROXYPORT - long proxy listen port
+ * CURLOPT_PROXYUSERPWD - char * user:password to authenticate to proxy
+ *
+ * TODO:
+ * CURLOPT_PROXYTYPE - long enum type of proxy (HTTP, SOCKS)
+ * CURLOPT_PROXYAUTH - long bitmask which authentication methods to use for proxy
+ */
+static axis2_status_t
+axis2_libcurl_set_proxy_options(
+ CURL *handler,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *proxy_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+ axutil_property_t *property = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+ axis2_char_t *proxy_host = NULL;
+ axis2_char_t *proxy_port = NULL;
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME);
+ if (property)
+ {
+ uname = (axis2_char_t *) axutil_property_get_value(property, env);
+ }
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD);
+ if (property)
+ {
+ passwd = (axis2_char_t *) axutil_property_get_value(property, env);
+ }
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if (conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if (conf)
+ {
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+ }
+ if (trans_desc)
+ {
+ proxy_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_HTTP_PROXY_API);
+ if (!proxy_param)
+ {
+ proxy_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_HTTP_PROXY);
+ }
+ if (proxy_param)
+ {
+ transport_attrs = axutil_param_get_attributes(proxy_param, env);
+ }
+ }
+
+ if (transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *attr = NULL;
+
+ if (!uname || !passwd)
+ {
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME, AXIS2_HASH_KEY_STRING);
+ if (obj)
+ {
+ attr = (axiom_attribute_t *) axutil_generic_obj_get_value(obj, env);
+ }
+ if (attr)
+ {
+ uname = axiom_attribute_get_value(attr, env);
+ }
+
+ attr = NULL;
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD, AXIS2_HASH_KEY_STRING);
+ if (obj)
+ {
+ attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if (attr)
+ {
+ passwd = axiom_attribute_get_value(attr, env);
+ }
+ }
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING);
+ if (obj)
+ {
+ attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if (attr)
+ {
+ proxy_host = axiom_attribute_get_value(attr, env);
+ }
+ if (proxy_host)
+ {
+ curl_easy_setopt(handler, CURLOPT_PROXY, proxy_host);
+ }
+
+ attr = NULL;
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING);
+ if (obj)
+ {
+ attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if (attr)
+ {
+ proxy_port = axiom_attribute_get_value(attr, env);
+ }
+ if (proxy_port)
+ {
+ curl_easy_setopt(handler, CURLOPT_PROXYPORT, AXIS2_ATOI(proxy_port));
+ }
+ }
+ if (uname && passwd)
+ {
+ axis2_char_t buffer[256];
+ strncpy(buffer, uname, 256);
+ strncat(buffer, ":", 256);
+ strncat(buffer, passwd, 256);
+ curl_easy_setopt(handler, CURLOPT_PROXYUSERPWD, buffer);
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * axis2_libcurl_set_ssl_options maps SSL AXIS2/C options to
+ * libcURL options.
+ *
+ * CURLOPT_SSL_VERIFYHOST - long enum whether to verify the server identity
+ * CURLOPT_SSL_VERIFYPEER - long boolean whether to verify the server certificate
+ */
+static axis2_status_t
+axis2_libcurl_set_ssl_options(
+ CURL *handler,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axutil_property_t *property = NULL;
+ axis2_char_t *verify_peer = NULL;
+ axis2_char_t *verify_host = NULL;
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_VERIFY_PEER);
+ if (property)
+ {
+ verify_peer = (axis2_char_t *)axutil_property_get_value(property, env);
+ }
+ if (verify_peer)
+ {
+ if (0 == axutil_strcasecmp(verify_peer, AXIS2_VALUE_TRUE))
+ {
+ curl_easy_setopt(handler, CURLOPT_SSL_VERIFYPEER, 1);
+ }
+ else
+ {
+ curl_easy_setopt(handler, CURLOPT_SSL_VERIFYPEER, 0);
+ }
+ }
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_VERIFY_HOST);
+ if (property)
+ {
+ verify_host = (axis2_char_t *)axutil_property_get_value(property, env);
+ }
+ if (verify_host)
+ {
+ curl_easy_setopt(handler, CURLOPT_SSL_VERIFYHOST, AXIS2_ATOI(verify_host));
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * axis2_libcurl_set_connection_options maps connection AXIS2/C options to
+ * libcURL options.
+ * CURLOPT_CONNECTTIMEOUT_MS - long connection timeout in milliseconds
+ * CURLOPT_TIMEOUT_MS - long transfer timeout in milliseconds
+ */
+static axis2_status_t
+axis2_libcurl_set_connection_options(
+ CURL *handler,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axutil_property_t *property = NULL;
+ long long_property_value = 0;
+
+ /* check if timeout has been set by user using options
+ * with axis2_options_set_timeout_in_milli_seconds
+ */
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_CONNECTION_TIMEOUT);
+ if (property)
+ {
+ axis2_char_t *value = axutil_property_get_value(property, env);
+ if (value)
+ {
+ long_property_value = AXIS2_ATOI(value);
+ curl_easy_setopt(handler, CURLOPT_CONNECTTIMEOUT_MS, long_property_value);
+ }
+ }
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_SO_TIMEOUT);
+ if (property)
+ {
+ axis2_char_t *value = axutil_property_get_value(property, env);
+ if (value)
+ {
+ long_property_value = AXIS2_ATOI(value);
+ curl_easy_setopt(handler, CURLOPT_TIMEOUT_MS, long_property_value);
+ }
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+/**
+ * axis2_libcurl_set_options maps the AXIS2/C options to libcURL options.
+ */
+static axis2_status_t
+axis2_libcurl_set_options(
+ CURL *handler,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ if (axis2_libcurl_set_auth_options(handler, env, msg_ctx) != AXIS2_SUCCESS)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ if (axis2_libcurl_set_proxy_options(handler, env, msg_ctx) != AXIS2_SUCCESS)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ if (axis2_libcurl_set_ssl_options(handler, env, msg_ctx) != AXIS2_SUCCESS)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ if (axis2_libcurl_set_connection_options(handler, env, msg_ctx) != AXIS2_SUCCESS)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+
+#endif /* AXIS2_LIBCURL_ENABLED */
+
diff --git a/src/core/transport/http/sender/libcurl/axis2_libcurl.h b/src/core/transport/http/sender/libcurl/axis2_libcurl.h
new file mode 100644
index 0000000..f2971e5
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/axis2_libcurl.h
@@ -0,0 +1,53 @@
+/*
+ * 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_LIBCURL_H
+#define AXIS2_LIBCURL_H
+#include <curl/curl.h>
+#include <stdio.h>
+#include <string.h>
+#include <axis2_http_sender.h>
+#include <axutil_string.h>
+#include <axutil_types.h>
+#include <axutil_generic_obj.h>
+#include <axis2_const.h>
+#include <axis2_util.h>
+#include <axiom.h>
+
+/* typedef struct axis2_libcurl axis2_libcurl_t; */
+/* actually defined in axis2_http_sender.h as it is part of axis2/include */
+
+AXIS2_EXTERN axis2_libcurl_t *AXIS2_CALL
+axis2_libcurl_create(
+ const axutil_env_t * env);
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_libcurl_free(
+ axis2_libcurl_t *data,
+ const axutil_env_t * env);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_libcurl_send(
+ axis2_libcurl_t *data,
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axiom_soap_envelope_t * out,
+ const axis2_char_t * str_url,
+ const axis2_char_t * soap_action);
+
+#endif /* AXIS2_LIBCURL_H */
diff --git a/src/core/transport/http/sender/libcurl/libcurl_stream.c b/src/core/transport/http/sender/libcurl/libcurl_stream.c
new file mode 100644
index 0000000..0c9126d
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/libcurl_stream.c
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+#ifdef AXIS2_LIBCURL_ENABLED
+
+#include "libcurl_stream.h"
+#include <string.h>
+
+typedef struct libcurl_stream_impl
+{
+ axutil_stream_t stream;
+ axutil_stream_type_t stream_type;
+ axis2_char_t *buffer;
+ int size;
+ int read_len;
+}
+libcurl_stream_impl_t;
+
+#define AXIS2_INTF_TO_IMPL(stream) ((libcurl_stream_impl_t *)(stream))
+
+/********************************Function headers******************************/
+axutil_stream_type_t AXIS2_CALL libcurl_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+int AXIS2_CALL libcurl_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count);
+
+int AXIS2_CALL libcurl_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count);
+
+int AXIS2_CALL libcurl_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count);
+
+int AXIS2_CALL libcurl_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+/************************* End of function headers ****************************/
+
+/*
+ * Internal function. Not exposed to outside
+ */
+AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+axutil_stream_create_libcurl(
+ const axutil_env_t * env,
+ axis2_char_t * buffer,
+ unsigned int size)
+{
+ libcurl_stream_impl_t *stream_impl = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, buffer, NULL);
+
+ stream_impl =
+ (libcurl_stream_impl_t *) AXIS2_MALLOC(env->allocator,
+ sizeof(libcurl_stream_impl_t));
+
+ if (!stream_impl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ stream_impl->buffer = buffer;
+ stream_impl->size = size;
+ stream_impl->read_len = 0;
+ stream_impl->stream_type = AXIS2_STREAM_MANAGED;
+
+ axutil_stream_set_read(&(stream_impl->stream), env, libcurl_stream_read);
+ axutil_stream_set_write(&(stream_impl->stream), env, libcurl_stream_write);
+ axutil_stream_set_skip(&(stream_impl->stream), env, libcurl_stream_skip);
+
+ return &(stream_impl->stream);
+}
+
+void AXIS2_CALL
+libcurl_stream_free(
+ void * stream,
+ const axutil_env_t * env)
+{
+ libcurl_stream_impl_t *stream_impl = NULL;
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ AXIS2_FREE(env->allocator, stream_impl);
+
+ return;
+}
+
+int AXIS2_CALL
+libcurl_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count)
+{
+ libcurl_stream_impl_t *stream_impl = NULL;
+ int read = 0;
+ int unread = 0;
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ if (stream_impl->size >= (int)count)
+ /* We are sure that the difference lies within the int range */
+ {
+ if (buffer && (stream_impl->size > stream_impl->read_len))
+ {
+ unread = (stream_impl->size - stream_impl->read_len);
+ if (unread > (int)count)
+ /* We are sure that the difference lies within the int range */
+ {
+ memcpy(buffer, &stream_impl->buffer[stream_impl->read_len],
+ count);
+ read = (int)count;
+ /* We are sure that the difference lies within the int range */
+ stream_impl->read_len += read;
+ }
+ else
+ {
+ memcpy(buffer, &stream_impl->buffer[stream_impl->read_len],
+ unread);
+ read = unread;
+ stream_impl->read_len += read;
+ }
+ }
+ else
+ read = 0;
+ }
+ else
+ {
+ if (buffer && (stream_impl->size > stream_impl->read_len))
+ {
+ memcpy(buffer, &stream_impl->buffer[stream_impl->read_len],
+ stream_impl->size - stream_impl->read_len);
+ read = stream_impl->size - stream_impl->read_len;
+ stream_impl->read_len += read;
+ }
+ else
+ read = 0;
+ }
+ return read;
+}
+
+int AXIS2_CALL
+libcurl_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count)
+{
+ return (int)count;
+ /* We are sure that the difference lies within the int range */
+}
+
+int AXIS2_CALL
+libcurl_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count)
+{
+ return 0;
+}
+
+int AXIS2_CALL
+libcurl_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ return 0;
+}
+
+#endif /* AXIS2_LIBCURL_ENABLED */
+
diff --git a/src/core/transport/http/sender/libcurl/libcurl_stream.h b/src/core/transport/http/sender/libcurl/libcurl_stream.h
new file mode 100644
index 0000000..8a24fcc
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/libcurl_stream.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 LIBCURL_STREAM_H
+#define LIBCURL_STREAM_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /** brief Constructor for creating apche2 stream
+ * @return axutil_stream (libcurl)
+ */
+ AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+ axutil_stream_create_libcurl(
+ const axutil_env_t * env,
+ axis2_char_t * buffer,
+ unsigned int size);
+
+ /** @} */
+
+ void AXIS2_CALL libcurl_stream_free(
+ void * stream,
+ const axutil_env_t * env);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBCURL_STREAM_H */
diff --git a/src/core/transport/http/sender/ssl/Makefile.am b/src/core/transport/http/sender/ssl/Makefile.am
new file mode 100644
index 0000000..3e457e5
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST= ssl_stream.c ssl_stream.h ssl_utils.c ssl_utils.h
+
diff --git a/src/core/transport/http/sender/ssl/ssl_stream.c b/src/core/transport/http/sender/ssl/ssl_stream.c
new file mode 100644
index 0000000..9360f1a
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/ssl_stream.c
@@ -0,0 +1,239 @@
+/*
+ * 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.
+ */
+#ifdef AXIS2_SSL_ENABLED
+
+#include <string.h>
+#include <stdlib.h>
+#include "ssl_stream.h"
+#include "ssl_utils.h"
+
+/**
+ * @brief Stream struct impl
+ * Streaming mechanisms for SSL
+ */
+typedef struct ssl_stream_impl ssl_stream_impl_t;
+
+struct ssl_stream_impl
+{
+ axutil_stream_t stream;
+ axutil_stream_type_t stream_type;
+ SSL *ssl;
+ SSL_CTX *ctx;
+ axis2_socket_t socket;
+};
+
+#define AXIS2_INTF_TO_IMPL(stream) ((ssl_stream_impl_t *)(stream))
+
+void AXIS2_CALL axis2_ssl_stream_free(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+axutil_stream_type_t AXIS2_CALL axis2_ssl_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+int AXIS2_CALL axis2_ssl_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count);
+
+int AXIS2_CALL axis2_ssl_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count);
+
+int AXIS2_CALL axis2_ssl_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count);
+
+int AXIS2_CALL axis2_ssl_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+axutil_stream_create_ssl(
+ const axutil_env_t * env,
+ axis2_socket_t socket,
+ axis2_char_t * server_cert,
+ axis2_char_t * key_file,
+ axis2_char_t * ssl_pp)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+
+ stream_impl =
+ (ssl_stream_impl_t *) AXIS2_MALLOC(env->allocator,
+ sizeof(ssl_stream_impl_t));
+
+ if (!stream_impl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset ((void *)stream_impl, 0, sizeof (ssl_stream_impl_t));
+ stream_impl->socket = socket;
+ stream_impl->ctx = NULL;
+ stream_impl->ssl = NULL;
+
+ stream_impl->ctx = axis2_ssl_utils_initialize_ctx(env, server_cert,
+ key_file, ssl_pp);
+ if (!stream_impl->ctx)
+ {
+ axis2_ssl_stream_free((axutil_stream_t *) stream_impl, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ stream_impl->ssl = axis2_ssl_utils_initialize_ssl(env, stream_impl->ctx,
+ stream_impl->socket);
+ if (!stream_impl->ssl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ stream_impl->stream_type = AXIS2_STREAM_MANAGED;
+
+ axutil_stream_set_read(&(stream_impl->stream), env, axis2_ssl_stream_read);
+ axutil_stream_set_write(&(stream_impl->stream), env,
+ axis2_ssl_stream_write);
+ axutil_stream_set_skip(&(stream_impl->stream), env, axis2_ssl_stream_skip);
+
+ return &(stream_impl->stream);
+}
+
+void AXIS2_CALL
+axis2_ssl_stream_free(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ axis2_ssl_utils_cleanup_ssl(env, stream_impl->ctx, stream_impl->ssl);
+ AXIS2_FREE(env->allocator, stream_impl);
+
+ return;
+}
+
+int AXIS2_CALL
+axis2_ssl_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+ int read = -1;
+ int len = -1;
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+
+ SSL_set_mode(stream_impl->ssl, SSL_MODE_AUTO_RETRY);
+
+ read = SSL_read(stream_impl->ssl, buffer, (int)count);
+ /* We are sure that the difference lies within the int range */
+ switch (SSL_get_error(stream_impl->ssl, read))
+ {
+ case SSL_ERROR_NONE:
+ len = read;
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ len = -1;
+ break;
+ case SSL_ERROR_SYSCALL:
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "SSL Error: Premature close");
+ len = -1;
+ break;
+ default:
+ len = -1;
+ break;
+ }
+ return len;
+}
+
+int AXIS2_CALL
+axis2_ssl_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buf,
+ size_t count)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+ int write = -1;
+
+ AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE);
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ write = SSL_write(stream_impl->ssl, buf, (int)count);
+ /* We are sure that the difference lies within the int range */
+
+ switch (SSL_get_error(stream_impl->ssl, write))
+ {
+ case SSL_ERROR_NONE:
+ if ((int)count != write)
+ /* We are sure that the difference lies within the int range */
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Incomplete SSL write!");
+ break;
+ default:
+ return -1;
+ }
+ return write;
+}
+
+int AXIS2_CALL
+axis2_ssl_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+ axis2_char_t *tmp_buffer = NULL;
+ int len = -1;
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+
+ tmp_buffer = AXIS2_MALLOC(env->allocator, count * sizeof(axis2_char_t));
+ if (tmp_buffer == NULL)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return -1;
+ }
+ len = SSL_read(stream_impl->ssl, tmp_buffer, count);
+ AXIS2_FREE(env->allocator, tmp_buffer);
+ return len;
+
+}
+
+int AXIS2_CALL
+axis2_ssl_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ int ret = -1;
+
+ return ret;
+}
+
+axutil_stream_type_t AXIS2_CALL
+axis2_ssl_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ return AXIS2_INTF_TO_IMPL(stream)->stream_type;
+}
+
+#endif
+
diff --git a/src/core/transport/http/sender/ssl/ssl_stream.h b/src/core/transport/http/sender/ssl/ssl_stream.h
new file mode 100644
index 0000000..396da5d
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/ssl_stream.h
@@ -0,0 +1,50 @@
+
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain count 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_SSL_STREAM_H
+#define AXIS2_SSL_STREAM_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+#include <platforms/axutil_platform_auto_sense.h>
+#include <openssl/ssl.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /** \brief Constructor for creating ssl stream
+ * @return axutil_stream (ssl)
+ */
+ AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+ axutil_stream_create_ssl(
+ const axutil_env_t * env,
+ axis2_socket_t socket,
+ axis2_char_t * server_cert,
+ axis2_char_t * key_file,
+ axis2_char_t * ssl_pp);
+
+ /** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AXIS2_SSL_STREAM_H */
diff --git a/src/core/transport/http/sender/ssl/ssl_utils.c b/src/core/transport/http/sender/ssl/ssl_utils.c
new file mode 100644
index 0000000..d565555
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/ssl_utils.c
@@ -0,0 +1,227 @@
+/*
+ * 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.
+ */
+#ifdef AXIS2_SSL_ENABLED
+
+#include "ssl_utils.h"
+#include <openssl/err.h>
+BIO *bio_err = 0;
+
+static int
+password_cb(
+ char *buf,
+ int size,
+ int rwflag,
+ void *passwd)
+{
+ strncpy(buf, (char *) passwd, size);
+ buf[size - 1] = '\0';
+ return (int)(strlen(buf));
+ /* We are sure that the difference lies within the int range */
+}
+
+AXIS2_EXTERN SSL_CTX *AXIS2_CALL
+axis2_ssl_utils_initialize_ctx(
+ const axutil_env_t * env,
+ axis2_char_t * server_cert,
+ axis2_char_t * key_file,
+ axis2_char_t * ssl_pp)
+{
+ SSL_METHOD *meth = NULL;
+ SSL_CTX *ctx = NULL;
+ axis2_char_t *ca_file = server_cert;
+
+ if (!ca_file)
+ {
+ AXIS2_LOG_INFO(env->log, "[ssl client] CA certificate not specified");
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_NO_CA_FILE, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ if (!bio_err)
+ {
+ /* Global system initialization */
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ /* An error write context */
+ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+ }
+
+ /* Create our context */
+ meth = SSLv23_method();
+ ctx = SSL_CTX_new(meth);
+
+ /* Load our keys and certificates
+ * If we need client certificates it has to be done here
+ */
+ if (key_file) /*can we check if the server needs client auth? */
+ {
+ if (!ssl_pp)
+ {
+ AXIS2_LOG_INFO(env->log,
+ "[ssl client] No passphrase specified for \
+key file %s and server cert %s", key_file, server_cert);
+ }
+
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) ssl_pp);
+ SSL_CTX_set_default_passwd_cb(ctx, password_cb);
+
+ if (!(SSL_CTX_use_certificate_chain_file(ctx, key_file)))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[ssl client] Loading client certificate failed \
+, key file %s", key_file);
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+
+ if (!(SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM)))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[ssl client] Loading client key failed, key file \
+%s", key_file);
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ }
+ else
+ {
+ AXIS2_LOG_INFO(env->log,
+ "[ssl client] Client certificate chain file"
+ "not specified");
+ }
+
+ /* Load the CAs we trust */
+ if (!(SSL_CTX_load_verify_locations(ctx, ca_file, 0)))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[ssl client] Loading CA certificate failed, \
+ca_file is %s", ca_file);
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+AXIS2_EXTERN SSL *AXIS2_CALL
+axis2_ssl_utils_initialize_ssl(
+ const axutil_env_t * env,
+ SSL_CTX * ctx,
+ axis2_socket_t socket)
+{
+ SSL *ssl = NULL;
+ BIO *sbio = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, ctx, NULL);
+
+ ssl = SSL_new(ctx);
+ if (!ssl)
+ {
+ AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI,
+ "[ssl]unable to create new ssl context");
+ return NULL;
+ }
+
+ sbio = BIO_new_socket((int)socket, BIO_NOCLOSE);
+ if (!sbio)
+ {
+ AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI,
+ "[ssl]unable to create BIO new socket for socket %d",
+ (int)socket);
+ return NULL;
+ }
+
+ SSL_set_bio(ssl, sbio, sbio);
+ if (SSL_connect(ssl) <= 0)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ if (SSL_get_verify_result(ssl) != X509_V_OK)
+ {
+ char sslerror[128]; /** error buffer must be at least 120 bytes long */
+ X509 *peer_cert = NULL;
+ X509_STORE *cert_store = NULL;
+ X509_NAME *peer_name = NULL;
+ X509_OBJECT *client_object = NULL;
+ X509 *client_cert = NULL;
+
+ peer_cert = SSL_get_peer_certificate(ssl);
+ if (peer_cert && peer_cert->cert_info)
+ {
+ peer_name = (peer_cert->cert_info)->subject;
+ }
+
+ cert_store = SSL_CTX_get_cert_store(ctx);
+ if (peer_name && cert_store)
+ {
+ client_object = X509_OBJECT_retrieve_by_subject(cert_store->objs,
+ X509_LU_X509,
+ peer_name);
+ }
+ if (client_object)
+ {
+ client_cert = (client_object->data).x509;
+ if (client_cert &&
+ (M_ASN1_BIT_STRING_cmp(client_cert->signature,
+ peer_cert->signature) == 0))
+ {
+ if (peer_cert)
+ {
+ X509_free(peer_cert);
+ }
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "[ssl client] SSL certificate verified against peer");
+ return ssl;
+ }
+ }
+ if (peer_cert)
+ {
+ X509_free(peer_cert);
+ }
+ ERR_error_string(SSL_get_verify_result(ssl), sslerror);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[ssl client] SSL certificate verification failed (%s)",
+ sslerror);
+ return NULL;
+ }
+
+ return ssl;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_ssl_utils_cleanup_ssl(
+ const axutil_env_t * env,
+ SSL_CTX * ctx,
+ SSL * ssl)
+{
+
+ if (ssl)
+ {
+ SSL_shutdown(ssl);
+ }
+ if (ctx)
+ {
+ SSL_CTX_free(ctx);
+ }
+ return AXIS2_SUCCESS;
+}
+
+#endif
+
diff --git a/src/core/transport/http/sender/ssl/ssl_utils.h b/src/core/transport/http/sender/ssl/ssl_utils.h
new file mode 100644
index 0000000..26dc16b
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/ssl_utils.h
@@ -0,0 +1,56 @@
+
+/*
+ * 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_SSL_UTILS_H
+#define AXIS2_SSL_UTILS_H
+
+
+#include <platforms/axutil_platform_auto_sense.h>
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <openssl/ssl.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ AXIS2_EXTERN SSL_CTX *AXIS2_CALL
+ axis2_ssl_utils_initialize_ctx(
+ const axutil_env_t * env,
+ axis2_char_t * server_cert,
+ axis2_char_t * key_file,
+ axis2_char_t * ssl_pp);
+
+ AXIS2_EXTERN SSL *AXIS2_CALL
+ axis2_ssl_utils_initialize_ssl(
+ const axutil_env_t * env,
+ SSL_CTX * ctx,
+ axis2_socket_t socket);
+
+ AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axis2_ssl_utils_cleanup_ssl(
+ const axutil_env_t * env,
+ SSL_CTX * ctx,
+ SSL * ssl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AXIS2_SSL_UTILS_H */
diff --git a/src/core/transport/http/server/CGI/Makefile.am b/src/core/transport/http/server/CGI/Makefile.am
new file mode 100644
index 0000000..fafb8bf
--- /dev/null
+++ b/src/core/transport/http/server/CGI/Makefile.am
@@ -0,0 +1,31 @@
+prgbindir=$(bindir)
+prgbin_PROGRAMS = axis2.cgi
+SUBDIRS =
+AM_CFLAGS = -g -pthread
+axis2_cgi_SOURCES = axis2_cgi_main.c \
+ axis2_cgi_out_transport_info.c \
+ axis2_cgi_stream.c
+
+axis2_cgi_LDADD = $(LDFLAGS) \
+ $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la \
+ $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la \
+ $(top_builddir)/axiom/src/om/libaxis2_axiom.la \
+ $(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la \
+ $(top_builddir)/src/core/description/libaxis2_description.la \
+ $(top_builddir)/src/core/deployment/libaxis2_deployment.la \
+ $(top_builddir)/src/core/context/libaxis2_context.la \
+ $(top_builddir)/src/core/clientapi/libaxis2_clientapi.la \
+ $(top_builddir)/src/core/engine/libaxis2_engine.la \
+ $(top_builddir)/src/core/transport/http/sender/libaxis2_http_sender.la \
+ $(top_builddir)/src/core/transport/http/receiver/libaxis2_http_receiver.la \
+ -lpthread
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/description\
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/deployment\
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
diff --git a/src/core/transport/http/server/CGI/axis2_cgi_main.c b/src/core/transport/http/server/CGI/axis2_cgi_main.c
new file mode 100644
index 0000000..6f9a59d
--- /dev/null
+++ b/src/core/transport/http/server/CGI/axis2_cgi_main.c
@@ -0,0 +1,280 @@
+/*
+ * 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_cgi_out_transport_info.h"
+#include "axis2_cgi_stream.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <axutil_error_default.h>
+#include <axutil_log_default.h>
+#include <axutil_thread_pool.h>
+#include <axutil_types.h>
+#include <axutil_version.h>
+#include <axutil_file_handler.h>
+#include <axutil_url.h>
+#include <axutil_string.h>
+#include <platforms/axutil_platform_auto_sense.h>
+
+#include <axis2_engine.h>
+#include <axis2_conf_init.h>
+#include <axis2_http_transport_utils.h>
+
+axis2_char_t *axis2_cgi_default_url_prefix = "/cgi-bin/axis2.cgi/";
+
+/***************************** Function headers *******************************/
+
+void
+axis2_cgi_system_exit(
+ axutil_env_t * env,
+ int status);
+
+void
+axis2_cgi_set_request_vars(
+ axis2_cgi_request_t *cgi_request);
+
+axis2_status_t
+axis2_cgi_write_response(
+ const void *buffer,
+ unsigned int length);
+
+/***************************** End of function headers ************************/
+
+int
+main(
+ int argc,
+ char *argv[])
+{
+ axutil_allocator_t *allocator = NULL;
+ axutil_env_t *env = NULL;
+ const axis2_char_t *repo_path;
+ axis2_conf_ctx_t *conf_ctx;
+ axis2_cgi_request_t *cgi_request = NULL;
+ int content_length = 0;
+ axis2_char_t *request_url = NULL;
+ /* axutil_stream_t *request_body_stream = NULL; */
+ axutil_stream_t *out_stream = NULL;
+ axis2_transport_in_desc_t *in_desc = NULL;
+ axis2_transport_out_desc_t *out_desc = NULL;
+ /* axis2_msg_ctx_t *msg_ctx = NULL; */
+ /* axis2_bool_t processed = AXIS2_FALSE; */
+ axis2_http_transport_in_t request;
+ axis2_http_transport_out_t response;
+ /*axis2_http_header_t* http_header = NULL; */
+ /*axutil_hash_t *headers = NULL; */
+ /* axis2_char_t *axis2_cgi_url_prefix = NULL; */
+
+ if(!(repo_path = AXIS2_GETENV("AXIS2C_HOME")))
+ {
+ fprintf(stderr, "Error: AXIS2C_HOME environment variable not set!");
+ axis2_cgi_system_exit(env, -1);
+ }
+
+ allocator = axutil_allocator_init(NULL);
+ env = axutil_env_create(allocator);
+
+ if(axutil_file_handler_access(repo_path, AXIS2_R_OK) != AXIS2_SUCCESS)
+ {
+ fprintf(stderr, "Error reading repository: %s\nPlease check AXIS2C_HOME var", repo_path);
+ axis2_cgi_system_exit(env, -1);
+ }
+
+ /* Set configuration */
+
+ conf_ctx = axis2_build_conf_ctx(env, repo_path);
+ if(!conf_ctx)
+ {
+ fprintf(stderr, "Error: Configuration not builded propertly\n");
+ axis2_cgi_system_exit(env, -1);
+ }
+
+ axis2_http_transport_utils_transport_out_init(&response, env);
+ axis2_http_transport_utils_transport_in_init(&request, env);
+
+ /* Get input info */
+
+ cgi_request = AXIS2_MALLOC(allocator, sizeof(axis2_cgi_request_t));
+ axis2_cgi_set_request_vars(cgi_request);
+
+ request_url = (axis2_char_t *)AXIS2_MALLOC(allocator, (7 + /* "http:" */
+ strlen(cgi_request->server_name) + ((strlen(cgi_request->server_port)) ? 1 : 0) + /* ":"*/
+ strlen(cgi_request->server_port) + strlen(cgi_request->script_name) + strlen(
+ cgi_request->path_info) + ((strlen(cgi_request->path_info)) ? 1 : 0) + /* "?" */
+ strlen(cgi_request->query_string)) * sizeof(axis2_char_t));
+
+ request_url[0] = '\0';
+
+ strcat(request_url, "http://");
+ strcat(request_url, cgi_request->server_name);
+ if(strlen(cgi_request->server_port))
+ strcat(request_url, ":");
+ strcat(request_url, cgi_request->server_port);
+ strcat(request_url, cgi_request->script_name);
+ strcat(request_url, cgi_request->path_info);
+ if(strlen(cgi_request->query_string))
+ strcat(request_url, "?");
+ strcat(request_url, cgi_request->query_string);
+
+ if(cgi_request->content_length)
+ content_length = axutil_atoi(cgi_request->content_length);
+ else
+ content_length = 0;
+
+ /* Set streams */
+
+ out_stream = axutil_stream_create_basic(env);
+
+ /* Set message contexts */
+
+ out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(conf_ctx, env), env,
+ AXIS2_TRANSPORT_ENUM_HTTP);
+ in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(conf_ctx, env), env,
+ AXIS2_TRANSPORT_ENUM_HTTP);
+
+ 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);
+ axis2_msg_ctx_set_transport_headers(request.msg_ctx, env, NULL);
+
+ /* Set request parameters */
+
+ request.soap_action = cgi_request->soap_action;
+ request.in_stream = axutil_stream_create_cgi(env, content_length);
+ request.remote_ip = cgi_request->remote_addr;
+ request.content_length = content_length;
+ request.content_type = cgi_request->content_type;
+ request.request_uri = request_url;
+ request.svr_port = cgi_request->server_port;
+ request.accept_header = AXIS2_GETENV("HTTP_ACCEPT");
+ request.accept_language_header = AXIS2_GETENV("HTTP_ACCEPT_LANGUAGE");
+ request.accept_charset_header = AXIS2_GETENV("HTTP_ACCEPT_CHARSET");
+ request.request_url_prefix = (AXIS2_GETENV("AXIS2C_URL_PREFIX")) ? AXIS2_GETENV(
+ "AXIS2C_URL_PREFIX") : axis2_cgi_default_url_prefix;
+
+ if(axutil_strcasecmp(cgi_request->request_method, "POST") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_POST;
+ }
+ else if(axutil_strcasecmp(cgi_request->request_method, "GET") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_GET;
+ }
+ else if(axutil_strcasecmp(cgi_request->request_method, "HEAD") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_HEAD;
+ }
+ else if(axutil_strcasecmp(cgi_request->request_method, "PUT") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_PUT;
+ }
+ else if(axutil_strcasecmp(cgi_request->request_method, "DELETE") == 0)
+ {
+ request.request_method = AXIS2_HTTP_METHOD_DELETE;
+ }
+
+ request.out_transport_info = axis2_cgi_out_transport_info_create(env, cgi_request);
+
+ /*Process request */
+ fprintf(stderr, "ok\n");
+ axis2_http_transport_utils_process_request(env, conf_ctx, &request, &response);
+ fprintf(stderr, "ok\n");
+ /*Send status */
+
+ fprintf(stdout, "Status: %d %s \r\n", response.http_status_code, response.http_status_code_name);
+
+ if(response.content_type)
+ {
+ fprintf(stdout, "Content-type: %s \r\n", response.content_type);
+ }
+ else if(strlen(axis2_cgi_out_transport_get_content(request.out_transport_info))
+ && axis2_cgi_out_transport_get_content(request.out_transport_info))
+ {
+ fprintf(stdout, "Content-type: %s \r\n", axis2_cgi_out_transport_get_content(
+ request.out_transport_info));
+ }
+
+ fprintf(stdout, "\r\n"); /* End of headers for server */
+
+ /* Write data body */
+ if(!axis2_cgi_write_response(response.response_data, response.response_data_length))
+ {
+ fprintf(stderr, "Error writing output data\n");
+ }
+
+ axis2_http_transport_utils_transport_in_uninit(&request, env);
+ axis2_http_transport_utils_transport_out_uninit(&response, env);
+
+ return 0;
+}
+
+axis2_status_t
+axis2_cgi_write_response(
+ const void *buffer,
+ unsigned int length)
+{
+ if(buffer && length)
+ {
+ unsigned int completed = 0;
+ unsigned int written = 0;
+
+ while(completed < length)
+ {
+ written = fwrite(buffer, sizeof(char), length - completed, stdout);
+ if(written < 0)
+ return AXIS2_FALSE;
+ completed += written;
+ }
+ }
+ return AXIS2_TRUE;
+}
+
+void
+axis2_cgi_set_request_vars(
+ axis2_cgi_request_t *cgi_request)
+{
+ cgi_request->server_name = (AXIS2_GETENV("SERVER_NAME")) ? AXIS2_GETENV("SERVER_NAME") : "";
+ cgi_request->script_name = (AXIS2_GETENV("SCRIPT_NAME")) ? AXIS2_GETENV("SCRIPT_NAME") : "";
+ cgi_request->path_info = (AXIS2_GETENV("PATH_INFO")) ? AXIS2_GETENV("PATH_INFO") : "";
+ cgi_request->server_port = (AXIS2_GETENV("SERVER_PORT")) ? AXIS2_GETENV("SERVER_PORT") : "";
+ cgi_request->server_protocol = (AXIS2_GETENV("SERVER_PROTOCOL")) ? AXIS2_GETENV(
+ "SERVER_PROTOCOL") : "";
+ cgi_request->content_length = (AXIS2_GETENV("CONTENT_LENGTH")) ? AXIS2_GETENV("CONTENT_LENGTH")
+ : "";
+ cgi_request->content_type = (AXIS2_GETENV("CONTENT_TYPE")) ? AXIS2_GETENV("CONTENT_TYPE") : "";
+ cgi_request->request_method = (AXIS2_GETENV("REQUEST_METHOD")) ? AXIS2_GETENV("REQUEST_METHOD")
+ : "";
+ cgi_request->remote_addr = (AXIS2_GETENV("REMOTE_ADDR")) ? AXIS2_GETENV("REMOTE_ADDR") : "";
+ cgi_request->soap_action = (AXIS2_GETENV("HTTP_SOAPACTION")) ? AXIS2_GETENV("HTTP_SOAPACTION")
+ : NULL;
+ cgi_request->query_string = (AXIS2_GETENV("QUERY_STRING")) ? AXIS2_GETENV("QUERY_STRING") : "";
+}
+
+void
+axis2_cgi_system_exit(
+ axutil_env_t * env,
+ int status)
+{
+ axutil_allocator_t *allocator = NULL;
+
+ if(env)
+ {
+ allocator = env->allocator;
+ axutil_env_free(env);
+ }
+ exit(status);
+}
diff --git a/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.c b/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.c
new file mode 100644
index 0000000..59e6820
--- /dev/null
+++ b/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.c
@@ -0,0 +1,160 @@
+/*
+ * 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_cgi_out_transport_info.h"
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+
+/**
+ * @brief CIG Out transport info impl structure
+ * Axis2 cgi_out_transport_info_impl
+ */
+
+typedef struct axis2_cgi_out_transport_info_s
+{
+ axis2_http_out_transport_info_t out_transport_info;
+ axis2_cgi_request_t *request;
+ axis2_char_t *encoding;
+} axis2_cgi_out_transport_info_t;
+
+#define AXIS2_INTF_TO_IMPL(out_transport_info) \
+ ((axis2_cgi_out_transport_info_t *)(out_transport_info))
+
+void AXIS2_CALL
+axis2_cgi_out_transport_info_free(
+ axis2_http_out_transport_info_t * info,
+ const axutil_env_t * env)
+{
+ axis2_cgi_out_transport_info_t *info_impl = NULL;
+ AXIS2_ENV_CHECK(env, void);
+
+ info_impl = AXIS2_INTF_TO_IMPL(info);
+
+ info_impl->request = NULL; /* doesn't belong here so no need to free it here */
+ if(info_impl->encoding)
+ {
+ AXIS2_FREE(env->allocator, info_impl->encoding);
+ info_impl->encoding = NULL;
+ }
+
+ AXIS2_FREE(env->allocator, info_impl);
+ return;
+}
+
+void AXIS2_CALL
+axis2_cgi_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_cgi_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_cgi_out_transport_info_t *info_impl = NULL;
+
+ axis2_char_t *temp1 = NULL;
+ axis2_char_t *temp2 = NULL;
+
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE);
+ info_impl = AXIS2_INTF_TO_IMPL(info);
+ if(info_impl->encoding)
+ {
+ temp1 = axutil_stracat(env, content_type, ";charset=");
+ temp2 = axutil_stracat(env, temp1, info_impl->encoding);
+ info_impl->request->content_type = axutil_strdup(env, temp2);
+ AXIS2_FREE(env->allocator, temp1);
+ AXIS2_FREE(env->allocator, temp2);
+ }
+ else
+ {
+ info_impl->request->content_type = axutil_strdup(env, content_type);
+ }
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_cgi_out_transport_info_set_char_encoding(
+ axis2_http_out_transport_info_t * info,
+ const axutil_env_t * env,
+ const axis2_char_t * encoding)
+{
+ axis2_cgi_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_cgi_out_transport_info_create(
+ const axutil_env_t * env,
+ axis2_cgi_request_t * request)
+{
+ axis2_cgi_out_transport_info_t *info = NULL;
+ axis2_http_out_transport_info_t *out_transport_info = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ info = (axis2_cgi_out_transport_info_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_cgi_out_transport_info_t));
+
+ if(!info)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ info->request = request;
+ info->encoding = NULL;
+
+ out_transport_info = &(info->out_transport_info);
+
+ axis2_http_out_transport_info_set_char_encoding_func(out_transport_info, env,
+ axis2_cgi_out_transport_info_set_char_encoding);
+ axis2_http_out_transport_info_set_content_type_func(out_transport_info, env,
+ axis2_cgi_out_transport_info_set_content_type);
+
+ return out_transport_info;
+}
+
+axis2_char_t *
+axis2_cgi_out_transport_get_content(
+ axis2_http_out_transport_info_t * info)
+{
+ axis2_cgi_out_transport_info_t *info_impl = NULL;
+ info_impl = AXIS2_INTF_TO_IMPL(info);
+ return info_impl->request->content_type;
+}
+
diff --git a/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.h b/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.h
new file mode 100644
index 0000000..bc0f526
--- /dev/null
+++ b/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.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_CGI_OUT_TRANSPORT_INFO_H
+#define AXIS2_CGI_OUT_TRANSPORT_INFO_H
+
+/**
+ * @ingroup axis2_core_transport_http
+ * @{
+ */
+
+/**
+ * @file axis2_cgi_out_transport_info.h
+ * @brief axis2 CGI Out Transport Info
+ */
+
+#include "axis2_cgi_types.h"
+#include <axis2_http_out_transport_info.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ axis2_http_out_transport_info_t *AXIS2_CALL
+
+ axis2_cgi_out_transport_info_create(
+ const axutil_env_t * env,
+ axis2_cgi_request_t * request);
+
+ /**
+ * 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_cgi_out_transport_info_free_void_arg(
+ void *transport_info,
+ const axutil_env_t * env);
+
+ axis2_char_t *axis2_cgi_out_transport_get_content(
+ axis2_http_out_transport_info_t * out_transport_info);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* AXIS2_SGI_OUT_TRANSPORT_INFO_H */
diff --git a/src/core/transport/http/server/CGI/axis2_cgi_stream.c b/src/core/transport/http/server/CGI/axis2_cgi_stream.c
new file mode 100644
index 0000000..68ad19f
--- /dev/null
+++ b/src/core/transport/http/server/CGI/axis2_cgi_stream.c
@@ -0,0 +1,164 @@
+/*
+ * 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_cgi_stream.h"
+
+/**
+ * @brief Stream struct impl
+ * Streaming mechanisms for cgi
+ */
+
+typedef struct cgi_stream_impl
+{
+ axutil_stream_t stream;
+ axutil_stream_type_t stream_type;
+ unsigned int cur_pos;
+ unsigned int content_length;
+} cgi_stream_impl_t;
+
+#define AXIS2_INTF_TO_IMPL(stream) ((cgi_stream_impl_t *)(stream))
+
+axutil_stream_type_t AXIS2_CALL
+cgi_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+int AXIS2_CALL cgi_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count);
+
+int AXIS2_CALL cgi_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count);
+
+int AXIS2_CALL cgi_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count);
+
+int AXIS2_CALL cgi_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+axutil_stream_t *AXIS2_CALL
+axutil_stream_create_cgi(
+ const axutil_env_t * env,
+ unsigned int content_length)
+{
+ cgi_stream_impl_t *stream_impl = NULL;
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, content_length, NULL);
+
+ stream_impl = (cgi_stream_impl_t *)AXIS2_MALLOC(env->allocator, sizeof(cgi_stream_impl_t));
+
+ if(!stream_impl)
+ {
+ return NULL;
+ }
+ stream_impl->cur_pos = 0;
+ stream_impl->content_length = content_length;
+ stream_impl->stream_type = AXIS2_STREAM_MANAGED;
+
+ axutil_stream_set_read(&(stream_impl->stream), env, cgi_stream_read);
+ axutil_stream_set_write(&(stream_impl->stream), env, cgi_stream_write);
+ axutil_stream_set_skip(&(stream_impl->stream), env, cgi_stream_skip);
+
+ return &(stream_impl->stream);
+}
+int AXIS2_CALL
+cgi_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;*/
+ unsigned int read_bytes = 0;
+ /*axis2_bool_t ret_ok = AXIS2_TRUE;*/
+
+ cgi_stream_impl_t *stream_impl = NULL;
+ /*char *temp = NULL;*/
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ stream_impl = (cgi_stream_impl_t *)stream;
+
+ if(count < stream_impl->content_length)
+ {
+ read_bytes = fread(buffer, sizeof(char), count, stdin);
+ }
+ else
+ {
+ read_bytes = fread(buffer, sizeof(char), stream_impl->content_length, stdin);
+ }
+
+ return read_bytes;
+}
+
+int AXIS2_CALL
+cgi_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buf,
+ size_t count)
+{
+ /* Cannot write on cgi stdin, explicitly an input stream */
+
+ return -1;
+}
+
+int AXIS2_CALL
+cgi_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count)
+{
+ cgi_stream_impl_t *stream_impl = NULL;
+ int skipped = -1;
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+
+ if(fseek(stdin, count, SEEK_CUR) == 0)
+ skipped = count;
+ return skipped;
+}
+
+int AXIS2_CALL
+cgi_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
+cgi_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/CGI/axis2_cgi_stream.h b/src/core/transport/http/server/CGI/axis2_cgi_stream.h
new file mode 100644
index 0000000..9a6af34
--- /dev/null
+++ b/src/core/transport/http/server/CGI/axis2_cgi_stream.h
@@ -0,0 +1,44 @@
+
+/*
+ * 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 CGI_STREAM_H
+#define CGI_STREAM_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /** brief Constructor for creating CGI stream
+ * @return axutil_stream (CGI)
+ */
+ axutil_stream_t *AXIS2_CALL
+ axutil_stream_create_cgi(
+ const axutil_env_t * env,
+ unsigned int content_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CGI_STREAM_H */
diff --git a/src/core/transport/http/server/CGI/axis2_cgi_types.h b/src/core/transport/http/server/CGI/axis2_cgi_types.h
new file mode 100644
index 0000000..af184a1
--- /dev/null
+++ b/src/core/transport/http/server/CGI/axis2_cgi_types.h
@@ -0,0 +1,34 @@
+
+/*
+ * 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_const.h>
+
+typedef struct axis2_cgi_request
+{
+ axis2_char_t *server_name;
+ axis2_char_t *server_port;
+ axis2_char_t *script_name;
+ axis2_char_t *path_info;
+ axis2_char_t *server_protocol;
+ axis2_char_t *content_length;
+ axis2_char_t *content_type;
+ axis2_char_t *request_method;
+ axis2_char_t *remote_addr;
+ axis2_char_t *soap_action;
+ axis2_char_t *query_string;
+} axis2_cgi_request_t;
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
diff --git a/src/core/transport/http/server/Makefile.am b/src/core/transport/http/server/Makefile.am
new file mode 100644
index 0000000..07cf1e9
--- /dev/null
+++ b/src/core/transport/http/server/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS=@APACHE2BUILD@ simple_axis2_server ${CGI_DIR}
+EXTRA_DIST=IIS CGI
diff --git a/src/core/transport/http/server/apache2/Makefile.am b/src/core/transport/http/server/apache2/Makefile.am
new file mode 100644
index 0000000..d5f6bd8
--- /dev/null
+++ b/src/core/transport/http/server/apache2/Makefile.am
@@ -0,0 +1,40 @@
+lib_LTLIBRARIES = libmod_axis2.la
+libmod_axis2_la_SOURCES = mod_axis2.c\
+ apache2_stream.c\
+ apache2_out_transport_info.c\
+ apache2_worker.c
+
+AM_CFLAGS = -DLINUX=2 -D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE
+
+libmod_axis2_la_LIBADD = $(LDFLAGS) \
+ $(top_builddir)/axiom/src/om/libaxis2_axiom.la \
+ $(top_builddir)/src/core/engine/libaxis2_engine.la\
+ $(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la\
+ $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la\
+ $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la\
+ -lpthread
+
+libmod_axis2_la_LDFLAGS = -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport/http \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/axiom/include\
+ -I$(top_builddir)/util/include\
+ @APACHE2INC@ \
+ @APRINC@
+
+EXTRA_DIST=axis2_apache2_worker.h apache2_stream.h axis2_apache2_out_transport_info.h
+
+
+
+
+
+
+
+
diff --git a/src/core/transport/http/server/apache2/apache2_out_transport_info.c b/src/core/transport/http/server/apache2/apache2_out_transport_info.c
new file mode 100644
index 0000000..9deaa56
--- /dev/null
+++ b/src/core/transport/http/server/apache2/apache2_out_transport_info.c
@@ -0,0 +1,191 @@
+/*
+ * 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_apache2_out_transport_info.h"
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <axutil_string.h>
+#include <apr_strings.h>
+
+typedef struct axis2_apache2_out_transport_info
+{
+ axis2_http_out_transport_info_t out_transport_info;
+ request_rec *request;
+ axis2_char_t *encoding;
+} axis2_apache2_out_transport_info_t;
+
+#define AXIS2_INTF_TO_IMPL(out_transport_info) \
+ ((axis2_apache2_out_transport_info_t *)(out_transport_info))
+
+void AXIS2_CALL
+axis2_apache2_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_apache_out_transport_info_free(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env)
+{
+ axis2_apache2_out_transport_info_t *info = NULL;
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+
+ info = AXIS2_INTF_TO_IMPL(out_transport_info);
+
+ info->request = NULL; /* request doesn't belong to info */
+ if(info->encoding)
+ {
+ AXIS2_FREE(env->allocator, info->encoding);
+ info->encoding = NULL;
+ }
+
+ AXIS2_FREE(env->allocator, info);
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_apache_out_transport_info_set_content_type(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * content_type)
+{
+ axis2_apache2_out_transport_info_t *info = NULL;
+
+ axis2_char_t *tmp1 = NULL;
+ axis2_char_t *tmp2 = NULL;
+
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE);
+ info = AXIS2_INTF_TO_IMPL(out_transport_info);
+
+ if(info->encoding)
+ {
+
+ tmp1 = axutil_stracat(env, content_type, ";charset=");
+ tmp2 = axutil_stracat(env, tmp1, info->encoding);
+ info->request->content_type = apr_pstrdup(info->request->pool, tmp2);
+ AXIS2_FREE(env->allocator, tmp1);
+ AXIS2_FREE(env->allocator, tmp2);
+ }
+ else
+ {
+ info->request->content_type = apr_pstrdup(info->request->pool, content_type);
+ }
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_apache_out_transport_info_set_char_encoding(
+ axis2_http_out_transport_info_t * info,
+ const axutil_env_t * env,
+ const axis2_char_t * encoding)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE);
+
+ if(info->encoding)
+ {
+ AXIS2_FREE(env->allocator, info->encoding);
+ }
+ info->encoding = axutil_strdup(env, encoding);
+
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_apache_out_transport_info_set_cookie_header(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * cookie_header)
+{
+ axis2_apache2_out_transport_info_t *info = NULL;
+
+
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, cookie_header, AXIS2_FAILURE);
+ info = AXIS2_INTF_TO_IMPL(out_transport_info);
+
+ apr_table_set(info->request->headers_out, AXIS2_HTTP_HEADER_SET_COOKIE, cookie_header);
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_apache_out_transport_info_set_session(
+ axis2_http_out_transport_info_t * out_transport_info,
+ const axutil_env_t * env,
+ const axis2_char_t * session_id,
+ const axis2_char_t * session_value)
+{
+ axis2_apache2_out_transport_info_t *info = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, session_id, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, session_value, AXIS2_FAILURE);
+ info = AXIS2_INTF_TO_IMPL(out_transport_info);
+
+ status = env->set_session_fn(info->request, session_id, session_value);
+
+ return status;
+}
+
+axis2_http_out_transport_info_t *AXIS2_CALL
+axis2_apache2_out_transport_info_create(
+ const axutil_env_t * env,
+ request_rec * request)
+{
+ axis2_apache2_out_transport_info_t *info = NULL;
+ axis2_http_out_transport_info_t *out_transport_info = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ info = (axis2_apache2_out_transport_info_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_apache2_out_transport_info_t));
+
+ if(!info)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ info->request = request;
+ info->encoding = NULL;
+
+ out_transport_info = &(info->out_transport_info);
+ out_transport_info->encoding = NULL;
+ out_transport_info->response = NULL;
+
+ axis2_http_out_transport_info_set_char_encoding_func(out_transport_info, env,
+ axis2_apache_out_transport_info_set_char_encoding);
+ axis2_http_out_transport_info_set_content_type_func(out_transport_info, env,
+ axis2_apache_out_transport_info_set_content_type);
+ axis2_http_out_transport_info_set_cookie_header_func(out_transport_info, env,
+ axis2_apache_out_transport_info_set_cookie_header);
+ axis2_http_out_transport_info_set_session_func(out_transport_info, env,
+ axis2_apache_out_transport_info_set_session);
+
+ return out_transport_info;
+}
+
+
diff --git a/src/core/transport/http/server/apache2/apache2_stream.c b/src/core/transport/http/server/apache2/apache2_stream.c
new file mode 100644
index 0000000..5e189a7
--- /dev/null
+++ b/src/core/transport/http/server/apache2/apache2_stream.c
@@ -0,0 +1,292 @@
+/*
+ * 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 "apache2_stream.h"
+#include <http_protocol.h>
+
+typedef struct apache2_stream_impl
+{
+ axutil_stream_t stream;
+ axutil_stream_type_t stream_type;
+ request_rec *request;
+} apache2_stream_impl_t;
+
+#define AXIS2_INTF_TO_IMPL(stream) ((apache2_stream_impl_t *)(stream))
+
+axutil_stream_type_t AXIS2_CALL
+apache2_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+int AXIS2_CALL apache2_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count);
+
+int AXIS2_CALL apache2_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count);
+
+static int AXIS2_CALL
+apache2_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count);
+
+int AXIS2_CALL apache2_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+static apr_size_t
+apache2_ap_get_client_block(
+ request_rec *r,
+ char* buffer,
+ apr_size_t bufsiz);
+
+AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+axutil_stream_create_apache2(
+ const axutil_env_t * env,
+ request_rec * request)
+{
+ apache2_stream_impl_t *stream_impl = NULL;
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, request, NULL);
+
+ stream_impl = (apache2_stream_impl_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(apache2_stream_impl_t));
+
+ if(!stream_impl)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ memset(&(stream_impl->stream), 0, sizeof(axutil_stream_t));
+
+ stream_impl->request = request;
+ stream_impl->stream_type = AXIS2_STREAM_MANAGED;
+
+ axutil_stream_set_read(&(stream_impl->stream), env, apache2_stream_read);
+ axutil_stream_set_write(&(stream_impl->stream), env, apache2_stream_write);
+ axutil_stream_set_skip(&(stream_impl->stream), env, apache2_stream_skip);
+
+ return &(stream_impl->stream);
+}
+
+int AXIS2_CALL
+apache2_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count)
+{
+ apache2_stream_impl_t *stream_impl = NULL;
+ size_t read = 0;
+ size_t len = 0;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+
+ while(count - len > 0)
+ {
+ read = apache2_ap_get_client_block(stream_impl->request, (char *) buffer + len,
+ count - len);
+ if(read > 0)
+ {
+ len += read;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return (int)len;
+ /* We are sure that the difference lies within the int range */
+}
+
+int AXIS2_CALL
+apache2_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buf,
+ size_t count)
+{
+ apache2_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;
+ if(count <= 0)
+ {
+ return (int)count;
+ /* We are sure that the difference lies within the int range */
+ }
+ /* assume that buffer is not null terminated */
+ return ap_rwrite(buffer, (int)count, stream_impl->request);
+ /* We are sure that the difference lies within the int range */
+}
+
+static int AXIS2_CALL
+apache2_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count)
+{
+ apache2_stream_impl_t *stream_impl = NULL;
+ axis2_char_t *tmp_buffer = NULL;
+ apr_size_t len = -1;
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+
+ tmp_buffer = AXIS2_MALLOC(env->allocator, count * sizeof(axis2_char_t));
+ if(tmp_buffer == NULL)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return -1;
+ }
+ len = apache2_ap_get_client_block(stream_impl->request, tmp_buffer, count);
+ AXIS2_FREE(env->allocator, tmp_buffer);
+ return (int)len;
+
+}
+
+int AXIS2_CALL
+apache2_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
+apache2_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;
+}
+
+/*
+ * This is a re-write of get_client_block found in http_filters.c in httpd
+ * which does not work when dealing with compressed payloads (or any other input
+ * filters that could potentially return 0 bytes of filtered data and not be at
+ * the end of the stream).
+ * get_client_block is called in a loop to get the request message body.
+ * This is quite simple if the client includes a content-length
+ * (the normal case), but gets messy if the body is chunked. Note that
+ * r->remaining is used to maintain state across calls and that
+ * r->read_length is the total number of bytes given to the caller
+ * across all invocations. It is messy because we have to be careful not
+ * to read past the data provided by the client, since these reads block.
+ * Returns 0 on End-of-body, -1 on error or premature chunk end.
+ *
+ */
+static apr_size_t
+apache2_ap_get_client_block(
+ request_rec *r,
+ char *buffer,
+ apr_size_t bufsiz)
+{
+ apr_status_t rv;
+ apr_bucket_brigade *bb;
+ int loop = 1;
+ apr_size_t origBufSize = bufsiz;
+
+ if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) {
+ return 0;
+ }
+
+ bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ if (bb == NULL) {
+ r->connection->keepalive = AP_CONN_CLOSE;
+ return -1;
+ }
+
+ /* we need to loop until the input filters (if any) give us data */
+ while (loop) {
+ rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+ APR_BLOCK_READ, bufsiz);
+
+ /* We lose the failure code here. This is why ap_get_client_block should
+ * not be used.
+ */
+ if (rv != APR_SUCCESS) {
+ /* if we actually fail here, we want to just return and
+ * stop trying to read data from the client.
+ */
+ r->connection->keepalive = AP_CONN_CLOSE;
+ apr_brigade_destroy(bb);
+ return -1;
+ }
+
+ /* If this fails, it means that a filter is written incorrectly and that
+ * it needs to learn how to properly handle APR_BLOCK_READ requests by
+ * returning data when requested.
+ */
+ AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(bb));
+
+ /* Check to see if EOS in the brigade.
+ *
+ * If so, we have to leave a nugget for the *next* ap_get_client_block
+ * call to return 0.
+ */
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
+ if (r->read_chunked) {
+ r->remaining = -1;
+ } else {
+ r->remaining = 0;
+ }
+ }
+
+ rv = apr_brigade_flatten(bb, buffer, &bufsiz);
+ if (rv != APR_SUCCESS) {
+ apr_brigade_destroy(bb);
+ return -1;
+ }
+
+ /* XXX yank me? */
+ r->read_length += bufsiz;
+
+ /* it is possible that the entire bucket brigade is exhausted, but no data
+ * has been produced by the input filter (mod_deflate, for example)....
+ * in this scenario, we really need to keep looping
+ */
+ if (bufsiz != 0 || r->remaining <= 0) {
+ loop = 0;
+ apr_brigade_destroy(bb);
+ } else {
+ if (bufsiz == 0) {
+ bufsiz = origBufSize;
+ }
+ }
+
+ }
+
+ return (long)bufsiz;
+}
diff --git a/src/core/transport/http/server/apache2/apache2_stream.h b/src/core/transport/http/server/apache2/apache2_stream.h
new file mode 100644
index 0000000..abbea45
--- /dev/null
+++ b/src/core/transport/http/server/apache2/apache2_stream.h
@@ -0,0 +1,46 @@
+
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain count 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 APACHE2_STREAM_H
+#define APACHE2_STREAM_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+#include <httpd.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /** \brief Constructor for creating apche2 stream
+ * @return axutil_stream (apache2)
+ */
+ AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+ axutil_stream_create_apache2(
+ const axutil_env_t * env,
+ request_rec * req);
+
+ /** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APACHE2_STREAM_H */
diff --git a/src/core/transport/http/server/apache2/apache2_worker.c b/src/core/transport/http/server/apache2/apache2_worker.c
new file mode 100644
index 0000000..12b05b2
--- /dev/null
+++ b/src/core/transport/http/server/apache2/apache2_worker.c
@@ -0,0 +1,1687 @@
+/*
+ * 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_apache2_worker.h"
+#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_http_accept_record.h>
+#include <axis2_op_ctx.h>
+#include <axis2_engine.h>
+#include <axutil_uuid_gen.h>
+#include <axis2_conf_init.h>
+#include "axis2_apache2_out_transport_info.h"
+#include <axutil_url.h>
+#include <http_core.h>
+#include <http_protocol.h>
+#include <axiom_soap.h>
+#include <axutil_class_loader.h>
+#include <axutil_string_util.h>
+#include <axiom_mime_part.h>
+#include <axiom_mtom_sending_callback.h>
+
+#define READ_SIZE 2048
+
+static axis2_status_t
+apache2_worker_send_mtom_message(
+ request_rec *request,
+ const axutil_env_t * env,
+ axutil_array_list_t *mime_parts,
+ axis2_char_t *mtom_sending_callback_name);
+
+static axis2_status_t
+apache2_worker_send_attachment_using_file(
+ const axutil_env_t * env,
+ request_rec *request,
+ FILE *fp,
+ axis2_byte_t *buffer,
+ int buffer_size);
+
+static axis2_status_t
+apache2_worker_send_attachment_using_callback(
+ const axutil_env_t * env,
+ request_rec *request,
+ axiom_mtom_sending_callback_t *callback,
+ void *handler,
+ void *user_param);
+
+static axutil_hash_t*
+axis2_apache_worker_get_headers(
+ const axutil_env_t *env,
+ request_rec *request);
+
+
+struct axis2_apache2_worker
+{
+ axis2_conf_ctx_t *conf_ctx;
+};
+
+AXIS2_EXTERN axis2_apache2_worker_t *AXIS2_CALL
+axis2_apache2_worker_create(
+ const axutil_env_t * env,
+ axis2_char_t * repo_path)
+{
+ axis2_apache2_worker_t *apache2_worker = NULL;
+ axutil_hash_t* svc_map = NULL;
+ axis2_conf_t* conf = NULL;
+ axutil_hash_index_t *hi = NULL;
+ void* svc = NULL;
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_LOG_INFO(env->log, "[Axis2] Axis2 worker created");
+ apache2_worker = (axis2_apache2_worker_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_apache2_worker_t));
+
+ if(!apache2_worker)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ apache2_worker->conf_ctx = axis2_build_conf_ctx(env, repo_path);
+
+ if(!apache2_worker->conf_ctx)
+ {
+ axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env);
+ return NULL;
+ }
+
+ /*
+ * we have to load all the services. This is because, before the fork (in linux)
+ * we should have a full code segment. Otherwise, we can't share function pointers of services
+ * between processed. In fork, the code segment will be duplicated across processes
+ */
+ conf = axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env);
+ if(!conf)
+ {
+ axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env);
+ return NULL;
+ }
+
+ svc_map = axis2_conf_get_all_svcs(conf, env);
+ if(!svc_map)
+ {
+ axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env);
+ return NULL;
+ }
+
+ for(hi = axutil_hash_first(svc_map, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ void *impl_class = NULL;
+ axis2_msg_recv_t *msg_recv = NULL;
+ axutil_hash_t *ops_hash = NULL;
+
+ axutil_hash_this(hi, NULL, NULL, &svc);
+ if(!svc)
+ continue;
+ impl_class = axis2_svc_get_impl_class(svc, env);
+ if(impl_class)
+ continue;
+ ops_hash = axis2_svc_get_all_ops(svc, env);
+ if(ops_hash)
+ {
+ axutil_hash_index_t *op_hi = NULL;
+ void *op = NULL;
+ op_hi = axutil_hash_first(ops_hash, env);
+ if(op_hi)
+ {
+ axutil_hash_this(op_hi, NULL, NULL, &op);
+ if(op)
+ {
+ msg_recv = axis2_op_get_msg_recv(op, env);
+ if(msg_recv)
+ {
+ axis2_msg_recv_set_conf_ctx(msg_recv, env, apache2_worker->conf_ctx);
+ axis2_msg_recv_load_and_init_svc(msg_recv, env, svc);
+ }
+ }
+ }
+
+ }
+ }
+
+ AXIS2_LOG_INFO(env->log, "[Axis2] Axis2 worker created");
+
+ return apache2_worker;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_apache2_worker_free(
+ axis2_apache2_worker_t * apache2_worker,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, void);
+
+ if(apache2_worker->conf_ctx)
+ {
+ axis2_conf_ctx_free(apache2_worker->conf_ctx, env);
+ apache2_worker->conf_ctx = NULL;
+ }
+
+ AXIS2_FREE(env->allocator, apache2_worker);
+
+ return;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_apache2_worker_process_request(
+ axis2_apache2_worker_t * apache2_worker,
+ const axutil_env_t * env,
+ request_rec * request)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axutil_stream_t *request_body = 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 *http_version = NULL;
+ axutil_string_t *soap_action = NULL;
+ axis2_char_t *soap_action_header_txt = NULL;
+ axis2_bool_t processed = AXIS2_FALSE;
+ int content_length = -1;
+ axis2_char_t *url_external_form = NULL;
+ axis2_char_t *body_string = NULL;
+ unsigned int body_string_len = 0;
+ int send_status = DECLINED;
+ axis2_char_t *content_type = NULL;
+ axis2_http_out_transport_info_t *apache2_out_transport_info = NULL;
+ axis2_char_t *ctx_uuid = NULL;
+ axis2_op_ctx_t *op_ctx = NULL;
+ axis2_char_t *peer_ip = NULL;
+ axutil_property_t *peer_property = NULL;
+ axutil_url_t *request_url = NULL;
+ axis2_char_t *accept_header_value = NULL;
+ axis2_char_t *accept_charset_header_value = NULL;
+ axis2_char_t *accept_language_header_value = NULL;
+ axis2_char_t *content_language_header_value = NULL;
+ axis2_bool_t do_mtom = AXIS2_FALSE;
+ axutil_array_list_t *mime_parts = NULL;
+ axutil_param_t *callback_name_param = NULL;
+ axis2_char_t *mtom_sending_callback_name = NULL;
+ axis2_char_t *cookie = NULL;
+ axis2_char_t *header_value = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_hash_t *headers = NULL;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, request, AXIS2_CRITICAL_FAILURE);
+
+ conf_ctx = apache2_worker->conf_ctx;
+
+ if(!conf_ctx)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE);
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ content_length = (int)request->remaining;
+ /* We are sure that the difference lies within the int range */
+ http_version = request->protocol;
+
+ request_url = axutil_url_create(env, "http", request->hostname, request->parsed_uri.port,
+ request->unparsed_uri);
+ if(request_url)
+ {
+ url_external_form = axutil_url_to_external_form(request_url, env);
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, url_external_form);
+ axutil_url_free(request_url, env);
+ request_url = NULL;
+ }
+ else
+ {
+ send_status = OK;
+ request->status = HTTP_BAD_REQUEST;
+ return send_status;
+ }
+
+ content_type = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if(!content_type)
+ {
+ content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN;
+ }
+ request->content_type = content_type;
+
+ out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env),
+ env, AXIS2_TRANSPORT_ENUM_HTTP);
+ in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env),
+ env, AXIS2_TRANSPORT_ENUM_HTTP);
+ {
+ axis2_transport_receiver_t *receiver = NULL;
+ receiver = axis2_transport_in_desc_get_recv(in_desc, env);
+ if(receiver)
+ axis2_transport_receiver_set_server_ip(receiver, env, request->connection->local_ip);
+ }
+
+ msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc);
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+ cookie = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_COOKIE);
+ if(cookie)
+ {
+ char *session_str = NULL;
+ axis2_char_t *session_id = NULL;
+
+ session_id = axis2_http_transport_utils_get_session_id_from_cookie(env, cookie);
+ if(session_id)
+ session_str = env->get_session_fn((void *) request, session_id);
+ if(session_str)
+ axis2_http_transport_utils_set_session(env, msg_ctx, session_str);
+ }
+
+ if(request->read_chunked == AXIS2_TRUE && 0 == content_length)
+ {
+ content_length = -1;
+ request->chunked = 1;
+ }
+ if(!http_version)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE);
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ out_stream = axutil_stream_create_basic(env);
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Client HTTP version %s", http_version);
+
+ peer_ip = request->connection->remote_ip;
+
+ if(peer_ip)
+ {
+ peer_property = axutil_property_create(env);
+ axutil_property_set_value(peer_property, env, axutil_strdup(env, peer_ip));
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_SVR_PEER_IP_ADDR, peer_property);
+ }
+
+ axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream);
+
+ ctx_uuid = axutil_uuid_gen(env);
+ if(ctx_uuid)
+ {
+ axutil_string_t *uuid_str = axutil_string_create_assume_ownership(env, &ctx_uuid);
+ axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, uuid_str);
+ axutil_string_free(uuid_str, env);
+ }
+
+ apache2_out_transport_info = axis2_apache2_out_transport_info_create(env, request);
+ axis2_msg_ctx_set_out_transport_info(msg_ctx, env, &(apache2_out_transport_info->out_transport));
+
+ accept_header_value = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_ACCEPT);
+ if(accept_header_value)
+ {
+ axutil_array_list_t *accept_header_field_list = NULL;
+ axutil_array_list_t *accept_record_list = NULL;
+ accept_header_field_list = axutil_tokenize(env, accept_header_value, ',');
+ if(accept_header_field_list && axutil_array_list_size(accept_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_header_field_list, env, 0);
+ }
+ while(token);
+ }
+ if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0)
+ {
+ axis2_msg_ctx_set_http_accept_record_list(msg_ctx, env, accept_record_list);
+ }
+ }
+
+ accept_charset_header_value = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_ACCEPT_CHARSET);
+ if(accept_charset_header_value)
+ {
+ axutil_array_list_t *accept_charset_header_field_list = NULL;
+ axutil_array_list_t *accept_charset_record_list = NULL;
+ accept_charset_header_field_list = axutil_tokenize(env, accept_charset_header_value, ',');
+ if(accept_charset_header_field_list && axutil_array_list_size(
+ accept_charset_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_charset_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_charset_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_charset_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_charset_header_field_list,
+ env, 0);
+ }
+ while(token);
+ }
+ if(accept_charset_record_list && axutil_array_list_size(accept_charset_record_list, env)
+ > 0)
+ {
+ axis2_msg_ctx_set_http_accept_charset_record_list(msg_ctx, env,
+ accept_charset_record_list);
+ }
+ }
+
+ accept_language_header_value = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_ACCEPT_LANGUAGE);
+ if(accept_language_header_value)
+ {
+ axutil_array_list_t *accept_language_header_field_list = NULL;
+ axutil_array_list_t *accept_language_record_list = NULL;
+ accept_language_header_field_list = axutil_tokenize(env, accept_language_header_value, ',');
+ if(accept_language_header_field_list && axutil_array_list_size(
+ accept_language_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_language_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_language_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_language_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_language_header_field_list,
+ env, 0);
+ }
+ while(token);
+ }
+ if(accept_language_record_list && axutil_array_list_size(accept_language_record_list, env)
+ > 0)
+ {
+ axis2_msg_ctx_set_http_accept_language_record_list(msg_ctx, env,
+ accept_language_record_list);
+ }
+ }
+
+ soap_action_header_txt = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_SOAP_ACTION);
+
+ if(soap_action_header_txt)
+ {
+ soap_action = axutil_string_create(env, soap_action_header_txt);
+ }
+
+ headers = axis2_apache_worker_get_headers(env, request);
+ axis2_msg_ctx_set_transport_headers(msg_ctx, env, headers);
+
+ request_body = axutil_stream_create_apache2(env, request);
+ if(!request_body)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in"
+ " creating input stream.");
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ if(M_GET == request->method_number || M_DELETE == request->method_number)
+ {
+ if(M_DELETE == request->method_number)
+ {
+ processed = axis2_http_transport_utils_process_http_delete_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx,
+ axis2_http_transport_utils_get_request_params(env,
+ (axis2_char_t *)url_external_form));
+ }
+ else if(request->header_only)
+ {
+ processed = axis2_http_transport_utils_process_http_head_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx,
+ axis2_http_transport_utils_get_request_params(env,
+ (axis2_char_t *)url_external_form));
+ }
+ else
+ {
+ processed = axis2_http_transport_utils_process_http_get_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx,
+ axis2_http_transport_utils_get_request_params(env,
+ (axis2_char_t *)url_external_form));
+ }
+ if(AXIS2_FALSE == processed)
+ {
+ axis2_char_t *wsdl = NULL;
+ axis2_bool_t is_services_path = AXIS2_FALSE;
+ if(M_DELETE != request->method_number)
+ {
+ axis2_char_t *temp = NULL;
+ temp = strstr(url_external_form, AXIS2_REQUEST_URL_PREFIX);
+ if(temp)
+ {
+ temp += strlen(AXIS2_REQUEST_URL_PREFIX);
+ if(*temp == '/')
+ {
+ temp++;
+ }
+ if(!*temp || *temp == '?' || *temp == '#')
+ {
+ is_services_path = AXIS2_TRUE;
+ }
+ }
+ }
+ wsdl = strstr(url_external_form, AXIS2_REQUEST_WSDL);
+ if(is_services_path)
+ {
+ body_string = axis2_http_transport_utils_get_services_html(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ }
+ else if(M_DELETE != request->method_number && wsdl)
+ {
+ body_string = axis2_http_transport_utils_get_services_static_wsdl(env, conf_ctx,
+ (axis2_char_t *)url_external_form);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
+
+ }
+ else if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND)
+ {
+ axutil_array_list_t *method_list = NULL;
+ int size = 0;
+ method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env);
+ size = axutil_array_list_size(method_list, env);
+ if(method_list && size)
+ {
+ axis2_char_t *method_list_str = NULL;
+ axis2_char_t *temp;
+ int i = 0;
+ method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29);
+ temp = method_list_str;
+ request->allowed_methods->method_mask = 0;
+ for(i = 0; i < size; i++)
+ {
+ if(i)
+ {
+ sprintf(temp, ", ");
+ temp += 2;
+ }
+ sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env,
+ i));
+ temp += strlen(temp);
+ /* Conditions below is to assist down-stream modules */
+ if(!strcasecmp(AXIS2_HTTP_PUT, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_PUT;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_POST, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_POST;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_GET, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_HEAD, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ /* Apache Can't differentiate between HEAD and GET */
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_DELETE,
+ (axis2_char_t *)axutil_array_list_get(method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_DELETE;
+ }
+ }
+ *temp = '\0';
+ apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_ALLOW,
+ method_list_str);
+ AXIS2_FREE(env->allocator, method_list_str);
+ body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx);
+ request->status = HTTP_METHOD_NOT_ALLOWED;
+ }
+ else
+ {
+ body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx);
+ request->status = HTTP_NOT_FOUND;
+ }
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_BAD_REQUEST;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_REQUEST_TIME_OUT;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_CONFLICT;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_gone(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_GONE;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_PRECONDITION_FAILED;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_SERVICE_UNAVAILABLE;
+ }
+ else
+ {
+ body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if(body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ }
+ }
+ else if(M_POST == request->method_number || M_PUT == request->method_number)
+ {
+ /*axis2_status_t status = AXIS2_FAILURE;*/
+ if(M_POST == request->method_number)
+ {
+ status = axis2_http_transport_utils_process_http_post_request(env, msg_ctx,
+ request_body, out_stream, content_type, content_length, soap_action,
+ (axis2_char_t *)url_external_form);
+ }
+ else
+ {
+ status = axis2_http_transport_utils_process_http_put_request(env, msg_ctx,
+ request_body, out_stream, content_type, content_length, soap_action,
+ (axis2_char_t *)url_external_form);
+ }
+ if(AXIS2_FAILURE == status && (M_PUT == request->method_number
+ || axis2_msg_ctx_get_doing_rest(msg_ctx, env)))
+ {
+ if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND)
+ {
+ axutil_array_list_t *method_list = NULL;
+ int size = 0;
+ method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env);
+ size = axutil_array_list_size(method_list, env);
+ if(method_list && size)
+ {
+ axis2_char_t *method_list_str = NULL;
+ axis2_char_t *temp;
+ int i = 0;
+ method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29);
+ temp = method_list_str;
+ request->allowed_methods->method_mask = 0;
+ for(i = 0; i < size; i++)
+ {
+ if(i)
+ {
+ sprintf(temp, ", ");
+ temp += 2;
+ }
+ sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env,
+ i));
+ temp += strlen(temp);
+ /* Conditions below is to assist down-stream modules */
+ if(!strcasecmp(AXIS2_HTTP_PUT, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_PUT;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_POST, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_POST;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_GET, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_HEAD, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ /* Apache Can't differentiate between HEAD and GET */
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_DELETE,
+ (axis2_char_t *)axutil_array_list_get(method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_DELETE;
+ }
+ }
+ *temp = '\0';
+ apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_ALLOW,
+ method_list_str);
+ AXIS2_FREE(env->allocator, method_list_str);
+ body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx);
+ request->status = HTTP_METHOD_NOT_ALLOWED;
+ }
+ else
+ {
+ body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx);
+ request->status = HTTP_NOT_FOUND;
+ }
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ }
+ else
+ {
+ body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if(body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ }
+ else if(status == AXIS2_FAILURE)
+ {
+ axis2_msg_ctx_t *fault_ctx = NULL;
+ axis2_char_t *fault_code = NULL;
+ axis2_engine_t *engine = axis2_engine_create(env, conf_ctx);
+ if(!engine)
+ {
+ /* Critical error, cannot proceed, Apache will send default
+ document for 500
+ */
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":"
+ AXIOM_SOAP11_FAULT_CODE_SENDER;
+ }
+ else
+ {
+ fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":"
+ AXIOM_SOAP12_SOAP_FAULT_VALUE_SENDER;
+ }
+ fault_ctx = axis2_engine_create_fault_msg_ctx(engine, env, msg_ctx,
+ fault_code,
+ axutil_error_get_message
+ (env->error));
+ axis2_engine_send_fault(engine, env, fault_ctx);
+ if (out_stream)
+ {
+ body_string = axutil_stream_get_buffer(out_stream, env);
+ body_string_len = axutil_stream_get_len(out_stream, env);
+ }
+
+ /* In case of a SOAP Fault, we have to set the status to 500,
+ but still return OK because the module has handled the error
+ */
+ send_status = OK;
+ request->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ else
+ {
+ body_string =
+ axis2_http_transport_utils_get_not_implemented(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ request->status = HTTP_NOT_IMPLEMENTED;
+ }
+
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+
+ if (op_ctx)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ if (out_msg_ctx)
+ {
+ content_language_header_value = axis2_msg_ctx_get_content_language(out_msg_ctx, env);
+ }
+ }
+
+ if (send_status == DECLINED)
+ {
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ if (M_POST != request->method_number ||
+ axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ do_rest = AXIS2_TRUE;
+ }
+ if ((accept_header_value || accept_charset_header_value ||
+ accept_language_header_value) && do_rest)
+ {
+ axis2_char_t *content_type_header_value = NULL;
+ axis2_char_t *temp = NULL;
+ axis2_char_t *language_header_value = NULL;
+
+ content_type_header_value = (axis2_char_t *) request->content_type;
+ language_header_value = content_language_header_value;
+ if (content_type_header_value)
+ {
+ temp = axutil_strdup(env, content_type_header_value);
+ }
+ if (temp)
+ {
+ axis2_char_t *content_type = NULL;
+ axis2_char_t *char_set = NULL;
+ axis2_char_t *temp2 = NULL;
+
+ temp2 = strchr(temp, ';');
+ if (temp2)
+ {
+ *temp2 = '\0';
+ temp2++;
+ char_set = axutil_strcasestr(temp2, AXIS2_HTTP_CHAR_SET_ENCODING);
+ }
+ if (char_set)
+ {
+ char_set = axutil_strltrim(env, char_set, " \t=");
+ }
+ if (char_set)
+ {
+ temp2 = strchr(char_set, ';');
+ }
+ if (temp2)
+ {
+ *temp2 = '\0';
+ }
+ content_type = axutil_strtrim(env, temp, NULL);
+
+ if (temp)
+ {
+ AXIS2_FREE(env->allocator, temp);
+ temp = NULL;
+ }
+ if (content_type && accept_header_value &&
+ !axutil_strcasestr(accept_header_value, content_type))
+ {
+ temp2 = strchr(content_type, '/');
+ if (temp2)
+ {
+ *temp2 = '\0';
+ temp = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * ((int)strlen(content_type) + 3));
+ if (!temp)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return AXIS2_FALSE;
+ }
+ sprintf(temp, "%s/*", content_type);
+ if (!axutil_strcasestr(accept_header_value, temp) &&
+ !strstr(accept_header_value, AXIS2_HTTP_HEADER_ACCEPT_ALL))
+ {
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ request->status = HTTP_NOT_ACCEPTABLE;
+ }
+ AXIS2_FREE(env->allocator, temp);
+ }
+ }
+ if (content_type)
+ {
+ AXIS2_FREE(env->allocator, content_type);
+ }
+ if (char_set && accept_charset_header_value &&
+ !axutil_strcasestr(accept_charset_header_value, char_set))
+ {
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ request->status = HTTP_NOT_ACCEPTABLE;
+ }
+ if (char_set)
+ {
+ AXIS2_FREE(env->allocator, char_set);
+ }
+ }
+ if (language_header_value)
+ {
+ if (accept_language_header_value &&
+ !axutil_strcasestr(accept_language_header_value, language_header_value))
+ {
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ request->status = HTTP_NOT_ACCEPTABLE;
+ }
+ }
+ }
+ }
+
+ header_value = axis2_http_transport_utils_get_session(env, msg_ctx);
+ if(header_value)
+ {
+ axis2_http_out_transport_info_t *out_info = NULL;
+ out_info = (axis2_http_out_transport_info_t *)axis2_msg_ctx_get_out_transport_info(msg_ctx, env);
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_COOKIE_HEADER(out_info, env, header_value);
+ }
+ if (send_status == DECLINED)
+ {
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ if (M_POST != request->method_number ||
+ axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ do_rest = AXIS2_TRUE;
+ }
+ if (op_ctx && axis2_op_ctx_get_response_written(op_ctx, env))
+ {
+ if (do_rest)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+ if (in_msg_ctx)
+ {
+ /* TODO: Add necessary handling */
+ }
+ if (out_msg_ctx)
+ {
+ int size = 0;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list, env);
+ }
+ while (size)
+ {
+ axis2_http_header_t *output_header = NULL;
+ size--;
+ output_header = (axis2_http_header_t *)
+ axutil_array_list_get(output_header_list, env, size);
+ apr_table_set(request->err_headers_out,
+ axis2_http_header_get_name(output_header, env),
+ axis2_http_header_get_value(output_header, env));
+ }
+ if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ request->status = HTTP_CONTINUE;
+ break;
+ case AXIS2_HTTP_RESPONSE_ACK_CODE_VAL:
+ request->status = HTTP_ACCEPTED;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ request->status = HTTP_MULTIPLE_CHOICES;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ request->status = HTTP_MOVED_PERMANENTLY;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ request->status = HTTP_SEE_OTHER;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ request->status = HTTP_NOT_MODIFIED;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ request->status = HTTP_TEMPORARY_REDIRECT;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ request->status = HTTP_BAD_REQUEST;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ request->status = HTTP_REQUEST_TIME_OUT;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ request->status = HTTP_CONFLICT;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ request->status = HTTP_GONE;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ request->status = HTTP_PRECONDITION_FAILED;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ request->status = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ request->status = HTTP_SERVICE_UNAVAILABLE;
+ break;
+ default:
+ request->status = HTTP_OK;
+ break;
+ }
+ send_status = DONE;
+ }
+ }
+ }
+ if (send_status == DECLINED)
+ {
+ send_status = OK;
+ if (out_stream)
+ {
+ body_string = axutil_stream_get_buffer(out_stream, env);
+ body_string_len = axutil_stream_get_len(out_stream, env);
+ }
+ }
+ }
+ else if (op_ctx)
+ {
+ if (do_rest)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+ if (in_msg_ctx)
+ {
+ /* TODO: Add necessary handling */
+ }
+ if (out_msg_ctx)
+ {
+ int size = 0;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list, env);
+ }
+ while (size)
+ {
+ axis2_http_header_t *output_header = NULL;
+ size--;
+ output_header = (axis2_http_header_t *)
+ axutil_array_list_get(output_header_list, env, size);
+ apr_table_set(request->err_headers_out,
+ axis2_http_header_get_name(output_header, env),
+ axis2_http_header_get_value(output_header, env));
+ }
+ if (axis2_msg_ctx_get_no_content(out_msg_ctx, env))
+ {
+ if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL:
+ request->status = HTTP_RESET_CONTENT;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ request->status = HTTP_NOT_MODIFIED;
+ break;
+ default:
+ request->status = HTTP_NO_CONTENT;
+ break;
+ }
+ }
+ else
+ {
+ request->status = HTTP_NO_CONTENT;
+ }
+ send_status = DONE;
+ }
+ else if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ request->status = HTTP_CONTINUE;
+ break;
+ case AXIS2_HTTP_RESPONSE_OK_CODE_VAL:
+ request->status = HTTP_OK;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ request->status = HTTP_MULTIPLE_CHOICES;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ request->status = HTTP_MOVED_PERMANENTLY;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ request->status = HTTP_SEE_OTHER;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ request->status = HTTP_NOT_MODIFIED;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ request->status = HTTP_TEMPORARY_REDIRECT;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ request->status = HTTP_BAD_REQUEST;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ request->status = HTTP_REQUEST_TIME_OUT;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ request->status = HTTP_CONFLICT;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ request->status = HTTP_GONE;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ request->status = HTTP_PRECONDITION_FAILED;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ request->status = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ request->status = HTTP_SERVICE_UNAVAILABLE;
+ break;
+ default:
+ request->status = HTTP_ACCEPTED;
+ break;
+ }
+ send_status = DONE;
+ }
+ }
+ }
+ if (send_status == DECLINED)
+ {
+ if (msg_ctx)
+ {
+ int size = 0;
+ int status_code;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list = axis2_msg_ctx_get_http_output_headers(msg_ctx, env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list, env);
+ }
+ while (size)
+ {
+ axis2_http_header_t *output_header = NULL;
+ size--;
+ output_header = (axis2_http_header_t *)
+ axutil_array_list_get(output_header_list, env, size);
+ apr_table_set(request->err_headers_out,
+ axis2_http_header_get_name(output_header, env),
+ axis2_http_header_get_value(output_header, env));
+ }
+
+ status_code = axis2_msg_ctx_get_status_code(msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ request->status = HTTP_CONTINUE;
+ break;
+ case AXIS2_HTTP_RESPONSE_OK_CODE_VAL:
+ request->status = HTTP_OK;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ request->status = HTTP_MULTIPLE_CHOICES;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ request->status = HTTP_MOVED_PERMANENTLY;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ request->status = HTTP_SEE_OTHER;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ request->status = HTTP_NOT_MODIFIED;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ request->status = HTTP_TEMPORARY_REDIRECT;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ request->status = HTTP_BAD_REQUEST;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ request->status = HTTP_REQUEST_TIME_OUT;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ request->status = HTTP_CONFLICT;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ request->status = HTTP_GONE;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ request->status = HTTP_PRECONDITION_FAILED;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ request->status = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ request->status = HTTP_SERVICE_UNAVAILABLE;
+ break;
+ case AXIS2_HTTP_RESPONSE_FORBIDDEN_CODE_VAL:
+ request->status = HTTP_FORBIDDEN;
+ break;
+ case AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL:
+ request->status = HTTP_UNAUTHORIZED;
+ break;
+ default:
+ request->status = HTTP_ACCEPTED;
+ break;
+ }
+
+ out_stream = axis2_msg_ctx_get_transport_out_stream(msg_ctx, env);
+ if (out_stream)
+ {
+ body_string = axutil_stream_get_buffer(out_stream, env);
+ body_string_len = axutil_stream_get_len(out_stream, env);
+ }
+ send_status = DONE;
+ }
+ else
+ {
+ request->status = HTTP_ACCEPTED;
+ send_status = DONE;
+ }
+ }
+ }
+ else
+ {
+ send_status = DONE;
+ request->status = HTTP_ACCEPTED;
+ }
+ }
+
+ if (content_language_header_value)
+ {
+ apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_CONTENT_LANGUAGE,
+ content_language_header_value);
+ }
+
+ if (op_ctx)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL,
+ *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+ axis2_char_t *msg_id = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+
+ /* In mtom case we send the attachment differently */
+
+ /* status = AXIS2_FAILURE means fault scenario. We are not
+ * doing MTOM for fault cases. */
+
+ if(status != AXIS2_FAILURE)
+ {
+ do_mtom = axis2_msg_ctx_get_doing_mtom(out_msg_ctx, env);
+ if(do_mtom)
+ {
+ mime_parts = axis2_msg_ctx_get_mime_parts(out_msg_ctx, env);
+ if(!mime_parts)
+ {
+ return AXIS2_FAILURE;
+ }
+ callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env ,
+ AXIS2_MTOM_SENDING_CALLBACK);
+ if(callback_name_param)
+ {
+ mtom_sending_callback_name =
+ (axis2_char_t *) axutil_param_get_value (callback_name_param, env);
+ }
+ }
+ }
+
+ if (out_msg_ctx)
+ {
+ axis2_msg_ctx_free(out_msg_ctx, env);
+ out_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
+ }
+
+ if (in_msg_ctx)
+ {
+ msg_id =
+ axutil_strdup(env, axis2_msg_ctx_get_msg_id(in_msg_ctx, env));
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(in_msg_ctx, env);
+ axis2_msg_ctx_reset_out_transport_info(in_msg_ctx, env);
+ axis2_msg_ctx_free(in_msg_ctx, env);
+ in_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL;
+ }
+
+ if (!axis2_op_ctx_is_in_use(op_ctx, env))
+ {
+ axis2_op_ctx_destroy_mutex(op_ctx, env);
+ if (conf_ctx && msg_id)
+ {
+ axis2_conf_ctx_register_op_ctx(conf_ctx, env, msg_id, NULL);
+ AXIS2_FREE(env->allocator, msg_id);
+ }
+ axis2_op_ctx_free(op_ctx, env);
+ }
+
+ } /* Done freeing message contexts */
+
+ /* We send the message in parts when doing MTOM */
+
+ if(do_mtom)
+ {
+ axis2_status_t mtom_status = AXIS2_FAILURE;
+
+ if(!mtom_sending_callback_name)
+ {
+ /* If the callback name is not there, then we will check whether there
+ * is any mime_parts which has type callback. If we found then no point
+ * of continuing we should return a failure */
+
+ if(!mtom_sending_callback_name)
+ {
+ if(axis2_http_transport_utils_is_callback_required(
+ env, mime_parts))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Sender callback not specified");
+ return AXIS2_FAILURE;
+ }
+ }
+ }
+
+ mtom_status = apache2_worker_send_mtom_message(request, env, mime_parts,
+ mtom_sending_callback_name);
+ if(mtom_status == AXIS2_SUCCESS)
+ {
+ send_status = DONE;
+ }
+ else
+ {
+ send_status = DECLINED;
+ }
+
+ axis2_http_transport_utils_destroy_mime_parts(mime_parts, env);
+ mime_parts = NULL;
+ }
+
+ else if (body_string)
+ {
+ ap_rwrite(body_string, body_string_len, request);
+ body_string = NULL;
+ }
+
+ if (request_body)
+ {
+ axutil_stream_free(request_body, env);
+ request_body = NULL;
+ }
+
+ axutil_string_free(soap_action, env);
+
+ msg_ctx = NULL;
+ return send_status;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_apache2_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_status = AXIS2_TRUE;
+
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, stream, NULL);
+
+ tmp_stream = axutil_stream_create_basic(env);
+ while(loop_status)
+ {
+ 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;
+}
+
+static axis2_status_t
+apache2_worker_send_mtom_message(
+ request_rec *request,
+ const axutil_env_t * env,
+ axutil_array_list_t *mime_parts,
+ axis2_char_t *mtom_sending_callback_name)
+{
+ int i = 0;
+ axiom_mime_part_t *mime_part = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+ /*int written = 0;*/
+ int len = 0;
+
+ if(mime_parts)
+ {
+ for(i = 0; i < axutil_array_list_size(mime_parts, env); i++)
+ {
+ mime_part = (axiom_mime_part_t *)axutil_array_list_get(mime_parts, env, i);
+ if((mime_part->type) == AXIOM_MIME_PART_BUFFER)
+ {
+ len = 0;
+ len = ap_rwrite(mime_part->part, (int)mime_part->part_size, request);
+ ap_rflush(request);
+ if(len == -1)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ }
+ else if((mime_part->type) == AXIOM_MIME_PART_FILE)
+ {
+ FILE *f = NULL;
+ axis2_byte_t *output_buffer = NULL;
+ int output_buffer_size = 0;
+
+ f = fopen(mime_part->file_name, "rb");
+ if(!f)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error opening file %s for reading",
+ mime_part->file_name);
+ return AXIS2_FAILURE;
+ }
+ if(mime_part->part_size > AXIS2_MTOM_OUTPUT_BUFFER_SIZE)
+ {
+ output_buffer_size = AXIS2_MTOM_OUTPUT_BUFFER_SIZE;
+ }
+ else
+ {
+ output_buffer_size = (int)mime_part->part_size;
+ }
+
+ output_buffer = AXIS2_MALLOC(env->allocator, (output_buffer_size + 1)
+ * sizeof(axis2_char_t));
+
+ status = apache2_worker_send_attachment_using_file(env, request, f, output_buffer,
+ output_buffer_size);
+ if(status == AXIS2_FAILURE)
+ {
+ return status;
+ }
+ }
+ else if((mime_part->type) == AXIOM_MIME_PART_CALLBACK)
+ {
+ void *handler = NULL;
+ axiom_mtom_sending_callback_t *callback = NULL;
+
+ handler = axis2_http_transport_utils_initiate_callback(env,
+ mtom_sending_callback_name, mime_part->user_param, &callback);
+
+ if(handler)
+ {
+ status = apache2_worker_send_attachment_using_callback(env, request, callback,
+ handler, mime_part->user_param);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MTOM Sending Callback loading failed");
+ status = AXIS2_FAILURE;
+ }
+ if(callback)
+ {
+ axutil_param_t *param = NULL;
+
+ param = callback->param;
+
+ AXIOM_MTOM_SENDING_CALLBACK_FREE(callback, env);
+ callback = NULL;
+
+ if(param)
+ {
+ axutil_param_free(param, env);
+ param = NULL;
+ }
+
+ }
+
+ if(status == AXIS2_FAILURE)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ if(status == AXIS2_FAILURE)
+ {
+ break;
+ }
+ }
+ return status;
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+}
+
+static axis2_status_t
+apache2_worker_send_attachment_using_file(
+ const axutil_env_t * env,
+ request_rec *request,
+ FILE *fp,
+ axis2_byte_t *buffer,
+ int buffer_size)
+{
+
+ int count = 0;
+ int len = 0;
+ /*int written = 0;*/
+ axis2_status_t status = AXIS2_SUCCESS;
+
+ do
+ {
+ count = (int)fread(buffer, 1, buffer_size + 1, fp);
+ if(ferror(fp))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in reading file containg the attachment");
+ if(buffer)
+ {
+ AXIS2_FREE(env->allocator, buffer);
+ buffer = NULL;
+ }
+ fclose(fp);
+ return AXIS2_FAILURE;
+ }
+
+ if(count > 0)
+ {
+ len = 0;
+ len = ap_rwrite(buffer, count, request);
+ ap_rflush(request);
+ if(len == -1)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ }
+ else
+ {
+ if(buffer)
+ {
+ AXIS2_FREE(env->allocator, buffer);
+ buffer = NULL;
+ }
+ fclose(fp);
+ return AXIS2_FAILURE;
+ }
+ memset(buffer, 0, buffer_size);
+ if(status == AXIS2_FAILURE)
+ {
+ if(buffer)
+ {
+ AXIS2_FREE(env->allocator, buffer);
+ buffer = NULL;
+ }
+ fclose(fp);
+ return AXIS2_FAILURE;
+ }
+ }
+ while(!feof(fp));
+
+ fclose(fp);
+ AXIS2_FREE(env->allocator, buffer);
+ buffer = NULL;
+ return AXIS2_SUCCESS;
+}
+
+static axis2_status_t
+apache2_worker_send_attachment_using_callback(
+ const axutil_env_t * env,
+ request_rec *request,
+ axiom_mtom_sending_callback_t *callback,
+ void *handler,
+ void *user_param)
+{
+ int count = 0;
+ int len = 0;
+ axis2_status_t status = AXIS2_SUCCESS;
+ axis2_char_t *buffer = NULL;
+
+ /* Keep on loading the data in a loop until
+ * all the data is sent */
+
+ while((count = AXIOM_MTOM_SENDING_CALLBACK_LOAD_DATA(callback, env, handler, &buffer)) > 0)
+ {
+ len = 0;
+ len = ap_rwrite(buffer, count, request);
+ ap_rflush(request);
+ if(len == -1)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ }
+
+ if(status == AXIS2_FAILURE)
+ {
+ AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, handler);
+ return status;
+ }
+
+ status = AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, handler);
+ return status;
+}
+
+
+static axutil_hash_t*
+axis2_apache_worker_get_headers(
+ const axutil_env_t *env,
+ request_rec *request)
+{
+ int i = 0;
+ axutil_hash_t *header_map = NULL;
+ const apr_array_header_t *tarr;
+ const apr_table_entry_t *telts;
+ axis2_http_header_t * tmp_http_header = NULL;
+
+
+ header_map = axutil_hash_make(env);
+ tarr = apr_table_elts(request->headers_in);
+ telts = (const apr_table_entry_t*)tarr->elts;
+
+ for (i = 0; i < tarr->nelts; i++)
+ {
+ axis2_char_t* tmp_key = (axis2_char_t*) telts[i].key;
+ axis2_char_t* tmp_value = (axis2_char_t*) telts[i].val;
+ tmp_http_header = axis2_http_header_create(env, tmp_key, tmp_value);
+ axutil_hash_set(header_map, tmp_key, AXIS2_HASH_KEY_STRING, tmp_http_header);
+ }
+
+ return header_map;
+
+
+}
diff --git a/src/core/transport/http/server/apache2/axis2_apache2_out_transport_info.h b/src/core/transport/http/server/apache2/axis2_apache2_out_transport_info.h
new file mode 100644
index 0000000..9ab9250
--- /dev/null
+++ b/src/core/transport/http/server/apache2/axis2_apache2_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_APACHE2_OUT_TRANSPORT_INFO_H
+#define AXIS2_APACHE2_OUT_TRANSPORT_INFO_H
+
+/**
+ * @ingroup axis2_core_transport_http
+ * @{
+ */
+
+/**
+ * @file axis2_apache2_out_transport_info.h
+ * @brief axis2 Apache2 Out Transport Info
+ */
+
+#include <axis2_http_out_transport_info.h>
+#include <httpd.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ AXIS2_EXTERN axis2_http_out_transport_info_t *AXIS2_CALL
+
+ axis2_apache2_out_transport_info_create(
+ const axutil_env_t * env,
+ request_rec * r);
+
+ /**
+ * 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
+ */
+ AXIS2_EXTERN void AXIS2_CALL
+
+ axis2_apache2_out_transport_info_free_void_arg(
+ void *transport_info,
+ const axutil_env_t * env);
+
+ /** @} */
+#ifdef __cplusplus
+}
+#endif
+#endif /* AXIS2_APACHE2_OUT_TRANSPORT_INFO_H */
diff --git a/src/core/transport/http/server/apache2/axis2_apache2_worker.h b/src/core/transport/http/server/apache2/axis2_apache2_worker.h
new file mode 100644
index 0000000..eea4033
--- /dev/null
+++ b/src/core/transport/http/server/apache2/axis2_apache2_worker.h
@@ -0,0 +1,78 @@
+
+/*
+ * 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
+
+/**
+ * @brief Apache2 Worker ops struct
+ * Encapsulator struct for ops of axis2_apache2_worker
+ */
+
+/**
+ * @ingroup axis2_core_transport_http
+ * @{
+ */
+
+/**
+ * @file axis2_apache2_worker.h
+ * @brief axis2 Apache2 Worker
+ */
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axis2_conf_ctx.h>
+#include "apache2_stream.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct axis2_apache2_worker axis2_apache2_worker_t;
+
+ AXIS2_EXTERN int AXIS2_CALL
+ axis2_apache2_worker_process_request(
+ axis2_apache2_worker_t * apache2_worker,
+ const axutil_env_t * env,
+ request_rec * r);
+
+ AXIS2_EXTERN void AXIS2_CALL
+ axis2_apache2_worker_free(
+ axis2_apache2_worker_t * apache2_worker,
+ const axutil_env_t * env);
+
+ AXIS2_EXTERN axis2_apache2_worker_t *AXIS2_CALL
+
+ axis2_apache2_worker_create(
+ const axutil_env_t * env,
+ axis2_char_t * repo_path);
+
+#define AXIS2_APACHE2_WORKER_PROCESS_REQUEST(apache2_worker, env, request) \
+ axis2_apache2_worker_process_request(\
+ apache2_worker, env, request)
+#define AXIS2_APACHE2_WORKER_FREE(apache2_worker, env) \
+ axis2_apache2_worker_free(apache2_worker, env)
+
+ /** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AXIS2_APACHE2_WORKER_H */
diff --git a/src/core/transport/http/server/apache2/mod_axis2.c b/src/core/transport/http/server/apache2/mod_axis2.c
new file mode 100644
index 0000000..a9431eb
--- /dev/null
+++ b/src/core/transport/http/server/apache2/mod_axis2.c
@@ -0,0 +1,844 @@
+/*
+ * 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 <httpd.h>
+#include <http_config.h>
+#include <http_log.h>
+#include <http_protocol.h>
+#include <ap_config.h>
+#include <apr_strings.h>
+#include "axis2_apache2_worker.h"
+#include <axutil_error_default.h>
+#include <axutil_log_default.h>
+#include <axutil_thread_pool.h>
+#include <axiom_xml_reader.h>
+#include <axutil_version.h>
+#include <apr_rmm.h>
+#include <apr_shm.h>
+#include <apr_dbd.h>
+#include <mod_dbd.h>
+#include <axis2_http_transport.h>
+#include <axutil_types.h>
+
+/* Configuration structure populated by apache2.conf */
+typedef struct axis2_config_rec
+{
+ char *axutil_log_file;
+ char *axis2_repo_path;
+ axutil_log_levels_t log_level;
+ int max_log_file_size;
+ int axis2_global_pool_size;
+} axis2_config_rec_t;
+
+axis2_apache2_worker_t *axis2_worker = NULL;
+axutil_env_t *axutil_env = NULL;
+apr_rmm_t* rmm = NULL;
+apr_global_mutex_t *global_mutex = NULL;
+
+/******************************Function Headers********************************/
+static void *
+axis2_create_svr(
+ apr_pool_t * p,
+ server_rec * s);
+
+static const char *
+axis2_set_repo_path(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg);
+
+static const char *
+axis2_set_log_file(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg);
+
+static const char *
+axis2_set_max_log_file_size(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg);
+
+static const char *
+axis2_set_global_pool_size(
+ cmd_parms * cmd,
+ void * dummy,
+ const char *arg);
+
+static const char *
+axis2_set_log_level(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg);
+
+static const char *
+axis2_set_svc_url_prefix(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg);
+
+static int
+axis2_handler(
+ request_rec * req);
+
+/* Shutdown Axis2 */
+apr_status_t
+axis2_shutdown(
+ void *tmp);
+
+void *AXIS2_CALL axis2_module_malloc(
+ axutil_allocator_t * allocator,
+ size_t size);
+
+void *AXIS2_CALL axis2_module_realloc(
+ axutil_allocator_t * allocator,
+ void *ptr,
+ size_t size);
+
+void AXIS2_CALL axis2_module_free(
+ axutil_allocator_t * allocator,
+ void *ptr);
+
+static void
+axis2_module_init(
+ apr_pool_t * p,
+ server_rec * svr_rec);
+
+static void
+axis2_register_hooks(
+ apr_pool_t * p);
+
+char *
+axis2_get_session(
+ void *req,
+ const char *id);
+
+axis2_status_t
+axis2_set_session(
+ void *req,
+ const char *id,
+ const char *session);
+
+/***************************End of Function Headers****************************/
+
+static const command_rec axis2_cmds[] = { AP_INIT_TAKE1("Axis2RepoPath", axis2_set_repo_path, NULL,
+ RSRC_CONF, "Axis2/C repository path"), AP_INIT_TAKE1("Axis2LogFile", axis2_set_log_file, NULL,
+ RSRC_CONF, "Axis2/C log file name"), AP_INIT_TAKE1("Axis2LogLevel", axis2_set_log_level, NULL,
+ RSRC_CONF, "Axis2/C log level"), AP_INIT_TAKE1("Axis2MaxLogFileSize",
+ axis2_set_max_log_file_size, NULL, RSRC_CONF, "Axis2/C maximum log file size"),
+ AP_INIT_TAKE1("Axis2GlobalPoolSize", axis2_set_global_pool_size, NULL, RSRC_CONF,
+ "Axis2/C global pool size"), AP_INIT_TAKE1("Axis2ServiceURLPrefix",
+ axis2_set_svc_url_prefix, NULL, RSRC_CONF, "Axis2/C service URL prifix"),
+ { NULL } };
+
+/* Dispatch list for API hooks */
+module AP_MODULE_DECLARE_DATA axis2_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ axis2_create_svr, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ axis2_cmds, /* table of config file commands */
+ axis2_register_hooks /* register hooks */
+ };
+
+static void *
+axis2_create_svr(
+ apr_pool_t * p,
+ server_rec * s)
+{
+ axis2_config_rec_t *conf = apr_palloc(p, sizeof(*conf));
+ conf->axutil_log_file = NULL;
+ conf->axis2_repo_path = NULL;
+ conf->log_level = AXIS2_LOG_LEVEL_DEBUG;
+ conf->axis2_global_pool_size = 0;
+ conf->max_log_file_size = 1;
+ return conf;
+}
+
+static const char *
+axis2_set_repo_path(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg)
+{
+ axis2_config_rec_t *conf = NULL;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if(err != NULL)
+ {
+ return err;
+ }
+ conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module);
+ conf->axis2_repo_path = apr_pstrdup(cmd->pool, arg);
+ return NULL;
+}
+
+static const char *
+axis2_set_log_file(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg)
+{
+ axis2_config_rec_t *conf = NULL;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if(err != NULL)
+ {
+ return err;
+ }
+
+ conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module);
+ conf->axutil_log_file = apr_pstrdup(cmd->pool, arg);
+ return NULL;
+}
+
+static const char *
+axis2_set_max_log_file_size(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg)
+{
+ axis2_config_rec_t *conf = NULL;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if(err != NULL)
+ {
+ return err;
+ }
+
+ conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module);
+ conf->max_log_file_size = 1024 * 1024 * atoi(arg);
+ return NULL;
+}
+
+static const char *
+axis2_set_global_pool_size(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg)
+{
+ axis2_config_rec_t *conf = NULL;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if(err != NULL)
+ {
+ return err;
+ }
+
+ conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module);
+ conf->axis2_global_pool_size = 1024 * 1024 * atoi(arg);
+ return NULL;
+}
+
+static const char *
+axis2_set_log_level(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg)
+{
+ char *str;
+ axutil_log_levels_t level = AXIS2_LOG_LEVEL_DEBUG;
+ axis2_config_rec_t *conf = NULL;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if(err != NULL)
+ {
+ return err;
+ }
+
+ conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module);
+
+ str = ap_getword_conf(cmd->pool, &arg);
+ if(str)
+ {
+ if(!strcasecmp(str, "crit"))
+ {
+ level = AXIS2_LOG_LEVEL_CRITICAL;
+ }
+ else if(!strcasecmp(str, "error"))
+ {
+ level = AXIS2_LOG_LEVEL_ERROR;
+ }
+ else if(!strcasecmp(str, "warn"))
+ {
+ level = AXIS2_LOG_LEVEL_WARNING;
+ }
+ else if(!strcasecmp(str, "info"))
+ {
+ level = AXIS2_LOG_LEVEL_INFO;
+ }
+ else if(!strcasecmp(str, "debug"))
+ {
+ level = AXIS2_LOG_LEVEL_DEBUG;
+ }
+ else if(!strcasecmp(str, "user"))
+ {
+ level = AXIS2_LOG_LEVEL_USER;
+ }
+ else if(!strcasecmp(str, "trace"))
+ {
+ level = AXIS2_LOG_LEVEL_TRACE;
+ }
+ }
+ conf->log_level = level;
+ return NULL;
+}
+
+static const char *
+axis2_set_svc_url_prefix(
+ cmd_parms * cmd,
+ void *dummy,
+ const char *arg)
+{
+ AXIS2_IMPORT extern axis2_char_t *axis2_request_url_prefix;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ axis2_request_url_prefix = AXIS2_REQUEST_URL_PREFIX;
+ if(!err)
+ {
+ axis2_char_t *prefix = apr_pstrdup(cmd->pool, arg);
+ if(prefix)
+ axis2_request_url_prefix = prefix;
+ }
+
+ return NULL;
+}
+
+/* The sample content handler */
+static int
+axis2_handler(
+ request_rec * req)
+{
+ int rv = 0;
+ axutil_env_t *thread_env = NULL;
+ axutil_allocator_t *allocator = NULL;
+ axutil_error_t *error = NULL;
+
+ apr_allocator_t *local_allocator = NULL;
+ apr_pool_t *local_pool = NULL;
+
+ if(strcmp(req->handler, "axis2_module"))
+ {
+ return DECLINED;
+ }
+
+ /* Set up the read policy from the client. */
+ if((rv = ap_setup_client_block(req, REQUEST_CHUNKED_DECHUNK)) != OK)
+ {
+ return rv;
+ }
+ ap_should_client_block(req);
+
+ apr_allocator_create(&local_allocator);
+ apr_pool_create_ex(&local_pool, NULL, NULL, local_allocator);
+
+ /*thread_env = axutil_init_thread_env(axutil_env);*/
+
+ /*axutil_env->allocator->current_pool = (void *) req->pool;
+ rv = AXIS2_APACHE2_WORKER_PROCESS_REQUEST(axis2_worker, axutil_env, req);*/
+
+ /* create new allocator for this request */
+ /*allocator = (axutil_allocator_t *) apr_palloc(req->pool,
+ sizeof(axutil_allocator_t));*/
+
+ allocator = (axutil_allocator_t *)apr_palloc(local_pool, sizeof(axutil_allocator_t));
+
+ if(!allocator)
+ {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ allocator->malloc_fn = axis2_module_malloc;
+ allocator->realloc = axis2_module_realloc;
+ allocator->free_fn = axis2_module_free;
+ allocator->global_pool_ref = 0;
+ allocator->local_pool = (void *)local_pool;
+ allocator->current_pool = (void *)local_pool;
+ allocator->global_pool = axutil_env->allocator->global_pool;
+
+ error = axutil_error_create(allocator);
+ thread_env = axutil_env_create_with_error_log_thread_pool(allocator, error, axutil_env->log,
+ axutil_env-> thread_pool);
+ thread_env->allocator = allocator;
+ thread_env->set_session_fn = axis2_set_session;
+ thread_env->get_session_fn = axis2_get_session;
+
+ rv = AXIS2_APACHE2_WORKER_PROCESS_REQUEST(axis2_worker, thread_env, req);
+ if(AXIS2_CRITICAL_FAILURE == rv)
+ {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ apr_pool_destroy(local_pool);
+ apr_allocator_destroy(local_allocator);
+
+ return rv;
+}
+
+void *AXIS2_CALL
+axis2_module_malloc(
+ axutil_allocator_t * allocator,
+ size_t size)
+{
+#if APR_HAS_SHARED_MEMORY
+ if (rmm == allocator->current_pool)
+ {
+
+ void* ptr = NULL;
+ apr_rmm_off_t offset;
+ apr_global_mutex_lock(global_mutex);
+ offset = apr_rmm_malloc(rmm, size);
+ if (offset)
+ ptr = apr_rmm_addr_get(rmm, offset);
+ apr_global_mutex_unlock(global_mutex);
+ return ptr;
+ }
+#endif
+ return apr_palloc((apr_pool_t *)(allocator->current_pool), size);
+}
+
+void *AXIS2_CALL
+axis2_module_realloc(
+ axutil_allocator_t * allocator,
+ void *ptr,
+ size_t size)
+{
+#if APR_HAS_SHARED_MEMORY
+ if (rmm == allocator->current_pool)
+ {
+ void* ptr = NULL;
+ apr_rmm_off_t offset;
+ apr_global_mutex_lock(global_mutex);
+ offset = apr_rmm_realloc(rmm, ptr, size);
+ if (offset)
+ ptr = apr_rmm_addr_get(rmm, offset);
+ apr_global_mutex_unlock(global_mutex);
+ return ptr;
+ }
+#endif
+ /* can't be easily implemented */
+ return NULL;
+}
+
+void AXIS2_CALL
+axis2_module_free(
+ axutil_allocator_t * allocator,
+ void *ptr)
+{
+#if APR_HAS_SHARED_MEMORY
+ if (rmm == allocator->current_pool)
+ {
+ apr_rmm_off_t offset;
+ apr_global_mutex_lock(global_mutex);
+ offset = apr_rmm_offset_get(rmm, ptr);
+ apr_rmm_free(rmm, offset);
+ apr_global_mutex_unlock(global_mutex);
+ }
+#endif
+}
+
+static int
+axis2_post_config(
+ apr_pool_t *pconf,
+ apr_pool_t *plog,
+ apr_pool_t *ptemp,
+ server_rec *svr_rec)
+{
+ apr_status_t status = APR_SUCCESS;
+ axutil_allocator_t *allocator = NULL;
+ axutil_error_t *error = NULL;
+ axutil_log_t *axutil_logger = NULL;
+ axutil_thread_pool_t *thread_pool = NULL;
+ void *data = NULL;
+ const char *userdata_key = "axis2_init";
+ axis2_config_rec_t *conf = (axis2_config_rec_t *)ap_get_module_config(svr_rec->module_config,
+ &axis2_module);
+
+ /* axis2_post_config() will be called twice. Don't bother
+ * going through all of the initialization on the first call
+ * because it will just be thrown away.*/
+
+ ap_add_version_component(pconf, AXIS2_HTTP_HEADER_SERVER_AXIS2C);
+
+ apr_pool_userdata_get(&data, userdata_key, svr_rec->process->pool);
+ if(!data)
+ {
+ apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null,
+ svr_rec->process->pool);
+ return OK;
+ }
+
+#if APR_HAS_SHARED_MEMORY
+ if (conf->axis2_global_pool_size > 0)
+ {
+ apr_shm_t *shm;
+ apr_rmm_off_t offset;
+
+ status = apr_shm_create(&shm, conf->axis2_global_pool_size, NULL, pconf);
+ if (status != APR_SUCCESS)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec,
+ "[Axis2] Error creating shared memory pool");
+ exit(APEXIT_INIT);
+ }
+
+ status = apr_rmm_init(&rmm, NULL, apr_shm_baseaddr_get(shm), conf->axis2_global_pool_size,
+ pconf);
+ if (status != APR_SUCCESS)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec,
+ "[Axis2] Error creating relocatable memory pool");
+ exit(APEXIT_INIT);
+ }
+
+ status = apr_global_mutex_create(&global_mutex, NULL,
+ APR_LOCK_DEFAULT, pconf);
+ if (status != APR_SUCCESS)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec,
+ "[Axis2] Error creating global mutex");
+ exit(APEXIT_INIT);
+ }
+
+ /*status = unixd_set_global_mutex_perms(global_mutex);
+ if (status != APR_SUCCESS)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec,
+ "[Axis2] Permision cannot be set to global mutex");
+ exit(APEXIT_INIT);
+ }
+ */
+
+ offset = apr_rmm_malloc(rmm, sizeof(axutil_allocator_t));
+ if (!offset)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec,
+ "[Axis2] Error in creating allocator in global pool");
+ exit(APEXIT_INIT);
+ }
+ allocator = apr_rmm_addr_get(rmm, offset);
+ allocator->malloc_fn = axis2_module_malloc;
+ allocator->realloc = axis2_module_realloc;
+ allocator->free_fn = axis2_module_free;
+ allocator->global_pool_ref = 0;
+ allocator->local_pool = (void *) rmm;
+ allocator->current_pool = (void *) rmm;
+ allocator->global_pool = (void *) rmm;
+
+ /* We need to init xml readers before we go into threaded env
+ */
+ axiom_xml_reader_init();
+ axutil_error_init();
+
+ error = axutil_error_create(allocator);
+ if (!error)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error creating mod_axis2 error structure");
+ exit(APEXIT_CHILDFATAL);
+ }
+
+ axutil_logger = axutil_log_create(allocator, NULL, conf->axutil_log_file);
+ if (!axutil_logger)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error creating mod_axis2 log structure");
+ exit(APEXIT_CHILDFATAL);
+ }
+ thread_pool = axutil_thread_pool_init(allocator);
+ if (!thread_pool)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error initializing mod_axis2 thread pool");
+ exit(APEXIT_CHILDFATAL);
+ }
+ axutil_env = axutil_env_create_with_error_log_thread_pool(allocator, error,
+ axutil_logger,
+ thread_pool);
+ if (!axutil_env)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error creating mod_axis2 environment");
+ exit(APEXIT_CHILDFATAL);
+ }
+ if (axutil_logger)
+ {
+ axutil_logger->level = conf->log_level;
+ axutil_logger->size = conf->max_log_file_size;
+ AXIS2_LOG_INFO(axutil_env->log, "Apache Axis2/C version in use : %s",
+ axis2_version_string());
+ AXIS2_LOG_INFO(axutil_env->log,
+ "Starting log with log level %d and max log file size %d",
+ conf->log_level, conf->max_log_file_size);
+ }
+ axutil_env->set_session_fn = axis2_set_session;
+ axutil_env->get_session_fn = axis2_get_session;
+
+ axis2_worker = axis2_apache2_worker_create(axutil_env,
+ conf->axis2_repo_path);
+ if (!axis2_worker)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error creating mod_axis2 apache2 worker");
+ exit(APEXIT_CHILDFATAL);
+ }
+ }
+
+#endif
+
+ return OK;
+}
+
+static void
+axis2_module_init(
+ apr_pool_t * p,
+ server_rec * svr_rec)
+{
+ apr_pool_t *pool;
+ apr_status_t status;
+ axutil_allocator_t *allocator = NULL;
+ axutil_error_t *error = NULL;
+ axutil_log_t *axutil_logger = NULL;
+ axutil_thread_pool_t *thread_pool = NULL;
+ axis2_config_rec_t *conf = (axis2_config_rec_t*)ap_get_module_config(svr_rec->module_config,
+ &axis2_module);
+
+ if(conf->axis2_global_pool_size > 0)
+ {
+ /*
+ If we are using shared memory, no need to init the child, as the
+ worker has been created in post config.
+ */
+ return;
+ }
+
+ /* We need to init xml readers before we go into threaded env
+ */
+ axiom_xml_reader_init();
+
+ /* create an allocator that uses APR memory pools and lasts the
+ * lifetime of the httpd server child process
+ */
+ status = apr_pool_create(&pool, p);
+ if(status)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec,
+ "[Axis2] Error allocating mod_axis2 memory pool");
+ exit(APEXIT_CHILDFATAL);
+ }
+ allocator = (axutil_allocator_t*)apr_palloc(pool, sizeof(axutil_allocator_t));
+ if(!allocator)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_ENOMEM, svr_rec,
+ "[Axis2] Error allocating mod_axis2 allocator");
+ exit(APEXIT_CHILDFATAL);
+ }
+ allocator->malloc_fn = axis2_module_malloc;
+ allocator->realloc = axis2_module_realloc;
+ allocator->free_fn = axis2_module_free;
+ allocator->global_pool_ref = 0;
+ allocator->local_pool = (void*)pool;
+ allocator->current_pool = (void*)pool;
+ allocator->global_pool = (void*)pool;
+
+ if(!allocator)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error initializing mod_axis2 allocator");
+ exit(APEXIT_CHILDFATAL);
+ }
+
+ axutil_error_init();
+
+ error = axutil_error_create(allocator);
+ if(!error)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error creating mod_axis2 error structure");
+ exit(APEXIT_CHILDFATAL);
+ }
+ axutil_logger = axutil_log_create(allocator, NULL, conf->axutil_log_file);
+ if(!axutil_logger)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error creating mod_axis2 log structure");
+ exit(APEXIT_CHILDFATAL);
+ }
+ thread_pool = axutil_thread_pool_init(allocator);
+ if(!thread_pool)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error initializing mod_axis2 thread pool");
+ exit(APEXIT_CHILDFATAL);
+ }
+ axutil_env = axutil_env_create_with_error_log_thread_pool(allocator, error, axutil_logger,
+ thread_pool);
+ if(!axutil_env)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error creating mod_axis2 environment");
+ exit(APEXIT_CHILDFATAL);
+ }
+ if(axutil_logger)
+ {
+
+ axutil_logger->level = conf->log_level;
+ AXIS2_LOG_INFO(axutil_env->log, "Apache Axis2/C version in use : %s",
+ axis2_version_string());
+ AXIS2_LOG_INFO(axutil_env->log, "Starting log with log level %d", conf->log_level);
+ }
+ axutil_env->set_session_fn = axis2_set_session;
+ axutil_env->get_session_fn = axis2_get_session;
+ axis2_worker = axis2_apache2_worker_create(axutil_env, conf->axis2_repo_path);
+ if(!axis2_worker)
+ {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec,
+ "[Axis2] Error creating mod_axis2 apache2 worker");
+ exit(APEXIT_CHILDFATAL);
+ }
+
+ /*ap_dbd_prepare(svr_rec, "SELECT value FROM session WHERE id = %s", "retrieve_session");
+ ap_dbd_prepare(svr_rec, "INSERT INTO session VALUES(?,?)", "insert_session");*/
+
+
+ /* If we are initialized we register a clean up as well */
+ /* apr_pool_cleanup_register(p, NULL, axis2_shutdown, apr_pool_cleanup_null);*/
+}
+
+static void
+axis2_register_hooks(
+ apr_pool_t * p)
+{
+ ap_hook_post_config(axis2_post_config, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_handler(axis2_handler, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_child_init(axis2_module_init, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+apr_status_t
+axis2_shutdown(
+ void *tmp)
+{
+ if(axis2_worker)
+ {
+ axis2_apache2_worker_free(axis2_worker, axutil_env);
+ }
+ return APR_SUCCESS;
+}
+
+char *
+axis2_get_session(
+ void *req,
+ const char *id)
+{
+ request_rec *request = NULL;
+ apr_status_t rv;
+ const char *dbd_session = NULL;
+ apr_dbd_prepared_t *statement;
+ apr_dbd_results_t *res = NULL;
+ apr_dbd_row_t *row = NULL;
+ ap_dbd_t *dbd = NULL;
+ ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL;
+ request = (request_rec *) req;
+
+ authn_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
+ dbd = authn_dbd_acquire_fn(request);
+ if (!dbd)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request,
+ "Failed to acquire database connection to look up "
+ "id '%s'", id);
+ return NULL;
+ }
+
+ statement = apr_hash_get(dbd->prepared, "retrieve_session", APR_HASH_KEY_STRING);
+ if (!statement)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request,
+ "A prepared statement could not be found for "
+ "the key '%s'", "retrieve_session");
+ return NULL;
+ }
+ if (apr_dbd_pvselect(dbd->driver, request->pool, dbd->handle, &res, statement,
+ 0, id, NULL) != 0)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request,
+ "Query execution error looking up '%s' "
+ "in database", id);
+ return NULL;
+ }
+ for (rv = apr_dbd_get_row(dbd->driver, request->pool, res, &row, -1); rv != -1;
+ rv = apr_dbd_get_row(dbd->driver, request->pool, res, &row, -1))
+ {
+ if (rv != 0)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, request,
+ "Error retrieving results while looking up '%s' "
+ "in database", id);
+ return NULL;
+ }
+ if (!dbd_session)
+ {
+ dbd_session = apr_dbd_get_entry(dbd->driver, row, 0);
+ }
+ /* we can't break out here or row won't get cleaned up */
+ }
+
+ if (!dbd_session)
+ {
+ return NULL;
+ }
+
+ return (char *) dbd_session;
+}
+
+axis2_status_t
+axis2_set_session(
+ void *req,
+ const char *id,
+ const char *session)
+{
+ request_rec *request = NULL;
+ apr_dbd_prepared_t *statement;
+ int affected_rows = -1;
+ ap_dbd_t *dbd = NULL;
+ ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL;
+ request = (request_rec *) req;
+
+ authn_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
+ dbd = authn_dbd_acquire_fn(request);
+ if (!dbd)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request,
+ "Failed to acquire database connection to insert session for "
+ "id '%s'", id);
+ return AXIS2_FAILURE;
+ }
+
+ statement = apr_hash_get(dbd->prepared, "insert_session", APR_HASH_KEY_STRING);
+ if (!statement)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request,
+ "A prepared statement could not be found for "
+ "the key '%s'", "insert_session");
+ return AXIS2_FAILURE;
+ }
+ if (apr_dbd_pvquery(dbd->driver, request->pool, dbd->handle, &affected_rows, statement, id,
+ session, NULL) != 0)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request,
+ "Query execution error inserting session for '%s' "
+ "in database", id);
+ return AXIS2_FAILURE;
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+
diff --git a/src/core/transport/http/server/simple_axis2_server/Makefile.am b/src/core/transport/http/server/simple_axis2_server/Makefile.am
new file mode 100644
index 0000000..604851d
--- /dev/null
+++ b/src/core/transport/http/server/simple_axis2_server/Makefile.am
@@ -0,0 +1,30 @@
+prgbindir=$(bindir)
+prgbin_PROGRAMS = axis2_http_server
+SUBDIRS =
+AM_CFLAGS = -g -pthread
+axis2_http_server_SOURCES = http_server_main.c
+
+axis2_http_server_LDADD = $(LDFLAGS) \
+ $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la \
+ $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la \
+ $(top_builddir)/axiom/src/om/libaxis2_axiom.la \
+ $(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la \
+ $(top_builddir)/src/core/description/libaxis2_description.la \
+ $(top_builddir)/src/core/deployment/libaxis2_deployment.la \
+ $(top_builddir)/src/core/context/libaxis2_context.la \
+ $(top_builddir)/src/core/clientapi/libaxis2_clientapi.la \
+ $(top_builddir)/src/core/engine/libaxis2_engine.la \
+ $(top_builddir)/src/core/transport/http/sender/libaxis2_http_sender.la \
+ $(top_builddir)/src/core/transport/http/receiver/libaxis2_http_receiver.la \
+ $(top_builddir)/neethi/src/libneethi.la \
+ -lpthread
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/description\
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/deployment\
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
diff --git a/src/core/transport/http/server/simple_axis2_server/http_server_main.c b/src/core/transport/http/server/simple_axis2_server/http_server_main.c
new file mode 100644
index 0000000..cfbcda4
--- /dev/null
+++ b/src/core/transport/http/server/simple_axis2_server/http_server_main.c
@@ -0,0 +1,310 @@
+/*
+ * 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_server.h>
+#include <axis2_http_transport.h>
+#include <platforms/axutil_platform_auto_sense.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <axutil_error_default.h>
+#include <axutil_log_default.h>
+#include <axutil_thread_pool.h>
+#include <signal.h>
+#include <axutil_types.h>
+#include <ctype.h>
+#include <axiom_xml_reader.h>
+#include <axutil_version.h>
+#include <axutil_file_handler.h>
+
+axutil_env_t *system_env = NULL;
+axis2_transport_receiver_t *server = NULL;
+AXIS2_IMPORT extern int axis2_http_socket_read_timeout;
+AXIS2_IMPORT extern axis2_char_t *axis2_request_url_prefix;
+
+#define DEFAULT_REPO_PATH "../"
+
+/***************************** Function headers *******************************/
+axutil_env_t *
+init_syetem_env(
+ axutil_allocator_t * allocator,
+ const axis2_char_t * log_file);
+
+void
+system_exit(
+ axutil_env_t * env,
+ int status);
+
+void
+usage(
+ axis2_char_t * prog_name);
+
+void
+sig_handler(
+ int signal);
+
+/***************************** End of function headers ************************/
+axutil_env_t *
+init_syetem_env(
+ axutil_allocator_t * allocator,
+ const axis2_char_t * log_file)
+{
+ axutil_error_t *error = axutil_error_create(allocator);
+ axutil_log_t *log = axutil_log_create(allocator, NULL, log_file);
+ /* if (!log) */
+
+ /* log = axutil_log_create_default (allocator); */
+ axutil_thread_pool_t *thread_pool = axutil_thread_pool_init(allocator);
+ /* We need to init the parser in main thread before spawning child
+ * threads
+ */
+ axiom_xml_reader_init();
+ return axutil_env_create_with_error_log_thread_pool(allocator, error, log, thread_pool);
+}
+
+void
+system_exit(
+ axutil_env_t * env,
+ int status)
+{
+ axutil_allocator_t *allocator = NULL;
+ if(server)
+ {
+ axis2_transport_receiver_free(server, system_env);
+ }
+ if(env)
+ {
+ allocator = env->allocator;
+ axutil_env_free(env);
+ }
+ /*axutil_allocator_free(allocator); */
+ axiom_xml_reader_cleanup();
+ exit(status);
+}
+
+int
+main(
+ int argc,
+ char *argv[])
+{
+ axutil_allocator_t *allocator = NULL;
+ axutil_env_t *env = NULL;
+ extern char *optarg;
+ extern int optopt;
+ int c;
+ unsigned int len;
+ int log_file_size = AXUTIL_LOG_FILE_SIZE;
+ unsigned int file_flag = 0;
+ axutil_log_levels_t log_level = AXIS2_LOG_LEVEL_DEBUG;
+ const axis2_char_t *log_file = "axis2.log";
+ const axis2_char_t *repo_path = DEFAULT_REPO_PATH;
+ int port = 9090;
+ axis2_status_t status;
+
+ /* Set the service URL prefix to be used. This could default to services if not
+ set with AXIS2_REQUEST_URL_PREFIX macro at compile time */
+ axis2_request_url_prefix = AXIS2_REQUEST_URL_PREFIX;
+
+ while((c = AXIS2_GETOPT(argc, argv, ":p:r:ht:l:s:f:")) != -1)
+ {
+
+ switch(c)
+ {
+ case 'p':
+ port = AXIS2_ATOI(optarg);
+ break;
+ case 'r':
+ repo_path = optarg;
+ break;
+ case 't':
+ axis2_http_socket_read_timeout = AXIS2_ATOI(optarg) * 1000;
+ break;
+ case 'l':
+ log_level = AXIS2_ATOI(optarg);
+ if(log_level < AXIS2_LOG_LEVEL_CRITICAL)
+ log_level = AXIS2_LOG_LEVEL_CRITICAL;
+ if(log_level > AXIS2_LOG_LEVEL_TRACE)
+ log_level = AXIS2_LOG_LEVEL_TRACE;
+ break;
+ case 's':
+ log_file_size = 1024 * 1024 * AXIS2_ATOI(optarg);
+ break;
+ case 'f':
+ log_file = optarg;
+ break;
+ case 'h':
+ usage(argv[0]);
+ return 0;
+ case ':':
+ fprintf(stderr, "\nOption -%c requires an operand\n", optopt);
+ usage(argv[0]);
+ return -1;
+ case '?':
+ if(isprint(optopt))
+ fprintf(stderr, "\nUnknown option `-%c'.\n", optopt);
+ usage(argv[0]);
+ return -1;
+ }
+ }
+
+ allocator = axutil_allocator_init(NULL);
+
+ if(!allocator)
+ {
+ system_exit(NULL, -1);
+ }
+
+ env = init_syetem_env(allocator, log_file);
+ env->log->level = log_level;
+ env->log->size = log_file_size;
+
+ axutil_error_init();
+ system_env = env;
+
+ signal(SIGINT, sig_handler);
+#ifndef WIN32
+ signal(SIGPIPE, sig_handler);
+#endif
+
+ AXIS2_LOG_INFO(env->log, "Starting Axis2 HTTP server....");
+ AXIS2_LOG_INFO(env->log, "Apache Axis2/C version in use : %s", axis2_version_string());
+ AXIS2_LOG_INFO(env->log, "Server port : %d", port);
+ AXIS2_LOG_INFO(env->log, "Repo location : %s", repo_path);
+ AXIS2_LOG_INFO(env->log, "Read Timeout : %d ms", axis2_http_socket_read_timeout);
+
+ status = axutil_file_handler_access(repo_path, AXIS2_R_OK);
+ if(status == AXIS2_SUCCESS)
+ {
+ len = (unsigned int)strlen(repo_path);
+ /* We are sure that the difference lies within the unsigned int range */
+ if((len >= 9) && !strcmp((repo_path + (len - 9)), "axis2.xml"))
+ {
+ file_flag = 1;
+ }
+ }
+ else
+ {
+ AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "provided repo path %s does "
+ "not exist or no permissions to read, set "
+ "repo_path to DEFAULT_REPO_PATH", repo_path);
+ repo_path = DEFAULT_REPO_PATH;
+ }
+
+ if(!file_flag)
+ server = axis2_http_server_create(env, repo_path, port);
+ else
+ server = axis2_http_server_create_with_file(env, repo_path, port);
+
+ if(!server)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Server creation failed: Error code:" " %d :: %s",
+ env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error));
+ system_exit(env, -1);
+
+ }
+ printf("Started Simple Axis2 HTTP Server ...\n");
+ if(axis2_transport_receiver_start(server, env) == AXIS2_FAILURE)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Server start failed: Error code:" " %d :: %s",
+ env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error));
+ system_exit(env, -1);
+ }
+ return 0;
+}
+
+void
+usage(
+ axis2_char_t * prog_name)
+{
+ fprintf(stdout, "\n Usage : %s", prog_name);
+ fprintf(stdout, " [-p PORT]");
+ fprintf(stdout, " [-t TIMEOUT]");
+ fprintf(stdout, " [-r REPO_PATH]");
+ fprintf(stdout, " [-l LOG_LEVEL]");
+ fprintf(stdout, " [-f LOG_FILE]\n");
+ fprintf(stdout, " [-s LOG_FILE_SIZE]\n");
+ fprintf(stdout, " Options :\n");
+ fprintf(stdout, "\t-p PORT \t port number to use, default port is 9090\n");
+ fprintf(stdout, "\t-r REPO_PATH \t repository path, default is ../\n");
+ fprintf(stdout, "\t-t TIMEOUT\t socket read timeout, default is 30 seconds\n");
+ fprintf(stdout, "\t-l LOG_LEVEL\t log level, available log levels:"
+ "\n\t\t\t 0 - critical 1 - errors 2 - warnings"
+ "\n\t\t\t 3 - information 4 - debug 5- user 6- trace"
+ "\n\t\t\t Default log level is 4(debug).\n");
+#ifndef WIN32
+ fprintf(stdout, "\t-f LOG_FILE\t log file, default is $AXIS2C_HOME/logs/axis2.log"
+ "\n\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n");
+#else
+ fprintf(stdout,
+ "\t-f LOG_FILE\t log file, default is %%AXIS2C_HOME%%\\logs\\axis2.log"
+ "\n\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n");
+#endif
+ fprintf(stdout,
+ "\t-s LOG_FILE_SIZE\t Maximum log file size in mega bytes, default maximum size is 1MB.\n");
+ fprintf(stdout, " Help :\n\t-h \t display this help screen.\n\n");
+}
+
+/**
+ * Signal handler
+ */
+void
+sig_handler(
+ int signal)
+{
+
+ if(!system_env)
+ {
+ AXIS2_LOG_ERROR(
+ system_env->log,
+ AXIS2_LOG_SI,
+ "Received signal %d, unable to proceed system_env is NULL ,\
+ system exit with -1",
+ signal);
+ _exit(-1);
+ }
+
+ switch(signal)
+ {
+ case SIGINT:
+ {
+ /* Use of SIGINT in Windows is valid, since we have a console application
+ * Thus, eventhough this may a single threaded application, it does work.
+ */
+ AXIS2_LOG_INFO(system_env->log, "Received signal SIGINT. Server "
+ "shutting down");
+ if(server)
+ {
+ axis2_http_server_stop(server, system_env);
+ }
+
+ AXIS2_LOG_INFO(system_env->log, "Shutdown complete ...");
+ system_exit(system_env, 0);
+ }
+#ifndef WIN32
+ case SIGPIPE:
+ {
+ AXIS2_LOG_INFO(system_env->log, "Received signal SIGPIPE. Client "
+ "request serve aborted");
+ return;
+ }
+#endif
+ case SIGSEGV:
+ {
+ fprintf(stderr, "Received deadly signal SIGSEGV. Terminating\n");
+ _exit(-1);
+ }
+ }
+}
diff --git a/src/core/transport/http/util/Makefile.am b/src/core/transport/http/util/Makefile.am
new file mode 100644
index 0000000..eff6c0e
--- /dev/null
+++ b/src/core/transport/http/util/Makefile.am
@@ -0,0 +1,14 @@
+NSUBDIRS =
+noinst_LTLIBRARIES = libaxis2_http_util.la
+
+libaxis2_http_util_la_SOURCES = http_transport_utils.c
+
+libaxis2_http_util_la_LIBADD=$(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/axiom/src/parser/${WRAPPER_DIR}/libaxis2_parser.la\
+ $(top_builddir)/axiom/src/om/libaxis2_axiom.la
+
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
diff --git a/src/core/transport/http/util/http_transport_utils.c b/src/core/transport/http/util/http_transport_utils.c
new file mode 100644
index 0000000..97d1510
--- /dev/null
+++ b/src/core/transport/http/util/http_transport_utils.c
@@ -0,0 +1,3885 @@
+/*
+ * 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_utils.h>
+#include <string.h>
+#include <ctype.h>
+#include <axis2_conf.h>
+#include <axis2_op.h>
+#include <axutil_qname.h>
+#include <axis2_http_transport.h>
+#include <axiom_soap_builder.h>
+#include <axis2_engine.h>
+#include <axiom_soap_body.h>
+#include <axutil_utils.h>
+#include <axiom_namespace.h>
+#include <axiom_node.h>
+#include <axutil_hash.h>
+#include <axiom_soap_const.h>
+#include <axis2_http_header.h>
+#include <axutil_property.h>
+#include <axutil_utils.h>
+#include <axiom_mime_parser.h>
+#include <axis2_http_accept_record.h>
+#include <axis2_disp.h>
+#include <axis2_msg.h>
+#include <axutil_string_util.h>
+#include <stdlib.h>
+#include <axutil_uuid_gen.h>
+#include <platforms/axutil_platform_auto_sense.h>
+#include <axiom_mime_part.h>
+#include <axutil_class_loader.h>
+
+#define AXIOM_MIME_BOUNDARY_BYTE 45
+
+/** Size of the buffer to be used when reading a file */
+#ifndef AXIS2_FILE_READ_SIZE
+#define AXIS2_FILE_READ_SIZE 2048
+#endif
+
+/** Content length value to be used in case of chunked content */
+#ifndef AXIS2_CHUNKED_CONTENT_LENGTH
+#define AXIS2_CHUNKED_CONTENT_LENGTH 100000000
+#endif
+
+const axis2_char_t *AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING =
+ AXIS2_HTTP_HEADER_DEFAULT_CHAR_ENCODING;
+
+/***************************** Function headers *******************************/
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_process_http_post_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ const int content_length,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_process_http_put_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ const int content_length,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri);
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_process_http_get_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri,
+ axis2_conf_ctx_t * conf_ctx,
+ axutil_hash_t * request_params);
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_process_http_head_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri,
+ axis2_conf_ctx_t * conf_ctx,
+ axutil_hash_t * request_params);
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_process_http_delete_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri,
+ axis2_conf_ctx_t * conf_ctx,
+ axutil_hash_t * request_params);
+
+AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL
+axis2_http_transport_utils_select_builder_for_mime(
+ const axutil_env_t * env,
+ axis2_char_t * request_uri,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axis2_char_t * content_type);
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_is_optimized(
+ const axutil_env_t * env,
+ axiom_element_t * om_element);
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_do_write_mtom(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_strdecode(
+ const axutil_env_t * env,
+ axis2_char_t * dest,
+ axis2_char_t * src);
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_http_transport_utils_hexit(
+ axis2_char_t c);
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_services_html(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx);
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_services_static_wsdl(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_char_t * request_url);
+
+AXIS2_EXTERN axutil_string_t *AXIS2_CALL
+axis2_http_transport_utils_get_charset_enc(
+ const axutil_env_t * env,
+ const axis2_char_t * content_type);
+
+int AXIS2_CALL
+axis2_http_transport_utils_on_data_request(
+ char *buffer,
+ int size,
+ void *ctx);
+
+AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
+axis2_http_transport_utils_create_soap_msg(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ const axis2_char_t * soap_ns_uri);
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_value_from_content_type(
+ const axutil_env_t * env,
+ const axis2_char_t * content_type,
+ const axis2_char_t * key);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_dispatch_and_verify(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
+axis2_http_transport_utils_handle_media_type_url_encoded(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_hash_t * param_map,
+ axis2_char_t * method);
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_transport_utils_session_map_free_void_arg(
+ void *sm_void,
+ const axutil_env_t *env);
+
+static axis2_status_t
+axis2_http_transport_utils_send_attachment_using_file(
+ const axutil_env_t * env,
+ axutil_http_chunked_stream_t *chunked_stream,
+ FILE *fp,
+ axis2_byte_t *buffer,
+ int buffer_size);
+
+static axis2_status_t
+axis2_http_transport_utils_send_attachment_using_callback(
+ const axutil_env_t * env,
+ axutil_http_chunked_stream_t *chunked_stream,
+ axiom_mtom_sending_callback_t *callback,
+ void *handler,
+ void *user_param);
+
+static axis2_char_t *
+axis2_http_transport_utils_copy_key(
+ const axutil_env_t *env,
+ axis2_char_t *);
+
+static axis2_char_t *
+axis2_http_transport_utils_copy_value(
+ const axutil_env_t *env,
+ axis2_char_t *pair);
+
+static void
+axis2_http_transport_utils_parse_session_str(
+ const axutil_env_t *env,
+ axis2_char_t *str,
+ axutil_hash_t *ht);
+/***************************** End of function headers ************************/
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_transport_out_init(
+ axis2_http_transport_out_t *response,
+ const axutil_env_t *env)
+{
+ response->http_status_code_name = NULL;
+ response->http_status_code = 0;
+ response->msg_ctx = NULL;
+ response->response_data = NULL;
+ response->content_type = NULL;
+ response->response_data_length = 0;
+ response->content_language = NULL;
+ response->output_headers = NULL;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_transport_out_uninit(
+ axis2_http_transport_out_t *response,
+ const axutil_env_t *env)
+{
+ if(response->msg_ctx)
+ {
+ axis2_msg_ctx_free(response->msg_ctx, env);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_transport_in_init(
+ axis2_http_transport_in_t *request,
+ const axutil_env_t *env)
+{
+ request->content_type = NULL;
+ request->content_length = 0;
+ request->msg_ctx = NULL;
+ request->soap_action = NULL;
+ request->request_uri = NULL;
+ request->in_stream = NULL;
+ request->remote_ip = NULL;
+ request->svr_port = NULL;
+ request->transfer_encoding = NULL;
+ request->accept_header = NULL;
+ request->accept_language_header = NULL;
+ request->accept_charset_header = NULL;
+ request->request_method = 0;
+ request->out_transport_info = NULL;
+ request->request_url_prefix = NULL;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_transport_in_uninit(
+ axis2_http_transport_in_t *request,
+ const axutil_env_t *env)
+{
+ if(request->msg_ctx)
+ {
+ axis2_msg_ctx_reset_out_transport_info(request->msg_ctx, env);
+ axis2_msg_ctx_free(request->msg_ctx, env);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_process_http_post_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ const int content_length,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri)
+{
+ axiom_soap_envelope_t *soap_envelope = NULL;
+ axiom_soap_builder_t *soap_builder = NULL;
+ axiom_stax_builder_t *om_builder = NULL;
+ axis2_bool_t is_soap11 = AXIS2_FALSE;
+ axiom_xml_reader_t *xml_reader = NULL;
+ axutil_string_t *char_set_str = NULL;
+
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_callback_info_t *callback_ctx = NULL;
+ axis2_callback_info_t *mime_cb_ctx = NULL;
+ axutil_hash_t *headers = NULL;
+ axis2_engine_t *engine = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_hash_t *binary_data_map = NULL;
+ axis2_char_t *soap_body_str = NULL;
+ axutil_stream_t *stream = NULL;
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ axis2_bool_t run_as_get = AXIS2_FALSE;
+ axis2_char_t *soap_action = NULL;
+ unsigned int soap_action_len = 0;
+ axutil_property_t *http_error_property = NULL;
+ axiom_mime_parser_t *mime_parser = NULL;
+ axis2_bool_t is_svc_callback = AXIS2_FALSE;
+ axutil_property_t *is_client_property = NULL;
+ axis2_bool_t is_application_client_side = AXIS2_FALSE;
+ axis2_char_t *mime_boundary = NULL;
+ axis2_bool_t check_for_fault = AXIS2_FALSE;
+ axis2_bool_t has_fault = AXIS2_FALSE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FAILURE);
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+
+ callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t));
+ /* Note: the memory created above is freed in xml reader free function
+ as this is passed on to the reader */
+ callback_ctx->in_stream = in_stream;
+ callback_ctx->env = env;
+ callback_ctx->content_length = content_length;
+ callback_ctx->unread_len = content_length;
+ callback_ctx->chunked_stream = NULL;
+
+ soap_action = (axis2_char_t *)axutil_string_get_buffer(soap_action_header, env);
+ soap_action_len = axutil_string_get_length(soap_action_header, env);
+
+ if(soap_action && (soap_action_len > 0))
+ {
+ /* remove leading and trailing " s */
+ if(AXIS2_DOUBLE_QUOTE == soap_action[0])
+ {
+ memmove(soap_action, soap_action + sizeof(char), soap_action_len - 1 + sizeof(char));
+ }
+ if(AXIS2_DOUBLE_QUOTE == soap_action[soap_action_len - 2])
+ {
+ soap_action[soap_action_len - 2] = AXIS2_ESC_NULL;
+ }
+ }
+ else
+ {
+ /** soap action is null, check whether soap action is in content_type header */
+ soap_action = axis2_http_transport_utils_get_value_from_content_type(env, content_type,
+ AXIS2_ACTION);
+ }
+
+ headers = axis2_msg_ctx_get_transport_headers(msg_ctx, env);
+ if(headers)
+ {
+ axis2_http_header_t *encoding_header = NULL;
+ encoding_header = (axis2_http_header_t *)axutil_hash_get(headers,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING, AXIS2_HASH_KEY_STRING);
+
+ if(encoding_header)
+ {
+ axis2_char_t *encoding_value = NULL;
+ encoding_value = axis2_http_header_get_value(encoding_header, env);
+ if(encoding_value && 0 == axutil_strcasecmp(encoding_value,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ callback_ctx->chunked_stream = axutil_http_chunked_stream_create(env, in_stream);
+
+ if(!callback_ctx->chunked_stream)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occurred in"
+ " creating in chunked stream.");
+ return AXIS2_FAILURE;
+ }
+
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "HTTP"
+ " stream chunked");
+ }
+ }
+ }
+ else
+ {
+ /* Encoding header is not available */
+ /* check content encoding from msg ctx property */
+ axis2_char_t *value = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env);
+
+ if(value && axutil_strstr(value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ /* In case Transfer encoding is set to message context, some streams strip chunking meta
+ data, so chunked streams should not be created */
+
+ callback_ctx->content_length = -1;
+ callback_ctx->unread_len = -1;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[chunked ] setting length to -1");
+ }
+ }
+
+ /* when the message contains does not contain pure XML we can't send it
+ * directly to the parser, First we need to separate the SOAP part from
+ * the attachment */
+
+ if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED))
+ {
+ /* get mime boundary */
+ mime_boundary = axis2_http_transport_utils_get_value_from_content_type(env,
+ content_type, AXIS2_HTTP_HEADER_CONTENT_TYPE_MIME_BOUNDARY);
+
+ if(mime_boundary)
+ {
+ /*axiom_mime_parser_t *mime_parser = NULL;*/
+ int soap_body_len = 0;
+ axutil_param_t *buffer_size_param = NULL;
+ axutil_param_t *max_buffers_param = NULL;
+ axutil_param_t *attachment_dir_param = NULL;
+ axutil_param_t *callback_name_param = NULL;
+ axutil_param_t *enable_service_callback_param = NULL;
+ axis2_char_t *value_size = NULL;
+ axis2_char_t *value_num = NULL;
+ axis2_char_t *value_dir = NULL;
+ axis2_char_t *value_callback = NULL;
+ axis2_char_t *value_enable_service_callback = NULL;
+ int size = 0;
+ int num = 0;
+
+ mime_parser = axiom_mime_parser_create(env);
+ /* This is the size of the buffer we keep inside mime_parser
+ * when parsing. */
+
+ enable_service_callback_param = axis2_msg_ctx_get_parameter(msg_ctx, env,
+ AXIS2_ENABLE_MTOM_SERVICE_CALLBACK);
+ if(enable_service_callback_param)
+ {
+ value_enable_service_callback = (axis2_char_t *)axutil_param_get_value(
+ enable_service_callback_param, env);
+ if(value_enable_service_callback)
+ {
+ if(!axutil_strcmp(value_enable_service_callback, AXIS2_VALUE_TRUE))
+ {
+ is_svc_callback = AXIS2_TRUE;
+ }
+ }
+ }
+
+ buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE);
+ if(buffer_size_param)
+ {
+ value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env);
+ if(value_size)
+ {
+ size = atoi(value_size);
+ axiom_mime_parser_set_buffer_size(mime_parser, env, size);
+ }
+ }
+
+ /* We create an array of buffers in order to conatin SOAP data inside
+ * mime_parser. This is the number of sucj buffers */
+ max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS);
+ if(max_buffers_param)
+ {
+ value_num = (axis2_char_t *)axutil_param_get_value(max_buffers_param, env);
+ if(value_num)
+ {
+ num = atoi(value_num);
+ axiom_mime_parser_set_max_buffers(mime_parser, env, num);
+ }
+ }
+ /* If this paramter is there mime_parser will cached the attachment
+ * using to the directory for large attachments. */
+
+ callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env,
+ AXIS2_MTOM_CACHING_CALLBACK);
+ if(callback_name_param)
+ {
+ value_callback = (axis2_char_t *)axutil_param_get_value(callback_name_param, env);
+ if(value_callback)
+ {
+ axiom_mime_parser_set_caching_callback_name(mime_parser, env, value_callback);
+ }
+ }
+
+ attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR);
+
+ if(attachment_dir_param)
+ {
+ value_dir = (axis2_char_t *)axutil_param_get_value(attachment_dir_param, env);
+ if(value_dir)
+ {
+ axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
+ }
+ }
+
+ axiom_mime_parser_set_mime_boundary(mime_parser, env, mime_boundary);
+
+ if(axiom_mime_parser_parse_for_soap(mime_parser, env,
+ axis2_http_transport_utils_on_data_request, (void *)callback_ctx, mime_boundary)
+ == AXIS2_FAILURE)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ if(!is_svc_callback)
+ {
+ binary_data_map = axiom_mime_parser_parse_for_attachments(mime_parser, env,
+ axis2_http_transport_utils_on_data_request, (void *)callback_ctx,
+ mime_boundary, NULL);
+ if(!binary_data_map)
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ soap_body_len = (int)axiom_mime_parser_get_soap_body_len(mime_parser, env);
+ soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env);
+
+ if(!is_svc_callback)
+ {
+ if(callback_ctx->chunked_stream)
+ {
+ axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env);
+ callback_ctx->chunked_stream = NULL;
+ }
+ }
+ else
+ {
+ mime_cb_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t));
+ if(mime_cb_ctx)
+ {
+ mime_cb_ctx->in_stream = callback_ctx->in_stream;
+ mime_cb_ctx->env = callback_ctx->env;
+ mime_cb_ctx->content_length = callback_ctx->content_length;
+ mime_cb_ctx->unread_len = callback_ctx->unread_len;
+ mime_cb_ctx->chunked_stream = callback_ctx->chunked_stream;
+ }
+ }
+
+ stream = axutil_stream_create_basic(env);
+ if(stream)
+ {
+ axutil_stream_write(stream, env, soap_body_str, soap_body_len);
+ callback_ctx->in_stream = stream;
+ callback_ctx->chunked_stream = NULL;
+ callback_ctx->content_length = soap_body_len;
+ callback_ctx->unread_len = soap_body_len;
+ }
+ /*axiom_mime_parser_free(mime_parser, env);
+ mime_parser = NULL;*/
+
+ /*AXIS2_FREE(env->allocator, mime_boundary);*/
+ }
+ /*AXIS2_FREE(env->allocator, mime_boundary);*/
+ }
+
+ if(soap_action_header)
+ {
+ axis2_msg_ctx_set_soap_action(msg_ctx, env, soap_action_header);
+
+ }
+ else if(soap_action)
+ {
+ axutil_string_t *soap_action_str = NULL;
+ soap_action_str = axutil_string_create(env, soap_action);
+ axis2_msg_ctx_set_soap_action(msg_ctx, env, soap_action_str);
+ axutil_string_free(soap_action_str, env);
+ }
+ axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
+
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+ char_set_str = axis2_http_transport_utils_get_charset_enc(env, content_type);
+ xml_reader = axiom_xml_reader_create_for_io(env, axis2_http_transport_utils_on_data_request,
+ NULL, (void *)callback_ctx, axutil_string_get_buffer(char_set_str, env));
+
+ if(!xml_reader)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str);
+
+ om_builder = axiom_stax_builder_create(env, xml_reader);
+ if(!om_builder)
+ {
+ axiom_xml_reader_free(xml_reader, env);
+ xml_reader = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
+ {
+ is_soap11 = AXIS2_FALSE;
+ soap_builder = axiom_soap_builder_create(env, om_builder,
+ AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI);
+ if(!soap_builder)
+ {
+ /* We should not be freeing om_builder here as it is done by
+ axiom_soap_builder_create in case of error - Samisa */
+ om_builder = NULL;
+ xml_reader = NULL;
+ axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
+ return AXIS2_FAILURE;
+ }
+
+ soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
+ if(!soap_envelope)
+ {
+ axiom_stax_builder_free(om_builder, env);
+ om_builder = NULL;
+ xml_reader = NULL;
+ axiom_soap_builder_free(soap_builder, env);
+ soap_builder = NULL;
+ axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
+ return AXIS2_FAILURE;
+ }
+ }
+ else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
+ {
+ is_soap11 = AXIS2_TRUE;
+ if(soap_action_header)
+ {
+ soap_builder = axiom_soap_builder_create(env, om_builder,
+ AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI);
+ if(!soap_builder)
+ {
+ /* We should not be freeing om_builder here as it is done by
+ axiom_soap_builder_create in case of error - Samisa */
+ om_builder = NULL;
+ xml_reader = NULL;
+ axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
+ return AXIS2_FAILURE;
+ }
+ soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
+ if(!soap_envelope)
+ {
+ axiom_soap_builder_free(soap_builder, env);
+ om_builder = NULL;
+ xml_reader = NULL;
+ soap_builder = NULL;
+ axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ /* REST support */
+ do_rest = AXIS2_TRUE;
+ }
+ }
+
+ else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_X_WWW_FORM_URLENCODED))
+ {
+ /* REST support */
+ do_rest = AXIS2_TRUE;
+ run_as_get = AXIS2_TRUE;
+ }
+ else
+ {
+ http_error_property = axutil_property_create(env);
+ axutil_property_set_value(http_error_property, env, AXIS2_HTTP_UNSUPPORTED_MEDIA_TYPE);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_TRANSPORT_ERROR, http_error_property);
+ }
+
+ if(soap_builder)
+ {
+ if(mime_parser)
+ {
+ axiom_soap_builder_set_mime_parser(soap_builder, env, mime_parser);
+ if(mime_cb_ctx)
+ {
+ axiom_soap_builder_set_callback_ctx(soap_builder, env, mime_cb_ctx);
+ axiom_soap_builder_set_callback_function(soap_builder, env,
+ axis2_http_transport_utils_on_data_request);
+ }
+ else if(is_svc_callback)
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ }
+
+ if(do_rest)
+ {
+ /* REST support */
+ axutil_param_t *rest_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ENABLE_REST);
+ if(rest_param && 0 == axutil_strcmp(AXIS2_VALUE_TRUE, axutil_param_get_value(rest_param,
+ env)))
+ {
+ axiom_soap_body_t *def_body = NULL;
+ axiom_document_t *om_doc = NULL;
+ axiom_node_t *root_node = NULL;
+ if(!run_as_get)
+ {
+ soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
+ def_body = axiom_soap_envelope_get_body(soap_envelope, env);
+ om_doc = axiom_stax_builder_get_document(om_builder, env);
+ root_node = axiom_document_build_all(om_doc, env);
+ axiom_soap_body_add_child(def_body, env, root_node);
+ }
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_POST);
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+
+ if(run_as_get)
+ {
+ axis2_char_t *buffer = NULL;
+ axis2_char_t *new_url = NULL;
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (content_length + 1));
+ if(!buffer)
+ {
+ return AXIS2_FAILURE;
+ }
+ axis2_http_transport_utils_on_data_request(buffer, content_length, (void *)callback_ctx);
+
+ new_url = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * ((int)(strlen(request_uri)
+ + strlen(buffer)) + 2));
+ if(!new_url)
+ {
+ return AXIS2_FAILURE;
+ }
+ sprintf(new_url, "%s?%s", request_uri, buffer);
+ AXIS2_FREE(env->allocator, buffer);
+
+ soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
+ axis2_http_transport_utils_get_request_params(env, new_url), AXIS2_HTTP_POST);
+ }
+
+ if(binary_data_map)
+ {
+ axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map);
+ }
+
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
+
+ engine = axis2_engine_create(env, conf_ctx);
+
+ if(!soap_envelope)
+ return AXIS2_FAILURE;
+
+ soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
+
+ if(!soap_body)
+ return AXIS2_FAILURE;
+
+ if(!is_svc_callback)
+ {
+ is_client_property = axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE);
+ if(is_client_property)
+ {
+ axis2_char_t *prop_value = NULL;
+ prop_value = axutil_property_get_value(is_client_property, env);
+ if(prop_value && !axutil_strcmp(prop_value , AXIS2_VALUE_TRUE))
+ {
+ is_application_client_side = AXIS2_TRUE;
+ }
+ }
+ if(mime_boundary || is_application_client_side)
+ {
+ check_for_fault = AXIS2_TRUE;
+ }
+ if(check_for_fault)
+ {
+ has_fault = axiom_soap_body_has_fault(soap_body, env);
+ }
+ if(has_fault)
+ {
+ status = axis2_engine_receive_fault(engine, env, msg_ctx);
+ }
+ else
+ {
+ status = axis2_engine_receive(engine, env, msg_ctx);
+ }
+ }
+ else
+ {
+ status = axis2_engine_receive(engine, env, msg_ctx);
+ }
+
+ if(!axis2_msg_ctx_get_soap_envelope(msg_ctx, env) && AXIS2_FALSE == is_soap11)
+ {
+ axiom_soap_envelope_t *def_envelope = axiom_soap_envelope_create_default_soap_envelope(env,
+ AXIOM_SOAP12);
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, def_envelope);
+ }
+
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ }
+
+ if(soap_body_str)
+ {
+ AXIS2_FREE(env->allocator, soap_body_str);
+ }
+
+ if(stream)
+ {
+ axutil_stream_free(stream, env);
+ }
+
+ if(char_set_str)
+ {
+ axutil_string_free(char_set_str, env);
+ }
+ if(!soap_builder && om_builder)
+ {
+ axiom_stax_builder_free_self(om_builder, env);
+ om_builder = NULL;
+ }
+ if(!axutil_string_get_buffer(soap_action_header, env) && soap_action)
+ {
+ AXIS2_FREE(env->allocator, soap_action);
+ soap_action = NULL;
+ }
+ return status;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_process_http_put_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ const int content_length,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri)
+{
+ axiom_soap_envelope_t *soap_envelope = NULL;
+ axiom_soap_builder_t *soap_builder = NULL;
+ axiom_stax_builder_t *om_builder = NULL;
+ axis2_bool_t is_soap11 = AXIS2_FALSE;
+ axiom_xml_reader_t *xml_reader = NULL;
+ axutil_string_t *char_set_str = NULL;
+
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_callback_info_t *callback_ctx;
+ axutil_hash_t *headers = NULL;
+ axis2_engine_t *engine = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_hash_t *binary_data_map = NULL;
+ axis2_char_t *soap_body_str = NULL;
+ axutil_stream_t *stream = NULL;
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ axis2_bool_t run_as_get = AXIS2_FALSE;
+ axutil_property_t *http_error_property = NULL;
+ axutil_property_t *is_client_property = NULL;
+ axis2_bool_t is_application_client_side = AXIS2_FALSE;
+ axis2_char_t *mime_boundary = NULL;
+ axis2_bool_t check_for_fault = AXIS2_FALSE;
+ axis2_bool_t has_fault = AXIS2_FALSE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FAILURE);
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+
+ callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t));
+ /* Note: the memory created above is freed in xml reader free function
+ as this is passed on to the reader */
+ callback_ctx->in_stream = in_stream;
+ callback_ctx->env = env;
+ callback_ctx->content_length = content_length;
+ callback_ctx->unread_len = content_length;
+ callback_ctx->chunked_stream = NULL;
+
+ headers = axis2_msg_ctx_get_transport_headers(msg_ctx, env);
+ if(headers)
+ {
+ axis2_http_header_t *encoding_header = NULL;
+ encoding_header = (axis2_http_header_t *)axutil_hash_get(headers,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING, AXIS2_HASH_KEY_STRING);
+
+ if(encoding_header)
+ {
+ axis2_char_t *encoding_value = NULL;
+ encoding_value = axis2_http_header_get_value(encoding_header, env);
+ if(encoding_value && 0 == axutil_strcasecmp(encoding_value,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ callback_ctx->chunked_stream = axutil_http_chunked_stream_create(env, in_stream);
+ if(!callback_ctx->chunked_stream)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in"
+ " creating in chunked stream.");
+ return AXIS2_FAILURE;
+ }
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "HTTP"
+ " stream chunked");
+ }
+ }
+ }
+ else
+ {
+ /* check content encoding from msg ctx property */
+ axis2_char_t *value = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env);
+
+ if(value && axutil_strstr(value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ /* this is an UGLY hack to get some of the transports working
+ e.g. PHP transport where it strips the chunking info in case of chunking
+ and also gives out a content lenght of 0.
+ We need to fix the transport design to fix sutuations like this.
+ */
+ callback_ctx->content_length = AXIS2_CHUNKED_CONTENT_LENGTH;
+ callback_ctx->unread_len = callback_ctx->content_length;
+ }
+ }
+
+ if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED))
+ {
+ /* get mime boundry */
+ mime_boundary = axis2_http_transport_utils_get_value_from_content_type(env,
+ content_type, AXIS2_HTTP_HEADER_CONTENT_TYPE_MIME_BOUNDARY);
+
+ if(mime_boundary)
+ {
+ axiom_mime_parser_t *mime_parser = NULL;
+ int soap_body_len = 0;
+ axutil_param_t *buffer_size_param = NULL;
+ axutil_param_t *max_buffers_param = NULL;
+ axutil_param_t *attachment_dir_param = NULL;
+ axutil_param_t *callback_name_param = NULL;
+ axis2_char_t *value_size = NULL;
+ axis2_char_t *value_num = NULL;
+ axis2_char_t *value_dir = NULL;
+ axis2_char_t *value_callback = NULL;
+ int size = 0;
+ int num = 0;
+
+ mime_parser = axiom_mime_parser_create(env);
+
+ buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE);
+ if(buffer_size_param)
+ {
+ value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env);
+ if(value_size)
+ {
+ size = atoi(value_size);
+ axiom_mime_parser_set_buffer_size(mime_parser, env, size);
+ }
+ }
+
+ max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS);
+ if(max_buffers_param)
+ {
+ value_num = (axis2_char_t *)axutil_param_get_value(max_buffers_param, env);
+ if(value_num)
+ {
+ num = atoi(value_num);
+ axiom_mime_parser_set_max_buffers(mime_parser, env, num);
+ }
+ }
+
+ callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env,
+ AXIS2_MTOM_CACHING_CALLBACK);
+ if(callback_name_param)
+ {
+ value_callback = (axis2_char_t *)axutil_param_get_value(callback_name_param, env);
+ if(value_callback)
+ {
+ axiom_mime_parser_set_caching_callback_name(mime_parser, env, value_callback);
+ }
+ }
+
+ attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR);
+
+ if(attachment_dir_param)
+ {
+ value_dir = (axis2_char_t *)axutil_param_get_value(attachment_dir_param, env);
+ if(value_dir)
+ {
+ axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
+ }
+ }
+
+ if(mime_parser)
+ {
+ /*binary_data_map =
+ axiom_mime_parser_parse(mime_parser, env,
+ axis2_http_transport_utils_on_data_request,
+ (void *) callback_ctx,
+ mime_boundary);*/
+ if(!binary_data_map)
+ {
+ return AXIS2_FAILURE;
+ }
+ soap_body_len = (int)axiom_mime_parser_get_soap_body_len(mime_parser, env);
+ soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env);
+ }
+
+ stream = axutil_stream_create_basic(env);
+ if(stream)
+ {
+ axutil_stream_write(stream, env, soap_body_str, soap_body_len);
+ callback_ctx->in_stream = stream;
+ callback_ctx->chunked_stream = NULL;
+ callback_ctx->content_length = soap_body_len;
+ callback_ctx->unread_len = soap_body_len;
+ }
+ axiom_mime_parser_free(mime_parser, env);
+ mime_parser = NULL;
+ }
+ /*AXIS2_FREE(env->allocator, mime_boundary);*/
+ }
+
+ axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
+
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+ char_set_str = axis2_http_transport_utils_get_charset_enc(env, content_type);
+ xml_reader = axiom_xml_reader_create_for_io(env, axis2_http_transport_utils_on_data_request,
+ NULL, (void *)callback_ctx, axutil_string_get_buffer(char_set_str, env));
+
+ if(!xml_reader)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str);
+
+ om_builder = axiom_stax_builder_create(env, xml_reader);
+ if(!om_builder)
+ {
+ axiom_xml_reader_free(xml_reader, env);
+ xml_reader = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
+ {
+ is_soap11 = AXIS2_FALSE;
+ soap_builder = axiom_soap_builder_create(env, om_builder,
+ AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI);
+ if(!soap_builder)
+ {
+ /* We should not be freeing om_builder here as it is done by
+ axiom_soap_builder_create in case of error - Samisa */
+ om_builder = NULL;
+ xml_reader = NULL;
+ axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
+ return AXIS2_FAILURE;
+ }
+
+ soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
+ if(!soap_envelope)
+ {
+ axiom_stax_builder_free(om_builder, env);
+ om_builder = NULL;
+ xml_reader = NULL;
+ axiom_soap_builder_free(soap_builder, env);
+ soap_builder = NULL;
+ axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
+ return AXIS2_FAILURE;
+ }
+ }
+ else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
+ {
+ do_rest = AXIS2_TRUE;
+ if(soap_action_header)
+ {
+ return AXIS2_FAILURE;
+ }
+ else
+ {
+ /* REST support */
+ do_rest = AXIS2_TRUE;
+ }
+ }
+ else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_X_WWW_FORM_URLENCODED))
+ {
+ /* REST support */
+ do_rest = AXIS2_TRUE;
+ run_as_get = AXIS2_TRUE;
+ }
+ else
+ {
+ http_error_property = axutil_property_create(env);
+ axutil_property_set_value(http_error_property, env, AXIS2_HTTP_UNSUPPORTED_MEDIA_TYPE);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_TRANSPORT_ERROR, http_error_property);
+ }
+
+ if(do_rest)
+ {
+ /* REST support */
+ axutil_param_t *rest_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ENABLE_REST);
+ if(rest_param && 0 == axutil_strcmp(AXIS2_VALUE_TRUE, axutil_param_get_value(rest_param,
+ env)))
+ {
+ axiom_soap_body_t *def_body = NULL;
+ axiom_document_t *om_doc = NULL;
+ axiom_node_t *root_node = NULL;
+ if(!run_as_get)
+ {
+ soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
+ def_body = axiom_soap_envelope_get_body(soap_envelope, env);
+ om_doc = axiom_stax_builder_get_document(om_builder, env);
+ root_node = axiom_document_build_all(om_doc, env);
+ axiom_soap_body_add_child(def_body, env, root_node);
+ }
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_PUT);
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+
+ if(run_as_get)
+ {
+ axis2_char_t *buffer = NULL;
+ axis2_char_t *new_url = NULL;
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (content_length + 1));
+ if(!buffer)
+ {
+ return AXIS2_FAILURE;
+ }
+ axis2_http_transport_utils_on_data_request(buffer, content_length, (void *)callback_ctx);
+
+ new_url = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * ((int)(strlen(request_uri)
+ + strlen(buffer)) + 2));
+ if(!new_url)
+ {
+ return AXIS2_FAILURE;
+ }
+ sprintf(new_url, "%s?%s", request_uri, buffer);
+ AXIS2_FREE(env->allocator, buffer);
+
+ soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
+ axis2_http_transport_utils_get_request_params(env, new_url), AXIS2_HTTP_POST);
+ }
+
+ if(binary_data_map)
+ {
+ axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map);
+ }
+
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
+
+ engine = axis2_engine_create(env, conf_ctx);
+
+ if(!soap_envelope)
+ return AXIS2_FAILURE;
+
+ soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
+
+ if(!soap_body)
+ return AXIS2_FAILURE;
+
+ is_client_property = axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE);
+ if(is_client_property)
+ {
+ axis2_char_t *prop_value = NULL;
+ prop_value = axutil_property_get_value(is_client_property, env);
+ if(prop_value && !axutil_strcmp(prop_value , AXIS2_VALUE_TRUE))
+ {
+ is_application_client_side = AXIS2_TRUE;
+ }
+ }
+ if(mime_boundary || is_application_client_side)
+ {
+ check_for_fault = AXIS2_TRUE;
+ }
+ if(check_for_fault)
+ {
+ has_fault = axiom_soap_body_has_fault(soap_body, env);
+ }
+ if(has_fault)
+ {
+ status = axis2_engine_receive_fault(engine, env, msg_ctx);
+ }
+ else
+ {
+ status = axis2_engine_receive(engine, env, msg_ctx);
+ }
+ if(mime_boundary)
+ {
+ AXIS2_FREE(env->allocator, mime_boundary);
+ }
+ if(!axis2_msg_ctx_get_soap_envelope(msg_ctx, env) && AXIS2_FALSE == is_soap11)
+ {
+ axiom_soap_envelope_t *def_envelope = axiom_soap_envelope_create_default_soap_envelope(env,
+ AXIOM_SOAP12);
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, def_envelope);
+ }
+
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ }
+
+ if(soap_body_str)
+ {
+ AXIS2_FREE(env->allocator, soap_body_str);
+ }
+
+ if(stream)
+ {
+ axutil_stream_free(stream, env);
+ }
+
+ if(char_set_str)
+ {
+ axutil_string_free(char_set_str, env);
+ }
+ if(!soap_builder && om_builder)
+ {
+ axiom_stax_builder_free_self(om_builder, env);
+ om_builder = NULL;
+ }
+ return status;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_process_http_head_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri,
+ axis2_conf_ctx_t * conf_ctx,
+ axutil_hash_t * request_params)
+{
+ axiom_soap_envelope_t *soap_envelope = NULL;
+ axis2_engine_t *engine = NULL;
+ axis2_bool_t do_rest = AXIS2_TRUE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE);
+
+ AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FALSE);
+
+ axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+ if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
+ {
+ if(soap_action_header)
+ {
+ do_rest = AXIS2_FALSE;
+ }
+ }
+ else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
+ {
+ do_rest = AXIS2_FALSE;
+ }
+
+ if(do_rest)
+ {
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_HEAD);
+ }
+ else
+ {
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE);
+ }
+ if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
+ {
+ return AXIS2_FALSE;
+ }
+
+ soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
+ request_params, AXIS2_HTTP_HEAD);
+ if(!soap_envelope)
+ {
+ return AXIS2_FALSE;
+ }
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
+ engine = axis2_engine_create(env, conf_ctx);
+ axis2_engine_receive(engine, env, msg_ctx);
+ return AXIS2_TRUE;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_process_http_get_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri,
+ axis2_conf_ctx_t * conf_ctx,
+ axutil_hash_t * request_params)
+{
+ axiom_soap_envelope_t *soap_envelope = NULL;
+ axis2_engine_t *engine = NULL;
+ axis2_bool_t do_rest = AXIS2_TRUE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FALSE);
+
+ axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+ if(content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
+ {
+ if(soap_action_header)
+ {
+ do_rest = AXIS2_FALSE;
+ }
+ }
+ else if(content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
+ {
+ do_rest = AXIS2_FALSE;
+ }
+
+ if(do_rest)
+ {
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_GET);
+ }
+ else
+ {
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE);
+ }
+
+ if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
+ {
+ return AXIS2_FALSE;
+ }
+ soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
+ request_params, AXIS2_HTTP_GET);
+ if(!soap_envelope)
+ {
+ return AXIS2_FALSE;
+ }
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
+
+ engine = axis2_engine_create(env, conf_ctx);
+ axis2_engine_receive(engine, env, msg_ctx);
+ return AXIS2_TRUE;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_process_http_delete_request(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_stream_t * in_stream,
+ axutil_stream_t * out_stream,
+ const axis2_char_t * content_type,
+ axutil_string_t * soap_action_header,
+ const axis2_char_t * request_uri,
+ axis2_conf_ctx_t * conf_ctx,
+ axutil_hash_t * request_params)
+{
+ axiom_soap_envelope_t *soap_envelope = NULL;
+ axis2_engine_t *engine = NULL;
+ axis2_bool_t do_rest = AXIS2_TRUE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE);
+ AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FALSE);
+
+ axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+ if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
+ {
+ if(soap_action_header)
+ {
+ do_rest = AXIS2_FALSE;
+ }
+ }
+ else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
+ {
+ do_rest = AXIS2_FALSE;
+ }
+
+ if(do_rest)
+ {
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_DELETE);
+ }
+ else
+ {
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE);
+ }
+
+ soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
+ request_params, AXIS2_HTTP_DELETE);
+ if(!soap_envelope)
+ {
+ return AXIS2_FALSE;
+ }
+
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
+
+ if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
+ {
+ return AXIS2_FALSE;
+ }
+ engine = axis2_engine_create(env, conf_ctx);
+ axis2_engine_receive(engine, env, msg_ctx);
+ return AXIS2_TRUE;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_do_write_mtom(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ return (axis2_msg_ctx_get_doing_mtom(msg_ctx, env));
+}
+
+AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
+axis2_http_transport_utils_get_request_params(
+ const axutil_env_t * env,
+ axis2_char_t * request_uri)
+{
+
+ axis2_char_t *query_str = NULL;
+ axis2_char_t *tmp = strchr(request_uri, AXIS2_Q_MARK);
+ axis2_char_t *tmp2 = NULL;
+ axis2_char_t *tmp_name = NULL;
+ axis2_char_t *tmp_value = NULL;
+ axutil_hash_t *ret = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, request_uri, NULL);
+
+ if(!tmp || AXIS2_ESC_NULL == *(tmp + 1))
+ {
+ return NULL;
+ }
+ query_str = axutil_strdup(env, tmp + 1);
+
+ for(tmp2 = tmp = query_str; *tmp != AXIS2_ESC_NULL; ++tmp)
+ {
+ if(AXIS2_EQ == *tmp)
+ {
+ *tmp = AXIS2_ESC_NULL;
+ tmp_name = axutil_strdup(env, tmp2);
+ axis2_http_transport_utils_strdecode(env, tmp_name, tmp_name);
+ tmp2 = tmp + 1;
+ }
+ if(AXIS2_AND == *tmp)
+ {
+ *tmp = AXIS2_ESC_NULL;
+ tmp_value = axutil_strdup(env, tmp2);
+ axis2_http_transport_utils_strdecode(env, tmp_value, tmp_value);
+ tmp2 = tmp + 1;
+ }
+ if(tmp_name && NULL != tmp_value)
+ {
+ if(!ret)
+ {
+ ret = axutil_hash_make(env);
+ }
+ axutil_hash_set(ret, tmp_name, AXIS2_HASH_KEY_STRING, tmp_value);
+ tmp_name = NULL;
+ tmp_value = NULL;
+ }
+ }
+ if(tmp_name && AXIS2_ESC_NULL != *tmp2)
+ {
+ if(!ret)
+ {
+ ret = axutil_hash_make(env);
+ }
+ tmp_value = axutil_strdup(env, tmp2);
+ axis2_http_transport_utils_strdecode(env, tmp_value, tmp_value);
+ axutil_hash_set(ret, tmp_name, AXIS2_HASH_KEY_STRING, tmp_value);
+ }
+
+ return ret;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_strdecode(
+ const axutil_env_t * env,
+ axis2_char_t * dest,
+ axis2_char_t * src)
+{
+ AXIS2_PARAM_CHECK(env->error, dest, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, src, AXIS2_FAILURE);
+
+ for(; *src != AXIS2_ESC_NULL; ++dest, ++src)
+ {
+ if(src[0] == AXIS2_PERCENT && isxdigit((int)src[1]) && isxdigit((int)src[2]))
+ {
+ *dest = (axis2_char_t)(axis2_http_transport_utils_hexit(src[1]) * 16
+ + axis2_http_transport_utils_hexit(src[2]));
+ /* We are sure that the conversion is valid */
+ src += 2;
+ }
+ else
+ {
+ *dest = *src;
+ }
+ }
+ *dest = AXIS2_ESC_NULL;
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_http_transport_utils_hexit(
+ axis2_char_t c)
+{
+ if(c >= '0' && c <= '9')
+ {
+ return c - '0';
+ }
+ if(c >= 'a' && c <= 'f')
+ {
+ return c - 'a' + 10;
+ }
+ if(c >= 'A' && c <= 'F')
+ {
+ return c - 'A' + 10;
+ }
+ return 0; /* shouldn't happen, we're guarded by isxdigit() */
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_not_found(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_NOT_FOUND;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_not_implemented(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_NOT_IMPLEMENTED;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_internal_server_error(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_INTERNAL_SERVER_ERROR;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_method_not_allowed(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_METHOD_NOT_ALLOWED;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_not_acceptable(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_NOT_ACCEPTABLE;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_bad_request(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_BAD_REQUEST;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_request_timeout(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_REQUEST_TIMEOUT;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_conflict(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_CONFLICT;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_gone(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_GONE;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_precondition_failed(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_PRECONDITION_FAILED;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_request_entity_too_large(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_TOO_LARGE;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_service_unavailable(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ return AXIS2_HTTP_SERVICE_UNAVILABLE;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_services_html(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ axutil_hash_t *services_map = NULL;
+ axutil_hash_t *errorneous_svc_map = NULL;
+ axis2_char_t *ret = NULL;
+ axis2_char_t *tmp2 = (axis2_char_t *)"<h2>Deployed Services</h2>";
+ axutil_hash_index_t *hi = NULL;
+ axis2_bool_t svcs_exists = AXIS2_FALSE;
+ axis2_conf_t *conf = NULL;
+ AXIS2_PARAM_CHECK(env->error, conf_ctx, NULL);
+
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ services_map = axis2_conf_get_all_svcs(conf, env);
+ errorneous_svc_map = axis2_conf_get_all_faulty_svcs(conf, env);
+ if(services_map && 0 != axutil_hash_count(services_map))
+ {
+ void *service = NULL;
+ axis2_char_t *sname = NULL;
+ axutil_hash_t *ops = NULL;
+ svcs_exists = AXIS2_TRUE;
+
+ for(hi = axutil_hash_first(services_map, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ axutil_hash_this(hi, NULL, NULL, &service);
+ sname = axutil_qname_get_localpart(axis2_svc_get_qname(((axis2_svc_t *)service), env),
+ env);
+ ret = axutil_stracat(env, tmp2, "<h3><u>");
+ tmp2 = ret;
+ ret = axutil_stracat(env, tmp2, sname);
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+ ret = axutil_stracat(env, tmp2, "</u></h3>");
+ tmp2 = ret;
+ ret = axutil_stracat(env, tmp2, "<p>");
+ tmp2 = ret;
+
+ /**
+ *setting services description */
+ ret = axutil_stracat(env, tmp2, axis2_svc_get_svc_desc((axis2_svc_t *)service, env));
+ tmp2 = ret;
+ ret = axutil_stracat(env, tmp2, "</p>");
+ tmp2 = ret;
+ ops = axis2_svc_get_all_ops(((axis2_svc_t *)service), env);
+ if(ops && 0 != axutil_hash_count(ops))
+ {
+ axutil_hash_index_t *hi2 = NULL;
+ void *op = NULL;
+ axis2_char_t *oname = NULL;
+
+ ret = axutil_stracat(env, tmp2, "<i>Available Operations</i> <ul>");
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+ for(hi2 = axutil_hash_first(ops, env); hi2; hi2 = axutil_hash_next(env, hi2))
+ {
+ axutil_hash_this(hi2, NULL, NULL, &op);
+ oname = axutil_qname_get_localpart(axis2_op_get_qname(((axis2_op_t *)op), env),
+ env);
+ ret = axutil_stracat(env, tmp2, "<li>");
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+
+ ret = axutil_stracat(env, tmp2, oname);
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+ ret = axutil_stracat(env, tmp2, "</li>");
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+ }
+ ret = axutil_stracat(env, tmp2, "</ul>");
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+ }
+ else
+ {
+ ret = axutil_stracat(env, tmp2, "No operations Available");
+ tmp2 = ret;
+ }
+ }
+ }
+
+ if(errorneous_svc_map && 0 != axutil_hash_count(errorneous_svc_map))
+ {
+ void *fsname = NULL;
+ svcs_exists = AXIS2_TRUE;
+ ret = axutil_stracat(env, tmp2,
+ "<hr><h2><font color=\"red\">Faulty \
+ Services</font></h2>");
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+
+ for(hi = axutil_hash_first(errorneous_svc_map, env); hi; axutil_hash_next(env, hi))
+ {
+ axutil_hash_this(hi, (const void **)&fsname, NULL, NULL);
+ ret = axutil_stracat(env, tmp2, "<h3><font color=\"red\">");
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+ ret = axutil_stracat(env, tmp2, (axis2_char_t *)fsname);
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+ ret = axutil_stracat(env, tmp2, "</font></h3>");
+ AXIS2_FREE(env->allocator, tmp2);
+ tmp2 = ret;
+ }
+ }
+ if(AXIS2_FALSE == svcs_exists)
+ {
+ ret = axutil_strdup(env, "<h2>There are no services deployed</h2>");
+ }
+ ret = axutil_stracat(env, "<html><head><title>Axis2C :: Services</title></head>"
+ "<body><font face=\"courier\">", tmp2);
+ tmp2 = ret;
+ ret = axutil_stracat(env, tmp2, "</font></body></html>\r\n");
+
+ return ret;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_services_static_wsdl(
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_char_t * request_url)
+{
+ axis2_char_t *wsdl_string = NULL;
+ axis2_char_t *wsdl_path = NULL;
+ axis2_char_t **url_tok = NULL;
+ unsigned int len = 0;
+ axis2_char_t *svc_name = NULL;
+ axis2_conf_t *conf = NULL;
+ axutil_hash_t *services_map = NULL;
+ axutil_hash_index_t *hi = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, conf_ctx, NULL);
+ AXIS2_PARAM_CHECK(env->error, request_url, NULL);
+
+ url_tok = axutil_parse_request_url_for_svc_and_op(env, request_url);
+ if(url_tok[0])
+ {
+ len = (int)strlen(url_tok[0]);
+ /* We are sure that the difference lies within the int range */
+ url_tok[0][len - 5] = 0;
+ svc_name = url_tok[0];
+ }
+
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ services_map = axis2_conf_get_all_svcs(conf, env);
+
+ if(services_map && 0 != axutil_hash_count(services_map))
+ {
+ void *service = NULL;
+ axis2_char_t *sname = NULL;
+
+ for(hi = axutil_hash_first(services_map, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ axutil_hash_this(hi, NULL, NULL, &service);
+ sname = axutil_qname_get_localpart(axis2_svc_get_qname(((axis2_svc_t *)service), env),
+ env);
+ if(!axutil_strcmp(svc_name, sname))
+ {
+ wsdl_path = (axis2_char_t *)axutil_strdup(env, axis2_svc_get_svc_wsdl_path(
+ (axis2_svc_t *)service, env));
+ if(!wsdl_path)
+ {
+ wsdl_path = axutil_strcat(env, axis2_svc_get_svc_folder_path(
+ (axis2_svc_t *)service, env), AXIS2_PATH_SEP_STR, svc_name, ".wsdl", NULL);
+ }
+ break;
+ }
+
+ }
+ }
+
+ if(wsdl_path)
+ {
+ FILE *wsdl_file = NULL;
+ axis2_char_t *content = NULL;
+ int c;
+ int size = AXIS2_FILE_READ_SIZE;
+ axis2_char_t *tmp;
+ int i = 0;
+
+ content = (axis2_char_t *)AXIS2_MALLOC(env->allocator, size);
+ wsdl_file = fopen(wsdl_path, "r");
+ if(wsdl_file)
+ {
+ c = fgetc(wsdl_file);
+ while(c != EOF)
+ {
+ if(i >= size)
+ {
+ size = size * 3;
+ tmp = (axis2_char_t *)AXIS2_MALLOC(env->allocator, size);
+ memcpy(tmp, content, i);
+ AXIS2_FREE(env->allocator, content);
+ content = tmp;
+ }
+ content[i++] = (axis2_char_t)c;
+ c = fgetc(wsdl_file);
+ }
+ content[i] = AXIS2_ESC_NULL;
+ wsdl_string = (axis2_char_t *)content;
+ fclose(wsdl_file);
+ }
+
+ AXIS2_FREE(env->allocator, wsdl_path);
+ }
+ else
+ {
+ wsdl_string = axutil_strdup(env, "Unable to retrieve wsdl for this service");
+ }
+
+ return wsdl_string;
+}
+
+AXIS2_EXTERN axutil_string_t *AXIS2_CALL
+axis2_http_transport_utils_get_charset_enc(
+ const axutil_env_t * env,
+ const axis2_char_t * content_type)
+{
+ axis2_char_t *tmp = NULL;
+ axis2_char_t *tmp_content_type = NULL;
+ axis2_char_t *tmp2 = NULL;
+ axutil_string_t *str = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, content_type, NULL);
+
+ tmp_content_type = (axis2_char_t *)content_type;
+ if(!tmp_content_type)
+ {
+ return axutil_string_create_const(env,
+ (axis2_char_t **)&AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING);
+ }
+
+ tmp = strstr(tmp_content_type, AXIS2_HTTP_CHAR_SET_ENCODING);
+
+ if(tmp)
+ {
+ tmp = strchr(tmp, AXIS2_EQ);
+ if(tmp)
+ {
+ tmp2 = strchr(tmp, AXIS2_SEMI_COLON);
+ if(!tmp2)
+ {
+ tmp2 = tmp + strlen(tmp);
+ }
+ }
+
+ if(tmp2)
+ {
+ if('\'' == *(tmp2 - sizeof(axis2_char_t)) || '\"' == *(tmp2 - sizeof(axis2_char_t)))
+ {
+ tmp2 -= sizeof(axis2_char_t);
+ }
+ *tmp2 = AXIS2_ESC_NULL;
+ }
+ }
+
+ if(tmp)
+ {
+ /* Following formats are acceptable
+ * charset="UTF-8"
+ * charser='UTF-8'
+ * charset=UTF-8
+ * But for our requirements charset we get should be UTF-8
+ */
+ if(AXIS2_ESC_SINGLE_QUOTE == *(tmp + sizeof(axis2_char_t)) || AXIS2_ESC_DOUBLE_QUOTE
+ == *(tmp + sizeof(axis2_char_t)))
+ {
+ tmp += 2 * sizeof(axis2_char_t);
+ }
+ else
+ {
+ tmp += sizeof(axis2_char_t);
+ }
+ }
+
+ if(tmp)
+ {
+ str = axutil_string_create(env, tmp);
+ }
+ else
+ {
+ str = axutil_string_create_const(env,
+ (axis2_char_t **)&AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING);
+ }
+ return str;
+}
+
+int AXIS2_CALL
+axis2_http_transport_utils_on_data_request(
+ char *buffer,
+ int size,
+ void *ctx)
+{
+ const axutil_env_t *env = NULL;
+ int len = -1;
+ axis2_callback_info_t *cb_ctx = (axis2_callback_info_t *)ctx;
+
+ if(!buffer || !ctx)
+ {
+ return 0;
+ }
+ env = ((axis2_callback_info_t *)ctx)->env;
+ if(cb_ctx->unread_len <= 0 && -1 != cb_ctx->content_length)
+ {
+ return 0;
+ }
+ if(cb_ctx->chunked_stream)
+ {
+ --size;
+ /* reserve space to insert trailing null */
+ len = axutil_http_chunked_stream_read(cb_ctx->chunked_stream, env, buffer, size);
+ if(len >= 0)
+ {
+ buffer[len] = AXIS2_ESC_NULL;
+ }
+ }
+ else
+ {
+ axutil_stream_t *in_stream = NULL;
+ in_stream = (axutil_stream_t *)((axis2_callback_info_t *)ctx)->in_stream;
+ --size; /* reserve space to insert trailing null */
+ len = axutil_stream_read(in_stream, env, buffer, size);
+ if(len > 0)
+ {
+ buffer[len] = AXIS2_ESC_NULL;
+ ((axis2_callback_info_t *)ctx)->unread_len -= len;
+ }
+ else if(len == 0)
+ {
+ ((axis2_callback_info_t *)ctx)->unread_len = 0;
+ }
+ }
+ return len;
+}
+
+AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
+axis2_http_transport_utils_create_soap_msg(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ const axis2_char_t * soap_ns_uri)
+{
+ axis2_op_ctx_t *op_ctx = NULL;
+ const axis2_char_t *char_set_enc = NULL;
+ axis2_char_t *content_type = NULL;
+ axutil_stream_t *in_stream = NULL;
+ axis2_callback_info_t *callback_ctx = NULL;
+ axis2_char_t *trans_enc = NULL;
+ int *content_length = NULL;
+ axutil_property_t *property = NULL;
+ axutil_hash_t *binary_data_map = NULL;
+ axiom_soap_envelope_t *soap_envelope = NULL;
+ axutil_stream_t *stream = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL);
+ AXIS2_PARAM_CHECK(env->error, soap_ns_uri, NULL);
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_IN);
+ if(property)
+ {
+ in_stream = axutil_property_get_value(property, env);
+ property = NULL;
+ }
+ callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t));
+ /* Note: the memory created above is freed in xml reader free function
+ as this is passed on to the reader */
+ if(!callback_ctx)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ callback_ctx->in_stream = in_stream;
+ callback_ctx->env = env;
+ callback_ctx->content_length = -1;
+ callback_ctx->unread_len = -1;
+ callback_ctx->chunked_stream = NULL;
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH);
+ if(property)
+ {
+ content_length = axutil_property_get_value(property, env);
+ property = NULL;
+ }
+
+ if(content_length)
+ {
+ callback_ctx->content_length = *content_length;
+ callback_ctx->unread_len = *content_length;
+ }
+
+ if(!in_stream)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_IN_STREAM_IN_MSG_CTX, AXIS2_FAILURE);
+ AXIS2_FREE(env->allocator, callback_ctx);
+ return NULL;
+ }
+
+ trans_enc = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env);
+
+ if(trans_enc && 0 == axutil_strcmp(trans_enc, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ callback_ctx->chunked_stream = axutil_http_chunked_stream_create(env, in_stream);
+ if(!callback_ctx->chunked_stream)
+ {
+ return NULL;
+ }
+ }
+
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+ if(op_ctx)
+ {
+ axis2_ctx_t *ctx = axis2_op_ctx_get_base(op_ctx, env);
+ if(ctx)
+ {
+ property = axis2_ctx_get_property(ctx, env, AXIS2_CHARACTER_SET_ENCODING);
+ if(property)
+ {
+ char_set_enc = axutil_property_get_value(property, env);
+ property = NULL;
+ }
+ property = axis2_ctx_get_property(ctx, env, MTOM_RECIVED_CONTENT_TYPE);
+ if(property)
+ {
+ content_type = axutil_property_get_value(property, env);
+ property = NULL;
+ }
+
+ }
+ }
+
+ if(!char_set_enc)
+ {
+ char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING;
+ }
+ if(content_type)
+ {
+ axis2_char_t *mime_boundary = NULL;
+ axis2_msg_ctx_set_doing_mtom(msg_ctx, env, AXIS2_TRUE);
+ /* get mime boundry */
+ mime_boundary = axis2_http_transport_utils_get_value_from_content_type(env, content_type,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE_MIME_BOUNDARY);
+
+ if(mime_boundary)
+ {
+ axiom_mime_parser_t *mime_parser = NULL;
+ int soap_body_len = 0;
+ axis2_char_t *soap_body_str = NULL;
+ axutil_param_t *buffer_size_param = NULL;
+ axutil_param_t *max_buffers_param = NULL;
+ axutil_param_t *attachment_dir_param = NULL;
+ axutil_param_t *callback_name_param = NULL;
+ axis2_char_t *value_size = NULL;
+ axis2_char_t *value_num = NULL;
+ axis2_char_t *value_dir = NULL;
+ axis2_char_t *value_callback = NULL;
+ int size = 0;
+ int num = 0;
+
+ mime_parser = axiom_mime_parser_create(env);
+
+ /* Following are the parameters in the axis2.xml regarding MTOM */
+
+ buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE);
+ if(buffer_size_param)
+ {
+ value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env);
+
+ if(value_size)
+ {
+ size = atoi(value_size);
+ axiom_mime_parser_set_buffer_size(mime_parser, env, size);
+ }
+ }
+
+ max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS);
+ if(max_buffers_param)
+ {
+ value_num = (axis2_char_t *)axutil_param_get_value(max_buffers_param, env);
+ if(value_num)
+ {
+ num = atoi(value_num);
+ axiom_mime_parser_set_max_buffers(mime_parser, env, num);
+ }
+ }
+
+ callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env,
+ AXIS2_MTOM_CACHING_CALLBACK);
+ if(callback_name_param)
+ {
+ value_callback = (axis2_char_t *)axutil_param_get_value(callback_name_param, env);
+ if(value_callback)
+ {
+ axiom_mime_parser_set_caching_callback_name(mime_parser, env, value_callback);
+ }
+ }
+
+ attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR);
+ if(attachment_dir_param)
+ {
+ value_dir = (axis2_char_t *)axutil_param_get_value(attachment_dir_param, env);
+ if(value_dir)
+ {
+ axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
+ }
+ }
+
+ if(mime_parser)
+ {
+ if(axiom_mime_parser_parse_for_soap(mime_parser, env,
+ axis2_http_transport_utils_on_data_request, (void *)callback_ctx, mime_boundary)
+ == AXIS2_FAILURE)
+ {
+ return NULL;
+ }
+
+ binary_data_map = axiom_mime_parser_parse_for_attachments(mime_parser, env,
+ axis2_http_transport_utils_on_data_request, (void *)callback_ctx,
+ mime_boundary, NULL);
+ if(!binary_data_map)
+ {
+ return NULL;
+ }
+
+ if(!binary_data_map)
+ {
+ return NULL;
+ }
+
+ soap_body_len = (int)axiom_mime_parser_get_soap_body_len(mime_parser, env);
+ soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env);
+ }
+
+ if(callback_ctx->chunked_stream)
+ {
+ axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env);
+ callback_ctx->chunked_stream = NULL;
+ }
+
+ stream = axutil_stream_create_basic(env);
+ if(stream)
+ {
+ axutil_stream_write(stream, env, soap_body_str, soap_body_len);
+ callback_ctx->in_stream = stream;
+ callback_ctx->chunked_stream = NULL;
+ callback_ctx->content_length = soap_body_len;
+ callback_ctx->unread_len = soap_body_len;
+ }
+
+ axiom_mime_parser_free(mime_parser, env);
+ mime_parser = NULL;
+ if(mime_boundary)
+ {
+ AXIS2_FREE(env->allocator, mime_boundary);
+ }
+
+ if(soap_body_str)
+ {
+ AXIS2_FREE(env->allocator, soap_body_str);
+ }
+ }
+ }
+
+ if(AXIS2_TRUE != axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ axiom_xml_reader_t *xml_reader = NULL;
+ axiom_stax_builder_t *om_builder = NULL;
+ axiom_soap_builder_t *soap_builder = NULL;
+
+ xml_reader = axiom_xml_reader_create_for_io(env,
+ axis2_http_transport_utils_on_data_request, NULL, (void *)callback_ctx, char_set_enc);
+ if(!xml_reader)
+ {
+ return NULL;
+ }
+ om_builder = axiom_stax_builder_create(env, xml_reader);
+ if(!om_builder)
+ {
+ axiom_xml_reader_free(xml_reader, env);
+ xml_reader = NULL;
+ return NULL;
+ }
+ soap_builder = axiom_soap_builder_create(env, om_builder, soap_ns_uri);
+ if(!soap_builder)
+ {
+ /* We should not be freeing om_builder here as it is done by
+ axiom_soap_builder_create in case of error - Samisa */
+ om_builder = NULL;
+ xml_reader = NULL;
+ return NULL;
+ }
+
+ soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
+
+ if(binary_data_map)
+ {
+ axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map);
+ }
+
+ if(soap_envelope)
+ {
+ /* hack to get around MTOM problem */
+ axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
+
+ if(soap_body)
+ {
+ axiom_soap_body_has_fault(soap_body, env);
+ }
+ }
+ if(stream)
+ {
+ axutil_stream_free(stream, env);
+ callback_ctx->in_stream = NULL;
+ }
+ if(callback_ctx->chunked_stream)
+ {
+ axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env);
+ callback_ctx->chunked_stream = NULL;
+ }
+
+ }
+ else
+ {
+ /* REST processing */
+ axiom_xml_reader_t *xml_reader = NULL;
+ axiom_stax_builder_t *om_builder = NULL;
+ axiom_soap_body_t *def_body = NULL;
+ axiom_document_t *om_doc = NULL;
+ axiom_node_t *root_node = NULL;
+
+ xml_reader = axiom_xml_reader_create_for_io(env,
+ axis2_http_transport_utils_on_data_request, NULL, (void *)callback_ctx, char_set_enc);
+ if(!xml_reader)
+ {
+ return NULL;
+ }
+ om_builder = axiom_stax_builder_create(env, xml_reader);
+ if(!om_builder)
+ {
+ axiom_xml_reader_free(xml_reader, env);
+ xml_reader = NULL;
+ return NULL;
+ }
+ soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
+ def_body = axiom_soap_envelope_get_body(soap_envelope, env);
+ om_doc = axiom_stax_builder_get_document(om_builder, env);
+ root_node = axiom_document_build_all(om_doc, env);
+ axiom_soap_body_add_child(def_body, env, root_node);
+ axiom_stax_builder_free_self(om_builder, env);
+ }
+
+ return soap_envelope;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_value_from_content_type(
+ const axutil_env_t * env,
+ const axis2_char_t * content_type,
+ const axis2_char_t * key)
+{
+ axis2_char_t *tmp = NULL;
+ axis2_char_t *tmp_content_type = NULL;
+ axis2_char_t *tmp2 = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, content_type, NULL);
+ AXIS2_PARAM_CHECK(env->error, key, NULL);
+
+ tmp_content_type = axutil_strdup(env, content_type);
+ if(!tmp_content_type)
+ {
+ return NULL;
+ }
+ tmp = strstr(tmp_content_type, key);
+ if(!tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp_content_type);
+ return NULL;
+ }
+
+ tmp = strchr(tmp, AXIS2_EQ);
+ tmp2 = strchr(tmp, AXIS2_SEMI_COLON);
+
+ if(tmp2)
+ {
+ *tmp2 = AXIS2_ESC_NULL;
+ }
+ if(!tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp_content_type);
+ return NULL;
+ }
+
+ tmp2 = axutil_strdup(env, tmp + 1);
+
+ AXIS2_FREE(env->allocator, tmp_content_type);
+ if(*tmp2 == AXIS2_DOUBLE_QUOTE)
+ {
+ tmp = tmp2;
+ tmp2 = axutil_strdup(env, tmp + 1);
+ tmp2[strlen(tmp2) - 1] = AXIS2_ESC_NULL;
+ if(tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp);
+ tmp = NULL;
+ }
+
+ }
+ /* handle XOP */
+ if(*tmp2 == AXIS2_B_SLASH && *(tmp2 + 1) == '\"')
+ {
+ tmp = tmp2;
+ tmp2 = axutil_strdup(env, tmp + 2);
+ tmp2[strlen(tmp2) - 3] = AXIS2_ESC_NULL;
+ if(tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp);
+ tmp = NULL;
+ }
+ }
+ return tmp2;
+}
+
+AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
+axis2_http_transport_utils_handle_media_type_url_encoded(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axutil_hash_t * param_map,
+ axis2_char_t * method)
+{
+ axiom_soap_envelope_t *soap_env = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axiom_element_t *body_child = NULL;
+ axiom_node_t *body_child_node = NULL;
+ axiom_node_t *body_element_node = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL);
+ AXIS2_PARAM_CHECK(env->error, method, NULL);
+
+ soap_env = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
+
+ if(!soap_env)
+ {
+ soap_env = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
+ }
+ soap_body = axiom_soap_envelope_get_body(soap_env, env);
+ if(!soap_body)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ body_element_node = axiom_soap_body_get_base_node(soap_body, env);
+
+ if(body_element_node)
+ {
+ body_child_node = axiom_node_get_first_child(body_element_node, env);
+ }
+
+ if(!body_child_node)
+ {
+ if(!axis2_msg_ctx_get_op(msg_ctx, env))
+ {
+ return NULL;
+ }
+ body_child = axiom_element_create_with_qname(env, NULL, axis2_op_get_qname(
+ axis2_msg_ctx_get_op(msg_ctx, env), env), &body_child_node);
+ axiom_soap_body_add_child(soap_body, env, body_child_node);
+ }
+ if(param_map)
+ {
+ axutil_hash_index_t *hi = NULL;
+ for(hi = axutil_hash_first(param_map, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ void *name = NULL;
+ void *value = NULL;
+ axiom_node_t *node = NULL;
+ axiom_element_t *element = NULL;
+
+ axutil_hash_this(hi, (const void **)&name, NULL, (void **)&value);
+ element = axiom_element_create(env, NULL, (axis2_char_t *)name, NULL, &node);
+ axiom_element_set_text(element, env, (axis2_char_t *)value, node);
+ axiom_node_add_child(body_child_node, env, node);
+ }
+ }
+ return soap_env;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_dispatch_and_verify(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_disp_t *rest_disp = NULL;
+ axis2_handler_t *handler = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ if(axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ rest_disp = axis2_rest_disp_create(env);
+ handler = axis2_disp_get_base(rest_disp, env);
+ axis2_handler_invoke(handler, env, msg_ctx);
+
+ if(!axis2_msg_ctx_get_svc(msg_ctx, env) || !axis2_msg_ctx_get_op(msg_ctx, env))
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SVC_OR_OP_NOT_FOUND, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axis2_http_transport_utils_process_accept_headers(
+ const axutil_env_t *env,
+ axis2_char_t *accept_value)
+{
+ axutil_array_list_t *accept_field_list = NULL;
+ axutil_array_list_t *accept_record_list = NULL;
+ accept_field_list = axutil_tokenize(env, accept_value, ',');
+ if(accept_field_list && axutil_array_list_size(accept_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_field_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_field_list, env, 0);
+ }
+ while(token);
+ }
+ if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0)
+ {
+ return accept_record_list;
+ }
+ return NULL;
+}
+
+int
+axis2_http_transport_utils_check_status_code(
+ int status_code)
+{
+ int status = AXIS2_HTTP_RESPONSE_OK_CODE_VAL;
+ switch(status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_ACK_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_GONE_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ status = AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL;
+ break;
+ }
+ return status;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_process_request(
+ const axutil_env_t *env,
+ axis2_conf_ctx_t *conf_ctx,
+ axis2_http_transport_in_t *request,
+ axis2_http_transport_out_t *response)
+{
+ axis2_status_t status = AXIS2_FAILURE;
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axutil_stream_t *out_stream = NULL;
+ axutil_string_t *soap_action = NULL;
+ axis2_bool_t processed = AXIS2_FALSE;
+ axis2_char_t *body_string = NULL;
+ axis2_char_t *ctx_uuid = NULL;
+ axis2_op_ctx_t *op_ctx = NULL;
+ axis2_char_t *peer_ip = NULL;
+ axutil_property_t *peer_property = NULL;
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, request, AXIS2_CRITICAL_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, request->request_uri, AXIS2_FALSE);
+
+ if(!conf_ctx)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE);
+ return AXIS2_CRITICAL_FAILURE;
+ }
+
+ if(!request->content_type)
+ {
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN;
+ }
+
+ /** creating the out stream */
+ out_stream = axutil_stream_create_basic(env);
+
+ if(request->transfer_encoding)
+ axis2_msg_ctx_set_transfer_encoding(request->msg_ctx, env, request->transfer_encoding);
+
+ axis2_msg_ctx_set_server_side(request->msg_ctx, env, AXIS2_TRUE);
+ msg_ctx = request->msg_ctx;
+ peer_ip = request->remote_ip;
+
+ if(peer_ip)
+ {
+ peer_property = axutil_property_create(env);
+ axutil_property_set_value(peer_property, env, axutil_strdup(env, peer_ip));
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_SVR_PEER_IP_ADDR, peer_property);
+ }
+
+ axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream);
+
+ ctx_uuid = axutil_uuid_gen(env);
+ if(ctx_uuid)
+ {
+ axutil_string_t *uuid_str = axutil_string_create_assume_ownership(env, &ctx_uuid);
+ axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, uuid_str);
+ axutil_string_free(uuid_str, env);
+ }
+
+ axis2_msg_ctx_set_out_transport_info(msg_ctx, env,
+ &(request->out_transport_info->out_transport));
+
+ if(request->accept_header)
+ {
+ axutil_array_list_t *accept_record_list = NULL;
+ accept_record_list = axis2_http_transport_utils_process_accept_headers(env,
+ request->accept_header);
+ if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0)
+ {
+ axis2_msg_ctx_set_http_accept_record_list(msg_ctx, env, accept_record_list);
+ }
+ }
+ if(request->accept_charset_header)
+ {
+ axutil_array_list_t *accept_charset_record_list = NULL;
+ accept_charset_record_list = axis2_http_transport_utils_process_accept_headers(env,
+ request->accept_charset_header);
+ if(accept_charset_record_list)
+ {
+ axis2_msg_ctx_set_http_accept_charset_record_list(msg_ctx, env,
+ accept_charset_record_list);
+ }
+ }
+ if(request->accept_language_header)
+ {
+ axutil_array_list_t *accept_language_record_list = NULL;
+ accept_language_record_list = axis2_http_transport_utils_process_accept_headers(env,
+ request->accept_language_header);
+ if(accept_language_record_list)
+ {
+ axis2_msg_ctx_set_http_accept_language_record_list(msg_ctx, env,
+ accept_language_record_list);
+ }
+ }
+
+ if(request->soap_action)
+ {
+ soap_action = axutil_string_create(env, request->soap_action);
+ }
+
+ if(request->request_method == AXIS2_HTTP_METHOD_GET || request->request_method
+ == AXIS2_HTTP_METHOD_DELETE || request->request_method == AXIS2_HTTP_METHOD_HEAD)
+ {
+
+ if(request->request_method == AXIS2_HTTP_METHOD_DELETE)
+ {
+ processed = axis2_http_transport_utils_process_http_delete_request(env,
+ request->msg_ctx, request->in_stream, out_stream, request->content_type,
+ soap_action, request->request_uri, conf_ctx,
+ axis2_http_transport_utils_get_request_params(env, request->request_uri));
+ }
+ else if(request->request_method == AXIS2_HTTP_METHOD_HEAD)
+ {
+ processed = axis2_http_transport_utils_process_http_head_request(env, request->msg_ctx,
+ request->in_stream, out_stream, request->content_type, soap_action,
+ request->request_uri, conf_ctx, axis2_http_transport_utils_get_request_params(env,
+ request->request_uri));
+ }
+ else if(request->request_method == AXIS2_HTTP_METHOD_GET)
+ {
+ processed = axis2_http_transport_utils_process_http_get_request(env, request->msg_ctx,
+ request->in_stream, out_stream, request->content_type, soap_action,
+ request->request_uri, conf_ctx, axis2_http_transport_utils_get_request_params(env,
+ request->request_uri));
+ }
+ if(AXIS2_FALSE == processed)
+ {
+ axis2_bool_t is_services_path = AXIS2_FALSE;
+ int msg_ctx_status_code = axis2_msg_ctx_get_status_code(msg_ctx, env);
+ if(request->request_method != AXIS2_HTTP_METHOD_DELETE && request->request_url_prefix)
+ {
+ axis2_char_t *temp = NULL;
+ temp = strstr(request->request_uri, request->request_url_prefix);
+ if(temp)
+ {
+ temp += strlen(request->request_url_prefix);
+ if(*temp == '/')
+ {
+ temp++;
+ }
+ if(!*temp || *temp == '?' || *temp == '#')
+ {
+ is_services_path = AXIS2_TRUE;
+ }
+ }
+ }
+ if(is_services_path)
+ {
+ body_string = axis2_http_transport_utils_get_services_html(env, conf_ctx);
+ response->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ response->http_status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_OK_CODE_NAME;
+ }
+ else if(AXIS2_HTTP_METHOD_DELETE != request->request_method)
+ {
+ axis2_char_t *wsdl = NULL;
+ wsdl = strstr(request->request_uri, AXIS2_REQUEST_WSDL);
+ if(wsdl)
+ {
+ body_string = axis2_http_transport_utils_get_services_static_wsdl(env,
+ conf_ctx, request->request_uri);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
+ response->http_status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_OK_CODE_NAME;
+ }
+ }
+ else if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND)
+ {
+ axutil_array_list_t *method_list = NULL;
+ int size = 0;
+ method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env);
+ size = axutil_array_list_size(method_list, env);
+
+ if(method_list && size)
+ {
+ /** 405 */
+ body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx);
+
+ response->http_status_code = AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL;
+ response->http_status_code_name
+ = AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME;
+ }
+ else
+ {
+ /** 404 */
+ body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME;
+ }
+ }
+ else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL)
+ {
+ /* 400, Bad Request */
+ body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME;
+
+ }
+ else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL)
+ {
+ /* 408, Request Timeout */
+ body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME;
+ }
+ else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL)
+ {
+ /* 409, Conflict Types */
+ body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME;
+ }
+ else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL)
+ {
+ /* 410, Gone. Resource no longer available */
+ body_string = axis2_http_transport_utils_get_gone(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_GONE_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_GONE_CODE_NAME;
+
+ }
+ else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL)
+ {
+ /*410, Precondition for the url failed */
+ body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME;
+
+ }
+ else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL)
+ {
+ /* 413, Request entity too large */
+ body_string
+ = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL;
+ response->http_status_code_name
+ = AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME;
+ }
+ else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL)
+ {
+ /* 513, Service Unavailable */
+ body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME;
+ }
+ else
+ {
+ /* 500, Internal Server Error */
+ body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL;
+ response->http_status_code_name
+ = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME;
+ }
+
+ if(body_string)
+ {
+ response->response_data = body_string;
+ response->response_data_length = axutil_strlen(body_string);
+ }
+ status = AXIS2_SUCCESS;
+ }
+ }
+ else if(AXIS2_HTTP_METHOD_POST == request->request_method || AXIS2_HTTP_METHOD_PUT
+ == request->request_method)
+ {
+ if(AXIS2_HTTP_METHOD_POST == request->request_method)
+ {
+ processed = axis2_http_transport_utils_process_http_post_request(env, request->msg_ctx,
+ request->in_stream, out_stream, request->content_type, request->content_length,
+ soap_action, request->request_uri);
+ }
+ else
+ {
+ processed = axis2_http_transport_utils_process_http_put_request(env, request->msg_ctx,
+ request->in_stream, out_stream, request->content_type, request->content_length,
+ soap_action, request->request_uri);
+ }
+ if(AXIS2_FAILURE == processed && (AXIS2_HTTP_METHOD_PUT == request->request_method
+ || axis2_msg_ctx_get_doing_rest(msg_ctx, env)))
+ {
+
+ if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND)
+ {
+ axutil_array_list_t *method_list = NULL;
+ int size = 0;
+ method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env);
+ size = axutil_array_list_size(method_list, env);
+ if(method_list && size)
+ {
+ /** 405 */
+ body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL;
+ response->http_status_code_name
+ = AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME;
+ }
+ else
+ {
+ /** 404 */
+ body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME;
+ }
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ }
+ else
+ {
+ /* 500, Internal Server Error */
+ body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL;
+ response->http_status_code_name
+ = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME;
+
+ }
+
+ if(body_string)
+ {
+ response->response_data = body_string;
+ response->response_data_length = axutil_strlen(body_string);
+ }
+ status = AXIS2_SUCCESS;
+ }
+ else if(processed == AXIS2_FAILURE)
+ {
+ axis2_msg_ctx_t *fault_ctx = NULL;
+ axis2_char_t *fault_code = NULL;
+ axis2_engine_t *engine = axis2_engine_create(env, conf_ctx);
+ if(!engine)
+ {
+ /* Critical error, cannot proceed, send defaults document for 500 */
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":"
+ AXIOM_SOAP11_FAULT_CODE_SENDER;
+ }
+ else
+ {
+ fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":"
+ AXIOM_SOAP12_SOAP_FAULT_VALUE_SENDER;
+ }
+ fault_ctx = axis2_engine_create_fault_msg_ctx(engine, env, request->msg_ctx,
+ fault_code, axutil_error_get_message(env->error));
+
+ axis2_engine_send_fault(engine, env, fault_ctx);
+ if (out_stream)
+ {
+ response->response_data = axutil_stream_get_buffer(out_stream, env);
+ response->response_data_length = axutil_stream_get_len (out_stream, env);
+ }
+ /* In case of a SOAP Fault, we have to set the status to 500, but still return */
+ status = AXIS2_SUCCESS;
+ response->http_status_code = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME;
+ }
+ }
+ else
+ {
+ response->response_data = axis2_http_transport_utils_get_not_implemented(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (response->response_data)
+ {
+ response->response_data_length = axutil_strlen(response->response_data);
+ }
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_NAME;
+ status = AXIS2_SUCCESS;
+ }
+
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+
+ if (op_ctx)
+ {
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ response->msg_ctx = out_msg_ctx;
+ }
+
+ if (status == AXIS2_FAILURE)
+ {
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ if (AXIS2_HTTP_METHOD_POST != request->request_method ||
+ axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ do_rest = AXIS2_TRUE;
+ }
+ if ((request->accept_header || request->accept_charset_header ||
+ request->accept_language_header) && do_rest)
+ {
+ axis2_char_t *content_type_header_value = NULL;
+ axis2_char_t *temp = NULL;
+ axis2_char_t *language_header_value = NULL;
+
+ content_type_header_value = (axis2_char_t *) request->content_type;
+ language_header_value = axis2_msg_ctx_get_content_language(out_msg_ctx,env);
+ if (content_type_header_value)
+ {
+ temp = axutil_strdup(env, content_type_header_value);
+ }
+ if (temp)
+ {
+ axis2_char_t *content_type = NULL;
+ axis2_char_t *char_set = NULL;
+ axis2_char_t *temp2 = NULL;
+
+ temp2 = strchr(temp, ';');
+ if (temp2)
+ {
+ *temp2 = '\0';
+ temp2++;
+ char_set = axutil_strcasestr(temp2, AXIS2_HTTP_CHAR_SET_ENCODING);
+ }
+ if (char_set)
+ {
+ char_set = axutil_strltrim(env, char_set, " \t=");
+ }
+ if (char_set)
+ {
+ temp2 = strchr(char_set, ';');
+ }
+ if (temp2)
+ {
+ *temp2 = '\0';
+ }
+ content_type = axutil_strtrim(env, temp, NULL);
+
+ if (temp)
+ {
+ AXIS2_FREE(env->allocator, temp);
+ temp = NULL;
+ }
+ if (content_type && request->accept_header &&
+ !axutil_strcasestr(request->accept_header, content_type))
+ {
+ temp2 = strchr(content_type, '/');
+ if (temp2)
+ {
+ *temp2 = '\0';
+ temp = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * ((int)strlen(content_type) + 3));
+ if (!temp)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return AXIS2_FALSE;
+ }
+ sprintf(temp, "%s/*", content_type);
+ if (!axutil_strcasestr(request->accept_header, temp) &&
+ !strstr(request->accept_header, AXIS2_HTTP_HEADER_ACCEPT_ALL))
+ {
+ response->response_data =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ response->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ if (response->response_data)
+ {
+ response->response_data_length = axutil_strlen(response->response_data);
+ }
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_NAME;
+ status = AXIS2_TRUE;
+ }
+ AXIS2_FREE(env->allocator, temp);
+ }
+ }
+ if (content_type)
+ {
+ AXIS2_FREE(env->allocator, content_type);
+ }
+ if (char_set && request->accept_charset_header &&
+ !axutil_strcasestr(request->accept_charset_header , char_set))
+ {
+ response->response_data =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ response->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (response->response_data)
+ {
+ response->response_data_length= axutil_strlen(response->response_data);
+ }
+ status = AXIS2_SUCCESS;
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME;
+ }
+ if (char_set)
+ {
+ AXIS2_FREE(env->allocator, char_set);
+ }
+ }
+ if (language_header_value)
+ {
+ if (request->accept_language_header &&
+ !axutil_strcasestr(request->accept_language_header , language_header_value))
+ {
+ response->response_data =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ response->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ if (response->response_data)
+ {
+ response->response_data_length = axutil_strlen(response->response_data);
+ }
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME;
+ }
+ }
+ }
+ }
+ if (status == AXIS2_FAILURE)
+ {
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ if (AXIS2_HTTP_METHOD_POST != request->request_method ||
+ axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ do_rest = AXIS2_TRUE;
+ }
+ if (op_ctx && axis2_op_ctx_get_response_written(op_ctx, env))
+ {
+ if (do_rest)
+ {
+ if (out_msg_ctx)
+ {
+ int size = 0;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list, env);
+ response->output_headers = output_header_list;
+ }
+
+ if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ response->http_status_code =
+ axis2_http_transport_utils_check_status_code(status_code);
+ status = AXIS2_SUCCESS;
+ }
+ }
+ }
+ if (status == AXIS2_FAILURE)
+ {
+ status = AXIS2_SUCCESS;
+ if (out_stream)
+ {
+ response->response_data = axutil_stream_get_buffer(out_stream, env);
+ response->response_data_length = axutil_stream_get_len(out_stream, env);
+ response->http_status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_OK_CODE_NAME;
+ }
+ }
+ }
+ else if (op_ctx)
+ {
+ if (do_rest)
+ {
+ if (out_msg_ctx)
+ {
+ int size = 0;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list, env);
+ response->output_headers = output_header_list;
+ }
+ if (axis2_msg_ctx_get_no_content(out_msg_ctx, env))
+ {
+ if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL:
+ response->http_status_code = AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL;
+ break;
+ default:
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL;
+ break;
+ }
+ }
+ else
+ {
+ response->http_status_code = AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL;
+ }
+ status = AXIS2_SUCCESS;
+ }
+ else if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ response->http_status_code =
+ axis2_http_transport_utils_check_status_code(status_code);
+ status = AXIS2_SUCCESS;
+ }
+ }
+ }
+ if (status == AXIS2_FAILURE)
+ {
+ response->http_status_code = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_ACK_CODE_NAME;
+ status = AXIS2_SUCCESS;
+ }
+ }
+ else
+ {
+ status = AXIS2_SUCCESS;
+ response->http_status_code = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL;
+ response->http_status_code_name = AXIS2_HTTP_RESPONSE_ACK_CODE_NAME;
+ }
+ }
+ axutil_string_free(soap_action, env);
+ msg_ctx = NULL;
+
+ return status;
+}
+
+/* This method takes an array_list as the input. It has items some
+ may be buffers and some may be files. This will send these part
+ one by one to the wire using the chunked stream.*/
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_transport_utils_send_mtom_message(
+ axutil_http_chunked_stream_t * chunked_stream,
+ const axutil_env_t * env,
+ axutil_array_list_t *mime_parts,
+ axis2_char_t *sending_callback_name)
+{
+ int i = 0;
+ axis2_status_t status = AXIS2_SUCCESS;
+
+ for(i = 0; i < axutil_array_list_size(mime_parts, env); i++)
+ {
+ axiom_mime_part_t *mime_part = NULL;
+ mime_part = (axiom_mime_part_t *)axutil_array_list_get(mime_parts, env, i);
+
+ /* If it is a buffer just write it to the wire. This includes mime_bounadaries,
+ * mime_headers and SOAP */
+ if(mime_part->type == AXIOM_MIME_PART_BUFFER)
+ {
+ size_t written = 0;
+ while(written < mime_part->part_size)
+ {
+ int len = 0;
+ len = axutil_http_chunked_stream_write(chunked_stream, env,
+ mime_part->part + written, mime_part->part_size - written);
+ if(len == -1)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ else
+ {
+ written += len;
+ }
+ }
+ }
+
+ /* If it is a file we load a very little portion to memory and send it as chunked ,
+ * we keep on doing this until we find the end of the file */
+ else if(mime_part->type == AXIOM_MIME_PART_FILE)
+ {
+ FILE *f = NULL;
+ axis2_byte_t *output_buffer = NULL;
+ int output_buffer_size = 0;
+
+ f = fopen(mime_part->file_name, "rb");
+ if(!f)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error opening file %s for reading",
+ mime_part->file_name);
+ return AXIS2_FAILURE;
+ }
+
+ /* If the part_size is less than the defined buffer size then
+ * from the first write to the wire we can send the file */
+ if(mime_part->part_size > AXIS2_MTOM_OUTPUT_BUFFER_SIZE)
+ {
+ output_buffer_size = AXIS2_MTOM_OUTPUT_BUFFER_SIZE;
+ }
+ else
+ {
+ output_buffer_size = (int)mime_part->part_size;
+ }
+
+ output_buffer = AXIS2_MALLOC(env->allocator, output_buffer_size * sizeof(axis2_char_t));
+
+ /*This is the method responsible for writing to the wire */
+ status = axis2_http_transport_utils_send_attachment_using_file(env, chunked_stream,
+ f, output_buffer, output_buffer_size);
+ AXIS2_FREE(env->allocator, output_buffer);
+ fclose(f);
+ }
+
+ /* if the callback is given, send data using callback */
+ else if((mime_part->type) == AXIOM_MIME_PART_CALLBACK)
+ {
+ void *handler = NULL;
+ axiom_mtom_sending_callback_t *callback = NULL;
+
+ handler = axis2_http_transport_utils_initiate_callback(env, sending_callback_name,
+ mime_part->user_param, &callback);
+ if(handler)
+ {
+ status = axis2_http_transport_utils_send_attachment_using_callback(env,
+ chunked_stream, callback, handler, mime_part->user_param);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MTOM Sending Callback loading failed");
+ status = AXIS2_FAILURE;
+ }
+
+ if(callback)
+ {
+ axutil_param_t *param = NULL;
+ param = callback->param;
+ AXIOM_MTOM_SENDING_CALLBACK_FREE(callback, env);
+ if(param)
+ {
+ axutil_param_free(param, env);
+ }
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unknown mime_part.");
+ status = AXIS2_FAILURE;
+ }
+
+ if(status != AXIS2_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ if(status == AXIS2_SUCCESS)
+ {
+ /* send the end of chunk */
+ status = axutil_http_chunked_stream_write_last_chunk(chunked_stream, env);
+ }
+
+ return status;
+}
+
+static axis2_status_t
+axis2_http_transport_utils_send_attachment_using_file(
+ const axutil_env_t * env,
+ axutil_http_chunked_stream_t *chunked_stream,
+ FILE *fp,
+ axis2_byte_t *buffer,
+ int buffer_size)
+{
+ /*We do not load the whole file to memory. Just load a buffer_size portion
+ *and send it. Keep on doing this until the end of file */
+ do
+ {
+ int written = 0;
+ int count = (int)fread(buffer, 1, buffer_size, fp);
+ if(ferror(fp) || (count < 0))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in reading file containing the attachment");
+ return AXIS2_FAILURE;
+ }
+
+ /* count == 0 is a valid case. If the file size is multiple of buffer_size, then last read
+ * will have count == 0
+ */
+
+ /*Writing the part we loaded to memory to the wire*/
+ while(written < count)
+ {
+ int len = axutil_http_chunked_stream_write(chunked_stream, env,
+ buffer + written, count - written);
+ if(len == -1)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "error in writing file to stream");
+ return AXIS2_FAILURE;
+ }
+
+ written += len;
+ }
+ }
+ while(!feof(fp));
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_transport_utils_destroy_mime_parts(
+ axutil_array_list_t *mime_parts,
+ const axutil_env_t *env)
+{
+ if (mime_parts)
+ {
+ int i = 0;
+ for (i = 0; i < axutil_array_list_size(mime_parts, env); i++)
+ {
+ axiom_mime_part_t *mime_part = NULL;
+ mime_part = (axiom_mime_part_t *)
+ axutil_array_list_get(mime_parts, env, i);
+ if (mime_part)
+ {
+ axiom_mime_part_free(mime_part, env);
+ }
+ }
+ axutil_array_list_free(mime_parts, env);
+ }
+}
+
+AXIS2_EXTERN void *AXIS2_CALL
+axis2_http_transport_utils_initiate_callback(
+ const axutil_env_t *env,
+ axis2_char_t *callback_name,
+ void *user_param,
+ axiom_mtom_sending_callback_t **callback)
+{
+ axutil_dll_desc_t *dll_desc = NULL;
+ axutil_param_t *impl_info_param = NULL;
+ void *ptr = NULL;
+
+ if(!callback_name)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "invalid callback name given");
+ return NULL;
+ }
+
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Trying to load module = %s", callback_name);
+
+ dll_desc = axutil_dll_desc_create(env);
+ axutil_dll_desc_set_name(dll_desc, env, callback_name);
+ impl_info_param = axutil_param_create(env, NULL, dll_desc);
+ axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg);
+ axutil_class_loader_init(env);
+ ptr = axutil_class_loader_create_dll(env, impl_info_param);
+ if (!ptr)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to load the module %s.", callback_name);
+ return NULL;
+ }
+
+ *callback = (axiom_mtom_sending_callback_t *)ptr;
+ (*callback)->param = impl_info_param;
+
+ return AXIOM_MTOM_SENDING_CALLBACK_INIT_HANDLER(*callback, env, user_param);
+}
+
+static axis2_status_t
+axis2_http_transport_utils_send_attachment_using_callback(
+ const axutil_env_t * env,
+ axutil_http_chunked_stream_t *chunked_stream,
+ axiom_mtom_sending_callback_t *callback,
+ void *handler,
+ void *user_param)
+{
+ int count = 0;
+ axis2_status_t status = AXIS2_SUCCESS;
+ axis2_char_t *buffer = NULL;
+
+ /* Keep on loading the data in a loop until all the data is sent */
+ while((count = AXIOM_MTOM_SENDING_CALLBACK_LOAD_DATA(callback, env, handler, &buffer)) > 0)
+ {
+ int written = 0;
+ while(written < count)
+ {
+ int len = 0;
+ len = axutil_http_chunked_stream_write(chunked_stream, env,
+ buffer + written, count - written);
+ if(len == -1)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+
+ written += len;
+ }
+ }
+
+ status = AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, handler) && status;
+ return status;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_transport_utils_is_callback_required(
+ const axutil_env_t *env,
+ axutil_array_list_t *mime_parts)
+{
+ int size = 0;
+ int i = 0;
+ axis2_bool_t is_required = AXIS2_FALSE;
+
+ size = axutil_array_list_size(mime_parts, env);
+ for(i = 0; i < size; i++)
+ {
+ axiom_mime_part_t *mime_part = NULL;
+ mime_part = (axiom_mime_part_t *)axutil_array_list_get(mime_parts, env, i);
+ if(mime_part)
+ {
+ if(mime_part->type == AXIOM_MIME_PART_CALLBACK)
+ {
+ is_required = AXIS2_TRUE;
+ break;
+ }
+ }
+ }
+
+ return is_required;
+}
+
+static void
+axis2_http_transport_utils_parse_session_str(const axutil_env_t *env, axis2_char_t *str,
+ axutil_hash_t *ht)
+{
+ while (*str)
+ {
+ axis2_char_t *next = axutil_strstr(str, ";");
+ if (next)
+ {
+ axis2_char_t *key = NULL;
+ axis2_char_t *val = NULL;
+
+
+ /* Get key and value pairs */
+ key = axis2_http_transport_utils_copy_key(env, str);
+ val = axis2_http_transport_utils_copy_value(env, str);
+ axutil_hash_set(ht, key, AXIS2_HASH_KEY_STRING, val);
+
+ /* find next token */
+ str = next + 1;
+ }
+
+ }
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_session(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx)
+{
+ axutil_hash_index_t *hi = NULL;
+ void *val = NULL;
+ const void *key = NULL;
+ axutil_hash_t *ht = NULL;
+ axis2_char_t *session_id = NULL;
+ axis2_char_t *time_str = NULL;
+ axis2_char_t *header_value = NULL;
+ axutil_date_time_t *expire_time = NULL;
+ axis2_char_t session_value[256];
+ axis2_http_out_transport_info_t *out_info = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_utils_get_session");
+ ht = axis2_msg_ctx_get_property_value(msg_ctx, env, AXIS2_TRANSPORT_SESSION_TABLE);
+ if(!ht)
+ {
+ axis2_op_ctx_t *op_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+ if(op_ctx)
+ {
+ in_msg_ctx = axis2_op_ctx_get_msg_ctx(op_ctx, env, AXIS2_WSDL_MESSAGE_LABEL_IN);
+ if(in_msg_ctx)
+ {
+ ht = axis2_msg_ctx_get_property_value(in_msg_ctx, env,
+ AXIS2_TRANSPORT_SESSION_TABLE);
+ }
+ }
+ if(!ht)
+ {
+ return NULL;
+ }
+ }
+ session_id = axutil_hash_get(ht, "id", AXIS2_HASH_KEY_STRING);
+ if(!session_id)
+ {
+ /* Generate session and set it in session table */
+ session_id = axutil_uuid_gen(env);
+ axutil_hash_set(ht, axutil_strdup(env, "id"), AXIS2_HASH_KEY_STRING, axutil_strdup(env,
+ session_id));
+
+ /* Generate expire time and set it in session table */
+ expire_time = axutil_date_time_create_with_offset(env, AXIS2_TRANSPORT_SESSION_EXPIRE_DURATION);
+ time_str = axutil_strdup(env, axutil_date_time_serialize_date_time(expire_time, env));
+ axutil_date_time_free(expire_time, env);
+ axutil_hash_set(ht, axutil_strdup(env, "expires"), AXIS2_HASH_KEY_STRING, time_str);
+
+ sprintf(session_value, "%s", "");
+
+ for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ axis2_char_t *name = NULL;
+ axis2_char_t *value = NULL;
+ int len = -1;
+
+ axutil_hash_this(hi, &key, NULL, &val);
+ name = (axis2_char_t *) key;
+ value = (axis2_char_t *) val;
+ if(name)
+ {
+ len = axutil_strlen(session_value);
+ sprintf(session_value + len, "%s=", name);
+ AXIS2_FREE(env->allocator, name);
+ }
+ if(value)
+ {
+ len = axutil_strlen(session_value);
+ sprintf(session_value + len, "%s;", value);
+ AXIS2_FREE(env->allocator, value);
+ }
+ }
+
+ out_info = (axis2_http_out_transport_info_t *)axis2_msg_ctx_get_out_transport_info(
+ msg_ctx, env);
+ if(!out_info)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_OUT_TRNSPORT_INFO_NULL, AXIS2_FAILURE);
+ AXIS2_FREE(env->allocator, header_value);
+ return NULL;
+ }
+ status = AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_SESSION(out_info, env, session_id, session_value);
+ if(status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Inserting session value failed for session id %s", session_id);
+ return NULL;
+ }
+ }
+ else
+ {
+ time_str = axutil_hash_get(ht, "expires", AXIS2_HASH_KEY_STRING);
+ }
+ header_value = AXIS2_MALLOC(env->allocator, 256 * sizeof(axis2_char_t));
+ sprintf(header_value, "ID=%s; expires=%s;", session_id, time_str);
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_utils_get_session");
+ return header_value;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_transport_utils_set_session(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_char_t *session_str)
+{
+ axutil_date_time_t *expire_time = NULL;
+ axutil_date_time_t *current_time = NULL;
+ axutil_date_time_comp_result_t result;
+ axis2_char_t *time_str = NULL;
+ axutil_hash_t *ht = NULL;
+ axutil_property_t *property = NULL;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_tranpsport_utils_set_session");
+
+ /* Check whether session has expired. If so set error and return */
+ ht = axutil_hash_make(env);
+ axis2_http_transport_utils_parse_session_str(env, session_str, ht);
+ time_str = (axis2_char_t *) axutil_hash_get(ht, "time", AXIS2_HASH_KEY_STRING);
+ expire_time = axutil_date_time_create(env);
+ axutil_date_time_deserialize_date_time(expire_time, env, time_str);
+ current_time = axutil_date_time_create(env);
+ result = axutil_date_time_compare(current_time, env, expire_time);
+ axutil_date_time_free(current_time, env);
+ axutil_date_time_free(expire_time, env);
+ if(result == AXIS2_DATE_TIME_COMP_RES_EXPIRED)
+ {
+ axutil_hash_index_t *hi = NULL;
+ void *val = NULL;
+ const void *key = NULL;
+
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Session time out");
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SESSION_TIMEOUT, AXIS2_FAILURE);
+ for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ axis2_char_t *name = NULL;
+ axis2_char_t *value = NULL;
+
+ axutil_hash_this(hi, &key, NULL, &val);
+ name = (axis2_char_t *) key;
+ if(name)
+ {
+ AXIS2_FREE(env->allocator, name);
+ }
+ value = (axis2_char_t *) val;
+ if(value)
+ {
+ AXIS2_FREE(env->allocator, value);
+ }
+ }
+ axutil_hash_free(ht, env);
+ }
+
+ property = axutil_property_create_with_args(env, 0, AXIS2_TRUE, 0, ht);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_SESSION_TABLE, property);
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_tranpsport_utils_set_session");
+}
+
+/**
+ * After receiving Set-Cookie header store it
+ */
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_transport_utils_store_cookie(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_char_t *cookie)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axutil_property_t *property = NULL;
+ axutil_hash_t *session_map = NULL;
+ axis2_endpoint_ref_t *endpoint = NULL;
+ const axis2_char_t *address = NULL;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_utils_store_cookie");
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_TRANSPORT_SESSION_MAP);
+ if(property)
+ {
+ session_map = axutil_property_get_value(property, env);
+ }
+ if(!session_map)
+ {
+ if(!cookie)
+ {
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "No session map found and no cookie set. So return");
+ return;
+ }
+ session_map = axutil_hash_make(env);
+ if(session_map)
+ {
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 1,
+ axis2_http_transport_utils_session_map_free_void_arg, session_map);
+ axis2_conf_ctx_set_property(conf_ctx, env, AXIS2_TRANSPORT_SESSION_MAP, property);
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return;
+ }
+ }
+ endpoint = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(endpoint)
+ {
+ address = axis2_endpoint_ref_get_address(endpoint, env);
+ if(address)
+ {
+ axutil_url_t *url = NULL;
+
+ url = axutil_url_parse_string(env, address);
+ if(url)
+ {
+ axis2_char_t *server = NULL;
+ server = axutil_url_get_server(url, env);
+ if(server)
+ {
+ if(cookie)
+ {
+ axutil_hash_set(session_map, axutil_strdup(env, server), AXIS2_HASH_KEY_STRING,
+ axutil_strdup(env, cookie));
+ }
+ else /* We remove any cookie set for this endpoint */
+ {
+ cookie = axutil_hash_get(session_map, server, AXIS2_HASH_KEY_STRING);
+ if(cookie)
+ {
+ AXIS2_FREE(env->allocator, cookie);
+ }
+ axutil_hash_set(session_map, axutil_strdup(env, server), AXIS2_HASH_KEY_STRING, NULL);
+ }
+ }
+ axutil_url_free(url, env);
+ }
+ }
+ }
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_utils_store_cookie");
+}
+
+/* Read from cookie store before sending */
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_read_from_cookie_store(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx)
+{
+ axutil_property_t *property = NULL;
+ axutil_hash_t *session_map = NULL;
+ axis2_endpoint_ref_t *endpoint = NULL;
+ const axis2_char_t *address = NULL;
+ axis2_char_t *cookie = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_utils_read_from_cookie_store");
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_TRANSPORT_SESSION_MAP);
+ if(property)
+ {
+ session_map = axutil_property_get_value(property, env);
+ }
+ if(!session_map)
+ {
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "No session map stored");
+ return NULL;
+ }
+ endpoint = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(endpoint)
+ {
+ address = axis2_endpoint_ref_get_address(endpoint, env);
+ if(address)
+ {
+ axutil_url_t *url = NULL;
+ url = axutil_url_parse_string(env, address);
+ if(url)
+ {
+ axis2_char_t *server = NULL;
+ server = axutil_url_get_server(url, env);
+ if(server)
+ {
+ cookie = axutil_hash_get(session_map, server, AXIS2_HASH_KEY_STRING);
+ }
+ axutil_url_free(url, env);
+ }
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "cookie:%s", cookie);
+ }
+ }
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_utils_read_from_cookie_store");
+ return cookie;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_transport_utils_get_session_id_from_cookie(
+ const axutil_env_t *env,
+ axis2_char_t *cookie)
+{
+ axis2_char_t *next = NULL;
+ axis2_char_t *session_id = NULL;
+
+ next = axutil_strstr(cookie, ";");
+ if (next)
+ {
+ session_id = axis2_http_transport_utils_copy_value(env, cookie);
+ }
+
+ return session_id;
+}
+
+static axis2_char_t *
+axis2_http_transport_utils_copy_key(
+ const axutil_env_t *env,
+ axis2_char_t *pair)
+{
+ axis2_char_t *p = axutil_strchr(pair, '=');
+ axis2_char_t *ret = NULL;
+
+ if (p)
+ {
+ axis2_char_t c;
+ size_t len = p - pair;
+ c = pair[len];
+ pair[len] = '\0';
+ ret = axutil_strdup(env, pair);
+ pair[len] = c;
+ }
+
+ return ret;
+}
+
+static axis2_char_t *
+axis2_http_transport_utils_copy_value(
+ const axutil_env_t *env,
+ axis2_char_t *pair)
+{
+ axis2_char_t *ret = NULL;
+ size_t len;
+ axis2_char_t c;
+
+ pair = axutil_strchr(pair, '=');
+ if (pair)
+ {
+ pair++;
+ len = axutil_strchr(pair, ';') - pair;
+ c = pair[len];
+ pair[len] = '\0';
+ ret = axutil_strdup(env, pair);
+ pair[len] = c;
+ }
+
+ return ret;
+}
+
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_transport_utils_session_map_free_void_arg(
+ void *sm_void,
+ const axutil_env_t *env)
+{
+ void *val = NULL;
+ const void *key = NULL;
+ axutil_hash_index_t *hi = NULL;
+ axutil_hash_t *ht = (axutil_hash_t *)sm_void;
+
+ for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ axis2_char_t *name = NULL;
+ axis2_char_t *value = NULL;
+
+ axutil_hash_this(hi, &key, NULL, &val);
+ name = (axis2_char_t *) key;
+ if(name)
+ {
+ AXIS2_FREE(env->allocator, name);
+ }
+ value = (axis2_char_t *) val;
+ if(value)
+ {
+ AXIS2_FREE(env->allocator, value);
+ }
+ }
+ axutil_hash_free(ht, env);
+}
+
+