summaryrefslogtreecommitdiffstats
path: root/src/core/transport/http/server/apache2
diff options
context:
space:
mode:
authorGravatar gmcdonald2010-02-13 01:32:03 +0000
committerGravatar gmcdonald2010-02-13 01:32:03 +0000
commit0425aadc78680e53000fd0108b540d6eca048516 (patch)
tree8ec7ab8e015d454c5ec586dfc91e05a2dce1cfc0 /src/core/transport/http/server/apache2
downloadaxis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.gz
axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.bz2
Moving axis svn, part of TLP move INFRA-2441
git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/core/transport/http/server/apache2')
-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
8 files changed, 3239 insertions, 0 deletions
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;
+}
+
+