diff options
Diffstat (limited to 'src/core')
196 files changed, 69581 insertions, 0 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am new file mode 100644 index 0000000..a3316e6 --- /dev/null +++ b/src/core/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = addr context description phaseresolver receivers util clientapi deployment transport/http/util transport/http/common engine transport diff --git a/src/core/addr/Makefile.am b/src/core/addr/Makefile.am new file mode 100644 index 0000000..1f7512f --- /dev/null +++ b/src/core/addr/Makefile.am @@ -0,0 +1,13 @@ +noinst_LTLIBRARIES = libaxis2_addr.la + +libaxis2_addr_la_SOURCES = relates_to.c \ + svc_name.c \ + any_content_type.c \ + endpoint_ref.c \ + msg_info_headers.c + + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/addr/any_content_type.c b/src/core/addr/any_content_type.c new file mode 100644 index 0000000..1a9e6a1 --- /dev/null +++ b/src/core/addr/any_content_type.c @@ -0,0 +1,120 @@ +/* + * 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_any_content_type.h> +#include <axutil_string.h> + +struct axis2_any_content_type +{ + + /** map of values in the any content type */ + axutil_hash_t *value_map; +}; + +AXIS2_EXTERN axis2_any_content_type_t *AXIS2_CALL +axis2_any_content_type_create( + const axutil_env_t * env) +{ + axis2_any_content_type_t *any_content_type = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + any_content_type = AXIS2_MALLOC(env->allocator, sizeof(axis2_any_content_type_t)); + if(!any_content_type) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + any_content_type->value_map = NULL; + + any_content_type->value_map = axutil_hash_make(env); + + if(!(any_content_type->value_map)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_any_content_type_free(any_content_type, env); + return NULL; + } + + return any_content_type; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_any_content_type_add_value( + axis2_any_content_type_t * any_content_type, + const axutil_env_t * env, + const axutil_qname_t * qname, + const axis2_char_t * value) +{ + axis2_char_t *temp = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(any_content_type->value_map) + { + axis2_char_t *name = NULL; + + name = axutil_qname_to_string((axutil_qname_t *)qname, env); + axutil_hash_set(any_content_type->value_map, name, AXIS2_HASH_KEY_STRING, value); + + temp = axutil_hash_get(any_content_type->value_map, name, AXIS2_HASH_KEY_STRING); + if(temp) + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_any_content_type_get_value( + const axis2_any_content_type_t * any_content_type, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + if(any_content_type->value_map) + { + axis2_char_t *name = NULL; + + name = axutil_qname_to_string((axutil_qname_t *)qname, env); + return axutil_hash_get(any_content_type->value_map, name, AXIS2_HASH_KEY_STRING); + } + return NULL; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_any_content_type_get_value_map( + const axis2_any_content_type_t * any_content_type, + const axutil_env_t * env) +{ + return any_content_type->value_map; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_any_content_type_free( + axis2_any_content_type_t * any_content_type, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(any_content_type->value_map) + { + axutil_hash_free(any_content_type->value_map, env); + } + + AXIS2_FREE(env->allocator, any_content_type); + + return; +} diff --git a/src/core/addr/endpoint_ref.c b/src/core/addr/endpoint_ref.c new file mode 100644 index 0000000..dd351f0 --- /dev/null +++ b/src/core/addr/endpoint_ref.c @@ -0,0 +1,375 @@ +/* + * 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_endpoint_ref.h> +#include <axutil_string.h> +#include <axutil_array_list.h> + +struct axis2_endpoint_ref +{ + + /** endpoint address */ + axis2_char_t *address; + + /** interface qname */ + axutil_qname_t *interface_qname; + + /** reference parameters */ + axutil_array_list_t *ref_param_list; + + /** meta data */ + axutil_array_list_t *metadata_list; + + /** reference parameter attribute list */ + axutil_array_list_t *ref_attribute_list; + + /** meta data attribute list */ + axutil_array_list_t *meta_attribute_list; + + /** extensible element list */ + axutil_array_list_t *extension_list; + + /** service name */ + axis2_svc_name_t *svc_name; +}; + +axis2_endpoint_ref_t *AXIS2_CALL +axis2_endpoint_ref_create( + const axutil_env_t * env, + const axis2_char_t * address) +{ + axis2_endpoint_ref_t *endpoint_ref = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + endpoint_ref = AXIS2_MALLOC(env->allocator, sizeof(axis2_endpoint_ref_t)); + if(!endpoint_ref) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + endpoint_ref->address = NULL; + endpoint_ref->interface_qname = NULL; + endpoint_ref->ref_param_list = NULL; + endpoint_ref->metadata_list = NULL; + endpoint_ref->ref_attribute_list = NULL; + endpoint_ref->meta_attribute_list = NULL; + endpoint_ref->extension_list = NULL; + endpoint_ref->svc_name = NULL; + + if(address) + { + endpoint_ref->address = axutil_strdup(env, address); + if(!(endpoint_ref->address)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_endpoint_ref_free(endpoint_ref, env); + return NULL; + } + } + + return endpoint_ref; +} + +const axis2_char_t *AXIS2_CALL +axis2_endpoint_ref_get_address( + const axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + return endpoint_ref->address; +} + +axis2_status_t AXIS2_CALL +axis2_endpoint_ref_set_address( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env, + const axis2_char_t * address) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(endpoint_ref->address) + { + AXIS2_FREE(env->allocator, endpoint_ref->address); + } + + endpoint_ref->address = axutil_strdup(env, address); + return AXIS2_SUCCESS; +} + +const axutil_qname_t *AXIS2_CALL +axis2_endpoint_ref_get_interface_qname( + const axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + return endpoint_ref->interface_qname; +} + +axis2_status_t AXIS2_CALL +axis2_endpoint_ref_set_interface_qname( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env, + const axutil_qname_t * interface_qname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + endpoint_ref->interface_qname = axutil_qname_clone((axutil_qname_t *)interface_qname, env); + return AXIS2_SUCCESS; +} + +axis2_svc_name_t *AXIS2_CALL +axis2_endpoint_ref_get_svc_name( + const axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + return endpoint_ref->svc_name; +} + +axis2_status_t AXIS2_CALL +axis2_endpoint_ref_set_svc_name( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env, + axis2_svc_name_t * svc_name) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + endpoint_ref->svc_name = svc_name; + return AXIS2_SUCCESS; +} + +void AXIS2_CALL +axis2_endpoint_ref_free_void_arg( + void *endpoint_ref, + const axutil_env_t * env) +{ + axis2_endpoint_ref_t *endpoint_ref_l = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + endpoint_ref_l = (axis2_endpoint_ref_t *)endpoint_ref; + axis2_endpoint_ref_free(endpoint_ref_l, env); + return; +} + +void AXIS2_CALL +axis2_endpoint_ref_free( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(endpoint_ref->address) + { + AXIS2_FREE(env->allocator, endpoint_ref->address); + } + + if(endpoint_ref->ref_param_list) + { + axutil_array_list_free(endpoint_ref->ref_param_list, env); + } + + if(endpoint_ref->metadata_list) + { + axutil_array_list_free(endpoint_ref->metadata_list, env); + } + + if(endpoint_ref->ref_attribute_list) + { + axutil_array_list_free(endpoint_ref->ref_attribute_list, env); + } + + if(endpoint_ref->meta_attribute_list) + { + axutil_array_list_free(endpoint_ref->meta_attribute_list, env); + } + + if(endpoint_ref->extension_list) + { + axutil_array_list_free(endpoint_ref->extension_list, env); + } + + AXIS2_FREE(env->allocator, endpoint_ref); + + return; +} + +axutil_array_list_t *AXIS2_CALL +axis2_endpoint_ref_get_ref_param_list( + const axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + return endpoint_ref->ref_param_list; +} + +axutil_array_list_t *AXIS2_CALL +axis2_endpoint_ref_get_metadata_list( + const axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + return endpoint_ref->metadata_list; +} + +axis2_status_t AXIS2_CALL +axis2_endpoint_ref_add_ref_param( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env, + axiom_node_t * ref_param_node) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!(endpoint_ref->ref_param_list)) + { + endpoint_ref->ref_param_list = axutil_array_list_create(env, 0); + if(!(endpoint_ref->ref_param_list)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + if(endpoint_ref->ref_param_list && ref_param_node) + { + return axutil_array_list_add(endpoint_ref->ref_param_list, env, ref_param_node); + } + + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +axis2_endpoint_ref_add_metadata( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env, + axiom_node_t * meta_data_node) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!(endpoint_ref->metadata_list)) + { + endpoint_ref->metadata_list = axutil_array_list_create(env, 0); + if(!(endpoint_ref->metadata_list)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + if(endpoint_ref->metadata_list && meta_data_node) + { + return axutil_array_list_add(endpoint_ref->metadata_list, env, meta_data_node); + } + + return AXIS2_FAILURE; +} + +axutil_array_list_t *AXIS2_CALL +axis2_endpoint_ref_get_ref_attribute_list( + const axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + return endpoint_ref->ref_attribute_list; +} + +axutil_array_list_t *AXIS2_CALL +axis2_endpoint_ref_get_metadata_attribute_list( + const axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + return endpoint_ref->meta_attribute_list; +} + +axutil_array_list_t *AXIS2_CALL +axis2_endpoint_ref_get_extension_list( + const axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env) +{ + return endpoint_ref->extension_list; +} + +axis2_status_t AXIS2_CALL +axis2_endpoint_ref_add_ref_attribute( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env, + axiom_attribute_t * attr) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!(endpoint_ref->ref_attribute_list)) + { + endpoint_ref->ref_attribute_list = axutil_array_list_create(env, 0); + if(!(endpoint_ref->ref_attribute_list)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + if(endpoint_ref->ref_attribute_list && attr) + { + return axutil_array_list_add(endpoint_ref->ref_attribute_list, env, attr); + } + + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +axis2_endpoint_ref_add_metadata_attribute( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env, + axiom_attribute_t * attr) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!(endpoint_ref->meta_attribute_list)) + { + endpoint_ref->meta_attribute_list = axutil_array_list_create(env, 0); + if(!(endpoint_ref->meta_attribute_list)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + if(endpoint_ref->meta_attribute_list && attr) + { + return axutil_array_list_add(endpoint_ref->meta_attribute_list, env, attr); + } + + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +axis2_endpoint_ref_add_extension( + axis2_endpoint_ref_t * endpoint_ref, + const axutil_env_t * env, + axiom_node_t * extension_node) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!(endpoint_ref->extension_list)) + { + endpoint_ref->extension_list = axutil_array_list_create(env, 0); + if(!(endpoint_ref->extension_list)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + if(endpoint_ref->extension_list && extension_node) + { + return axutil_array_list_add(endpoint_ref->extension_list, env, extension_node); + } + + return AXIS2_FAILURE; +} diff --git a/src/core/addr/msg_info_headers.c b/src/core/addr/msg_info_headers.c new file mode 100644 index 0000000..8d61c5b --- /dev/null +++ b/src/core/addr/msg_info_headers.c @@ -0,0 +1,448 @@ +/* + * 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_msg_info_headers.h> +#include <axutil_string.h> + +struct axis2_msg_info_headers +{ + + /** The address of the intended receiver of the message. This is mandatory */ + axis2_endpoint_ref_t *to; + + /** Reference of the endpoint where the message originated from */ + axis2_endpoint_ref_t *from; + + /** Pair of values that indicate how this message relate to another message */ + axis2_relates_to_t *relates_to; + + /** Identifies the intended receiver for replies to the message, + if this is set, none and anonymous settings are ignored */ + axis2_endpoint_ref_t *reply_to; + + /** reply to should be none */ + axis2_bool_t reply_to_none; + + /** reply to should be anonymous, this is overridden by none*/ + axis2_bool_t reply_to_anonymous; + + /** identifies the intended receiver for faults related to the message + if this is set, none and anonymous settings are ignored */ + axis2_endpoint_ref_t *fault_to; + + /** fault to should be none */ + axis2_bool_t fault_to_none; + + /** fault to should be anonymous, this is overridden by none*/ + axis2_bool_t fault_to_anonymous; + + /** action */ + axis2_char_t *action; + + /** message Id */ + axis2_char_t *message_id; + + /** reference parameters */ + axutil_array_list_t *ref_params; +}; + +AXIS2_EXTERN axis2_msg_info_headers_t *AXIS2_CALL +axis2_msg_info_headers_create( + const axutil_env_t * env, + axis2_endpoint_ref_t * to, + const axis2_char_t * action) +{ + axis2_msg_info_headers_t *msg_info_headers = NULL; + + msg_info_headers = AXIS2_MALLOC(env->allocator, sizeof(axis2_msg_info_headers_t)); + + if(!msg_info_headers) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + msg_info_headers->to = NULL; + msg_info_headers->from = NULL; + msg_info_headers->relates_to = NULL; + msg_info_headers->reply_to_none = AXIS2_FALSE; + msg_info_headers->reply_to_anonymous = AXIS2_FALSE; + msg_info_headers->reply_to = NULL; + msg_info_headers->fault_to_none = AXIS2_FALSE; + msg_info_headers->fault_to_anonymous = AXIS2_FALSE; + msg_info_headers->fault_to = NULL; + msg_info_headers->action = NULL; + msg_info_headers->message_id = NULL; + msg_info_headers->ref_params = NULL; + + if(to) + { + msg_info_headers->to = to; + } + + if(action) + { + msg_info_headers->action = axutil_strdup(env, action); + if(!(msg_info_headers->action)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_msg_info_headers_free(msg_info_headers, env); + return NULL; + } + } + + return msg_info_headers; +} + +/** + * Method getTo + * + * @return + */ +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_msg_info_headers_get_to( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->to; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_to( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + axis2_endpoint_ref_t * to) +{ + if(msg_info_headers->to && to) /* if the incoming to is NULL, + we consider that to be a reset, + so don't free */ + { + axis2_endpoint_ref_free(msg_info_headers->to, env); + msg_info_headers->to = NULL; + } + msg_info_headers->to = to; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_msg_info_headers_get_from( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->from; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_from( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + axis2_endpoint_ref_t * from) +{ + msg_info_headers->from = from; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_msg_info_headers_get_reply_to( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->reply_to; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_reply_to( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + axis2_endpoint_ref_t * reply_to) +{ + msg_info_headers->reply_to = reply_to; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_msg_info_headers_get_fault_to( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->fault_to; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_fault_to( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + axis2_endpoint_ref_t * fault_to) +{ + msg_info_headers->fault_to = fault_to; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_msg_info_headers_get_action( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->action; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_action( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + const axis2_char_t * action) +{ + if(msg_info_headers->action) + { + AXIS2_FREE(env->allocator, msg_info_headers->action); + msg_info_headers->action = NULL; + } + if(action) + { + msg_info_headers->action = axutil_strdup(env, action); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_msg_info_headers_get_message_id( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->message_id; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_message_id( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + const axis2_char_t * message_id) +{ + if(msg_info_headers->message_id) + { + AXIS2_FREE(env->allocator, msg_info_headers->message_id); + msg_info_headers->message_id = NULL; + } + + if(message_id) + { + msg_info_headers->message_id = axutil_stracat(env, AXIS2_MESSAGE_ID_PREFIX, message_id); + if(!(msg_info_headers->message_id)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_in_message_id( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + const axis2_char_t * message_id) +{ + if(msg_info_headers->message_id) + { + AXIS2_FREE(env->allocator, msg_info_headers->message_id); + msg_info_headers->message_id = NULL; + } + + if(message_id) + { + msg_info_headers->message_id = axutil_strdup(env, message_id); + + if(!(msg_info_headers->message_id)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_relates_to_t *AXIS2_CALL +axis2_msg_info_headers_get_relates_to( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->relates_to; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_relates_to( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + axis2_relates_to_t * relates_to) +{ + if(msg_info_headers->relates_to) + { + axis2_relates_to_free(msg_info_headers->relates_to, env); + } + msg_info_headers->relates_to = relates_to; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_info_headers_get_all_ref_params( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->ref_params; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_add_ref_param( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + axiom_node_t * ref_param) +{ + if(!(msg_info_headers->ref_params)) + { + msg_info_headers->ref_params = axutil_array_list_create(env, 10); + if(!(msg_info_headers->ref_params)) + return AXIS2_FAILURE; + } + + if(ref_param) + { + return axutil_array_list_add(msg_info_headers->ref_params, env, ref_param); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_msg_info_headers_free( + struct axis2_msg_info_headers *msg_info_headers, + const axutil_env_t * env) +{ + if(msg_info_headers->to) + { + axis2_endpoint_ref_free(msg_info_headers->to, env); + } + if(msg_info_headers->from) + { + axis2_endpoint_ref_free(msg_info_headers->from, env); + } + if(msg_info_headers->reply_to) + { + axis2_endpoint_ref_free(msg_info_headers->reply_to, env); + } + if(msg_info_headers->relates_to) + { + axis2_relates_to_free(msg_info_headers->relates_to, env); + } + + if(msg_info_headers->fault_to) + { + axis2_endpoint_ref_free(msg_info_headers->fault_to, env); + } + + if(msg_info_headers->ref_params) + { + axutil_array_list_free(msg_info_headers->ref_params, env); + } + if(msg_info_headers->action) + { + AXIS2_FREE(env->allocator, msg_info_headers->action); + } + if(msg_info_headers->message_id) + { + AXIS2_FREE(env->allocator, msg_info_headers->message_id); + } + + AXIS2_FREE(env->allocator, msg_info_headers); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_reply_to_none( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + const axis2_bool_t none) +{ + msg_info_headers->reply_to_none = none; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_msg_info_headers_get_reply_to_none( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->reply_to_none; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_reply_to_anonymous( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + const axis2_bool_t anonymous) +{ + msg_info_headers->reply_to_anonymous = anonymous; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_msg_info_headers_get_reply_to_anonymous( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->reply_to_anonymous; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_fault_to_none( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + const axis2_bool_t none) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + msg_info_headers->fault_to_none = none; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_msg_info_headers_get_fault_to_none( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->fault_to_none; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_info_headers_set_fault_to_anonymous( + struct axis2_msg_info_headers * msg_info_headers, + const axutil_env_t * env, + const axis2_bool_t anonymous) +{ + msg_info_headers->fault_to_anonymous = anonymous; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_msg_info_headers_get_fault_to_anonymous( + const axis2_msg_info_headers_t * msg_info_headers, + const axutil_env_t * env) +{ + return msg_info_headers->fault_to_anonymous; +} + diff --git a/src/core/addr/relates_to.c b/src/core/addr/relates_to.c new file mode 100644 index 0000000..e28df54 --- /dev/null +++ b/src/core/addr/relates_to.c @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_relates_to.h> +#include <axutil_string.h> + +struct axis2_relates_to +{ + + /** value string */ + axis2_char_t *value; + + /** relationship type string */ + axis2_char_t *relationship_type; +}; + +axis2_relates_to_t *AXIS2_CALL +axis2_relates_to_create( + const axutil_env_t * env, + const axis2_char_t * value, + const axis2_char_t * relationship_type) +{ + axis2_relates_to_t *relates_to = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + relates_to = AXIS2_MALLOC(env->allocator, sizeof(axis2_relates_to_t)); + if(!relates_to) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + relates_to->value = NULL; + relates_to->relationship_type = NULL; + + if(value) + { + relates_to->value = axutil_strdup(env, value); + if(!(relates_to->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_relates_to_free(relates_to, env); + return NULL; + } + } + + if(relationship_type) + { + relates_to->relationship_type = axutil_strdup(env, relationship_type); + if(!(relates_to->relationship_type)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_relates_to_free(relates_to, env); + return NULL; + } + } + + return relates_to; +} + +const axis2_char_t *AXIS2_CALL +axis2_relates_to_get_value( + const axis2_relates_to_t * relates_to, + const axutil_env_t * env) +{ + return relates_to->value; +} + +axis2_status_t AXIS2_CALL +axis2_relates_to_set_value( + struct axis2_relates_to * relates_to, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(relates_to->value) + { + AXIS2_FREE(env->allocator, relates_to->value); + } + + if(value) + { + relates_to->value = (axis2_char_t *)axutil_strdup(env, value); + if(!(relates_to->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_relates_to_get_relationship_type( + const axis2_relates_to_t * relates_to, + const axutil_env_t * env) +{ + return relates_to->relationship_type; +} + +axis2_status_t AXIS2_CALL +axis2_relates_to_set_relationship_type( + struct axis2_relates_to * relates_to, + const axutil_env_t * env, + const axis2_char_t * relationship_type) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(relates_to->relationship_type) + { + AXIS2_FREE(env->allocator, relates_to->relationship_type); + } + + if(relationship_type) + { + relates_to->relationship_type = (axis2_char_t *)axutil_strdup(env, relationship_type); + if(!(relates_to->relationship_type)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +void AXIS2_CALL +axis2_relates_to_free( + struct axis2_relates_to *relates_to, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(relates_to->value) + { + AXIS2_FREE(env->allocator, relates_to->value); + } + + if(relates_to->relationship_type) + { + AXIS2_FREE(env->allocator, relates_to->relationship_type); + } + + AXIS2_FREE(env->allocator, relates_to); + + return; +} diff --git a/src/core/addr/svc_name.c b/src/core/addr/svc_name.c new file mode 100644 index 0000000..0aa34ab --- /dev/null +++ b/src/core/addr/svc_name.c @@ -0,0 +1,151 @@ +/* + * 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_svc_name.h> +#include <axutil_string.h> + +struct axis2_svc_name +{ + + /** service QName */ + axutil_qname_t *qname; + + /** service endpoint name */ + axis2_char_t *endpoint_name; +}; + +axis2_svc_name_t *AXIS2_CALL +axis2_svc_name_create( + const axutil_env_t * env, + const axutil_qname_t * qname, + const axis2_char_t * endpoint_name) +{ + axis2_svc_name_t *svc_name = NULL; + + svc_name = AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_name_t)); + if(!svc_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + svc_name->qname = NULL; + svc_name->endpoint_name = NULL; + + if(qname) + { + svc_name->qname = axutil_qname_clone((axutil_qname_t *)qname, env); + if(!(svc_name->qname)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_svc_name_free(svc_name, env); + return NULL; + } + } + + if(endpoint_name) + { + svc_name->endpoint_name = axutil_strdup(env, endpoint_name); + if(!(svc_name->endpoint_name)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_svc_name_free(svc_name, env); + return NULL; + } + } + + return svc_name; +} + +const axutil_qname_t *AXIS2_CALL +axis2_svc_name_get_qname( + const axis2_svc_name_t * svc_name, + const axutil_env_t * env) +{ + return svc_name->qname; +} + +axis2_status_t AXIS2_CALL +axis2_svc_name_set_qname( + struct axis2_svc_name * svc_name, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + if(svc_name->qname) + { + axutil_qname_free(svc_name->qname, env); + } + + if(qname) + { + svc_name->qname = axutil_qname_clone((axutil_qname_t *)qname, env); + if(!(svc_name->qname)) + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_svc_name_get_endpoint_name( + const axis2_svc_name_t * svc_name, + const axutil_env_t * env) +{ + return svc_name->endpoint_name; +} + +axis2_status_t AXIS2_CALL +axis2_svc_name_set_endpoint_name( + struct axis2_svc_name * svc_name, + const axutil_env_t * env, + const axis2_char_t * endpoint_name) +{ + if(svc_name->endpoint_name) + { + AXIS2_FREE(env->allocator, svc_name->endpoint_name); + } + + if(endpoint_name) + { + svc_name->endpoint_name = axutil_strdup(env, endpoint_name); + if(!(svc_name->endpoint_name)) + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +void AXIS2_CALL +axis2_svc_name_free( + struct axis2_svc_name *svc_name, + const axutil_env_t * env) +{ + if(svc_name->qname) + { + axutil_qname_free(svc_name->qname, env); + } + + if(svc_name->endpoint_name) + { + AXIS2_FREE(env->allocator, svc_name->endpoint_name); + } + + AXIS2_FREE(env->allocator, svc_name); + + return; +} + diff --git a/src/core/clientapi/Makefile.am b/src/core/clientapi/Makefile.am new file mode 100644 index 0000000..8dead6f --- /dev/null +++ b/src/core/clientapi/Makefile.am @@ -0,0 +1,17 @@ +noinst_LTLIBRARIES = libaxis2_clientapi.la
+libaxis2_clientapi_la_SOURCES = async_result.c \
+ callback.c \
+ listener_manager.c \
+ callback_recv.c \
+ stub.c \
+ options.c \
+ op_client.c \
+ svc_client.c
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/util/include/platforms \
+ -I$(top_builddir)/axiom/include \
+ -I$(top_builddir)/neethi/include
diff --git a/src/core/clientapi/async_result.c b/src/core/clientapi/async_result.c new file mode 100644 index 0000000..693e283 --- /dev/null +++ b/src/core/clientapi/async_result.c @@ -0,0 +1,83 @@ +/* + * 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_async_result.h> +#include <axis2_const.h> +#include <axutil_hash.h> + +struct axis2_async_result +{ + + /** result message context */ + axis2_msg_ctx_t *result; +}; + +AXIS2_EXTERN axis2_async_result_t *AXIS2_CALL +axis2_async_result_create( + const axutil_env_t * env, + axis2_msg_ctx_t * result) +{ + axis2_async_result_t *async_result = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + async_result = AXIS2_MALLOC(env->allocator, sizeof(axis2_async_result_t)); + if(!async_result) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create asynchronous result."); + return NULL; + } + + async_result->result = NULL; + + if(result) + { + async_result->result = result; /* shallow copy */ + } + + return async_result; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axis2_async_result_get_envelope( + axis2_async_result_t * async_result, + const axutil_env_t * env) +{ + if(async_result->result) + { + return axis2_msg_ctx_get_soap_envelope(async_result->result, env); + } + + return NULL; +} + +AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL +axis2_async_result_get_result( + axis2_async_result_t * async_result, + const axutil_env_t * env) +{ + return async_result->result; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_async_result_free( + axis2_async_result_t * async_result, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, async_result); +} diff --git a/src/core/clientapi/callback.c b/src/core/clientapi/callback.c new file mode 100644 index 0000000..6f875df --- /dev/null +++ b/src/core/clientapi/callback.c @@ -0,0 +1,272 @@ +/* + * 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_callback.h> +#include <axis2_const.h> +#include <axutil_hash.h> + +struct axis2_callback +{ + + /** callback complete? */ + axis2_bool_t complete; + + /** envelope corresponding to the result */ + axiom_soap_envelope_t *envelope; + + /** message context corresponding to the result */ + axis2_msg_ctx_t *msg_ctx; + + /** error code */ + int error; + + /** to store callback specific data */ + void *data; + axutil_thread_mutex_t *mutex; + + /** + * This function is called by invoke_on_complete. + * Users could provide this method so that they can define what to be + * done when the callback returns on completion. + * @param callback pointer to callback struct + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + axis2_status_t + ( + AXIS2_CALL * on_complete) + ( + axis2_callback_t * callback, + const axutil_env_t * env); + + /** + * This function is called by report_error. + * Users could provide this method so that they can define what to be done + * when the callback returns an error. + * @param callback pointer to callback struct + * @param env pointer to environment struct + * @param exception error code representing the error + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + axis2_status_t + ( + AXIS2_CALL * on_error) +( axis2_callback_t * callback, +const axutil_env_t * env, +const int exception); +}; + +static axis2_status_t AXIS2_CALL axis2_callback_on_complete( + axis2_callback_t * callback, + const axutil_env_t * env); + +static axis2_status_t AXIS2_CALL axis2_callback_on_error( + axis2_callback_t * callback, + const axutil_env_t * env, + int exception); + +AXIS2_EXTERN axis2_callback_t *AXIS2_CALL +axis2_callback_create( + const axutil_env_t * env) +{ + axis2_callback_t *callback = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + callback = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_t)); + if(!callback) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create callback."); + return NULL; + } + + callback->complete = AXIS2_FALSE; + callback->envelope = NULL; + callback->msg_ctx = NULL; + callback->error = AXIS2_ERROR_NONE; + callback->data = NULL; + callback->mutex = NULL; + callback->on_complete = axis2_callback_on_complete; + callback->on_error = axis2_callback_on_error; + + callback->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT); + return callback; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_callback_invoke_on_complete( + axis2_callback_t * callback, + const axutil_env_t * env, + axis2_async_result_t * result) +{ + axis2_status_t status = AXIS2_FAILURE; + + callback->envelope = axis2_async_result_get_envelope(result, env); + callback->msg_ctx = axis2_async_result_get_result(result, env); + axis2_msg_ctx_increment_ref(callback->msg_ctx, env); /* this will be set in opclient's msgctx + map and will be deleted from there */ + + status = callback->on_complete(callback, env); + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_callback_report_error( + axis2_callback_t * callback, + const axutil_env_t * env, + const int exception) +{ + axis2_callback_set_error(callback, env, exception); + return callback->on_error(callback, env, exception); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_callback_get_complete( + const axis2_callback_t * callback, + const axutil_env_t * env) +{ + return callback->complete; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_callback_set_complete( + axis2_callback_t * callback, + const axutil_env_t * env, + const axis2_bool_t complete) +{ + callback->complete = complete; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axis2_callback_get_envelope( + const axis2_callback_t * callback, + const axutil_env_t * env) +{ + return callback->envelope; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_callback_set_envelope( + axis2_callback_t * callback, + const axutil_env_t * env, + axiom_soap_envelope_t * envelope) +{ + callback->envelope = envelope; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL +axis2_callback_get_msg_ctx( + const axis2_callback_t * callback, + const axutil_env_t * env) +{ + return callback->msg_ctx; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_callback_set_msg_ctx( + axis2_callback_t * callback, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + callback->msg_ctx = msg_ctx; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_callback_get_error( + const axis2_callback_t * callback, + const axutil_env_t * env) +{ + return callback->error; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_callback_set_error( + axis2_callback_t * callback, + const axutil_env_t * env, + const int error) +{ + callback->error = error; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_callback_free( + axis2_callback_t * callback, + const axutil_env_t * env) +{ + if(callback->mutex) + { + axutil_thread_mutex_destroy(callback->mutex); + } + + AXIS2_FREE(env->allocator, callback); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_callback_set_data( + axis2_callback_t * callback, + void *data) +{ + callback->data = (void *)data; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void *AXIS2_CALL +axis2_callback_get_data( + const axis2_callback_t * callback) +{ + return callback->data; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_callback_set_on_complete( + axis2_callback_t * callback, + axis2_on_complete_func_ptr func) +{ + callback->on_complete = func; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_callback_set_on_error( + axis2_callback_t * callback, + axis2_on_error_func_ptr func) +{ + callback->on_error = func; +} + +static axis2_status_t AXIS2_CALL +axis2_callback_on_complete( + axis2_callback_t * callback, + const axutil_env_t * env) +{ + return AXIS2_SUCCESS; +} + +static axis2_status_t AXIS2_CALL +axis2_callback_on_error( + axis2_callback_t * callback, + const axutil_env_t * env, + int exception) +{ + return AXIS2_SUCCESS; +} diff --git a/src/core/clientapi/callback_recv.c b/src/core/clientapi/callback_recv.c new file mode 100644 index 0000000..f45ed87 --- /dev/null +++ b/src/core/clientapi/callback_recv.c @@ -0,0 +1,199 @@ +/* + * 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_callback_recv.h" +#include <axis2_const.h> +#include <axutil_hash.h> + +struct axis2_callback_recv +{ + /** base context struct */ + axis2_msg_recv_t *base; + axis2_bool_t base_deep_copy; + + /** callback map */ + axutil_hash_t *callback_map; + axutil_thread_mutex_t *mutex; +}; + +static axis2_status_t AXIS2_CALL axis2_callback_recv_receive( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + void *callback_recv_param); + +AXIS2_EXTERN axis2_callback_recv_t *AXIS2_CALL +axis2_callback_recv_create( + const axutil_env_t * env) +{ + axis2_callback_recv_t *callback_recv = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + callback_recv = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_recv_t)); + + if(!callback_recv) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create callback receive."); + return NULL; + } + + callback_recv->base = NULL; + callback_recv->base_deep_copy = AXIS2_TRUE; + callback_recv->callback_map = NULL; + callback_recv->mutex = NULL; + + callback_recv->base = axis2_msg_recv_create(env); + if(!callback_recv->base) + { + axis2_callback_recv_free(callback_recv, env); + return NULL; + } + axis2_msg_recv_set_derived(callback_recv->base, env, callback_recv); + axis2_msg_recv_set_receive(callback_recv->base, env, axis2_callback_recv_receive); + + callback_recv->callback_map = axutil_hash_make(env); + if(!callback_recv->callback_map) + { + axis2_callback_recv_free(callback_recv, env); + return NULL; + } + + callback_recv->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT); + return callback_recv; +} + +AXIS2_EXTERN axis2_msg_recv_t *AXIS2_CALL +axis2_callback_recv_get_base( + axis2_callback_recv_t * callback_recv, + const axutil_env_t * env) +{ + callback_recv->base_deep_copy = AXIS2_FALSE; + return callback_recv->base; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_callback_recv_free( + axis2_callback_recv_t * callback_recv, + const axutil_env_t * env) +{ + if(callback_recv->mutex) + { + axutil_thread_mutex_destroy(callback_recv->mutex); + } + + if(callback_recv->callback_map) + { + axutil_hash_index_t *hi = NULL; + const void *key = NULL; + void *val = NULL; + for(hi = axutil_hash_first(callback_recv->callback_map, env); hi; hi = axutil_hash_next( + env, hi)) + { + axutil_hash_this(hi, &key, NULL, &val); + if(key) + { + AXIS2_FREE(env->allocator, (char *)key); + } + if(val) + { + axis2_callback_t *callback = (axis2_callback_t *) val; + axis2_callback_free(callback, env); + } + + } + + axutil_hash_free(callback_recv->callback_map, env); + } + + if(callback_recv->base && callback_recv->base_deep_copy) + { + axis2_msg_recv_free(callback_recv->base, env); + } + + if(callback_recv) + { + AXIS2_FREE(env->allocator, callback_recv); + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_callback_recv_add_callback( + axis2_callback_recv_t * callback_recv, + const axutil_env_t * env, + const axis2_char_t * msg_id, + axis2_callback_t * callback) +{ + if(msg_id) + { + axis2_char_t *mid = axutil_strdup(env, msg_id); + axutil_hash_set(callback_recv->callback_map, mid, AXIS2_HASH_KEY_STRING, callback); + } + return AXIS2_SUCCESS; +} + +/* In the dual channel invocations client set a callback function to be invoked when a resonse + * is received from the server. When the response is received by the listening port of the + * listener manager, in the engine receive call the message is finally hit by callback receiver + * which is an implementation of the axis2 message receiver. This is the function that is called + * at that stage. The client set callback function is called from within here. + */ +static axis2_status_t AXIS2_CALL +axis2_callback_recv_receive( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + void *callback_recv_param) +{ + axis2_callback_recv_t *callback_recv = NULL; + axis2_relates_to_t *relates_to = NULL; + axis2_msg_info_headers_t *msg_info_headers = NULL; + + callback_recv = axis2_msg_recv_get_derived(msg_recv, env); + + msg_info_headers = axis2_msg_ctx_get_msg_info_headers(msg_ctx, env); + if(msg_info_headers) + { + relates_to = axis2_msg_info_headers_get_relates_to(msg_info_headers, env); + if(relates_to) + { + const axis2_char_t *msg_id = axis2_relates_to_get_value(relates_to, env); + if(msg_id) + { + axis2_async_result_t *result = NULL; + axis2_callback_t *callback = (axis2_callback_t *)axutil_hash_get( + callback_recv->callback_map, msg_id, AXIS2_HASH_KEY_STRING); + + result = axis2_async_result_create(env, msg_ctx); + if(callback && result) + { + axis2_callback_invoke_on_complete(callback, env, result); + axis2_callback_set_complete(callback, env, AXIS2_TRUE); + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, NULL); + } + + axis2_async_result_free(result, env); + if(callback && result) + return AXIS2_SUCCESS; + } + } + } + + return AXIS2_FAILURE; +} + diff --git a/src/core/clientapi/listener_manager.c b/src/core/clientapi/listener_manager.c new file mode 100644 index 0000000..1e3e3f2 --- /dev/null +++ b/src/core/clientapi/listener_manager.c @@ -0,0 +1,302 @@ +/* + * 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_listener_manager.h> +#include <axis2_const.h> +#include <axutil_hash.h> +#include <axis2_transport_receiver.h> + +/** + * keep information about the listener for a given transport + */ +typedef struct axis2_transport_listener_state +{ + int waiting_calls; + + axis2_transport_receiver_t *listener; + +} axis2_transport_listener_state_t; + +struct axis2_listener_manager +{ + + /** hash map of listeners */ + axis2_transport_listener_state_t *listener_map[AXIS2_TRANSPORT_ENUM_MAX]; + axutil_thread_t *listener_thread[AXIS2_TRANSPORT_ENUM_MAX]; + + /** configuration context */ + axis2_conf_ctx_t *conf_ctx; +}; + +typedef struct axis2_listener_manager_worker_func_args +{ + const axutil_env_t *env; + axis2_listener_manager_t *listner_manager; + axis2_transport_receiver_t *listener; +} axis2_listener_manager_worker_func_args_t; + +void *AXIS2_THREAD_FUNC axis2_listener_manager_worker_func( + axutil_thread_t * thd, + void *data); + +AXIS2_EXTERN axis2_listener_manager_t *AXIS2_CALL +axis2_listener_manager_create( + const axutil_env_t * env) +{ + axis2_listener_manager_t *listener_manager = NULL; + int i = 0; + + AXIS2_ENV_CHECK(env, NULL); + + listener_manager = AXIS2_MALLOC(env->allocator, sizeof(axis2_listener_manager_t)); + + if(!listener_manager) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create listener manager."); + return NULL; + } + + listener_manager->conf_ctx = NULL; + + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + listener_manager->listener_map[i] = NULL; + listener_manager->listener_thread[i] = NULL; + } + + return listener_manager; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_listener_manager_make_sure_started( + axis2_listener_manager_t * listener_manager, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS transport, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_transport_listener_state_t *tl_state = NULL; + + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + + if(listener_manager->conf_ctx) + { + if(conf_ctx != listener_manager->conf_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CLIENT_SIDE_SUPPORT_ONLY_ONE_CONF_CTX, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Only one configuration context is supported at client side."); + return AXIS2_FAILURE; + } + } + else + { + listener_manager->conf_ctx = conf_ctx; + } + + tl_state = listener_manager->listener_map[transport]; + + if(!tl_state) + { + /*means this transport not yet started, start the transport */ + axis2_transport_in_desc_t *transport_in = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_receiver_t *listener = NULL; + + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + transport_in = axis2_conf_get_transport_in(conf, env, transport); + if(transport_in) + { + listener = axis2_transport_in_desc_get_recv(transport_in, env); + if(listener) + { + axutil_thread_t *worker_thread = NULL; + axis2_listener_manager_worker_func_args_t *arg_list = NULL; + arg_list = AXIS2_MALLOC(env->allocator, + sizeof(axis2_listener_manager_worker_func_args_t)); + if(!arg_list) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create listener manager worker function arguments."); + return AXIS2_FAILURE; + } + arg_list->env = env; + arg_list->listner_manager = listener_manager; + arg_list->listener = listener; +#ifdef AXIS2_SVR_MULTI_THREADED + if (env->thread_pool) + { + worker_thread = + axutil_thread_pool_get_thread(env->thread_pool, + axis2_listener_manager_worker_func, + (void *) arg_list); + if (!worker_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Thread creation failed" + "Invoke non blocking failed"); + } + else + { + /*axutil_thread_pool_thread_detach(env->thread_pool, + worker_thread);*/ + /* we should not detach this, because, in the dual channel case + we should be able to terminate the thread before deleting the listener */ + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Thread pool not set in environment." + " Cannot invoke call non blocking"); + } +#else + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Threading not enabled." + " Cannot start separate listener"); + return AXIS2_FAILURE; +#endif + + tl_state = AXIS2_MALLOC(env->allocator, + sizeof(axis2_transport_listener_state_t)); + + if(!tl_state) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create transport listener state."); + } + else + { + tl_state->listener = listener; + tl_state->waiting_calls = 0; + listener_manager->listener_map[transport] = tl_state; + listener_manager->listener_thread[transport] = worker_thread; + } + } + } + } + } + + if(tl_state) + { + tl_state->waiting_calls++; + return AXIS2_SUCCESS; + } + else + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_listener_manager_stop( + axis2_listener_manager_t * listener_manager, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS transport) +{ + axis2_transport_listener_state_t *tl_state = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_thread_t *listener_thread = NULL; + + tl_state = listener_manager->listener_map[transport]; + listener_thread = listener_manager->listener_thread[transport]; + + if(tl_state) + { + tl_state->waiting_calls--; + if(tl_state->waiting_calls == 0) + { + status = axis2_transport_receiver_stop(tl_state->listener, env); + if(status == AXIS2_SUCCESS) + listener_manager->listener_map[transport] = NULL; + } + } + + if(listener_thread) + { + axutil_thread_pool_exit_thread(env->thread_pool, listener_thread); + listener_manager->listener_thread[transport] = NULL; + } + + return status; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_listener_manager_get_reply_to_epr( + const axis2_listener_manager_t * listener_manager, + const axutil_env_t * env, + const axis2_char_t * svc_name, + const AXIS2_TRANSPORT_ENUMS transport) +{ + axis2_transport_listener_state_t *tl_state = NULL; + + tl_state = listener_manager->listener_map[transport]; + if(tl_state) + { + return axis2_transport_receiver_get_reply_to_epr(tl_state->listener, env, svc_name); + } + return NULL; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_listener_manager_free( + axis2_listener_manager_t * listener_manager, + const axutil_env_t * env) +{ + int i = 0; + + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + if(listener_manager->listener_map[i]) + AXIS2_FREE(env->allocator, listener_manager->listener_map[i]); + } + + AXIS2_FREE(env->allocator, listener_manager); +} + +AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL +axis2_listener_manager_get_conf_ctx( + const axis2_listener_manager_t * listener_manager, + const axutil_env_t * env) +{ + return listener_manager->conf_ctx; +} + +void *AXIS2_THREAD_FUNC +axis2_listener_manager_worker_func( + axutil_thread_t * thd, + void *data) +{ + axis2_listener_manager_worker_func_args_t *args_list = NULL; + const axutil_env_t *th_env = NULL; + + args_list = (axis2_listener_manager_worker_func_args_t *)data; + if(!args_list) + return NULL; + + th_env = axutil_init_thread_env(args_list->env); + /* Start the protocol server. For examlle if protocol is http axis2_http_server_start function + * of the axis2_http_receiver is called. + */ + if(args_list->listener) + { + axis2_transport_receiver_start(args_list->listener, th_env); + } + return NULL; +} diff --git a/src/core/clientapi/op_client.c b/src/core/clientapi/op_client.c new file mode 100644 index 0000000..3ccb776 --- /dev/null +++ b/src/core/clientapi/op_client.c @@ -0,0 +1,1439 @@ +/* + * 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_op_client.h> +#include <axis2_const.h> +#include <axutil_hash.h> +#include <axutil_uuid_gen.h> +#include <axis2_listener_manager.h> +#include <axis2_engine.h> +#include "axis2_callback_recv.h" +#include <axiom_xml_reader.h> +#include <axis2_core_utils.h> +#include <axiom_soap_envelope.h> +#include <axiom_soap_const.h> +#include <axiom_soap_body.h> +#include <axutil_types.h> +#include <platforms/axutil_platform_auto_sense.h> + +struct axis2_op_client +{ + axis2_svc_ctx_t *svc_ctx; + + axis2_options_t *options; + + axis2_op_ctx_t *op_ctx; + + axis2_callback_t *callback; + + axis2_bool_t completed; + + /* to hold the locally created async result */ + axis2_async_result_t *async_result; + + axis2_callback_recv_t *callback_recv; + + /** message exchange pattern */ + axis2_char_t *mep; + + axis2_char_t *soap_version_uri; + axutil_string_t *soap_action; + axis2_char_t *wsa_action; + axis2_bool_t reuse; + +}; + +typedef struct axis2_op_client_worker_func_args +{ + const axutil_env_t *env; + axis2_op_client_t *op_client; + axis2_callback_t *callback; + axis2_op_t *op; + axis2_msg_ctx_t *msg_ctx; +} axis2_op_client_worker_func_args_t; + +void *AXIS2_THREAD_FUNC axis2_op_client_worker_func( + axutil_thread_t * thd, + void *data); + +static axis2_char_t *AXIS2_CALL axis2_op_client_get_transport_from_url( + const axis2_char_t * url, + const axutil_env_t * env); + +AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL +axis2_op_client_create( + const axutil_env_t * env, + axis2_op_t * op, + axis2_svc_ctx_t * svc_ctx, + axis2_options_t * options) +{ + axis2_op_client_t *op_client = NULL; + const axis2_char_t *mep_uri = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, op, NULL); + AXIS2_PARAM_CHECK(env->error, svc_ctx, NULL); + AXIS2_PARAM_CHECK(env->error, options, NULL); + + op_client = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_client_t)); + if(!op_client) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create op client."); + return NULL; + } + + /** initialize data */ + op_client->callback = NULL; + op_client->completed = AXIS2_FALSE; + op_client->reuse = AXIS2_FALSE; + op_client->async_result = NULL; + op_client->callback_recv = NULL; + + op_client->options = options; + op_client->svc_ctx = svc_ctx; + + op_client->mep = NULL; + op_client->soap_version_uri = NULL; + op_client->soap_action = NULL; + op_client->wsa_action = NULL; + + op_client->op_ctx = axis2_op_ctx_create(env, op, op_client->svc_ctx); + if(!(op_client->op_ctx)) + { + axis2_op_client_free(op_client, env); + return NULL; + } + + mep_uri = axis2_op_get_msg_exchange_pattern(op, env); + + if(!mep_uri) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_DETERMINE_MEP, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find message exchange pattern uri."); + axis2_op_client_free(op_client, env); + return NULL; + } + + op_client->mep = axutil_strdup(env, mep_uri); + + op_client->soap_version_uri = axutil_strdup(env, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI); + if(!(op_client->soap_version_uri)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap version uri."); + axis2_op_client_free(op_client, env); + return NULL; + } + + /** initialize parser for thread safety */ + axiom_xml_reader_init(); + return op_client; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_set_options( + axis2_op_client_t * op_client, + const axutil_env_t * env, + const axis2_options_t * options) +{ + if(op_client->options) + { + axis2_options_free(op_client->options, env); + } + op_client->options = (axis2_options_t *)options; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_options_t *AXIS2_CALL +axis2_op_client_get_options( + const axis2_op_client_t * op_client, + const axutil_env_t * env) +{ + return op_client->options; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_add_msg_ctx( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_msg_ctx_t * mc) +{ + axis2_msg_ctx_t *out_msg_ctx = NULL, *in_msg_ctx = NULL; + axis2_msg_ctx_t **msg_ctx_map = NULL; + + /* Don't use AXIS2_PARAM_CHECK to verify op_client, as it clobbers + env->error->status_code on no error destroying the information + therein that an error has already occurred. */ + if(!op_client) + { + if(axutil_error_get_status_code(env->error) == AXIS2_SUCCESS) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + } + return AXIS2_FAILURE; + } + /* mc message context pointer may be NULL, e.g., when no response message + is received */ + + if(op_client->op_ctx) + { + msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "op_ctx is NULL, unable to continue"); + return AXIS2_FAILURE; + } + + if(msg_ctx_map) + { + out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; + in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN]; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "msg_ctx_map is NULL, unable to continue"); + return AXIS2_FAILURE; + } + + if(op_client->reuse) + { + /* This is the second invocation using the same service client, + so reset */ + 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) + { + axis2_msg_ctx_free(in_msg_ctx, env); + in_msg_ctx = NULL; + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL; + } + + axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_FALSE); + op_client->reuse = AXIS2_FALSE; + } + + if(out_msg_ctx && in_msg_ctx) + { + /* may be this is the second invocation using the same service clinet, + so reset */ + axis2_msg_ctx_free(out_msg_ctx, env); + out_msg_ctx = NULL; + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL; + axis2_msg_ctx_free(in_msg_ctx, env); + in_msg_ctx = NULL; + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL; + axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_FALSE); + } + + if(!out_msg_ctx) + { + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = mc; + } + else + { + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = mc; + axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_TRUE); + } + + if(out_msg_ctx && !mc) + { + axutil_property_t *dump_property; + axis2_char_t *dump_value = NULL; + if(!axis2_msg_ctx_get_doing_rest(out_msg_ctx, env)) + { + dump_property = axis2_msg_ctx_get_property(out_msg_ctx, env, AXIS2_DUMP_INPUT_MSG_TRUE); + if(dump_property) + { + dump_value = (axis2_char_t *)axutil_property_get_value(dump_property, env); + } + } + + if(axutil_strcmp(dump_value, AXIS2_VALUE_TRUE)) + { + axis2_msg_ctx_free(out_msg_ctx, env); + out_msg_ctx = NULL; + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_add_out_msg_ctx( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_msg_ctx_t * mc) +{ + axis2_msg_ctx_t **msg_ctx_map = NULL; + + msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env); + + if(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]) + { + axis2_msg_ctx_free(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT], env); + } + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = mc; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_add_in_msg_ctx( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_msg_ctx_t * mc) +{ + axis2_msg_ctx_t **msg_ctx_map = NULL; + + msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env); + + if(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN]) + { + axis2_msg_ctx_free(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN], env); + } + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = mc; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_msg_ctx_t *AXIS2_CALL +axis2_op_client_get_msg_ctx( + const axis2_op_client_t * op_client, + const axutil_env_t * env, + const axis2_wsdl_msg_labels_t message_label) +{ + return axis2_op_ctx_get_msg_ctx(op_client->op_ctx, env, message_label); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_set_callback( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_callback_t * callback) +{ + if(op_client->callback) + { + axis2_callback_free(op_client->callback, env); + } + + op_client->callback = callback; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_callback_t *AXIS2_CALL +axis2_op_client_get_callback( + axis2_op_client_t * op_client, + const axutil_env_t * env) +{ + return op_client->callback; +} + +/* This function is called from service client irrespective of the message exchange pattern + * and whether one/two way channel used. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_execute( + axis2_op_client_t * op_client, + const axutil_env_t * env, + const axis2_bool_t block) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_msg_ctx_t *msg_ctx = NULL; + + axis2_transport_out_desc_t *transport_out = NULL; + axis2_transport_in_desc_t *transport_in = NULL; + + axis2_status_t status = AXIS2_FAILURE; + axis2_op_t *op = NULL; + axis2_char_t *msg_id = NULL; + + if(op_client->completed) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Op client execute failed. Already completed."); + return AXIS2_FAILURE; + } + + conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env); + + msg_ctx = (axis2_msg_ctx_t *)axis2_op_client_get_msg_ctx(op_client, env, + AXIS2_WSDL_MESSAGE_LABEL_OUT); + + if(!msg_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Op client execute failed. Message context is not valid."); + return AXIS2_FAILURE; + } + + axis2_msg_ctx_set_options(msg_ctx, env, op_client->options); + + /** + if the transport to use for sending is not specified, try to find it + from the URL or the client option. + */ + transport_out = axis2_options_get_transport_out(op_client->options, env); + if(!transport_out) + { + axis2_endpoint_ref_t *to_epr = NULL; + axutil_property_t *property = NULL; + property = axis2_options_get_property(op_client->options, env, AXIS2_TARGET_EPR); + if(property) + { + to_epr = axutil_property_get_value(property, env); + } + + if(!to_epr) + { + to_epr = axis2_options_get_to(op_client->options, env); + } + + if(!to_epr) + { + to_epr = axis2_msg_ctx_get_to(msg_ctx, env); + } + + transport_out = axis2_op_client_infer_transport(op_client, env, to_epr); + } + + if(!transport_out) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Op client execute failed. Cannot find transport out."); + return AXIS2_FAILURE; + } + + if(!(axis2_msg_ctx_get_transport_out_desc(msg_ctx, env))) + { + axis2_msg_ctx_set_transport_out_desc(msg_ctx, env, transport_out); + } + + transport_in = axis2_options_get_transport_in(op_client->options, env); + if(!transport_in) + { + axis2_conf_ctx_t *conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env); + + if(conf_ctx) + { + axis2_conf_t *conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + transport_in = axis2_conf_get_transport_in(conf, env, + axis2_transport_out_desc_get_enum(transport_out, env)); + } + } + } + if(!transport_in) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Op client execute failed. Cannot find transport in."); + return AXIS2_FAILURE; + } + + if(!(axis2_msg_ctx_get_transport_in_desc(msg_ctx, env))) + { + axis2_msg_ctx_set_transport_in_desc(msg_ctx, env, transport_in); + } + + op = axis2_op_ctx_get_op(op_client->op_ctx, env); + + if(!op) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Op client execute failed. Cannot find operation."); + return AXIS2_FAILURE; + } + status = axis2_op_client_prepare_invocation(op_client, env, op, msg_ctx); + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Op client execute failed. Preparing for invocation failed."); + return AXIS2_FAILURE; + } + msg_id = (axis2_char_t *)axutil_uuid_gen(env); + axis2_msg_ctx_set_message_id(msg_ctx, env, msg_id); + if(msg_id) + { + AXIS2_FREE(env->allocator, msg_id); + msg_id = NULL; + } + + /* If dual channel. */ + if(axis2_options_get_use_separate_listener(op_client->options, env)) + { + axis2_engine_t *engine = NULL; + + if(op_client->callback) + { + AXIS2_CALLBACK_RECV_ADD_CALLBACK(op_client->callback_recv, env, + axis2_msg_ctx_get_msg_id(msg_ctx, env), op_client->callback); + } + + axis2_msg_ctx_set_op_ctx(msg_ctx, env, axis2_op_find_op_ctx(op, env, msg_ctx, + op_client-> svc_ctx)); + axis2_msg_ctx_set_svc_ctx(msg_ctx, env, op_client->svc_ctx); + + /* send the message */ + engine = axis2_engine_create(env, conf_ctx); + if(!engine) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Op client execute failed due to engine creation failure."); + return AXIS2_FAILURE; + } + axis2_engine_send(engine, env, msg_ctx); + axis2_engine_free(engine, env); + } + else /* Same channel will be used irrespective of message exchange pattern. */ + { + if(block) + { + axis2_msg_ctx_t *response_mc = NULL; + + axis2_msg_ctx_set_svc_ctx(msg_ctx, env, op_client->svc_ctx); + axis2_msg_ctx_set_conf_ctx(msg_ctx, env, axis2_svc_ctx_get_conf_ctx( + op_client-> svc_ctx, env)); + axis2_msg_ctx_set_op_ctx(msg_ctx, env, op_client->op_ctx); + + /*Send the SOAP Message and receive a response */ + response_mc = axis2_op_client_two_way_send(env, msg_ctx); + if(!response_mc) + { + const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env); + if(!(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY)) || !(axutil_strcmp(mep, + AXIS2_MEP_URI_ROBUST_OUT_ONLY))) + { + if(env->error) + { + return env->error->status_code; + } + else + { + return AXIS2_FAILURE; + } + } + else + { + return AXIS2_FAILURE; + } + } + axis2_op_client_add_msg_ctx(op_client, env, response_mc); + } + else + { + axis2_op_client_worker_func_args_t *arg_list = NULL; + arg_list = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_client_worker_func_args_t)); + if(!arg_list) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create op client worker function argument list."); + return AXIS2_FAILURE; + } + arg_list->env = env; + arg_list->op_client = op_client; + arg_list->callback = op_client->callback; + arg_list->op = op; + arg_list->msg_ctx = msg_ctx; +#ifdef AXIS2_SVR_MULTI_THREADED + if (env->thread_pool) + { + axutil_thread_t *worker_thread = NULL; + worker_thread = axutil_thread_pool_get_thread(env->thread_pool, + axis2_op_client_worker_func, + (void *) + arg_list); + if (!worker_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Thread creation failed call invoke non blocking"); + } + else + { + axutil_thread_pool_thread_detach(env->thread_pool, + worker_thread); + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Thread pool not set in environment" + "Cannot invoke call non blocking"); + } +#else + axis2_op_client_worker_func(NULL, (void *)arg_list); +#endif + + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_reset( + axis2_op_client_t * op_client, + const axutil_env_t * env) +{ + if(!op_client->completed) + return AXIS2_FAILURE; + + op_client->completed = AXIS2_FALSE; + + op_client->op_ctx = NULL; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_complete( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_msg_ctx_t * mc) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_listener_manager_t *listener_manager = NULL; + AXIS2_TRANSPORT_ENUMS transport = AXIS2_TRANSPORT_ENUM_HTTP; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(mc, env); + + if(!conf_ctx) + return AXIS2_FAILURE; + + if(!listener_manager) + return AXIS2_FAILURE; + + return axis2_listener_manager_stop(listener_manager, env, transport); +} + +AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL +axis2_op_client_get_operation_context( + const axis2_op_client_t * op_client, + const axutil_env_t * env) +{ + return op_client->op_ctx; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_op_client_free( + axis2_op_client_t * op_client, + const axutil_env_t * env) +{ + if(!op_client) + return; + + /*if(op_client->callback) + { + axis2_callback_free(op_client->callback, env); + }*/ + + if(op_client->op_ctx) + { + axis2_op_ctx_free(op_client->op_ctx, env); + op_client->op_ctx = NULL; + } + + if(op_client->soap_version_uri) + { + AXIS2_FREE(env->allocator, op_client->soap_version_uri); + } + + if(op_client->mep) + { + AXIS2_FREE(env->allocator, op_client->mep); + } + + if(axis2_options_get_xml_parser_reset(op_client->options, env)) + { + axiom_xml_reader_cleanup(); + } + + AXIS2_FREE(env->allocator, op_client); +} + +/* This function is the thread worker function for the single channel non blocking case. Here + * being non-blocking implies that message is two way. */ +void *AXIS2_THREAD_FUNC +axis2_op_client_worker_func( + axutil_thread_t * thd, + void *data) +{ + axis2_op_client_worker_func_args_t *args_list = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_msg_ctx_t *response = NULL; + axutil_env_t *th_env = NULL; + axutil_thread_pool_t *th_pool = NULL; + + args_list = (axis2_op_client_worker_func_args_t *)data; + if(!args_list) + { + return NULL; + } + + th_env = axutil_init_thread_env(args_list->env); + + op_ctx = axis2_op_ctx_create(th_env, args_list->op, args_list->op_client->svc_ctx); + if(!op_ctx) + { + return NULL; + } + axis2_msg_ctx_set_op_ctx(args_list->msg_ctx, th_env, op_ctx); + axis2_msg_ctx_set_svc_ctx(args_list->msg_ctx, th_env, args_list->op_client->svc_ctx); + + /* send the request and wait for response */ + response = axis2_op_client_two_way_send(th_env, args_list->msg_ctx); + + /* We do not need to handle the NULL response here because this thread function is called only + * in the single channel non blocking case which, imply this is two way message by design. + */ + + /* Here after the code is a subset of what callback receiver do in dual channel case.*/ + axis2_op_client_add_msg_ctx(args_list->op_client, th_env, response); + args_list->op_client->async_result = axis2_async_result_create(th_env, response); + + if(args_list->callback) + { + axis2_callback_invoke_on_complete(args_list->callback, th_env, + args_list->op_client->async_result); + + axis2_callback_set_complete(args_list->callback, th_env, AXIS2_TRUE); + } + + /* Clean up memory */ + axis2_async_result_free(args_list->op_client->async_result, th_env); + + axis2_op_ctx_free(op_ctx, th_env); + + th_pool = th_env->thread_pool; + + AXIS2_FREE(th_env->allocator, args_list); + + if(th_env) + { + axutil_free_thread_env(th_env); + th_env = NULL; + } + axutil_thread_pool_exit_thread(th_pool, thd); + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_set_callback_recv( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_callback_recv_t * callback_recv) +{ + op_client->callback_recv = callback_recv; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axis2_op_client_get_soap_action( + const axis2_op_client_t * op_client, + const axutil_env_t * env) +{ + return op_client->soap_action; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_prepare_invocation( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_op_t * op, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_svc_t *svc = NULL; + + AXIS2_PARAM_CHECK(env->error, op, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + /* make sure operation's MEP is the same as given MEP */ + if(op_client->mep) + { + if(axutil_strcmp(op_client->mep, axis2_op_get_msg_exchange_pattern(op, env))) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_MISMATCH_IN_MEP_CLIENT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Message exchange pattern of op client and operation are different."); + return AXIS2_FAILURE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_BE_NULL_IN_MEP_CLIENT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Message exchange pattern of op client is not valid."); + return AXIS2_FAILURE; + } + /* If operation has a parent service get it */ + svc = axis2_op_get_parent(op, env); + if(svc) + { + axis2_svc_ctx_set_svc(op_client->svc_ctx, env, svc); + } + else + { + svc = axis2_svc_ctx_get_svc(op_client->svc_ctx, env); + if(svc) + { + axis2_op_t *temp_op = NULL; + const axutil_qname_t *op_qname = axis2_op_get_qname(op, env); + temp_op = axis2_svc_get_op_with_qname(svc, env, op_qname); + if(!temp_op) + { + axis2_svc_add_op(svc, env, op); + } + } + } + + if(op_client->wsa_action) + { + axis2_msg_ctx_set_wsa_action(msg_ctx, env, op_client->wsa_action); + } + + if(op_client->soap_action) + { + axis2_msg_ctx_set_soap_action(msg_ctx, env, op_client->soap_action); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL +axis2_op_client_prepare_soap_envelope( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axiom_node_t * to_send) +{ + axis2_msg_ctx_t *msg_ctx = NULL; + axiom_soap_envelope_t *envelope = NULL; + int soap_version = AXIOM_SOAP12; + + if(op_client->svc_ctx) + { + msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(op_client-> svc_ctx, env), + NULL, NULL); + } + + if(!msg_ctx) + { + return NULL; + } + + if(op_client->soap_version_uri) + { + if(!(axutil_strcmp(op_client->soap_version_uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI))) + soap_version = AXIOM_SOAP11; + else + soap_version = AXIOM_SOAP12; + } + + envelope = axiom_soap_envelope_create_default_soap_envelope(env, soap_version); + if(!envelope) + { + return NULL; + } + + if(to_send) + { + axiom_soap_body_t *soap_body = NULL; + soap_body = axiom_soap_envelope_get_body(envelope, env); + if(soap_body) + { + axiom_node_t *node = NULL; + node = axiom_soap_body_get_base_node(soap_body, env); + if(node) + { + axiom_node_add_child(node, env, to_send); + } + } + } + + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, envelope); + + return msg_ctx; +} + +AXIS2_EXTERN axis2_transport_out_desc_t *AXIS2_CALL +axis2_op_client_infer_transport( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_endpoint_ref_t * epr) +{ + axis2_char_t *transport = NULL; + axis2_transport_out_desc_t *transport_out_desc = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + AXIS2_TRANSPORT_ENUMS transport_enum = AXIS2_TRANSPORT_ENUM_MAX; + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Start:axis2_op_client_infer_transport"); + + /* We first try the client option */ + transport_enum = axis2_options_get_sender_transport_protocol(op_client->options, env); + if(transport_enum == AXIS2_TRANSPORT_ENUM_MAX) + { + /* If we couldn't find the transport we default to HTTP */ + transport_enum = AXIS2_TRANSPORT_ENUM_HTTP; + /* We try to infer transport from the url */ + if(epr) + { + const axis2_char_t *to_url = axis2_endpoint_ref_get_address(epr, env); + + transport = axis2_op_client_get_transport_from_url(to_url, env); + } + + if(transport) + { + if(!axutil_strcmp(transport, AXIS2_TRANSPORT_HTTP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_HTTP; + } + else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_HTTPS)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_HTTPS; + } + else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_XMPP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_XMPP; + } + else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_TCP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_TCP; + } + else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_AMQP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_AMQP; + } + else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_UDP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_UDP; + } + + AXIS2_FREE(env->allocator, transport); + transport = NULL; + } + } + conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + transport_out_desc = axis2_conf_get_transport_out(conf, env, transport_enum); + } + } + if(!transport_out_desc) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot infer transport"); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CANNOT_INFER_TRANSPORT, AXIS2_FAILURE); + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "End:axis2_op_client_infer_transport"); + return transport_out_desc; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axis2_op_client_create_default_soap_envelope( + axis2_op_client_t * op_client, + const axutil_env_t * env) +{ + axiom_soap_envelope_t *envelope = NULL; + + if(!(axutil_strcmp(AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI, op_client->soap_version_uri))) + { + envelope = axiom_soap_envelope_create_with_soap_version_prefix(env, AXIOM_SOAP12, NULL); + } + + if(!(axutil_strcmp(AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI, op_client->soap_version_uri))) + { + envelope = axiom_soap_envelope_create_with_soap_version_prefix(env, AXIOM_SOAP11, NULL); + } + return envelope; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_engage_module( + axis2_op_client_t * op_client, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + + if(op_client->svc_ctx) + { + conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + /*if it is already engaged do not engage it again */ + if(!(axis2_conf_is_engaged(conf, env, qname))) + { + return axis2_conf_engage_module(conf, env, qname); + } + } + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_set_soap_version_uri( + axis2_op_client_t * op_client, + const axutil_env_t * env, + const axis2_char_t * soap_version_uri) +{ + if(op_client->soap_version_uri) + { + AXIS2_FREE(env->allocator, op_client->soap_version_uri); + op_client->soap_version_uri = NULL; + } + + if(soap_version_uri) + { + op_client->soap_version_uri = axutil_strdup(env, soap_version_uri); + if(!(op_client->soap_version_uri)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap version uri."); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_set_soap_action( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axutil_string_t * soap_action) +{ + if(op_client->soap_action) + { + axutil_string_free(op_client->soap_action, env); + op_client->soap_action = NULL; + } + + if(soap_action) + { + op_client->soap_action = axutil_string_clone(soap_action, env); + if(!(op_client->soap_action)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap action."); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_client_set_wsa_action( + axis2_op_client_t * op_client, + const axutil_env_t * env, + const axis2_char_t * wsa_action) +{ + if(op_client->wsa_action) + { + AXIS2_FREE(env->allocator, op_client->wsa_action); + op_client->wsa_action = NULL; + } + + if(wsa_action) + { + op_client->wsa_action = axutil_strdup(env, wsa_action); + if(!(op_client->wsa_action)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create wsa action."); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +static axis2_char_t *AXIS2_CALL +axis2_op_client_get_transport_from_url( + const axis2_char_t * url, + const axutil_env_t * env) +{ + axis2_char_t *transport = NULL; + const axis2_char_t *start = NULL; + const axis2_char_t *end = NULL; + AXIS2_PARAM_CHECK(env->error, url, NULL); + start = url; + end = url; + while((*end) && (*end) != ':') + end++; + + if((*end) == ':') + { + const axis2_char_t *c = NULL; + transport = AXIS2_MALLOC(env->allocator, (end - start + 1) * sizeof(char)); + if(!transport) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create transport protocol identifier."); + return NULL; + } + + for(c = start; c < end; c++) + transport[c - start] = *c; + transport[c - start] = '\0'; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "URL is malformed or does not contain a transport protocol"); + } + return transport; +} + +AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL +axis2_op_client_get_svc_ctx( + const axis2_op_client_t * op_client, + const axutil_env_t * env) +{ + return op_client->svc_ctx; +} + +/* This function is called only for single channel invocations */ +AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL +axis2_op_client_two_way_send( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_engine_t *engine = NULL; + axis2_status_t status = AXIS2_SUCCESS; + axis2_msg_ctx_t *response = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_op_t *op = NULL; + axiom_soap_envelope_t *response_envelope = NULL; + axutil_property_t *property = NULL; + long index = -1; + axis2_bool_t wait_indefinitely = AXIS2_FALSE; + axis2_char_t *mep = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + engine = axis2_engine_create(env, conf_ctx); + if(!engine) + return NULL; + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TIMEOUT_IN_SECONDS); + if(property) + { + axis2_char_t *value = axutil_property_get_value(property, env); + if(value) + index = AXIS2_ATOI(value); + if(index == -1) + { + wait_indefinitely = AXIS2_TRUE; + index = 1; + } + } + + status = axis2_engine_send(engine, env, msg_ctx); + + axis2_engine_free(engine, env); + engine = NULL; + + if(status != AXIS2_SUCCESS) + { + if(AXIS2_ERROR_GET_STATUS_CODE(env->error) == AXIS2_SUCCESS) + { + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + } + return NULL; + } + + op = axis2_msg_ctx_get_op(msg_ctx, env); + if(op) + { + mep = (axis2_char_t *)axis2_op_get_msg_exchange_pattern(op, env); + } + + if(!mep) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_DETERMINE_MEP, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot determine message exchange pattern."); + return NULL; + } + + /* handle one way non robust case */ + if(!(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY))) + { + return NULL; + } + + /* create the response */ + response = axis2_msg_ctx_create(env, conf_ctx, + axis2_msg_ctx_get_transport_in_desc(msg_ctx, env), axis2_msg_ctx_get_transport_out_desc( + msg_ctx, env)); + if(!response) + return NULL; + + axis2_msg_ctx_set_server_side(response, env, AXIS2_FALSE); + axis2_msg_ctx_set_conf_ctx(response, env, axis2_msg_ctx_get_conf_ctx(msg_ctx, env)); + axis2_msg_ctx_set_svc_grp_ctx(response, env, axis2_msg_ctx_get_svc_grp_ctx(msg_ctx, env)); + + /* If request is REST we assume the response is REST, so set the variable */ + axis2_msg_ctx_set_doing_rest(response, env, axis2_msg_ctx_get_doing_rest(msg_ctx, env)); + axis2_msg_ctx_set_status_code(response, env, axis2_msg_ctx_get_status_code(msg_ctx, env)); + + if(op) + { + axis2_op_register_op_ctx(op, env, response, axis2_msg_ctx_get_op_ctx(msg_ctx, env)); + } + + /* set response envelope */ + if(engine) + { + axis2_engine_free(engine, env); + engine = NULL; + } + response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env); + if(response_envelope) + { + axis2_msg_ctx_set_soap_envelope(response, env, response_envelope); + engine = axis2_engine_create(env, conf_ctx); + if(engine) + { + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HANDLER_ALREADY_VISITED); + if(property) + { + axis2_char_t *value = axutil_property_get_value(property, env); + if(!axutil_strcmp(AXIS2_VALUE_TRUE, value)) + { + if(engine) + { + axis2_engine_free(engine, env); + } + return response; + } + } + status = axis2_engine_receive(engine, env, response); + } + } + else + { + while(!response_envelope && index > 0) + { + /*wait till the response arrives */ + AXIS2_SLEEP(1); + if(!wait_indefinitely) + index--; + response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env); + } + /* if it is a two way message, then the status should be in error, + else it is a one way message */ + if(response_envelope) + { + axis2_msg_ctx_set_soap_envelope(response, env, response_envelope); + /* There could be a scenariao where the message has already passed + * through the incoming phases. eg. Reliable Messaging 1.0 two + * way single channel + */ + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HANDLER_ALREADY_VISITED); + if(property) + { + axis2_char_t *value = axutil_property_get_value(property, env); + if(!axutil_strcmp(AXIS2_VALUE_TRUE, value)) + { + return response; + } + } + engine = axis2_engine_create(env, conf_ctx); + if(engine) + { + status = axis2_engine_receive(engine, env, response); + if(status != AXIS2_SUCCESS) + return NULL; + } + } + else + { + if(AXIS2_ERROR_GET_STATUS_CODE(env->error) != AXIS2_SUCCESS) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Response is not valid. Blocking invocation expects response."); + if(engine) + { + axis2_engine_free(engine, env); + engine = NULL; + } + axis2_msg_ctx_free(response, env); + return NULL; + } + } + } + + /*following is no longer valid. Just keeping for others view*/ + + /* property is NULL, and we set null for AXIS2_TRANSPORT_IN in msg_ctx to + avoid double free of this property */ + /*axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property);*/ + + if(engine) + { + axis2_engine_free(engine, env); + engine = NULL; + } + if(!(axutil_strcmp(mep, AXIS2_MEP_URI_ROBUST_OUT_ONLY)) && response) + { + if(axis2_msg_ctx_get_doing_rest(response, env) && axis2_msg_ctx_get_status_code(response, + env) >= 400) + { + /* All HTTP 4xx and 5xx status codes are treated as errors */ + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP client transport error."); + return NULL; + } + switch(axis2_msg_ctx_get_status_code(response, env)) + { + /* In a SOAP request HTTP status code 500 is used for errors */ + case 500: + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP client transport error."); + break; + case 0: + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Response is not valid. Blocking invocation expects response."); + break; + case -1: + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Response is not valid. Blocking invocation expects response."); + break; + } + + if(response) + { + axis2_msg_ctx_free(response, env); + } + + return NULL; + } + return response; +} + +AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL +axis2_op_client_receive( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_engine_t *engine = NULL; + axis2_status_t status = AXIS2_SUCCESS; + axis2_msg_ctx_t *response = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_op_t *op = NULL; + axiom_soap_envelope_t *response_envelope = NULL; + axutil_property_t *property = NULL; + + /* create the response */ + response = axis2_msg_ctx_create(env, conf_ctx, + axis2_msg_ctx_get_transport_in_desc(msg_ctx, env), axis2_msg_ctx_get_transport_out_desc( + msg_ctx, env)); + if(!response) + return NULL; + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_IN); + if(property) + { + axis2_msg_ctx_set_property(response, env, AXIS2_TRANSPORT_IN, property); + property = NULL; + } + + op = axis2_msg_ctx_get_op(msg_ctx, env); + if(op) + { + axis2_op_register_op_ctx(op, env, response, axis2_msg_ctx_get_op_ctx(msg_ctx, env)); + } + axis2_msg_ctx_set_server_side(response, env, AXIS2_FALSE); + axis2_msg_ctx_set_conf_ctx(response, env, axis2_msg_ctx_get_conf_ctx(msg_ctx, env)); + axis2_msg_ctx_set_svc_grp_ctx(response, env, axis2_msg_ctx_get_svc_grp_ctx(msg_ctx, env)); + + /* If request is REST we assume the response is REST, so set the variable */ + axis2_msg_ctx_set_doing_rest(response, env, axis2_msg_ctx_get_doing_rest(msg_ctx, env)); + + response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env); + if(response_envelope) + { + axis2_msg_ctx_set_soap_envelope(response, env, response_envelope); + if(engine) + { + axis2_engine_free(engine, env); + engine = NULL; + } + + engine = axis2_engine_create(env, conf_ctx); + if(engine) + { + status = axis2_engine_receive(engine, env, response); + if(status != AXIS2_SUCCESS) + { + return NULL; + } + } + + } + else + { + /* if it is a two way message, then the status should be in error, + else it is a one way message */ + if(AXIS2_ERROR_GET_STATUS_CODE(env->error) != AXIS2_SUCCESS) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE, + AXIS2_FAILURE); + return NULL; + } + } + + /* property is NULL, and we set null for AXIS2_TRANSPORT_IN in msg_ctx to + avoid double free of this property */ + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property); + + if(engine) + { + axis2_engine_free(engine, env); + engine = NULL; + } + return response; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_op_client_set_reuse( + axis2_op_client_t * op_client, + const axutil_env_t * env, + axis2_bool_t reuse) +{ + op_client->reuse = reuse; +} diff --git a/src/core/clientapi/options.c b/src/core/clientapi/options.c new file mode 100644 index 0000000..26c5d33 --- /dev/null +++ b/src/core/clientapi/options.c @@ -0,0 +1,1068 @@ +/* + * 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_options.h> +#include <axis2_const.h> +#include <axutil_hash.h> +#include <axiom_soap_const.h> +#include <axis2_msg_info_headers.h> +#include <axutil_array_list.h> +#include <axis2_http_transport.h> + +struct axis2_options +{ + + /** parent options */ + axis2_options_t *parent; + + axutil_hash_t *properties; + + axis2_char_t *soap_version_uri; + + int soap_version; + + long timeout_in_milli_seconds; + + axis2_bool_t use_separate_listener; + + /** addressing specific properties */ + axis2_msg_info_headers_t *msg_info_headers; + + axis2_transport_receiver_t *receiver; + + axis2_transport_in_desc_t *transport_in; + + AXIS2_TRANSPORT_ENUMS transport_in_protocol; + + /** for sending and receiving messages */ + axis2_transport_out_desc_t *transport_out; + AXIS2_TRANSPORT_ENUMS sender_transport_protocol; + + axis2_bool_t manage_session; + axis2_bool_t enable_mtom; + axutil_string_t *soap_action; + axis2_bool_t xml_parser_reset; +}; + +AXIS2_EXTERN axis2_options_t *AXIS2_CALL +axis2_options_create( + const axutil_env_t * env) +{ + axis2_options_t *options = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + options = AXIS2_MALLOC(env->allocator, sizeof(axis2_options_t)); + if(!options) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create options."); + return NULL; + } + + options->parent = NULL; + options->properties = NULL; + options->soap_version_uri = NULL; + options->timeout_in_milli_seconds = -1; + options->use_separate_listener = -1; + options->receiver = NULL; + options->transport_in = NULL; + options->transport_in_protocol = AXIS2_TRANSPORT_ENUM_MAX; + options->transport_out = NULL; + options->sender_transport_protocol = AXIS2_TRANSPORT_ENUM_MAX; + options->manage_session = -1; + options->soap_version = AXIOM_SOAP12; + options->enable_mtom = AXIS2_FALSE; + options->soap_action = NULL; + options->xml_parser_reset = AXIS2_TRUE; + + options->msg_info_headers = axis2_msg_info_headers_create(env, NULL, NULL); + if(!options->msg_info_headers) + { + axis2_options_free(options, env); + return NULL; + } + + options->properties = axutil_hash_make(env); + if(!options->properties) + { + axis2_options_free(options, env); + return NULL; + } + + return options; +} + +AXIS2_EXTERN axis2_options_t *AXIS2_CALL +axis2_options_create_with_parent( + const axutil_env_t * env, + axis2_options_t * parent) +{ + + axis2_options_t *options = NULL; + + options = axis2_options_create(env); + + if(options) + { + options->parent = parent; + } + return options; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_options_get_action( + const axis2_options_t * options, + const axutil_env_t * env) +{ + const axis2_char_t *action = NULL; + action = axis2_msg_info_headers_get_action(options->msg_info_headers, env); + + if(!action && options->parent) + { + return axis2_options_get_action(options->parent, env); + } + + return action; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_options_get_fault_to( + const axis2_options_t * options, + const axutil_env_t * env) +{ + axis2_endpoint_ref_t *fault_to = NULL; + + fault_to = axis2_msg_info_headers_get_fault_to(options->msg_info_headers, env); + + if(!fault_to && options->parent) + { + return axis2_options_get_fault_to(options->parent, env); + } + + return fault_to; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_options_get_from( + const axis2_options_t * options, + const axutil_env_t * env) +{ + axis2_endpoint_ref_t *from = NULL; + + from = axis2_msg_info_headers_get_from(options->msg_info_headers, env); + + if(!from && options->parent) + { + return axis2_options_get_from(options->parent, env); + } + + return from; +} + +AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL +axis2_options_get_transport_receiver( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(!options->receiver && options->parent) + { + return axis2_options_get_transport_receiver(options->parent, env); + } + + return options->receiver; +} + +AXIS2_EXTERN axis2_transport_in_desc_t *AXIS2_CALL +axis2_options_get_transport_in( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(!options->transport_in && options->parent) + { + return axis2_options_get_transport_in(options->parent, env); + } + + return options->transport_in; +} + +AXIS2_EXTERN AXIS2_TRANSPORT_ENUMS AXIS2_CALL +axis2_options_get_transport_in_protocol( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(options->parent) + { + return axis2_options_get_transport_in_protocol(options->parent, env); + } + + return options->transport_in_protocol; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_options_get_message_id( + const axis2_options_t * options, + const axutil_env_t * env) +{ + const axis2_char_t *message_id = NULL; + + message_id = axis2_msg_info_headers_get_message_id(options->msg_info_headers, env); + + if(!message_id && options->parent) + { + return axis2_options_get_message_id(options->parent, env); + } + + return message_id; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_options_get_properties( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(!axutil_hash_count(options->properties) && options->parent) + { + return axis2_options_get_properties(options->parent, env); + } + + return options->properties; +} + +AXIS2_EXTERN void *AXIS2_CALL +axis2_options_get_property( + const axis2_options_t * options, + const axutil_env_t * env, + const axis2_char_t * key) +{ + void *property = NULL; + + property = axutil_hash_get(options->properties, key, AXIS2_HASH_KEY_STRING); + + if(!property && options->parent) + { + return axis2_options_get_property(options->parent, env, key); + } + + return property; +} + +AXIS2_EXTERN axis2_relates_to_t *AXIS2_CALL +axis2_options_get_relates_to( + const axis2_options_t * options, + const axutil_env_t * env) +{ + axis2_relates_to_t *relates_to = NULL; + + relates_to = axis2_msg_info_headers_get_relates_to(options->msg_info_headers, env); + + if(!relates_to && options->parent) + { + return axis2_options_get_relates_to(options->parent, env); + } + + return relates_to; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_options_get_reply_to( + const axis2_options_t * options, + const axutil_env_t * env) +{ + axis2_endpoint_ref_t *reply_to = NULL; + + reply_to = axis2_msg_info_headers_get_reply_to(options->msg_info_headers, env); + + if(!reply_to && options->parent) + { + return axis2_options_get_reply_to(options->parent, env); + } + + return reply_to; +} + +AXIS2_EXTERN axis2_transport_out_desc_t *AXIS2_CALL +axis2_options_get_transport_out( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(!options->transport_out && options->parent) + { + return axis2_options_get_transport_out(options->parent, env); + } + + return options->transport_out; +} + +AXIS2_EXTERN AXIS2_TRANSPORT_ENUMS AXIS2_CALL +axis2_options_get_sender_transport_protocol( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(options->parent) + { + return axis2_options_get_sender_transport_protocol(options->parent, env); + } + + return options->sender_transport_protocol; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_options_get_soap_version_uri( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(!options->soap_version_uri && options->parent) + { + return axis2_options_get_soap_version_uri(options->parent, env); + } + + if(options->soap_version_uri) + { + return options->soap_version_uri; + } + return AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + +} + +AXIS2_EXTERN long AXIS2_CALL +axis2_options_get_timeout_in_milli_seconds( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(options->timeout_in_milli_seconds == -1) + { + if(options->parent) + { + return axis2_options_get_timeout_in_milli_seconds(options->parent, env); + } + else + { + return AXIS2_DEFAULT_TIMEOUT_MILLISECONDS; + } + } + + return options->timeout_in_milli_seconds; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_options_get_to( + const axis2_options_t * options, + const axutil_env_t * env) +{ + axis2_endpoint_ref_t *to = NULL; + + to = axis2_msg_info_headers_get_to(options->msg_info_headers, env); + + if(!to && options->parent) + { + return axis2_options_get_to(options->parent, env); + } + + return to; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_options_get_use_separate_listener( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(options->use_separate_listener == -1) + { + if(options->parent) + { + return axis2_options_get_use_separate_listener(options->parent, env); + } + else + { + return AXIS2_FALSE; + } + } + + return options->use_separate_listener; +} + +AXIS2_EXTERN axis2_options_t *AXIS2_CALL +axis2_options_get_parent( + const axis2_options_t * options, + const axutil_env_t * env) +{ + return options->parent; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_parent( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_options_t * parent) +{ + options->parent = (axis2_options_t *)parent; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_action( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_char_t * action) +{ + axis2_msg_info_headers_set_action(options->msg_info_headers, env, action); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_fault_to( + axis2_options_t * options, + const axutil_env_t * env, + axis2_endpoint_ref_t * fault_to) +{ + axis2_msg_info_headers_set_fault_to(options->msg_info_headers, env, fault_to); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_from( + axis2_options_t * options, + const axutil_env_t * env, + axis2_endpoint_ref_t * from) +{ + axis2_msg_info_headers_set_from(options->msg_info_headers, env, from); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_to( + axis2_options_t * options, + const axutil_env_t * env, + axis2_endpoint_ref_t * to) +{ + axis2_msg_info_headers_set_to(options->msg_info_headers, env, to); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_transport_receiver( + axis2_options_t * options, + const axutil_env_t * env, + axis2_transport_receiver_t * receiver) +{ + options->receiver = receiver; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_transport_in( + axis2_options_t * options, + const axutil_env_t * env, + axis2_transport_in_desc_t * transport_in) +{ + options->transport_in = transport_in; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_transport_in_protocol( + axis2_options_t * options, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS transport_in_protocol) +{ + options->transport_in_protocol = transport_in_protocol; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_message_id( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_char_t * message_id) +{ + axis2_msg_info_headers_set_message_id(options->msg_info_headers, env, message_id); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_properties( + axis2_options_t * options, + const axutil_env_t * env, + axutil_hash_t * properties) +{ + if(options->properties) + { + axutil_hash_free(options->properties, env); + } + options->properties = properties; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_property( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_char_t * property_key, + const void *property) +{ + axutil_hash_set(options->properties, property_key, AXIS2_HASH_KEY_STRING, property); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_relates_to( + axis2_options_t * options, + const axutil_env_t * env, + axis2_relates_to_t * relates_to) +{ + axis2_msg_info_headers_set_relates_to(options->msg_info_headers, env, relates_to); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_reply_to( + axis2_options_t * options, + const axutil_env_t * env, + axis2_endpoint_ref_t * reply_to) +{ + axis2_msg_info_headers_set_reply_to(options->msg_info_headers, env, reply_to); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_transport_out( + axis2_options_t * options, + const axutil_env_t * env, + axis2_transport_out_desc_t * transport_out) +{ + options->transport_out = transport_out; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_sender_transport( + axis2_options_t * options, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS sender_transport, + axis2_conf_t * conf) +{ + options->transport_out = axis2_conf_get_transport_out(conf, env, sender_transport); + + if(!options->transport_out) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_soap_version_uri( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_char_t * soap_version_uri) +{ + if(options->soap_version_uri) + { + AXIS2_FREE(env->allocator, options->soap_version_uri); + options->soap_version_uri = NULL; + } + + if(soap_version_uri) + { + options->soap_version_uri = axutil_strdup(env, soap_version_uri); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_timeout_in_milli_seconds( + axis2_options_t * options, + const axutil_env_t * env, + const long timeout_in_milli_seconds) +{ + options->timeout_in_milli_seconds = timeout_in_milli_seconds; + /* set the property AXIS2_HTTP_CONNECTION_TIMEOUT, + * to be picked up by http_sender + */ + if(options->timeout_in_milli_seconds > 0) + { + axis2_char_t time_str[19]; /* supports 18 digit timeout */ + axutil_property_t *property = axutil_property_create(env); + sprintf(time_str, "%ld", options->timeout_in_milli_seconds); + if(property) + { + axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_value(property, env, axutil_strdup(env, time_str)); + axis2_options_set_property(options, env, AXIS2_HTTP_CONNECTION_TIMEOUT, property); + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_transport_info( + axis2_options_t * options, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS sender_transport, + const AXIS2_TRANSPORT_ENUMS receiver_transport, + const axis2_bool_t use_separate_listener) +{ + /* + here we check for the legal combination + */ + if(!use_separate_listener) + { + if(sender_transport != receiver_transport) + { + return AXIS2_FAILURE; + } + } + else + { + axis2_options_set_use_separate_listener(options, env, use_separate_listener); + } + axis2_options_set_transport_in_protocol(options, env, receiver_transport); + options->sender_transport_protocol = sender_transport; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_use_separate_listener( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_bool_t use_separate_listener) +{ + axutil_property_t *property = NULL; + + options->use_separate_listener = use_separate_listener; + + if(use_separate_listener) + { + property = axutil_property_create(env); + axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_TRUE)); + axis2_options_set_property(options, env, AXIS2_USE_SEPARATE_LISTENER, property); + } + else + { + property = axutil_property_create(env); + axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_FALSE)); + axis2_options_set_property(options, env, AXIS2_USE_SEPARATE_LISTENER, property); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_add_reference_parameter( + axis2_options_t * options, + const axutil_env_t * env, + axiom_node_t * reference_parameter) +{ + axis2_msg_info_headers_add_ref_param(options->msg_info_headers, env, reference_parameter); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_manage_session( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_bool_t manage_session) +{ + options->manage_session = manage_session; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_options_get_manage_session( + const axis2_options_t * options, + const axutil_env_t * env) +{ + if(options->manage_session == -1) + { + if(options->parent) + { + return axis2_options_get_manage_session(options->parent, env); + } + else + { + return AXIS2_FALSE; + } + } + + return options->manage_session; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_msg_info_headers( + axis2_options_t * options, + const axutil_env_t * env, + axis2_msg_info_headers_t * msg_info_headers) +{ + if(options->msg_info_headers) + { + axis2_msg_info_headers_free(options->msg_info_headers, env); + } + + options->msg_info_headers = msg_info_headers; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_info_headers_t *AXIS2_CALL +axis2_options_get_msg_info_headers( + const axis2_options_t * options, + const axutil_env_t * env) +{ + return options->msg_info_headers; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_options_free( + axis2_options_t * options, + const axutil_env_t * env) +{ + if(options->properties) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + const void *key = NULL; + for(hi = axutil_hash_first(options->properties, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_property_t *property = NULL; + + axutil_hash_this(hi, &key, NULL, &val); + property = (axutil_property_t *)val; + + if(property) + { + axutil_property_free(property, env); + } + } + axutil_hash_free(options->properties, env); + } + + if(options->soap_version_uri) + { + AXIS2_FREE(env->allocator, options->soap_version_uri); + } + + if(options->msg_info_headers) + { + axis2_msg_info_headers_free(options->msg_info_headers, env); + } + + if(options->soap_action) + { + axutil_string_free(options->soap_action, env); + } + + AXIS2_FREE(env->allocator, options); +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_options_get_soap_version( + const axis2_options_t * options, + const axutil_env_t * env) +{ + return options->soap_version; + +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_soap_version( + axis2_options_t * options, + const axutil_env_t * env, + const int soap_version) +{ + if(soap_version == AXIOM_SOAP11) + { + options->soap_version = soap_version; + axis2_options_set_soap_version_uri(options, env, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI); + } + else + { + options->soap_version = AXIOM_SOAP12; + axis2_options_set_soap_version_uri(options, env, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_enable_mtom( + axis2_options_t * options, + const axutil_env_t * env, + axis2_bool_t enable_mtom) +{ + options->enable_mtom = enable_mtom; + + if(enable_mtom) + { + axutil_property_t *property = axutil_property_create(env); + if(property) + { + axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_TRUE)); + axis2_options_set_property(options, env, AXIS2_ENABLE_MTOM, property); + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_options_get_enable_mtom( + const axis2_options_t * options, + const axutil_env_t * env) +{ + return options->enable_mtom; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axis2_options_get_soap_action( + const axis2_options_t * options, + const axutil_env_t * env) +{ + return options->soap_action; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_soap_action( + axis2_options_t * options, + const axutil_env_t * env, + axutil_string_t * soap_action) +{ + if(options->soap_action) + { + axutil_string_free(options->soap_action, env); + options->soap_action = NULL; + } + + if(soap_action) + { + options->soap_action = axutil_string_clone(soap_action, env); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_options_get_xml_parser_reset( + const axis2_options_t * options, + const axutil_env_t * env) +{ + return options->xml_parser_reset; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_xml_parser_reset( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_bool_t xml_parser_reset) +{ + options->xml_parser_reset = xml_parser_reset; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_enable_rest( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_bool_t enable_rest) +{ + axutil_property_t *rest_property = NULL; + + if(enable_rest) + { + rest_property = axutil_property_create(env); + axutil_property_set_value(rest_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE)); + axis2_options_set_property(options, env, AXIS2_ENABLE_REST, rest_property); + } + else + { + rest_property = axutil_property_create(env); + axutil_property_set_value(rest_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE)); + axis2_options_set_property(options, env, AXIS2_ENABLE_REST, rest_property); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_test_http_auth( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_bool_t test_http_auth) +{ + axutil_property_t *test_auth_property = NULL; + + if(test_http_auth) + { + test_auth_property = axutil_property_create(env); + axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE)); + axis2_options_set_property(options, env, AXIS2_TEST_HTTP_AUTH, test_auth_property); + } + else + { + test_auth_property = axutil_property_create(env); + axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE)); + axis2_options_set_property(options, env, AXIS2_TEST_HTTP_AUTH, test_auth_property); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_test_proxy_auth( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_bool_t test_proxy_auth) +{ + axutil_property_t *test_auth_property = NULL; + + if(test_proxy_auth) + { + test_auth_property = axutil_property_create(env); + axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE)); + axis2_options_set_property(options, env, AXIS2_TEST_PROXY_AUTH, test_auth_property); + } + else + { + test_auth_property = axutil_property_create(env); + axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE)); + axis2_options_set_property(options, env, AXIS2_TEST_PROXY_AUTH, test_auth_property); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_http_method( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_char_t * http_method) +{ + axutil_property_t *method_property = NULL; + + method_property = axutil_property_create(env); + axutil_property_set_value(method_property, env, axutil_strdup(env, http_method)); + axis2_options_set_property(options, env, AXIS2_HTTP_METHOD, method_property); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_http_headers( + axis2_options_t * options, + const axutil_env_t * env, + axutil_array_list_t * http_header_list) +{ + axutil_property_t *headers_property = NULL; + + headers_property = axutil_property_create(env); + axutil_property_set_value(headers_property, env, http_header_list); + axis2_options_set_property(options, env, AXIS2_TRANSPORT_HEADER_PROPERTY, headers_property); + axutil_property_set_free_func(headers_property, env, axutil_array_list_free_void_arg); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_proxy_auth_info( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_char_t * username, + const axis2_char_t * password, + const axis2_char_t * auth_type) +{ + axis2_bool_t force_proxy_auth = AXIS2_FALSE; + axutil_property_t *prop_pw = NULL; + axutil_property_t *prop_un = NULL; + + prop_un = axutil_property_create(env); + axutil_property_set_value(prop_un, env, axutil_strdup(env, username)); + axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_UNAME, prop_un); + + prop_pw = axutil_property_create(env); + axutil_property_set_value(prop_pw, env, axutil_strdup(env, password)); + axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_PASSWD, prop_pw); + + if(auth_type) + { + if((axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0) || (axutil_strcasecmp( + auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0)) + { + force_proxy_auth = AXIS2_TRUE; + } + } + if(force_proxy_auth) + { + axutil_property_t *proxy_auth_property = axutil_property_create(env); + axutil_property_t *proxy_auth_type_property = axutil_property_create(env); + + axutil_property_set_value(proxy_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE)); + axis2_options_set_property(options, env, AXIS2_FORCE_PROXY_AUTH, proxy_auth_property); + + axutil_property_set_value(proxy_auth_type_property, env, axutil_strdup(env, auth_type)); + axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_TYPE, proxy_auth_type_property); + } + else + { + axutil_property_t *proxy_auth_property = axutil_property_create(env); + axutil_property_set_value(proxy_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE)); + axis2_options_set_property(options, env, AXIS2_FORCE_PROXY_AUTH, proxy_auth_property); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_options_set_http_auth_info( + axis2_options_t * options, + const axutil_env_t * env, + const axis2_char_t * username, + const axis2_char_t * password, + const axis2_char_t * auth_type) +{ + axis2_bool_t force_http_auth = AXIS2_FALSE; + axutil_property_t *prop_un = NULL; + axutil_property_t *prop_pw = NULL; + + prop_un = axutil_property_create(env); + axutil_property_set_value(prop_un, env, axutil_strdup(env, username)); + axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_UNAME, prop_un); + + prop_pw = axutil_property_create(env); + axutil_property_set_value(prop_pw, env, axutil_strdup(env, password)); + axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_PASSWD, prop_pw); + + if(auth_type) + { + if((axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0) || (axutil_strcasecmp( + auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0)) + { + force_http_auth = AXIS2_TRUE; + } + } + if(force_http_auth) + { + axutil_property_t *http_auth_property = axutil_property_create(env); + axutil_property_t *http_auth_type_property = axutil_property_create(env); + + axutil_property_set_value(http_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE)); + axis2_options_set_property(options, env, AXIS2_FORCE_HTTP_AUTH, http_auth_property); + + axutil_property_set_value(http_auth_type_property, env, axutil_strdup(env, auth_type)); + axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_TYPE, http_auth_type_property); + } + else + { + axutil_property_t *http_auth_property = axutil_property_create(env); + axutil_property_set_value(http_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE)); + axis2_options_set_property(options, env, AXIS2_FORCE_HTTP_AUTH, http_auth_property); + } + return AXIS2_SUCCESS; +} + diff --git a/src/core/clientapi/stub.c b/src/core/clientapi/stub.c new file mode 100644 index 0000000..2b27274 --- /dev/null +++ b/src/core/clientapi/stub.c @@ -0,0 +1,228 @@ +/* + * 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_stub.h> + +struct axis2_stub +{ + axis2_svc_client_t *svc_client; + axis2_options_t *options; +}; + +AXIS2_EXTERN axis2_stub_t *AXIS2_CALL +axis2_stub_create( + const axutil_env_t * env) +{ + axis2_stub_t *stub = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + stub = (axis2_stub_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_stub_t)); + + if(!stub) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create stub."); + return NULL; + } + stub->svc_client = NULL; + stub->options = NULL; + + return stub; +} + +AXIS2_EXTERN axis2_stub_t *AXIS2_CALL +axis2_stub_create_with_endpoint_ref_and_client_home( + const axutil_env_t * env, + axis2_endpoint_ref_t * endpoint_ref, + const axis2_char_t * client_home) +{ + axis2_stub_t *stub = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, endpoint_ref, NULL); + + stub = (axis2_stub_t *)axis2_stub_create(env); + + if(!stub) + { + return NULL; + } + + stub->svc_client = axis2_svc_client_create(env, client_home); + + if(!stub->svc_client) + { + axis2_stub_free(stub, env); + return NULL; + } + + stub->options = axis2_options_create(env); + if(!stub->options) + { + axis2_stub_free(stub, env); + return NULL; + } + + axis2_svc_client_set_options(stub->svc_client, env, stub->options); + + axis2_options_set_to(stub->options, env, endpoint_ref); + + return stub; +} + +AXIS2_EXTERN axis2_stub_t *AXIS2_CALL +axis2_stub_create_with_endpoint_uri_and_client_home( + const axutil_env_t * env, + const axis2_char_t * endpoint_uri, + const axis2_char_t * client_home) +{ + axis2_stub_t *stub = NULL; + axis2_endpoint_ref_t *endpoint_ref = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, endpoint_uri, NULL); + + endpoint_ref = axis2_endpoint_ref_create(env, endpoint_uri); + if(!endpoint_ref) + { + return NULL; + } + stub = (axis2_stub_t *)axis2_stub_create_with_endpoint_ref_and_client_home(env, endpoint_ref, + client_home); + + if(!stub) + { + return NULL; + } + + return stub; +} + +void AXIS2_CALL +axis2_stub_free( + axis2_stub_t * stub, + const axutil_env_t * env) +{ + if(stub) + { + if(stub->svc_client) + { + axis2_svc_client_free(stub->svc_client, env); + } + + AXIS2_FREE(env->allocator, stub); + } +} + +axis2_status_t AXIS2_CALL +axis2_stub_set_endpoint_ref( + axis2_stub_t * stub, + const axutil_env_t * env, + axis2_endpoint_ref_t * endpoint_ref) +{ + AXIS2_PARAM_CHECK(env->error, endpoint_ref, AXIS2_FAILURE); + axis2_options_set_to(stub->options, env, endpoint_ref); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_stub_set_endpoint_uri( + axis2_stub_t * stub, + const axutil_env_t * env, + const axis2_char_t * endpoint_uri) +{ + axis2_endpoint_ref_t *endpoint_ref = NULL; + + AXIS2_PARAM_CHECK(env->error, endpoint_uri, AXIS2_FAILURE); + + endpoint_ref = axis2_endpoint_ref_create(env, endpoint_uri); + if(!endpoint_ref) + { + return AXIS2_FAILURE; + } + axis2_options_set_to(stub->options, env, endpoint_ref); + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_stub_set_use_separate_listener( + axis2_stub_t * stub, + const axutil_env_t * env, + const axis2_bool_t use_separate_listener) +{ + return axis2_options_set_use_separate_listener(stub->options, env, use_separate_listener); +} + +axis2_status_t AXIS2_CALL +axis2_stub_engage_module( + axis2_stub_t * stub, + const axutil_env_t * env, + const axis2_char_t * module_name) +{ + AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE); + + return axis2_svc_client_engage_module(stub->svc_client, env, module_name); +} + +axis2_status_t AXIS2_CALL +axis2_stub_set_soap_version( + axis2_stub_t * stub, + const axutil_env_t * env, + const int soap_version) +{ + if(!stub->options) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Cannot set soap version. Stub option is not valid."); + return AXIS2_FAILURE; + } + return axis2_options_set_soap_version(stub->options, env, soap_version); +} + +const axis2_char_t *AXIS2_CALL +axis2_stub_get_svc_ctx_id( + const axis2_stub_t * stub, + const axutil_env_t * env) +{ + const axis2_svc_ctx_t *svc_ctx = NULL; + const axis2_char_t *svc_ctx_id = NULL; + + AXIS2_PARAM_CHECK(env->error, stub, NULL); + + svc_ctx = axis2_svc_client_get_svc_ctx(stub->svc_client, env); + svc_ctx_id = axis2_svc_ctx_get_svc_id(svc_ctx, env); + return svc_ctx_id; +} + +axis2_svc_client_t *AXIS2_CALL +axis2_stub_get_svc_client( + const axis2_stub_t * stub, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, stub, NULL); + return stub->svc_client; +} + +axis2_options_t *AXIS2_CALL +axis2_stub_get_options( + const axis2_stub_t * stub, + const axutil_env_t * env) +{ + return stub->options; +} diff --git a/src/core/clientapi/svc_client.c b/src/core/clientapi/svc_client.c new file mode 100644 index 0000000..d25f340 --- /dev/null +++ b/src/core/clientapi/svc_client.c @@ -0,0 +1,1624 @@ +/* + * 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_svc_client.h> +#include <axis2_phases_info.h> +#include <axis2_const.h> +#include <axutil_hash.h> +#include <axutil_uri.h> +#include "axis2_callback_recv.h" +#include <axiom_soap_const.h> +#include <axiom_soap_body.h> +#include <axiom_soap_header.h> +#include <axiom_util.h> +#include <axis2_listener_manager.h> +#include <axis2_module_desc.h> +#include <axutil_array_list.h> +#include <axis2_options.h> +#include <axis2_conf_init.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <stdio.h> +#include <axutil_generic_obj.h> +#include <axis2_http_transport.h> +#include <axis2_http_header.h> +#include <neethi_util.h> +#include <axis2_policy_include.h> + +struct axis2_svc_client +{ + axis2_svc_t *svc; + + axis2_conf_t *conf; + + axis2_conf_ctx_t *conf_ctx; + + axis2_svc_ctx_t *svc_ctx; + + axis2_options_t *options; + + axis2_options_t *override_options; + + /* SOAP Headers */ + axutil_array_list_t *headers; + + /* for receiving the async messages */ + axis2_callback_recv_t *callback_recv; + + axis2_listener_manager_t *listener_manager; + + axis2_op_client_t *op_client; + + axiom_soap_envelope_t *last_response_soap_envelope; + + axis2_bool_t last_response_has_fault; + + axis2_bool_t reuse; + + axis2_bool_t auth_failed; + + axis2_bool_t required_auth_is_http; + + axis2_char_t *auth_type; + + axutil_array_list_t *http_headers; + + int http_status_code; + + axis2_bool_t keep_externally_passed_ctx_and_svc; + +}; + +static void +axis2_svc_client_set_http_info( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +static axis2_svc_t * +axis2_svc_client_create_annonymous_svc( + axis2_svc_client_t * svc_client, + const axutil_env_t * env); + +static axis2_bool_t +axis2_svc_client_init_transports_from_conf_ctx( + const axutil_env_t * env, + axis2_svc_client_t * svc_client, + axis2_conf_ctx_t * conf_ctx, + const axis2_char_t * client_home); + +static axis2_bool_t +axis2_svc_client_init_data( + const axutil_env_t * env, + axis2_svc_client_t * svc_client); + +static axis2_bool_t +axis2_svc_client_fill_soap_envelope( + const axutil_env_t * env, + axis2_svc_client_t * svc_client, + axis2_msg_ctx_t * msg_ctx, + const axiom_node_t * payload); + +AXIS2_EXTERN axis2_svc_client_t *AXIS2_CALL +axis2_svc_client_create( + const axutil_env_t * env, + const axis2_char_t * client_home) +{ + axis2_svc_client_t *svc_client = NULL; + + AXIS2_ENV_CHECK(env, NULL); + svc_client = axis2_svc_client_create_with_conf_ctx_and_svc(env, client_home, NULL, NULL); + + return svc_client; +} + +AXIS2_EXTERN axis2_svc_client_t *AXIS2_CALL +axis2_svc_client_create_with_conf_ctx_and_svc( + const axutil_env_t * env, + const axis2_char_t * client_home, + axis2_conf_ctx_t * conf_ctx, + axis2_svc_t * svc) +{ + axis2_svc_client_t *svc_client = NULL; + axis2_svc_grp_t *svc_grp = NULL; + axis2_svc_grp_ctx_t *svc_grp_ctx = NULL; + const axis2_char_t *svc_grp_name = NULL; + + svc_client = AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_client_t)); + if(!svc_client) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create service client."); + return NULL; + } + + svc_client->svc = NULL; + svc_client->conf = NULL; + svc_client->conf_ctx = NULL; + svc_client->svc_ctx = NULL; + svc_client->options = NULL; + svc_client->override_options = NULL; + svc_client->headers = NULL; + svc_client->callback_recv = NULL; + svc_client->listener_manager = NULL; + svc_client->op_client = NULL; + svc_client->last_response_soap_envelope = NULL; + svc_client->last_response_has_fault = AXIS2_FALSE; + svc_client->reuse = AXIS2_FALSE; + svc_client->auth_failed = AXIS2_FALSE; + svc_client->required_auth_is_http = AXIS2_FALSE; + svc_client->auth_type = NULL; + svc_client->http_headers = NULL; + svc_client->keep_externally_passed_ctx_and_svc = AXIS2_FALSE; + + if(!axis2_svc_client_init_data(env, svc_client)) + { + axis2_svc_client_free(svc_client, env); + return NULL; + } + + /*create the default conf_ctx if it is NULL */ + if(!axis2_svc_client_init_transports_from_conf_ctx(env, svc_client, conf_ctx, client_home)) + { + axis2_svc_client_free(svc_client, env); + return NULL; + } + + svc_client->conf = axis2_conf_ctx_get_conf(svc_client->conf_ctx, env); + + if(svc) + { + svc_client->keep_externally_passed_ctx_and_svc = AXIS2_TRUE; + svc_client->svc = svc; + } + else + { + svc_client->svc = axis2_svc_client_create_annonymous_svc(svc_client, env); + if(!svc_client->svc) + { + axis2_svc_client_free(svc_client, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create annonymous service."); + return NULL; + } + } + + /** add the service to the config context if it isn't in there already */ + if(!axis2_conf_get_svc(svc_client->conf, env, axis2_svc_get_name(svc_client->svc, env))) + { + axis2_conf_add_svc(svc_client->conf, env, svc_client->svc); + } + + /** create a service context for myself: create a new service group + context and then get the service context for myself as I'll need that + later for stuff that I gotta do */ + svc_grp = axis2_svc_get_parent(svc_client->svc, env); + if(!svc_grp) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot access service group of service client."); + return NULL; + } + + svc_grp_ctx = axis2_svc_grp_get_svc_grp_ctx(svc_grp, env, svc_client->conf_ctx); + if(!svc_grp_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Cannot access service group context of service client."); + return NULL; + } + + svc_grp_name = axis2_svc_grp_get_name(svc_grp, env); + if(!svc_grp_name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Cannot access service group name of service client."); + return NULL; /* service group name is mandatory */ + } + + axis2_conf_ctx_register_svc_grp_ctx(svc_client->conf_ctx, env, svc_grp_name, svc_grp_ctx); + + svc_client->svc_ctx = axis2_svc_grp_ctx_get_svc_ctx(svc_grp_ctx, env, axis2_svc_get_name( + svc_client->svc, env)); + + return svc_client; +} + +AXIS2_EXTERN axis2_svc_t *AXIS2_CALL +axis2_svc_client_get_svc( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + return svc_client->svc; +} + +AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL +axis2_svc_client_get_conf_ctx( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + return svc_client->conf_ctx; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_set_options( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axis2_options_t * options) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + if(svc_client->options) + { + axis2_options_free(svc_client->options, env); + } + svc_client->options = (axis2_options_t *)options; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_options_t *AXIS2_CALL +axis2_svc_client_get_options( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + return svc_client->options; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_set_override_options( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axis2_options_t * override_options) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + if(svc_client->override_options) + { + axis2_options_free(svc_client->override_options, env); + } + + svc_client->override_options = (axis2_options_t *)override_options; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_options_t *AXIS2_CALL +axis2_svc_client_get_override_options( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + return svc_client->override_options; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_engage_module( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axis2_char_t * module_name) +{ + axis2_module_desc_t *module = NULL; + axutil_qname_t *mod_qname = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE); + + mod_qname = axutil_qname_create(env, module_name, NULL, NULL); + + if(!mod_qname) + { + return AXIS2_FAILURE; + } + + module = axis2_conf_get_module(svc_client->conf, env, mod_qname); + + axutil_qname_free(mod_qname, env); + mod_qname = NULL; + + if(module) + { + return axis2_svc_engage_module(svc_client->svc, env, module, svc_client->conf); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_disengage_module( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axis2_char_t * module_name) +{ + axis2_module_desc_t *module = NULL; + axutil_qname_t *mod_qname = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE); + + mod_qname = axutil_qname_create(env, module_name, NULL, NULL); + if(!mod_qname) + { + return AXIS2_FAILURE; + } + + module = axis2_conf_get_module(svc_client->conf, env, mod_qname); + axutil_qname_free(mod_qname, env); + mod_qname = NULL; + + if(module) + { + return axis2_svc_disengage_module(svc_client->svc, env, module, svc_client->conf); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_add_header( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + axiom_node_t * header) +{ + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + if(!svc_client->headers) + { + svc_client->headers = axutil_array_list_create(env, 0); + if(!svc_client->headers) + { + return AXIS2_FAILURE; + } + } + axutil_array_list_add(svc_client->headers, env, header); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_remove_all_headers( + axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + int i = 0; + int size = 0; + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + + if(!svc_client->headers) + { + return AXIS2_SUCCESS; + } + + size = axutil_array_list_size(svc_client->headers, env); + + for(i = size - 1; i > -1; i--) + { + axutil_array_list_remove(svc_client->headers, env, i); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_send_robust_with_op_qname( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axutil_qname_t * op_qname, + const axiom_node_t * payload) +{ + axis2_msg_ctx_t *msg_ctx = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_bool_t qname_free_flag = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + + if(!op_qname) + { + op_qname = axutil_qname_create(env, AXIS2_ANON_ROBUST_OUT_ONLY_OP, NULL, NULL); + if(!op_qname) + { + return AXIS2_FAILURE; + } + qname_free_flag = AXIS2_TRUE; + } + else + { + axis2_op_t *op = NULL; + axis2_char_t *mep = NULL; + axis2_svc_t *svc = NULL; + svc = axis2_svc_client_get_svc(svc_client, env); + if(!svc) + { + return AXIS2_FAILURE; + } + op = axis2_svc_get_op_with_qname(svc, env, op_qname); + if(!op) + { + return AXIS2_FAILURE; + } + mep = (axis2_char_t *)axis2_op_get_msg_exchange_pattern(op, env); + if(!mep || axutil_strcmp(AXIS2_MEP_URI_OUT_ONLY, mep) != 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s%s", + "To use this method opeation uri should be", AXIS2_MEP_URI_OUT_ONLY); + return AXIS2_FAILURE; + } + } + + svc_client->auth_failed = AXIS2_FALSE; + svc_client->required_auth_is_http = AXIS2_FALSE; + if(svc_client->auth_type) + { + AXIS2_FREE(env->allocator, svc_client->auth_type); + } + svc_client->auth_type = NULL; + + msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env), NULL, + NULL); + if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload)) + { + return AXIS2_FAILURE; + } + + if(!axis2_svc_client_create_op_client(svc_client, env, op_qname)) + { + return AXIS2_FAILURE; + } + + axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx); + status = axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE); + axis2_svc_client_set_http_info(svc_client, env, msg_ctx); + svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env); + svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env); + if(axis2_msg_ctx_get_auth_type(msg_ctx, env)) + { + svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env)); + } + + if(qname_free_flag) + { + axutil_qname_free((axutil_qname_t *)op_qname, env); + } + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_send_robust( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axiom_node_t * payload) +{ + return axis2_svc_client_send_robust_with_op_qname(svc_client, env, NULL, payload); +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_client_fire_and_forget_with_op_qname( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axutil_qname_t * op_qname, + const axiom_node_t * payload) +{ + axis2_msg_ctx_t *msg_ctx = NULL; + axis2_bool_t qname_free_flag = AXIS2_FALSE; + + AXIS2_PARAM_CHECK_VOID(env->error, svc_client); + + if(!op_qname) + { + op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_ONLY_OP, NULL, NULL); + if(!op_qname) + { + return; + } + qname_free_flag = AXIS2_TRUE; + } + + svc_client->auth_failed = AXIS2_FALSE; + svc_client->required_auth_is_http = AXIS2_FALSE; + if(svc_client->auth_type) + { + AXIS2_FREE(env->allocator, svc_client->auth_type); + } + svc_client->auth_type = NULL; + + msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env), NULL, + NULL); + if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload)) + { + return; + } + + if(!axis2_svc_client_create_op_client(svc_client, env, op_qname)) + { + return; + } + + axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx); + axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE); + axis2_svc_client_set_http_info(svc_client, env, msg_ctx); + svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env); + svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env); + if(axis2_msg_ctx_get_auth_type(msg_ctx, env)) + { + svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env)); + } + + if(qname_free_flag) + { + axutil_qname_free((axutil_qname_t *)op_qname, env); + } +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_client_fire_and_forget( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axiom_node_t * payload) +{ + axis2_svc_client_fire_and_forget_with_op_qname(svc_client, env, NULL, payload); +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axis2_svc_client_send_receive_with_op_qname( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axutil_qname_t * op_qname, + const axiom_node_t * payload) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_soap_body_t *soap_body = NULL; + axiom_node_t *soap_node = NULL; + axis2_op_t *op = NULL; + axutil_param_t *param = NULL; + axutil_uri_t *action_uri = NULL; + axis2_char_t *action_str = NULL; + axis2_bool_t qname_free_flag = AXIS2_FALSE; + + axis2_msg_ctx_t *res_msg_ctx = NULL; + axis2_msg_ctx_t *msg_ctx = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + + svc_client->last_response_soap_envelope = NULL; + svc_client->last_response_has_fault = AXIS2_FALSE; + svc_client->auth_failed = AXIS2_FALSE; + svc_client->required_auth_is_http = AXIS2_FALSE; + if(svc_client->auth_type) + { + AXIS2_FREE(env->allocator, svc_client->auth_type); + } + svc_client->auth_type = NULL; + + op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname); + if(op) + { + param = axis2_op_get_param(op, env, AXIS2_SOAP_ACTION); + if(param) + { + action_uri = (axutil_uri_t *)axutil_param_get_value(param, env); + action_str = axutil_uri_to_string(action_uri, env, AXIS2_URI_UNP_OMITUSERINFO); + axis2_options_set_action(svc_client->options, env, action_str); + } + } + + if(!op_qname) + { + op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL); + if(!op_qname) + return NULL; + + qname_free_flag = AXIS2_TRUE; + } + + /* If dual channel blocking. We come to this block if the client indicate to use + * a separate listener but don't provide a callback function to acted upon when + * response is received in the listener thread. What we do here is we create a callback + * and call axis2_svc_client_send_receive_non_blocking_with_op_qname with it. */ + if(axis2_options_get_use_separate_listener(svc_client->options, env)) + { + axis2_callback_t *callback = NULL; + axis2_msg_ctx_t *msg_ctx = NULL; + long index = 0; + + /* This means doing a Request-Response invocation using two channels. + If the transport is a two way transport (e.g. http), only one channel is used + (e.g. in http cases 202 OK is sent to say no response available). + Axis2 gets blocked and return when the response is available. */ + + callback = axis2_callback_create(env); + if(!callback) + { + return NULL; + } + + /* Call two channel non blocking invoke to do the work and wait on the callback. We don't + * set a callback function for the callback. That functionality is handled here. + */ + axis2_svc_client_send_receive_non_blocking_with_op_qname(svc_client, env, op_qname, + payload, callback); + + index = axis2_options_get_timeout_in_milli_seconds(svc_client->options, env) / 10; + + while(!axis2_callback_get_complete(callback, env)) + { + if(index-- >= 0) + { + AXIS2_USLEEP(10000); + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response time out."); + return NULL; + } + } + + soap_envelope = axis2_callback_get_envelope(callback, env); + msg_ctx = axis2_callback_get_msg_ctx(callback, env); + axis2_op_client_add_in_msg_ctx(svc_client->op_client, env, msg_ctx); + + /* start of hack to get rid of memory leak */ + /*msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client-> svc_ctx, env), + NULL, NULL); + if(!msg_ctx) + return NULL; + + axis2_op_client_add_in_msg_ctx(svc_client->op_client, env, msg_ctx); + + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);*/ + /* end of hack to get rid of memory leak */ + + /* process the result of the invocation */ + if(!soap_envelope) + { + if(axis2_callback_get_error(callback, env) != AXIS2_ERROR_NONE) + { + AXIS2_ERROR_SET(env->error, axis2_callback_get_error(callback, env), AXIS2_FAILURE); + return NULL; + } + } + } + else + { + msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env), + NULL, NULL); + if(!msg_ctx) + return NULL; + + if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload)) + { + return NULL; + } + + if(!axis2_svc_client_create_op_client(svc_client, env, op_qname)) + { + return NULL; + } + + axis2_op_client_add_msg_ctx(svc_client->op_client, env, msg_ctx); + axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE); + axis2_svc_client_set_http_info(svc_client, env, msg_ctx); + svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env); + svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env); + if(axis2_msg_ctx_get_auth_type(msg_ctx, env)) + { + svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env)); + } + res_msg_ctx = (axis2_msg_ctx_t *)axis2_op_client_get_msg_ctx(svc_client-> op_client, env, + AXIS2_WSDL_MESSAGE_LABEL_IN); + + if(res_msg_ctx) + { + soap_envelope = axis2_msg_ctx_get_soap_envelope(res_msg_ctx, env); + } + else + { + axis2_op_client_add_msg_ctx(svc_client->op_client, env, res_msg_ctx); + /* set in msg_ctx to be NULL to reset */ + } + } + + if(qname_free_flag) + { + axutil_qname_free((axutil_qname_t *)op_qname, env); + } + + if(!soap_envelope) + { + return NULL; + } + svc_client->last_response_soap_envelope = soap_envelope; + + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + + if(!soap_body) + { + axiom_node_t *node = axiom_soap_envelope_get_base_node(soap_envelope, env); + if(node) + { + axiom_element_t *envelope_element = (axiom_element_t *)axiom_node_get_data_element( + node, env); + axiom_util_get_first_child_element_with_localname(envelope_element, env, node, + AXIOM_SOAP_BODY_LOCAL_NAME, &soap_node); + if(soap_node) + { + return axiom_node_get_first_element(soap_node, env); + } + } + return NULL; + } + + if(axis2_msg_ctx_get_doing_rest(res_msg_ctx, env)) + { + /* All HTTP 4xx and 5xx status codes are treated as errors */ + if(axis2_msg_ctx_get_status_code(res_msg_ctx, env) >= 400) + { + svc_client->last_response_has_fault = AXIS2_TRUE; + } + else + { + svc_client->last_response_has_fault = AXIS2_FALSE; + } + } + else + { + svc_client->last_response_has_fault = axiom_soap_body_has_fault(soap_body, env); + } + + if(AXIOM_SOAP11 == axiom_soap_envelope_get_soap_version(soap_envelope, env)) + { + axiom_soap_body_convert_fault_to_soap11(soap_body, env); + } + + soap_node = axiom_soap_body_get_base_node(soap_body, env); + if(!soap_node) + { + return NULL; + } + return axiom_node_get_first_element(soap_node, env); +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axis2_svc_client_send_receive( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axiom_node_t * payload) +{ + return axis2_svc_client_send_receive_with_op_qname(svc_client, env, NULL, payload); +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_client_send_receive_non_blocking_with_op_qname( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axutil_qname_t * op_qname, + const axiom_node_t * payload, + axis2_callback_t * callback) +{ + axis2_msg_ctx_t *msg_ctx = NULL; + AXIS2_TRANSPORT_ENUMS transport_in_protocol; + axis2_bool_t qname_free_flag = AXIS2_FALSE; + + AXIS2_PARAM_CHECK_VOID(env->error, svc_client); + + if(!op_qname) + { + op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL); + if(!op_qname) + return; + qname_free_flag = AXIS2_TRUE; + } + + svc_client->auth_failed = AXIS2_FALSE; + svc_client->required_auth_is_http = AXIS2_FALSE; + if(svc_client->auth_type) + { + AXIS2_FREE(env->allocator, svc_client->auth_type); + } + svc_client->auth_type = NULL; + + msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client-> svc_ctx, env), + NULL, NULL); + if(!msg_ctx) + return; + + if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload)) + { + return; + } + + if(!axis2_svc_client_create_op_client(svc_client, env, op_qname)) + { + return; + } + + axis2_op_client_set_callback(svc_client->op_client, env, callback); + axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx); + + /* If dual channel */ + if(axis2_options_get_use_separate_listener(svc_client->options, env)) + { + axis2_op_t *op = NULL; + + transport_in_protocol = axis2_options_get_transport_in_protocol(svc_client->options, env); + if(transport_in_protocol == AXIS2_TRANSPORT_ENUM_MAX) + { + axis2_options_set_transport_in_protocol(svc_client->options, env, + AXIS2_TRANSPORT_ENUM_HTTP); + transport_in_protocol = AXIS2_TRANSPORT_ENUM_HTTP; + } + axis2_listener_manager_make_sure_started(svc_client->listener_manager, env, + transport_in_protocol, svc_client->conf_ctx); + /* Following sleep is required to ensure the listener is ready to receive response. + If it is missing, the response gets lost. - Samisa */ + AXIS2_USLEEP(1); + + op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname); + /* At the end of the incoming flow this message receiver will be hit */ + axis2_op_set_msg_recv(op, env, + AXIS2_CALLBACK_RECV_GET_BASE(svc_client-> callback_recv, env)); + axis2_op_client_set_callback_recv(svc_client->op_client, env, svc_client->callback_recv); + } + + axis2_op_client_execute(svc_client->op_client, env, AXIS2_FALSE); + axis2_svc_client_set_http_info(svc_client, env, msg_ctx); + svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env); + svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env); + if(axis2_msg_ctx_get_auth_type(msg_ctx, env)) + { + svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env)); + } + + if(qname_free_flag) + { + axutil_qname_free((axutil_qname_t *)op_qname, env); + op_qname = NULL; + } +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_client_send_receive_non_blocking( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axiom_node_t * payload, + axis2_callback_t * callback) +{ + axis2_svc_client_send_receive_non_blocking_with_op_qname(svc_client, env, NULL, payload, + callback); +} + +AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL +axis2_svc_client_create_op_client( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axutil_qname_t * op_qname) +{ + axis2_op_t *op = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + + op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname); + + if(!op) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find operation to create op client."); + return NULL; + } + + if(!(svc_client->op_client) || svc_client->reuse) + { + if((svc_client->reuse) && (svc_client->op_client)) + axis2_op_client_free(svc_client->op_client, env); + svc_client->op_client = axis2_op_client_create(env, op, svc_client->svc_ctx, + svc_client->options); + } + + /** + If override options have been set, that means we need to make sure + those options override the options of even the operation client. So, + what we do is switch the parents around to make that work. + */ + if(svc_client->override_options) + { + axis2_options_set_parent(svc_client->override_options, env, axis2_op_client_get_options( + svc_client-> op_client, env)); + axis2_op_client_set_options(svc_client->op_client, env, svc_client->override_options); + } + svc_client->reuse = AXIS2_TRUE; + axis2_op_client_set_reuse(svc_client->op_client, env, svc_client->reuse); + return svc_client->op_client; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_finalize_invoke( + axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_TRANSPORT_ENUMS transport_in_protocol; + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + + transport_in_protocol = axis2_options_get_transport_in_protocol(svc_client->options, env); + + if(svc_client->listener_manager) + { + return axis2_listener_manager_stop(svc_client->listener_manager, env, transport_in_protocol); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_endpoint_ref_t *AXIS2_CALL +axis2_svc_client_get_own_endpoint_ref( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env, + const axis2_char_t * transport) +{ + return NULL; +} + +AXIS2_EXTERN const axis2_endpoint_ref_t *AXIS2_CALL +axis2_svc_client_get_target_endpoint_ref( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_set_target_endpoint_ref( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + axis2_endpoint_ref_t * target_endpoint_ref) +{ + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL +axis2_svc_client_get_svc_ctx( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + return svc_client->svc_ctx; +} + +static axis2_bool_t +axis2_svc_client_init_transports_from_conf_ctx( + const axutil_env_t * env, + axis2_svc_client_t * svc_client, + axis2_conf_ctx_t * conf_ctx, + const axis2_char_t * client_home) +{ + svc_client->conf_ctx = conf_ctx; + if(!svc_client->conf_ctx) + { + svc_client->conf_ctx = axis2_build_client_conf_ctx(env, client_home); + if(!svc_client->conf_ctx) + { + return AXIS2_FALSE; + } + } + else + { + svc_client->keep_externally_passed_ctx_and_svc = AXIS2_TRUE; + } + + if(!svc_client->listener_manager) + { + svc_client->listener_manager = axis2_listener_manager_create(env); + if(!svc_client->listener_manager) + { + return AXIS2_FALSE; + } + } + + return AXIS2_TRUE; +} + +static axis2_bool_t +axis2_svc_client_init_data( + const axutil_env_t * env, + axis2_svc_client_t * svc_client) +{ + svc_client->svc = NULL; + svc_client->conf_ctx = NULL; + svc_client->svc_ctx = NULL; + + svc_client->options = axis2_options_create(env); + if(!svc_client->options) + { + return AXIS2_FALSE; + } + + svc_client->override_options = NULL; + svc_client->headers = NULL; + + if(svc_client->callback_recv) + { + AXIS2_CALLBACK_RECV_FREE(svc_client->callback_recv, env); + svc_client->callback_recv = NULL; + } + + svc_client->callback_recv = axis2_callback_recv_create(env); + if(!svc_client->callback_recv) + { + return AXIS2_FALSE; + } + + return AXIS2_TRUE; +} + +static axis2_svc_t * +axis2_svc_client_create_annonymous_svc( + axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + + /** + now add anonymous operations to the axis2 service for use with the + shortcut client API. NOTE: We only add the ones we know we'll use + later in the convenience API; if you use + this constructor then you can't expect any magic! + */ + axutil_qname_t *tmp_qname; + axis2_svc_t *svc; + axis2_op_t *op_out_in, *op_out_only, *op_robust_out_only; + axis2_phases_info_t *info = NULL; + + tmp_qname = axutil_qname_create(env, AXIS2_ANON_SERVICE, NULL, NULL); + if(!tmp_qname) + { + return NULL; + } + + svc = axis2_svc_create_with_qname(env, tmp_qname); + axutil_qname_free(tmp_qname, env); + if(!svc) + { + return NULL; + } + + tmp_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL); + if(!tmp_qname) + { + return NULL; + } + op_out_in = axis2_op_create_with_qname(env, tmp_qname); + axutil_qname_free(tmp_qname, env); + + tmp_qname = axutil_qname_create(env, AXIS2_ANON_OUT_ONLY_OP, NULL, NULL); + if(!tmp_qname) + { + return NULL; + } + op_out_only = axis2_op_create_with_qname(env, tmp_qname); + axutil_qname_free(tmp_qname, env); + + tmp_qname = axutil_qname_create(env, AXIS2_ANON_ROBUST_OUT_ONLY_OP, NULL, NULL); + if(!tmp_qname) + { + return NULL; + } + op_robust_out_only = axis2_op_create_with_qname(env, tmp_qname); + axutil_qname_free(tmp_qname, env); + + if(!op_out_in || !op_out_only || !op_robust_out_only) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + if(op_out_in) + { + axis2_op_free(op_out_in, env); + } + if(op_out_only) + { + axis2_op_free(op_out_only, env); + } + if(op_robust_out_only) + { + axis2_op_free(op_robust_out_only, env); + } + + return NULL; + } + + axis2_op_set_msg_exchange_pattern(op_out_in, env, AXIS2_MEP_URI_OUT_IN); + axis2_op_set_msg_exchange_pattern(op_out_only, env, AXIS2_MEP_URI_OUT_ONLY); + axis2_op_set_msg_exchange_pattern(op_robust_out_only, env, AXIS2_MEP_URI_ROBUST_OUT_ONLY); + + /* Setting operation phase */ + info = axis2_conf_get_phases_info(svc_client->conf, env); + axis2_phases_info_set_op_phases(info, env, op_out_in); + axis2_phases_info_set_op_phases(info, env, op_out_only); + axis2_phases_info_set_op_phases(info, env, op_robust_out_only); + axis2_svc_add_op(svc, env, op_out_in); + axis2_svc_add_op(svc, env, op_out_only); + axis2_svc_add_op(svc, env, op_robust_out_only); + return svc; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_client_free( + axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + if(!svc_client) + { + return; + } + + if(svc_client->headers) + { + axis2_svc_client_remove_all_headers(svc_client, env); + axutil_array_list_free(svc_client->headers, env); + svc_client->headers = NULL; + } + + if(svc_client->svc && !svc_client->keep_externally_passed_ctx_and_svc) + { + axis2_svc_free(svc_client->svc, env); + } + + if(svc_client->callback_recv) + { + AXIS2_CALLBACK_RECV_FREE(svc_client->callback_recv, env); + } + + if(svc_client->op_client) + { + axis2_op_client_free(svc_client->op_client, env); + svc_client->op_client = NULL; + } + + if(svc_client->options) + { + axis2_options_free(svc_client->options, env); + } + + if(svc_client->listener_manager) + { + axis2_listener_manager_free(svc_client->listener_manager, env); + } + + if(svc_client->conf_ctx && !svc_client->keep_externally_passed_ctx_and_svc) + { + axis2_conf_ctx_free(svc_client->conf_ctx, env); + } + + if(svc_client->auth_type) + { + AXIS2_FREE(env->allocator, svc_client->auth_type); + } + + if(svc_client->http_headers) + { + axis2_svc_client_set_http_info(svc_client, env, NULL); + } + + AXIS2_FREE(env->allocator, svc_client); + + return; +} + +static axis2_bool_t +axis2_svc_client_fill_soap_envelope( + const axutil_env_t * env, + axis2_svc_client_t * svc_client, + axis2_msg_ctx_t * msg_ctx, + const axiom_node_t * payload) +{ + const axis2_char_t *soap_version_uri; + int soap_version; + axiom_soap_envelope_t *envelope = NULL; + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + + soap_version_uri = axis2_options_get_soap_version_uri(svc_client->options, env); + + if(!soap_version_uri) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find soap version uri."); + return AXIS2_FALSE; + } + + if(axutil_strcmp(soap_version_uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI) == 0) + { + soap_version = AXIOM_SOAP11; + } + else + { + soap_version = AXIOM_SOAP12; + } + + envelope = axiom_soap_envelope_create_default_soap_envelope(env, soap_version); + if(!envelope) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create default soap envelope."); + return AXIS2_FALSE; + } + + if(svc_client->headers) + { + axiom_soap_header_t *soap_header = NULL; + soap_header = axiom_soap_envelope_get_header(envelope, env); + + if(soap_header) + { + axiom_node_t *header_node = NULL; + header_node = axiom_soap_header_get_base_node(soap_header, env); + + if(header_node) + { + int size = 0; + int i = 0; + size = axutil_array_list_size(svc_client->headers, env); + while(i < size) + { + axiom_node_t *node = NULL; + node = axutil_array_list_remove(svc_client->headers, env, 0); + /* This removes and retrieves data. The order of the + * removal is chosen such that the headers are appended + * in the order they were added. + */ + size--; + if(node) + { + axiom_node_add_child(header_node, env, node); + } + } + } + } + } + + if(payload) + { + axiom_soap_body_t *soap_body = NULL; + soap_body = axiom_soap_envelope_get_body(envelope, env); + if(soap_body) + { + axiom_node_t *node = NULL; + node = axiom_soap_body_get_base_node(soap_body, env); + if(node) + { + axiom_node_add_child(node, env, (axiom_node_t *)payload); + } + } + } + + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, envelope); + + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL +axis2_svc_client_get_op_client( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + return svc_client->op_client; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axis2_svc_client_get_last_response_soap_envelope( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, NULL); + return svc_client->last_response_soap_envelope; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_svc_client_get_last_response_has_fault( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE); + return svc_client->last_response_has_fault; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_svc_client_get_http_auth_required( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE); + if(svc_client->auth_failed && svc_client->required_auth_is_http) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_svc_client_get_proxy_auth_required( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE); + if(svc_client->auth_failed && !svc_client->required_auth_is_http) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_svc_client_get_auth_type( + const axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + return svc_client->auth_type; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_set_proxy_with_auth( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + axis2_char_t * proxy_host, + axis2_char_t * proxy_port, + axis2_char_t * username, + axis2_char_t * password) +{ + axis2_transport_out_desc_t *trans_desc = NULL; + axis2_conf_t *conf = NULL; + axutil_param_container_t *param_container; + axutil_param_t *param; + axis2_char_t *proxy = AXIS2_HTTP_PROXY_API; + axutil_hash_t *attribute; + axutil_generic_obj_t *host_obj = NULL; + axutil_generic_obj_t *port_obj = NULL; + axutil_generic_obj_t *username_obj = NULL; + axutil_generic_obj_t *password_obj = NULL; + axiom_attribute_t *host_attr = NULL; + axiom_attribute_t *port_attr = NULL; + axiom_attribute_t *username_attr = NULL; + axiom_attribute_t *password_attr = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, proxy_host, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, proxy_port, AXIS2_FAILURE); + + if(svc_client->conf) + { + conf = svc_client->conf; + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + if(!trans_desc) + { + return AXIS2_FAILURE; + } + param_container = axis2_transport_out_desc_param_container(trans_desc, env); + param = axutil_param_create(env, proxy, (void *)NULL); + + if(!param) + { + return AXIS2_FAILURE; + } + + attribute = axutil_hash_make(env); + host_obj = axutil_generic_obj_create(env); + port_obj = axutil_generic_obj_create(env); + host_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_HOST, proxy_host, NULL); + port_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_PORT, proxy_port, NULL); + axutil_generic_obj_set_value(host_obj, env, host_attr); + axutil_generic_obj_set_free_func(host_obj, env, axiom_attribute_free_void_arg); + axutil_generic_obj_set_value(port_obj, env, port_attr); + axutil_generic_obj_set_free_func(port_obj, env, axiom_attribute_free_void_arg); + + axutil_hash_set(attribute, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING, host_obj); + axutil_hash_set(attribute, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING, port_obj); + if(username && password) + { + username_obj = axutil_generic_obj_create(env); + password_obj = axutil_generic_obj_create(env); + username_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_USERNAME, username, NULL); + password_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_PASSWORD, password, NULL); + axutil_generic_obj_set_value(username_obj, env, username_attr); + axutil_generic_obj_set_value(password_obj, env, password_attr); + axutil_generic_obj_set_free_func(username_obj, env, axiom_attribute_free_void_arg); + axutil_generic_obj_set_free_func(password_obj, env, axiom_attribute_free_void_arg); + axutil_hash_set(attribute, AXIS2_HTTP_PROXY_USERNAME, AXIS2_HASH_KEY_STRING, + username_obj); + axutil_hash_set(attribute, AXIS2_HTTP_PROXY_PASSWORD, AXIS2_HASH_KEY_STRING, + password_obj); + } + axutil_param_set_attributes(param, env, attribute); + axutil_param_container_add_param(param_container, env, param); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_set_proxy( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + axis2_char_t * proxy_host, + axis2_char_t * proxy_port) +{ + return axis2_svc_client_set_proxy_with_auth(svc_client, env, proxy_host, proxy_port, NULL, NULL); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_set_policy_from_om( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + axiom_node_t * root_node) +{ + neethi_policy_t *neethi_policy = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + neethi_policy = neethi_util_create_policy_from_om(env, root_node); + + if(neethi_policy) + { + return axis2_svc_client_set_policy(svc_client, env, neethi_policy); + } + else + { + return AXIS2_FAILURE; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_set_policy( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + neethi_policy_t * policy) +{ + + axis2_svc_t *svc = NULL; + axis2_desc_t *desc = NULL; + axis2_policy_include_t *policy_include = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, policy, AXIS2_FAILURE); + + svc = axis2_svc_client_get_svc(svc_client, env); + + if(!svc) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Cannot find service of service client. Cannot set policy."); + return AXIS2_FAILURE; + } + + desc = axis2_svc_get_base(svc, env); + if(!desc) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Cannot find service description of service client. Cannot set policy."); + return AXIS2_FAILURE; + } + + policy_include = axis2_desc_get_policy_include(desc, env); + if(!policy_include) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find policy include. Cannot set policy."); + return AXIS2_FAILURE; + } + + axis2_policy_include_add_policy_element(policy_include, env, AXIS2_SERVICE_POLICY, policy); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_svc_client_get_http_headers( + axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + return svc_client->http_headers; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_svc_client_get_http_status_code( + axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + return svc_client->http_status_code; +} + +void +axis2_svc_client_set_http_info( + axis2_svc_client_t * svc_client, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_transport_in_desc_t *transport_in = NULL; + axutil_param_t *expose_headers_param = NULL; + axis2_bool_t expose_headers = AXIS2_FALSE; + + if(msg_ctx) + { + transport_in = axis2_msg_ctx_get_transport_in_desc(msg_ctx, env); + if(transport_in) + { + expose_headers_param = axutil_param_container_get_param( + axis2_transport_in_desc_param_container(transport_in, env), env, + AXIS2_EXPOSE_HEADERS); + } + if(expose_headers_param) + { + axis2_char_t *expose_headers_value = NULL; + expose_headers_value = axutil_param_get_value(expose_headers_param, env); + if(expose_headers_value && 0 == axutil_strcasecmp(expose_headers_value, + AXIS2_VALUE_TRUE)) + { + expose_headers = AXIS2_TRUE; + } + } + } + if(expose_headers) + { + if(svc_client->http_headers == axis2_msg_ctx_get_http_output_headers(msg_ctx, env)) + { + svc_client->http_status_code = axis2_msg_ctx_get_status_code(msg_ctx, env); + return; + } + } + + if(svc_client->http_headers) + { + axis2_http_header_t *header = NULL; + while(axutil_array_list_size(svc_client->http_headers, env)) + { + header = (axis2_http_header_t *)axutil_array_list_remove(svc_client->http_headers, env, + 0); + if(header) + { + axis2_http_header_free(header, env); + } + } + axutil_array_list_free(svc_client->http_headers, env); + svc_client->http_headers = NULL; + } + svc_client->http_status_code = 0; + + if(msg_ctx) + { + if(expose_headers) + { + svc_client->http_headers = axis2_msg_ctx_extract_http_output_headers(msg_ctx, env); + } + svc_client->http_status_code = axis2_msg_ctx_get_status_code(msg_ctx, env); + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_client_close( + axis2_svc_client_t * svc_client, + const axutil_env_t * env) +{ + axis2_status_t status = AXIS2_FAILURE; + axutil_property_t *property = NULL; + axis2_endpoint_ref_t *replyto = NULL; + + property = axutil_property_create_with_args(env, 0, 0, 0, AXIS2_VALUE_TRUE); + axis2_options_set_property(svc_client->options, env, AXIS2_SVC_CLIENT_CLOSED, property); + replyto = axis2_options_get_reply_to(svc_client->options, env); + if(replyto) + { + axiom_node_t *reply = NULL; + + reply = axis2_svc_client_send_receive(svc_client, env, NULL); + if(reply) + { + status = AXIS2_SUCCESS; + } + } + else + { + status = axis2_svc_client_send_robust(svc_client, env, NULL); + } + + return status; +} + diff --git a/src/core/context/Makefile.am b/src/core/context/Makefile.am new file mode 100644 index 0000000..30184e0 --- /dev/null +++ b/src/core/context/Makefile.am @@ -0,0 +1,13 @@ +noinst_LTLIBRARIES = libaxis2_context.la + +libaxis2_context_la_SOURCES = ctx.c \ + msg_ctx.c \ + op_ctx.c \ + svc_ctx.c \ + svc_grp_ctx.c \ + conf_ctx.c + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/context/conf_ctx.c b/src/core/context/conf_ctx.c new file mode 100644 index 0000000..9922649 --- /dev/null +++ b/src/core/context/conf_ctx.c @@ -0,0 +1,599 @@ +/* + * 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_conf_ctx.h> +#include <axis2_svc_grp.h> +#include <axis2_const.h> +#include <axutil_uuid_gen.h> + + +struct axis2_conf_ctx +{ + + /** base context struct */ + axis2_ctx_t *base; + + /** engine configuration */ + axis2_conf_t *conf; + + /** root directory */ + /* should be handled as a URL string ? */ + axis2_char_t *root_dir; + + /** + * axutil_hash_t *containing message ID to + * operation context mapping. + */ + axutil_hash_t *op_ctx_map; + + axutil_hash_t *svc_ctx_map; + + axutil_hash_t *svc_grp_ctx_map; + + /* Mutex to synchronize the read/write operations */ + axutil_thread_mutex_t *mutex; +}; + +AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL +axis2_conf_ctx_create( + const axutil_env_t * env, + axis2_conf_t * conf) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + + conf_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_conf_ctx_t)); + if(!conf_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + conf_ctx->base = NULL; + conf_ctx->conf = NULL; + conf_ctx->root_dir = NULL; + conf_ctx->op_ctx_map = NULL; + conf_ctx->svc_ctx_map = NULL; + conf_ctx->svc_grp_ctx_map = NULL; + conf_ctx->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT); + if(!conf_ctx->mutex) + { + axis2_conf_ctx_free(conf_ctx, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create thread mutex"); + return NULL; + } + + if(conf) + conf_ctx->conf = conf; + + conf_ctx->base = axis2_ctx_create(env); + if(!(conf_ctx->base)) + { + axis2_conf_ctx_free(conf_ctx, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create base context"); + return NULL; + } + + conf_ctx->op_ctx_map = axutil_hash_make(env); + if(!(conf_ctx->op_ctx_map)) + { + axis2_conf_ctx_free(conf_ctx, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create operation context map"); + return NULL; + } + + conf_ctx->svc_ctx_map = axutil_hash_make(env); + if(!(conf_ctx->svc_ctx_map)) + { + axis2_conf_ctx_free(conf_ctx, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create service context map"); + return NULL; + } + + conf_ctx->svc_grp_ctx_map = axutil_hash_make(env); + if(!(conf_ctx->svc_grp_ctx_map)) + { + axis2_conf_ctx_free(conf_ctx, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create service group context map"); + return NULL; + } + + return conf_ctx; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_ctx_set_conf( + axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + axis2_conf_t * conf) +{ + conf_ctx->conf = conf; /* We just maintain a shallow copy here */ + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_ctx_t *AXIS2_CALL +axis2_conf_ctx_get_base( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env) +{ + return conf_ctx->base; +} + +AXIS2_EXTERN axis2_conf_t *AXIS2_CALL +axis2_conf_ctx_get_conf( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env) +{ + return conf_ctx->conf; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_ctx_get_op_ctx_map( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env) +{ + return conf_ctx->op_ctx_map; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_ctx_get_svc_ctx_map( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env) +{ + return conf_ctx->svc_ctx_map; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_ctx_get_svc_grp_ctx_map( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env) +{ + return conf_ctx->svc_grp_ctx_map; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_ctx_register_op_ctx( + axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + const axis2_char_t * message_id, + axis2_op_ctx_t * op_ctx) +{ + axutil_thread_mutex_lock(conf_ctx->mutex); + if(conf_ctx->op_ctx_map) + { + axutil_hash_set(conf_ctx->op_ctx_map, message_id, AXIS2_HASH_KEY_STRING, op_ctx); + } + axutil_thread_mutex_unlock(conf_ctx->mutex); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL +axis2_conf_ctx_get_op_ctx( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + const axis2_char_t * message_id) +{ + axis2_op_ctx_t *rv = NULL; + + AXIS2_PARAM_CHECK(env->error, message_id, NULL); + + axutil_thread_mutex_lock(conf_ctx->mutex); + if(conf_ctx->op_ctx_map) + { + rv = (axis2_op_ctx_t *)axutil_hash_get(conf_ctx->op_ctx_map, message_id, + AXIS2_HASH_KEY_STRING); + } + axutil_thread_mutex_unlock(conf_ctx->mutex); + return rv; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_ctx_register_svc_ctx( + axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + const axis2_char_t * svc_id, + axis2_svc_ctx_t * svc_ctx) +{ + axutil_thread_mutex_lock(conf_ctx->mutex); + if(conf_ctx->svc_ctx_map) + { + axutil_hash_set(conf_ctx->svc_ctx_map, svc_id, AXIS2_HASH_KEY_STRING, svc_ctx); + } + axutil_thread_mutex_unlock(conf_ctx->mutex); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL +axis2_conf_ctx_get_svc_ctx( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + const axis2_char_t * svc_id) +{ + axis2_svc_ctx_t *rv = NULL; + + axutil_thread_mutex_lock(conf_ctx->mutex); + if(conf_ctx->svc_ctx_map) + { + rv = (axis2_svc_ctx_t *)axutil_hash_get(conf_ctx->svc_ctx_map, svc_id, + AXIS2_HASH_KEY_STRING); + } + axutil_thread_mutex_unlock(conf_ctx->mutex); + return rv; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_ctx_register_svc_grp_ctx( + axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + const axis2_char_t * svc_grp_id, + axis2_svc_grp_ctx_t * svc_grp_ctx) +{ + axutil_thread_mutex_lock(conf_ctx->mutex); + if(conf_ctx->svc_grp_ctx_map) + { + axutil_hash_set(conf_ctx->svc_grp_ctx_map, svc_grp_id, AXIS2_HASH_KEY_STRING, svc_grp_ctx); + } + axutil_thread_mutex_unlock(conf_ctx->mutex); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_svc_grp_ctx_t *AXIS2_CALL +axis2_conf_ctx_get_svc_grp_ctx( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + const axis2_char_t * svc_grp_id) +{ + axis2_svc_grp_ctx_t *rv = NULL; + axutil_thread_mutex_lock(conf_ctx->mutex); + if(conf_ctx->svc_grp_ctx_map) + { + rv = (axis2_svc_grp_ctx_t *)axutil_hash_get(conf_ctx->svc_grp_ctx_map, svc_grp_id, + AXIS2_HASH_KEY_STRING); + } + axutil_thread_mutex_unlock(conf_ctx->mutex); + return rv; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_conf_ctx_get_root_dir( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env) +{ + axis2_char_t *rv = NULL; + /* Do we need to lock here? - damitha */ + axutil_thread_mutex_lock(conf_ctx->mutex); + rv = conf_ctx->root_dir; + axutil_thread_mutex_unlock(conf_ctx->mutex); + return rv; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_ctx_set_root_dir( + axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + const axis2_char_t * path) +{ + axutil_thread_mutex_lock(conf_ctx->mutex); + if(conf_ctx->root_dir) + { + AXIS2_FREE(env->allocator, conf_ctx->root_dir); + conf_ctx->root_dir = NULL; + } + + if(path) + { + conf_ctx->root_dir = axutil_strdup(env, path); + if(!(conf_ctx->root_dir)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axutil_thread_mutex_unlock(conf_ctx->mutex); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + } + axutil_thread_mutex_unlock(conf_ctx->mutex); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_ctx_init( + axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + axis2_conf_t * conf) +{ + axutil_hash_index_t *hi = NULL; + void *ctx = NULL; + + axutil_thread_mutex_lock(conf_ctx->mutex); + conf_ctx->conf = conf; + + for(hi = axutil_hash_first(conf_ctx->op_ctx_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &ctx); + if(ctx) + { + axis2_op_ctx_t *op_ctx = (axis2_op_ctx_t *)ctx; + axis2_op_ctx_init(op_ctx, env, conf); + } + } + + for(hi = axutil_hash_first(conf_ctx->svc_ctx_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &ctx); + if(ctx) + { + axis2_svc_ctx_t *svc_ctx = (axis2_svc_ctx_t *)ctx; + axis2_svc_ctx_init(svc_ctx, env, conf); + } + } + + for(hi = axutil_hash_first(conf_ctx->svc_grp_ctx_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &ctx); + if(ctx) + { + axis2_svc_grp_ctx_t *svc_grp_ctx = (axis2_svc_grp_ctx_t *)ctx; + axis2_svc_grp_ctx_init(svc_grp_ctx, env, conf); + } + } + axutil_thread_mutex_unlock(conf_ctx->mutex); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_conf_ctx_free( + axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env) +{ + if(conf_ctx->base) + { + axis2_ctx_free(conf_ctx->base, env); + } + + if(conf_ctx->op_ctx_map) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(conf_ctx->op_ctx_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_op_ctx_t *op_ctx = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + op_ctx = (axis2_op_ctx_t *)val; + if(op_ctx) + axis2_op_ctx_free(op_ctx, env); + val = NULL; + op_ctx = NULL; + + } + axutil_hash_free(conf_ctx->op_ctx_map, env); + } + + if(conf_ctx->svc_ctx_map) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(conf_ctx->svc_ctx_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_svc_ctx_t *svc_ctx = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + svc_ctx = (axis2_svc_ctx_t *)val; + if(svc_ctx) + axis2_svc_ctx_free(svc_ctx, env); + + val = NULL; + svc_ctx = NULL; + + } + axutil_hash_free(conf_ctx->svc_ctx_map, env); + } + + if(conf_ctx->svc_grp_ctx_map) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(conf_ctx->svc_grp_ctx_map, env); hi; hi = axutil_hash_next(env, + hi)) + { + axis2_svc_grp_ctx_t *svc_grp_ctx = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + svc_grp_ctx = (axis2_svc_grp_ctx_t *)val; + if(svc_grp_ctx) + axis2_svc_grp_ctx_free(svc_grp_ctx, env); + + val = NULL; + svc_grp_ctx = NULL; + + } + axutil_hash_free(conf_ctx->svc_grp_ctx_map, env); + } + if(conf_ctx->conf) + { + axis2_conf_free(conf_ctx->conf, env); + } + if(conf_ctx->mutex) + { + axutil_thread_mutex_destroy(conf_ctx->mutex); + } + + if(conf_ctx->root_dir) + { + AXIS2_FREE(env->allocator, conf_ctx->root_dir); + } + + AXIS2_FREE(env->allocator, conf_ctx); +} + +AXIS2_EXTERN axis2_svc_grp_ctx_t *AXIS2_CALL +axis2_conf_ctx_fill_ctxs( + axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_char_t *svc_grp_ctx_id = NULL; + axis2_svc_grp_ctx_t *svc_grp_ctx = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_svc_t *svc = NULL; + axis2_svc_grp_t *svc_grp = NULL; + const axutil_qname_t *qname = NULL; + axis2_char_t *svc_id = NULL; + axis2_op_ctx_t *op_ctx = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + svc = axis2_msg_ctx_get_svc(msg_ctx, env); + if(!svc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SERVICE_NOT_YET_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Service not yet found in message context. Cannot proceed"); + + return NULL; + } + + qname = axis2_svc_get_qname(svc, env); + if(!qname) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service found in message context has no name."); + return NULL; + } + + svc_id = axutil_qname_get_localpart(qname, env); + if(!svc_id) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service found in message context has no name."); + return NULL; + } + + svc_grp = axis2_svc_get_parent(svc, env); + if(svc_grp) + { + svc_grp_ctx_id = (axis2_char_t *)axis2_svc_grp_get_name(svc_grp, env); + } + + if(!svc_grp_ctx_id) + { + svc_grp_ctx_id = (axis2_char_t *)axutil_string_get_buffer(axis2_msg_ctx_get_svc_grp_ctx_id( + msg_ctx, env), env); + } + + /* By this time service group context id must have a value, either from transport or from + * addressing + */ + if(svc_grp_ctx_id) + { + svc_grp_ctx = (axis2_svc_grp_ctx_t *)axutil_hash_get(conf_ctx->svc_grp_ctx_map, + svc_grp_ctx_id, AXIS2_HASH_KEY_STRING); + + if(svc_grp_ctx) + { + svc_ctx = axis2_svc_grp_ctx_get_svc_ctx(svc_grp_ctx, env, svc_id); + if(!svc_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC_GRP, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Service group context has no servie context set for service %s", svc_id); + + return NULL; + } + } + } + + if(!svc_grp_ctx_id) + { + svc_grp_ctx_id = axutil_uuid_gen(env); + if(svc_grp_ctx_id) + { + axutil_string_t *svc_grp_ctx_id_str = axutil_string_create_assume_ownership(env, + &svc_grp_ctx_id); + + axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, svc_grp_ctx_id_str); + axutil_string_free(svc_grp_ctx_id_str, env); + } + } + + if(!svc_grp_ctx) + { + axis2_svc_grp_t *svc_grp = NULL; + svc_grp = axis2_svc_get_parent(svc, env); + svc_grp_ctx = axis2_svc_grp_get_svc_grp_ctx(svc_grp, env, conf_ctx); + svc_ctx = axis2_svc_grp_ctx_get_svc_ctx(svc_grp_ctx, env, svc_id); + if(!svc_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC_GRP, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Service group context has no servie context set for service %s", svc_id); + + return NULL; + } + + axis2_svc_grp_ctx_set_id(svc_grp_ctx, env, svc_grp_ctx_id); + axis2_conf_ctx_register_svc_grp_ctx(conf_ctx, env, svc_grp_ctx_id, svc_grp_ctx); + } + + /* When you come here operation context MUST have already been assigned + to the message context */ + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(!op_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_MSG_CTX, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Operation context not set for message context"); + return NULL; + } + + axis2_op_ctx_set_parent(op_ctx, env, svc_ctx); + axis2_msg_ctx_set_svc_ctx(msg_ctx, env, svc_ctx); + axis2_msg_ctx_set_svc_grp_ctx(msg_ctx, env, svc_grp_ctx); + return svc_grp_ctx; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_ctx_set_property( + axis2_conf_ctx_t *conf_ctx, + const axutil_env_t * env, + const axis2_char_t * key, + axutil_property_t * value) +{ + axis2_status_t status = AXIS2_FAILURE; + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, key, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + + axutil_thread_mutex_lock(conf_ctx->mutex); + status = axis2_ctx_set_property(conf_ctx->base, env, key, value); + axutil_thread_mutex_unlock(conf_ctx->mutex); + + return status; +} + +AXIS2_EXTERN axutil_property_t *AXIS2_CALL +axis2_conf_ctx_get_property( + const axis2_conf_ctx_t * conf_ctx, + const axutil_env_t * env, + const axis2_char_t * key) +{ + axutil_property_t* property = NULL; + AXIS2_PARAM_CHECK(env->error, conf_ctx, NULL); + AXIS2_PARAM_CHECK(env->error, key, NULL); + + axutil_thread_mutex_lock(conf_ctx->mutex); + property = axis2_ctx_get_property(conf_ctx->base, env, key); + axutil_thread_mutex_unlock(conf_ctx->mutex); + + return property; +} diff --git a/src/core/context/ctx.c b/src/core/context/ctx.c new file mode 100644 index 0000000..df39a9b --- /dev/null +++ b/src/core/context/ctx.c @@ -0,0 +1,197 @@ +/* + * 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_ctx.h> +#include <axis2_const.h> +#include <axutil_hash.h> + +struct axis2_ctx +{ + + /** non persistent map */ + axutil_hash_t *property_map; + + /** non persistent map is a deep copy */ + axis2_bool_t property_map_deep_copy; +}; + +AXIS2_EXTERN axis2_ctx_t *AXIS2_CALL +axis2_ctx_create( + const axutil_env_t * env) +{ + axis2_ctx_t *ctx = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_ctx_t)); + if(!ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + ctx->property_map = NULL; + + ctx->property_map = axutil_hash_make(env); + ctx->property_map_deep_copy = AXIS2_TRUE; + if(!(ctx->property_map)) + { + axis2_ctx_free(ctx, env); + return NULL; + } + + return ctx; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ctx_set_property( + struct axis2_ctx * ctx, + const axutil_env_t * env, + const axis2_char_t * key, + axutil_property_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(value) + { + /* handle the case where we are setting a new value with the + same key, we would have to free the existing value */ + axutil_property_t *temp_value = axutil_hash_get(ctx->property_map, key, + AXIS2_HASH_KEY_STRING); + if(temp_value) + { + void *temp_value_value = axutil_property_get_value(temp_value, env); + void *value_value = axutil_property_get_value(value, env); + if(temp_value_value != value_value) + { + axutil_property_free(temp_value, env); + } + } + } + if(ctx->property_map) + { + axutil_hash_set(ctx->property_map, key, AXIS2_HASH_KEY_STRING, value); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_property_t *AXIS2_CALL +axis2_ctx_get_property( + const axis2_ctx_t * ctx, + const axutil_env_t * env, + const axis2_char_t * key) +{ + axutil_property_t *ret = NULL; + + if(ctx->property_map) + { + ret = axutil_hash_get(ctx->property_map, key, AXIS2_HASH_KEY_STRING); + } + + /** it is the responsibility of the caller to look-up parent if key is not found here + Note that in C implementation it is the responsibility of the deriving struct to + handle the parent as we do not have the inheritance facility. In case of + context it is not worth trying to mimic inheritance. */ + + return ret; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_ctx_get_all_properties( + const axis2_ctx_t * ctx, + const axutil_env_t * env) +{ + return ctx->property_map; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_ctx_get_property_map( + const axis2_ctx_t * ctx, + const axutil_env_t * env) +{ + return ctx->property_map; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_ctx_free( + struct axis2_ctx *ctx, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(ctx->property_map && ctx->property_map_deep_copy) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + const void *key = NULL; + for(hi = axutil_hash_first(ctx->property_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_property_t *property = NULL; + + axutil_hash_this(hi, &key, NULL, &val); + property = (axutil_property_t *)val; + + if(property) + { + axutil_property_free(property, env); + } + } + axutil_hash_free(ctx->property_map, env); + } + + AXIS2_FREE(env->allocator, ctx); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ctx_set_property_map( + struct axis2_ctx * ctx, + const axutil_env_t * env, + axutil_hash_t * map) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(ctx->property_map && ctx->property_map_deep_copy) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + const void *key = NULL; + for(hi = axutil_hash_first(ctx->property_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_property_t *property = NULL; + + axutil_hash_this(hi, &key, NULL, &val); + property = (axutil_property_t *)val; + + if(property) + { + axutil_property_free(property, env); + } + } + if(ctx->property_map != map) /* handle repeated invocation case */ + { + axutil_hash_free(ctx->property_map, env); + } + } + + ctx->property_map = map; + ctx->property_map_deep_copy = AXIS2_FALSE; + + return AXIS2_SUCCESS; +} diff --git a/src/core/context/msg_ctx.c b/src/core/context/msg_ctx.c new file mode 100644 index 0000000..c2342c4 --- /dev/null +++ b/src/core/context/msg_ctx.c @@ -0,0 +1,2768 @@ +/* + * 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_msg_ctx.h> +#include <axis2_conf_ctx.h> +#include <axis2_op.h> +#include <axis2_svc.h> +#include <axis2_svc_grp.h> +#include <axis2_conf.h> +#include <axis2_transport_in_desc.h> +#include <axis2_transport_out_desc.h> +#include <axis2_out_transport_info.h> +#include <axis2_http_accept_record.h> +#include <axis2_http_header.h> +#include <axiom_soap_envelope.h> +#include <axiom_soap_const.h> +#include <axis2_options.h> + + +struct axis2_msg_ctx +{ + + /** base context struct */ + axis2_ctx_t *base; + + /** parent of message context is an op context instance */ + struct axis2_op_ctx *parent; + + /** process fault enabled? */ + axis2_bool_t process_fault; + + /** + * Addressing Information for Axis 2 + * Following Properties will be kept inside this, these fields will be initially filled by + * the transport. Then later an addressing handler will make relevant changes to this, if addressing + * information is present in the SOAP header. + */ + axis2_msg_info_headers_t *msg_info_headers; + axis2_bool_t msg_info_headers_deep_copy; + + struct axis2_op_ctx *op_ctx; + struct axis2_svc_ctx *svc_ctx; + struct axis2_svc_grp_ctx *svc_grp_ctx; + struct axis2_conf_ctx *conf_ctx; + + /** op */ + axis2_op_t *op; + + /** service */ + axis2_svc_t *svc; + + /** service group */ + axis2_svc_grp_t *svc_grp; + + axis2_transport_in_desc_t *transport_in_desc; + axis2_transport_out_desc_t *transport_out_desc; + + /** SOAP envelope */ + axiom_soap_envelope_t *soap_envelope; + + /** Response SOAP envelope */ + axiom_soap_envelope_t *response_soap_envelope; + + /** SOAP Fault envelope */ + axiom_soap_envelope_t *fault_soap_envelope; + + /** in fault flow? */ + axis2_bool_t in_fault_flow; + + /** is this server side? */ + axis2_bool_t server_side; + + /** message ID */ + axis2_char_t *message_id; + + /** new thread required? */ + axis2_bool_t new_thread_required; + + /** paused */ + axis2_bool_t paused; + axis2_bool_t keep_alive; + + /** output written? */ + axis2_bool_t output_written; + + /** service context ID */ + axis2_char_t *svc_ctx_id; + + /** paused phase name */ + axis2_char_t *paused_phase_name; + + /** paused handler name */ + axutil_string_t *paused_handler_name; + + /** SOAP action */ + axutil_string_t *soap_action; + + /** REST HTTP Method */ + axis2_char_t *rest_http_method; + + /** + * Supported REST HTTP Methods + * Made use of in a 405 Error Scenario + */ + axutil_array_list_t *supported_rest_http_methods; + + /** are we doing MTOM now? */ + axis2_bool_t doing_mtom; + + /** are we doing REST now? */ + axis2_bool_t doing_rest; + + /** Rest through HTTP POST? */ + axis2_bool_t do_rest_through_post; + + /** Session management enabled? */ + axis2_bool_t manage_session; + + /* http status code */ + int status_code; + + /** use SOAP 1.1? */ + axis2_bool_t is_soap_11; + + /** service group context id */ + axutil_string_t *svc_grp_ctx_id; + + /** qname of transport in */ + AXIS2_TRANSPORT_ENUMS transport_in_desc_enum; + + /** qname of transport out */ + AXIS2_TRANSPORT_ENUMS transport_out_desc_enum; + + /** service group id */ + axis2_char_t *svc_grp_id; + + /** service description qname */ + axutil_qname_t *svc_qname; + + /** op qname */ + axutil_qname_t *op_qname; + /* To keep track of the direction */ + int flow; + + /** The chain of Handlers/Phases for processing this message */ + axutil_array_list_t *execution_chain; + + /** Index into the execution chain of the currently executing handler */ + int current_handler_index; + + /** Index of the paused handler */ + int paused_handler_index; + + /** Index of the paused phase */ + int paused_phase_index; + + /** Index into the current Phase of the currently executing handler (if any)*/ + int current_phase_index; + + /* axis2 options container */ + + axis2_options_t *options; + + /** + * Finds the service to be invoked. This function is used by dispatchers + * to locate the service to be invoked. + * @param msg_ctx message context + * @param env pointer to environment struct + * @return pointer to service to be invoked + */ + struct axis2_svc * + ( + AXIS2_CALL * find_svc) + ( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env); + + /** + * Finds the operation to be invoked in the given service. This function + * is used by dispatchers to locate the operation to be invoked. + * @param msg_ctx message context + * @param env pointer to environment struct + * @param svc pointer to service to whom the operation belongs + * @return pointer to the operation to be invoked + */ + struct axis2_op * + ( + AXIS2_CALL * find_op) + ( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + struct axis2_svc * svc); + + axutil_string_t *charset_encoding; + axutil_stream_t *transport_out_stream; + axis2_out_transport_info_t *out_transport_info; + axutil_hash_t *transport_headers; + axutil_array_list_t *output_headers; + axutil_array_list_t *accept_record_list; + axutil_array_list_t *accept_charset_record_list; + axutil_array_list_t *accept_language_record_list; + axis2_char_t *transfer_encoding; + axis2_char_t *content_language; + axis2_char_t *transport_url; + axis2_bool_t is_auth_failure; + axis2_bool_t required_auth_is_http; + axis2_char_t *auth_type; + axis2_bool_t no_content; + + axutil_array_list_t *mime_parts; + int ref; +}; + +AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL +axis2_msg_ctx_create( + const axutil_env_t * env, + struct axis2_conf_ctx *conf_ctx, + struct axis2_transport_in_desc *transport_in_desc, + struct axis2_transport_out_desc *transport_out_desc) +{ + axis2_msg_ctx_t *msg_ctx = NULL; + + msg_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_msg_ctx_t)); + if(!msg_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)msg_ctx, 0, sizeof(axis2_msg_ctx_t)); + msg_ctx->base = NULL; + msg_ctx->process_fault = AXIS2_FALSE; + msg_ctx->msg_info_headers = NULL; + msg_ctx->op_ctx = NULL; + msg_ctx->svc_ctx = NULL; + msg_ctx->svc_grp_ctx = NULL; + msg_ctx->conf_ctx = NULL; + msg_ctx->op = NULL; + msg_ctx->svc = NULL; + msg_ctx->svc_grp = NULL; + msg_ctx->transport_in_desc = NULL; + msg_ctx->transport_out_desc = NULL; + msg_ctx->soap_envelope = NULL; + msg_ctx->fault_soap_envelope = NULL; + msg_ctx->in_fault_flow = AXIS2_FALSE; + msg_ctx->server_side = AXIS2_FALSE; + msg_ctx->message_id = NULL; + msg_ctx->new_thread_required = AXIS2_FALSE; + msg_ctx->paused = AXIS2_FALSE; + msg_ctx->keep_alive = AXIS2_FALSE; + msg_ctx->output_written = AXIS2_FALSE; + msg_ctx->svc_ctx_id = NULL; + msg_ctx->paused_phase_name = NULL; + msg_ctx->paused_handler_name = NULL; + msg_ctx->soap_action = NULL; + msg_ctx->rest_http_method = NULL; + msg_ctx->supported_rest_http_methods = NULL; + msg_ctx->doing_mtom = AXIS2_FALSE; + msg_ctx->doing_rest = AXIS2_FALSE; + msg_ctx->do_rest_through_post = AXIS2_FALSE; + msg_ctx->manage_session = AXIS2_FALSE; + msg_ctx->is_soap_11 = AXIS2_FALSE; + msg_ctx->svc_grp_ctx_id = NULL; + msg_ctx->transport_in_desc_enum = AXIS2_TRANSPORT_ENUM_MAX; + msg_ctx->transport_out_desc_enum = AXIS2_TRANSPORT_ENUM_MAX; + msg_ctx->svc_grp_id = NULL; + msg_ctx->svc_qname = NULL; + msg_ctx->op_qname = NULL; + msg_ctx->flow = AXIS2_IN_FLOW; + msg_ctx->execution_chain = NULL; + msg_ctx->current_handler_index = -1; + msg_ctx->paused_handler_index = -1; + msg_ctx->current_phase_index = 0; + msg_ctx->paused_phase_index = 0; + msg_ctx->charset_encoding = NULL; + msg_ctx->transport_out_stream = NULL; + msg_ctx->out_transport_info = NULL; + msg_ctx->transport_headers = NULL; + msg_ctx->accept_record_list = NULL; + msg_ctx->accept_charset_record_list = NULL; + msg_ctx->output_headers = NULL; + msg_ctx->accept_language_record_list = NULL; + msg_ctx->transfer_encoding = NULL; + msg_ctx->content_language = NULL; + msg_ctx->transport_url = NULL; + msg_ctx->response_soap_envelope = NULL; + msg_ctx->is_auth_failure = AXIS2_FALSE; + msg_ctx->required_auth_is_http = AXIS2_FALSE; + msg_ctx->auth_type = NULL; + msg_ctx->no_content = AXIS2_FALSE; + msg_ctx->status_code = 0; + msg_ctx->options = NULL; + msg_ctx->mime_parts = NULL; + + msg_ctx->base = axis2_ctx_create(env); + if(!(msg_ctx->base)) + { + axis2_msg_ctx_free(msg_ctx, env); + return NULL; + } + + if(transport_in_desc) + msg_ctx->transport_in_desc = transport_in_desc; + if(transport_out_desc) + msg_ctx->transport_out_desc = transport_out_desc; + if(conf_ctx) + msg_ctx->conf_ctx = conf_ctx; + + if(msg_ctx->transport_in_desc) + msg_ctx->transport_in_desc_enum = axis2_transport_in_desc_get_enum(transport_in_desc, env); + if(msg_ctx->transport_out_desc) + msg_ctx->transport_out_desc_enum = axis2_transport_out_desc_get_enum(transport_out_desc, + env); + + msg_ctx->msg_info_headers = axis2_msg_info_headers_create(env, NULL, NULL); + if(!(msg_ctx->msg_info_headers)) + { + axis2_msg_ctx_free(msg_ctx, env); + return NULL; + } + msg_ctx->msg_info_headers_deep_copy = AXIS2_TRUE; + msg_ctx->ref = 1; + + return msg_ctx; +} + +/******************************************************************************/ +struct axis2_ctx *AXIS2_CALL +axis2_msg_ctx_get_base( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + return msg_ctx->base; +} + +struct axis2_op_ctx *AXIS2_CALL +axis2_msg_ctx_get_parent( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->parent; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_parent( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + struct axis2_op_ctx * parent) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(parent) + { + msg_ctx->parent = parent; + } + + return AXIS2_SUCCESS; +} + +void AXIS2_CALL +axis2_msg_ctx_free( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(--(msg_ctx->ref) > 0) + { + return; + } + + if(msg_ctx->keep_alive) + { + return; + } + + if(msg_ctx->base) + { + axis2_ctx_free(msg_ctx->base, env); + } + + if(msg_ctx->msg_info_headers && msg_ctx->msg_info_headers_deep_copy) + { + axis2_msg_info_headers_free(msg_ctx->msg_info_headers, env); + } + + if(msg_ctx->message_id) + { + AXIS2_FREE(env->allocator, msg_ctx->message_id); + } + + if(msg_ctx->svc_ctx_id) + { + AXIS2_FREE(env->allocator, msg_ctx->svc_ctx_id); + } + + if(msg_ctx->soap_action) + { + axutil_string_free(msg_ctx->soap_action, env); + } + + if(msg_ctx->rest_http_method) + { + AXIS2_FREE(env->allocator, msg_ctx->rest_http_method); + } + + if(msg_ctx->svc_grp_ctx_id) + { + axutil_string_free(msg_ctx->svc_grp_ctx_id, env); + } + + if(msg_ctx->soap_envelope) + { + axiom_soap_envelope_free(msg_ctx->soap_envelope, env); + } + + if(msg_ctx->fault_soap_envelope) + { + axiom_soap_envelope_free(msg_ctx->fault_soap_envelope, env); + } + + if(msg_ctx->charset_encoding) + { + axutil_string_free(msg_ctx->charset_encoding, env); + } + + if(msg_ctx->transport_out_stream) + { + axutil_stream_free(msg_ctx->transport_out_stream, env); + } + + if(msg_ctx->out_transport_info) + { + AXIS2_OUT_TRANSPORT_INFO_FREE(msg_ctx->out_transport_info, env); + } + + if(msg_ctx->transport_headers) + { + axutil_hash_free(msg_ctx->transport_headers, env); + } + + if(msg_ctx->accept_charset_record_list) + { + axis2_http_accept_record_t *rec = NULL; + while(axutil_array_list_size(msg_ctx->accept_charset_record_list, env)) + { + rec = (axis2_http_accept_record_t *)axutil_array_list_remove( + msg_ctx->accept_charset_record_list, env, 0); + if(rec) + { + axis2_http_accept_record_free(rec, env); + } + } + axutil_array_list_free(msg_ctx->accept_charset_record_list, env); + } + + if(msg_ctx->output_headers) + { + axis2_http_header_t *header = NULL; + while(axutil_array_list_size(msg_ctx->output_headers, env)) + { + header = (axis2_http_header_t *)axutil_array_list_remove(msg_ctx->output_headers, env, + 0); + if(header) + { + axis2_http_header_free(header, env); + } + } + axutil_array_list_free(msg_ctx->output_headers, env); + } + + if(msg_ctx->accept_language_record_list) + { + axis2_http_accept_record_t *rec = NULL; + while(axutil_array_list_size(msg_ctx->accept_language_record_list, env)) + { + rec = (axis2_http_accept_record_t *)axutil_array_list_remove( + msg_ctx->accept_language_record_list, env, 0); + if(rec) + { + axis2_http_accept_record_free(rec, env); + } + } + axutil_array_list_free(msg_ctx->accept_language_record_list, env); + } + + if(msg_ctx->accept_record_list) + { + axis2_http_accept_record_t *rec = NULL; + while(axutil_array_list_size(msg_ctx->accept_record_list, env)) + { + rec = (axis2_http_accept_record_t *)axutil_array_list_remove( + msg_ctx->accept_record_list, env, 0); + if(rec) + { + axis2_http_accept_record_free(rec, env); + } + } + axutil_array_list_free(msg_ctx->accept_record_list, env); + } + + if(msg_ctx->transfer_encoding) + { + AXIS2_FREE(env->allocator, msg_ctx->transfer_encoding); + } + + if(msg_ctx->content_language) + { + AXIS2_FREE(env->allocator, msg_ctx->content_language); + } + + if(msg_ctx->auth_type) + { + AXIS2_FREE(env->allocator, msg_ctx->auth_type); + } + + if(msg_ctx->supported_rest_http_methods) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(msg_ctx->supported_rest_http_methods, env); + for(i = 0; i < size; i++) + { + axis2_char_t *rest_http_method = NULL; + rest_http_method = axutil_array_list_get(msg_ctx->supported_rest_http_methods, env, i); + if(rest_http_method) + { + AXIS2_FREE(env->allocator, rest_http_method); + } + } + axutil_array_list_free(msg_ctx->supported_rest_http_methods, env); + } + + if(msg_ctx->options) + { + /* freeing only axis2_options_t allocated space, should not + * call axis2_options_free because it will free internal + * properties as well. */ + AXIS2_FREE(env->allocator, msg_ctx->options); + } + + AXIS2_FREE(env->allocator, msg_ctx); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_increment_ref( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + msg_ctx->ref++; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_init( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + struct axis2_conf * conf) +{ + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + msg_ctx->transport_in_desc = axis2_conf_get_transport_in(conf, env, + msg_ctx-> transport_in_desc_enum); + + msg_ctx->transport_out_desc = axis2_conf_get_transport_out(conf, env, + msg_ctx-> transport_out_desc_enum); + + if(msg_ctx->svc_grp_id) + { + msg_ctx->svc_grp = axis2_conf_get_svc_grp(conf, env, msg_ctx->svc_grp_id); + } + + if(msg_ctx->svc_qname) + { + msg_ctx->svc = axis2_conf_get_svc(conf, env, axutil_qname_get_localpart( + msg_ctx-> svc_qname, env)); + } + + if(msg_ctx->op_qname) + { + if(msg_ctx->svc) + msg_ctx->op = axis2_svc_get_op_with_qname(msg_ctx->svc, env, msg_ctx->op_qname); + } + + return AXIS2_SUCCESS; +} + +axis2_endpoint_ref_t *AXIS2_CALL +axis2_msg_ctx_get_fault_to( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_get_fault_to(msg_ctx->msg_info_headers, env); + } + + return NULL; +} + +axis2_endpoint_ref_t *AXIS2_CALL +axis2_msg_ctx_get_from( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_get_from(msg_ctx->msg_info_headers, env); + } + + return NULL; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_in_fault_flow( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->in_fault_flow; +} + +axiom_soap_envelope_t *AXIS2_CALL +axis2_msg_ctx_get_soap_envelope( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->soap_envelope; +} + +axiom_soap_envelope_t *AXIS2_CALL +axis2_msg_ctx_get_response_soap_envelope( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->response_soap_envelope; +} + +axiom_soap_envelope_t *AXIS2_CALL +axis2_msg_ctx_get_fault_soap_envelope( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->fault_soap_envelope; +} + +const axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_msg_id( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_get_message_id(msg_ctx->msg_info_headers, env); + } + + return NULL; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_msg_id( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_char_t * msg_id) +{ + AXIS2_PARAM_CHECK(env->error, msg_id, AXIS2_FAILURE); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_message_id(msg_ctx->msg_info_headers, env, msg_id); + } + + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_process_fault( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->process_fault; +} + +axis2_relates_to_t *AXIS2_CALL +axis2_msg_ctx_get_relates_to( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_get_relates_to(msg_ctx->msg_info_headers, env); + } + + return NULL; +} + +axis2_endpoint_ref_t *AXIS2_CALL +axis2_msg_ctx_get_reply_to( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_get_reply_to(msg_ctx->msg_info_headers, env); + } + + return NULL; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_server_side( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->server_side; +} + +axis2_endpoint_ref_t *AXIS2_CALL +axis2_msg_ctx_get_to( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_get_to(msg_ctx->msg_info_headers, env); + } + + return NULL; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_fault_to( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_endpoint_ref_t * reference) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_to(msg_ctx->msg_info_headers, env, reference); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_from( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_endpoint_ref_t * reference) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_from(msg_ctx->msg_info_headers, env, reference); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_in_fault_flow( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t in_fault_flow) +{ + msg_ctx->in_fault_flow = in_fault_flow; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_soap_envelope( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axiom_soap_envelope_t * soap_envelope) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(soap_envelope) + { + int soap_v = AXIOM_SOAP12; + soap_v = axiom_soap_envelope_get_soap_version(soap_envelope, env); + msg_ctx->is_soap_11 = (soap_v == AXIOM_SOAP12) ? AXIS2_FALSE : AXIS2_TRUE; + msg_ctx->soap_envelope = soap_envelope; + } + else + { + msg_ctx->soap_envelope = NULL; + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_response_soap_envelope( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axiom_soap_envelope_t * soap_envelope) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(soap_envelope) + { + int soap_v = AXIOM_SOAP12; + soap_v = axiom_soap_envelope_get_soap_version(soap_envelope, env); + msg_ctx->response_soap_envelope = soap_envelope; + } + else + { + msg_ctx->response_soap_envelope = NULL; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_fault_soap_envelope( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axiom_soap_envelope_t * soap_envelope) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->fault_soap_envelope = soap_envelope; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_message_id( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * message_id) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_message_id(msg_ctx->msg_info_headers, env, message_id); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_process_fault( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t process_fault) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->process_fault = process_fault; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_relates_to( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_relates_to_t * reference) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_relates_to(msg_ctx->msg_info_headers, env, reference); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_reply_to( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_endpoint_ref_t * reference) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_reply_to(msg_ctx->msg_info_headers, env, reference); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_server_side( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t server_side) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->server_side = server_side; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_to( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_endpoint_ref_t * reference) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_to(msg_ctx->msg_info_headers, env, reference); + } + + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_new_thread_required( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + return msg_ctx->new_thread_required; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_new_thread_required( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t new_thread_required) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->new_thread_required = new_thread_required; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_wsa_action( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * action_uri) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_action(msg_ctx->msg_info_headers, env, action_uri); + } + + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_wsa_action( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_get_action(msg_ctx->msg_info_headers, env); + } + + return NULL; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_wsa_message_id( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * message_id) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_set_message_id(msg_ctx->msg_info_headers, env, message_id); + } + + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_wsa_message_id( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + if(msg_ctx->msg_info_headers) + { + return axis2_msg_info_headers_get_message_id(msg_ctx->msg_info_headers, env); + } + + return NULL; + +} + +axis2_msg_info_headers_t *AXIS2_CALL +axis2_msg_ctx_get_msg_info_headers( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->msg_info_headers; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_paused( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->paused; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_paused( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t paused) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->paused = paused; + msg_ctx->paused_phase_index = msg_ctx->current_phase_index; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_keep_alive( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t keep_alive) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->keep_alive = keep_alive; + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_is_keep_alive( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->keep_alive; +} + +struct axis2_transport_in_desc *AXIS2_CALL +axis2_msg_ctx_get_transport_in_desc( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->transport_in_desc; +} + +struct axis2_transport_out_desc *AXIS2_CALL +axis2_msg_ctx_get_transport_out_desc( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->transport_out_desc; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_transport_in_desc( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + struct axis2_transport_in_desc * transport_in_desc) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(transport_in_desc) + { + msg_ctx->transport_in_desc = transport_in_desc; + msg_ctx->transport_in_desc_enum = axis2_transport_in_desc_get_enum(transport_in_desc, env); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_transport_out_desc( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + struct axis2_transport_out_desc * transport_out_desc) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(transport_out_desc) + { + msg_ctx->transport_out_desc = transport_out_desc; + msg_ctx->transport_out_desc_enum = axis2_transport_out_desc_get_enum(transport_out_desc, + env); + } + + return AXIS2_SUCCESS; +} + +struct axis2_op_ctx *AXIS2_CALL +axis2_msg_ctx_get_op_ctx( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->op_ctx; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_op_ctx( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + struct axis2_op_ctx * op_ctx) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(op_ctx) + { + msg_ctx->op_ctx = op_ctx; + + if(msg_ctx->svc_ctx) + { + if(!(axis2_op_ctx_get_parent(msg_ctx->op_ctx, env))) + { + axis2_op_ctx_set_parent(msg_ctx->op_ctx, env, msg_ctx->svc_ctx); + } + } + axis2_msg_ctx_set_parent(msg_ctx, env, op_ctx); + axis2_msg_ctx_set_op(msg_ctx, env, axis2_op_ctx_get_op(op_ctx, env)); + } + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_output_written( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->output_written; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_output_written( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t output_written) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->output_written = output_written; + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_rest_http_method( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->rest_http_method; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_rest_http_method( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * rest_http_method) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx->rest_http_method) + { + AXIS2_FREE(env->allocator, msg_ctx->rest_http_method); + msg_ctx->rest_http_method = NULL; + } + + if(rest_http_method) + { + msg_ctx->rest_http_method = axutil_strdup(env, rest_http_method); + if(!(msg_ctx->rest_http_method)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_svc_ctx_id( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->svc_ctx_id; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_svc_ctx_id( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * svc_ctx_id) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx->svc_ctx_id) + { + AXIS2_FREE(env->allocator, msg_ctx->svc_ctx_id); + msg_ctx->svc_ctx_id = NULL; + } + + if(svc_ctx_id) + { + msg_ctx->svc_ctx_id = axutil_strdup(env, svc_ctx_id); + if(!(msg_ctx->svc_ctx_id)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +struct axis2_conf_ctx *AXIS2_CALL +axis2_msg_ctx_get_conf_ctx( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->conf_ctx; +} + +struct axis2_svc_ctx *AXIS2_CALL +axis2_msg_ctx_get_svc_ctx( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->svc_ctx; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_conf_ctx( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + struct axis2_conf_ctx * conf_ctx) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(conf_ctx) + { + msg_ctx->conf_ctx = conf_ctx; + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_svc_ctx( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + struct axis2_svc_ctx * svc_ctx) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(svc_ctx) + { + msg_ctx->svc_ctx = svc_ctx; + + if(msg_ctx->op_ctx) + { + if(!axis2_op_ctx_get_parent(msg_ctx->op_ctx, env)) + axis2_op_ctx_set_parent(msg_ctx->op_ctx, env, svc_ctx); + } + axis2_msg_ctx_set_svc(msg_ctx, env, axis2_svc_ctx_get_svc(svc_ctx, env)); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_msg_info_headers( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_msg_info_headers_t * msg_info_headers) +{ + AXIS2_PARAM_CHECK(env->error, msg_info_headers, AXIS2_FAILURE); + + if(msg_info_headers) + { + if(msg_ctx->msg_info_headers && msg_ctx->msg_info_headers_deep_copy) + { + axis2_msg_info_headers_free(msg_ctx->msg_info_headers, env); + msg_ctx->msg_info_headers = NULL; + } + msg_ctx->msg_info_headers = msg_info_headers; + msg_ctx->msg_info_headers_deep_copy = AXIS2_FALSE; + } + + return AXIS2_SUCCESS; +} + +axutil_param_t *AXIS2_CALL +axis2_msg_ctx_get_parameter( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * key) +{ + axutil_param_t *param = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + if(msg_ctx->op) + { + param = axis2_op_get_param(msg_ctx->op, env, key); + if(param) + { + return param; + } + } + + if(msg_ctx->svc) + { + param = axis2_svc_get_param(msg_ctx->svc, env, key); + if(param) + { + return param; + } + } + + if(msg_ctx->svc_grp) + { + param = axis2_svc_grp_get_param(msg_ctx->svc_grp, env, key); + if(param) + { + return param; + } + } + + if(msg_ctx->conf_ctx) + { + axis2_conf_t *conf = axis2_conf_ctx_get_conf(msg_ctx->conf_ctx, env); + param = axis2_conf_get_param(conf, env, key); + } + + return param; +} + +AXIS2_EXTERN void *AXIS2_CALL +axis2_msg_ctx_get_property_value( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * property_str) +{ + axutil_property_t *property; + void *property_value = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + property = axis2_msg_ctx_get_property(msg_ctx, env, property_str); + + if(!property) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "%s not set in message context", property_str); + return NULL; + } + + property_value = axutil_property_get_value(property, env); + if(!property_value) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "%s properties not set in message context", + property_str); + return NULL; + } + + return property_value; +} + +axutil_property_t *AXIS2_CALL +axis2_msg_ctx_get_property( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * key) +{ + void *obj = NULL; + axis2_ctx_t *ctx = NULL; + + /* Don't use AXIS2_PARAM_CHECK to verify msg_ctx, as it clobbers + env->error->status_code destroying the information therein that + an error has already occurred. */ + if(!msg_ctx) + { + if(axutil_error_get_status_code(env->error) == AXIS2_SUCCESS) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + } + return obj; + } + + /* search in message context */ + obj = axis2_ctx_get_property(msg_ctx->base, env, key); + if(obj) + { + return obj; + } + + if(msg_ctx->op_ctx) + { + ctx = axis2_op_ctx_get_base(msg_ctx->op_ctx, env); + if(ctx) + { + obj = axis2_ctx_get_property(ctx, env, key); + if(obj) + { + return obj; + } + } + } + + if(msg_ctx->svc_ctx) + { + ctx = axis2_svc_ctx_get_base(msg_ctx->svc_ctx, env); + if(ctx) + { + obj = axis2_ctx_get_property(ctx, env, key); + if(obj) + { + return obj; + } + } + } + + if(msg_ctx->svc_grp_ctx) + { + ctx = axis2_svc_grp_ctx_get_base(msg_ctx->svc_grp_ctx, env); + if(ctx) + { + obj = axis2_ctx_get_property(ctx, env, key); + if(obj) + { + return obj; + } + } + } + + if(msg_ctx->conf_ctx) + { + ctx = axis2_conf_ctx_get_base(msg_ctx->conf_ctx, env); + if(ctx) + { + obj = axis2_ctx_get_property(ctx, env, key); + if(obj) + { + return obj; + } + } + } + + return NULL; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_property( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * key, + axutil_property_t * value) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + return axis2_ctx_set_property(msg_ctx->base, env, key, value); +} + +const axutil_string_t *AXIS2_CALL +axis2_msg_ctx_get_paused_handler_name( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->paused_handler_name; +} + +const axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_paused_phase_name( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->paused_phase_name; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_paused_phase_name( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * paused_phase_name) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + /* a shallow copy is sufficient as phase lives beyond message */ + msg_ctx->paused_phase_name = (axis2_char_t *)paused_phase_name; + return AXIS2_SUCCESS; +} + +axutil_string_t *AXIS2_CALL +axis2_msg_ctx_get_soap_action( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->soap_action; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_soap_action( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axutil_string_t * soap_action) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(msg_ctx->soap_action) + { + axutil_string_free(msg_ctx->soap_action, env); + } + + if(soap_action) + { + msg_ctx->soap_action = axutil_string_clone(soap_action, env); + if(!(msg_ctx->soap_action)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_doing_mtom( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + + if(!(msg_ctx->doing_mtom) && msg_ctx->conf_ctx) + { + axis2_conf_t *conf = axis2_conf_ctx_get_conf(msg_ctx->conf_ctx, env); + msg_ctx->doing_mtom = axis2_conf_get_enable_mtom(conf, env); + } + + return msg_ctx->doing_mtom; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_doing_mtom( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t doing_mtom) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->doing_mtom = doing_mtom; + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_doing_rest( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + /* Don't use AXIS2_PARAM_CHECK to verify msg_ctx, as it clobbers + env->error->status_code destroying the information therein that + an error has already occurred. */ + if(!msg_ctx) + { + if(axutil_error_get_status_code(env->error) == AXIS2_SUCCESS) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + } + return AXIS2_FALSE; + } + return msg_ctx->doing_rest; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_doing_rest( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t doing_rest) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->doing_rest = doing_rest; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_do_rest_through_post( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t do_rest_through_post) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->do_rest_through_post = do_rest_through_post; + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_do_rest_through_post( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->do_rest_through_post; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_manage_session( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->manage_session; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_manage_session( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t manage_session) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->manage_session = manage_session; + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_is_soap_11( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->is_soap_11; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_is_soap_11( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t is_soap11) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->is_soap_11 = is_soap11; + return AXIS2_SUCCESS; +} + +struct axis2_svc_grp_ctx *AXIS2_CALL +axis2_msg_ctx_get_svc_grp_ctx( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->svc_grp_ctx; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_svc_grp_ctx( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + struct axis2_svc_grp_ctx * svc_grp_ctx) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(svc_grp_ctx) + { + msg_ctx->svc_grp_ctx = svc_grp_ctx; + } + + return AXIS2_SUCCESS; +} + +axis2_op_t *AXIS2_CALL +axis2_msg_ctx_get_op( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->op; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_op( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_op_t * op) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(op) + { + msg_ctx->op = op; + msg_ctx->op_qname = (axutil_qname_t *)axis2_op_get_qname(op, env); + } + + return AXIS2_SUCCESS; +} + +axis2_svc_t *AXIS2_CALL +axis2_msg_ctx_get_svc( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->svc; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_svc( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(svc) + { + axis2_svc_grp_t *svc_grp = NULL; + msg_ctx->svc = svc; + msg_ctx->svc_qname = (axutil_qname_t *)axis2_svc_get_qname(svc, env); + + svc_grp = axis2_svc_get_parent(svc, env); + if(svc_grp) + { + msg_ctx->svc_grp = svc_grp; + msg_ctx->svc_grp_id = (axis2_char_t *)axis2_svc_grp_get_name(svc_grp, env); + } + } + + return AXIS2_SUCCESS; +} + +axis2_svc_grp_t *AXIS2_CALL +axis2_msg_ctx_get_svc_grp( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->svc_grp; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_svc_grp( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axis2_svc_grp_t * svc_grp) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(svc_grp) + { + msg_ctx->svc_grp = svc_grp; + msg_ctx->svc_grp_id = (axis2_char_t *)axis2_svc_grp_get_name(svc_grp, env); + } + + return AXIS2_SUCCESS; +} + +const axutil_string_t *AXIS2_CALL +axis2_msg_ctx_get_svc_grp_ctx_id( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->svc_grp_ctx_id; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_svc_grp_ctx_id( + struct axis2_msg_ctx * msg_ctx, + const axutil_env_t * env, + axutil_string_t * svc_grp_ctx_id) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(msg_ctx->svc_grp_ctx_id) + { + axutil_string_free(msg_ctx->svc_grp_ctx_id, env); + msg_ctx->svc_grp_ctx_id = NULL; + } + + if(svc_grp_ctx_id) + { + msg_ctx->svc_grp_ctx_id = axutil_string_clone(svc_grp_ctx_id, env); + } + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_msg_ctx_is_paused( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->paused; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + AXIS2_MSG_CTX_FIND_SVC func) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->find_svc = func; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + AXIS2_MSG_CTX_FIND_OP func) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->find_op = func; + return AXIS2_SUCCESS; +} + +axis2_options_t *AXIS2_CALL +axis2_msg_ctx_get_options( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axutil_hash_t *properties = NULL; + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + if(!msg_ctx->options) + { + msg_ctx->options = axis2_options_create(env); + + if(!msg_ctx->options) + { + return NULL; + } + } + + axis2_options_set_msg_info_headers(msg_ctx->options, env, msg_ctx->msg_info_headers); + properties = axis2_ctx_get_property_map(msg_ctx->base, env); + axis2_options_set_properties(msg_ctx->options, env, properties); + return msg_ctx->options; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_options( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_options_t * options) +{ + axutil_property_t *rest_val = NULL; + axis2_char_t *value; + axutil_string_t *soap_action = NULL; + ; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, options, AXIS2_FAILURE); + + if(msg_ctx->msg_info_headers && msg_ctx->msg_info_headers_deep_copy) + { + axis2_msg_info_headers_free(msg_ctx->msg_info_headers, env); + } + msg_ctx->msg_info_headers = axis2_options_get_msg_info_headers(options, env); + msg_ctx->msg_info_headers_deep_copy = AXIS2_FALSE; + + msg_ctx->doing_mtom = axis2_options_get_enable_mtom(options, env); + + msg_ctx->manage_session = axis2_options_get_manage_session(options, env); + + axis2_ctx_set_property_map(msg_ctx->base, env, axis2_options_get_properties(options, env)); + rest_val = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_ENABLE_REST); + if(rest_val) + { + value = (axis2_char_t *)axutil_property_get_value(rest_val, env); + if(value) + { + if(axutil_strcmp(value, AXIS2_VALUE_TRUE) == 0) + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE); + } + } + + if(msg_ctx->soap_action) + { + axutil_string_free(msg_ctx->soap_action, env); + } + + soap_action = axis2_options_get_soap_action(options, env); + if(soap_action) + { + msg_ctx->soap_action = axutil_string_clone(soap_action, env); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_flow( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + int flow) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->flow = flow; + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +axis2_msg_ctx_get_flow( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, 0); + return msg_ctx->flow; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_execution_chain( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_array_list_t * execution_chain) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->execution_chain = execution_chain; + msg_ctx->current_handler_index = -1; + msg_ctx->paused_handler_index = -1; + msg_ctx->current_phase_index = 0; + + return AXIS2_SUCCESS; +} + +axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_get_execution_chain( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->execution_chain; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_supported_rest_http_methods( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_array_list_t * supported_rest_http_methods) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->supported_rest_http_methods = supported_rest_http_methods; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_get_supported_rest_http_methods( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->supported_rest_http_methods; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_current_handler_index( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const int index) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->current_handler_index = index; + if(msg_ctx->execution_chain) + { + axis2_handler_t *handler = (axis2_handler_t *)axutil_array_list_get( + msg_ctx->execution_chain, env, index); + if(handler) + { + msg_ctx->paused_handler_name = (axutil_string_t *)axis2_handler_get_name(handler, env); + } + } + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +axis2_msg_ctx_get_current_handler_index( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, 0); + return msg_ctx->current_handler_index; +} + +int AXIS2_CALL +axis2_msg_ctx_get_paused_handler_index( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, 0); + return msg_ctx->paused_handler_index; +} + +axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_current_phase_index( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const int index) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->current_phase_index = index; + return AXIS2_SUCCESS; + +} + +int AXIS2_CALL +axis2_msg_ctx_get_current_phase_index( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, 0); + return msg_ctx->current_phase_index; +} + +int AXIS2_CALL +axis2_msg_ctx_get_paused_phase_index( + const axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, 0); + return msg_ctx->paused_phase_index; +} + +AXIS2_EXTERN axis2_svc_t *AXIS2_CALL +axis2_msg_ctx_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->find_svc(msg_ctx, env); +} + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_msg_ctx_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + return msg_ctx->find_op(msg_ctx, env, svc); +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axis2_msg_ctx_get_charset_encoding( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + if(msg_ctx) + return msg_ctx->charset_encoding; + else + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_charset_encoding( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_string_t * str) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx) + { + if(msg_ctx->charset_encoding) + { + axutil_string_free(msg_ctx->charset_encoding, env); + msg_ctx->charset_encoding = NULL; + } + if(str) + { + msg_ctx->charset_encoding = axutil_string_clone(str, env); + } + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axis2_msg_ctx_get_transport_out_stream( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + if(msg_ctx) + { + return msg_ctx->transport_out_stream; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_transport_out_stream( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_stream_t * stream) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx) + { + if(msg_ctx->transport_out_stream) + { + axutil_stream_free(msg_ctx->transport_out_stream, env); + } + + msg_ctx->transport_out_stream = stream; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_reset_transport_out_stream( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx) + { + msg_ctx->transport_out_stream = NULL; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_out_transport_info_t *AXIS2_CALL +axis2_msg_ctx_get_out_transport_info( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + if(msg_ctx) + { + return msg_ctx->out_transport_info; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_out_transport_info( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_out_transport_info_t * out_transport_info) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx) + { + if(msg_ctx->out_transport_info) + { + AXIS2_OUT_TRANSPORT_INFO_FREE(msg_ctx->out_transport_info, env); + } + + msg_ctx->out_transport_info = out_transport_info; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_reset_out_transport_info( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + if(msg_ctx) + { + msg_ctx->out_transport_info = NULL; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_msg_ctx_get_transport_headers( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + { + return msg_ctx->transport_headers; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_msg_ctx_extract_transport_headers( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axutil_hash_t *temp = NULL; + if(msg_ctx) + { + temp = msg_ctx->transport_headers; + msg_ctx->transport_headers = NULL; + return temp; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_transport_headers( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_hash_t * transport_headers) +{ + if(msg_ctx) + { + if(msg_ctx->transport_headers) + { + axutil_hash_free(msg_ctx->transport_headers, env); + } + + msg_ctx->transport_headers = transport_headers; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_get_http_accept_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + { + return msg_ctx->accept_record_list; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_extract_http_accept_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axutil_array_list_t *temp = NULL; + if(msg_ctx) + { + temp = msg_ctx->accept_record_list; + msg_ctx->accept_record_list = NULL; + return temp; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_http_accept_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_array_list_t * accept_record_list) +{ + if(msg_ctx) + { + if(msg_ctx->accept_record_list && msg_ctx->accept_record_list != accept_record_list) + { + axis2_http_accept_record_t *rec = NULL; + while(axutil_array_list_size(msg_ctx->accept_record_list, env)) + { + rec = (axis2_http_accept_record_t *)axutil_array_list_remove( + msg_ctx->accept_record_list, env, 0); + if(rec) + { + axis2_http_accept_record_free(rec, env); + } + } + axutil_array_list_free(msg_ctx->accept_record_list, env); + } + msg_ctx->accept_record_list = accept_record_list; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_get_http_accept_charset_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + { + return msg_ctx->accept_charset_record_list; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_extract_http_accept_charset_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axutil_array_list_t *temp = NULL; + if(msg_ctx) + { + temp = msg_ctx->accept_charset_record_list; + msg_ctx->accept_charset_record_list = NULL; + return temp; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_http_accept_charset_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_array_list_t * accept_charset_record_list) +{ + if(msg_ctx) + { + if(msg_ctx->accept_charset_record_list && msg_ctx->accept_charset_record_list + != accept_charset_record_list) + { + axis2_http_accept_record_t *rec = NULL; + while(axutil_array_list_size(msg_ctx->accept_charset_record_list, env)) + { + rec = (axis2_http_accept_record_t *)axutil_array_list_remove( + msg_ctx->accept_charset_record_list, env, 0); + if(rec) + { + axis2_http_accept_record_free(rec, env); + } + } + axutil_array_list_free(msg_ctx->accept_charset_record_list, env); + } + msg_ctx->accept_charset_record_list = accept_charset_record_list; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_get_http_output_headers( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + { + return msg_ctx->output_headers; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_extract_http_output_headers( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + { + axutil_array_list_t *temp = NULL; + temp = msg_ctx->output_headers; + msg_ctx->output_headers = NULL; + return temp; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_http_output_headers( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_array_list_t * output_headers) +{ + if(msg_ctx) + { + if(msg_ctx->output_headers && msg_ctx->output_headers != output_headers) + { + axis2_http_header_t *header = NULL; + while(axutil_array_list_size(msg_ctx->output_headers, env)) + { + header = (axis2_http_header_t *)axutil_array_list_remove(msg_ctx->output_headers, + env, 0); + if(header) + { + axis2_http_header_free(header, env); + } + } + axutil_array_list_free(msg_ctx->output_headers, env); + } + msg_ctx->output_headers = output_headers; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_get_http_accept_language_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + { + return msg_ctx->accept_language_record_list; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_extract_http_accept_language_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axutil_array_list_t *temp = NULL; + if(msg_ctx) + { + temp = msg_ctx->accept_language_record_list; + msg_ctx->accept_language_record_list = NULL; + return temp; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_http_accept_language_record_list( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_array_list_t * accept_language_record_list) +{ + if(msg_ctx) + { + if(msg_ctx->accept_language_record_list && msg_ctx->accept_language_record_list + != accept_language_record_list) + { + axis2_http_accept_record_t *rec = NULL; + while(axutil_array_list_size(msg_ctx->accept_language_record_list, env)) + { + rec = (axis2_http_accept_record_t *)axutil_array_list_remove( + msg_ctx->accept_language_record_list, env, 0); + if(rec) + { + axis2_http_accept_record_free(rec, env); + } + } + axutil_array_list_free(msg_ctx->accept_language_record_list, env); + } + msg_ctx->accept_language_record_list = accept_language_record_list; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_transfer_encoding( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + return msg_ctx->transfer_encoding; + else + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_transfer_encoding( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_char_t * str) +{ + if(msg_ctx) + { + if(msg_ctx->transfer_encoding) + { + AXIS2_FREE(env->allocator, msg_ctx->transfer_encoding); + msg_ctx->transfer_encoding = NULL; + } + if(str) + { + msg_ctx->transfer_encoding = str; + } + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_content_language( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + return msg_ctx->content_language; + else + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_content_language( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_char_t * str) +{ + if(msg_ctx) + { + if(msg_ctx->content_language) + { + AXIS2_FREE(env->allocator, msg_ctx->content_language); + msg_ctx->content_language = NULL; + } + if(str) + { + msg_ctx->content_language = str; + } + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_transport_url( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(msg_ctx) + return msg_ctx->transport_url; + else + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_transport_url( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_char_t * str) +{ + if(msg_ctx) + { + /* this is a shallow copy, no need to free */ + msg_ctx->transport_url = str; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_msg_ctx_get_status_code( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, 0); + return msg_ctx->status_code; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_status_code( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const int status_code) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->status_code = status_code; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_auth_failed( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->is_auth_failure; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_auth_failed( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t status) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->is_auth_failure = status; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_no_content( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->no_content; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_no_content( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t no_content) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->no_content = no_content; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_msg_ctx_get_required_auth_is_http( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + return msg_ctx->required_auth_is_http; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_required_auth_is_http( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const axis2_bool_t status) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + msg_ctx->required_auth_is_http = status; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_ctx_set_auth_type( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + const axis2_char_t * auth_type) +{ + if(msg_ctx->auth_type) + { + AXIS2_FREE(env->allocator, msg_ctx->auth_type); + } + msg_ctx->auth_type = NULL; + if(auth_type) + { + msg_ctx->auth_type = axutil_strdup(env, auth_type); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_msg_ctx_get_auth_type( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + return msg_ctx->auth_type; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_ctx_get_mime_parts( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + return msg_ctx->mime_parts; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_msg_ctx_set_mime_parts( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axutil_array_list_t *mime_parts) +{ + if(msg_ctx->mime_parts) + { + axutil_array_list_free(mime_parts, env); + msg_ctx->mime_parts = NULL; + } + msg_ctx->mime_parts = mime_parts; +} diff --git a/src/core/context/op_ctx.c b/src/core/context/op_ctx.c new file mode 100644 index 0000000..30f0e3b --- /dev/null +++ b/src/core/context/op_ctx.c @@ -0,0 +1,420 @@ +/* + * 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_op_ctx.h> +#include <axis2_conf_ctx.h> +#include <axis2_op.h> +#include <axis2_const.h> +#include <axutil_hash.h> + +struct axis2_op_ctx +{ + + /** base context struct */ + axis2_ctx_t *base; + + /** parent of operation context is a service context instance */ + struct axis2_svc_ctx *parent; + + /** message context map */ + axis2_msg_ctx_t *msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_MAX]; + + /** + * the operation of which this is a running instance. The MEP of this + * operation must be one of the 8 predefined ones in WSDL 2.0. + */ + axis2_op_t *op; + + /** operation Message Exchange Pattern (MEP) */ + int op_mep; + + /** is complete? */ + axis2_bool_t is_complete; + + /** the global message_id -> op_ctx map which is stored in + * the axis2_conf_ctx. We are caching it here for faster access. + */ + axutil_hash_t *op_ctx_map; + + /** op qname */ + axutil_qname_t *op_qname; + + /** service qname */ + axutil_qname_t *svc_qname; + /* mutex to synchronize the read/write operations */ + axutil_thread_mutex_t *mutex; + axis2_bool_t response_written; + axis2_bool_t is_in_use; + + int ref; +}; + +AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL +axis2_op_ctx_create( + const axutil_env_t * env, + axis2_op_t * op, + struct axis2_svc_ctx *svc_ctx) +{ + axis2_op_ctx_t *op_ctx = NULL; + int i = 0; + + op_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_ctx_t)); + if(!op_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + op_ctx->base = NULL; + op_ctx->parent = NULL; + op_ctx->op = NULL; + op_ctx->op_mep = 0; + op_ctx->is_complete = AXIS2_FALSE; + op_ctx->is_in_use = AXIS2_FALSE; + op_ctx->op_ctx_map = NULL; + op_ctx->op_qname = NULL; + op_ctx->svc_qname = NULL; + op_ctx->response_written = AXIS2_FALSE; + op_ctx->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT); + + if(!op_ctx->mutex) + { + axis2_op_ctx_free(op_ctx, env); + return NULL; + } + + op_ctx->base = axis2_ctx_create(env); + if(!(op_ctx->base)) + { + axis2_op_ctx_free(op_ctx, env); + return NULL; + } + + if(op) + { + op_ctx->op = op; + } + + for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++) + { + op_ctx->msg_ctx_array[i] = NULL; + } + + if(op_ctx->op) + { + op_ctx->op_qname = (axutil_qname_t *)axis2_op_get_qname(op_ctx->op, env); + op_ctx->op_mep = axis2_op_get_axis_specific_mep_const(op_ctx->op, env); + } + + axis2_op_ctx_set_parent(op_ctx, env, svc_ctx); + op_ctx->ref = 1; + + return op_ctx; +} + +AXIS2_EXTERN axis2_ctx_t *AXIS2_CALL +axis2_op_ctx_get_base( + const axis2_op_ctx_t * op_ctx, + const axutil_env_t * env) +{ + return op_ctx->base; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_op_ctx_free( + struct axis2_op_ctx *op_ctx, + const axutil_env_t * env) +{ + int i = 0; + if(--(op_ctx->ref) > 0) + { + return; + } + if(op_ctx->is_in_use) + { + return; + } + + if(op_ctx->base) + { + axis2_ctx_free(op_ctx->base, env); + } + + for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++) + { + if(op_ctx->msg_ctx_array[i]) + { + axis2_msg_ctx_free(op_ctx->msg_ctx_array[i], env); + op_ctx->msg_ctx_array[i] = NULL; + } + } + + if(op_ctx->mutex) + { + axutil_thread_mutex_destroy(op_ctx->mutex); + } + + AXIS2_FREE(env->allocator, op_ctx); + + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_op_ctx_destroy_mutex( + struct axis2_op_ctx *op_ctx, + const axutil_env_t * env) +{ + + if(op_ctx->mutex) + { + axutil_thread_mutex_destroy(op_ctx->mutex); + op_ctx->mutex = NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_ctx_init( + struct axis2_op_ctx *op_ctx, + const axutil_env_t * env, + struct axis2_conf *conf) +{ + int i = 0; + + if(op_ctx->op_qname && op_ctx->svc_qname) + { + axis2_svc_t *svc = NULL; + axis2_char_t *svc_name = NULL; + + svc_name = axutil_qname_get_localpart(op_ctx->svc_qname, env); + + if(svc_name) + { + svc = axis2_conf_get_svc(conf, env, svc_name); + + if(svc) + { + op_ctx->op = axis2_svc_get_op_with_qname(svc, env, op_ctx->op_qname); + } + } + } + + for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++) + { + if(op_ctx->msg_ctx_array[i]) + { + axis2_msg_ctx_init(op_ctx->msg_ctx_array[i], env, conf); + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_op_ctx_get_op( + const axis2_op_ctx_t * op_ctx, + const axutil_env_t * env) +{ + return op_ctx->op; +} + +AXIS2_EXTERN struct axis2_svc_ctx *AXIS2_CALL +axis2_op_ctx_get_parent( + const axis2_op_ctx_t * op_ctx, + const axutil_env_t * env) +{ + return op_ctx->parent; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_ctx_add_msg_ctx( + struct axis2_op_ctx * op_ctx, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + + axutil_thread_mutex_lock(op_ctx->mutex); + + out_msg_ctx = op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_OUT]; + in_msg_ctx = op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_IN]; + + if(out_msg_ctx && in_msg_ctx) + { + axutil_thread_mutex_unlock(op_ctx->mutex); + return AXIS2_FAILURE; + } + + if(!out_msg_ctx) + { + op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_OUT] = msg_ctx; + } + else + { + op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_IN] = msg_ctx; + } + + axutil_thread_mutex_unlock(op_ctx->mutex); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL +axis2_op_ctx_get_msg_ctx( + const axis2_op_ctx_t * op_ctx, + const axutil_env_t * env, + const axis2_wsdl_msg_labels_t message_id) +{ + axutil_thread_mutex_lock(op_ctx->mutex); + if(op_ctx->msg_ctx_array) + { + axis2_msg_ctx_t *rv = NULL; + rv = op_ctx->msg_ctx_array[message_id]; + axutil_thread_mutex_unlock(op_ctx->mutex); + return rv; + } + axutil_thread_mutex_unlock(op_ctx->mutex); + return NULL; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_op_ctx_get_is_complete( + const axis2_op_ctx_t * op_ctx, + const axutil_env_t * env) +{ + return op_ctx->is_complete; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_ctx_set_complete( + struct axis2_op_ctx * op_ctx, + const axutil_env_t * env, + axis2_bool_t is_complete) +{ + op_ctx->is_complete = is_complete; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_op_ctx_is_in_use( + const axis2_op_ctx_t * op_ctx, + const axutil_env_t * env) +{ + return op_ctx->is_in_use; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_ctx_set_in_use( + struct axis2_op_ctx * op_ctx, + const axutil_env_t * env, + axis2_bool_t is_in_use) +{ + op_ctx->is_in_use = is_in_use; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_ctx_cleanup( + struct axis2_op_ctx * op_ctx, + const axutil_env_t * env) +{ + int i = 0; + + for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++) + { + if(op_ctx->msg_ctx_array[i]) + { + axis2_msg_ctx_free(op_ctx->msg_ctx_array[i], env); + op_ctx->msg_ctx_array[i] = NULL; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_ctx_set_parent( + struct axis2_op_ctx * op_ctx, + const axutil_env_t * env, + struct axis2_svc_ctx * svc_ctx) +{ + if(svc_ctx) + { + op_ctx->parent = svc_ctx; + } + + if(op_ctx->parent) /* that is if there is a service context associated */ + { + axis2_conf_ctx_t *conf_ctx = NULL; + conf_ctx = axis2_svc_ctx_get_conf_ctx(op_ctx->parent, env); + if(conf_ctx) + { + op_ctx->op_ctx_map = axis2_conf_ctx_get_op_ctx_map(conf_ctx, env); + } + op_ctx->svc_qname = (axutil_qname_t *)axis2_svc_get_qname(axis2_svc_ctx_get_svc( + op_ctx->parent, env), env); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_ctx_t **AXIS2_CALL +axis2_op_ctx_get_msg_ctx_map( + const axis2_op_ctx_t * op_ctx, + const axutil_env_t * env) +{ + return (axis2_msg_ctx_t **)(op_ctx->msg_ctx_array); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_op_ctx_get_response_written( + const axis2_op_ctx_t * op_ctx, + const axutil_env_t * env) +{ + if(op_ctx) + return op_ctx->response_written; + else + return AXIS2_FALSE; + +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_ctx_set_response_written( + axis2_op_ctx_t * op_ctx, + const axutil_env_t * env, + const axis2_bool_t written) +{ + if(op_ctx) + { + op_ctx->response_written = written; + } + else + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_ctx_increment_ref( + axis2_op_ctx_t * op_ctx, + const axutil_env_t * env) +{ + op_ctx->ref++; + return AXIS2_SUCCESS; +} + diff --git a/src/core/context/svc_ctx.c b/src/core/context/svc_ctx.c new file mode 100644 index 0000000..c9e19fe --- /dev/null +++ b/src/core/context/svc_ctx.c @@ -0,0 +1,200 @@ +/* + * 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_svc_ctx.h> +#include <axis2_conf_ctx.h> +#include <axis2_const.h> +#include <axutil_hash.h> + +struct axis2_svc_ctx +{ + + /** base context struct */ + axis2_ctx_t *base; + + /** parent of op context is a service context instance */ + struct axis2_svc_grp_ctx *parent; + + /** service associated with this service context */ + axis2_svc_t *svc; + + /** id of the service associated with this context */ + axis2_char_t *svc_id; + + /** service qname */ + axutil_qname_t *svc_qname; +}; + +AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL +axis2_svc_ctx_create( + const axutil_env_t * env, + axis2_svc_t * svc, + struct axis2_svc_grp_ctx *svc_grp_ctx) +{ + axis2_svc_ctx_t *svc_ctx = NULL; + + svc_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_ctx_t)); + if(!svc_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + svc_ctx->base = NULL; + svc_ctx->parent = NULL; + svc_ctx->svc = NULL; + svc_ctx->svc_id = NULL; + svc_ctx->svc_qname = NULL; + + svc_ctx->base = axis2_ctx_create(env); + if(!(svc_ctx->base)) + { + axis2_svc_ctx_free(svc_ctx, env); + return NULL; + } + + if(svc) + { + svc_ctx->svc = svc; + svc_ctx->svc_qname = (axutil_qname_t *)axis2_svc_get_qname(svc, env); + if(svc_ctx->svc_qname) + { + svc_ctx->svc_id = axutil_qname_get_localpart(svc_ctx->svc_qname, env); + } + } + + if(svc_grp_ctx) + { + svc_ctx->parent = svc_grp_ctx; + } + + return svc_ctx; +} + +axis2_ctx_t *AXIS2_CALL +axis2_svc_ctx_get_base( + const axis2_svc_ctx_t * svc_ctx, + const axutil_env_t * env) +{ + return svc_ctx->base; +} + +struct axis2_svc_grp_ctx *AXIS2_CALL +axis2_svc_ctx_get_parent( + const axis2_svc_ctx_t * svc_ctx, + const axutil_env_t * env) +{ + return svc_ctx->parent; +} + +axis2_status_t AXIS2_CALL +axis2_svc_ctx_set_parent( + axis2_svc_ctx_t * svc_ctx, + const axutil_env_t * env, + axis2_svc_grp_ctx_t * parent) +{ + svc_ctx->parent = parent; + return AXIS2_SUCCESS; +} + +void AXIS2_CALL +axis2_svc_ctx_free( + struct axis2_svc_ctx *svc_ctx, + const axutil_env_t * env) +{ + if(svc_ctx->base) + { + axis2_ctx_free(svc_ctx->base, env); + } + + AXIS2_FREE(env->allocator, svc_ctx); + return; +} + +axis2_status_t AXIS2_CALL +axis2_svc_ctx_init( + struct axis2_svc_ctx * svc_ctx, + const axutil_env_t * env, + axis2_conf_t * conf) +{ + if(svc_ctx->svc_qname) + { + axis2_char_t *svc_name = axutil_qname_get_localpart(svc_ctx->svc_qname, env); + svc_ctx->svc = axis2_conf_get_svc(conf, env, svc_name); + } + + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_svc_ctx_get_svc_id( + const axis2_svc_ctx_t * svc_ctx, + const axutil_env_t * env) +{ + return svc_ctx->svc_id; +} + +axis2_svc_t *AXIS2_CALL +axis2_svc_ctx_get_svc( + const axis2_svc_ctx_t * svc_ctx, + const axutil_env_t * env) +{ + return svc_ctx->svc; +} + +axis2_status_t AXIS2_CALL +axis2_svc_ctx_set_svc( + axis2_svc_ctx_t * svc_ctx, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + AXIS2_PARAM_CHECK(env->error, svc, AXIS2_FAILURE); + + svc_ctx->svc = svc; + svc_ctx->svc_qname = (axutil_qname_t *)axis2_svc_get_qname(svc, env); + if(svc_ctx->svc_qname) + { + svc_ctx->svc_id = axutil_qname_get_localpart(svc_ctx->svc_qname, env); + } + return AXIS2_SUCCESS; +} + +struct axis2_conf_ctx *AXIS2_CALL +axis2_svc_ctx_get_conf_ctx( + const axis2_svc_ctx_t * svc_ctx, + const axutil_env_t * env) +{ + return axis2_svc_grp_ctx_get_parent(svc_ctx->parent, env); +} + +axis2_op_ctx_t *AXIS2_CALL +axis2_svc_ctx_create_op_ctx( + struct axis2_svc_ctx * svc_ctx, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + axis2_op_t *op = NULL; + + if(svc_ctx->svc) + { + op = axis2_svc_get_op_with_qname(svc_ctx->svc, env, qname); + return axis2_op_ctx_create(env, op, svc_ctx); + } + + return NULL; +} + diff --git a/src/core/context/svc_grp_ctx.c b/src/core/context/svc_grp_ctx.c new file mode 100644 index 0000000..449c01b --- /dev/null +++ b/src/core/context/svc_grp_ctx.c @@ -0,0 +1,256 @@ +/* + * 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_svc_grp_ctx.h> +#include <axis2_svc_grp.h> +#include <axis2_const.h> +#include <axutil_hash.h> + +struct axis2_svc_grp_ctx +{ + + /** base context struct */ + axis2_ctx_t *base; + + /** parent of service group context is a configuration context instance */ + struct axis2_conf_ctx *parent; + + /** service group context ID */ + axis2_char_t *id; + + /** map of service contexts belonging to this service context group */ + axutil_hash_t *svc_ctx_map; + + /** service group associated with this service group context */ + axis2_svc_grp_t *svc_grp; + + /** name of the service group associated with this context */ + axis2_char_t *svc_grp_name; +}; + +AXIS2_EXTERN axis2_svc_grp_ctx_t *AXIS2_CALL +axis2_svc_grp_ctx_create( + const axutil_env_t * env, + axis2_svc_grp_t * svc_grp, + struct axis2_conf_ctx *conf_ctx) +{ + axis2_svc_grp_ctx_t *svc_grp_ctx = NULL; + + svc_grp_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_grp_ctx_t)); + if(!svc_grp_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + svc_grp_ctx->base = NULL; + svc_grp_ctx->parent = NULL; + svc_grp_ctx->id = NULL; + svc_grp_ctx->svc_ctx_map = NULL; + svc_grp_ctx->svc_grp = NULL; + svc_grp_ctx->svc_grp_name = NULL; + + svc_grp_ctx->base = axis2_ctx_create(env); + if(!(svc_grp_ctx->base)) + { + axis2_svc_grp_ctx_free(svc_grp_ctx, env); + return NULL; + } + + if(svc_grp) + { + svc_grp_ctx->svc_grp = svc_grp; + svc_grp_ctx->svc_grp_name = (axis2_char_t *)axis2_svc_grp_get_name(svc_grp_ctx->svc_grp, + env); + svc_grp_ctx->id = axutil_strdup(env, svc_grp_ctx->svc_grp_name); + } + + if(conf_ctx) + { + svc_grp_ctx->parent = conf_ctx; + } + + svc_grp_ctx->svc_ctx_map = axutil_hash_make(env); + if(!(svc_grp_ctx->svc_ctx_map)) + { + axis2_svc_grp_ctx_free(svc_grp_ctx, env); + return NULL; + } + + axis2_svc_grp_ctx_fill_svc_ctx_map((svc_grp_ctx), env); + + return svc_grp_ctx; +} + +AXIS2_EXTERN axis2_ctx_t *AXIS2_CALL +axis2_svc_grp_ctx_get_base( + const axis2_svc_grp_ctx_t * svc_grp_ctx, + const axutil_env_t * env) +{ + return svc_grp_ctx->base; +} + +AXIS2_EXTERN struct axis2_conf_ctx *AXIS2_CALL +axis2_svc_grp_ctx_get_parent( + const axis2_svc_grp_ctx_t * svc_grp_ctx, + const axutil_env_t * env) +{ + return svc_grp_ctx->parent; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_grp_ctx_free( + struct axis2_svc_grp_ctx *svc_grp_ctx, + const axutil_env_t * env) +{ + if(svc_grp_ctx->id) + { + AXIS2_FREE(env->allocator, svc_grp_ctx->id); + } + + if(svc_grp_ctx->base) + { + axis2_ctx_free(svc_grp_ctx->base, env); + } + + if(svc_grp_ctx->svc_ctx_map) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(svc_grp_ctx->svc_ctx_map, env); hi; hi = axutil_hash_next(env, + hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + axis2_svc_ctx_t *svc_ctx = NULL; + svc_ctx = (axis2_svc_ctx_t *)val; + axis2_svc_ctx_free(svc_ctx, env); + } + } + + axutil_hash_free(svc_grp_ctx->svc_ctx_map, env); + svc_grp_ctx->base = NULL; + } + + AXIS2_FREE(env->allocator, svc_grp_ctx); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_ctx_init( + struct axis2_svc_grp_ctx * svc_grp_ctx, + const axutil_env_t * env, + axis2_conf_t * conf) +{ + if(svc_grp_ctx->svc_grp_name) + { + svc_grp_ctx->svc_grp = axis2_conf_get_svc_grp(conf, env, svc_grp_ctx->svc_grp_name); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_grp_ctx_get_id( + const axis2_svc_grp_ctx_t * svc_grp_ctx, + const axutil_env_t * env) +{ + return svc_grp_ctx->id; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_ctx_set_id( + struct axis2_svc_grp_ctx * svc_grp_ctx, + const axutil_env_t * env, + const axis2_char_t * id) +{ + if(svc_grp_ctx->id) + { + AXIS2_FREE(env->allocator, svc_grp_ctx->id); + svc_grp_ctx->id = NULL; + } + + if(id) + { + svc_grp_ctx->id = axutil_strdup(env, id); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL +axis2_svc_grp_ctx_get_svc_ctx( + const axis2_svc_grp_ctx_t * svc_grp_ctx, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + return (axis2_svc_ctx_t *)axutil_hash_get(svc_grp_ctx->svc_ctx_map, svc_name, + AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_ctx_fill_svc_ctx_map( + struct axis2_svc_grp_ctx * svc_grp_ctx, + const axutil_env_t * env) +{ + axutil_hash_index_t *hi = NULL; + void *next_svc = NULL; + + if(svc_grp_ctx->svc_grp) + { + axutil_hash_t *service_map = axis2_svc_grp_get_all_svcs(svc_grp_ctx->svc_grp, env); + if(service_map) + { + for(hi = axutil_hash_first(service_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &next_svc); + if(next_svc) + { + axis2_svc_t *svc = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_char_t *svc_name = NULL; + svc = (axis2_svc_t *)next_svc; + svc_ctx = axis2_svc_ctx_create(env, svc, svc_grp_ctx); + svc_name = axutil_qname_get_localpart(axis2_svc_get_qname(svc, env), env); + if(svc_name) + axutil_hash_set(svc_grp_ctx->svc_ctx_map, svc_name, AXIS2_HASH_KEY_STRING, + svc_ctx); + } + } + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_svc_grp_t *AXIS2_CALL +axis2_svc_grp_ctx_get_svc_grp( + const axis2_svc_grp_ctx_t * svc_grp_ctx, + const axutil_env_t * env) +{ + return svc_grp_ctx->svc_grp; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_svc_grp_ctx_get_svc_ctx_map( + const axis2_svc_grp_ctx_t * svc_grp_ctx, + const axutil_env_t * env) +{ + return svc_grp_ctx->svc_ctx_map; +} + diff --git a/src/core/deployment/Makefile.am b/src/core/deployment/Makefile.am new file mode 100644 index 0000000..7099839 --- /dev/null +++ b/src/core/deployment/Makefile.am @@ -0,0 +1,38 @@ +noinst_LTLIBRARIES = libaxis2_deployment.la + +noinst_HEADERS = axis2_deployment.h \ + axis2_arch_file_data.h \ + axis2_arch_reader.h \ + axis2_conf_builder.h \ + axis2_dep_engine.h \ + axis2_desc_builder.h \ + axis2_module_builder.h \ + axis2_repos_listener.h \ + axis2_svc_builder.h \ + axis2_svc_grp_builder.h \ + axis2_ws_info.h \ + axis2_ws_info_list.h + +libaxis2_deployment_la_SOURCES =phases_info.c \ + desc_builder.c \ + arch_reader.c \ + dep_engine.c \ + arch_file_data.c \ + ws_info.c \ + ws_info_list.c \ + svc_builder.c \ + svc_grp_builder.c \ + module_builder.c \ + conf_builder.c \ + repos_listener.c \ + conf_init.c + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/src/core/util \ + -I$(top_builddir)/axiom/include \ + -I$(top_builddir)/neethi/include \ + -I$(top_builddir)/util/include diff --git a/src/core/deployment/arch_file_data.c b/src/core/deployment/arch_file_data.c new file mode 100644 index 0000000..b785399 --- /dev/null +++ b/src/core/deployment/arch_file_data.c @@ -0,0 +1,369 @@ +/* + * 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_arch_file_data.h> +#include <string.h> +#include <axutil_class_loader.h> + +struct axis2_arch_file_data +{ + axutil_file_t *file; + int type; + axis2_char_t *msg_recv; + axis2_char_t *module_name; + axis2_char_t *module_dll_name; + axis2_char_t *name; + /* + * To store services in a service group. Those services are temporarily + * stored in this table + */ + axutil_hash_t *svc_map; + axutil_array_list_t *deployable_svcs; + +}; + +AXIS2_EXTERN axis2_arch_file_data_t *AXIS2_CALL +axis2_arch_file_data_create( + const axutil_env_t * env) +{ + axis2_arch_file_data_t *arch_file_data = NULL; + arch_file_data = (axis2_arch_file_data_t *)AXIS2_MALLOC(env-> allocator, + sizeof(axis2_arch_file_data_t)); + + if(!arch_file_data) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)arch_file_data, 0, sizeof(axis2_arch_file_data_t)); + + arch_file_data->deployable_svcs = axutil_array_list_create(env, 0); + if(!arch_file_data->deployable_svcs) + { + axis2_arch_file_data_free(arch_file_data, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return arch_file_data; +} + +AXIS2_EXTERN axis2_arch_file_data_t *AXIS2_CALL +axis2_arch_file_data_create_with_type_and_file( + const axutil_env_t * env, + int type, + axutil_file_t * file) +{ + axis2_arch_file_data_t *arch_file_data = NULL; + arch_file_data = (axis2_arch_file_data_t *)axis2_arch_file_data_create(env); + if(!arch_file_data) + { + axis2_char_t *file_name = axutil_file_get_name(file, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create arch_file_data for file %s", + file_name); + return NULL; + } + + arch_file_data->type = type; + arch_file_data->file = axutil_file_clone(file, env); + return arch_file_data; +} + +AXIS2_EXTERN axis2_arch_file_data_t *AXIS2_CALL +axis2_arch_file_data_create_with_type_and_name( + const axutil_env_t * env, + int type, + const axis2_char_t * name) +{ + axis2_arch_file_data_t *arch_file_data = NULL; + arch_file_data = (axis2_arch_file_data_t *)axis2_arch_file_data_create(env); + if(!arch_file_data) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create arch_file_data for %s", name); + return NULL; + } + arch_file_data->type = type; + arch_file_data->name = axutil_strdup(env, name); + return arch_file_data; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_arch_file_data_free( + axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + if(arch_file_data->file) + { + axutil_file_free(arch_file_data->file, env); + } + if(arch_file_data->msg_recv) + { + AXIS2_FREE(env->allocator, arch_file_data->msg_recv); + } + if(arch_file_data->module_name) + { + AXIS2_FREE(env->allocator, arch_file_data->module_name); + } + if(arch_file_data->module_dll_name) + { + AXIS2_FREE(env->allocator, arch_file_data->module_dll_name); + } + if(arch_file_data->name) + { + AXIS2_FREE(env->allocator, arch_file_data->name); + } + + if(arch_file_data->svc_map) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + for(hi = axutil_hash_first(arch_file_data->svc_map, env); hi; hi + = axutil_hash_next(env, hi)) + { + axis2_svc_t *svc = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + svc = (axis2_svc_t *)val; + if(svc) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Service name :%s", axis2_svc_get_name(svc, + env)); + axis2_svc_free(svc, env); + } + } + axutil_hash_free(arch_file_data->svc_map, env); + } + if(arch_file_data->deployable_svcs) + { + axutil_array_list_free(arch_file_data->deployable_svcs, env); + } + + if(arch_file_data) + { + AXIS2_FREE(env->allocator, arch_file_data); + } + + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_arch_file_data_get_msg_recv( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + return arch_file_data->msg_recv; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_arch_file_data_set_msg_recv( + axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env, + axis2_char_t * msg_recv) +{ + AXIS2_PARAM_CHECK(env->error, msg_recv, AXIS2_FAILURE); + + if(arch_file_data->msg_recv) + { + AXIS2_FREE(env->allocator, arch_file_data->msg_recv); + arch_file_data->msg_recv = NULL; + } + arch_file_data->msg_recv = axutil_strdup(env, msg_recv); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_arch_file_data_get_name( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + return axutil_file_get_name(arch_file_data->file, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_arch_file_data_get_svc_name( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + axis2_char_t *svc_name = NULL; + + if(arch_file_data->file) + { + svc_name = axutil_file_get_name(arch_file_data->file, env); + } + else + { + svc_name = arch_file_data->name; + } + + return svc_name; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_arch_file_data_get_type( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + return arch_file_data->type; +} + +AXIS2_EXTERN axutil_file_t *AXIS2_CALL +axis2_arch_file_data_get_file( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + return arch_file_data->file; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_arch_file_data_get_module_name( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + axis2_char_t *module_name = NULL; + + if(arch_file_data->file) + { + module_name = axutil_file_get_name(arch_file_data->file, env); + } + else + { + module_name = arch_file_data->module_name; + } + return module_name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_arch_file_data_set_module_name( + axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env, + axis2_char_t * module_name) +{ + AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE); + + if(arch_file_data->module_name) + { + AXIS2_FREE(env->allocator, arch_file_data->module_name); + arch_file_data->module_name = NULL; + } + arch_file_data->module_name = axutil_strdup(env, module_name); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_arch_file_data_get_module_dll_name( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + return arch_file_data->module_dll_name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_arch_file_data_set_module_dll_name( + axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env, + axis2_char_t * module_dll_name) +{ + AXIS2_PARAM_CHECK(env->error, module_dll_name, AXIS2_FAILURE); + + if(arch_file_data->module_dll_name) + { + AXIS2_FREE(env->allocator, arch_file_data->module_dll_name); + arch_file_data->module_dll_name = NULL; + } + arch_file_data->module_dll_name = axutil_strdup(env, module_dll_name); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_arch_file_data_add_svc( + axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env, + axis2_svc_t * svc_desc) +{ + const axutil_qname_t *svc_qname = NULL; + axis2_char_t *svc_name = NULL; + AXIS2_PARAM_CHECK(env->error, svc_desc, AXIS2_FAILURE); + + svc_qname = axis2_svc_get_qname(svc_desc, env); + svc_name = axutil_qname_to_string((axutil_qname_t *)svc_qname, env); + if(!arch_file_data->svc_map) + { + arch_file_data->svc_map = axutil_hash_make(env); + if(!arch_file_data->svc_map) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + axutil_hash_set(arch_file_data->svc_map, svc_name, AXIS2_HASH_KEY_STRING, svc_desc); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN struct axis2_svc *AXIS2_CALL +axis2_arch_file_data_get_svc( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env, + axis2_char_t * svc_name) +{ + axis2_svc_t *svc = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_name, NULL); + + if(arch_file_data->svc_map) + { + svc = (axis2_svc_t *)axutil_hash_get(arch_file_data->svc_map, svc_name, + AXIS2_HASH_KEY_STRING); + } + else + { + return NULL; + } + return svc; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_arch_file_data_get_svc_map( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + return arch_file_data->svc_map; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_arch_file_data_get_deployable_svcs( + const axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env) +{ + return arch_file_data->deployable_svcs; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_arch_file_data_set_deployable_svcs( + axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env, + axutil_array_list_t * deployable_svcs) +{ + AXIS2_PARAM_CHECK(env->error, deployable_svcs, AXIS2_FAILURE); + if(arch_file_data->deployable_svcs) + { + AXIS2_FREE(env->allocator, arch_file_data->deployable_svcs); + arch_file_data->deployable_svcs = NULL; + } + arch_file_data->deployable_svcs = deployable_svcs; + return AXIS2_SUCCESS; +} + diff --git a/src/core/deployment/arch_reader.c b/src/core/deployment/arch_reader.c new file mode 100644 index 0000000..3403d8e --- /dev/null +++ b/src/core/deployment/arch_reader.c @@ -0,0 +1,313 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_arch_reader.h> +#include <string.h> +#include <axutil_class_loader.h> +#include <axis2_svc_builder.h> +#include <axis2_module_builder.h> +#include <axis2_svc.h> + +struct axis2_arch_reader +{ + axis2_desc_builder_t *desc_builder; +}; + +AXIS2_EXTERN axis2_arch_reader_t *AXIS2_CALL +axis2_arch_reader_create( + const axutil_env_t * env) +{ + axis2_arch_reader_t *arch_reader = NULL; + + arch_reader = (axis2_arch_reader_t *)AXIS2_MALLOC(env-> allocator, sizeof(axis2_arch_reader_t)); + + if(!arch_reader) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + arch_reader->desc_builder = NULL; + + return arch_reader; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_arch_reader_free( + axis2_arch_reader_t * arch_reader, + const axutil_env_t * env) +{ + /* Description builder is owned by dep_engine, so do not free it here */ + + if(arch_reader) + { + AXIS2_FREE(env->allocator, arch_reader); + } + + return; +} + +AXIS2_EXTERN struct axis2_svc *AXIS2_CALL +axis2_arch_reader_create_svc( + const axutil_env_t * env, + struct axis2_arch_file_data *file) +{ + axis2_svc_t *svc = NULL; + svc = axis2_svc_create(env); + return svc; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_arch_reader_process_svc_grp( + axis2_arch_reader_t * arch_reader, + const axutil_env_t * env, + axis2_char_t * file_name, + struct axis2_dep_engine * dep_engine, + axis2_svc_grp_t * svc_grp) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *svc_grp_xml = NULL; + axis2_char_t *repos_path = NULL; + axis2_bool_t file_flag = AXIS2_FALSE; + AXIS2_PARAM_CHECK(env->error, file_name, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, svc_grp, AXIS2_FAILURE); + + file_flag = axis2_dep_engine_get_file_flag(dep_engine, env); + + if(!file_flag) + { + + repos_path = axis2_dep_engine_get_repos_path(dep_engine, env); + + svc_grp_xml = axutil_strcat(env, repos_path, AXIS2_PATH_SEP_STR, AXIS2_SERVICE_FOLDER, + AXIS2_PATH_SEP_STR, file_name, AXIS2_PATH_SEP_STR, AXIS2_SVC_XML, NULL); + } + else + { + repos_path = axis2_dep_engine_get_svc_dir(dep_engine, env); + svc_grp_xml = axutil_strcat(env, repos_path, AXIS2_PATH_SEP_STR, file_name, + AXIS2_PATH_SEP_STR, AXIS2_SVC_XML, NULL); + } + + if(!svc_grp_xml) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service xml file not found for %s", file_name); + return AXIS2_FAILURE; + } + status = axutil_file_handler_access(svc_grp_xml, AXIS2_F_OK); + if(AXIS2_SUCCESS == status) + { + struct axis2_arch_file_data *arch_file_data = NULL; + axis2_char_t *svc_name = NULL; + + status + = axis2_arch_reader_build_svc_grp(arch_reader, env, svc_grp_xml, dep_engine, svc_grp); + if(AXIS2_SUCCESS != status) + { + return status; + } + arch_file_data = axis2_dep_engine_get_current_file_item(dep_engine, env); + svc_name = axis2_arch_file_data_get_svc_name(arch_file_data, env); + axis2_svc_grp_set_name(svc_grp, env, svc_name); + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SERVICE_XML_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Access to service configuration file %s failed", + file_name); + status = AXIS2_FAILURE; + } + AXIS2_FREE(env->allocator, svc_grp_xml); + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_arch_reader_build_svc_grp( + axis2_arch_reader_t * arch_reader, + const axutil_env_t * env, + axis2_char_t * svc_xml, + axis2_dep_engine_t * dep_engine, + axis2_svc_grp_t * svc_grp) +{ + axis2_char_t *root_element_name = NULL; + axiom_node_t *svc_grp_node = NULL; + axiom_element_t *svc_grp_element = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, svc_xml, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, svc_grp, AXIS2_FAILURE); + + arch_reader->desc_builder = axis2_desc_builder_create_with_file_and_dep_engine(env, svc_xml, + dep_engine); + if(!arch_reader->desc_builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating description builder for service file %s failed", svc_xml); + return AXIS2_FAILURE; + } + axis2_dep_engine_add_desc_builder(dep_engine, env, arch_reader->desc_builder); + + svc_grp_node = axis2_desc_builder_build_om(arch_reader->desc_builder, env); + + if(svc_grp_node) + { + svc_grp_element = axiom_node_get_data_element(svc_grp_node, env); + if(svc_grp_element) + { + root_element_name = axiom_element_get_localname(svc_grp_element, env); + } + } + + if(root_element_name && 0 == axutil_strcmp(AXIS2_SVC_ELEMENT, root_element_name)) + { + /* If service group is actually a service. In this case service group + * contain only single service */ + axis2_svc_t *svc = NULL; + axis2_svc_builder_t *svc_builder = NULL; + axis2_arch_file_data_t *file_data = NULL; + axutil_array_list_t *dep_svcs = NULL; + axis2_char_t *svc_name = NULL; + + file_data = axis2_dep_engine_get_current_file_item(dep_engine, env); + svc_name = axis2_arch_file_data_get_name(file_data, env); + svc = axis2_arch_file_data_get_svc(file_data, env, svc_name); + if(!svc) + { + axutil_qname_t *svc_qname = NULL; + + svc_qname = axutil_qname_create(env, svc_name, NULL, NULL); + svc = axis2_svc_create_with_qname(env, svc_qname); + status = axis2_arch_file_data_add_svc(file_data, env, svc); + axutil_qname_free(svc_qname, env); + if(AXIS2_SUCCESS != status) + { + axis2_svc_free(svc, env); + return status; + } + } + axis2_svc_set_parent(svc, env, svc_grp); + + svc_builder = axis2_svc_builder_create_with_dep_engine_and_svc(env, dep_engine, svc); + status = axis2_svc_builder_populate_svc(svc_builder, env, svc_grp_node); + axis2_dep_engine_add_svc_builder(dep_engine, env, svc_builder); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Populating service failed for %s", svc_name); + return AXIS2_FAILURE; + } + + dep_svcs = axis2_arch_file_data_get_deployable_svcs(file_data, env); + if(!dep_svcs) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Deployable services list is NULL within arch file data"); + return AXIS2_FAILURE; + } + status = axutil_array_list_add(dep_svcs, env, svc); + if(AXIS2_SUCCESS != status) + { + return AXIS2_FAILURE; + } + + } + else if(root_element_name && 0 == axutil_strcmp(AXIS2_SVC_GRP_ELEMENT, root_element_name)) + { + axis2_svc_grp_builder_t *grp_builder = NULL; + grp_builder = axis2_svc_grp_builder_create_with_svc_and_dep_engine(env, svc_grp_node, + dep_engine); + status = axis2_svc_grp_builder_populate_svc_grp(grp_builder, env, svc_grp); + axis2_dep_engine_add_svc_grp_builder(dep_engine, env, grp_builder); + } + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_arch_reader_read_module_arch( + const axutil_env_t * env, + axis2_char_t * file_name, + axis2_dep_engine_t * dep_engine, + axis2_module_desc_t * module_desc) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *module_xml = NULL; + axis2_char_t *repos_path = NULL; + axis2_bool_t file_flag; + + AXIS2_PARAM_CHECK(env->error, file_name, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + + file_flag = axis2_dep_engine_get_file_flag(dep_engine, env); + if(!file_flag) + { + repos_path = axis2_dep_engine_get_repos_path(dep_engine, env); + module_xml = axutil_strcat(env, repos_path, AXIS2_PATH_SEP_STR, AXIS2_MODULE_FOLDER, + AXIS2_PATH_SEP_STR, file_name, AXIS2_PATH_SEP_STR, AXIS2_MODULE_XML, NULL); + } + else + { + repos_path = axis2_dep_engine_get_module_dir(dep_engine, env); + module_xml = axutil_strcat(env, repos_path, AXIS2_PATH_SEP_STR, file_name, + AXIS2_PATH_SEP_STR, AXIS2_MODULE_XML, NULL); + } + + if(!module_xml) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + status = axutil_file_handler_access(module_xml, AXIS2_F_OK); + + if(AXIS2_SUCCESS == status) + { + axis2_module_builder_t *module_builder = NULL; + module_builder = axis2_module_builder_create_with_file_and_dep_engine_and_module(env, + module_xml, dep_engine, module_desc); + status = axis2_module_builder_populate_module(module_builder, env); + axis2_dep_engine_add_module_builder(dep_engine, env, module_builder); + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_XML_NOT_FOUND_FOR_THE_MODULE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Module configuration file access failed for module file %s", module_xml); + status = AXIS2_FAILURE; + } + AXIS2_FREE(env->allocator, module_xml); + return status; +} + +AXIS2_EXTERN axutil_file_t *AXIS2_CALL +axis2_arch_reader_create_module_arch( + const axutil_env_t * env, + axis2_char_t * module_name) +{ + axutil_file_t *file = NULL; + + file = axutil_file_create(env); + if(!file) + { + return NULL; + } + axutil_file_set_name(file, env, module_name); + return file; +} + diff --git a/src/core/deployment/axis2_arch_file_data.h b/src/core/deployment/axis2_arch_file_data.h new file mode 100644 index 0000000..d27d065 --- /dev/null +++ b/src/core/deployment/axis2_arch_file_data.h @@ -0,0 +1,265 @@ + +/* + * 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_ARCH_FILE_DATA_H +#define AXIS2_ARCH_FILE_DATA_H + +/** @defgroup axis2_arch_file_data Arch File Data + * @ingroup axis2_deployment + * @{ + */ + +/** + * @file axis2_arch_file_data.h + * @brief Axis2 Arch File Data interface. arch_file_data construct contain + * deployment information retrieved from a module or service configuration file. + */ +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include <axis2_conf.h> +#include <axutil_array_list.h> +#include <axutil_dir_handler.h> +#include <axutil_file.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct axis2_conf; + + /** Type name for struct axis2_arch_fila_data */ + typedef struct axis2_arch_file_data axis2_arch_file_data_t; + + /** + * De-allocate memory + * @param arch_file_data pointer to arch_file_data + * @param env pointer to environment struct + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_arch_file_data_free( + axis2_arch_file_data_t * arch_file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axis2_arch_file_data_get_msg_recv( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + * @param msg_recv pointer to message receiver + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_arch_file_data_set_msg_recv( + axis2_arch_file_data_t * file_data, + const axutil_env_t * env, + axis2_char_t * msg_recv); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + * @return the name of the contained file. + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axis2_arch_file_data_get_name( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + * @return the service name. If contained file is not null this is the + * file name. else this is the name property + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axis2_arch_file_data_get_svc_name( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + */ + AXIS2_EXTERN int AXIS2_CALL + axis2_arch_file_data_get_type( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + */ + AXIS2_EXTERN axutil_file_t *AXIS2_CALL + axis2_arch_file_data_get_file( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + + axis2_arch_file_data_get_module_name( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + * @param module_name pointer to module_name + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_arch_file_data_set_module_name( + axis2_arch_file_data_t * file_data, + const axutil_env_t * env, + axis2_char_t * module_name); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + + axis2_arch_file_data_get_module_dll_name( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_arch_file_data_set_module_dll_name( + axis2_arch_file_data_t * file_data, + const axutil_env_t * env, + axis2_char_t * module_dll_name); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_arch_file_data_add_svc( + axis2_arch_file_data_t * file_data, + const axutil_env_t * env, + struct axis2_svc *svc_desc); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + */ + AXIS2_EXTERN struct axis2_svc *AXIS2_CALL + axis2_arch_file_data_get_svc( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env, + axis2_char_t * svc_name); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + */ + AXIS2_EXTERN axutil_hash_t *AXIS2_CALL + axis2_arch_file_data_get_svc_map( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + */ + AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL + + axis2_arch_file_data_get_deployable_svcs( + const axis2_arch_file_data_t * file_data, + const axutil_env_t * env); + + /** + * @param file_data pointer to arch_file_data + * @param env pointer to environment struct + * @param deployable_svcs pointer to deployable services + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_arch_file_data_set_deployable_svcs( + axis2_arch_file_data_t * file_data, + const axutil_env_t * env, + axutil_array_list_t * deployable_svcs); + + /** + * Creates arch file data struct + * @param env pointer to environment struct + * @return pointer to newly created arch file data + */ + AXIS2_EXTERN axis2_arch_file_data_t *AXIS2_CALL + + axis2_arch_file_data_create( + const axutil_env_t * env); + + /** + * Creates arch file data struct + * @param env pointer to environment struct + * @param type type + * @param file folder name of service or module + * @return pointer to newly created arch file data + */ + AXIS2_EXTERN axis2_arch_file_data_t *AXIS2_CALL + + axis2_arch_file_data_create_with_type_and_file( + const axutil_env_t * env, + int type, + axutil_file_t * file); + + /** + * Creates arch file data struct + * @param env pointer to environment struct + * @param type type + * @param name pointer to name + * @return pointer to newly created arch file data + */ + AXIS2_EXTERN axis2_arch_file_data_t *AXIS2_CALL + + axis2_arch_file_data_create_with_type_and_name( + const axutil_env_t * env, + int type, + const axis2_char_t * name); + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_ARCH_FILE_DATA_H */ diff --git a/src/core/deployment/axis2_arch_reader.h b/src/core/deployment/axis2_arch_reader.h new file mode 100644 index 0000000..274ded2 --- /dev/null +++ b/src/core/deployment/axis2_arch_reader.h @@ -0,0 +1,152 @@ + +/* + * 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_ARCH_READER_H +#define AXIS2_ARCH_READER_H + +/** @defgroup axis2_arch_reader Arch Reader + * @ingroup axis2_deployment + * @{ + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include <axis2_conf.h> +#include <axis2_deployment.h> +#include <axis2_arch_file_data.h> +#include <axis2_dep_engine.h> +#include <axutil_file_handler.h> +#include <axiom_element.h> +#include <axis2_desc_builder.h> +#include <axis2_svc_grp_builder.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct axis2_conf; + struct axis2_arch_file_data; + struct axis2_dep_engine; + + /** Type name for struct axis2_arch_reader */ + typedef struct axis2_arch_reader axis2_arch_reader_t; + + /** + * De-allocate memory + * @param arch_reader pointer to arch reader + * @param env pointer to environment struct + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_arch_reader_free( + axis2_arch_reader_t * arch_reader, + const axutil_env_t * env); + + /** + * To create a service descrption <code>axis2_svc_t</code> using given + * deployment info file. + * @param env pointer to environment struct + * @param file pointer to file + */ + AXIS2_EXTERN struct axis2_svc *AXIS2_CALL + axis2_arch_reader_create_svc( + const axutil_env_t * env, + struct axis2_arch_file_data *file); + + /** + * Construct the path to the service group configuration file(services.xml) + * using the passed file name and populate the passed service group + * description. + * @param arch_reader pointer to arch reader + * @param env pointer to environment struct + * @param file_name pointer to service group configuration file. + * @param dep_engine pointer to deployment engine + * @param svc_grp pointer to service group to be populated. + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_arch_reader_process_svc_grp( + axis2_arch_reader_t * arch_reader, + const axutil_env_t * env, + axis2_char_t * file_name, + struct axis2_dep_engine *dep_engine, + axis2_svc_grp_t * svc_grp); + + /** + * Populate the passed service group description using the service group + * configuration file(services.xml). + * @param arch_reader pointer to arch reader + * @param env pointer to environment struct + * @param file_path path to the service group configuration file(services.xml) + * @param dep_engine pointer to deployment engine + * @param svc_grp pointer to service group + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_arch_reader_build_svc_grp( + axis2_arch_reader_t * arch_reader, + const axutil_env_t * env, + axis2_char_t * file_path, + struct axis2_dep_engine *dep_engine, + struct axis2_svc_grp *svc_grp); + + /** + * Construct the path to the module configuration file(module.xml) + * using the passed file name and populate the passed module description. + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_arch_reader_read_module_arch( + const axutil_env_t * env, + axis2_char_t * file_path, + struct axis2_dep_engine *dep_engine, + axis2_module_desc_t * module); + + /** + * Create an axis2 file using the passed module name. + * @param env pointer to environment struct + * @param module_name pointer to module name + */ + AXIS2_EXTERN axutil_file_t *AXIS2_CALL + + axis2_arch_reader_create_module_arch( + const axutil_env_t * env, + axis2_char_t * module_name); + + /** + * Creates arch reader struct + * @param env pointer to environment struct + * @return pointer to newly created arch reader + */ + AXIS2_EXTERN axis2_arch_reader_t *AXIS2_CALL + axis2_arch_reader_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_ARCH_READER_H */ diff --git a/src/core/deployment/axis2_conf_builder.h b/src/core/deployment/axis2_conf_builder.h new file mode 100644 index 0000000..9a0aa91 --- /dev/null +++ b/src/core/deployment/axis2_conf_builder.h @@ -0,0 +1,116 @@ + +/* + * 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_CONF_BUILDER_H +#define AXIS2_CONF_BUILDER_H + +/** + * @defgroup axis2_conf_builder Conf Builder + * @ingroup axis2_deployment + * @{ + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include "axis2_desc_builder.h" +#include <axis2_conf.h> +#include "axis2_dep_engine.h" +#include <axiom_children_qname_iterator.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct axis2_desc_builder; + struct axis2_dep_engine; + + /** Type name for struct axis2_conf_builder */ + typedef struct axis2_conf_builder axis2_conf_builder_t; + + /** + * De-allocate memory + * @param conf_builder pointer to configuration builder + * @param env pointer to environment struct + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_conf_builder_free( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env); + + /** + * @param conf_builder pointer to configuration builder + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_conf_builder_populate_conf( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env); + + /** + * To get the list og modules that is requird to be engage globally + * @param conf_builder pointer to configuration builder + * @param env pointer to environment struct + * @param module_refs pointer to module refs + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_conf_builder_process_module_refs( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_refs); + + /** + * Creates conf builder struct + * @param env pointer to environment struct + * @return pointer to newly created conf builder + */ + AXIS2_EXTERN axis2_conf_builder_t *AXIS2_CALL + axis2_conf_builder_create( + const axutil_env_t * env); + + /** + * Creates conf builder struct + * @param env pointer to environment struct + * @param file This is the full path to the server xml file + * @param dep_engine pointer to dep engine + * @param conf pointer to conf + * @return pointer to newly created conf builder + */ + + AXIS2_EXTERN axis2_conf_builder_t *AXIS2_CALL + + axis2_conf_builder_create_with_file_and_dep_engine_and_conf( + const axutil_env_t * env, + axis2_char_t * file, + struct axis2_dep_engine *dep_engine, + axis2_conf_t * conf); + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_CONF_BUILDER_H */ diff --git a/src/core/deployment/axis2_dep_engine.h b/src/core/deployment/axis2_dep_engine.h new file mode 100644 index 0000000..a9130af --- /dev/null +++ b/src/core/deployment/axis2_dep_engine.h @@ -0,0 +1,418 @@ + +/* + * 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_DEP_ENGINE_H +#define AXIS2_DEP_ENGINE_H + +/** + * @defgroup axis2_dep_engine Deployment Engine + * @ingroup axis2_deployment + * @{ + */ + +/** + * @file axis2_dep_engine.h + * @brief Axis2 Deployment Engine interface + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include "axis2_arch_file_data.h" +#include "axis2_ws_info.h" +#include "axis2_conf_builder.h" +#include "axis2_repos_listener.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + struct axis2_arch_file_data; + struct axis2_arch_reader; + struct axis2_ws_info; + struct axis2_phases_info; + struct axis2_svc; + + /** Type name for struct axis2_dep_engine */ + typedef struct axis2_dep_engine axis2_dep_engine_t; + struct axis2_desc_builder; + struct axis2_module_builder; + struct axis2_svc_builder; + struct axis2_grp_builder; + struct axis2_svc_grp_builder; + + /** + * De-allocate memory + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_dep_engine_free( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * while parsing the axis2.xml the module refferences have to be stored some + * where , since at that time none of module availble (they load after parsing + * the document) + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param module_qname <code>QName</code> + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_add_module( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axutil_qname_t * module_qname); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param module_name pointer to module name + */ + AXIS2_EXTERN struct axis2_module_desc *AXIS2_CALL + + axis2_dep_engine_get_module( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axutil_qname_t * module_name); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + */ + AXIS2_EXTERN struct axis2_arch_file_data *AXIS2_CALL + + axis2_dep_engine_get_current_file_item( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param file pointer to file + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_add_ws_to_deploy( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_arch_file_data *file); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param file pointer to file + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_dep_engine_add_ws_to_undeploy( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_ws_info *file); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + */ + AXIS2_EXTERN struct axis2_phases_info *AXIS2_CALL + axis2_dep_engine_get_phases_info( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @return AxisConfiguration <code>AxisConfiguration</code> + */ + AXIS2_EXTERN struct axis2_conf *AXIS2_CALL + axis2_dep_engine_get_axis_conf( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + */ + AXIS2_EXTERN struct axis2_conf *AXIS2_CALL + axis2_dep_engine_load( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + */ + AXIS2_EXTERN struct axis2_conf *AXIS2_CALL + axis2_dep_engine_load_client( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + const axis2_char_t * client_home); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param dll_name pointer to dll_name + */ + AXIS2_EXTERN void *AXIS2_CALL + axis2_dep_engine_get_handler_dll( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_char_t * dll_name); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_do_deploy( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_undeploy( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_dep_engine_is_hot_update( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param phases_info pointer to phases info + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_set_phases_info( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_phases_info *phases_info); + + /** + * This method is used to fill a axisservice object using services.xml , first it should create + * an axisservice object using WSDL and then fill that using given servic.xml and load all the requed + * class and build the chains , finally add the servicecontext to EngineContext and axisservice into + * EngineConfiguration + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param svc pointer to service + * @param file_name pointer to file name + */ + AXIS2_EXTERN struct axis2_svc *AXIS2_CALL + axis2_dep_engine_build_svc( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_svc *svc, + axis2_char_t * file_name); + + /** + * This method can be used to build ModuleDescription for a given module archiev file + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param module_archive pointer to module archive + * @param conf pointer to conf + */ + AXIS2_EXTERN struct axis2_module_desc *AXIS2_CALL + axis2_dep_engine_build_module( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axutil_file_t * module_archive, + struct axis2_conf *conf); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axis2_dep_engine_get_repos_path( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to module directory + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_dep_engine_get_file_flag( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + + /** + * @param dep_engine pointer to module directory + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axis2_dep_engine_get_module_dir( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + /** + * @param dep_engine pointer to module directory + * @param env pointer to environment struct + * @param module_dir pointer of the directory path + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_set_module_dir( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + const axis2_char_t *module_dir); + + + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axis2_dep_engine_get_svc_dir( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_set_svc_dir( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + const axis2_char_t *svc_dir); + + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param file_data pointer to file data + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_set_current_file_item( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_arch_file_data *file_data); + + /** + * @param dep_engine pointer to deployment engine + * @param env pointer to environment struct + * @param arch_reader pointer to arch reader + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_set_arch_reader( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_arch_reader *arch_reader); + + /** + * No param constructor is need to deploye module and service programatically + * @param env pointer to environment struct + * @return pointer to newly created deployment engine + */ + AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL + axis2_dep_engine_create( + const axutil_env_t * env); + + /** + * Creates description builder struct + * This the constructor which is used by Engine in order to start + * Deployment module, + * @param env pointer to environment struct + * @param repos_path is the path to which Repositary Listner should listen. + * @return pointer to newly created deployment engine + */ + AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL + axis2_dep_engine_create_with_repos_name( + const axutil_env_t * env, + const axis2_char_t * repos_path); + + + /** + * Creates description builder struct using axis2 xml + * This the constructor which is used by Engine in order to start + * Deployment module, + * @param env pointer to environment struct + * @param axis2_xml is the path of the axis2.xml . + * @return pointer to newly created deployment engine + */ + AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL + axis2_dep_engine_create_with_axis2_xml( + const axutil_env_t * env, + const axis2_char_t * axis2_xml); + + + /** + * Creates deployment engine struct + * @param env pointer to environment struct + * @param repos_path is the path to which Repositary Listner should listen. + * @param svr_xml_file pointer to service xml file + * @return pointer to newly created deployment engine + */ + AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL + + axis2_dep_engine_create_with_repos_name_and_svr_xml_file( + const axutil_env_t * env, + const axis2_char_t * repos_path, + const axis2_char_t * svr_xml_file); + + AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL + axis2_dep_engine_create_with_svr_xml_file( + const axutil_env_t * env, + const axis2_char_t * svr_xml_file); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_add_desc_builder( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_desc_builder *desc_builder); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_add_module_builder( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_module_builder *module_builder); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_dep_engine_add_svc_builder( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_svc_builder *svc_builder); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_dep_engine_add_svc_grp_builder( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_svc_grp_builder *svc_grp_builder); + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_DEP_ENGINE_H */ diff --git a/src/core/deployment/axis2_deployment.h b/src/core/deployment/axis2_deployment.h new file mode 100644 index 0000000..044f10f --- /dev/null +++ b/src/core/deployment/axis2_deployment.h @@ -0,0 +1,119 @@ + +/* + * 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_DEPLOYMENT_H +#define AXIS2_DEPLOYMENT_H + +/** + * @file axis2_axis2_deployment.h + * @brief axis2 deployment + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_string.h> +#include <axutil_hash.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*********************************** Constansts********************************/ + +/** + * DeployCons interface is to keep constent value required for Deployemnt + */ + +#define AXIS2_SVC 0 /* if it is a service */ +#define AXIS2_MODULE 1 /* if it is a module */ + +#define AXIS2_SVC_XML "services.xml" +#define AXIS2_MODULE_XML "module.xml" +#define AXIS2_PARAMETERST "parameter" /* paramater start tag */ +#define AXIS2_HANDLERST "handler" +#define AXIS2_MODULEST "module" +#define AXIS2_PHASEST "phase" +#define AXIS2_PHASE_ORDER "phaseOrder" +#define AXIS2_OPERATIONST "operation" /* operation start tag */ +#define AXIS2_IN_FLOW_START "inflow" /* inflow start tag */ +#define AXIS2_OUT_FLOW_START "outflow" /* outflowr start tag */ +#define AXIS2_IN_FAILTFLOW "INfaultflow" /* faultflow start tag */ +#define AXIS2_OUT_FAILTFLOW "Outfaultflow" /* faultflow start tag */ + +#define AXIS2_MODULE_PATH "modules" +#define AXIS2_SVC_PATH "services" + +/* for parameters */ +#define AXIS2_ATTNAME "name" +#define AXIS2_ATTLOCKED "locked" +#define AXIS2_TYPE "type" + +/* for operations */ +#define AXIS2_MEP "mep" + +/* for messages */ +#define AXIS2_MESSAGE "message" +#define AXIS2_LABEL "label" + +/* for handlers */ +#define AXIS2_REF "ref" +#define AXIS2_CLASSNAME "class" +#define AXIS2_BEFORE "before" +#define AXIS2_AFTER "after" +#define AXIS2_PHASE "phase" +#define AXIS2_PHASEFIRST "phaseFirst" +#define AXIS2_PHASELAST "phaseLast" +#define AXIS2_ORDER "order" /* to resolve the order tag */ +#define AXIS2_DESCRIPTION "description" + +#define AXIS2_TRANSPORTSENDER "transportSender" +#define AXIS2_TRANSPORTRECEIVER "transportReceiver" + +#define AXIS2_MESSAGERECEIVER "messageReceiver" + +#define AXIS2_HOTDEPLOYMENT "hotdeployment" +#define AXIS2_HOTUPDATE "hotupdate" +#define AXIS2_DISPATCH_ORDER "dispatchOrder" +#define AXIS2_DISPATCHER "dispatcher" + +/* element in a services.xml */ +#define AXIS2_SVC_ELEMENT "service" +#define AXIS2_SVC_WSDL_PATH "wsdl_path" +#define AXIS2_SVC_GRP_ELEMENT "serviceGroup" + +#define AXIS2_SERVER_XML_FILE "axis2.xml" + +#define AXIS2_MODULE_FOLDER "modules" +#define AXIS2_SERVICE_FOLDER "services" +#define AXIS2_LIB_FOLDER "lib" +#define AXIS2_LIB_DIR "libDir" + +#define AXIS2_ATTRIBUTE_DEFAULT_VERSION "version" +#define AXIS2_DEFAULT_MODULE_VERSION "defaultModuleVersions" + +/*********************************** Constants*********************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_DEPLOYMENT_H */ diff --git a/src/core/deployment/axis2_desc_builder.h b/src/core/deployment/axis2_desc_builder.h new file mode 100644 index 0000000..347f592 --- /dev/null +++ b/src/core/deployment/axis2_desc_builder.h @@ -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. + */ + +#ifndef AXIS2_DESC_BUILDER_H +#define AXIS2_DESC_BUILDER_H + +/** @defgroup axis2_desc_builder Description Builder + * @ingroup axis2_deployment + * @{ + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include "axis2_deployment.h" +#include "axis2_dep_engine.h" +#include <axis2_flow.h> +#include <axiom_stax_builder.h> +#include <axiom_document.h> +#include <axiom_element.h> +#include <axiom_node.h> +#include <axutil_param_container.h> +#include <axis2_handler_desc.h> +#include <axiom_attribute.h> +#include <axiom_xml_reader.h> +#include <axis2_handler_desc.h> +#include <axis2_op.h> +#include <axiom_children_with_specific_attribute_iterator.h> +#include <axis2_phase.h> +#include <axis2_core_dll_desc.h> +#include <axis2_policy_include.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct axis2_flow; + struct axis2_phase; + struct axis2_dep_engine; + + /** Type name for struct axis2_desc_builder */ + typedef struct axis2_desc_builder axis2_desc_builder_t; + + /** + * De-allocate memory + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_desc_builder_free( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env); + + /** + * This will creat OMElemnt for a given descrition document (axis2.xml , + * services.xml and module.xml) + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @return OMElement <code>OMElement</code> + */ + AXIS2_EXTERN axiom_node_t *AXIS2_CALL + axis2_desc_builder_build_om( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env); + + /** + * To process Flow elements in services.xml + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @param flow_element <code>axiom_element_t</code> + * @param parent pointer to parent + * @param node pointer to node + * @return flow + */ + AXIS2_EXTERN axis2_flow_t *AXIS2_CALL + axis2_desc_builder_process_flow( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_element_t * flow_element, + axutil_param_container_t * parent, + axiom_node_t * node); + + /** + * To process Handler element + * @param handler_element <code>OMElement</code> + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @param handler_element pointer to handler element + * @param parent pointer to parent + */ + AXIS2_EXTERN axis2_handler_desc_t *AXIS2_CALL + + axis2_desc_builder_process_handler( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_node_t * handler_element, + axutil_param_container_t * parent); + + /** + * To get the Param out from the OM + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @param params <code>axutil_param_t</code> + * @param param_container <code>axutil_param_container_t</code> + * @param parent <code>axutil_param_container_t</code> + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_desc_builder_process_params( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * params, + axutil_param_container_t * param_container, + axutil_param_container_t * parent); + + /** + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @param module_refs pointer to module refs + * @param op pointer to op + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_desc_builder_process_op_module_refs( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_refs, + axis2_op_t * op); + + /** + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @param recv_element pointer to recv element + */ + AXIS2_EXTERN axis2_msg_recv_t *AXIS2_CALL + + axis2_desc_builder_load_msg_recv( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_element_t * recv_element); + + /** + * This method is used to retrive service name form the arechive file name + * if the archive file name is service1.aar , then axis service name would be service1 + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @param file_name pointer to file name + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + + axis2_desc_builder_get_short_file_name( + const axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axis2_char_t * file_name); + + /** + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @param short_file_name pointer to short file name + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + + axis2_desc_builder_get_file_name_without_prefix( + const axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axis2_char_t * short_file_name); + + /** + * this method is to get the value of attribue + * eg xsd:anyVal --> anyVal + * @param desc_builder pointer to desc builder + * @param env pointer to environment struct + * @param in pointer to in + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axis2_desc_builder_get_value( + const axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axis2_char_t * in); + + /** + * Populate the Axis2 Operation with details from the actionMapping, + * outputActionMapping and faultActionMapping elements from the operation + * element. + * @param operation + * @param op_desc + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_desc_builder_process_action_mappings( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_node_t * op_node, + axis2_op_t * op_desc); + + /** + * Populate the Axis2 Operation with details from the RESTLocation, + * RESTMethod elements from the operation element. + * @param operation + * @param op_desc + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_desc_builder_process_rest_params( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_node_t * op_node, + axis2_op_t * op_desc); + + /** + * @param env pointer to environment struct + */ + AXIS2_EXTERN struct axis2_msg_recv *AXIS2_CALL + axis2_desc_builder_load_default_msg_recv( + const axutil_env_t * env); + + AXIS2_EXTERN struct axis2_dep_engine *AXIS2_CALL + axis2_desc_builder_get_dep_engine( + const axis2_desc_builder_t * desc_builder, + const axutil_env_t * env); + + /** + * Creates description builder struct + * @param env pointer to environment struct + * @return pointer to newly created description builder + */ + AXIS2_EXTERN axis2_desc_builder_t *AXIS2_CALL + axis2_desc_builder_create( + const axutil_env_t * env); + + /** + * Creates description builder struct + * @param env pointer to environment struct + * @param engine pointer to engine + * @return pointer to newly created description builder + */ + AXIS2_EXTERN axis2_desc_builder_t *AXIS2_CALL + + axis2_desc_builder_create_with_dep_engine( + const axutil_env_t * env, + struct axis2_dep_engine *engine); + + /** + * Creates description builder struct + * @param env pointer to environment struct + * @param file_name pointer to file name + * @param engine pointer to engine + * @return pointer to newly created description builder + */ + AXIS2_EXTERN axis2_desc_builder_t *AXIS2_CALL + + axis2_desc_builder_create_with_file_and_dep_engine( + const axutil_env_t * env, + axis2_char_t * file_name, + struct axis2_dep_engine *engine); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_process_policy_elements( + const axutil_env_t * env, + int type, + axiom_children_qname_iterator_t * iterator, + axis2_policy_include_t * policy_include); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_process_policy_reference_elements( + const axutil_env_t * env, + int type, + axiom_children_qname_iterator_t * iterator, + axis2_policy_include_t * policy_include); + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_DESC_BUILDER_H */ diff --git a/src/core/deployment/axis2_module_builder.h b/src/core/deployment/axis2_module_builder.h new file mode 100644 index 0000000..cd713d6 --- /dev/null +++ b/src/core/deployment/axis2_module_builder.h @@ -0,0 +1,101 @@ + +/* + * 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_MODULE_BUILDER_H +#define AXIS2_MODULE_BUILDER_H + +/** @defgroup axis2_module_builder Module Builder + * @ingroup axis2_deployment + * @{ + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include <axis2_module_desc.h> +#include <axis2_dep_engine.h> +#include <axis2_desc_builder.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** Type name for struct axis2_module_builder */ + typedef struct axis2_module_builder axis2_module_builder_t; + + /** + * De-allocate memory + * @param module_builder pointer to module builder + * @param env pointer to environment struct + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_module_builder_free( + axis2_module_builder_t * module_builder, + const axutil_env_t * env); + + /** + * @param module_builder pointer to module builder + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_module_builder_populate_module( + axis2_module_builder_t * module_builder, + const axutil_env_t * env); + + /** + * Creates module builder struct + * @param env pointer to environment struct + * @return pointer to newly created module builder + */ + AXIS2_EXTERN axis2_module_builder_t *AXIS2_CALL + + axis2_module_builder_create( + const axutil_env_t * env); + + /** + * Creates module builder struct + * @param env pointer to environment struct + * @param file_name pointer to file name + * @param dep_engine pointer to deployment engine + * @return pointer to newly created module builder + */ + AXIS2_EXTERN axis2_module_builder_t *AXIS2_CALL + + axis2_module_builder_create_with_file_and_dep_engine_and_module( + const axutil_env_t * env, + axis2_char_t * file_name, + struct axis2_dep_engine *dep_engine, + axis2_module_desc_t * module); + + /** Populates the module. + #define AXIS2_MODULE_BUILDER_POPULATE_MODULE(module_builder, env) \ + axis2_module_builder_populate_module (module_builder, env)*/ + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_MODULE_BUILDER_H */ diff --git a/src/core/deployment/axis2_repos_listener.h b/src/core/deployment/axis2_repos_listener.h new file mode 100644 index 0000000..56a37c8 --- /dev/null +++ b/src/core/deployment/axis2_repos_listener.h @@ -0,0 +1,144 @@ + +/* + * 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_REPOS_LISTENER_H +#define AXIS2_REPOS_LISTENER_H + +/** @defgroup axis2_repos_listener Repos Listener + * @ingroup axis2_deployment + * @{ + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include <axutil_array_list.h> +#include "axis2_ws_info_list.h" +#include "axis2_dep_engine.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct axis2_dep_engine; + + /** Type name for struct axis2_repos_listener */ + typedef struct axis2_repos_listener axis2_repos_listener_t; + + /** + * De-allocate memory + * @param repos_listener pointer to repos listener + * @param env pointer to environment struct + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_repos_listener_free( + axis2_repos_listener_t * repos_listener, + const axutil_env_t * env); + + /** + * + * @param repos_listener pointer to repos listener + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_repos_listener_check_modules( + axis2_repos_listener_t * listener, + const axutil_env_t * env); + + /** + * + * @param repos_listener pointer to repos listener + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_repos_listener_check_svcs( + axis2_repos_listener_t * listener, + const axutil_env_t * env); + + /** + * + * @param repos_listener pointer to repos listener + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_repos_listener_update( + axis2_repos_listener_t * listener, + const axutil_env_t * env); + + /** + * + * then it call to check_modules to load all the modules. + * and then it call to update() method inorder to update the deployment engine and engine. + * @param repos_listener pointer to repos listener + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_repos_listener_init( + axis2_repos_listener_t * listener, + const axutil_env_t * env); + + /** + * @param env pointer to environment struct + * @return pointer to newly created deployment engine + */ + AXIS2_EXTERN axis2_repos_listener_t *AXIS2_CALL + axis2_repos_listener_create( + const axutil_env_t * env); + + /** + * @param env pointer to environment struct + * @param folder_name this is the axis2 deployment root directory(repository path) + * @param dep_engine pointer to deployment engine + * @return pointer to newly created deployment engine + */ + AXIS2_EXTERN axis2_repos_listener_t *AXIS2_CALL + axis2_repos_listener_create_with_folder_name_and_dep_engine( + const axutil_env_t * env, + axis2_char_t * folder_name, + struct axis2_dep_engine *dep_engine); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_repos_listener_set_conf( + axis2_repos_listener_t *repo_listener, + const axutil_env_t * env, + axis2_conf_t *conf); + + AXIS2_EXTERN axis2_conf_t *AXIS2_CALL + axis2_repos_listener_get_conf( + axis2_repos_listener_t *repo_listener, + const axutil_env_t * env); + + + + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_REPOS_LISTENER_H */ diff --git a/src/core/deployment/axis2_svc_builder.h b/src/core/deployment/axis2_svc_builder.h new file mode 100644 index 0000000..c71e7dc --- /dev/null +++ b/src/core/deployment/axis2_svc_builder.h @@ -0,0 +1,149 @@ + +/* + * 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_SVC_BUILDER_H +#define AXIS2_SVC_BUILDER_H + +/** + * @defgroup axis2_svc_builder Service Builder + * @ingroup axis2_deployment + * @{ + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include <axis2_desc_builder.h> +#include <axis2_addr.h> +#include <axis2_dep_engine.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct axis2_dep_engine; + + /** Type name for struct axis2_svc_builder */ + typedef struct axis2_svc_builder axis2_svc_builder_t; + + /** + * De-allocate memory + * @param svc_builder pointer to service builder + * @param env pointer to environment struct + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_svc_builder_free( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env); + + /** + * top most method that is used to populate service from corresponding OM + * @param svc_builder pointer to service builder + * @param env pointer to environment struct + * @param svc_node pointer to service node + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_svc_builder_populate_svc( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_node_t * svc_node); + + /** + * @param svc_builder pointer to service builder + * @param env pointer to environment struct + * @param module_confs pointer to module configurations + * @param parent pointer to parent + * @param svc pointer to service + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_svc_builder_process_svc_module_conf( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_confs, + axutil_param_container_t * parent, + axis2_svc_t * svc); + + /** + * To get the list og modules that is requird to be engage globally + * @param svc_builder pointer to service builder + * @param env pointer to environment struct + * @param module_refs pointer to module refs + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_svc_builder_process_module_refs( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_refs); + + AXIS2_EXTERN struct axis2_desc_builder *AXIS2_CALL + + axis2_svc_builder_get_desc_builder( + const axis2_svc_builder_t * svc_builder, + const axutil_env_t * env); + + /** + * Creates svc builder struct + * @param env pointer to environment struct + * @return pointer to newly created service builder + */ + AXIS2_EXTERN axis2_svc_builder_t *AXIS2_CALL + axis2_svc_builder_create( + const axutil_env_t * env); + + /** + * Creates svc builder struct + * @param env pointer to environment struct + * @param file_name pointer to file name + * @param dep_engine pointer to deployment engine + * @param svc pointer to service + * @return pointer to newly created service builder + */ + AXIS2_EXTERN axis2_svc_builder_t *AXIS2_CALL + + axis2_svc_builder_create_with_file_and_dep_engine_and_svc( + const axutil_env_t * env, + axis2_char_t * file_name, + struct axis2_dep_engine *dep_engine, + axis2_svc_t * svc); + + /** + * Creates svc builder struct + * @param env pointer to environment struct + * @param dep_engine pointer to deployment engine + * @param svc pointer to service + * @return pointer to newly created service builder + */ + AXIS2_EXTERN axis2_svc_builder_t *AXIS2_CALL + + axis2_svc_builder_create_with_dep_engine_and_svc( + const axutil_env_t * env, + struct axis2_dep_engine *dep_engine, + axis2_svc_t * svc); + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_SVC_BUILDER_H */ diff --git a/src/core/deployment/axis2_svc_grp_builder.h b/src/core/deployment/axis2_svc_grp_builder.h new file mode 100644 index 0000000..852c9a7 --- /dev/null +++ b/src/core/deployment/axis2_svc_grp_builder.h @@ -0,0 +1,122 @@ + +/* + * Copyright 2004,2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not svc_grp 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_SVC_GRP_BUILDER_H +#define AXIS2_SVC_GRP_BUILDER_H + +/** @defgroup axis2_svc_grp_builder Service Group Builder + * @ingroup axis2_deployment + * @{ + */ + +/** + * @file axis2_svc_grp_builder.h + * @brief Axis2 Service Group Builder interface + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include <axis2_desc_builder.h> +#include <axis2_svc_builder.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** Type name for struct axis2_svc_grp_builder */ + typedef struct axis2_svc_grp_builder axis2_svc_grp_builder_t; + + /** + * De-allocate memory + * @param svc_grp_builder pointer to service group builder + * @param env pointer to environment struct + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_svc_grp_builder_free( + axis2_svc_grp_builder_t * svc_grp_builder, + const axutil_env_t * env); + + /** + * @param grp_builder pointer to group builder + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_svc_grp_builder_populate_svc_grp( + axis2_svc_grp_builder_t * grp_builder, + const axutil_env_t * env, + axis2_svc_grp_t * svc_grp); + + /** + * To get the list og modules that is requird to be engage globally + * @param grp_builder pointer to group builder + * @param env pointer to environment struct + * @param module_refs <code>axiom_children_qname_iterator_t</code> + * @param svc_group pointer to service group + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_svc_grp_builder_process_module_refs( + axis2_svc_grp_builder_t * grp_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_refs, + axis2_svc_grp_t * svc_grp); + + AXIS2_EXTERN axis2_desc_builder_t *AXIS2_CALL + + axis2_svc_grp_builder_get_desc_builder( + const axis2_svc_grp_builder_t * svc_grp_builder, + const axutil_env_t * env); + + /** + * Creates svc_grp builder struct + * @param env pointer to environment struct + * @return pointer to newly created service group builder + */ + AXIS2_EXTERN axis2_svc_grp_builder_t *AXIS2_CALL + + axis2_svc_grp_builder_create( + const axutil_env_t * env); + + /** + * Creates svc_grp builder struct + * @param env pointer to environment strut + * @param svc pointer to service + * @param dep_engine pointer to deployment engine + * @return pointer to newly created service group builder + */ + AXIS2_EXTERN axis2_svc_grp_builder_t *AXIS2_CALL + + axis2_svc_grp_builder_create_with_svc_and_dep_engine( + const axutil_env_t * env, + axiom_node_t * svc, + axis2_dep_engine_t * dep_engine); + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_SVC_GRP_BUILDER_H */ diff --git a/src/core/deployment/axis2_ws_info.h b/src/core/deployment/axis2_ws_info.h new file mode 100644 index 0000000..d6fd117 --- /dev/null +++ b/src/core/deployment/axis2_ws_info.h @@ -0,0 +1,144 @@ + +/* + * 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_WS_INFO_H +#define AXIS2_WS_INFO_H + +/** + * @defgroup axis2_ws_info Ws Info + * @ingroup axis2_deployment + * @{ + */ + +/** + * @file axis2_ws_info.h + * @brief Axis2 Ws Info interface. ws_info construct contain file information + * for module or service configuration file. + */ +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include <axis2_conf.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct axis2_conf; + + /** Type name for struct axis2_ws_info */ + typedef struct axis2_ws_info axis2_ws_info_t; + + /** + * De-allocate memory + * @param ws_info pointer to ws info + * @param env pointer to environment struct + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_ws_info_free( + axis2_ws_info_t * ws_info, + const axutil_env_t * env); + + /** + * @param ws_info pointer to ws info + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axis2_ws_info_get_file_name( + const axis2_ws_info_t * ws_info, + const axutil_env_t * env); + + /** + * @param ws_info pointer to ws info + * @param env pointer to environment struct + * @param file_name pointer to file name + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_ws_info_set_file_name( + axis2_ws_info_t * ws_info, + const axutil_env_t * env, + axis2_char_t * file_name); + + /** + * @param ws_info pointer to ws info + * @param env pointer to environment struct + */ + AXIS2_EXTERN long AXIS2_CALL + axis2_ws_info_get_last_modified_date( + const axis2_ws_info_t * ws_info, + const axutil_env_t * env); + + /** + * @param ws_info pointer to ws info + * @param env pointer to environment struct + * @param modified_data pointer to modified date + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_ws_info_set_last_modified_date( + axis2_ws_info_t * ws_info, + const axutil_env_t * env, + long last_modified_date); + + /** + * @param ws_info pointer to ws info + * @param env pointer to environment struct + */ + AXIS2_EXTERN int AXIS2_CALL + axis2_ws_info_get_type( + const axis2_ws_info_t * ws_info, + const axutil_env_t * env); + + /** + * Creates ws_info struct + * @param env pointer to environment struct + * @param file_name pointer to file name + * @param last_modified_date pointer to last modified date + * @return pointer to newly created ws info + */ + AXIS2_EXTERN axis2_ws_info_t *AXIS2_CALL + + axis2_ws_info_create_with_file_name_and_last_modified_date( + const axutil_env_t * env, + axis2_char_t * file_name, + long last_modified_date); + + /** + * @param env pointer to environment struct + * @param file_name pointer to file name + * @param last_modifile_date last modified date + * @param type type + */ + AXIS2_EXTERN axis2_ws_info_t *AXIS2_CALL + + axis2_ws_info_create_with_file_name_and_last_modified_date_and_type( + const axutil_env_t * env, + axis2_char_t * file_name, + long last_modified_date, + int type); + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_WS_INFO_H */ diff --git a/src/core/deployment/axis2_ws_info_list.h b/src/core/deployment/axis2_ws_info_list.h new file mode 100644 index 0000000..3ffb68d --- /dev/null +++ b/src/core/deployment/axis2_ws_info_list.h @@ -0,0 +1,192 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_WS_INFO_LIST_H +#define AXIS2_WS_INFO_LIST_H + +/** @defgroup axis2_ws_info_list Ws Info List + * @ingroup axis2_deployment + * @{ + */ + +/** + * @file axis2_ws_info_list.h + * @brief Axis2 Ws Info List interface. Ws Info List is the list of ws_info structs. + * Each ws_info construct contain file information for module or service configuration file. + */ + +#include <axis2_const.h> +#include <axutil_error.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_qname.h> +#include <axis2_conf.h> +#include "axis2_deployment.h" +#include <axutil_file_handler.h> +#include <axutil_dir_handler.h> +#include "axis2_ws_info.h" +#include "axis2_arch_file_data.h" +#include "axis2_dep_engine.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct axis2_ws_info; + struct axis2_dep_engine; + + /** Type name for struct axis2_ws_info_list */ + typedef struct axis2_ws_info_list axis2_ws_info_list_t; + + /** + * De-allocate memory + * @param ws_info_list pointer to ws info list + * @param env pointer to environment struct + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_ws_info_list_free( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env); + + /** + * This method is used to initialize the ws info list. + * @param info_list pointer to ws info list + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_ws_info_list_init( + axis2_ws_info_list_t * info_list, + const axutil_env_t * env); + + /** + * This will add the deployment info struct(ws_info) into the deployment info + * list and deployment info file to the deployment engine as new + * service or module deployment info struct/file. + * In doing this, it first create an deployment info struct called ws_info + * to keep the file info that will be added to deployment info file + * list and then create deployment info file called arch_file_data that will + * be added to deployment engine for actual deployment of the service/module. + * + * This will add two entries to deployment engine one for new Deployment and + * other for undeployment. + * @param info_list pointer to ws info list + * @param env pointer to environment struct + * @param file actual axis2 configuration file for module/service. + * @param type indicate either service or module + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_ws_info_list_add_ws_info_item( + axis2_ws_info_list_t * info_list, + const axutil_env_t * env, + axutil_file_t * file, + int type); + + /** + * This method is used to check whether the service/module configuration + * file exist and if so it will return related ws_info object to the file, + * else return NULL; + * @param info_list pointer to ws info list + * @param env pointer to environment struct + * @param file_name pointer to file name + */ + AXIS2_EXTERN axis2_ws_info_t *AXIS2_CALL + + axis2_ws_info_list_get_file_item( + axis2_ws_info_list_t * info_list, + const axutil_env_t * env, + axis2_char_t * file_name); + + /** + * Compare the last update dates of both files and if those differ + * it will be assumed as the file has been modified. + * @param info_list pointer to ws info list + * @param env pointer to environment struct + * @param file pointer to servie/module configuration file. + * @param ws_info pointer to ws info struct. + */ + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_ws_info_list_is_modified( + axis2_ws_info_list_t * info_list, + const axutil_env_t * env, + axutil_file_t * file, + struct axis2_ws_info *ws_info); + + /** + * To check whether the deployment info file is alredy in the list. + * @param info_list pointer to ws info list + * @param env pointer to environment struct + * @param file_name pointer to file name + */ + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_ws_info_list_is_file_exist( + axis2_ws_info_list_t * info_list, + const axutil_env_t * env, + axis2_char_t * file_name); + + /** + * This is to check whether to undeploy ws info struct. + * What this realy does is, it check ws_info list and current deployment + * info name list. If ws_info exists in the ws_info_list but it's + * corresponding file name does not exist in the current deploymet file + * name list then, struct is deemed non existant. ie. that is hot + * undeployment. + * @param info_list pointer to ws info list + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_ws_info_list_check_for_undeploy( + axis2_ws_info_list_t * info_list, + const axutil_env_t * env); + + /** + * @param info_list pointer to ws info list + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_ws_info_list_update( + axis2_ws_info_list_t * info_list, + const axutil_env_t * env); + + /** + * Creates ws info list struct + * @param env pointer to environment struct + * @param dep_engine pointer to deployment engine + * @return pointer to newly created ws info list + */ + AXIS2_EXTERN axis2_ws_info_list_t *AXIS2_CALL + + axis2_ws_info_list_create_with_dep_engine( + const axutil_env_t * env, + struct axis2_dep_engine *dep_engine); + + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_WS_INFO_LIST_H */ diff --git a/src/core/deployment/conf_builder.c b/src/core/deployment/conf_builder.c new file mode 100644 index 0000000..15485b0 --- /dev/null +++ b/src/core/deployment/conf_builder.c @@ -0,0 +1,1337 @@ +/* + * 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_conf_builder.h> +#include <axis2_disp.h> +#include <axis2_conf.h> +#include <axutil_class_loader.h> +#include <axis2_transport_in_desc.h> +#include <axis2_transport_out_desc.h> +#include <axutil_utils.h> +#include <axis2_transport_receiver.h> + +struct axis2_conf_builder +{ + axis2_conf_t *conf; + struct axis2_desc_builder *desc_builder; +}; + +static axis2_status_t +axis2_conf_builder_process_disp_order( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_node_t * disp_order_node); + +static axis2_status_t +axis2_conf_builder_process_phase_orders( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * phase_orders); + +static axutil_array_list_t * +axis2_conf_builder_get_phase_list( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_node_t * phase_orders_node); + +static axis2_status_t +axis2_conf_builder_process_transport_senders( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * trs_senders); + +static axis2_status_t +axis2_conf_builder_process_transport_recvs( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * trs_recvs); + +static axis2_status_t AXIS2_CALL +axis2_conf_builder_process_default_module_versions( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_versions); + +AXIS2_EXTERN axis2_conf_builder_t *AXIS2_CALL +axis2_conf_builder_create( + const axutil_env_t * env) +{ + axis2_conf_builder_t *conf_builder = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + conf_builder = (axis2_conf_builder_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_conf_builder_t)); + + if(!conf_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + conf_builder->conf = NULL; + + return conf_builder; +} + +AXIS2_EXTERN axis2_conf_builder_t *AXIS2_CALL +axis2_conf_builder_create_with_file_and_dep_engine_and_conf( + const axutil_env_t * env, + axis2_char_t * file, + axis2_dep_engine_t * engine, + axis2_conf_t * conf) +{ + axis2_conf_builder_t *conf_builder = NULL; + + conf_builder = (axis2_conf_builder_t *)axis2_conf_builder_create(env); + if(!conf_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + conf_builder->desc_builder = axis2_desc_builder_create_with_file_and_dep_engine(env, file, + engine); + conf_builder->conf = conf; + + return conf_builder; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_conf_builder_free( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env) +{ + if(conf_builder->desc_builder) + { + axis2_desc_builder_free(conf_builder->desc_builder, env); + } + + if(conf_builder) + { + AXIS2_FREE(env->allocator, conf_builder); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_builder_populate_conf( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env) +{ + axutil_qname_t *qparamst = NULL; + axutil_qname_t *qmsgrecv = NULL; + axutil_qname_t *qdisporder = NULL; + axutil_qname_t *qmodulest = NULL; + axutil_qname_t *qtransportsender = NULL; + axutil_qname_t *qtransportrecv = NULL; + axutil_qname_t *qphaseorder = NULL; + axutil_qname_t *qdefmodver = NULL; + axiom_children_qname_iterator_t *itr = NULL; + axiom_children_qname_iterator_t *msg_recvs = NULL; + axiom_children_qname_iterator_t *module_itr = NULL; + axiom_children_qname_iterator_t *trs_senders = NULL; + axiom_children_qname_iterator_t *trs_recvs = NULL; + axiom_children_qname_iterator_t *phase_orders = NULL; + axiom_children_qname_iterator_t *def_mod_versions = NULL; + axiom_element_t *conf_element = NULL; + axiom_node_t *conf_node = NULL; + axiom_element_t *disp_order_element = NULL; + axiom_node_t *disp_order_node = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_param_t *param = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_conf_builder_populate_conf"); + conf_node = axis2_desc_builder_build_om(conf_builder->desc_builder, env); + if(!conf_node) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Building om tree failed. Unable to continue"); + return AXIS2_FAILURE; + } + conf_element = axiom_node_get_data_element(conf_node, env); + /* processing Paramters */ + /* Processing service level paramters */ + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + itr = axiom_element_get_children_with_qname(conf_element, env, qparamst, conf_node); + axutil_qname_free(qparamst, env); + axis2_desc_builder_process_params(conf_builder->desc_builder, env, itr, + axis2_conf_get_param_container(conf_builder->conf, env), axis2_conf_get_param_container( + conf_builder->conf, env)); + /* process Message Reciver */ + qmsgrecv = axutil_qname_create(env, AXIS2_MESSAGERECEIVER, NULL, NULL); + msg_recvs = axiom_element_get_children_with_qname(conf_element, env, qmsgrecv, conf_node); + axutil_qname_free(qmsgrecv, env); + while(axiom_children_qname_iterator_has_next(msg_recvs, env)) + { + axiom_node_t *msg_recv_node = NULL; + axiom_element_t *msg_recv_element = NULL; + axis2_msg_recv_t *msg_recv = NULL; + axiom_attribute_t *recv_name = NULL; + axutil_qname_t *class_qname = NULL; + axis2_char_t *class_name = NULL; + + msg_recv_node = (axiom_node_t *)axiom_children_qname_iterator_next(msg_recvs, env); + msg_recv_element = (axiom_element_t *)axiom_node_get_data_element(msg_recv_node, env); + msg_recv = axis2_desc_builder_load_msg_recv(conf_builder->desc_builder, env, + msg_recv_element); + if(!msg_recv) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Message receiver loading failed. Unable to continue"); + return AXIS2_FAILURE; + } + + class_qname = axutil_qname_create(env, AXIS2_CLASSNAME, NULL, NULL); + recv_name = axiom_element_get_attribute(msg_recv_element, env, class_qname); + axutil_qname_free(class_qname, env); + class_name = axiom_attribute_get_value(recv_name, env); + axis2_conf_add_msg_recv(conf_builder->conf, env, class_name, msg_recv); + } + + /* processing Dispatching Order */ + qdisporder = axutil_qname_create(env, AXIS2_DISPATCH_ORDER, NULL, NULL); + disp_order_element = axiom_element_get_first_child_with_qname(conf_element, env, qdisporder, + conf_node, &disp_order_node); + axutil_qname_free(qdisporder, env); + if(disp_order_element) + { + axis2_conf_builder_process_disp_order(conf_builder, env, disp_order_node); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Found the custom disptaching" + " order and continue with that order"); + } + else + { + status = axis2_conf_set_default_dispatchers(conf_builder->conf, env); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting default dispatchers to configuration failed, " + "unable to continue."); + return AXIS2_FAILURE; + } + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "No custom dispatching order" + " found. Continue with the default dispatching order"); + } + + /* Process Module refs */ + qmodulest = axutil_qname_create(env, AXIS2_MODULEST, NULL, NULL); + module_itr = axiom_element_get_children_with_qname(conf_element, env, qmodulest, conf_node); + axutil_qname_free(qmodulest, env); + status = axis2_conf_builder_process_module_refs(conf_builder, env, module_itr); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Processing module ref's failed, unable to continue."); + return AXIS2_FAILURE; + } + /* Proccessing Transport Sennders */ + qtransportsender = axutil_qname_create(env, AXIS2_TRANSPORTSENDER, NULL, NULL); + trs_senders = axiom_element_get_children_with_qname(conf_element, env, qtransportsender, + conf_node); + axutil_qname_free(qtransportsender, env); + status = axis2_conf_builder_process_transport_senders(conf_builder, env, trs_senders); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Processing transport senders failed, unable to continue"); + return AXIS2_FAILURE; + } + + /* Proccessing Transport Recivers */ + qtransportrecv = axutil_qname_create(env, AXIS2_TRANSPORTRECEIVER, NULL, NULL); + trs_recvs = axiom_element_get_children_with_qname(conf_element, env, qtransportrecv, conf_node); + axutil_qname_free(qtransportrecv, env); + status = axis2_conf_builder_process_transport_recvs(conf_builder, env, trs_recvs); + + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Processing transport receivers failed, unable to continue"); + return AXIS2_FAILURE; + } + + /* processing Phase orders */ + qphaseorder = axutil_qname_create(env, AXIS2_PHASE_ORDER, NULL, NULL); + phase_orders = axiom_element_get_children_with_qname(conf_element, env, qphaseorder, conf_node); + axutil_qname_free(qphaseorder, env); + status = axis2_conf_builder_process_phase_orders(conf_builder, env, phase_orders); + + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Processing phase orders failed, unable to continue"); + return AXIS2_FAILURE; + } + + /* Processing default module versions */ + qdefmodver = axutil_qname_create(env, AXIS2_DEFAULT_MODULE_VERSION, NULL, NULL); + def_mod_versions = axiom_element_get_children_with_qname(conf_element, env, qdefmodver, + conf_node); + axutil_qname_free(qdefmodver, env); + if(def_mod_versions) + { + status = axis2_conf_builder_process_default_module_versions(conf_builder, env, + def_mod_versions); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Processing default module versions failed, unable to continue"); + return AXIS2_FAILURE; + } + } + + param = axutil_param_container_get_param( + axis2_conf_get_param_container(conf_builder->conf, env), env, AXIS2_ENABLE_MTOM); + if(param) + { + axis2_char_t *value = NULL; + value = axutil_param_get_value(param, env); + if(value) + { + axis2_conf_set_enable_mtom(conf_builder->conf, env, (!axutil_strcmp(value, + AXIS2_VALUE_TRUE))); + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_conf_builder_populate_conf"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_builder_process_module_refs( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_refs) +{ + axis2_status_t status = AXIS2_SUCCESS; + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_conf_builder_process_module_refs"); + AXIS2_PARAM_CHECK(env->error, module_refs, AXIS2_FAILURE); + + while(axiom_children_qname_iterator_has_next(module_refs, env)) + { + axiom_node_t *module_ref_node = NULL; + axiom_element_t *module_ref_element = NULL; + axutil_qname_t *qref = NULL; + + axiom_attribute_t *module_ref_att = NULL; + module_ref_node = (axiom_node_t *)axiom_children_qname_iterator_next(module_refs, env); + if(!module_ref_node) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Module ref node is empty. Unable to continue"); + return AXIS2_FAILURE; + } + module_ref_element = axiom_node_get_data_element(module_ref_node, env); + qref = axutil_qname_create(env, AXIS2_REF, NULL, NULL); + module_ref_att = axiom_element_get_attribute(module_ref_element, env, qref); + if(qref) + { + axutil_qname_free(qref, env); + } + + if(module_ref_att) + { + axutil_qname_t *qrefname = NULL; + axis2_char_t *ref_name = NULL; + + ref_name = axiom_attribute_get_value(module_ref_att, env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Module %s found in axis2.xml", ref_name); + qrefname = axutil_qname_create(env, ref_name, NULL, NULL); + status = axis2_dep_engine_add_module(axis2_desc_builder_get_dep_engine( + conf_builder->desc_builder, env), env, qrefname); + if(qrefname) + { + axutil_qname_free(qrefname, env); + } + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_conf_builder_process_module_refs"); + return status; +} + +static axis2_status_t +axis2_conf_builder_process_disp_order( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_node_t * disp_order_node) +{ + axiom_element_t *disp_order_element = NULL; + axiom_children_qname_iterator_t *disps = NULL; + axutil_qname_t *qdisp = NULL; + axis2_bool_t found_disp = AXIS2_FALSE; + axis2_phase_t *disp_phase = NULL; + int count = 0; + axis2_bool_t qname_itr_has_next = AXIS2_FALSE; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_conf_builder_process_disp_order"); + AXIS2_PARAM_CHECK(env->error, disp_order_node, AXIS2_FAILURE); + + disp_order_element = axiom_node_get_data_element(disp_order_node, env); + qdisp = axutil_qname_create(env, AXIS2_DISPATCHER, NULL, NULL); + disps = axiom_element_get_children_with_qname(disp_order_element, env, qdisp, disp_order_node); + axutil_qname_free(qdisp, env); + disp_phase = axis2_phase_create(env, AXIS2_PHASE_DISPATCH); + if(!disp_phase) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Dispatch phase creation failed. Unable to continue"); + return AXIS2_FAILURE; + } + if(disps) + { + qname_itr_has_next = axiom_children_qname_iterator_has_next(disps, env); + } + while(qname_itr_has_next) + { + axiom_node_t *disp_node = NULL; + axiom_element_t *disp_element = NULL; + axiom_attribute_t *disp_att = NULL; + axis2_char_t *class_name = NULL; + axis2_char_t *dll_name = NULL; + axutil_qname_t *class_qname = NULL; + axis2_disp_t *disp_dll = NULL; + axutil_dll_desc_t *dll_desc = NULL; + axutil_param_t *impl_info_param = NULL; + axis2_handler_desc_t *handler_desc = NULL; + axis2_handler_t *handler = NULL; + + found_disp = AXIS2_TRUE; + disp_node = (axiom_node_t *)axiom_children_qname_iterator_next(disps, env); + disp_element = (axiom_element_t *) axiom_node_get_data_element(disp_node, env); + class_qname = axutil_qname_create(env, AXIS2_CLASSNAME, NULL, NULL); + disp_att = axiom_element_get_attribute(disp_element, env, class_qname); + axutil_qname_free(class_qname, env); + if(!disp_att) + { + qname_itr_has_next = axiom_children_qname_iterator_has_next(disps, env); + continue; + } + class_name = axiom_attribute_get_value(disp_att, env); + dll_desc = axutil_dll_desc_create(env); + dll_name = axutil_dll_desc_create_platform_specific_dll_name(dll_desc, env, class_name); + axutil_dll_desc_set_name(dll_desc, env, dll_name); + axutil_dll_desc_set_type(dll_desc, env, AXIS2_HANDLER_DLL); + impl_info_param = axutil_param_create(env, class_name, NULL); + if(!impl_info_param) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Parameter creation failed for %s. Unable to continue", class_name); + + axis2_phase_free(disp_phase, env); + + return AXIS2_FAILURE; + } + + axutil_param_set_value(impl_info_param, env, dll_desc); + axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg); + axutil_class_loader_init(env); + disp_dll = (axis2_disp_t *)axutil_class_loader_create_dll(env, impl_info_param); + + handler = axis2_disp_get_base(disp_dll, env); + handler_desc = axis2_handler_get_handler_desc(handler, env); + axis2_handler_desc_add_param(handler_desc, env, impl_info_param); + + axis2_phase_add_handler_at(disp_phase, env, count, handler); + count++; + qname_itr_has_next = axiom_children_qname_iterator_has_next(disps, env); + + } + + if(!found_disp) + { + axis2_phase_free(disp_phase, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_DISPATCHER_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No dispatcher found. Unable to continue"); + + return AXIS2_FAILURE; + } + else + { + status = axis2_conf_set_dispatch_phase(conf_builder->conf, env, disp_phase); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting dispatch phase failed. Unable to continue"); + + axis2_phase_free(disp_phase, env); + + return status; + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_conf_builder_process_disp_order"); + return AXIS2_SUCCESS; +} + +/** + * To process all the phase orders which are defined in axis2.xml retrieve each phase order node + * from the iterator passed as parameter and from each phase order node retrieve phases list + * defined for that phase order. Add the phases names into a array list and set it into the + * dep_engine->phases_info with the corresponding phase order name. + * @param phase_orders + */ +static axis2_status_t +axis2_conf_builder_process_phase_orders( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * phase_orders) +{ + axis2_phases_info_t *info = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_conf_builder_process_phase_orders"); + + AXIS2_PARAM_CHECK(env->error, phase_orders, AXIS2_FAILURE); + + info = axis2_dep_engine_get_phases_info(axis2_desc_builder_get_dep_engine( + conf_builder->desc_builder, env), env); + + while(axiom_children_qname_iterator_has_next(phase_orders, env)) + { + axiom_node_t *phase_orders_node = NULL; + axiom_element_t *phase_orders_element = NULL; + axiom_attribute_t *phase_orders_att = NULL; + axutil_qname_t *qtype = NULL; + axis2_char_t *flow_type = NULL; + axutil_array_list_t *phase_list = NULL; + + phase_orders_node = (axiom_node_t *)axiom_children_qname_iterator_next(phase_orders, env); + if(phase_orders_node) + { + phase_orders_element = axiom_node_get_data_element(phase_orders_node, env); + } + if(phase_orders_element) + { + qtype = axutil_qname_create(env, AXIS2_TYPE, NULL, NULL); + phase_orders_att = axiom_element_get_attribute(phase_orders_element, env, qtype); + axutil_qname_free(qtype, env); + } + + if(phase_orders_att) + { + flow_type = axiom_attribute_get_value(phase_orders_att, env); + } + + phase_list = axis2_conf_builder_get_phase_list(conf_builder, env, phase_orders_node); + if(!phase_list) + { + axis2_status_t status_code = AXIS2_FAILURE; + + status_code = AXIS2_ERROR_GET_STATUS_CODE(env->error); + if(AXIS2_SUCCESS != status_code) + { + return status_code; + } + + return AXIS2_SUCCESS; + } + + if(flow_type && !axutil_strcmp(AXIS2_IN_FLOW_START, flow_type)) + { + axis2_phases_info_set_in_phases(info, env, phase_list); + } + else if(flow_type && !axutil_strcmp(AXIS2_IN_FAILTFLOW, flow_type)) + { + axis2_phases_info_set_in_faultphases(info, env, phase_list); + } + else if(flow_type && !axutil_strcmp(AXIS2_OUT_FLOW_START, flow_type)) + { + axis2_phases_info_set_out_phases(info, env, phase_list); + } + else if(flow_type && !axutil_strcmp(AXIS2_OUT_FAILTFLOW, flow_type)) + { + axis2_phases_info_set_out_faultphases(info, env, phase_list); + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_conf_builder_process_phase_orders"); + + return AXIS2_SUCCESS; +} + +/* From the phase order node passed as parameter retrieve all phase element nodes. From them extract + * the phase name and add it to a array list. Return the array list. + */ +static axutil_array_list_t * +axis2_conf_builder_get_phase_list( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_node_t * phase_orders_node) +{ + axutil_array_list_t *phase_list = NULL; + axiom_children_qname_iterator_t *phases = NULL; + axutil_qname_t *qphase = NULL; + axiom_element_t *phase_orders_element; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_conf_builder_get_phase_list"); + + AXIS2_PARAM_CHECK(env->error, phase_orders_node, NULL); + + phase_orders_element = axiom_node_get_data_element(phase_orders_node, env); + if(!phase_orders_element) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DATA_ELEMENT_IS_NULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Retrieving phase orders data element from phase orders node failed. Unable to continue"); + + return NULL; + } + + phase_list = axutil_array_list_create(env, 0); + qphase = axutil_qname_create(env, AXIS2_PHASE, NULL, NULL); + phases = axiom_element_get_children_with_qname(phase_orders_element, env, qphase, + phase_orders_node); + + axutil_qname_free(qphase, env); + if(!phases) + { + axutil_array_list_free(phase_list, env); + + /* I guess this is not an error. So adding debug message*/ + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "No phase node found in the phase orders node"); + + return NULL; + } + + while(axiom_children_qname_iterator_has_next(phases, env)) + { + axiom_node_t *phase_node = NULL; + axiom_element_t *phase_element = NULL; + axiom_attribute_t *phase_att = NULL; + axutil_qname_t *qattname = NULL; + axis2_char_t *att_value = NULL; + + phase_node = (axiom_node_t *)axiom_children_qname_iterator_next(phases, env); + if(phase_node) + { + phase_element = (axiom_element_t *)axiom_node_get_data_element(phase_node, env); + } + + qattname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + if(phase_element) + { + phase_att = axiom_element_get_attribute(phase_element, env, qattname); + } + + if(phase_att) + { + att_value = axiom_attribute_get_value(phase_att, env); + } + + if(att_value) + { + axutil_array_list_add(phase_list, env, att_value); + } + + axutil_qname_free(qattname, env); + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_conf_builder_get_phase_list"); + + return phase_list; +} + +static axis2_status_t +axis2_conf_builder_process_transport_senders( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * trs_senders) +{ + axis2_status_t status = AXIS2_FAILURE; + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_conf_builder_process_transport_senders"); + while(axiom_children_qname_iterator_has_next(trs_senders, env)) + { + axis2_transport_out_desc_t *transport_out = NULL; + axiom_node_t *transport_node = NULL; + axiom_element_t *transport_element = NULL; + axiom_attribute_t *trs_name = NULL; + axutil_qname_t *qattname = NULL; + + transport_node = (axiom_node_t *)axiom_children_qname_iterator_next(trs_senders, env); + + if(transport_node) + { + transport_element = (axiom_element_t *)axiom_node_get_data_element(transport_node, env); + if(!transport_element) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Retrieving data element failed from the transport node." + " Unable to continue"); + return AXIS2_FAILURE; + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport node is empty. Unable to continue"); + return AXIS2_FAILURE; + } + + /* getting trsnport Name */ + qattname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + if(transport_element) + { + trs_name = axiom_element_get_attribute(transport_element, env, qattname); + } + + axutil_qname_free(qattname, env); + if(trs_name) + { + axis2_char_t *name = NULL; + axiom_attribute_t *trs_dll_att = NULL; + axis2_char_t *dll_name = NULL; + axis2_char_t *class_name = NULL; + axiom_children_qname_iterator_t *itr = NULL; + axutil_qname_t *qparamst = NULL; + axutil_qname_t *qinflowst = NULL; + axutil_qname_t *qoutflowst = NULL; + axutil_qname_t *qinfaultflowst = NULL; + axutil_qname_t *qoutfaultflowst = NULL; + axutil_qname_t *qdllname = NULL; + axiom_element_t *in_flow_element = NULL; + axiom_node_t *in_flow_node = NULL; + axiom_element_t *out_flow_element = NULL; + axiom_node_t *out_flow_node = NULL; + axiom_element_t *in_fault_flow_element = NULL; + axiom_node_t *in_fault_flow_node = NULL; + axiom_element_t *out_fault_flow_element = NULL; + axiom_node_t *out_fault_flow_node = NULL; + axutil_dll_desc_t *dll_desc = NULL; + axutil_param_t *impl_info_param = NULL; + void *transport_sender = NULL; + axis2_char_t *path_qualified_dll_name = NULL; + axis2_char_t *repos_name = NULL; + axis2_char_t *temp_path = NULL; + axis2_char_t *temp_path2 = NULL; + axis2_char_t *temp_path3 = NULL; + AXIS2_TRANSPORT_ENUMS transport_enum = AXIS2_TRANSPORT_ENUM_HTTP; + /* AXIS2_TRANSPORT_ENUMS transport_enum = AXIS2_TRANSPORT_ENUM_HTTP + * set to avoid C4701 on Windows + */ + axis2_bool_t axis2_flag = AXIS2_FALSE; + axutil_param_t *libparam; + axis2_char_t *libdir = NULL; + axis2_conf_t *conf; + + conf = conf_builder->conf; + axis2_flag = axis2_conf_get_axis2_flag(conf, env); + + name = axiom_attribute_get_value(trs_name, env); + + if(name) + { + if(!axutil_strcmp(name, AXIS2_TRANSPORT_HTTP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_HTTP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_SMTP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_SMTP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_XMPP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_XMPP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_TCP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_TCP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_HTTPS)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_HTTPS; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_AMQP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_AMQP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_UDP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_UDP; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Transport name %s doesn't match with transport enum. " + "Unable to continue", name); + return AXIS2_FAILURE; + } + + transport_out = axis2_transport_out_desc_create(env, transport_enum); + } + + if(!transport_out) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Transport_out value is NULL for transport %s", name); + return AXIS2_FAILURE; + } + + /* transport impl class */ + qdllname = axutil_qname_create(env, AXIS2_CLASSNAME, NULL, NULL); + trs_dll_att = axiom_element_get_attribute(transport_element, env, qdllname); + axutil_qname_free(qdllname, env); + if(!trs_dll_att) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_TRANSPORT_SENDER_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Transport dll name attribute is not set in the " + "%s transport element node", name); + return AXIS2_FAILURE; + } + class_name = axiom_attribute_get_value(trs_dll_att, env); + impl_info_param = axutil_param_create(env, class_name, NULL); + if(!impl_info_param) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating module dll name parameter failed for %s. Unable " + "to continue", class_name); + axis2_transport_out_desc_free(transport_out, env); + return AXIS2_FAILURE; + } + dll_desc = axutil_dll_desc_create(env); + dll_name = axutil_dll_desc_create_platform_specific_dll_name(dll_desc, env, class_name); + if(!axis2_flag) + { + repos_name = axis2_dep_engine_get_repos_path(axis2_desc_builder_get_dep_engine( + conf_builder->desc_builder, env), env); + temp_path = axutil_stracat(env, repos_name, AXIS2_PATH_SEP_STR); + temp_path2 = axutil_stracat(env, temp_path, AXIS2_LIB_FOLDER); + temp_path3 = axutil_stracat(env, temp_path2, AXIS2_PATH_SEP_STR); + path_qualified_dll_name = axutil_stracat(env, temp_path3, dll_name); + AXIS2_FREE(env->allocator, temp_path); + AXIS2_FREE(env->allocator, temp_path2); + AXIS2_FREE(env->allocator, temp_path3); + } + else + { + libparam = axis2_conf_get_param(conf, env, AXIS2_LIB_DIR); + if(libparam) + { + libdir = axutil_param_get_value(libparam, env); + } + + if(!libdir) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Specifying" + "services and modules directories using axis2.xml but" + " path of the library directory is not present"); + return AXIS2_FAILURE; + } + path_qualified_dll_name = axutil_strcat(env, libdir, AXIS2_PATH_SEP_STR, dll_name, + NULL); + } + + axutil_dll_desc_set_name(dll_desc, env, path_qualified_dll_name); + AXIS2_FREE(env->allocator, path_qualified_dll_name); + + axutil_dll_desc_set_type(dll_desc, env, AXIS2_TRANSPORT_SENDER_DLL); + axutil_param_set_value(impl_info_param, env, dll_desc); + axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg); + axutil_class_loader_init(env); + transport_sender = axutil_class_loader_create_dll(env, impl_info_param); + axis2_transport_out_desc_add_param(transport_out, env, impl_info_param); + + if(!transport_sender) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Transport sender is NULL for transport %s, unable to " + "continue", name); + axis2_transport_out_desc_free(transport_out, env); + return status; + } + + status = axis2_transport_out_desc_set_sender(transport_out, env, transport_sender); + if(!status) + { + axis2_transport_out_desc_free(transport_out, env); + return status; + } + + /* Process Parameters */ + /* Processing service level paramters */ + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + itr = axiom_element_get_children_with_qname(transport_element, env, qparamst, + transport_node); + axutil_qname_free(qparamst, env); + + if(itr) + { + status = axis2_desc_builder_process_params(conf_builder->desc_builder, env, itr, + axis2_transport_out_desc_param_container(transport_out, env), + axis2_conf_get_param_container(conf_builder->conf, env)); + } + if(!status) + { + axis2_transport_out_desc_free(transport_out, env); + return status; + } + /* process IN_FLOW */ + qinflowst = axutil_qname_create(env, AXIS2_IN_FLOW_START, NULL, NULL); + in_flow_element = axiom_element_get_first_child_with_qname(transport_element, env, + qinflowst, transport_node, &in_flow_node); + axutil_qname_free(qinflowst, env); + if(in_flow_element) + { + axis2_transport_out_desc_free(transport_out, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_IN_FLOW_NOT_ALLOWED_IN_TRS_OUT, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Transport in flow element is not allowed in the out path"); + return AXIS2_FAILURE; + } + qoutflowst = axutil_qname_create(env, AXIS2_OUT_FLOW_START, NULL, NULL); + out_flow_element = axiom_element_get_first_child_with_qname(transport_element, env, + qoutflowst, transport_node, &out_flow_node); + axutil_qname_free(qoutflowst, env); + if(out_flow_element) + { + axis2_flow_t *flow = NULL; + + flow = axis2_desc_builder_process_flow(conf_builder->desc_builder, env, + out_flow_element, axis2_conf_get_param_container(conf_builder->conf, env), + out_flow_node); + status = axis2_transport_out_desc_set_out_flow(transport_out, env, flow); + if(!status) + { + axis2_transport_out_desc_free(transport_out, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting the out flow failed on the trasnport out " + "description for the transport %s", name); + return status; + } + } + + /* process IN FAULT FLOW */ + qinfaultflowst = axutil_qname_create(env, AXIS2_IN_FAILTFLOW, NULL, NULL); + in_fault_flow_element = axiom_element_get_first_child_with_qname(transport_element, + env, qinfaultflowst, transport_node, &in_fault_flow_node); + axutil_qname_free(qinfaultflowst, env); + if(in_fault_flow_element) + { + axis2_transport_out_desc_free(transport_out, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_IN_FLOW_NOT_ALLOWED_IN_TRS_OUT, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "A soap fault has occured in the in flow while " + "processing transport senders. Unable to continue"); + return AXIS2_FAILURE; + } + + qoutfaultflowst = axutil_qname_create(env, AXIS2_OUT_FAILTFLOW, NULL, NULL); + out_fault_flow_element = axiom_element_get_first_child_with_qname(transport_element, + env, qoutfaultflowst, transport_node, &out_fault_flow_node); + axutil_qname_free(qoutfaultflowst, env); + if(out_fault_flow_element) + { + axis2_flow_t *flow = NULL; + + flow = axis2_desc_builder_process_flow(conf_builder->desc_builder, env, + out_fault_flow_element, + axis2_conf_get_param_container(conf_builder->conf, env), out_fault_flow_node); + status = axis2_transport_out_desc_set_fault_out_flow(transport_out, env, flow); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting the fault out flow into the transport out " + "failed"); + axis2_transport_out_desc_free(transport_out, env); + return status; + } + } + + /* adding to axis config */ + status = axis2_conf_add_transport_out(conf_builder->conf, env, transport_out, + transport_enum); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding transport out for %s into main configuration failed", name); + axis2_transport_out_desc_free(transport_out, env); + return status; + } + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_conf_builder_process_transport_senders"); + return AXIS2_SUCCESS; +} + +static axis2_status_t +axis2_conf_builder_process_transport_recvs( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * trs_recvs) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_conf_t *conf; + axis2_bool_t axis2_flag = AXIS2_FALSE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_conf_builder_process_transport_recvs"); + AXIS2_PARAM_CHECK(env->error, trs_recvs, AXIS2_FAILURE); + + conf = conf_builder->conf; + axis2_flag = axis2_conf_get_axis2_flag(conf, env); + + while(axiom_children_qname_iterator_has_next(trs_recvs, env)) + { + axis2_transport_in_desc_t *transport_in = NULL; + axiom_node_t *transport_node = NULL; + axiom_element_t *transport_element = NULL; + axiom_attribute_t *trs_name = NULL; + axutil_qname_t *qattname = NULL; + + transport_node = (axiom_node_t *)axiom_children_qname_iterator_next(trs_recvs, env); + if(transport_node) + { + transport_element = axiom_node_get_data_element(transport_node, env); + if(!transport_element) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Retrieving data element from the transport node failed."); + return AXIS2_FAILURE; + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport node is NULL. Unable to continue"); + return AXIS2_FAILURE; + } + + /* getting transport Name */ + qattname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + trs_name = axiom_element_get_attribute(transport_element, env, qattname); + axutil_qname_free(qattname, env); + + if(trs_name) + { + axis2_char_t *name = NULL; + axiom_attribute_t *trs_class_name = NULL; + axiom_children_qname_iterator_t *itr = NULL; + axutil_qname_t *class_qname = NULL; + axutil_qname_t *qparamst = NULL; + axutil_qname_t *qinflowst = NULL; + axutil_qname_t *qoutflowst = NULL; + axutil_qname_t *qinfaultflowst = NULL; + axutil_qname_t *qoutfaultflowst = NULL; + axiom_element_t *in_flow_element = NULL; + axiom_node_t *in_flow_node = NULL; + axiom_element_t *out_flow_element = NULL; + axiom_node_t *out_flow_node = NULL; + axiom_element_t *in_fault_flow_element = NULL; + axiom_node_t *in_fault_flow_node = NULL; + axiom_element_t *out_fault_flow_element = NULL; + axiom_node_t *out_fault_flow_node = NULL; + AXIS2_TRANSPORT_ENUMS transport_enum = AXIS2_TRANSPORT_ENUM_HTTP; + /* AXIS2_TRANSPORT_ENUMS transport_enum = AXIS2_TRANSPORT_ENUM_HTTP + * set to avoid C4701 on Windows + */ + + name = axiom_attribute_get_value(trs_name, env); + if(name) + { + if(!axutil_strcmp(name, AXIS2_TRANSPORT_HTTP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_HTTP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_SMTP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_SMTP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_XMPP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_XMPP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_TCP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_TCP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_HTTPS)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_HTTPS; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_AMQP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_AMQP; + } + else if(!axutil_strcmp(name, AXIS2_TRANSPORT_UDP)) + { + transport_enum = AXIS2_TRANSPORT_ENUM_UDP; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Transport %s could not be recognized.", name); + return AXIS2_FAILURE; + } + + transport_in = axis2_transport_in_desc_create(env, transport_enum); + } + if(!transport_in) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating trasport_in_desc for transport %s failed", name); + return AXIS2_FAILURE; + } + + /* transport impl class */ + class_qname = axutil_qname_create(env, AXIS2_CLASSNAME, NULL, NULL); + trs_class_name = axiom_element_get_attribute(transport_element, env, class_qname); + axutil_qname_free(class_qname, env); + + if(trs_class_name) + { + axis2_char_t *class_name = NULL; + axis2_char_t *dll_name = NULL; + axutil_dll_desc_t *dll_desc = NULL; + axutil_param_t *impl_info_param = NULL; + axis2_transport_receiver_t *recv = NULL; + axis2_status_t stat = AXIS2_FAILURE; + axis2_char_t *path_qualified_dll_name = NULL; + axis2_char_t *repos_name = NULL; + axis2_char_t *temp_path = NULL; + axis2_char_t *temp_path2 = NULL; + axis2_char_t *temp_path3 = NULL; + + axutil_param_t *tnsparam; + axis2_char_t *libpath; + + class_name = axiom_attribute_get_value(trs_class_name, env); + impl_info_param = axutil_param_create(env, class_name, NULL); + dll_desc = axutil_dll_desc_create(env); + dll_name = axutil_dll_desc_create_platform_specific_dll_name(dll_desc, env, + class_name); + if(!axis2_flag) + { + /* Axis2 Configuration is not built using axis2.xml */ + repos_name = axis2_dep_engine_get_repos_path(axis2_desc_builder_get_dep_engine( + conf_builder->desc_builder, env), env); + temp_path = axutil_stracat(env, repos_name, AXIS2_PATH_SEP_STR); + temp_path2 = axutil_stracat(env, temp_path, AXIS2_LIB_FOLDER); + temp_path3 = axutil_stracat(env, temp_path2, AXIS2_PATH_SEP_STR); + path_qualified_dll_name = axutil_stracat(env, temp_path3, dll_name); + AXIS2_FREE(env->allocator, temp_path); + AXIS2_FREE(env->allocator, temp_path2); + AXIS2_FREE(env->allocator, temp_path3); + } + else + { + /* Axis2 Configuration is built using axis2.xml */ + tnsparam = axis2_conf_get_param(conf, env, AXIS2_LIB_DIR); + if(tnsparam) + { + libpath = (axis2_char_t *)axutil_param_get_value(tnsparam, env); + + if(libpath) + { + path_qualified_dll_name = axutil_strcat(env, libpath, + AXIS2_PATH_SEP_STR, dll_name, NULL); + } + } + } + + axutil_dll_desc_set_name(dll_desc, env, path_qualified_dll_name); + AXIS2_FREE(env->allocator, path_qualified_dll_name); + axutil_dll_desc_set_type(dll_desc, env, AXIS2_TRANSPORT_RECV_DLL); + + axutil_param_set_value(impl_info_param, env, dll_desc); + axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg); + axutil_class_loader_init(env); + recv = (axis2_transport_receiver_t *)axutil_class_loader_create_dll(env, + impl_info_param); + axis2_transport_in_desc_add_param(transport_in, env, impl_info_param); + + if(!recv) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Transport receiver loading failed for %s, " + "unable to continue", dll_name); + axis2_transport_in_desc_free(transport_in, env); + return status; + } + axis2_transport_receiver_set_is_application_client_side(recv, env, AXIS2_TRUE); + stat = axis2_transport_in_desc_set_recv(transport_in, env, recv); + + if(!stat) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting transport receiver for transport %s into " + "transport in description failed, unable to continue", name); + axis2_transport_in_desc_free(transport_in, env); + return stat; + } + + } + + /* process Parameters */ + /* processing Paramters */ + /* Processing service level paramters */ + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + itr = axiom_element_get_children_with_qname(transport_element, env, qparamst, + transport_node); + axutil_qname_free(qparamst, env); + status = axis2_desc_builder_process_params(conf_builder->desc_builder, env, itr, + axis2_transport_in_desc_param_container(transport_in, env), + axis2_conf_get_param_container(conf_builder->conf, env)); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Processing transport receiver parameters failed. " + "Unable to continue"); + axis2_transport_in_desc_free(transport_in, env); + return status; + } + /* process OUT_FLOW */ + qoutflowst = axutil_qname_create(env, AXIS2_OUT_FLOW_START, NULL, NULL); + out_flow_element = axiom_element_get_first_child_with_qname(transport_element, env, + qoutflowst, transport_node, &out_flow_node); + axutil_qname_free(qoutflowst, env); + if(out_flow_element) + { + axis2_transport_in_desc_free(transport_in, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_OUT_FLOW_NOT_ALLOWED_IN_TRS_IN, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Out flow element not allowed in transport in path"); + return AXIS2_FAILURE; + } + + qinflowst = axutil_qname_create(env, AXIS2_IN_FLOW_START, NULL, NULL); + in_flow_element = axiom_element_get_first_child_with_qname(transport_element, env, + qinflowst, transport_node, &in_flow_node); + axutil_qname_free(qinflowst, env); + if(in_flow_element) + { + axis2_flow_t *flow = NULL; + + flow = axis2_desc_builder_process_flow(conf_builder->desc_builder, env, + in_flow_element, axis2_conf_get_param_container(conf_builder->conf, env), + in_flow_node); + status = axis2_transport_in_desc_set_in_flow(transport_in, env, flow); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting in flow into transport_in_desc of transport " + "%s failed", name); + axis2_transport_in_desc_free(transport_in, env); + return status; + } + } + + qinfaultflowst = axutil_qname_create(env, AXIS2_IN_FAILTFLOW, NULL, NULL); + in_fault_flow_element = axiom_element_get_first_child_with_qname(transport_element, + env, qinfaultflowst, transport_node, &in_fault_flow_node); + axutil_qname_free(qinfaultflowst, env); + if(in_fault_flow_element) + { + axis2_flow_t *flow = NULL; + + flow = axis2_desc_builder_process_flow(conf_builder->desc_builder, env, + in_fault_flow_element, axis2_conf_get_param_container(conf_builder->conf, env), + in_fault_flow_node); + status = axis2_transport_in_desc_set_fault_in_flow(transport_in, env, flow); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting in fault flow into transport_in_desc of " + "transport %s failed", name); + axis2_transport_in_desc_free(transport_in, env); + return status; + } + } + + qoutfaultflowst = axutil_qname_create(env, AXIS2_OUT_FAILTFLOW, NULL, NULL); + out_fault_flow_element = axiom_element_get_first_child_with_qname(transport_element, + env, qoutfaultflowst, transport_node, &out_fault_flow_node); + if(out_fault_flow_element) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_OUT_FLOW_NOT_ALLOWED_IN_TRS_IN, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Out flow element is not allowed in transport in path"); + return AXIS2_FAILURE; + } + + /* adding to axis config */ + status = axis2_conf_add_transport_in(conf_builder->conf, env, transport_in, + transport_enum); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding transport_in_desc for transport %s into main " + "configuration failed.", name); + axis2_transport_in_desc_free(transport_in, env); + return status; + } + + axutil_qname_free(qoutfaultflowst, env); + + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_conf_builder_process_transport_recvs"); + return AXIS2_SUCCESS; +} + +static axis2_status_t AXIS2_CALL +axis2_conf_builder_process_default_module_versions( + axis2_conf_builder_t * conf_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_versions) +{ + AXIS2_PARAM_CHECK(env->error, module_versions, AXIS2_FAILURE); + + while(axiom_children_qname_iterator_has_next(module_versions, env)) + { + axiom_element_t *om_element = NULL; + axis2_char_t *name = NULL; + axis2_char_t *default_version = NULL; + axutil_qname_t *attribute_qname = NULL; + + om_element = (axiom_element_t *)axiom_children_qname_iterator_next(module_versions, env); + if(!om_element) + { + continue; + } + attribute_qname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + if(!attribute_qname) + { + continue; + } + name = axiom_element_get_attribute_value(om_element, env, attribute_qname); + axutil_qname_free(attribute_qname, env); + attribute_qname = NULL; + if(!name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Attribute value is NULL for " + "attribute %s", AXIS2_ATTNAME); + return AXIS2_FAILURE; + } + attribute_qname = axutil_qname_create(env, AXIS2_ATTRIBUTE_DEFAULT_VERSION, NULL, NULL); + if(!attribute_qname) + { + continue; + } + default_version = axiom_element_get_attribute_value(om_element, env, attribute_qname); + axutil_qname_free(attribute_qname, env); + attribute_qname = NULL; + if(!default_version) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Attribute value is NULL for " + "attribute %s", AXIS2_ATTRIBUTE_DEFAULT_VERSION); + return AXIS2_FAILURE; + } + axis2_conf_add_default_module_version(conf_builder->conf, env, name, default_version); + } + return AXIS2_SUCCESS; +} + diff --git a/src/core/deployment/conf_init.c b/src/core/deployment/conf_init.c new file mode 100644 index 0000000..6a622b4 --- /dev/null +++ b/src/core/deployment/conf_init.c @@ -0,0 +1,460 @@ +/* + * 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_conf_init.h> +#include <axis2_transport_sender.h> +#include <axis2_transport_receiver.h> +#include <axis2_const.h> +#include <axutil_error.h> +#include <axutil_allocator.h> +#include <axutil_class_loader.h> +#include <axis2_dep_engine.h> +#include <axis2_module.h> + +#define DEFAULT_REPO_PATH "." + +axis2_status_t AXIS2_CALL +axis2_init_modules( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx); + +static axis2_status_t AXIS2_CALL +axis2_load_services( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx); + +axis2_status_t AXIS2_CALL +axis2_init_transports( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx); + +static axis2_conf_ctx_t *AXIS2_CALL +axis2_build_conf_ctx_with_dep_engine( + const axutil_env_t * env, + axis2_dep_engine_t *dep_engine, + axis2_char_t *is_server_side) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axutil_property_t *property = NULL; + axis2_ctx_t *conf_ctx_base = NULL; + + conf = axis2_dep_engine_load(dep_engine, env); + if(!conf) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Loading deployment engine failed"); + axis2_dep_engine_free(dep_engine, env); + return NULL; + } + axis2_conf_set_dep_engine(conf, env, dep_engine); + + conf_ctx = axis2_conf_ctx_create(env, conf); + if(!conf_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating Axis2 configuration context failed."); + return NULL; + } + axis2_conf_ctx_set_root_dir(conf_ctx, env, axis2_dep_engine_get_repos_path(dep_engine, env)); + + conf_ctx_base = axis2_conf_ctx_get_base(conf_ctx, env); + property = axutil_property_create_with_args(env, 2, 0, 0, is_server_side); + axis2_ctx_set_property(conf_ctx_base, env, AXIS2_IS_SVR_SIDE, property); + + axis2_init_modules(env, conf_ctx); + axis2_init_transports(env, conf_ctx); + + if(!axutil_strcmp(is_server_side, AXIS2_VALUE_TRUE)) + { + axis2_load_services(env, conf_ctx); + } + + return conf_ctx; +} + +AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL +axis2_build_conf_ctx( + const axutil_env_t * env, + const axis2_char_t * repo_name) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_dep_engine_t *dep_engine = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_build_conf_ctx"); + dep_engine = axis2_dep_engine_create_with_repos_name(env, repo_name); + if(!dep_engine) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating deployment engine failed for repository %s", repo_name); + return NULL; + } + + conf_ctx = axis2_build_conf_ctx_with_dep_engine(env, dep_engine, AXIS2_VALUE_TRUE); + if(!conf_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Loading configuration context failed for repository %s.", repo_name); + return NULL; + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_build_conf_ctx"); + return conf_ctx; +} + +AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL +axis2_build_conf_ctx_with_file( + const axutil_env_t * env, + const axis2_char_t * file) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_dep_engine_t *dep_engine = NULL; + axis2_char_t *repos_path = NULL; + axis2_char_t *temp_path = NULL; + axis2_char_t *index = NULL; + axis2_char_t *xmlfile = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_build_conf_ctx_with_file"); + temp_path = axutil_strdup(env, file); + index = axutil_rindex(temp_path, AXIS2_PATH_SEP_CHAR); + if(!index) + {/* searching from windows specific path seperator */ + index = axutil_rindex(temp_path, '\\'); + } + + if(!index) + { + /** only the xml file name is provided. Assume the default repo path */ + repos_path = AXIS2_GETENV("AXIS2C_HOME"); + xmlfile = (axis2_char_t*)file; + }else + { + xmlfile = index+1; + temp_path[index-temp_path] = '\0'; + repos_path = temp_path; + } + + dep_engine = axis2_dep_engine_create_with_repos_name_and_svr_xml_file(env, repos_path, xmlfile); + if(!dep_engine) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating deployment engine for given Axis2 configuration file" + "(axis2.xml) failed"); + return NULL; + } + + conf_ctx = axis2_build_conf_ctx_with_dep_engine(env, dep_engine, AXIS2_VALUE_TRUE); + if(!conf_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Loading configuration context failed for given Axis2 configuration %s.", file); + return NULL; + } + AXIS2_FREE(env->allocator, temp_path); + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_build_conf_ctx_with_file"); + return conf_ctx; +} + +axis2_conf_ctx_t *AXIS2_CALL +axis2_build_client_conf_ctx( + const axutil_env_t * env, + const axis2_char_t * axis2_home) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_dep_engine_t *dep_engine = NULL; + axis2_conf_t *conf = NULL; + axutil_property_t *property = NULL; + axis2_ctx_t *conf_ctx_base = NULL; + + axis2_status_t status; + unsigned int len = 0; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_build_client_conf_ctx"); + /* Building conf using axis2.xml, in that case we check whether + * last 9 characters of the axis2_home equals to the "axis2.xml" + * else treat it as a directory + */ + + status = axutil_file_handler_access (axis2_home, AXIS2_R_OK); + if (status == AXIS2_SUCCESS) + { + len = (int)strlen (axis2_home); + /* We are sure that the difference lies within the int range */ + if ((len >= 9) && + !strcmp ((axis2_home + (len - 9)), "axis2.xml")) + { + dep_engine = axis2_dep_engine_create_with_axis2_xml (env, + axis2_home); + } + else + { + dep_engine = axis2_dep_engine_create(env); + } + } + else + { + AXIS2_LOG_WARNING (env->log, AXIS2_LOG_SI, + "Provided client repository path %s does not exsist or no "\ + "permission to read, therefore set axis2c home to DEFAULT_REPO_PATH.", + axis2_home); + axis2_home = DEFAULT_REPO_PATH; + dep_engine = axis2_dep_engine_create(env); + } + if (!dep_engine) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating deployment engine for client repository %s failed." , + axis2_home); + return NULL; + } + conf = axis2_dep_engine_load_client(dep_engine, env, axis2_home); + if (!conf) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Loading deployment engine failed for client repository %s", + axis2_home); + axis2_dep_engine_free(dep_engine, env); + return NULL; + } + axis2_conf_set_dep_engine(conf, env, dep_engine); + + conf_ctx = axis2_conf_ctx_create(env, conf); + if (!conf_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating Axis2 configuration context failed"); + return NULL; + } + axis2_conf_ctx_set_root_dir(conf_ctx, env, axis2_dep_engine_get_repos_path(dep_engine, env)); + + conf_ctx_base = axis2_conf_ctx_get_base(conf_ctx, env); + property = axutil_property_create_with_args(env, 2, 0, 0, AXIS2_VALUE_FALSE); + axis2_ctx_set_property(conf_ctx_base, env, AXIS2_IS_SVR_SIDE, property); + + axis2_init_modules(env, conf_ctx); + axis2_init_transports(env, conf_ctx); + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_build_client_conf_ctx"); + return conf_ctx; +} + +axis2_status_t AXIS2_CALL +axis2_init_modules( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_conf_t *conf = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_init_modules"); + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + axutil_hash_t *module_map = axis2_conf_get_all_modules(conf, env); + if(module_map) + { + axutil_hash_index_t *hi = NULL; + void *module = NULL; + for(hi = axutil_hash_first(module_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &module); + if(module) + { + axis2_module_desc_t *mod_desc = (axis2_module_desc_t *)module; + if(mod_desc) + { + axis2_module_t *mod = axis2_module_desc_get_module(mod_desc, env); + if(mod) + { + axis2_module_init(mod, env, conf_ctx, mod_desc); + } + } + } + } + } + status = AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "Retrieving Axis2 configuration from Axis2 configuration context " + "failed. Initializing modules failed"); + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_init_modules"); + return status; +} + +static axis2_status_t AXIS2_CALL +axis2_load_services( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_conf_t *conf = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_hash_t *svc_map = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_load_services"); + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(!conf) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "Retrieving Axis2 configuration from Axis2 " + "configuration context failed, Loading services failed"); + return status; + } + + svc_map = axis2_conf_get_all_svcs_to_load(conf, env); + if(svc_map) + { + axutil_hash_index_t *hi = NULL; + void *svc = NULL; + for(hi = axutil_hash_first(svc_map, env); hi; hi = axutil_hash_next(env, hi)) + { + void *impl_class = NULL; + axutil_hash_t *ops_hash = NULL; + axis2_msg_recv_t *msg_recv = 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, conf_ctx);
+ axis2_msg_recv_load_and_init_svc(msg_recv, env, svc);
+ }
+ }
+ }
+
+ } + /* + svc_desc = (axis2_svc_t *)svc; + if(!svc_desc) + { + continue; + } + + svc_name = axis2_svc_get_name(svc_desc, env); + impl_info_param = axis2_svc_get_param(svc_desc, env, AXIS2_SERVICE_CLASS); + + if(!impl_info_param) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid state of the service %s", svc_name); + return AXIS2_FAILURE; + } + axutil_class_loader_init(env); + impl_class = axutil_class_loader_create_dll(env, impl_info_param); + if(!impl_class) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service %s could not be loaded", svc_name); + return AXIS2_FAILURE; + } + + axis2_svc_set_impl_class(svc_desc, env, impl_class); + if(AXIS2_SVC_SKELETON_INIT_WITH_CONF((axis2_svc_skeleton_t *)impl_class, env, conf) + != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Initialization failed for the service %s. " + "Check the service's init_with_conf() function for errors and retry", svc_name); + } + */ + + } + } + status = AXIS2_SUCCESS; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_load_services"); + return status; +} + +axis2_status_t AXIS2_CALL +axis2_init_transports( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_conf_t *conf = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_init_transports"); + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + axis2_transport_in_desc_t **transport_in_map = NULL; + axis2_transport_out_desc_t **transport_out_map = NULL; + int i = 0; + + transport_in_map = axis2_conf_get_all_in_transports(conf, env); + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + if(transport_in_map[i]) + { + axis2_transport_receiver_t *listener = axis2_transport_in_desc_get_recv( + transport_in_map[i], env); + if(listener) + { + status = axis2_transport_receiver_init(listener, env, conf_ctx, + transport_in_map[i]); + } + } + } + + transport_out_map = axis2_conf_get_all_out_transports(conf, env); + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + if(transport_out_map[i]) + { + axis2_transport_sender_t *sender = axis2_transport_out_desc_get_sender( + transport_out_map[i], env); + if(sender) + { + status = AXIS2_TRANSPORT_SENDER_INIT(sender, env, conf_ctx, + transport_out_map[i]); + } + } + } + status = AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "Retrieving Axis2 configuration from Axis2 configuration context " + "failed. Initializing transports failed"); + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_init_transports"); + return status; +} + diff --git a/src/core/deployment/dep_engine.c b/src/core/deployment/dep_engine.c new file mode 100644 index 0000000..2c43380 --- /dev/null +++ b/src/core/deployment/dep_engine.c @@ -0,0 +1,1988 @@ +/* + * 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_dep_engine.h" +#include <axutil_array_list.h> +#include <axis2_deployment.h> +#include <axutil_file_handler.h> +#include <axis2_flow.h> +#include <axis2_arch_reader.h> +#include <axis2_module_builder.h> +#include <axis2_svc_builder.h> +#include <axis2_svc_grp_builder.h> +#include <axiom_node.h> +#include <axutil_class_loader.h> +#include <axutil_string.h> +#include <axutil_utils.h> +#include <axis2_core_utils.h> +#include <axis2_module.h> + +struct axis2_dep_engine +{ + axis2_arch_file_data_t *curr_file; + axis2_arch_reader_t *arch_reader; + + /** + * To keep a reference to engine configuration. + * This reference will pass to engine when it call start() + * function + */ + axis2_conf_t *conf; + axis2_char_t *axis2_repos; + axis2_bool_t hot_dep; /* to do hot deployment or not */ + axis2_bool_t hot_update; /* to do hot update or not */ + + /* Whether dep_engine built using axis2.xml */ + axis2_bool_t file_flag; + + /** + * This will store all the web services to deploy + */ + axutil_array_list_t *ws_to_deploy; + + /** + * This will store all the web services to undeploy + */ + axutil_array_list_t *ws_to_undeploy; + axis2_phases_info_t *phases_info; /* To store phases list in axis2.xml */ + + axis2_char_t *folder_name; + + /** + * Module directory, dep_engine holds in the module build scenario. + */ + axis2_char_t *module_dir; + + /** + * Services directory, services are avialble in services directory + */ + + axis2_char_t *svc_dir; + + /** + * Full path to the server xml file(axis2.xml) + */ + axis2_char_t *conf_name; + + /** + * To store the module specified in the server.xml(axis2.xml) at the + * document parsing time + */ + axutil_array_list_t *module_list; + axis2_repos_listener_t *repos_listener; /*Added this here to help with freeing + memory allocated for this - Samisa */ + axis2_conf_builder_t *conf_builder; + axis2_svc_builder_t *svc_builder; + axutil_array_list_t *desc_builders; + axutil_array_list_t *module_builders; + axutil_array_list_t *svc_builders; + axutil_array_list_t *svc_grp_builders; +}; + +static axis2_status_t +axis2_dep_engine_set_dep_features( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + +static axis2_status_t +axis2_dep_engine_check_client_home( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + const axis2_char_t * client_home); + +static axis2_status_t +axis2_dep_engine_engage_modules( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + +static axis2_status_t +axis2_dep_engine_validate_system_predefined_phases( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env); + +static axis2_status_t +axis2_dep_engine_add_new_svc( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_svc_grp_t * svc_metadata); + +static axis2_status_t +axis2_dep_engine_load_module_dll( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_module_desc_t * module_desc); + +static axis2_status_t +axis2_dep_engine_add_module_flow_handlers( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_flow_t * flow, + axutil_hash_t * handler_create_func_map); + +static axis2_status_t +axis2_dep_engine_add_new_module( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_module_desc_t * module_metadata); + +static axis2_char_t * +axis2_dep_engine_get_axis_svc_name( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_char_t * file_name); + +static axis2_status_t +axis2_dep_engine_set_svc_and_module_dir_path( + axis2_dep_engine_t *dep_engine, + const axutil_env_t *env); + +AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL +axis2_dep_engine_create( + const axutil_env_t * env) +{ + axis2_dep_engine_t *dep_engine = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + dep_engine = (axis2_dep_engine_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_dep_engine_t)); + + if(!dep_engine) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + dep_engine = (axis2_dep_engine_t *)memset(dep_engine, 0, sizeof(axis2_dep_engine_t)); + dep_engine->curr_file = NULL; + dep_engine->arch_reader = NULL; + dep_engine->conf = NULL; + dep_engine->axis2_repos = NULL; + dep_engine->ws_to_deploy = NULL; + dep_engine->ws_to_undeploy = NULL; + dep_engine->phases_info = NULL; + dep_engine->folder_name = NULL; + dep_engine->module_dir = NULL; + dep_engine->svc_dir = NULL; + dep_engine->conf_name = NULL; + dep_engine->module_list = NULL; + dep_engine->repos_listener = NULL; + dep_engine->conf_builder = NULL; + dep_engine->svc_builder = NULL; + dep_engine->desc_builders = NULL; + dep_engine->module_builders = NULL; + dep_engine->svc_builders = NULL; + dep_engine->svc_grp_builders = NULL; + + dep_engine->ws_to_deploy = axutil_array_list_create(env, 0); + if(!(dep_engine->ws_to_deploy)) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + dep_engine->desc_builders = axutil_array_list_create(env, 0); + dep_engine->module_builders = axutil_array_list_create(env, 0); + dep_engine->svc_builders = axutil_array_list_create(env, 0); + dep_engine->svc_grp_builders = axutil_array_list_create(env, 0); + + dep_engine->phases_info = axis2_phases_info_create(env); + if(!(dep_engine->phases_info)) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + return dep_engine; +} + +AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL +axis2_dep_engine_create_with_repos_name( + const axutil_env_t * env, + const axis2_char_t * repos_path) +{ + axis2_dep_engine_t *dep_engine = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + dep_engine = (axis2_dep_engine_t *)axis2_dep_engine_create_with_repos_name_and_svr_xml_file( + env, repos_path, AXIS2_SERVER_XML_FILE); + + if(!dep_engine) + { + return NULL; + } + + dep_engine->file_flag = AXIS2_FALSE; + + return dep_engine; +} + +AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL +axis2_dep_engine_create_with_axis2_xml( + const axutil_env_t * env, + const axis2_char_t * axis2_xml) +{ + axis2_dep_engine_t *dep_engine = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + dep_engine = (axis2_dep_engine_t *)axis2_dep_engine_create_with_svr_xml_file(env, axis2_xml); + if(!dep_engine) + { + return NULL; + } + dep_engine->file_flag = AXIS2_TRUE; + + return dep_engine; +} + +AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL +axis2_dep_engine_create_with_repos_name_and_svr_xml_file( + const axutil_env_t * env, + const axis2_char_t * repos_path, + const axis2_char_t * svr_xml_file) +{ + axis2_dep_engine_t *dep_engine = NULL; + axis2_char_t *conf_file_l = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, repos_path, NULL); + AXIS2_PARAM_CHECK(env->error, svr_xml_file, NULL); + if(!axutil_strcmp("", repos_path)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_REPO_CAN_NOT_BE_NULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Repository path cannot be empty"); + return NULL; + } + + dep_engine = (axis2_dep_engine_t *)axis2_dep_engine_create(env); + + if(!dep_engine) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + status = axutil_file_handler_access(repos_path, AXIS2_F_OK); + if(AXIS2_SUCCESS != status) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_REPOSITORY_NOT_EXIST, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Repository path %s does not exist", repos_path); + return NULL; + } + + dep_engine->folder_name = axutil_strdup(env, repos_path); + if(!dep_engine->folder_name) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + dep_engine->axis2_repos = axutil_strdup(env, repos_path); + if(!dep_engine->axis2_repos) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + conf_file_l = axutil_stracat(env, repos_path, AXIS2_PATH_SEP_STR); + dep_engine->conf_name = axutil_stracat(env, conf_file_l, svr_xml_file); + + AXIS2_FREE(env->allocator, conf_file_l); + if(!dep_engine->conf_name) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_REPO_CAN_NOT_BE_NULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Axis2 Configuration file name cannot be NULL"); + return NULL; + } + + status = axutil_file_handler_access(dep_engine->conf_name, AXIS2_F_OK); + if(AXIS2_SUCCESS != status) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CONFIG_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Axis2 Configuration file name not found"); + return NULL; + } + + return dep_engine; +} + +AXIS2_EXTERN axis2_dep_engine_t *AXIS2_CALL +axis2_dep_engine_create_with_svr_xml_file( + const axutil_env_t * env, + const axis2_char_t * svr_xml_file) +{ + axis2_dep_engine_t *dep_engine = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, svr_xml_file, NULL); + + dep_engine = (axis2_dep_engine_t *)axis2_dep_engine_create(env); + + if(!dep_engine) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + dep_engine->conf_name = axutil_strdup(env, (axis2_char_t *)svr_xml_file); + if(!dep_engine->conf_name) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_REPO_CAN_NOT_BE_NULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Axis2 Configuration file name cannot be NULL"); + return NULL; + } + status = axutil_file_handler_access(dep_engine->conf_name, AXIS2_F_OK); + if(AXIS2_SUCCESS != status) + { + axis2_dep_engine_free(dep_engine, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CONFIG_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Axis2 Configuration file name not found"); + return NULL; + } + + return dep_engine; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_dep_engine_free( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + if(!dep_engine) + { + return; + } + + if(dep_engine->curr_file) + { + axis2_arch_file_data_free(dep_engine->curr_file, env); + } + + if(dep_engine->phases_info) + { + axis2_phases_info_free(dep_engine->phases_info, env); + } + + if(dep_engine->conf_builder) + { + axis2_conf_builder_free(dep_engine->conf_builder, env); + } + + if(dep_engine->arch_reader) + { + axis2_arch_reader_free(dep_engine->arch_reader, env); + } + + if(dep_engine->svc_builder) + { + axis2_svc_builder_free(dep_engine->svc_builder, env); + } + + if(dep_engine->ws_to_deploy) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(dep_engine->ws_to_deploy, env); + for(i = 0; i < size; i++) + { + axis2_arch_file_data_t *file_data = NULL; + + file_data = (axis2_arch_file_data_t *)axutil_array_list_get(dep_engine->ws_to_deploy, + env, i); + + axis2_arch_file_data_free(file_data, env); + } + + axutil_array_list_free(dep_engine->ws_to_deploy, env); + dep_engine->ws_to_deploy = NULL; + } + + if(dep_engine->desc_builders) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(dep_engine->desc_builders, env); + for(i = 0; i < size; i++) + { + axis2_desc_builder_t *desc_builder = NULL; + + desc_builder = (axis2_desc_builder_t *)axutil_array_list_get(dep_engine->desc_builders, + env, i); + + axis2_desc_builder_free(desc_builder, env); + } + + axutil_array_list_free(dep_engine->desc_builders, env); + } + + if(dep_engine->module_builders) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(dep_engine->module_builders, env); + for(i = 0; i < size; i++) + { + axis2_module_builder_t *module_builder = NULL; + + module_builder = (axis2_module_builder_t *)axutil_array_list_get( + dep_engine->module_builders, env, i); + + axis2_module_builder_free(module_builder, env); + } + + axutil_array_list_free(dep_engine->module_builders, env); + } + + if(dep_engine->svc_builders) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(dep_engine->svc_builders, env); + for(i = 0; i < size; i++) + { + axis2_svc_builder_t *svc_builder = NULL; + + svc_builder = (axis2_svc_builder_t *)axutil_array_list_get(dep_engine->svc_builders, + env, i); + + axis2_svc_builder_free(svc_builder, env); + } + + axutil_array_list_free(dep_engine->svc_builders, env); + } + + if(dep_engine->svc_grp_builders) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(dep_engine->svc_grp_builders, env); + for(i = 0; i < size; i++) + { + axis2_svc_grp_builder_t *svc_grp_builder = NULL; + + svc_grp_builder = (axis2_svc_grp_builder_t *)axutil_array_list_get( + dep_engine->svc_grp_builders, env, i); + + axis2_svc_grp_builder_free(svc_grp_builder, env); + } + + axutil_array_list_free(dep_engine->svc_grp_builders, env); + } + + if(dep_engine->ws_to_undeploy) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(dep_engine->ws_to_undeploy, env); + + for(i = 0; i < size; i++) + { + axis2_arch_file_data_t *file_data = NULL; + + file_data = (axis2_arch_file_data_t *)axutil_array_list_get(dep_engine->ws_to_undeploy, + env, i); + + axis2_arch_file_data_free(file_data, env); + } + + axutil_array_list_free(dep_engine->ws_to_undeploy, env); + dep_engine->ws_to_undeploy = NULL; + } + + if(dep_engine->module_list) + { + int size = 0; + int i = 0; + + size = axutil_array_list_size(dep_engine->module_list, env); + + for(i = 0; i < size; i++) + { + axutil_qname_t *qname = NULL; + qname = axutil_array_list_get(dep_engine->module_list, env, i); + if(qname) + { + axutil_qname_free(qname, env); + } + } + + axutil_array_list_free(dep_engine->module_list, env); + } + + if(dep_engine->folder_name) + { + AXIS2_FREE(env->allocator, dep_engine->folder_name); + } + + if(dep_engine->conf_name) + { + AXIS2_FREE(env->allocator, dep_engine->conf_name); + } + + if(dep_engine->axis2_repos) + { + AXIS2_FREE(env->allocator, dep_engine->axis2_repos); + } + + if(dep_engine->repos_listener) + { + axis2_repos_listener_free(dep_engine->repos_listener, env); + } + + if(dep_engine) + { + AXIS2_FREE(env->allocator, dep_engine); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_add_module( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axutil_qname_t * module_qname) +{ + axutil_qname_t *qname = NULL; + + AXIS2_PARAM_CHECK(env->error, module_qname, AXIS2_FAILURE); + + qname = axutil_qname_clone(module_qname, env); + if(!dep_engine->module_list) + { + dep_engine->module_list = axutil_array_list_create(env, 0); + if(!dep_engine->module_list) + { + axutil_qname_free(qname, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + } + return axutil_array_list_add(dep_engine->module_list, env, qname); +} + +struct axis2_module_desc *AXIS2_CALL +axis2_dep_engine_get_module( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axutil_qname_t * module_qname) +{ + AXIS2_PARAM_CHECK(env->error, module_qname, NULL); + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + + return axis2_conf_get_module(dep_engine->conf, env, module_qname); +} + +AXIS2_EXTERN struct axis2_arch_file_data *AXIS2_CALL +axis2_dep_engine_get_current_file_item( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + return dep_engine->curr_file; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_add_ws_to_deploy( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_arch_file_data_t * file) +{ + AXIS2_PARAM_CHECK(env->error, file, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + return axutil_array_list_add(dep_engine->ws_to_deploy, env, file); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_add_ws_to_undeploy( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_ws_info_t * file) +{ + AXIS2_PARAM_CHECK(env->error, file, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + if(!(dep_engine->ws_to_undeploy)) + { + dep_engine->ws_to_undeploy = axutil_array_list_create(env, 0); + } + return axutil_array_list_add(dep_engine->ws_to_undeploy, env, file); +} + +AXIS2_EXTERN axis2_phases_info_t *AXIS2_CALL +axis2_dep_engine_get_phases_info( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + return dep_engine->phases_info; +} + +AXIS2_EXTERN axis2_conf_t *AXIS2_CALL +axis2_dep_engine_get_axis_conf( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + return dep_engine->conf; +} + +/** + * To set hot deployment and hot update + */ +static axis2_status_t +axis2_dep_engine_set_dep_features( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + axis2_char_t *value = NULL; + axutil_param_t *para_hot_dep = NULL; + axutil_param_t *para_hot_update = NULL; + + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + para_hot_dep = axis2_conf_get_param(dep_engine->conf, env, AXIS2_HOTDEPLOYMENT); + para_hot_update = axis2_conf_get_param(dep_engine->conf, env, AXIS2_HOTUPDATE); + + if(para_hot_dep) + { + value = (axis2_char_t *)axutil_param_get_value(para_hot_dep, env); + if(0 == axutil_strcasecmp(AXIS2_VALUE_FALSE, value)) + { + dep_engine->hot_dep = AXIS2_FALSE; + } + } + + if(para_hot_update) + { + value = (axis2_char_t *)axutil_param_get_value(para_hot_update, env); + if(0 == axutil_strcasecmp(AXIS2_VALUE_FALSE, value)) + { + dep_engine->hot_update = AXIS2_FALSE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_conf_t *AXIS2_CALL +axis2_dep_engine_load( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + axis2_status_t status = AXIS2_FAILURE; + axutil_array_list_t *out_fault_phases = NULL; + + if(!dep_engine->conf_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_PATH_TO_CONFIG_CAN_NOT_BE_NULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Path to axis2 configuration file is NULL. Unable to continue"); + return NULL; + } + + dep_engine->conf = axis2_conf_create(env); + if(!dep_engine->conf) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Allocation to configuration failed"); + return NULL; + } + + /* Set a flag to mark that conf is created using axis2 xml. To find out that conf is build using + * axis2 xml , this flag can be used. + */ + axis2_conf_set_axis2_flag(dep_engine->conf, env, dep_engine->file_flag); + axis2_conf_set_axis2_xml(dep_engine->conf, env, dep_engine->conf_name); + + dep_engine->conf_builder = axis2_conf_builder_create_with_file_and_dep_engine_and_conf(env, + dep_engine->conf_name, dep_engine, dep_engine->conf); + if(!(dep_engine->conf_builder)) + { + axis2_conf_free(dep_engine->conf, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Configuration builder creation failed"); + dep_engine->conf = NULL; + } + + /* Populate the axis2 configuration from reading axis2.xml. + */ + status = axis2_conf_builder_populate_conf(dep_engine->conf_builder, env); + if(AXIS2_SUCCESS != status) + { + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Populating Axis2 Configuration failed"); + return NULL; + } + + status = axis2_dep_engine_set_svc_and_module_dir_path(dep_engine, env); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting service and module directory paths failed"); + return NULL; + } + + status = axis2_dep_engine_set_dep_features(dep_engine, env); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting deployment features failed"); + return NULL; + } + + if(dep_engine->repos_listener) + { + axis2_repos_listener_free(dep_engine->repos_listener, env); + } + + dep_engine->repos_listener = axis2_repos_listener_create_with_folder_name_and_dep_engine(env, + dep_engine->folder_name, dep_engine); + if(!dep_engine->repos_listener) + { + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "dep_engine repos listener creation failed, folder name is %s", dep_engine->folder_name); + return NULL; + } + + axis2_conf_set_repo(dep_engine->conf, env, dep_engine->axis2_repos); + axis2_core_utils_calculate_default_module_version(env, axis2_conf_get_all_modules( + dep_engine->conf, env), dep_engine->conf); + + status = axis2_dep_engine_validate_system_predefined_phases(dep_engine, env); + if(AXIS2_SUCCESS != status) + { + axis2_repos_listener_free(dep_engine->repos_listener, env); + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_VALIDATION_FAILED, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Validating system predefined phases failed"); + return NULL; + } + + status = axis2_conf_set_phases_info(dep_engine->conf, env, dep_engine->phases_info); + if(AXIS2_SUCCESS != status) + { + axis2_repos_listener_free(dep_engine->repos_listener, env); + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting phases info into Axis2 Configuration failed"); + return NULL; + } + + out_fault_phases = axis2_phases_info_get_op_out_faultphases(dep_engine->phases_info, env); + if(out_fault_phases) + { + status = axis2_conf_set_out_fault_phases(dep_engine->conf, env, out_fault_phases); + } + + if(AXIS2_SUCCESS != status) + { + axis2_repos_listener_free(dep_engine->repos_listener, env); + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting out fault phases into Axis2 Configuratin failed"); + return NULL; + } + + status = axis2_dep_engine_engage_modules(dep_engine, env); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "dep engine failed to engaged_modules"); + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_VALIDATION_FAILED, AXIS2_FAILURE); + return NULL; + } + + return dep_engine->conf; +} + +AXIS2_EXTERN axis2_conf_t *AXIS2_CALL +axis2_dep_engine_load_client( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + const axis2_char_t * client_home) +{ + axis2_bool_t is_repos_exist = AXIS2_FALSE; + axis2_status_t status = AXIS2_FAILURE; + axis2_bool_t flag = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, client_home, NULL); + + flag = axis2_dep_engine_get_file_flag(dep_engine, env); + + if(!flag) + { + dep_engine->axis2_repos = axutil_strdup(env, client_home); + if(!dep_engine->axis2_repos) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + if(client_home && axutil_strcmp("", client_home)) + { + status = axis2_dep_engine_check_client_home(dep_engine, env, client_home); + if(AXIS2_SUCCESS == status) + { + is_repos_exist = AXIS2_TRUE; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2.xml is not available in client repo %s ", client_home); + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CONFIG_NOT_FOUND, AXIS2_FAILURE); + + return NULL; + } + } + else + { + dep_engine->conf_name = axutil_strdup(env, AXIS2_CONFIGURATION_RESOURCE); + + if(!dep_engine->conf_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_REPO_CAN_NOT_BE_NULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Axis2 Configuration file name cannot be NULL"); + return NULL; + } + } + } + + else + { + is_repos_exist = AXIS2_TRUE; + } + + dep_engine->conf = axis2_conf_create(env); + if(!dep_engine->conf) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Allocation for Axis2 Configuration failed"); + return NULL; + } + dep_engine->conf_builder = axis2_conf_builder_create_with_file_and_dep_engine_and_conf(env, + dep_engine->conf_name, dep_engine, dep_engine->conf); + + if(!(dep_engine->conf_builder)) + { + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + } + + /** + Very important: Only after populating we will be able to access + parameters in axis2 xml. + */ + + axis2_conf_set_axis2_flag(dep_engine->conf, env, dep_engine->file_flag); + axis2_conf_set_axis2_xml(dep_engine->conf, env, dep_engine->conf_name); + + status = axis2_conf_builder_populate_conf(dep_engine->conf_builder, env); + if(AXIS2_SUCCESS != status) + { + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Populating Axis2 Configuration failed"); + return NULL; + } + + status = axis2_dep_engine_set_svc_and_module_dir_path(dep_engine, env); + if(AXIS2_SUCCESS != status) + { + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting service and module paths failed"); + return NULL; + } + + if(is_repos_exist) + { + dep_engine->hot_dep = AXIS2_FALSE; + dep_engine->hot_update = AXIS2_FALSE; + if(dep_engine->repos_listener) + { + axis2_repos_listener_free(dep_engine->repos_listener, env); + } + + dep_engine->repos_listener = axis2_repos_listener_create_with_folder_name_and_dep_engine( + env, dep_engine->folder_name, dep_engine); + } + + axis2_conf_set_repo(dep_engine->conf, env, dep_engine->axis2_repos); + axis2_core_utils_calculate_default_module_version(env, axis2_conf_get_all_modules( + dep_engine->conf, env), dep_engine->conf); + + axis2_conf_set_phases_info(dep_engine->conf, env, dep_engine->phases_info); + status = axis2_dep_engine_engage_modules(dep_engine, env); + if(AXIS2_SUCCESS != status) + { + axis2_repos_listener_free(dep_engine->repos_listener, env); + axis2_conf_free(dep_engine->conf, env); + dep_engine->conf = NULL; + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_VALIDATION_FAILED, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Module engage failed for deployment engine"); + return NULL; + } + + return dep_engine->conf; +} + +static axis2_status_t +axis2_dep_engine_check_client_home( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + const axis2_char_t * client_home) +{ + axis2_char_t *path_l = NULL; + axis2_status_t status = AXIS2_FAILURE; + + dep_engine->folder_name = axutil_strdup(env, client_home); + if(!dep_engine->folder_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + path_l = axutil_stracat(env, client_home, AXIS2_PATH_SEP_STR); + dep_engine->conf_name = axutil_stracat(env, path_l, AXIS2_SERVER_XML_FILE); + AXIS2_FREE(env->allocator, path_l); + + if(!dep_engine->conf_name) + { + dep_engine->conf_name = axutil_strdup(env, AXIS2_CONFIGURATION_RESOURCE); + if(!dep_engine->conf_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CONFIG_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Axis2 Configuration file name cannot be NULL"); + return AXIS2_FAILURE; + } + } + + status = axutil_file_handler_access(dep_engine->conf_name, AXIS2_F_OK); + if(AXIS2_SUCCESS != status) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CONFIG_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Axis2 Configuration file name not found"); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +static axis2_status_t +axis2_dep_engine_engage_modules( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + int size = 0; + int i = 0; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + if(!dep_engine->module_list) + { + /* There are no modules */ + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "No modules configured"); + return AXIS2_SUCCESS; + } + + size = axutil_array_list_size(dep_engine->module_list, env); + + for(i = 0; i < size; i++) + { + axutil_qname_t *qname = NULL; + qname = (axutil_qname_t *)axutil_array_list_get(dep_engine->module_list, env, i); + if(qname && dep_engine->conf) + { + status = axis2_conf_engage_module(dep_engine->conf, env, qname); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Engaging module %s to Axis2 Configuration failed", axutil_qname_get_localpart( + qname, env)); + + return status; + } + } + } + + return AXIS2_SUCCESS; +} + +static axis2_status_t +axis2_dep_engine_validate_system_predefined_phases( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + axutil_array_list_t *in_phases = NULL; + axis2_char_t *phase0 = NULL; + axis2_char_t *phase1 = NULL; + axis2_char_t *phase2 = NULL; + axis2_char_t *phase3 = NULL; + + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + in_phases = axis2_phases_info_get_in_phases(dep_engine->phases_info, env); + if(in_phases) + { + phase0 = (axis2_char_t *)axutil_array_list_get(in_phases, env, 0); + phase1 = (axis2_char_t *)axutil_array_list_get(in_phases, env, 1); + phase2 = (axis2_char_t *)axutil_array_list_get(in_phases, env, 2); + phase3 = (axis2_char_t *)axutil_array_list_get(in_phases, env, 3); + } + + if((phase0 && 0 != axutil_strcmp(phase0, AXIS2_PHASE_TRANSPORT_IN)) || (phase1 && 0 + != axutil_strcmp(phase1, AXIS2_PHASE_PRE_DISPATCH)) || (phase2 && 0 != axutil_strcmp( + phase2, AXIS2_PHASE_DISPATCH)) || (phase3 && 0 != axutil_strcmp(phase3, + AXIS2_PHASE_POST_DISPATCH))) + { + AXIS2_ERROR_SET(env->error, AXI2_ERROR_INVALID_PHASE, AXIS2_FAILURE); + return AXIS2_SUCCESS; + } + + return AXIS2_SUCCESS; +} + +/* For each searvices belonging to the service group passed as parameter, + * 1) Modules defined to be engaged to passed service group are engaged. + * 2) Modules defined to be engaged to service are engaged. + * + * Then for each service operation modules defined to be engaged to that operation are engaged. + */ +static axis2_status_t +axis2_dep_engine_add_new_svc( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_svc_grp_t * svc_metadata) +{ + axutil_array_list_t *svcs = NULL; + int sizei = 0; + int i = 0; + + AXIS2_PARAM_CHECK(env->error, svc_metadata, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + svcs = axis2_arch_file_data_get_deployable_svcs(dep_engine->curr_file, env); + if(svcs) + { + sizei = axutil_array_list_size(svcs, env); + } + + for(i = 0; i < sizei; i++) + { + axis2_svc_t *svc = NULL; + axutil_file_t *file = NULL; + axutil_array_list_t *grp_modules = NULL; + axutil_array_list_t *list = NULL; + int sizej = 0; + int j = 0; + axutil_hash_t *ops = NULL; + axutil_hash_index_t *index_i = NULL; + axis2_char_t *file_name = NULL; + + svc = (axis2_svc_t *)axutil_array_list_get(svcs, env, i); + + file = axis2_arch_file_data_get_file(dep_engine->curr_file, env); + file_name = axutil_file_get_name(file, env); + axis2_svc_set_file_name(svc, env, file_name); + + /* Modules from service group */ + grp_modules = axis2_svc_grp_get_all_module_qnames(svc_metadata, env); + if(grp_modules) + { + sizej = axutil_array_list_size(grp_modules, env); + } + for(j = 0; j < sizej; j++) + { + axis2_module_desc_t *module_desc = NULL; + axutil_qname_t *qmodulename = NULL; + + qmodulename = (axutil_qname_t *)axutil_array_list_get(grp_modules, env, j); + module_desc = axis2_conf_get_module(dep_engine->conf, env, qmodulename); + if(module_desc) + { + axis2_svc_engage_module(svc, env, module_desc, dep_engine->conf); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid module reference taken from conf"); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODUELE_REF, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + /* Modules from service */ + list = axis2_svc_get_all_module_qnames(svc, env); + sizej = axutil_array_list_size(list, env); + for(j = 0; j < sizej; j++) + { + axis2_module_desc_t *module_desc = NULL; + axutil_qname_t *qmodulename = NULL; + + qmodulename = (axutil_qname_t *)axutil_array_list_get(list, env, j); + module_desc = axis2_conf_get_module(dep_engine->conf, env, qmodulename); + if(module_desc) + { + axis2_status_t status = AXIS2_FAILURE; + status = axis2_svc_engage_module(svc, env, module_desc, dep_engine->conf); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Engaging module %s to service %s failed", axutil_qname_get_localpart( + qmodulename, env), file_name); + return status; + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid module reference taken from conf"); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODUELE_REF, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + ops = axis2_svc_get_all_ops(svc, env); + for(index_i = axutil_hash_first(ops, env); index_i; index_i + = axutil_hash_next(env, index_i)) + { + void *v = NULL; + axis2_op_t *op_desc = NULL; + axutil_array_list_t *modules = NULL; + int sizek = 0; + int k = 0; + + axutil_hash_this(index_i, NULL, NULL, &v); + op_desc = (axis2_op_t *)v; + + modules = axis2_op_get_all_module_qnames(op_desc, env); + if(modules) + { + sizek = axutil_array_list_size(modules, env); + } + for(k = 0; k < sizek; k++) + { + axutil_qname_t *module_qname = NULL; + axis2_module_desc_t *module = NULL; + + module_qname = (axutil_qname_t *)axutil_array_list_get(modules, env, k); + module = axis2_conf_get_module(dep_engine->conf, env, module_qname); + + if(module) + { + axis2_op_engage_module(op_desc, env, module, dep_engine->conf); + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODUELE_REF_BY_OP, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Module %s is not added to the Axis2 Configuration", + axutil_qname_get_localpart(module_qname, env)); + + return AXIS2_FAILURE; + } + } + } + + axis2_svc_grp_add_svc(svc_metadata, env, svc); + } + + return axis2_conf_add_svc_grp(dep_engine->conf, env, svc_metadata); +} + +/* Here we will load the actual module implementation dll using the class loader and store it in + * module description. + */ +static axis2_status_t +axis2_dep_engine_load_module_dll( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_module_desc_t * module_desc) +{ + axis2_char_t *read_in_dll = NULL; + axis2_module_t *module = NULL; + axutil_dll_desc_t *dll_desc = NULL; + axutil_param_t *impl_info_param = NULL; + axutil_file_t *module_folder = NULL; + AXIS2_TIME_T timestamp = 0; + axis2_char_t *module_folder_path = NULL; + axis2_char_t *temp_path = NULL; + axis2_char_t *dll_path = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *dll_name = NULL; + + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + read_in_dll = axis2_arch_file_data_get_module_dll_name(dep_engine->curr_file, env); + dll_desc = axutil_dll_desc_create(env); + dll_name = axutil_dll_desc_create_platform_specific_dll_name(dll_desc, env, read_in_dll); + + module_folder = axis2_arch_file_data_get_file(dep_engine->curr_file, env); + timestamp = axutil_file_get_timestamp(module_folder, env); + axutil_dll_desc_set_timestamp(dll_desc, env, timestamp); + module_folder_path = axutil_file_get_path(module_folder, env); + temp_path = axutil_stracat(env, module_folder_path, AXIS2_PATH_SEP_STR); + dll_path = axutil_stracat(env, temp_path, dll_name); + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "axis2_dep_engine_load_module_dll: DLL path is : %s", + dll_path); + status = axutil_dll_desc_set_name(dll_desc, env, dll_path); + if(AXIS2_SUCCESS != status) + { + axutil_dll_desc_free(dll_desc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting dll path %s to the dll description failed", dll_path); + + return AXIS2_FAILURE; + } + + /* Free all temp vars */ + AXIS2_FREE(env->allocator, temp_path); + temp_path = NULL; + AXIS2_FREE(env->allocator, dll_path); + dll_path = NULL; + + axutil_dll_desc_set_type(dll_desc, env, AXIS2_MODULE_DLL); + impl_info_param = axutil_param_create(env, read_in_dll, NULL); + axutil_param_set_value(impl_info_param, env, dll_desc); + axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg); + axutil_class_loader_init(env); + module = (axis2_module_t *)axutil_class_loader_create_dll(env, impl_info_param); + + /* We cannot free the created impl_info_param here because by freeing + * so, it will free dll_desc which in turn unload the module. So we + * add this as a param to module_desc + */ + axis2_module_desc_add_param(module_desc, env, impl_info_param); + + return axis2_module_desc_set_module(module_desc, env, module); +} + +/* For each handler description of the module flow take the corresponding handler create function + * from handler_create_func_map and create the handler instance for the handler description. + */ +static axis2_status_t +axis2_dep_engine_add_module_flow_handlers( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_flow_t * flow, + axutil_hash_t * handler_create_func_map) +{ + int count = 0; + int j = 0; + + AXIS2_PARAM_CHECK(env->error, flow, AXIS2_FAILURE); + + count = axis2_flow_get_handler_count(flow, env); + + for(j = 0; j < count; j++) + { + axis2_handler_desc_t *handlermd = NULL; + axis2_handler_t *handler = NULL; + const axutil_string_t *handler_name = NULL; + AXIS2_HANDLER_CREATE_FUNC handler_create_func = NULL; + + handlermd = axis2_flow_get_handler(flow, env, j); + handler_name = axis2_handler_desc_get_name(handlermd, env); + handler_create_func = axutil_hash_get(handler_create_func_map, axutil_string_get_buffer( + handler_name, env), AXIS2_HASH_KEY_STRING); + + handler = handler_create_func(env, handler_name); + axis2_handler_init(handler, env, handlermd); + axis2_handler_desc_set_handler(handlermd, env, handler); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void *AXIS2_CALL +axis2_dep_engine_get_handler_dll( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_char_t * class_name) +{ + axutil_dll_desc_t *dll_desc = NULL; + axutil_param_t *impl_info_param = NULL; + axis2_handler_t *handler = NULL; + axis2_char_t *dll_name = NULL; + + AXIS2_PARAM_CHECK(env->error, class_name, NULL); + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + + dll_desc = axutil_dll_desc_create(env); + dll_name = axutil_dll_desc_create_platform_specific_dll_name(dll_desc, env, class_name); + axutil_dll_desc_set_name(dll_desc, env, dll_name); + axutil_dll_desc_set_type(dll_desc, env, AXIS2_HANDLER_DLL); + axutil_class_loader_init(env); + impl_info_param = axutil_param_create(env, NULL, NULL); + axutil_param_set_value(impl_info_param, env, dll_desc); + handler = (axis2_handler_t *)axutil_class_loader_create_dll(env, impl_info_param); + + return handler; +} + +/* Caller has module description filled with the information in module.xml by the time this + * function is called. Now it will load the actual module implementation and fill the module + * flows with the actual handler instances. Finally module description will be added into the + * configuration module list. + */ +static axis2_status_t +axis2_dep_engine_add_new_module( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_module_desc_t * module_metadata) +{ + axis2_flow_t *in_flow = NULL; + axis2_flow_t *out_flow = NULL; + axis2_flow_t *in_fault_flow = NULL; + axis2_flow_t *out_fault_flow = NULL; + axis2_module_t *module = NULL; + axis2_status_t status = AXIS2_FAILURE; + const axutil_qname_t *module_qname = NULL; + axis2_char_t *module_name = NULL; + + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + module_qname = axis2_module_desc_get_qname(module_metadata, env); + module_name = axutil_qname_get_localpart(module_qname, env); + status = axis2_dep_engine_load_module_dll(dep_engine, env, module_metadata); + + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Loading module description %s failed", module_name); + + return status; + } + + module = axis2_module_desc_get_module(module_metadata, env); + if(!module) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Retrieving module from module description %s failed", module_name); + + return AXIS2_FAILURE; + } + + /* Module implementor will provide functions for creating his handlers and by calling this + * function these function pointers will be stored in a hash map in the module. + */ + status = axis2_module_fill_handler_create_func_map(module, env); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Filling handler create function for module map %s failed", module_name); + return status; + } + + in_flow = axis2_module_desc_get_in_flow(module_metadata, env); + if(in_flow) + { + axis2_dep_engine_add_module_flow_handlers(dep_engine, env, in_flow, + module->handler_create_func_map); + } + + out_flow = axis2_module_desc_get_out_flow(module_metadata, env); + if(out_flow) + { + axis2_dep_engine_add_module_flow_handlers(dep_engine, env, out_flow, + module->handler_create_func_map); + } + + in_fault_flow = axis2_module_desc_get_fault_in_flow(module_metadata, env); + if(in_fault_flow) + { + axis2_dep_engine_add_module_flow_handlers(dep_engine, env, in_fault_flow, + module->handler_create_func_map); + } + + out_fault_flow = axis2_module_desc_get_fault_out_flow(module_metadata, env); + if(out_fault_flow) + { + axis2_dep_engine_add_module_flow_handlers(dep_engine, env, out_fault_flow, + module->handler_create_func_map); + } + + /* Add the module description into the axis2 configuration. Axis2 configuration will keep these + * handlers in a hash_map called all_modules. + */ + axis2_conf_add_module(dep_engine->conf, env, module_metadata); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_do_deploy( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + int size = 0; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + size = axutil_array_list_size(dep_engine->ws_to_deploy, env); + + if(size > 0) + { + int i = 0; + for(i = 0; i < size; i++) + { + int type = 0; + axis2_svc_grp_t *svc_grp = NULL; + axis2_char_t *file_name = NULL; + axis2_module_desc_t *meta_data = NULL; + + dep_engine->curr_file = (axis2_arch_file_data_t *)axutil_array_list_get( + dep_engine->ws_to_deploy, env, i); + + type = axis2_arch_file_data_get_type(dep_engine->curr_file, env); + switch(type) + { + case AXIS2_SVC: + { + if(dep_engine->arch_reader) + { + axis2_arch_reader_free(dep_engine->arch_reader, env); + dep_engine->arch_reader = NULL; + } + + dep_engine->arch_reader = axis2_arch_reader_create(env); + svc_grp = axis2_svc_grp_create_with_conf(env, dep_engine->conf); + file_name = axis2_arch_file_data_get_name(dep_engine->curr_file, env); + status = axis2_arch_reader_process_svc_grp(dep_engine->arch_reader, env, + file_name, dep_engine, svc_grp); + + if(AXIS2_SUCCESS != status) + { + axis2_arch_reader_free(dep_engine->arch_reader, env); + dep_engine->arch_reader = NULL; + dep_engine->curr_file = NULL; + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SVC, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Processing service group %s failed", file_name); + + return status; + } + + status = axis2_dep_engine_add_new_svc(dep_engine, env, svc_grp); + if(AXIS2_SUCCESS != status) + { + axis2_arch_reader_free(dep_engine->arch_reader, env); + dep_engine->arch_reader = NULL; + dep_engine->curr_file = NULL; + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SVC, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding new service %s to the deployment engine failed", file_name); + + return status; + } + + dep_engine->curr_file = NULL; + break; + } + + case AXIS2_MODULE: + { + if(dep_engine->arch_reader) + { + axis2_arch_reader_free(dep_engine->arch_reader, env); + dep_engine->arch_reader = NULL; + } + dep_engine->arch_reader = axis2_arch_reader_create(env); + meta_data = axis2_module_desc_create(env); + file_name = axis2_arch_file_data_get_name(dep_engine->curr_file, env); + status = axis2_arch_reader_read_module_arch(env, file_name, dep_engine, + meta_data); + if(AXIS2_SUCCESS != status) + { + axis2_arch_reader_free(dep_engine->arch_reader, env); + dep_engine->arch_reader = NULL; + dep_engine->curr_file = NULL; + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODULE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Reading module archive for file %s failed", file_name); + + return AXIS2_FAILURE; + } + + status = axis2_dep_engine_add_new_module(dep_engine, env, meta_data); + if(AXIS2_SUCCESS != status) + { + axis2_arch_reader_free(dep_engine->arch_reader, env); + dep_engine->arch_reader = NULL; + dep_engine->curr_file = NULL; + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODULE, AXIS2_FAILURE); + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding new module %s to the deployment engine failed", file_name); + + return AXIS2_FAILURE; + } + + dep_engine->curr_file = NULL; + break; + } + }; + + axis2_arch_reader_free(dep_engine->arch_reader, env); + dep_engine->arch_reader = NULL; + dep_engine->curr_file = NULL; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_undeploy( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + int size = 0; + axis2_char_t *svc_name = NULL; + + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + size = axutil_array_list_size(dep_engine->ws_to_undeploy, env); + + if(size > 0) + { + int i = 0; + for(i = 0; i < size; i++) + { + int type = 0; + axis2_ws_info_t *ws_info = NULL; + axutil_hash_t *faulty_svcs = NULL; + + ws_info = (axis2_ws_info_t *)axutil_array_list_get(dep_engine->ws_to_undeploy, env, i); + type = axis2_ws_info_get_type(ws_info, env); + if(type == AXIS2_SVC) + { + axis2_char_t *file_name = NULL; + + file_name = axis2_ws_info_get_file_name(ws_info, env); + svc_name = axis2_dep_engine_get_axis_svc_name(dep_engine, env, file_name); + + axis2_conf_remove_svc(dep_engine->conf, env, svc_name); + } + + faulty_svcs = axis2_conf_get_all_faulty_svcs(dep_engine->conf, env); + axutil_hash_set(faulty_svcs, svc_name, AXIS2_HASH_KEY_STRING, NULL); + } + + } + + axutil_array_list_free(dep_engine->ws_to_undeploy, env); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_dep_engine_is_hot_update( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + return dep_engine->hot_update; +} + +static axis2_char_t * +axis2_dep_engine_get_axis_svc_name( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_char_t * file_name) +{ + axis2_char_t name_sep = '.'; + axis2_char_t *temp_name = NULL; + axis2_char_t *ptr = NULL; + axis2_char_t *file_name_l = NULL; + axis2_char_t *svc_name = NULL; + int len = 0; + + file_name_l = axutil_strdup(env, file_name); + ptr = AXIS2_STRRCHR(file_name_l, AXIS2_PATH_SEP_CHAR); + + temp_name = ptr + 1; + ptr = AXIS2_STRRCHR(temp_name, name_sep); + ptr[0] = '\0'; + len = (int)strlen(temp_name); + /* We are sure that the difference lies within the int range */ + svc_name = AXIS2_MALLOC(env->allocator, len + 1); + sscanf(temp_name, "%s", svc_name); + AXIS2_FREE(env->allocator, file_name_l); + + return svc_name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_set_phases_info( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_phases_info_t * phases_info) +{ + AXIS2_PARAM_CHECK(env->error, phases_info, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + dep_engine->phases_info = phases_info; + return AXIS2_SUCCESS; +} + +/** + * This method is used to fill a axis2 service instance using services.xml , + * first it should create an axis service instance and then fill that using + * given service.xml and load all the required class and build the chains , + * finally add the service context to engine context and axis2 service into + * Engine Configuration. + */ +AXIS2_EXTERN axis2_svc_t *AXIS2_CALL +axis2_dep_engine_build_svc( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_svc_t * svc, + axis2_char_t * file_name) +{ + axiom_node_t *node = NULL; + + AXIS2_PARAM_CHECK(env->error, file_name, NULL); + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + + dep_engine->curr_file = axis2_arch_file_data_create_with_type_and_name(env, AXIS2_SVC, ""); + + dep_engine->svc_builder = axis2_svc_builder_create_with_file_and_dep_engine_and_svc(env, + file_name, dep_engine, svc); + + node = axis2_desc_builder_build_om(axis2_svc_builder_get_desc_builder(dep_engine->svc_builder, + env), env); + + axis2_svc_builder_populate_svc(dep_engine->svc_builder, env, node); + + return svc; +} + +/** + * This function can be used to build Module Description for a given module + * archieve file. + */ +AXIS2_EXTERN axis2_module_desc_t *AXIS2_CALL +axis2_dep_engine_build_module( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axutil_file_t * module_archive, + axis2_conf_t * conf) +{ + axis2_module_desc_t *module_desc = NULL; + axis2_module_t *module = NULL; + axis2_phases_info_t *phases_info = NULL; + axis2_arch_reader_t *arch_reader = NULL; + axis2_flow_t *in_flow = NULL; + axis2_flow_t *out_flow = NULL; + axis2_flow_t *in_fault_flow = NULL; + axis2_flow_t *out_fault_flow = NULL; + axis2_char_t *file_name = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, module_archive, NULL); + AXIS2_PARAM_CHECK(env->error, conf, NULL); + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + + phases_info = axis2_conf_get_phases_info(conf, env); + axis2_dep_engine_set_phases_info(dep_engine, env, phases_info); + dep_engine->curr_file = axis2_arch_file_data_create_with_type_and_file(env, AXIS2_MODULE, + module_archive); + + module_desc = axis2_module_desc_create(env); + arch_reader = axis2_arch_reader_create(env); + file_name = axutil_file_get_name(module_archive, env); + status = axis2_arch_reader_read_module_arch(env, file_name, dep_engine, module_desc); + axis2_arch_reader_free(arch_reader, env); + if(AXIS2_SUCCESS != status) + { + axis2_module_desc_free(module_desc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Reading module archive for file %s failed", + file_name); + return NULL; + } + status = axis2_dep_engine_load_module_dll(dep_engine, env, module_desc); + if(AXIS2_SUCCESS != status) + { + axis2_module_desc_free(module_desc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Loading module dll %s failed", file_name); + return NULL; + } + + module = axis2_module_desc_get_module(module_desc, env); + + /* Module implementor will provide functions for creating his handlers and by calling this + * function these function pointers will be stored in a hash map in the module. + */ + axis2_module_fill_handler_create_func_map(module, env); + + in_flow = axis2_module_desc_get_in_flow(module_desc, env); + if(in_flow) + { + axis2_dep_engine_add_module_flow_handlers(dep_engine, env, in_flow, + module->handler_create_func_map); + } + + out_flow = axis2_module_desc_get_out_flow(module_desc, env); + if(out_flow) + { + axis2_dep_engine_add_module_flow_handlers(dep_engine, env, out_flow, + module->handler_create_func_map); + } + + in_fault_flow = axis2_module_desc_get_fault_in_flow(module_desc, env); + if(in_fault_flow) + { + axis2_dep_engine_add_module_flow_handlers(dep_engine, env, in_fault_flow, + module->handler_create_func_map); + } + + out_fault_flow = axis2_module_desc_get_fault_out_flow(module_desc, env); + if(out_fault_flow) + { + axis2_dep_engine_add_module_flow_handlers(dep_engine, env, out_fault_flow, + module->handler_create_func_map); + } + + dep_engine->curr_file = NULL; + + return module_desc; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_dep_engine_get_repos_path( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + return dep_engine->folder_name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_set_current_file_item( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_arch_file_data_t * file_data) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + if(dep_engine->curr_file) + { + axis2_arch_file_data_free(dep_engine->curr_file, env); + dep_engine->curr_file = NULL; + } + dep_engine->curr_file = file_data; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_set_arch_reader( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_arch_reader_t * arch_reader) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + if(dep_engine->arch_reader) + { + axis2_arch_reader_free(dep_engine->arch_reader, env); + dep_engine->arch_reader = NULL; + } + dep_engine->arch_reader = arch_reader; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_add_module_builder( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_module_builder_t * module_builder) +{ + AXIS2_PARAM_CHECK(env->error, module_builder, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + return axutil_array_list_add(dep_engine->module_builders, env, module_builder); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_add_svc_builder( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_svc_builder_t * svc_builder) +{ + AXIS2_PARAM_CHECK(env->error, svc_builder, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + return axutil_array_list_add(dep_engine->svc_builders, env, svc_builder); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_add_svc_grp_builder( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + axis2_svc_grp_builder_t * svc_grp_builder) +{ + AXIS2_PARAM_CHECK(env->error, svc_grp_builder, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + return axutil_array_list_add(dep_engine->svc_grp_builders, env, svc_grp_builder); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_add_desc_builder( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + struct axis2_desc_builder * desc_builder) +{ + AXIS2_PARAM_CHECK(env->error, desc_builder, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + + return axutil_array_list_add(dep_engine->desc_builders, env, desc_builder); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_dep_engine_get_module_dir( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + return axutil_strdup(env, dep_engine->module_dir); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_set_module_dir( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + const axis2_char_t *module_dir) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module_dir, AXIS2_FAILURE); + dep_engine->module_dir = axutil_strdup(env, module_dir); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_dep_engine_get_file_flag( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FALSE); + return dep_engine->file_flag; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_dep_engine_get_svc_dir( + const axis2_dep_engine_t * dep_engine, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + return axutil_strdup(env, dep_engine->svc_dir); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_dep_engine_set_svc_dir( + axis2_dep_engine_t * dep_engine, + const axutil_env_t * env, + const axis2_char_t *svc_dir) +{ + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, svc_dir, AXIS2_FAILURE); + dep_engine->svc_dir = axutil_strdup(env, svc_dir); + return AXIS2_SUCCESS; +} + +static axis2_status_t +axis2_dep_engine_set_svc_and_module_dir_path( + axis2_dep_engine_t *dep_engine, + const axutil_env_t *env) +{ + axis2_bool_t flag; + axis2_conf_t *conf; + axis2_char_t *dirpath; + axutil_param_t *dep_param; + AXIS2_PARAM_CHECK(env->error, dep_engine, AXIS2_FAILURE); + flag = dep_engine->file_flag; + if(!flag) + { + return AXIS2_SUCCESS; + } + else + { + conf = dep_engine->conf; + if(!conf) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Axis2 Configuration cannot be NULL"); + return AXIS2_FAILURE; + } + + dep_param = axis2_conf_get_param(conf, env, AXIS2_MODULE_DIR); + if(dep_param) + { + dirpath = (axis2_char_t *)axutil_param_get_value(dep_param, env); + if(dirpath) + { + dep_engine->module_dir = dirpath; + dirpath = NULL; + } + } + dep_param = NULL; + + dep_param = axis2_conf_get_param(conf, env, AXIS2_SERVICE_DIR); + if(dep_param) + { + dirpath = (axis2_char_t *)axutil_param_get_value(dep_param, env); + if(dirpath) + { + dep_engine->svc_dir = dirpath; + dirpath = NULL; + } + } + } + + return AXIS2_SUCCESS; +} + diff --git a/src/core/deployment/desc_builder.c b/src/core/deployment/desc_builder.c new file mode 100644 index 0000000..a6fde18 --- /dev/null +++ b/src/core/deployment/desc_builder.c @@ -0,0 +1,1148 @@ +/* + * 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_desc_builder.h> +#include <axutil_string.h> +#include <axutil_class_loader.h> +#include <axutil_utils.h> +#include <axutil_generic_obj.h> +#include <axis2_raw_xml_in_out_msg_recv.h> +#include <neethi_engine.h> + +struct axis2_desc_builder +{ + /** + * Store the full path to configuration file. + */ + axis2_char_t *file_name; + axiom_node_t *root; + struct axis2_dep_engine *engine; +}; + +static axis2_status_t +set_attrs_and_value( + axutil_param_t * param, + const axutil_env_t * env, + axiom_element_t * param_element, + axiom_node_t * param_node); + +AXIS2_EXTERN axis2_desc_builder_t *AXIS2_CALL +axis2_desc_builder_create( + const axutil_env_t * env) +{ + axis2_desc_builder_t *desc_builder = NULL; + + desc_builder = (axis2_desc_builder_t *)AXIS2_MALLOC(env-> allocator, + sizeof(axis2_desc_builder_t)); + + if(!desc_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot allocate memory to desc_builder"); + return NULL; + } + desc_builder->file_name = NULL; + desc_builder->engine = NULL; + desc_builder->root = NULL; + + return desc_builder; +} + +AXIS2_EXTERN axis2_desc_builder_t *AXIS2_CALL +axis2_desc_builder_create_with_file_and_dep_engine( + const axutil_env_t * env, + axis2_char_t * file_name, + axis2_dep_engine_t * engine) +{ + axis2_desc_builder_t *desc_builder = NULL; + + AXIS2_PARAM_CHECK(env->error, file_name, NULL); + AXIS2_PARAM_CHECK(env->error, engine, NULL); + + desc_builder = (axis2_desc_builder_t *)axis2_desc_builder_create(env); + if(!desc_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot allocate memory to desc_builder"); + return NULL; + } + + desc_builder->root = NULL; + + desc_builder->file_name = axutil_strdup(env, file_name); + if(!desc_builder->file_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot allocate memory to desc_builder->file_name"); + return NULL; + } + desc_builder->engine = engine; + + return desc_builder; +} + +AXIS2_EXTERN axis2_desc_builder_t *AXIS2_CALL +axis2_desc_builder_create_with_dep_engine( + const axutil_env_t * env, + struct axis2_dep_engine * engine) +{ + axis2_desc_builder_t *desc_builder = NULL; + + AXIS2_PARAM_CHECK(env->error, engine, NULL); + + desc_builder = (axis2_desc_builder_t *)axis2_desc_builder_create(env); + if(!desc_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot allocate memory to desc_builder"); + return NULL; + } + + desc_builder->engine = engine; + + return desc_builder; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_desc_builder_free( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env) +{ + if(desc_builder->file_name) + { + AXIS2_FREE(env->allocator, desc_builder->file_name); + } + + if(desc_builder->root) + { + axiom_node_free_tree(desc_builder->root, env); + } + + /* we cannot free deployment engine here */ + desc_builder->engine = NULL; + + if(desc_builder) + { + AXIS2_FREE(env->allocator, desc_builder); + } + return; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axis2_desc_builder_build_om( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env) +{ + axiom_xml_reader_t *reader = NULL; + axiom_document_t *document = NULL; + axiom_stax_builder_t *builder = NULL; + + if(!desc_builder->file_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_DESC_BUILDER, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid state desc builder. Unable to continue"); + return NULL; + } + + /** create pull parser using the file path to configuration file */ + reader = axiom_xml_reader_create_for_file(env, desc_builder->file_name, NULL); + + if(!reader) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CREATING_XML_STREAM_READER, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create xml reader for %s", + desc_builder->file_name); + return NULL; + }; + + /** create axiom_stax_builder by parsing pull_parser struct */ + builder = axiom_stax_builder_create(env, reader); + + if(!(builder)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CREATING_XML_STREAM_READER, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Could not create xml stream reader for desc builder %s. Unable " + "to continue", desc_builder->file_name); + return NULL; + } + + /** + get the om document form builder + document is the container of om model created using builder + */ + document = axiom_stax_builder_get_document(builder, env); + + /** + * In description building we don't want defferred building. So build + * the whole tree at once + */ + axiom_document_build_all(document, env); + + /** + get root element , building starts hear + */ + desc_builder->root = axiom_document_get_root_element(document, env); + /** + We have built the whole document. So no need of keeping the builder. + */ + axiom_stax_builder_free_self(builder, env); + + return desc_builder->root; +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_desc_builder_process_flow( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_element_t * flow_element, + axutil_param_container_t * parent, + axiom_node_t * flow_node) +{ + axis2_flow_t *flow = NULL; + axiom_children_qname_iterator_t *handlers = NULL; + axutil_qname_t *qchild = NULL; + + AXIS2_PARAM_CHECK(env->error, parent, NULL); + AXIS2_PARAM_CHECK(env->error, flow_node, NULL); + + flow = axis2_flow_create(env); + if(!flow) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Could not allocate to flow"); + return NULL; + } + + if(!flow_element) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "There is no flow element to process"); + return NULL; + } + + qchild = axutil_qname_create(env, AXIS2_HANDLERST, NULL, NULL); + handlers = axiom_element_get_children_with_qname(flow_element, env, qchild, flow_node); + if(qchild) + { + axutil_qname_free(qchild, env); + } + + while(axiom_children_qname_iterator_has_next(handlers, env)) + { + axiom_node_t *handler_node = NULL; + axis2_handler_desc_t *handler_desc = NULL; + axis2_status_t status = AXIS2_FAILURE; + + handler_node = (axiom_node_t *)axiom_children_qname_iterator_next(handlers, env); + + handler_desc = axis2_desc_builder_process_handler(desc_builder, env, handler_node, parent); + status = axis2_flow_add_handler(flow, env, handler_desc); + if(!status) + { + const axutil_string_t *handler_name = NULL; + const axis2_char_t *hname = NULL; + handler_name = axis2_handler_desc_get_name(handler_desc, env); + hname = axutil_string_get_buffer(handler_name, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding handler %s to flow failed", hname); + axis2_flow_free(flow, env); + return NULL; + } + } + return flow; +} + +struct axis2_handler_desc *AXIS2_CALL +axis2_desc_builder_process_handler( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_node_t * handler_node, + struct axutil_param_container *parent) +{ + axis2_handler_desc_t *handler_desc = NULL; + axiom_attribute_t *name_attrib = NULL; + axutil_qname_t *attr_qname = NULL; + axiom_attribute_t *class_attrib = NULL; + axutil_qname_t *class_qname = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *attrib_value = NULL; + axiom_element_t *handler_element = NULL; + axiom_node_t *order_node = NULL; + axiom_element_t *order_element = NULL; + axutil_qname_t *order_qname = NULL; + axutil_string_t *handler_name = NULL; + const axis2_char_t *hname = NULL; + + AXIS2_PARAM_CHECK(env->error, handler_node, NULL); + AXIS2_PARAM_CHECK(env->error, parent, NULL); + + handler_desc = axis2_handler_desc_create(env, NULL); + if(!handler_desc) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create handler description"); + return NULL; + } + /* Setting Handler name */ + attr_qname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + handler_element = axiom_node_get_data_element(handler_node, env); + name_attrib = axiom_element_get_attribute(handler_element, env, attr_qname); + if(attr_qname) + { + axutil_qname_free(attr_qname, env); + } + + if(!name_attrib) + { + axis2_handler_desc_free(handler_desc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Name attribute not fould for handler."); + return NULL; + } + else + { + axis2_char_t *value = NULL; + + value = axiom_attribute_get_value(name_attrib, env); + handler_name = axutil_string_create(env, value); + status = axis2_handler_desc_set_name(handler_desc, env, handler_name); + if(handler_name) + { + axutil_string_free(handler_name, env); + } + + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting name for handler description failed in %s", desc_builder->file_name); + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + } + hname = axutil_string_get_buffer(handler_name, env); + /*Setting Handler Class name */ + class_qname = axutil_qname_create(env, AXIS2_CLASSNAME, NULL, NULL); + class_attrib = axiom_element_get_attribute(handler_element, env, class_qname); + if(class_qname) + { + axutil_qname_free(class_qname, env); + } + + if(!class_attrib) + { + axis2_handler_desc_free(handler_desc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Library name attribute not found for handler %s", + hname); + return NULL; + } + else + { + attrib_value = axiom_attribute_get_value(class_attrib, env); + status = axis2_handler_desc_set_class_name(handler_desc, env, attrib_value); + } + + /*processing phase Rules (order) */ + + order_qname = axutil_qname_create(env, AXIS2_ORDER, NULL, NULL); + order_element = axiom_element_get_first_child_with_qname(handler_element, env, order_qname, + handler_node, &order_node); + if(order_qname) + { + axutil_qname_free(order_qname, env); + } + + if(!order_element || !order_node) + { + axis2_handler_desc_free(handler_desc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Order node not found for handler description %s", + hname); + return NULL; + } + else + { + axutil_hash_t *order_itr = NULL; + axiom_children_qname_iterator_t *params = NULL; + axutil_qname_t *param_qname = NULL; + axutil_hash_index_t *index_i = NULL; + + order_itr = axiom_element_get_all_attributes(order_element, env); + if(!order_itr) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Order element for handler desc %s does not contain any " + "attribute", hname); + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + + index_i = axutil_hash_first(order_itr, env); + + while(index_i) + { + axiom_attribute_t *order_attrib = NULL; + axutil_qname_t *qname = NULL; + axis2_char_t *name = NULL; + axis2_char_t *value = NULL; + void *v = NULL; + + axutil_hash_this(index_i, NULL, NULL, &v); + order_attrib = (axiom_attribute_t *)v; + qname = axiom_attribute_get_qname(order_attrib, env); + name = axutil_qname_get_localpart(qname, env); + + value = axiom_attribute_get_value(order_attrib, env); + if(!axutil_strcmp(AXIS2_AFTER, name)) + { + struct axis2_phase_rule *phase_rule = NULL; + + phase_rule = axis2_handler_desc_get_rules(handler_desc, env); + status = axis2_phase_rule_set_after(phase_rule, env, value); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting %s phase rule failed for handler %s", AXIS2_AFTER, hname); + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + } + if(!axutil_strcmp(AXIS2_BEFORE, name)) + { + struct axis2_phase_rule *phase_rule = NULL; + phase_rule = axis2_handler_desc_get_rules(handler_desc, env); + status = axis2_phase_rule_set_before(phase_rule, env, value); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting %s phase rule failed for handler %s", AXIS2_BEFORE, hname); + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + } + if(!axutil_strcmp(AXIS2_PHASE, name)) + { + struct axis2_phase_rule *phase_rule = NULL; + phase_rule = axis2_handler_desc_get_rules(handler_desc, env); + status = axis2_phase_rule_set_name(phase_rule, env, value); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting phase rule name failed for handler %s", hname); + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + } + if(!axutil_strcmp(AXIS2_PHASEFIRST, name)) + { + axis2_char_t *bool_val = NULL; + + bool_val = axis2_desc_builder_get_value(desc_builder, env, value); + if(!axutil_strcmp(bool_val, AXIS2_VALUE_TRUE)) + { + struct axis2_phase_rule *phase_rule = NULL; + phase_rule = axis2_handler_desc_get_rules(handler_desc, env); + status = axis2_phase_rule_set_first(phase_rule, env, AXIS2_TRUE); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting %s property for phase rules for handler " + "%s failed", AXIS2_PHASEFIRST, hname); + axis2_handler_desc_free(handler_desc, env); + AXIS2_FREE(env->allocator, bool_val); + return NULL; + } + } + else if(!axutil_strcmp(bool_val, AXIS2_VALUE_FALSE)) + { + struct axis2_phase_rule *phase_rule = NULL; + phase_rule = axis2_handler_desc_get_rules(handler_desc, env); + status = axis2_phase_rule_set_first(phase_rule, env, AXIS2_FALSE); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting %s property for phase rules for handler " + "%s failed", AXIS2_PHASEFIRST, hname); + axis2_handler_desc_free(handler_desc, env); + AXIS2_FREE(env->allocator, bool_val); + return NULL; + } + } + AXIS2_FREE(env->allocator, bool_val); + } + index_i = axutil_hash_next(env, index_i); + } + + param_qname = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + params = axiom_element_get_children_with_qname(handler_element, env, param_qname, + handler_node); + axutil_qname_free(param_qname, env); + status = axis2_desc_builder_process_params(desc_builder, env, params, + axis2_handler_desc_get_param_container(handler_desc, env), parent); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Processing params failed for handler %s", + hname); + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + } + + status = axis2_handler_desc_set_parent(handler_desc, env, parent); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting parent failed for handler %s", hname); + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + + return handler_desc; +} + +static axis2_status_t +set_attrs_and_value( + axutil_param_t * param, + const axutil_env_t * env, + axiom_element_t * param_element, + axiom_node_t * param_node) +{ + axis2_status_t status = AXIS2_FAILURE; + axutil_hash_t *attrs = NULL; + axiom_child_element_iterator_t *childs = NULL; + + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, param_element, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, param_node, AXIS2_FAILURE); + + /* Setting attributes */ + attrs = axiom_element_extract_attributes(param_element, env, param_node); + if(attrs) + { + axutil_hash_index_t *i = NULL; + + for(i = axutil_hash_first(attrs, env); i; i = axutil_hash_next(env, i)) + { + void *v = NULL; + axiom_attribute_t *value = NULL; + axutil_generic_obj_t *obj = NULL; + axutil_qname_t *attr_qname = NULL; + axis2_char_t *attr_name = NULL; + + axutil_hash_this(i, NULL, NULL, &v); + if(!v) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Attibute missing in the parameter element"); + axutil_param_free(param, env); + return AXIS2_FAILURE; + } + obj = axutil_generic_obj_create(env); + if(!obj) + { + axutil_param_free(param, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + value = (axiom_attribute_t *)v; + axutil_generic_obj_set_value(obj, env, value); + axutil_generic_obj_set_free_func(obj, env, axiom_attribute_free_void_arg); + attr_qname = axiom_attribute_get_qname(value, env); + attr_name = axutil_qname_to_string(attr_qname, env); + axutil_hash_set(attrs, attr_name, AXIS2_HASH_KEY_STRING, obj); + } + axutil_param_set_attributes(param, env, attrs); + } + + childs = axiom_element_get_child_elements(param_element, env, param_node); + if(childs) + { + axutil_array_list_t *value_list = NULL; + + value_list = axutil_array_list_create(env, 0); + axutil_param_set_value_list(param, env, value_list); + + while(AXIOM_CHILD_ELEMENT_ITERATOR_HAS_NEXT(childs, env)) + { + axiom_node_t *node = NULL; + axiom_element_t *element = NULL; + axutil_param_t *param = NULL; + axis2_char_t *pname = NULL; + + node = AXIOM_CHILD_ELEMENT_ITERATOR_NEXT(childs, env); + element = axiom_node_get_data_element(node, env); + param = axutil_param_create(env, NULL, NULL); + pname = axiom_element_get_localname(element, env); + status = axutil_param_set_name(param, env, pname); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting name to parameter failed"); + axutil_param_free(param, env); + return status; + } + axutil_param_set_param_type(param, env, AXIS2_DOM_PARAM); + set_attrs_and_value(param, env, element, node); + axutil_array_list_add(value_list, env, param); + } + } + else + { + axis2_char_t *para_test_value = NULL; + axis2_char_t *temp = NULL; + + temp = axiom_element_get_text(param_element, env, param_node); + para_test_value = axutil_strdup(env, temp); + status = axutil_param_set_value(param, env, para_test_value); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting value to parameter failed"); + axutil_param_free(param, env); + AXIS2_FREE(env->allocator, para_test_value); + return status; + } + axutil_param_set_param_type(param, env, AXIS2_TEXT_PARAM); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_builder_process_rest_params( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_node_t * op_node, + axis2_op_t * op_desc) +{ + axiom_element_t *op_element = NULL; + axutil_qname_t *qname = NULL; + axutil_qname_t *param_qname = NULL; + axiom_node_t *rest_node = NULL; + axiom_element_t *rest_element = NULL; + axiom_children_qname_iterator_t *rest_mappings = NULL; + + AXIS2_PARAM_CHECK(env->error, op_desc, AXIS2_FAILURE); + + op_element = axiom_node_get_data_element(op_node, env); + + param_qname = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + qname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + + if(op_element) + { + rest_mappings + = axiom_element_get_children_with_qname(op_element, env, param_qname, op_node); + } + + while(rest_mappings && axiom_children_qname_iterator_has_next(rest_mappings, env)) + { + axis2_char_t *param_value = NULL; + rest_node = (axiom_node_t *)axiom_children_qname_iterator_next(rest_mappings, env); + rest_element = axiom_node_get_data_element(rest_node, env); + param_value = axiom_element_get_attribute_value(rest_element, env, qname); + if(!strcmp(param_value, AXIS2_REST_HTTP_METHOD)) + { + axis2_op_set_rest_http_method(op_desc, env, axiom_element_get_text(rest_element, env, + rest_node)); + } + param_value = axiom_element_get_attribute_value(rest_element, env, qname); + if(!strcmp(param_value, AXIS2_REST_HTTP_LOCATION)) + { + axis2_op_set_rest_http_location(op_desc, env, axiom_element_get_text(rest_element, env, + rest_node)); + } + if(axis2_op_get_rest_http_method(op_desc, env) && axis2_op_get_rest_http_location(op_desc, + env)) + { + break; + } + } + + axutil_qname_free(qname, env); + axutil_qname_free(param_qname, env); + return AXIS2_SUCCESS; +} + +/** + * Populate the Axis2 Operation with details from the actionMapping, + * outputActionMapping and faultActionMapping elements from the operation + * element. + * + * @param operation + * @param op_desc + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_builder_process_action_mappings( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_node_t * op_node, + axis2_op_t * op_desc) +{ + axiom_element_t *op_element = NULL; + axutil_qname_t *qname = NULL; + axiom_children_qname_iterator_t *action_mappings = NULL; + axutil_array_list_t *mapping_list = axutil_array_list_create(env, 0); + AXIS2_PARAM_CHECK(env->error, op_desc, AXIS2_FAILURE); + + op_element = axiom_node_get_data_element(op_node, env); + qname = axutil_qname_create(env, AXIS2_ACTION_MAPPING, NULL, NULL); + if(op_element) + { + action_mappings = axiom_element_get_children_with_qname(op_element, env, qname, op_node); + } + + axutil_qname_free(qname, env); + qname = NULL; + if(!action_mappings) + { + if(mapping_list) + { + axutil_array_list_free(mapping_list, env); + mapping_list = NULL; + } + return AXIS2_SUCCESS; + } + while(axiom_children_qname_iterator_has_next(action_mappings, env)) + { + axiom_element_t *mapping_element = NULL; + axiom_node_t *mapping_node = NULL; + axis2_char_t *input_action_string = NULL; + axis2_char_t *temp_str = NULL; + + /* This is to check whether some one has locked the parmter at the top + * level + */ + mapping_node = (axiom_node_t *)axiom_children_qname_iterator_next(action_mappings, env); + mapping_element = axiom_node_get_data_element(mapping_node, env); + temp_str = axiom_element_get_text(mapping_element, env, mapping_node); + input_action_string = axutil_strtrim(env, temp_str, NULL); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Input action mapping found %s", + input_action_string); + if(axutil_strcmp("", input_action_string)) + { + axutil_array_list_add(mapping_list, env, input_action_string); + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Zero length " + "input_action_string found. Not added to the mapping list"); + } + } + axis2_op_set_wsamapping_list(op_desc, env, mapping_list); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_builder_process_params( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * params, + axutil_param_container_t * param_container, + axutil_param_container_t * parent) +{ + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, params, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, param_container, AXIS2_FAILURE); + + while(axiom_children_qname_iterator_has_next(params, env)) + { + axiom_element_t *param_element = NULL; + axiom_node_t *param_node = NULL; + axutil_param_t *param = NULL; + axutil_param_t *parent_para = NULL; + axiom_attribute_t *para_name = NULL; + axiom_attribute_t *para_locked = NULL; + axutil_qname_t *att_locked = NULL; + axutil_qname_t *att_qname = NULL; + axis2_char_t *pname = NULL; + + /* This is to check whether some one has locked the parmter at the top + * level + */ + param_node = (axiom_node_t *)axiom_children_qname_iterator_next(params, env); + param_element = axiom_node_get_data_element(param_node, env); + param = axutil_param_create(env, NULL, NULL); + + /* Setting paramter name */ + att_qname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + para_name = axiom_element_get_attribute(param_element, env, att_qname); + axutil_qname_free(att_qname, env); + if(!para_name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Parameter name attribute not found for parameter"); + axutil_param_free(param, env); + return AXIS2_FAILURE; + } + pname = axiom_attribute_get_value(para_name, env); + status = axutil_param_set_name(param, env, pname); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not set parameter name for parameter"); + axutil_param_free(param, env); + return status; + } + + /* Setting paramter Value (the chiled elemnt of the paramter) */ + set_attrs_and_value(param, env, param_element, param_node); + + /* Setting locking attrib */ + att_locked = axutil_qname_create(env, AXIS2_ATTLOCKED, NULL, NULL); + para_locked = axiom_element_get_attribute(param_element, env, att_locked); + axutil_qname_free(att_locked, env); + if(parent) + { + axis2_char_t *param_name = NULL; + + param_name = axutil_param_get_name(param, env); + parent_para = axutil_param_container_get_param(parent, env, param_name); + } + if(para_locked) + { + axis2_char_t *locked_value = NULL; + locked_value = axiom_attribute_get_value(para_locked, env); + if(!axutil_strcmp(AXIS2_VALUE_TRUE, locked_value)) + { + axis2_char_t *param_name = NULL; + axis2_bool_t is_param_locked = AXIS2_FALSE; + /*if the parameter is locked at some level parameter value replace + * by that + */ + param_name = axutil_param_get_name(param, env); + is_param_locked = axutil_param_container_is_param_locked(parent, env, param_name); + if(parent && is_param_locked) + { + axutil_param_free(param, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CONFIG_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Parameter %s is locked", param_name); + return AXIS2_FAILURE; + } + else + { + axutil_param_set_locked(param, env, AXIS2_TRUE); + } + } + else + { + axutil_param_set_locked(param, env, AXIS2_FALSE); + } + } + + if(parent) + { + axis2_char_t *name = NULL; + axis2_bool_t bvalue = AXIS2_FALSE; + + name = axutil_param_get_name(param, env); + bvalue = axutil_param_container_is_param_locked(parent, env, name); + if(parent_para || !bvalue) + { + status = axutil_param_container_add_param(param_container, env, param); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding parameter %s failed", name); + axutil_param_free(param, env); + return status; + } + } + } + else + { + status = axutil_param_container_add_param(param_container, env, param); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding parameter %s failed", pname); + axutil_param_free(param, env); + return status; + } + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_builder_process_op_module_refs( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_refs, + axis2_op_t * op) +{ + axiom_element_t *moduleref = NULL; + axiom_attribute_t *module_ref_attrib = NULL; + axutil_qname_t *qref = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, op, AXIS2_FAILURE); + + while(module_refs && axiom_children_qname_iterator_has_next(module_refs, env)) + { + axiom_node_t *moduleref_node = axiom_children_qname_iterator_next(module_refs, env); + moduleref = (axiom_element_t *)axiom_node_get_data_element(moduleref_node, env); + + qref = axutil_qname_create(env, AXIS2_REF, NULL, NULL); + module_ref_attrib = axiom_element_get_attribute(moduleref, env, qref); + axutil_qname_free(qref, env); + if(module_ref_attrib) + { + axis2_char_t *ref_name = NULL; + axutil_qname_t *ref_qname = NULL; + axis2_module_desc_t *module_desc = NULL; + + ref_name = axiom_attribute_get_value(module_ref_attrib, env); + ref_qname = axutil_qname_create(env, ref_name, NULL, NULL); + module_desc = axis2_dep_engine_get_module(desc_builder->engine, env, ref_qname); + if(!module_desc) + { + axutil_qname_free(ref_qname, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Module %s not found in the deployment engine", ref_name); + + return AXIS2_FAILURE; + } + else + { + status = axis2_op_add_module_qname(op, env, ref_qname); + axutil_qname_free(ref_qname, env); + if(AXIS2_SUCCESS != status) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding module ref %s to operation %s failed", ref_name, + axutil_qname_get_localpart(axis2_op_get_qname(op, env), env)); + + return AXIS2_FAILURE; + } + } + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_recv_t *AXIS2_CALL +axis2_desc_builder_load_msg_recv( + axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + struct axiom_element * recv_element) +{ + axiom_attribute_t *recv_name = NULL; + axis2_char_t *class_name = NULL; + axis2_msg_recv_t *msg_recv = NULL; + axutil_qname_t *class_qname = NULL; + axutil_param_t *impl_info_param = NULL; + axutil_dll_desc_t *dll_desc = NULL; + axis2_char_t *repos_name = NULL; + axis2_char_t *dll_name = NULL; + axis2_char_t *temp_path = NULL; + axis2_char_t *temp_path2 = NULL; + axis2_char_t *temp_path3 = NULL; + axis2_conf_t *conf = NULL; + axis2_char_t *msg_recv_dll_name = NULL; + + AXIS2_PARAM_CHECK(env->error, recv_element, NULL); + + class_qname = axutil_qname_create(env, AXIS2_CLASSNAME, NULL, NULL); + recv_name = axiom_element_get_attribute(recv_element, env, class_qname); + axutil_qname_free(class_qname, env); + class_name = axiom_attribute_get_value(recv_name, env); + + conf = axis2_dep_engine_get_axis_conf(desc_builder->engine, env); + if(!conf) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Configuration not found in the deployment engine"); + return NULL; + } + impl_info_param = axis2_conf_get_param(conf, env, class_name); + + if(!impl_info_param) + { + dll_desc = axutil_dll_desc_create(env); + msg_recv_dll_name = axutil_dll_desc_create_platform_specific_dll_name(dll_desc, env, + class_name); + repos_name = axis2_dep_engine_get_repos_path(desc_builder->engine, env); + temp_path = axutil_stracat(env, repos_name, AXIS2_PATH_SEP_STR); + temp_path2 = axutil_stracat(env, temp_path, AXIS2_LIB_FOLDER); + temp_path3 = axutil_stracat(env, temp_path2, AXIS2_PATH_SEP_STR); + dll_name = axutil_stracat(env, temp_path3, msg_recv_dll_name); + AXIS2_FREE(env->allocator, temp_path); + AXIS2_FREE(env->allocator, temp_path2); + AXIS2_FREE(env->allocator, temp_path3); + axutil_dll_desc_set_name(dll_desc, env, dll_name); + AXIS2_FREE(env->allocator, dll_name); + axutil_dll_desc_set_type(dll_desc, env, AXIS2_MSG_RECV_DLL); + impl_info_param = axutil_param_create(env, class_name, NULL); + axutil_param_set_value(impl_info_param, env, dll_desc); + axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg); + /* set the impl_info_param(which contain dll_desc as value) so that + * loaded msg_recv loader lib can be re-used in future + */ + axis2_conf_add_param(conf, env, impl_info_param); + } + + axutil_class_loader_init(env); + msg_recv = (axis2_msg_recv_t *)axutil_class_loader_create_dll(env, impl_info_param); + return msg_recv; +} + +AXIS2_EXTERN struct axis2_msg_recv *AXIS2_CALL +axis2_desc_builder_load_default_msg_recv( + const axutil_env_t * env) +{ + axis2_msg_recv_t *msg_recv = NULL; + + msg_recv = axis2_raw_xml_in_out_msg_recv_create(env); + return msg_recv; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_desc_builder_get_short_file_name( + const axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axis2_char_t * file_name) +{ + const axis2_char_t *separator = NULL; + axis2_char_t *value = NULL; + axis2_char_t *file_name_l = NULL; + axis2_char_t *short_name = NULL; + + AXIS2_PARAM_CHECK(env->error, file_name, NULL); + + file_name_l = axutil_strdup(env, file_name); + if(!file_name_l) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + return NULL; + } + separator = "."; + + value = axutil_strstr(file_name_l, separator); + + value[0] = AXIS2_EOLN; + short_name = file_name_l; + + return short_name; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_desc_builder_get_file_name_without_prefix( + const axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axis2_char_t * short_file_name) +{ + axis2_char_t *file_name_l = NULL; + axis2_char_t *short_name = NULL; + int len = 0; + AXIS2_PARAM_CHECK(env->error, short_file_name, NULL); + file_name_l = axutil_strdup(env, short_file_name); + if(!file_name_l) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + return NULL; + } + len = axutil_strlen(AXIS2_LIB_PREFIX); + short_name = &file_name_l[len]; + return short_name; + +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_desc_builder_get_value( + const axis2_desc_builder_t * desc_builder, + const axutil_env_t * env, + axis2_char_t * in) +{ + const axis2_char_t *separator = ":"; + axis2_char_t *value = NULL; + axis2_char_t *in_l = NULL; + + AXIS2_PARAM_CHECK(env->error, in, NULL); + + in_l = axutil_strdup(env, in); + if(!in_l) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + return NULL; + } + value = axutil_strstr(in_l, separator); + value = value + 1; + + return value; +} + +AXIS2_EXTERN struct axis2_dep_engine *AXIS2_CALL +axis2_desc_builder_get_dep_engine( + const axis2_desc_builder_t * desc_builder, + const axutil_env_t * env) +{ + return desc_builder->engine; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_process_policy_elements( + const axutil_env_t * env, + int type, + axiom_children_qname_iterator_t * iterator, + axis2_policy_include_t * policy_include) +{ + while(axiom_children_qname_iterator_has_next(iterator, env)) + { + axiom_node_t *node = NULL; + node = axiom_children_qname_iterator_next(iterator, env); + if(node) + { + axiom_element_t *element = NULL; + neethi_policy_t *policy = NULL; + + element = axiom_node_get_data_element(node, env); + policy = neethi_engine_get_policy(env, node, element); + if(!policy) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + return AXIS2_FAILURE; + } + axis2_policy_include_add_policy_element(policy_include, env, type, policy); + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_process_policy_reference_elements( + const axutil_env_t * env, + int type, + axiom_children_qname_iterator_t * iterator, + axis2_policy_include_t * policy_include) +{ + while(axiom_children_qname_iterator_has_next(iterator, env)) + { + axiom_node_t *node = NULL; + node = axiom_children_qname_iterator_next(iterator, env); + if(node) + { + axiom_element_t *element = NULL; + neethi_reference_t *reference = NULL; + + element = axiom_node_get_data_element(node, env); + /* TODO: add neethi_engine_get_policy_reference + reference = neethi_engine_get_policy_reference(env, node, element); */ + axis2_policy_include_add_policy_reference_element(policy_include, env, type, reference); + } + } + return AXIS2_SUCCESS; +} + diff --git a/src/core/deployment/module_builder.c b/src/core/deployment/module_builder.c new file mode 100644 index 0000000..ad91866 --- /dev/null +++ b/src/core/deployment/module_builder.c @@ -0,0 +1,514 @@ +/* + * 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_module_builder.h> +#include <axis2_arch_file_data.h> + +struct axis2_module_builder +{ + axis2_module_desc_t *module_desc; + struct axis2_desc_builder *desc_builder; +}; + +static axutil_array_list_t *AXIS2_CALL axis2_module_builder_process_ops( + axis2_module_builder_t * module_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * op_itr); + +AXIS2_EXTERN axis2_module_builder_t *AXIS2_CALL +axis2_module_builder_create( + const axutil_env_t * env) +{ + axis2_module_builder_t *module_builder = NULL; + + module_builder = (axis2_module_builder_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_module_builder_t)); + + if(!module_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory to create module builder"); + return NULL; + } + + return module_builder; +} + +AXIS2_EXTERN axis2_module_builder_t *AXIS2_CALL +axis2_module_builder_create_with_file_and_dep_engine_and_module( + const axutil_env_t * env, + axis2_char_t * file_name, + axis2_dep_engine_t * dep_engine, + axis2_module_desc_t * module_desc) +{ + axis2_module_builder_t *module_builder = NULL; + + module_builder = (axis2_module_builder_t *)axis2_module_builder_create(env); + if(!module_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory to create module builder %s", file_name); + return NULL; + } + module_builder->desc_builder = axis2_desc_builder_create_with_file_and_dep_engine(env, + file_name, dep_engine); + if(!module_builder->desc_builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Description builder creation failed for module builder %s", file_name); + axis2_module_builder_free(module_builder, env); + return NULL; + } + module_builder->module_desc = module_desc; + return module_builder; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_module_builder_free( + axis2_module_builder_t * module_builder, + const axutil_env_t * env) +{ + if(module_builder->desc_builder) + { + axis2_desc_builder_free(module_builder->desc_builder, env); + } + + if(module_builder) + { + AXIS2_FREE(env->allocator, module_builder); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_builder_populate_module( + axis2_module_builder_t * module_builder, + const axutil_env_t * env) +{ + axiom_element_t *module_element = NULL; + axiom_node_t *module_node = NULL; + axutil_qname_t *qdllname = NULL; + axutil_qname_t *qparamst = NULL; + axutil_qname_t *qinflowst = NULL; + axutil_qname_t *qoutflowst = NULL; + axutil_qname_t *qinfaultflow = NULL; + axutil_qname_t *qoutfaultflow = NULL; + axutil_qname_t *qopst = NULL; + axiom_attribute_t *module_dll_att = NULL; + axiom_children_qname_iterator_t *itr = NULL; + axiom_children_qname_iterator_t *op_itr = NULL; + axiom_element_t *in_flow_element = NULL; + axiom_node_t *in_flow_node = NULL; + axiom_element_t *out_flow_element = NULL; + axiom_node_t *out_flow_node = NULL; + axiom_element_t *in_fault_flow_element = NULL; + axiom_node_t *in_fault_flow_node = NULL; + axiom_element_t *out_fault_flow_element = NULL; + axiom_node_t *out_fault_flow_node = NULL; + axis2_conf_t *parent = NULL; + axutil_array_list_t *ops = NULL; + axutil_param_container_t *parent_container = NULL; + int size = 0; + int i = 0; + axis2_arch_file_data_t *file_data = NULL; + axis2_char_t *module_name = NULL; + axutil_qname_t *module_qname = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_module_builder_populate_module"); + + module_node = axis2_desc_builder_build_om(module_builder->desc_builder, env); + module_element = axiom_node_get_data_element(module_node, env); + if(!module_element) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Data element not found for the module node, Unable to proceed"); + return AXIS2_FAILURE; + } + file_data = axis2_dep_engine_get_current_file_item(axis2_desc_builder_get_dep_engine( + module_builder->desc_builder, env), env); + module_name = axis2_arch_file_data_get_module_name(file_data, env); + + module_qname = axutil_qname_create(env, module_name, NULL, NULL); + axis2_module_desc_set_qname(module_builder->module_desc, env, module_qname); + + if(module_qname) + { + axutil_qname_free(module_qname, env); + } + /* Setting Module Dll Name , if it is there */ + + qdllname = axutil_qname_create(env, AXIS2_CLASSNAME, NULL, NULL); + module_dll_att = axiom_element_get_attribute(module_element, env, qdllname); + if(qdllname) + { + axutil_qname_free(qdllname, env); + } + + if(module_dll_att) + { + axis2_char_t *class_name = NULL; + + class_name = axiom_attribute_get_value(module_dll_att, env); + if(class_name && (axutil_strcmp("", class_name))) + { + axis2_dep_engine_t *dep_engine = axis2_desc_builder_get_dep_engine( + module_builder->desc_builder, env); + if(dep_engine) + { + axis2_arch_file_data_t *file_data = NULL; + + file_data = axis2_dep_engine_get_current_file_item(dep_engine, env); + axis2_arch_file_data_set_module_dll_name(file_data, env, class_name); + } + } + } + + /* Processing Paramters */ + /* Processing service level paramters */ + + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + itr = axiom_element_get_children_with_qname(module_element, env, qparamst, module_node); + if(qparamst) + { + axutil_qname_free(qparamst, env); + } + parent = axis2_module_desc_get_parent(module_builder->module_desc, env); + + if(parent) + { + parent_container = axis2_conf_get_param_container(parent, env); + } + axis2_desc_builder_process_params(module_builder->desc_builder, env, itr, + axis2_module_desc_get_param_container(module_builder->module_desc, env), parent_container); + + /* Process IN_FLOW */ + qinflowst = axutil_qname_create(env, AXIS2_IN_FLOW_START, NULL, NULL); + in_flow_element = axiom_element_get_first_child_with_qname(module_element, env, qinflowst, + module_node, &in_flow_node); + if(qinflowst) + { + axutil_qname_free(qinflowst, env); + } + + if(in_flow_element && in_flow_node) + { + axis2_flow_t *flow = NULL; + + flow = axis2_desc_builder_process_flow(module_builder->desc_builder, env, in_flow_element, + axis2_module_desc_get_param_container(module_builder->module_desc, env), in_flow_node); + status = axis2_module_desc_set_in_flow(module_builder->module_desc, env, flow); + + if(!status) + { + if(flow) + { + axis2_flow_free(flow, env); + } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting in flow failed for module desc %s", + module_name); + return status; + } + } + + qoutflowst = axutil_qname_create(env, AXIS2_OUT_FLOW_START, NULL, NULL); + out_flow_element = axiom_element_get_first_child_with_qname(module_element, env, qoutflowst, + module_node, &out_flow_node); + if(qoutflowst) + { + axutil_qname_free(qoutflowst, env); + } + + if(out_flow_element && out_flow_node) + { + axis2_flow_t *flow = NULL; + + flow = axis2_desc_builder_process_flow(module_builder->desc_builder, env, out_flow_element, + axis2_module_desc_get_param_container(module_builder->module_desc, env), out_flow_node); + status = axis2_module_desc_set_out_flow(module_builder->module_desc, env, flow); + + if(!status) + { + axis2_flow_free(flow, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting out flow failed for module desc %s", + module_name); + return status; + } + } + + qinfaultflow = axutil_qname_create(env, AXIS2_IN_FAILTFLOW, NULL, NULL); + in_fault_flow_element = axiom_element_get_first_child_with_qname(module_element, env, + qinfaultflow, module_node, &in_fault_flow_node); + if(qinfaultflow) + { + axutil_qname_free(qinfaultflow, env); + } + + if(in_fault_flow_element && NULL != in_fault_flow_node) + { + axis2_flow_t *flow = NULL; + + flow = axis2_desc_builder_process_flow(module_builder->desc_builder, env, + in_fault_flow_element, axis2_module_desc_get_param_container( + module_builder->module_desc, env), in_fault_flow_node); + status = axis2_module_desc_set_fault_in_flow(module_builder->module_desc, env, flow); + + if(!status) + { + axis2_flow_free(flow, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting fault in flow failed for module desc %s", module_name); + return status; + } + } + + qoutfaultflow = axutil_qname_create(env, AXIS2_OUT_FAILTFLOW, NULL, NULL); + out_fault_flow_element = axiom_element_get_first_child_with_qname(module_element, env, + qoutfaultflow, module_node, &out_fault_flow_node); + if(qoutfaultflow) + { + axutil_qname_free(qoutfaultflow, env); + } + + if(out_fault_flow_element && NULL != out_fault_flow_node) + { + axis2_flow_t *flow = NULL; + + flow = axis2_desc_builder_process_flow(module_builder->desc_builder, env, + out_fault_flow_element, axis2_module_desc_get_param_container( + module_builder->module_desc, env), out_fault_flow_node); + status = axis2_module_desc_set_fault_out_flow(module_builder->module_desc, env, flow); + if(AXIS2_SUCCESS != status) + { + axis2_flow_free(flow, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting fault out flow failed for module desc %s", module_name); + return status; + } + } + + /* Processing Operations */ + qopst = axutil_qname_create(env, AXIS2_OPERATIONST, NULL, NULL); + op_itr = axiom_element_get_children_with_qname(module_element, env, qopst, module_node); + if(qopst) + { + axutil_qname_free(qopst, env); + } + ops = axis2_module_builder_process_ops(module_builder, env, op_itr); + size = axutil_array_list_size(ops, env); + for(i = 0; i < size; i++) + { + axis2_op_t *op_desc = NULL; + + op_desc = (axis2_op_t *)axutil_array_list_get(ops, env, i); + axis2_module_desc_add_op(module_builder->module_desc, env, op_desc); + } + axutil_array_list_free(ops, env); + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_module_builder_populate_module"); + return AXIS2_SUCCESS; +} + +static axutil_array_list_t *AXIS2_CALL +axis2_module_builder_process_ops( + axis2_module_builder_t * module_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * op_itr) +{ + axutil_array_list_t *ops = NULL; + + AXIS2_PARAM_CHECK(env->error, op_itr, NULL); + + ops = axutil_array_list_create(env, 0); + while(axiom_children_qname_iterator_has_next(op_itr, env)) + { + axiom_element_t *op_element = NULL; + axiom_node_t *op_node = NULL; + axiom_attribute_t *op_name_att = NULL; + axiom_attribute_t *op_mep_att = NULL; + axutil_qname_t *qattname = NULL; + axis2_char_t *mep_url = NULL; + axis2_char_t *op_name = NULL; + axutil_qname_t *qopname = NULL; + axutil_qname_t *qmsgrecv = NULL; + axutil_qname_t *qparamst = NULL; + axutil_qname_t *qmodulest = NULL; + axutil_qname_t *qmep = NULL; + axiom_children_qname_iterator_t *params = NULL; + axiom_children_qname_iterator_t *modules = NULL; + axiom_element_t *recv_element = NULL; + axiom_node_t *recv_node = NULL; + axis2_phases_info_t *info = NULL; + axis2_op_t *op_desc = NULL; + axutil_qname_t *qpolicy = NULL; + axiom_children_qname_iterator_t *itr = NULL; + axis2_desc_t *desc = NULL; + axis2_policy_include_t *policy_include = NULL; + + op_node = (axiom_node_t *)axiom_children_qname_iterator_next(op_itr, env); + op_element = axiom_node_get_data_element(op_node, env); + /* getting operation name */ + qattname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + op_name_att = axiom_element_get_attribute(op_element, env, qattname); + if(qattname) + { + axutil_qname_free(qattname, env); + } + + if(!op_name_att) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_OP_NAME_MISSING, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Operation name missing for module operation."); + return NULL; + } + qmep = axutil_qname_create(env, AXIS2_MEP, NULL, NULL); + op_mep_att = axiom_element_get_attribute(op_element, env, qmep); + if(qmep) + { + axutil_qname_free(qmep, env); + } + + if(op_mep_att) + { + mep_url = axiom_attribute_get_value(op_mep_att, env); + } + if(!mep_url) + { + /* Assuming in-out mep */ + op_desc = axis2_op_create_from_module(env); + } + else + { + op_desc = axis2_op_create_from_module(env); + axis2_op_set_msg_exchange_pattern(op_desc, env, mep_url); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "mep_url:%s", mep_url); + } + + op_name = axiom_attribute_get_value(op_name_att, env); + qopname = axutil_qname_create(env, op_name, NULL, NULL); + axis2_op_set_qname(op_desc, env, qopname); + if(qopname) + { + axutil_qname_free(qopname, env); + } + + /* Operation parameters */ + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + params = axiom_element_get_children_with_qname(op_element, env, qparamst, op_node); + if(qparamst) + { + axutil_qname_free(qparamst, env); + } + + axis2_desc_builder_process_params(module_builder->desc_builder, env, params, + axis2_op_get_param_container(op_desc, env), axis2_module_desc_get_param_container( + module_builder->module_desc, env)); + /* To process wsamapping */ + axis2_desc_builder_process_action_mappings(module_builder->desc_builder, env, op_node, + op_desc); + + /* To process REST params */ + axis2_desc_builder_process_rest_params(module_builder->desc_builder, env, op_node, op_desc); + + /* setting the policy_include */ + + desc = axis2_op_get_base(op_desc, env); + policy_include = axis2_desc_get_policy_include(desc, env); + + /* processing <wsp:Policy> .. </..> elements */ + + qpolicy = axutil_qname_create(env, NEETHI_POLICY, NEETHI_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qpolicy, op_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + + if((!itr) || (!axiom_children_qname_iterator_has_next(itr, env))) + { + qpolicy = axutil_qname_create(env, NEETHI_POLICY, NEETHI_POLICY_15_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qpolicy, op_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + } + if(itr) + { + axis2_process_policy_elements(env, AXIS2_MODULE_OPERATION_POLICY, itr, policy_include); + } + + /* processing <wsp:PolicyReference> .. </..> elements */ + qpolicy = axutil_qname_create(env, NEETHI_REFERENCE, NEETHI_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qpolicy, op_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + + if((!itr) || (!axiom_children_qname_iterator_has_next(itr, env))) + { + qpolicy = axutil_qname_create(env, NEETHI_REFERENCE, NEETHI_POLICY_15_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qpolicy, op_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + } + + if(itr) + { + axis2_process_policy_reference_elements(env, AXIS2_POLICY_REF, itr, policy_include); + } + + /* setting the mep of the operation */ + + /* loading the message receivers */ + qmsgrecv = axutil_qname_create(env, AXIS2_MESSAGERECEIVER, NULL, NULL); + recv_element = axiom_element_get_first_child_with_qname(op_element, env, qmsgrecv, op_node, + &recv_node); + if(qmsgrecv) + { + axutil_qname_free(qmsgrecv, env); + } + if(recv_element && NULL != recv_node) + { + axis2_msg_recv_t *msg_recv = NULL; + + msg_recv = axis2_desc_builder_load_msg_recv(module_builder-> desc_builder, env, + recv_element); + axis2_op_set_msg_recv(op_desc, env, msg_recv); + } + else + { + axis2_msg_recv_t *msg_recv = NULL; + /* setting default message reciver */ + msg_recv = axis2_desc_builder_load_default_msg_recv(env); + axis2_op_set_msg_recv(op_desc, env, msg_recv); + } + /* Process Module Refs */ + qmodulest = axutil_qname_create(env, AXIS2_MODULEST, NULL, NULL); + modules = axiom_element_get_children_with_qname(op_element, env, qmodulest, op_node); + if(qmodulest) + { + axutil_qname_free(qmodulest, env); + } + axis2_desc_builder_process_op_module_refs(module_builder->desc_builder, env, modules, + op_desc); + /* setting Operation phase */ + info = axis2_dep_engine_get_phases_info(axis2_desc_builder_get_dep_engine( + module_builder->desc_builder, env), env); + axis2_phases_info_set_op_phases(info, env, op_desc); + + /* adding operation */ + axutil_array_list_add(ops, env, op_desc); + } + return ops; +} + diff --git a/src/core/deployment/phases_info.c b/src/core/deployment/phases_info.c new file mode 100644 index 0000000..075fc8e --- /dev/null +++ b/src/core/deployment/phases_info.c @@ -0,0 +1,564 @@ +/* + * 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_phases_info.h> + +struct axis2_phases_info +{ + axutil_array_list_t *in_phases; + axutil_array_list_t *out_phases; + axutil_array_list_t *in_faultphases; + axutil_array_list_t *out_faultphases; + axutil_hash_t *op_in_phases; + axutil_hash_t *op_out_phases; + axutil_hash_t *op_in_faultphases; + axutil_hash_t *op_out_faultphases; + +}; + +AXIS2_EXTERN axis2_phases_info_t *AXIS2_CALL +axis2_phases_info_create( + const axutil_env_t * env) +{ + axis2_phases_info_t *phases_info = NULL; + + phases_info = (axis2_phases_info_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_phases_info_t)); + + if(!phases_info) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)phases_info, 0, sizeof(axis2_phases_info_t)); + phases_info->op_in_phases = axutil_hash_make(env); + phases_info->op_out_phases = axutil_hash_make(env); + phases_info->op_in_faultphases = axutil_hash_make(env); + phases_info->op_out_faultphases = axutil_hash_make(env); + + return phases_info; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_phases_info_free( + axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + if(phases_info->in_phases) + { + axutil_array_list_free(phases_info->in_phases, env); + } + + if(phases_info->out_phases) + { + axutil_array_list_free(phases_info->out_phases, env); + } + + if(phases_info->in_faultphases) + { + axutil_array_list_free(phases_info->in_faultphases, env); + } + + if(phases_info->out_faultphases) + { + axutil_array_list_free(phases_info->out_faultphases, env); + } + + if(phases_info->op_in_phases) + { + axutil_hash_free(phases_info->op_in_phases, env); + } + + if(phases_info->op_out_phases) + { + axutil_hash_free(phases_info->op_out_phases, env); + } + + if(phases_info->op_in_faultphases) + { + axutil_hash_free(phases_info->op_in_faultphases, env); + } + + if(phases_info->op_out_faultphases) + { + axutil_hash_free(phases_info->op_out_faultphases, env); + } + + if(phases_info) + { + AXIS2_FREE(env->allocator, phases_info); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phases_info_set_in_phases( + axis2_phases_info_t * phases_info, + const axutil_env_t * env, + axutil_array_list_t * in_phases) +{ + AXIS2_PARAM_CHECK(env->error, in_phases, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, phases_info, AXIS2_FAILURE); + + if(phases_info->in_phases) + { + axutil_array_list_free(phases_info->in_phases, env); + } + + phases_info->in_phases = in_phases; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phases_info_set_out_phases( + axis2_phases_info_t * phases_info, + const axutil_env_t * env, + axutil_array_list_t * out_phases) +{ + AXIS2_PARAM_CHECK(env->error, out_phases, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, phases_info, AXIS2_FAILURE); + + if(phases_info->out_phases) + { + axutil_array_list_free(phases_info->out_phases, env); + phases_info->out_phases = NULL; + } + phases_info->out_phases = out_phases; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phases_info_set_in_faultphases( + axis2_phases_info_t * phases_info, + const axutil_env_t * env, + axutil_array_list_t * in_faultphases) +{ + AXIS2_PARAM_CHECK(env->error, in_faultphases, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, phases_info, AXIS2_FAILURE); + + if(phases_info->in_faultphases) + { + axutil_array_list_free(phases_info->in_faultphases, env); + phases_info->in_faultphases = NULL; + } + phases_info->in_faultphases = in_faultphases; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phases_info_set_out_faultphases( + axis2_phases_info_t * phases_info, + const axutil_env_t * env, + axutil_array_list_t * out_faultphases) +{ + AXIS2_PARAM_CHECK(env->error, out_faultphases, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, phases_info, AXIS2_FAILURE); + + if(phases_info->out_faultphases) + { + axutil_array_list_free(phases_info->out_faultphases, env); + phases_info->out_faultphases = NULL; + } + phases_info->out_faultphases = out_faultphases; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_get_in_phases( + const axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, phases_info, NULL); + return phases_info->in_phases; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_get_out_phases( + const axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, phases_info, NULL); + return phases_info->out_phases; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_get_in_faultphases( + const axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, phases_info, NULL); + return phases_info->in_faultphases; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_get_out_faultphases( + const axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, phases_info, NULL); + return phases_info->out_faultphases; +} + +/* Here we create the operation inflow as an array list and create phases for phases defined in + * inflow of axis2.xml and add them into the array list. + */ +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_get_op_in_phases( + const axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + struct axis2_phase *phase = NULL; + int i = 0; + int size = 0; + axis2_char_t *phase_name = NULL; + axutil_array_list_t *op_in_phases = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, phases_info, NULL); + + op_in_phases = axutil_array_list_create(env, 0); + if(!op_in_phases) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(!phases_info->in_phases) + { + return op_in_phases; + } + + /* For each inflow phase name create a phase instance and add into the inflow. */ + size = axutil_array_list_size(phases_info->in_phases, env); + for(i = 0; i < size; i++) + { + phase_name = (axis2_char_t *)axutil_array_list_get(phases_info->in_phases, env, i); + + if(!axutil_strcmp(AXIS2_PHASE_TRANSPORT_IN, phase_name) || !axutil_strcmp( + AXIS2_PHASE_PRE_DISPATCH, phase_name) || !axutil_strcmp(AXIS2_PHASE_DISPATCH, + phase_name) || !axutil_strcmp(AXIS2_PHASE_POST_DISPATCH, phase_name)) + { + /* We are not concerned here with system phases. */ + } + else + { + /* This is the cause for jira AXIS2C-624. As solution I create new + * phases for each operation specific flow making the operation + * the owner of the flow and the phases contained within it*/ + /*phase = axutil_hash_get(phases_info->op_in_phases, phase_name, + AXIS2_HASH_KEY_STRING); + if(!phase) + { + phase = axis2_phase_create(env, phase_name); + axutil_hash_set(phases_info->op_in_phases, phase_name, + AXIS2_HASH_KEY_STRING, phase); + } */ + phase = axis2_phase_create(env, phase_name); + status = axutil_array_list_add(op_in_phases, env, phase); + if(AXIS2_SUCCESS != status) + { + int i = 0; + int size = 0; + + axis2_phase_free(phase, env); + phase = NULL; + size = axutil_array_list_size(op_in_phases, env); + for(i = 0; i < size; i++) + { + phase = axutil_array_list_get(op_in_phases, env, i); + axis2_phase_free(phase, env); + phase = NULL; + } + axutil_array_list_free(op_in_phases, env); + op_in_phases = NULL; + return NULL; + } + } + } + + return op_in_phases; +} + +/* Here we create the operation outflow as an array list and create phases for phases defined in + * outflow of axis2.xml and add them into the array list. + */ +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_get_op_out_phases( + const axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + struct axis2_phase *phase = NULL; + int i = 0; + int size = 0; + axis2_char_t *phase_name = NULL; + axutil_array_list_t *op_out_phases = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, phases_info, NULL); + + if(phases_info->out_phases) + { + size = axutil_array_list_size(phases_info->out_phases, env); + } + + op_out_phases = axutil_array_list_create(env, 0); + if(!op_out_phases) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + for(i = 0; i < size; i++) + { + phase_name = (axis2_char_t *)axutil_array_list_get(phases_info->out_phases, env, i); + + phase = axis2_phase_create(env, phase_name); + status = axutil_array_list_add(op_out_phases, env, phase); + if(AXIS2_SUCCESS != status) + { + int i = 0; + int size = 0; + + axis2_phase_free(phase, env); + phase = NULL; + size = axutil_array_list_size(op_out_phases, env); + for(i = 0; i < size; i++) + { + phase = axutil_array_list_get(op_out_phases, env, i); + axis2_phase_free(phase, env); + phase = NULL; + } + + axutil_array_list_free(op_out_phases, env); + op_out_phases = NULL; + return NULL; + } + } + + return op_out_phases; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_get_op_in_faultphases( + const axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + int i = 0; + int size = 0; + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *phase_name = NULL; + axutil_array_list_t *op_in_faultphases = NULL; + struct axis2_phase *phase = NULL; + + AXIS2_PARAM_CHECK(env->error, phases_info, NULL); + + if(!phases_info->in_faultphases) + { + return NULL; + } + + size = axutil_array_list_size(phases_info->in_faultphases, env); + if(0 == size) + { + return NULL; + } + + op_in_faultphases = axutil_array_list_create(env, 0); + if(!op_in_faultphases) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + for(i = 0; i < size; i++) + { + phase_name = (axis2_char_t *)axutil_array_list_get(phases_info->in_faultphases, env, i); + + phase = axis2_phase_create(env, phase_name); + status = axutil_array_list_add(op_in_faultphases, env, phase); + if(AXIS2_SUCCESS != status) + { + int i = 0; + int size = 0; + + axis2_phase_free(phase, env); + phase = NULL; + size = axutil_array_list_size(op_in_faultphases, env); + for(i = 0; i < size; i++) + { + phase = axutil_array_list_get(op_in_faultphases, env, i); + axis2_phase_free(phase, env); + phase = NULL; + } + axutil_array_list_free(op_in_faultphases, env); + op_in_faultphases = NULL; + return NULL; + + } + } + + return op_in_faultphases; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_get_op_out_faultphases( + const axis2_phases_info_t * phases_info, + const axutil_env_t * env) +{ + int i = 0; + int size = 0; + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *phase_name = NULL; + axutil_array_list_t *op_out_faultphases = NULL; + struct axis2_phase *phase = NULL; + + AXIS2_PARAM_CHECK(env->error, phases_info, NULL); + + if(!phases_info->out_faultphases) + { + return NULL; + } + size = axutil_array_list_size(phases_info->out_faultphases, env); + + if(0 == size) + { + return NULL; + } + + op_out_faultphases = axutil_array_list_create(env, 0); + if(!op_out_faultphases) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + for(i = 0; i < size; i++) + { + phase_name = (axis2_char_t *)axutil_array_list_get(phases_info->out_faultphases, env, i); + phase = axis2_phase_create(env, phase_name); + status = axutil_array_list_add(op_out_faultphases, env, phase); + if(AXIS2_SUCCESS != status) + { + int i = 0; + int size = 0; + + axis2_phase_free(phase, env); + phase = NULL; + size = axutil_array_list_size(op_out_faultphases, env); + for(i = 0; i < size; i++) + { + phase = axutil_array_list_get(op_out_faultphases, env, i); + axis2_phase_free(phase, env); + phase = NULL; + } + axutil_array_list_free(op_out_faultphases, env); + op_out_faultphases = NULL; + return NULL; + + } + } + + return op_out_faultphases; +} + +/* + * Get user defined phase instances for each flow defined in axis2.xml in an array list and add it + * into operation. This is called service builder, module builder and service client to add phases + * into operations. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phases_info_set_op_phases( + axis2_phases_info_t * phases_info, + const axutil_env_t * env, + axis2_op_t * op_desc) +{ + axis2_status_t status = AXIS2_FAILURE; + axutil_array_list_t *op_in_phases = NULL; + axutil_array_list_t *op_out_phases = NULL; + axutil_array_list_t *op_in_faultphases = NULL; + axutil_array_list_t *op_out_faultphases = NULL; + + AXIS2_PARAM_CHECK(env->error, op_desc, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, phases_info, AXIS2_FAILURE); + + op_in_phases = axis2_phases_info_get_op_in_phases(phases_info, env); + if(!op_in_phases) + { + status = AXIS2_ERROR_GET_STATUS_CODE(env->error); + /* op_in_phases cannot be NULL */ + return status; + } + + op_out_phases = axis2_phases_info_get_op_out_phases(phases_info, env); + if(!op_out_phases) + { + status = AXIS2_ERROR_GET_STATUS_CODE(env->error); + /* op_out_phases cannot be NULL */ + return status; + } + + op_in_faultphases = axis2_phases_info_get_op_in_faultphases(phases_info, env); + op_out_faultphases = axis2_phases_info_get_op_out_faultphases(phases_info, env); + + status = axis2_op_set_in_flow(op_desc, env, op_in_phases); + status = axis2_op_set_out_flow(op_desc, env, op_out_phases); + if(op_in_faultphases) + { + status = axis2_op_set_fault_in_flow(op_desc, env, op_in_faultphases); + } + + if(op_out_faultphases) + { + status = axis2_op_set_fault_out_flow(op_desc, env, op_out_faultphases); + } + + return status; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phases_info_copy_flow( + const axutil_env_t * env, + const axutil_array_list_t * flow_to_copy) +{ + int size = 0, i = 0; + + axutil_array_list_t *new_flow = NULL; + if(flow_to_copy) + { + size = axutil_array_list_size((axutil_array_list_t *)flow_to_copy, env); + } + + if(size > 0) + { + new_flow = axutil_array_list_create(env, 0); + if(!new_flow) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + for(i = 0; i < size; i++) + { + void *item = axutil_array_list_get((axutil_array_list_t *)flow_to_copy, env, i); + axis2_phase_increment_ref((axis2_phase_t *)item, env); + axutil_array_list_add(new_flow, env, item); + } + + return new_flow; +} + diff --git a/src/core/deployment/repos_listener.c b/src/core/deployment/repos_listener.c new file mode 100644 index 0000000..1df1325 --- /dev/null +++ b/src/core/deployment/repos_listener.c @@ -0,0 +1,398 @@ +/* + * 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_repos_listener.h> +#include <axis2_ws_info_list.h> +#include <axutil_dir_handler.h> + +struct axis2_repos_listener +{ + + /** + * Referance to a ws info list + */ + axis2_ws_info_list_t *info_list; + + /** + * The parent directory of the modules and services directories + * that the listener should listen + */ + axis2_char_t *folder_name; + axis2_conf_t *conf; +}; + +static axis2_status_t +axis2_repos_listener_search( + axis2_repos_listener_t * repos_listener, + const axutil_env_t * env, + axis2_char_t * folder_name, + int type); + +AXIS2_EXTERN axis2_repos_listener_t *AXIS2_CALL +axis2_repos_listener_create( + const axutil_env_t * env) +{ + axis2_repos_listener_t *repos_listener = NULL; + + repos_listener = (axis2_repos_listener_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_repos_listener_t)); + + if(!repos_listener) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + repos_listener->folder_name = NULL; + repos_listener->info_list = NULL; + repos_listener->folder_name = AXIS2_FALSE; + + return repos_listener; +} + +/** + * This constructor take two argumnets, folder name and referance to + * deployment engine. Fisrt it initilize the sysetm , by loading all the + * modules in the /modules directory and also create a ws info list to + * keep info about available modules and services. + * @param folderName path to parent directory that the repos_listener + * should listens + * @param deploy_engine refearnce to engine registry inorder to + * inform the updates + */ + +AXIS2_EXTERN axis2_repos_listener_t *AXIS2_CALL +axis2_repos_listener_create_with_folder_name_and_dep_engine( + const axutil_env_t * env, + axis2_char_t * folder_name, + axis2_dep_engine_t * dep_engine) +{ + axis2_repos_listener_t *repos_listener = NULL; + axis2_status_t status = AXIS2_FAILURE; + + axis2_conf_t *conf; + axis2_bool_t file_flag; + + repos_listener = (axis2_repos_listener_t *)axis2_repos_listener_create(env); + + if(!repos_listener) + { + return NULL; + } + + file_flag = axis2_dep_engine_get_file_flag(dep_engine, env); + + if(!file_flag) + { + repos_listener->folder_name = axutil_strdup(env, folder_name); + if(!repos_listener->folder_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + repos_listener->info_list = axis2_ws_info_list_create_with_dep_engine(env, dep_engine); + if(!repos_listener->info_list) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating ws info list failed"); + return NULL; + } + + /* Here dep_engine's conf will set to repo_listner. Then we could get + * details of the axis2.xml through axis2 configuration. + */ + + conf = axis2_dep_engine_get_axis_conf(dep_engine, env); + if(!conf) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Deployment engines axis2 configuration not available"); + + return NULL; + } + axis2_repos_listener_set_conf(repos_listener, env, conf); + + status = axis2_repos_listener_init(repos_listener, env); + if(AXIS2_SUCCESS != status) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_REPOS_LISTENER_INIT_FAILED, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Repository listener initialization failed"); + + return NULL; + } + return repos_listener; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_repos_listener_free( + axis2_repos_listener_t * repos_listener, + const axutil_env_t * env) +{ + if(!repos_listener) + return; + + if(repos_listener->folder_name) + { + AXIS2_FREE(env->allocator, repos_listener->folder_name); + } + + if(repos_listener->info_list) + { + axis2_ws_info_list_free(repos_listener->info_list, env); + } + + AXIS2_FREE(env->allocator, repos_listener); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_repos_listener_check_modules( + axis2_repos_listener_t * repos_listener, + const axutil_env_t * env) +{ + axis2_char_t *module_path = NULL; + axis2_char_t *temp_path = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_bool_t axis2_flag = AXIS2_FALSE; + axis2_conf_t *conf; + + axutil_param_t *module_param; + axis2_char_t *module_dir; + + AXIS2_PARAM_CHECK(env->error, repos_listener, AXIS2_FAILURE); + + conf = axis2_repos_listener_get_conf(repos_listener, env); + + /* Configuration is needed only to decide we are using axis2.xml. Other + * case we don't need. Hence even if conf is NULL we can continue. + */ + + if(conf) + { + axis2_flag = axis2_conf_get_axis2_flag(conf, env); + } + + if(!axis2_flag) + { + + temp_path = axutil_stracat(env, repos_listener->folder_name, AXIS2_PATH_SEP_STR); + module_path = axutil_stracat(env, temp_path, AXIS2_MODULE_PATH); + AXIS2_FREE(env->allocator, temp_path); + } + else + { + module_param = axis2_conf_get_param(conf, env, AXIS2_MODULE_DIR); + if(module_param) + { + module_dir = (axis2_char_t *)axutil_param_get_value(module_param, env); + module_path = axutil_strdup(env, module_dir); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "While creating axis2 configuration using " + "axis2.xml, modulesDir parameter not available."); + } + + } + + status = axis2_repos_listener_search(repos_listener, env, module_path, AXIS2_MODULE); + + AXIS2_FREE(env->allocator, module_path); + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_repos_listener_check_svcs( + axis2_repos_listener_t * repos_listener, + const axutil_env_t * env) +{ + axis2_char_t *svc_path = NULL; + axis2_char_t *temp_path = NULL; + axis2_status_t status = AXIS2_FAILURE; + + axis2_conf_t *conf; + axis2_bool_t axis2_flag = AXIS2_FALSE; + + axutil_param_t *svc_param; + axis2_char_t *svc_dir; + + AXIS2_PARAM_CHECK(env->error, repos_listener, AXIS2_FAILURE); + + conf = axis2_repos_listener_get_conf(repos_listener, env); + + if(conf) + axis2_flag = axis2_conf_get_axis2_flag(conf, env); + + if(!axis2_flag) + { + temp_path = axutil_stracat(env, repos_listener->folder_name, AXIS2_PATH_SEP_STR); + svc_path = axutil_stracat(env, temp_path, AXIS2_SVC_PATH); + AXIS2_FREE(env->allocator, temp_path); + } + else + { + svc_param = axis2_conf_get_param(conf, env, AXIS2_SERVICE_DIR); + if(svc_param) + { + svc_dir = axutil_param_get_value(svc_param, env); + svc_path = axutil_strdup(env, svc_dir); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "While creating axis2 configuration using axis2.xml, servicesDir" + " parameter not available."); + } + } + + status = axis2_repos_listener_search(repos_listener, env, svc_path, AXIS2_SVC); + AXIS2_FREE(env->allocator, svc_path); + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_repos_listener_update( + axis2_repos_listener_t * repos_listener, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, repos_listener, AXIS2_FAILURE); + return axis2_ws_info_list_update(repos_listener->info_list, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_repos_listener_init( + axis2_repos_listener_t * repos_listener, + const axutil_env_t * env) +{ + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, repos_listener, AXIS2_FAILURE); + + status = axis2_ws_info_list_init(repos_listener->info_list, env); + if(AXIS2_SUCCESS != status) + { + return status; + } + /* if check_modules return AXIS2_FAILURE that means + * there are no modules to load + */ + axis2_repos_listener_check_modules(repos_listener, env); + + /* if check_svcs return AXIS2_FAILURE that means + * there are no services to load + */ + axis2_repos_listener_check_svcs(repos_listener, env); + return axis2_repos_listener_update(repos_listener, env); +} + +/** + * Folder name could be a repository modules or services folder. If it is modules + * folder then current_info_list contain the list of axis2 files corresponding to + * the modules within it. For services folder it should be understood similarly. + */ +static axis2_status_t +axis2_repos_listener_search( + axis2_repos_listener_t * repos_listener, + const axutil_env_t * env, + axis2_char_t * folder_name, + int type) +{ + int size = 0; + int i = 0; + axutil_array_list_t *current_info_list = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, repos_listener, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, folder_name, AXIS2_FAILURE); + current_info_list = axutil_dir_handler_list_service_or_module_dirs(env, folder_name); + if(!current_info_list) + { + axis2_status_t status_code = AXIS2_FAILURE; + + status_code = AXIS2_ERROR_GET_STATUS_CODE(env->error); + if(AXIS2_SUCCESS != status) + { + return status; + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "No %s in the folder.", folder_name); + return AXIS2_SUCCESS; + } + + size = axutil_array_list_size(current_info_list, env); + + for(i = 0; i < size; i++) /* Loop until empty */ + { + axutil_file_t *file = NULL; + file = axutil_array_list_get(current_info_list, env, i); + status = axis2_ws_info_list_add_ws_info_item(repos_listener->info_list, env, file, type); + if(AXIS2_SUCCESS != status) + { + int size_j = 0; + int j = 0; + axis2_char_t* file_name = axutil_file_get_name(file, env); + + size_j = axutil_array_list_size(current_info_list, env); + for(j = 0; j < size_j; j++) + { + axutil_file_t *del_file = NULL; + + del_file = axutil_array_list_get(current_info_list, env, j); + axutil_file_free(del_file, env); + } + axutil_array_list_free(current_info_list, env); + current_info_list = NULL; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding file %s to ws info list failed", + file_name); + return status; + } + } + + for(i = 0; i < size; i++) + { + axutil_file_t *del_file = NULL; + + del_file = axutil_array_list_get(current_info_list, env, i); + axutil_file_free(del_file, env); + } + axutil_array_list_free(current_info_list, env); + current_info_list = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_repos_listener_set_conf( + axis2_repos_listener_t *repo_listener, + const axutil_env_t * env, + axis2_conf_t *conf) +{ + AXIS2_PARAM_CHECK(env->error, repo_listener, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + repo_listener->conf = conf; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_conf_t *AXIS2_CALL +axis2_repos_listener_get_conf( + axis2_repos_listener_t *repo_listener, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, repo_listener, NULL); + return repo_listener->conf; +} + diff --git a/src/core/deployment/svc_builder.c b/src/core/deployment/svc_builder.c new file mode 100644 index 0000000..7f55fb6 --- /dev/null +++ b/src/core/deployment/svc_builder.c @@ -0,0 +1,840 @@ +/* + * 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_svc_builder.h> +#include <axutil_class_loader.h> +#include <axutil_utils.h> +#include <axutil_property.h> +#include <axis2_msg.h> + +struct axis2_svc_builder +{ + axis2_svc_t *svc; + struct axis2_desc_builder *desc_builder; +}; + +static axutil_array_list_t * +axis2_svc_builder_process_ops( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * op_itr); + +static void +axis2_svc_builder_process_msgs( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * iterator, + axis2_op_t * op); + +AXIS2_EXTERN axis2_svc_builder_t *AXIS2_CALL +axis2_svc_builder_create( + const axutil_env_t * env) +{ + axis2_svc_builder_t *svc_builder = NULL; + + svc_builder = (axis2_svc_builder_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_builder_t)); + + if(!svc_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Allocation to svc_builder failed"); + return NULL; + } + + svc_builder->desc_builder = NULL; + svc_builder->svc = NULL; + + return svc_builder; +} + +AXIS2_EXTERN axis2_svc_builder_t *AXIS2_CALL +axis2_svc_builder_create_with_file_and_dep_engine_and_svc( + const axutil_env_t * env, + axis2_char_t * file_name, + struct axis2_dep_engine * dep_engine, + axis2_svc_t * svc) +{ + axis2_svc_builder_t *svc_builder = NULL; + + AXIS2_PARAM_CHECK(env->error, file_name, NULL); + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + AXIS2_PARAM_CHECK(env->error, svc, NULL); + svc_builder = (axis2_svc_builder_t *)axis2_svc_builder_create(env); + if(!svc_builder) + { + return NULL; + } + svc_builder->desc_builder = axis2_desc_builder_create_with_file_and_dep_engine(env, file_name, + dep_engine); + if(!svc_builder->desc_builder) + { + axis2_svc_builder_free(svc_builder, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating description builder for service builder %s failed", file_name); + return NULL; + } + svc_builder->svc = svc; + return svc_builder; +} + +AXIS2_EXTERN axis2_svc_builder_t *AXIS2_CALL +axis2_svc_builder_create_with_dep_engine_and_svc( + const axutil_env_t * env, + axis2_dep_engine_t * dep_engine, + axis2_svc_t * svc) +{ + axis2_svc_builder_t *svc_builder = NULL; + + AXIS2_PARAM_CHECK(env->error, dep_engine, NULL); + AXIS2_PARAM_CHECK(env->error, svc, NULL); + svc_builder = (axis2_svc_builder_t *)axis2_svc_builder_create(env); + if(!svc_builder) + { + return NULL; + } + svc_builder->desc_builder = axis2_desc_builder_create_with_dep_engine(env, dep_engine); + if(!svc_builder->desc_builder) + { + axis2_svc_builder_free(svc_builder, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating description builder for service builder failed"); + return NULL; + } + svc_builder->svc = svc; + return svc_builder; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_builder_free( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env) +{ + if(svc_builder->desc_builder) + { + axis2_desc_builder_free(svc_builder->desc_builder, env); + } + + svc_builder->svc = NULL; + + if(svc_builder) + { + AXIS2_FREE(env->allocator, svc_builder); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_builder_populate_svc( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_node_t * svc_node) +{ + axiom_element_t *svc_element = NULL; + axiom_children_qname_iterator_t *itr = NULL; + axiom_children_qname_iterator_t *operation_itr = NULL; + axutil_qname_t *qparamst = NULL; + axutil_qname_t *qdesc = NULL; + axutil_qname_t *qmodulest = NULL; + axutil_qname_t *qinflowst = NULL; + axutil_qname_t *qoutflowst = NULL; + axutil_qname_t *qin_faultflowst = NULL; + axutil_qname_t *qout_faultflowst = NULL; + axutil_qname_t *qopst = NULL; + axutil_qname_t *qattname = NULL; + axutil_qname_t *qpolicy = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_svc_grp_t *parent = NULL; + axiom_element_t *desc_element = NULL; + axiom_node_t *desc_node = NULL; + axiom_children_qname_iterator_t *module_refs = NULL; + axiom_node_t *in_flow_node = NULL; + axiom_element_t *in_flow_element = NULL; + axiom_node_t *out_flow_node = NULL; + axiom_element_t *out_flow_element = NULL; + axiom_node_t *in_faultflow_node = NULL; + axiom_element_t *in_faultflow_element = NULL; + axiom_node_t *out_faultflow_node = NULL; + axiom_element_t *out_faultflow_element = NULL; + axiom_attribute_t *name_attr = NULL; + axutil_array_list_t *ops = NULL; + axis2_char_t *svc_name = NULL; + axis2_char_t *class_name = NULL; + axis2_char_t *svc_dll_name = NULL; + axutil_dll_desc_t *dll_desc = NULL; + axutil_param_t *impl_info_param = NULL; + axutil_param_t *wsdl_path_param = NULL; + axis2_char_t *wsdl_path = NULL; + axis2_arch_file_data_t *arch_file_data = NULL; + axutil_file_t *svc_folder = NULL; + axis2_char_t *dll_path = NULL; + axis2_char_t *svc_folder_path = NULL; + int i = 0; + int size = 0; + AXIS2_TIME_T timestamp = 0; + axis2_desc_t *desc = NULL; + axis2_policy_include_t *policy_include = NULL; + axutil_qname_t *qname_addressing = NULL; + axis2_bool_t addressing_engaged = AXIS2_FALSE; + axutil_array_list_t *svc_module_qnames = NULL; + int svc_module_qname_size = 0; + + AXIS2_PARAM_CHECK(env->error, svc_node, AXIS2_FAILURE); + + svc_element = axiom_node_get_data_element(svc_node, env); + /* Processing service level paramters */ + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + if(!qparamst) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + itr = axiom_element_get_children_with_qname(svc_element, env, qparamst, svc_node); + axutil_qname_free(qparamst, env); + qparamst = NULL; + + parent = axis2_svc_get_parent(svc_builder->svc, env); + + desc = axis2_svc_get_base(svc_builder->svc, env); + policy_include = axis2_desc_get_policy_include(desc, env); + + status = axis2_desc_builder_process_params(svc_builder->desc_builder, env, itr, + axis2_svc_get_param_container(svc_builder->svc, env), axis2_svc_grp_get_param_container( + parent, env)); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Processing parameters failed"); + return status; + } + + /* process service description */ + qdesc = axutil_qname_create(env, AXIS2_DESCRIPTION, NULL, NULL); + desc_element = axiom_element_get_first_child_with_qname(svc_element, env, qdesc, svc_node, + &desc_node); + axutil_qname_free(qdesc, env); + qdesc = NULL; + if(desc_element) + { + axiom_element_t *desc_value_element = NULL; + axiom_node_t *desc_value_node = NULL; + axis2_char_t *description_text = NULL; + + desc_value_element = axiom_element_get_first_element(desc_element, env, desc_node, + &desc_value_node); + description_text = axiom_element_get_text(desc_element, env, desc_node); + if(description_text) + { + axis2_svc_set_svc_desc(svc_builder->svc, env, description_text); + } + } + + /* wsdl path */ + wsdl_path_param = axutil_param_container_get_param(axis2_svc_get_param_container( + svc_builder->svc, env), env, AXIS2_SVC_WSDL_PATH); + + if(wsdl_path_param) + { + wsdl_path = axutil_param_get_value(wsdl_path_param, env); + } + + if(wsdl_path) + { + axis2_svc_set_svc_wsdl_path(svc_builder->svc, env, wsdl_path); + } + + qattname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + name_attr = axiom_element_get_attribute(svc_element, env, qattname); + svc_name = axiom_attribute_get_value(name_attr, env); + axis2_svc_set_name(svc_builder->svc, env, svc_name); + axutil_qname_free(qattname, env); + + /* create dll_desc and set it in a parameter. then set that param in param + * container taken from svc + */ + dll_desc = axutil_dll_desc_create(env); + impl_info_param = axutil_param_container_get_param(axis2_svc_get_param_container( + svc_builder->svc, env), env, AXIS2_SERVICE_CLASS); + if(!impl_info_param) + { + axutil_dll_desc_free(dll_desc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s parameter not found", AXIS2_SERVICE_CLASS); + return AXIS2_FAILURE; + } + class_name = axutil_strtrim(env, axutil_param_get_value(impl_info_param, env), NULL); + svc_dll_name = axutil_dll_desc_create_platform_specific_dll_name(dll_desc, env, class_name); + + if(class_name) + { + AXIS2_FREE(env->allocator, class_name); + class_name = NULL; + } + + arch_file_data = axis2_dep_engine_get_current_file_item(axis2_desc_builder_get_dep_engine( + svc_builder->desc_builder, env), env); + svc_folder = axis2_arch_file_data_get_file(arch_file_data, env); + timestamp = axutil_file_get_timestamp(svc_folder, env); + axutil_dll_desc_set_timestamp(dll_desc, env, timestamp); + svc_folder_path = axutil_file_get_path(svc_folder, env); + axis2_svc_set_svc_folder_path(svc_builder->svc, env, svc_folder_path); + dll_path = axutil_strcat(env, svc_folder_path, AXIS2_PATH_SEP_STR, svc_dll_name, NULL); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "DLL path is : %s", dll_path); + status = axutil_dll_desc_set_name(dll_desc, env, dll_path); + if(AXIS2_SUCCESS != status) + { + axutil_dll_desc_free(dll_desc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting name to %s dll description failed", + dll_path); + return status; + } + AXIS2_FREE(env->allocator, dll_path); + dll_path = NULL; + + axutil_dll_desc_set_type(dll_desc, env, AXIS2_SVC_DLL); + status = axutil_param_set_value(impl_info_param, env, dll_desc); + axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg); + if(AXIS2_SUCCESS != status) + { + axutil_dll_desc_free(dll_desc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting dll_desc to parameter %s failed", + class_name); + return status; + } + /* processing service wide modules which required to engage globally */ + qmodulest = axutil_qname_create(env, AXIS2_MODULEST, NULL, NULL); + module_refs = axiom_element_get_children_with_qname(svc_element, env, qmodulest, svc_node); + axutil_qname_free(qmodulest, env); + qmodulest = NULL; + status = axis2_svc_builder_process_module_refs(svc_builder, env, module_refs); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Processing module references failed"); + return status; + } + + if(!addressing_engaged) + { + svc_module_qnames = axis2_svc_get_all_module_qnames(svc_builder->svc, env); + if(svc_module_qnames) + { + svc_module_qname_size = axutil_array_list_size(svc_module_qnames, env); + qname_addressing = axutil_qname_create(env, AXIS2_MODULE_ADDRESSING, NULL, NULL); + for(i = 0; i < svc_module_qname_size; i++) + { + if(axutil_qname_equals(axutil_array_list_get(svc_module_qnames, env, i), env, + qname_addressing)) + { + addressing_engaged = AXIS2_TRUE; + break; + } + } + axutil_qname_free(qname_addressing, env); + } + svc_module_qnames = NULL; + } + + /* process IN_FLOW */ + qinflowst = axutil_qname_create(env, AXIS2_IN_FLOW_START, NULL, NULL); + in_flow_element = axiom_element_get_first_child_with_qname( + svc_element, env, qinflowst, svc_node, &in_flow_node); + axutil_qname_free(qinflowst, env); + qinflowst = NULL; + + qoutflowst = axutil_qname_create(env, AXIS2_OUT_FLOW_START, NULL, NULL); + out_flow_element = axiom_element_get_first_child_with_qname( + svc_element, env, qoutflowst, svc_node, &out_flow_node); + axutil_qname_free(qoutflowst, env); + qoutflowst = NULL; + + qin_faultflowst = axutil_qname_create(env, AXIS2_IN_FAILTFLOW, NULL, NULL); + in_faultflow_element = axiom_element_get_first_child_with_qname( + svc_element, env, qin_faultflowst, svc_node, &in_faultflow_node); + axutil_qname_free(qin_faultflowst, env); + qin_faultflowst = NULL; + + qout_faultflowst = axutil_qname_create(env, AXIS2_OUT_FAILTFLOW, NULL, NULL); + out_faultflow_element = axiom_element_get_first_child_with_qname( + svc_element, env, qout_faultflowst, svc_node, &out_faultflow_node); + axutil_qname_free(qout_faultflowst, env); + qout_faultflowst = NULL; + + /* processing operations */ + qopst = axutil_qname_create(env, AXIS2_OPERATIONST, NULL, NULL); + operation_itr = axiom_element_get_children_with_qname(svc_element, env, qopst, svc_node); + axutil_qname_free(qopst, env); + qopst = NULL; + ops = axis2_svc_builder_process_ops(svc_builder, env, operation_itr); + if(ops) + { + size = axutil_array_list_size(ops, env); + } + for(i = 0; i < size; i++) + { + axis2_op_t *op_desc = NULL; + axutil_array_list_t *params = NULL; + int j = 0; + int sizej = 0; + + op_desc = (axis2_op_t *)axutil_array_list_get(ops, env, i); + if(addressing_engaged) + { + params = axis2_op_get_all_params(op_desc, env); + /* Adding wsa-mapping into service */ + sizej = axutil_array_list_size(params, env); + for(j = 0; j < sizej; j++) + { + axutil_param_t *param = NULL; + axis2_char_t *param_name = NULL; + + param = axutil_array_list_get(params, env, j); + param_name = axutil_param_get_name(param, env); + if(0 == axutil_strcmp(param_name, AXIS2_WSA_MAPPING)) + { + axis2_char_t *key = NULL; + + key = (axis2_char_t *)axutil_param_get_value(param, env); + axis2_svc_add_mapping(svc_builder->svc, env, key, op_desc); + } + } + } + axis2_svc_add_op(svc_builder->svc, env, op_desc); + if(axis2_op_get_rest_http_method(op_desc, env) && axis2_op_get_rest_http_location(op_desc, + env)) + { + axis2_svc_add_rest_mapping(svc_builder->svc, env, axis2_op_get_rest_http_method( + op_desc, env), axis2_op_get_rest_http_location(op_desc, env), op_desc); + } + } + axutil_array_list_free(ops, env); + + /* + <schema targetNamespace="http://x.y.z"/> + setting the PolicyInclude + processing <wsp:Policy> .. </..> elements + */ + qpolicy = axutil_qname_create(env, NEETHI_POLICY, NEETHI_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(svc_element, env, qpolicy, svc_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + if((!itr) || (!axiom_children_qname_iterator_has_next(itr, env))) + { + qpolicy = axutil_qname_create(env, NEETHI_POLICY, NEETHI_POLICY_15_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(svc_element, env, qpolicy, svc_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + } + + if(itr) + { + axis2_process_policy_elements(env, AXIS2_SERVICE_POLICY, itr, policy_include); + } + + /* processing <wsp:PolicyReference> .. </..> elements */ + qpolicy = axutil_qname_create(env, NEETHI_REFERENCE, NEETHI_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(svc_element, env, qpolicy, svc_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + + if((!itr) || (!axiom_children_qname_iterator_has_next(itr, env))) + { + qpolicy = axutil_qname_create(env, NEETHI_REFERENCE, NEETHI_POLICY_15_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(svc_element, env, qpolicy, svc_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + } + if(itr) + { + axis2_process_policy_reference_elements(env, AXIS2_POLICY_REF, itr, policy_include); + } + + return AXIS2_SUCCESS; +} + +static axutil_array_list_t * +axis2_svc_builder_process_ops( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * op_itr) +{ + axutil_array_list_t *ops = NULL; + + AXIS2_PARAM_CHECK(env->error, op_itr, NULL); + + ops = axutil_array_list_create(env, 0); + while(AXIS2_TRUE == axiom_children_qname_iterator_has_next(op_itr, env)) + { + axiom_element_t *op_element = NULL; + axiom_node_t *op_node = NULL; + axiom_attribute_t *op_name_att = NULL; + axiom_attribute_t *op_mep_att = NULL; + axutil_qname_t *qmep = NULL; + axutil_qname_t *qopname = NULL; + axutil_qname_t *qparamst = NULL; + axutil_qname_t *qmsgrecv = NULL; + axutil_qname_t *qmodulest = NULL; + axutil_qname_t *qattname = NULL; + axis2_char_t *mep_url = NULL; + axis2_char_t *op_name = NULL; + axis2_op_t *op_desc = NULL; + axiom_children_qname_iterator_t *params_itr = NULL; + axiom_children_qname_iterator_t *module_itr = NULL; + axiom_element_t *recv_element = NULL; + axiom_node_t *recv_node = NULL; + axis2_status_t status = AXIS2_FAILURE; + struct axis2_dep_engine *dep_engine = NULL; + axis2_desc_t *desc = NULL; + axis2_policy_include_t *policy_include = NULL; + axiom_children_qname_iterator_t *itr = NULL; + axutil_qname_t *qpolicy = NULL; + axutil_qname_t *qmessage = NULL; + + op_node = axiom_children_qname_iterator_next(op_itr, env); + /* getting operation name */ + op_element = axiom_node_get_data_element(op_node, env); + qattname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + op_name_att = axiom_element_get_attribute(op_element, env, qattname); + axutil_qname_free(qattname, env); + qattname = NULL; + if(!op_name_att) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_OP_NAME_MISSING, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + return NULL; + } + + op_name = axiom_attribute_get_value(op_name_att, env); + qopname = axutil_qname_create(env, op_name, NULL, NULL); + op_desc = axis2_op_create(env); + axis2_op_set_qname(op_desc, env, qopname); + axutil_qname_free(qopname, env); + qopname = NULL; + + /* set the mep of the operation */ + qmep = axutil_qname_create(env, AXIS2_MEP, NULL, NULL); + op_mep_att = axiom_element_get_attribute(op_element, env, qmep); + axutil_qname_free(qmep, env); + qmep = NULL; + op_name = axiom_attribute_get_value(op_name_att, env); + + if(op_mep_att) + { + mep_url = axiom_attribute_get_value(op_mep_att, env); + if(mep_url) + { + axis2_op_set_msg_exchange_pattern(op_desc, env, mep_url); + } + } + + desc = axis2_op_get_base(op_desc, env); + policy_include = axis2_desc_get_policy_include(desc, env); + + /* operation parameters */ + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + params_itr = axiom_element_get_children_with_qname(op_element, env, qparamst, op_node); + axutil_qname_free(qparamst, env); + qparamst = NULL; + status = axis2_desc_builder_process_params(svc_builder->desc_builder, env, params_itr, + axis2_op_get_param_container(op_desc, env), axis2_svc_get_param_container( + svc_builder->svc, env)); + /* To process wsamapping */ + axis2_desc_builder_process_action_mappings(svc_builder->desc_builder, env, op_node, op_desc); + + /* To process REST params */ + axis2_desc_builder_process_rest_params(svc_builder->desc_builder, env, op_node, op_desc); + + /* loading the message receivers */ + qmsgrecv = axutil_qname_create(env, AXIS2_MESSAGERECEIVER, NULL, NULL); + recv_element = axiom_element_get_first_child_with_qname(op_element, env, qmsgrecv, op_node, + &recv_node); + axutil_qname_free(qmsgrecv, env); + qmsgrecv = NULL; + if(recv_element && NULL != recv_node) + { + axis2_msg_recv_t *msg_recv = NULL; + msg_recv = axis2_desc_builder_load_msg_recv(svc_builder->desc_builder, env, + recv_element); + axis2_op_set_msg_recv(op_desc, env, msg_recv); + + } + else + { + axis2_msg_recv_t *msg_recv = NULL; + /* setting the default message receiver */ + msg_recv = axis2_desc_builder_load_default_msg_recv(env); + axis2_op_set_msg_recv(op_desc, env, msg_recv); + } + /* process module refs */ + qmodulest = axutil_qname_create(env, AXIS2_MODULEST, NULL, NULL); + module_itr = axiom_element_get_children_with_qname(op_element, env, qmodulest, op_node); + axutil_qname_free(qmodulest, env); + qmodulest = NULL; + status = axis2_desc_builder_process_op_module_refs(svc_builder-> desc_builder, env, + module_itr, op_desc); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Processing module operation references failed for operation %s", op_name); + return NULL; + } + + /* setting the policy_include */ + + /* processing <wsp:Policy> .. </..> elements */ + + qpolicy = axutil_qname_create(env, NEETHI_POLICY, NEETHI_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qpolicy, op_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + + if((!itr) || (!axiom_children_qname_iterator_has_next(itr, env))) + { + qpolicy = axutil_qname_create(env, NEETHI_POLICY, NEETHI_POLICY_15_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qpolicy, op_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + } + + if(itr) + { + axis2_process_policy_elements(env, AXIS2_SERVICE_POLICY, itr, policy_include); + } + + /* processing <wsp:PolicyReference> .. </..> elements */ + qpolicy = axutil_qname_create(env, NEETHI_REFERENCE, NEETHI_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qpolicy, op_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + + if((!itr) || (!axiom_children_qname_iterator_has_next(itr, env))) + { + qpolicy = axutil_qname_create(env, NEETHI_REFERENCE, NEETHI_POLICY_15_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qpolicy, op_node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + } + + if(itr) + { + axis2_process_policy_reference_elements(env, AXIS2_POLICY_REF, itr, policy_include); + } + + qmessage = axutil_qname_create(env, AXIS2_MESSAGE, NULL, NULL); + itr = axiom_element_get_children_with_qname(op_element, env, qmessage, op_node); + axutil_qname_free(qmessage, env); + qmessage = NULL; + + if(itr) + { + axis2_svc_builder_process_msgs(svc_builder, env, itr, op_desc); + } + + /* setting operation phase */ + dep_engine = axis2_desc_builder_get_dep_engine(svc_builder->desc_builder, env); + if(dep_engine) + { + axis2_phases_info_t *info = axis2_dep_engine_get_phases_info(dep_engine, env); + axis2_phases_info_set_op_phases(info, env, op_desc); + } + + /* adding operation */ + status = axutil_array_list_add(ops, env, op_desc); + } + + return ops; +} + +static void +axis2_svc_builder_process_msgs( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * iterator, + axis2_op_t * op) +{ + while(axiom_children_qname_iterator_has_next(iterator, env)) + { + axiom_node_t *node = NULL; + axiom_element_t *element = NULL; + axutil_qname_t *qname = NULL; + axis2_char_t *msg_label = NULL; + axis2_msg_t *msg = NULL; + axiom_children_qname_iterator_t *itr = NULL; + axutil_qname_t *qpolicy = NULL; + axis2_desc_t *desc = NULL; + axis2_policy_include_t *policy_include = NULL; + + node = axiom_children_qname_iterator_next(iterator, env); + element = axiom_node_get_data_element(node, env); + qname = axutil_qname_create(env, AXIS2_LABEL, NULL, NULL); + + if(element) + { + msg_label = axiom_element_get_attribute_value(element, env, qname); + } + + if(msg_label) + { + msg = axis2_op_get_msg(op, env, msg_label); + } + + if(msg) + { + /* operation parameters */ + axiom_children_qname_iterator_t *params_itr = NULL; + axutil_qname_t *qparamst = NULL; + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + params_itr = axiom_element_get_children_with_qname(element, env, qparamst, node); + axutil_qname_free(qparamst, env); + qparamst = NULL; + axis2_desc_builder_process_params(svc_builder->desc_builder, env, params_itr, + axis2_msg_get_param_container(msg, env), axis2_op_get_param_container(op, env)); + + desc = axis2_msg_get_base(msg, env); + policy_include = axis2_desc_get_policy_include(desc, env); + + /* setting the policy_include */ + + /* processing <wsp:Policy> .. </..> elements */ + + qpolicy = axutil_qname_create(env, NEETHI_POLICY, NEETHI_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(element, env, qpolicy, node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + + if((!itr) || (!axiom_children_qname_iterator_has_next(itr, env))) + { + qpolicy = axutil_qname_create(env, NEETHI_POLICY, NEETHI_POLICY_15_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(element, env, qpolicy, node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + } + + if(itr) + { + axis2_process_policy_elements(env, AXIS2_SERVICE_POLICY, itr, policy_include); + /* axis2_process_policy_elements(env, AXIS2_MESSAGE_POLICY, itr, + policy_include); */ + + } + + /* processing <wsp:PolicyReference> .. </..> elements */ + qpolicy = axutil_qname_create(env, NEETHI_REFERENCE, NEETHI_NAMESPACE, NULL); + itr = axiom_element_get_children_with_qname(element, env, qpolicy, node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + + if((!itr) || (!axiom_children_qname_iterator_has_next(itr, env))) + { + qpolicy = axutil_qname_create(env, NEETHI_REFERENCE, NEETHI_POLICY_15_NAMESPACE, + NULL); + itr = axiom_element_get_children_with_qname(element, env, qpolicy, node); + axutil_qname_free(qpolicy, env); + qpolicy = NULL; + } + + if(itr) + { + axis2_process_policy_reference_elements(env, AXIS2_POLICY_REF, itr, policy_include); + } + } + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_builder_process_svc_module_conf( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_confs, + axutil_param_container_t * parent, + axis2_svc_t * svc) +{ + while(axiom_children_qname_iterator_has_next(module_confs, env)) + { + axiom_element_t *module_conf_element = NULL; + axiom_node_t *module_conf_node = NULL; + axiom_attribute_t *module_name_att = NULL; + axutil_qname_t *qattname = NULL; + + module_conf_node = axiom_children_qname_iterator_next(module_confs, env); + module_conf_element = axiom_node_get_data_element(module_conf_node, env); + qattname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + module_name_att = axiom_element_get_attribute(module_conf_element, env, qattname); + axutil_qname_free(qattname, env); + qattname = NULL; + if(!module_name_att) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODULE_CONF, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Module name attribute not found for module node"); + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_builder_process_module_refs( + axis2_svc_builder_t * svc_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_refs) +{ + AXIS2_PARAM_CHECK(env->error, module_refs, AXIS2_FAILURE); + + while(axiom_children_qname_iterator_has_next(module_refs, env)) + { + axiom_element_t *module_ref_element = NULL; + axiom_node_t *module_ref_node = NULL; + axiom_attribute_t *module_ref_att = NULL; + axutil_qname_t *qref = NULL; + + module_ref_node = axiom_children_qname_iterator_next(module_refs, env); + module_ref_element = axiom_node_get_data_element(module_ref_node, env); + qref = axutil_qname_create(env, AXIS2_REF, NULL, NULL); + module_ref_att = axiom_element_get_attribute(module_ref_element, env, qref); + axutil_qname_free(qref, env); + if(module_ref_att) + { + axis2_char_t *ref_name = NULL; + axutil_qname_t *qrefname = NULL; + + ref_name = axiom_attribute_get_value(module_ref_att, env); + qrefname = axutil_qname_create(env, ref_name, NULL, NULL); + if(!axis2_dep_engine_get_module(axis2_desc_builder_get_dep_engine( + svc_builder->desc_builder, env), env, qrefname)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to find " + "Module %s, in Service %s", ref_name, axis2_svc_get_name(svc_builder->svc, env)); + return AXIS2_FAILURE; + } + else + { + axis2_svc_add_module_qname(svc_builder->svc, env, qrefname); + } + axutil_qname_free(qrefname, env); + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN struct axis2_desc_builder *AXIS2_CALL +axis2_svc_builder_get_desc_builder( + const axis2_svc_builder_t * svc_builder, + const axutil_env_t * env) +{ + return svc_builder->desc_builder; +} + diff --git a/src/core/deployment/svc_grp_builder.c b/src/core/deployment/svc_grp_builder.c new file mode 100644 index 0000000..6aa07ad --- /dev/null +++ b/src/core/deployment/svc_grp_builder.c @@ -0,0 +1,264 @@ +/* + * 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_svc_grp_builder.h> + +struct axis2_svc_grp_builder +{ + axiom_node_t *svc_grp; + axis2_desc_builder_t *desc_builder; +}; + +AXIS2_EXTERN axis2_svc_grp_builder_t *AXIS2_CALL +axis2_svc_grp_builder_create( + const axutil_env_t * env) +{ + axis2_svc_grp_builder_t *svc_grp_builder = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + svc_grp_builder = (axis2_svc_grp_builder_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_svc_grp_builder_t)); + + if(!svc_grp_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + svc_grp_builder->svc_grp = NULL; + svc_grp_builder->desc_builder = NULL; + + return svc_grp_builder; +} + +AXIS2_EXTERN axis2_svc_grp_builder_t *AXIS2_CALL +axis2_svc_grp_builder_create_with_svc_and_dep_engine( + const axutil_env_t * env, + axiom_node_t * svc_grp, + axis2_dep_engine_t * dep_engine) +{ + axis2_svc_grp_builder_t *svc_grp_builder = NULL; + + svc_grp_builder = (axis2_svc_grp_builder_t *)axis2_svc_grp_builder_create(env); + if(!svc_grp_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + svc_grp_builder = NULL; + } + svc_grp_builder->desc_builder = axis2_desc_builder_create_with_dep_engine(env, dep_engine); + if(!svc_grp_builder->desc_builder) + { + axis2_svc_grp_builder_free(svc_grp_builder, env); + return NULL; + } + svc_grp_builder->svc_grp = svc_grp; + + return svc_grp_builder; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_grp_builder_free( + axis2_svc_grp_builder_t * svc_grp_builder, + const axutil_env_t * env) +{ + if(svc_grp_builder->desc_builder) + { + axis2_desc_builder_free(svc_grp_builder->desc_builder, env); + } + if(svc_grp_builder) + { + AXIS2_FREE(env->allocator, svc_grp_builder); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_builder_populate_svc_grp( + axis2_svc_grp_builder_t * svc_grp_builder, + const axutil_env_t * env, + axis2_svc_grp_t * svc_grp) +{ + axiom_children_qname_iterator_t *itr = NULL; + axiom_children_qname_iterator_t *module_ref_itr = NULL; + axiom_children_qname_iterator_t *svc_itr = NULL; + axutil_qname_t *qparamst = NULL; + axutil_qname_t *qmodulest = NULL; + axutil_qname_t *qsvc_element = NULL; + axiom_element_t *svc_grp_element = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_conf_t *parent = NULL; + + /* Processing service level paramters */ + svc_grp_element = axiom_node_get_data_element(svc_grp_builder->svc_grp, env); + qparamst = axutil_qname_create(env, AXIS2_PARAMETERST, NULL, NULL); + + itr = axiom_element_get_children_with_qname(svc_grp_element, env, qparamst, + svc_grp_builder->svc_grp); + + if(qparamst) + { + axutil_qname_free(qparamst, env); + qparamst = NULL; + } + + parent = axis2_svc_grp_get_parent(svc_grp, env); + status = axis2_desc_builder_process_params(svc_grp_builder->desc_builder, env, itr, + axis2_svc_grp_get_param_container(svc_grp, env), + axis2_conf_get_param_container(parent, env)); + + /* Processing service modules required to be engaged globally */ + qmodulest = axutil_qname_create(env, AXIS2_MODULEST, NULL, NULL); + module_ref_itr = axiom_element_get_children_with_qname(svc_grp_element, env, qmodulest, + svc_grp_builder-> svc_grp); + + if(qmodulest) + { + axutil_qname_free(qmodulest, env); + qmodulest = NULL; + } + + axis2_svc_grp_builder_process_module_refs(svc_grp_builder, env, module_ref_itr, svc_grp); + qsvc_element = axutil_qname_create(env, AXIS2_SVC_ELEMENT, NULL, NULL); + svc_itr = axiom_element_get_children_with_qname(svc_grp_element, env, qsvc_element, + svc_grp_builder->svc_grp); + + if(qsvc_element) + { + axutil_qname_free(qsvc_element, env); + qsvc_element = NULL; + } + + while(axiom_children_qname_iterator_has_next(svc_itr, env)) + { + axiom_node_t *svc_node = NULL; + axiom_element_t *svc_element = NULL; + axiom_attribute_t *svc_name_att = NULL; + axis2_char_t *svc_name = NULL; + axutil_qname_t *qattname = NULL; + + svc_node = (axiom_node_t *)axiom_children_qname_iterator_next(svc_itr, env); + svc_element = axiom_node_get_data_element(svc_node, env); + qattname = axutil_qname_create(env, AXIS2_ATTNAME, NULL, NULL); + svc_name_att = axiom_element_get_attribute(svc_element, env, qattname); + + if(qattname) + { + axutil_qname_free(qattname, env); + qattname = NULL; + } + + svc_name = axiom_attribute_get_value(svc_name_att, env); + if(!svc_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_NAME_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service name attribute has no value"); + return AXIS2_FAILURE; + } + else + { + axis2_svc_t *axis_svc = NULL; + axis2_arch_file_data_t *file_data = NULL; + axutil_array_list_t *deployable_svcs = NULL; + axis2_svc_builder_t *svc_builder = NULL; + + file_data = axis2_dep_engine_get_current_file_item(axis2_desc_builder_get_dep_engine( + svc_grp_builder->desc_builder, env), env); + axis_svc = axis2_arch_file_data_get_svc(file_data, env, svc_name); + if(!axis_svc) + { + axutil_qname_t *qsvc_name = NULL; + + qsvc_name = axutil_qname_create(env, svc_name, NULL, NULL); + axis_svc = axis2_svc_create_with_qname(env, qsvc_name); + axutil_qname_free(qsvc_name, env); + axis2_arch_file_data_add_svc(file_data, env, axis_svc); + + } + /* Adding service to the deployable services list */ + deployable_svcs = axis2_arch_file_data_get_deployable_svcs(file_data, env); + axutil_array_list_add(deployable_svcs, env, axis_svc); + axis2_svc_set_parent(axis_svc, env, svc_grp); + svc_builder = axis2_svc_builder_create_with_dep_engine_and_svc(env, + axis2_desc_builder_get_dep_engine(svc_grp_builder-> desc_builder, env), axis_svc); + status = axis2_svc_builder_populate_svc(svc_builder, env, svc_node); + axis2_svc_builder_free(svc_builder, env); + + } + } + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_builder_process_module_refs( + axis2_svc_grp_builder_t * svc_grp_builder, + const axutil_env_t * env, + axiom_children_qname_iterator_t * module_refs, + axis2_svc_grp_t * svc_grp) +{ + AXIS2_PARAM_CHECK(env->error, module_refs, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, svc_grp, AXIS2_FAILURE); + + while(axiom_children_qname_iterator_has_next(module_refs, env)) + { + axiom_node_t *module_ref_node = NULL; + axiom_element_t *module_ref_element = NULL; + axiom_attribute_t *module_ref_att = NULL; + axutil_qname_t *qref = NULL; + + module_ref_node = (axiom_node_t *)axiom_children_qname_iterator_next(module_refs, env); + module_ref_element = axiom_node_get_data_element(module_ref_node, env); + qref = axutil_qname_create(env, AXIS2_REF, NULL, NULL); + module_ref_att = axiom_element_get_attribute(module_ref_element, env, qref); + if(module_ref_att) + { + axis2_char_t *ref_name = NULL; + axutil_qname_t *qrefname = NULL; + axis2_module_desc_t *module = NULL; + + ref_name = axiom_attribute_get_value(module_ref_att, env); + qrefname = axutil_qname_create(env, ref_name, NULL, NULL); + module = axis2_dep_engine_get_module(axis2_desc_builder_get_dep_engine( + svc_grp_builder->desc_builder, env), env, qrefname); + if(!module) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_NOT_FOUND, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Module %s not found in deployment engine.", ref_name); + return AXIS2_FAILURE; + } + else + { + axis2_svc_grp_add_module_ref(svc_grp, env, qrefname); + } + axutil_qname_free(qrefname, env); + } + axutil_qname_free(qref, env); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_desc_builder_t *AXIS2_CALL +axis2_svc_grp_builder_get_desc_builder( + const axis2_svc_grp_builder_t * svc_grp_builder, + const axutil_env_t * env) +{ + return svc_grp_builder->desc_builder; +} + diff --git a/src/core/deployment/ws_info.c b/src/core/deployment/ws_info.c new file mode 100644 index 0000000..0f2fa37 --- /dev/null +++ b/src/core/deployment/ws_info.c @@ -0,0 +1,158 @@ +/* + * 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_ws_info.h" +#include <string.h> + +struct axis2_ws_info +{ + axis2_char_t *file_name; + long last_modified_date; + + /** + * To check whether the file is a module or a servise + */ + int type; +}; + +AXIS2_EXTERN axis2_ws_info_t *AXIS2_CALL +axis2_ws_info_create_with_file_name_and_last_modified_date( + const axutil_env_t * env, + axis2_char_t * file_name, + long last_modified_date) +{ + axis2_ws_info_t *ws_info = NULL; + + AXIS2_PARAM_CHECK(env->error, file_name, NULL); + + ws_info = (axis2_ws_info_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_ws_info_t)); + + if(!ws_info) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + ws_info->file_name = NULL; + ws_info->last_modified_date = 0; + ws_info->type = 0; + + ws_info->file_name = axutil_strdup(env, file_name); + if(!ws_info->file_name) + { + axis2_ws_info_free(ws_info, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + ws_info->last_modified_date = last_modified_date; + + return ws_info; +} + +AXIS2_EXTERN axis2_ws_info_t *AXIS2_CALL +axis2_ws_info_create_with_file_name_and_last_modified_date_and_type( + const axutil_env_t * env, + axis2_char_t * file_name, + long last_modified_date, + int type) +{ + axis2_ws_info_t *ws_info = NULL; + + AXIS2_PARAM_CHECK(env->error, file_name, NULL); + + ws_info = (axis2_ws_info_t *)axis2_ws_info_create_with_file_name_and_last_modified_date(env, + file_name, last_modified_date); + if(!ws_info) + { + axis2_ws_info_free(ws_info, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + ws_info->type = type; + return ws_info; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_ws_info_free( + axis2_ws_info_t * ws_info, + const axutil_env_t * env) +{ + if(ws_info->file_name) + { + AXIS2_FREE(env->allocator, ws_info->file_name); + } + + if(ws_info) + { + AXIS2_FREE(env->allocator, ws_info); + } + + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_ws_info_get_file_name( + const axis2_ws_info_t * ws_info, + const axutil_env_t * env) +{ + return ws_info->file_name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ws_info_set_file_name( + axis2_ws_info_t * ws_info, + const axutil_env_t * env, + axis2_char_t * file_name) +{ + AXIS2_PARAM_CHECK(env->error, file_name, AXIS2_FAILURE); + + if(ws_info->file_name) + { + AXIS2_FREE(env->allocator, ws_info->file_name); + ws_info->file_name = NULL; + } + ws_info->file_name = file_name; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN long AXIS2_CALL +axis2_ws_info_get_last_modified_date( + const axis2_ws_info_t * ws_info, + const axutil_env_t * env) +{ + return ws_info->last_modified_date; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ws_info_set_last_modified_date( + axis2_ws_info_t * ws_info, + const axutil_env_t * env, + long last_modified_date) +{ + ws_info->last_modified_date = last_modified_date; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_ws_info_get_type( + const axis2_ws_info_t * ws_info, + const axutil_env_t * env) +{ + return ws_info->type; +} + diff --git a/src/core/deployment/ws_info_list.c b/src/core/deployment/ws_info_list.c new file mode 100644 index 0000000..41a85c7 --- /dev/null +++ b/src/core/deployment/ws_info_list.c @@ -0,0 +1,370 @@ +/* + * 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_ws_info_list.h> +#include <string.h> +#include <axutil_class_loader.h> + +struct axis2_ws_info_list +{ + /** + * This is to store all the deployment info about the deployment files + * for services or modules in a specified folder. + */ + axutil_array_list_t *ws_info_list; + + /** + * All the curently updated deployment info list. + */ + axutil_array_list_t *current_info_list; + + /** + * Referance to deployment engine to make update. + */ + struct axis2_dep_engine *dep_engine; + +}; + +AXIS2_EXTERN axis2_ws_info_list_t *AXIS2_CALL +axis2_ws_info_list_create_with_dep_engine( + const axutil_env_t * env, + struct axis2_dep_engine *dep_engine) +{ + axis2_ws_info_list_t *ws_info_list = NULL; + + ws_info_list = (axis2_ws_info_list_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_ws_info_list_t)); + + if(!ws_info_list) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)ws_info_list, 0, sizeof(axis2_ws_info_list_t)); + + ws_info_list->dep_engine = dep_engine; + + ws_info_list->ws_info_list = axutil_array_list_create(env, 0); + if(!(ws_info_list->ws_info_list)) + { + axis2_ws_info_list_free(ws_info_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + ws_info_list->current_info_list = axutil_array_list_create(env, 0); + if(!(ws_info_list->current_info_list)) + { + axis2_ws_info_list_free(ws_info_list, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return ws_info_list; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_ws_info_list_free( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env) +{ + if(ws_info_list->current_info_list) + { + int list_size = 0; + int i = 0; + + list_size = axutil_array_list_size(ws_info_list->current_info_list, env); + for(i = 0; i < list_size; i++) + { + axis2_char_t *file_name = NULL; + + file_name = (axis2_char_t *)axutil_array_list_get(ws_info_list->current_info_list, env, + i); + AXIS2_FREE(env->allocator, file_name); + } + axutil_array_list_free(ws_info_list->current_info_list, env); + } + + if(ws_info_list->ws_info_list) + { + int list_size = 0; + int i = 0; + + list_size = axutil_array_list_size(ws_info_list->ws_info_list, env); + for(i = 0; i < list_size; i++) + { + axis2_ws_info_t *ws_info = NULL; + + ws_info = (axis2_ws_info_t *)axutil_array_list_get(ws_info_list-> ws_info_list, env, i); + axis2_ws_info_free(ws_info, env); + } + axutil_array_list_free(ws_info_list->ws_info_list, env); + } + + if(ws_info_list) + { + AXIS2_FREE(env->allocator, ws_info_list); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ws_info_list_init( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env) +{ + int size = 0; + int i = 0; + + size = axutil_array_list_size(ws_info_list->ws_info_list, env); + for(i = 0; i < size; i++) + { + axis2_ws_info_t *ws_info = NULL; + + ws_info = (axis2_ws_info_t *)axutil_array_list_get(ws_info_list->ws_info_list, env, i); + axis2_ws_info_free(ws_info, env); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ws_info_list_add_ws_info_item( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env, + axutil_file_t * file, + int type) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *file_name = NULL; + axis2_char_t *temp_name = NULL; + + AXIS2_PARAM_CHECK(env->error, file, AXIS2_FAILURE); + + temp_name = axutil_file_get_name(file, env); + file_name = axutil_strdup(env, temp_name); + if(!file_name) + { + return AXIS2_FAILURE; + } + + switch(type) + { + case AXIS2_SVC: + { + axis2_ws_info_t *ws_info = NULL; + long last_modified_date = 0; + axis2_arch_file_data_t *file_data = NULL; + + last_modified_date = (long)axutil_file_get_timestamp(file, env); + /* We are sure that the difference lies within the long range */ + ws_info = axis2_ws_info_create_with_file_name_and_last_modified_date_and_type(env, + file_name, last_modified_date, AXIS2_SVC); + status = axutil_array_list_add(ws_info_list->ws_info_list, env, ws_info); + + if(AXIS2_SUCCESS != status) + { + return status; + } + file_data = axis2_arch_file_data_create_with_type_and_file(env, AXIS2_SVC, file); + /* To inform that new web service is to be deployed */ + status = axis2_dep_engine_add_ws_to_deploy(ws_info_list->dep_engine, env, file_data); + if(AXIS2_SUCCESS != status) + { + return status; + } + break; + } + case AXIS2_MODULE: + { + axis2_ws_info_t *ws_info = NULL; + long last_modified_date = 0; + axis2_arch_file_data_t *file_data = NULL; + + last_modified_date = (long)axutil_file_get_timestamp(file, env); + /* We are sure that the difference lies within the long range */ + ws_info = axis2_ws_info_create_with_file_name_and_last_modified_date_and_type(env, + file_name, last_modified_date, AXIS2_MODULE); + status = axutil_array_list_add(ws_info_list->ws_info_list, env, ws_info); + + if(AXIS2_SUCCESS != status) + { + return status; + } + file_data = axis2_arch_file_data_create_with_type_and_file(env, AXIS2_MODULE, file); + /* To inform that new module is to be deployed */ + status = axis2_dep_engine_add_ws_to_deploy(ws_info_list->dep_engine, env, file_data); + if(AXIS2_SUCCESS != status) + { + return status; + } + + break; + } + } + return axutil_array_list_add(ws_info_list->current_info_list, env, file_name); +} + +AXIS2_EXTERN axis2_ws_info_t *AXIS2_CALL +axis2_ws_info_list_get_file_item( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env, + axis2_char_t * file_name) +{ + int i = 0; + int size = 0; + AXIS2_PARAM_CHECK(env->error, file_name, NULL); + + size = axutil_array_list_size(ws_info_list->ws_info_list, env); + for(i = 0; i < size; i++) + { + axis2_ws_info_t *ws_info = NULL; + axis2_char_t *file_name_l = NULL; + + ws_info = (axis2_ws_info_t *)axutil_array_list_get(ws_info_list-> ws_info_list, env, i); + + file_name_l = axis2_ws_info_get_file_name(ws_info, env); + if(!axutil_strcmp(file_name_l, file_name)) + { + return ws_info; + } + } + return NULL; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_ws_info_list_is_modified( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env, + axutil_file_t * file, + axis2_ws_info_t * ws_info) +{ + long last_modified_date = 0; + + AXIS2_PARAM_CHECK(env->error, file, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, ws_info, AXIS2_FAILURE); + + last_modified_date = axis2_ws_info_get_last_modified_date(ws_info, env); + return (last_modified_date != axutil_file_get_timestamp(file, env)); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_ws_info_list_is_file_exist( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env, + axis2_char_t * file_name) +{ + axis2_ws_info_t *ws_info = NULL; + + AXIS2_PARAM_CHECK(env->error, file_name, AXIS2_FAILURE); + ws_info = axis2_ws_info_list_get_file_item(ws_info_list, env, file_name); + return !(ws_info == NULL); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ws_info_list_check_for_undeploy( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env) +{ + int list_size = 0; + axutil_array_list_t *temp_list = NULL; + int i = 0; + + /* Create temp list */ + temp_list = axutil_array_list_create(env, 0); + if(!temp_list) + { + return AXIS2_FAILURE; + } + list_size = axutil_array_list_size(ws_info_list->ws_info_list, env); + + for(i = 0; i < list_size; i++) + { + /* For each ws_info item in the ws_info_list check whether it is also + * in the current_info_list. If not mark it to be undeployed by adding + * it to a temporarily list. Also add that item to the undeploy list of + * deployment engine.*/ + int current_lists_size = 0; + axis2_ws_info_t *file_item = NULL; + axis2_char_t *file_item_name = NULL; + axis2_bool_t exist = AXIS2_FALSE; + int j = 0; + + file_item = (axis2_ws_info_t *)axutil_array_list_get(ws_info_list-> ws_info_list, env, i); + + file_item_name = axis2_ws_info_get_file_name(file_item, env); + current_lists_size = axutil_array_list_size(ws_info_list->current_info_list, env); + for(j = 0; j < current_lists_size; j++) + { + axis2_char_t *file_name = NULL; + file_name = (axis2_char_t *)axutil_array_list_get(ws_info_list-> current_info_list, + env, j); + if(!axutil_strcmp(file_name, file_item_name)) + { + exist = AXIS2_TRUE; + break; + } + } + + if(!exist) + { + axis2_ws_info_t *ws_info = NULL; + long last_modified_date = 0; + + last_modified_date = axis2_ws_info_get_last_modified_date(file_item, env); + axutil_array_list_add(temp_list, env, file_item); + ws_info = axis2_ws_info_create_with_file_name_and_last_modified_date(env, + file_item_name, last_modified_date); + /* This ws_info is to be undeployed */ + axis2_dep_engine_add_ws_to_undeploy(ws_info_list->dep_engine, env, ws_info); + } + + } + + list_size = axutil_array_list_size(temp_list, env); + for(i = 0; i < list_size; i++) + { + /* Get each ws_info item from the temp list created and remove that + * item from the ws_info_list */ + axis2_ws_info_t *file_item = NULL; + int index = 0; + + file_item = (axis2_ws_info_t *)axutil_array_list_get(temp_list, env, i); + index = axutil_array_list_index_of(ws_info_list->ws_info_list, env, file_item); + axutil_array_list_remove(ws_info_list->ws_info_list, env, index); + } + axutil_array_list_free(temp_list, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ws_info_list_update( + axis2_ws_info_list_t * ws_info_list, + const axutil_env_t * env) +{ + axis2_status_t status = AXIS2_FAILURE; + + status = axis2_ws_info_list_check_for_undeploy(ws_info_list, env); + if(AXIS2_SUCCESS != status) + { + return AXIS2_FAILURE; + } + + return axis2_dep_engine_do_deploy(ws_info_list->dep_engine, env); +} + diff --git a/src/core/description/Makefile.am b/src/core/description/Makefile.am new file mode 100644 index 0000000..5c3618c --- /dev/null +++ b/src/core/description/Makefile.am @@ -0,0 +1,24 @@ +noinst_LTLIBRARIES = libaxis2_description.la + +libaxis2_description_la_SOURCES =desc.c \ + op.c \ + policy_include.c \ + svc.c \ + module_desc.c \ + svc_grp.c \ + phase_rule.c \ + handler_desc.c \ + flow.c \ + flow_container.c \ + transport_in_desc.c \ + transport_out_desc.c \ + msg.c + +libaxis2_description_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include \ + -I$(top_builddir)/neethi/include + diff --git a/src/core/description/desc.c b/src/core/description/desc.c new file mode 100644 index 0000000..bd5a80a --- /dev/null +++ b/src/core/description/desc.c @@ -0,0 +1,261 @@ +/* + * 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_desc.h> +#include <axutil_property.h> +#include <axis2_policy_include.h> +#include <axis2_msg.h> + +struct axis2_desc +{ + + /** parameter container */ + axutil_param_container_t *param_container; + + /** children of this description */ + axutil_hash_t *children; + + axis2_desc_t *parent; + + axis2_policy_include_t *policy_include; +}; + +AXIS2_EXTERN axis2_desc_t *AXIS2_CALL +axis2_desc_create( + const axutil_env_t * env) +{ + axis2_desc_t *desc = NULL; + + desc = (axis2_desc_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_desc_t)); + + if(!desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + desc->param_container = NULL; + desc->children = NULL; + desc->parent = NULL; + desc->policy_include = NULL; + + desc->param_container = (axutil_param_container_t *)axutil_param_container_create(env); + if(!(desc->param_container)) + { + axis2_desc_free(desc, env); + return NULL; + } + + desc->children = axutil_hash_make(env); + if(!(desc->children)) + { + axis2_desc_free(desc, env); + return NULL; + } + + desc->policy_include = axis2_policy_include_create_with_desc(env, desc); + + return desc; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_desc_free( + axis2_desc_t * desc, + const axutil_env_t * env) +{ + if(desc->children) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + for(hi = axutil_hash_first(desc->children, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axis2_msg_free((axis2_msg_t *)val, env); + } + } + + axutil_hash_free(desc->children, env); + } + + if(desc->param_container) + { + axutil_param_container_free(desc->param_container, env); + } + + if(desc->policy_include) + { + axis2_policy_include_free(desc->policy_include, env); + } + + if(desc) + { + AXIS2_FREE(env->allocator, desc); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_add_param( + axis2_desc_t * desc, + const axutil_env_t * env, + axutil_param_t * param) +{ + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FALSE); + + return axutil_param_container_add_param(desc->param_container, env, param); +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_desc_get_param( + const axis2_desc_t * desc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + AXIS2_PARAM_CHECK(env->error, param_name, NULL); + return axutil_param_container_get_param(desc->param_container, env, param_name); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_desc_get_all_params( + const axis2_desc_t * desc, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, desc->param_container, AXIS2_FALSE); + + return axutil_param_container_get_params(desc->param_container, env); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_desc_is_param_locked( + const axis2_desc_t * desc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + axutil_param_t *param_l = NULL; + + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FALSE); + + param_l = axis2_desc_get_param(desc, env, param_name); + + return (param_l && axutil_param_is_locked(param_l, env)); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_add_child( + const axis2_desc_t * desc, + const axutil_env_t * env, + const axis2_char_t * key, + const axis2_msg_t *child) +{ + if(desc->children) + { + axis2_msg_t* msg = (axis2_msg_t *)axutil_hash_get(desc->children, key, + AXIS2_HASH_KEY_STRING); + if(msg != NULL) + { + axis2_msg_free(msg, env); + msg = NULL; + } + axutil_hash_set(desc->children, key, AXIS2_HASH_KEY_STRING, (void *)child); + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_desc_get_all_children( + const axis2_desc_t * desc, + const axutil_env_t * env) +{ + return desc->children; +} + +AXIS2_EXTERN void *AXIS2_CALL +axis2_desc_get_child( + const axis2_desc_t * desc, + const axutil_env_t * env, + const axis2_char_t * key) +{ + return axutil_hash_get(desc->children, key, AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_remove_child( + const axis2_desc_t * desc, + const axutil_env_t * env, + const axis2_char_t * key) +{ + if(desc->children) + { + axutil_hash_set(desc->children, key, AXIS2_HASH_KEY_STRING, NULL); + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_desc_t *AXIS2_CALL +axis2_desc_get_parent( + const axis2_desc_t * desc, + const axutil_env_t * env) +{ + return desc->parent; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_set_parent( + axis2_desc_t * desc, + const axutil_env_t * env, + axis2_desc_t * parent) +{ + desc->parent = parent; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_desc_set_policy_include( + axis2_desc_t * desc, + const axutil_env_t * env, + axis2_policy_include_t * policy_include) +{ + if(desc->policy_include) + { + axis2_policy_include_free(desc->policy_include, env); + desc->policy_include = NULL; + } + + desc->policy_include = policy_include; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_policy_include_t *AXIS2_CALL +axis2_desc_get_policy_include( + axis2_desc_t * desc, + const axutil_env_t * env) +{ + if(!desc->policy_include) + { + /*desc->policy_include = axis2_policy_include_create(env); */ + desc->policy_include = axis2_policy_include_create_with_desc(env, desc); + } + return desc->policy_include; +} + diff --git a/src/core/description/flow.c b/src/core/description/flow.c new file mode 100644 index 0000000..554d666 --- /dev/null +++ b/src/core/description/flow.c @@ -0,0 +1,130 @@ +/* + * 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_flow.h> + +struct axis2_flow +{ + axutil_array_list_t *list; +}; + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_flow_create( + const axutil_env_t * env) +{ + axis2_flow_t *flow = NULL; + + flow = (axis2_flow_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_flow_t)); + + if(!flow) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + flow->list = NULL; + + flow->list = axutil_array_list_create(env, 20); + if(!(flow->list)) + { + axis2_flow_free(flow, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return flow; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_flow_free( + axis2_flow_t * flow, + const axutil_env_t * env) +{ + if(flow->list) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(flow->list, env); + for(i = 0; i < size; i++) + { + axis2_handler_desc_t *handler_desc = NULL; + + handler_desc = (axis2_handler_desc_t *)axutil_array_list_get(flow->list, env, i); + axis2_handler_desc_free(handler_desc, env); + } + axutil_array_list_free(flow->list, env); + } + + if(flow) + { + AXIS2_FREE(env->allocator, flow); + } + + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_flow_free_void_arg( + void *flow, + const axutil_env_t * env) +{ + axis2_flow_t *flow_l = NULL; + + flow_l = (axis2_flow_t *)flow; + axis2_flow_free(flow_l, env); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_flow_add_handler( + axis2_flow_t * flow, + const axutil_env_t * env, + axis2_handler_desc_t * handler) +{ + AXIS2_PARAM_CHECK(env->error, handler, AXIS2_FAILURE); + + if(!flow->list) + { + flow->list = axutil_array_list_create(env, 0); + if(!flow->list) + { + axis2_flow_free(flow, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + return axutil_array_list_add(flow->list, env, handler); +} + +AXIS2_EXTERN axis2_handler_desc_t *AXIS2_CALL +axis2_flow_get_handler( + const axis2_flow_t * flow, + const axutil_env_t * env, + const int index) +{ + return axutil_array_list_get(flow->list, env, index); +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_flow_get_handler_count( + const axis2_flow_t * flow, + const axutil_env_t * env) +{ + return axutil_array_list_size(flow->list, env); +} + diff --git a/src/core/description/flow_container.c b/src/core/description/flow_container.c new file mode 100644 index 0000000..e39be01 --- /dev/null +++ b/src/core/description/flow_container.c @@ -0,0 +1,173 @@ +/* + * 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_flow.h> +#include <axis2_flow_container.h> + +struct axis2_flow_container +{ + axis2_flow_t *in; + axis2_flow_t *out; + axis2_flow_t *in_fault; + axis2_flow_t *out_fault; +}; + +AXIS2_EXTERN axis2_flow_container_t *AXIS2_CALL +axis2_flow_container_create( + const axutil_env_t * env) +{ + axis2_flow_container_t *flow_container = NULL; + + flow_container = (axis2_flow_container_t *)AXIS2_MALLOC(env-> allocator, + sizeof(axis2_flow_container_t)); + + if(!flow_container) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + flow_container->in = NULL; + flow_container->out = NULL; + flow_container->in_fault = NULL; + flow_container->out_fault = NULL; + + return flow_container; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_flow_container_free( + axis2_flow_container_t * flow_container, + const axutil_env_t * env) +{ + if(flow_container->in) + { + axis2_flow_free(flow_container->in, env); + } + + if(flow_container->out) + { + axis2_flow_free(flow_container->out, env); + } + + if(flow_container->in_fault) + { + axis2_flow_free(flow_container->in_fault, env); + } + + if(flow_container->out_fault) + { + axis2_flow_free(flow_container->out_fault, env); + } + + if(flow_container) + { + AXIS2_FREE(env->allocator, flow_container); + } + + return; +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_flow_container_get_in_flow( + const axis2_flow_container_t * flow_container, + const axutil_env_t * env) +{ + return flow_container->in; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_flow_container_set_in_flow( + axis2_flow_container_t * flow_container, + const axutil_env_t * env, + axis2_flow_t * in_flow) +{ + if(flow_container->in) + { + axis2_flow_free(flow_container->in, env); + } + flow_container->in = in_flow; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_flow_container_get_out_flow( + const axis2_flow_container_t * flow_container, + const axutil_env_t * env) +{ + return flow_container->out; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_flow_container_set_out_flow( + axis2_flow_container_t * flow_container, + const axutil_env_t * env, + axis2_flow_t * out_flow) +{ + if(flow_container->out) + { + axis2_flow_free(flow_container->out, env); + } + flow_container->out = out_flow; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_flow_container_get_fault_in_flow( + const axis2_flow_container_t * flow_container, + const axutil_env_t * env) +{ + return flow_container->in_fault; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_flow_container_set_fault_in_flow( + axis2_flow_container_t * flow_container, + const axutil_env_t * env, + axis2_flow_t * falut_in_flow) +{ + if(flow_container->in_fault) + { + axis2_flow_free(flow_container->in_fault, env); + } + flow_container->in_fault = falut_in_flow; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_flow_container_get_fault_out_flow( + const axis2_flow_container_t * flow_container, + const axutil_env_t * env) +{ + return flow_container->out_fault; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_flow_container_set_fault_out_flow( + axis2_flow_container_t * flow_container, + const axutil_env_t * env, + axis2_flow_t * fault_out_flow) +{ + AXIS2_PARAM_CHECK(env->error, fault_out_flow, AXIS2_FAILURE); + if(flow_container->out_fault) + { + axis2_flow_free(flow_container->out_fault, env); + } + flow_container->out_fault = fault_out_flow; + return AXIS2_SUCCESS; +} + diff --git a/src/core/description/handler_desc.c b/src/core/description/handler_desc.c new file mode 100644 index 0000000..c3281f5 --- /dev/null +++ b/src/core/description/handler_desc.c @@ -0,0 +1,333 @@ +/* + * 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_handler_desc.h> +#include <axutil_param_container.h> +#include <axutil_string.h> +#include <axis2_handler.h> + +struct axis2_handler_desc +{ + + /** name */ + axutil_string_t *name; + + /** phase rules */ + axis2_phase_rule_t *rules; + + /** handler represented by meta information*/ + axis2_handler_t *handler; + + /** class name */ + axis2_char_t *class_name; + + /** parent param container */ + axutil_param_container_t *parent; + + /** parameter container */ + axutil_param_container_t *param_container; +}; + +AXIS2_EXTERN axis2_handler_desc_t *AXIS2_CALL +axis2_handler_desc_create( + const axutil_env_t * env, + axutil_string_t * name) +{ + axis2_handler_desc_t *handler_desc = NULL; + + handler_desc = AXIS2_MALLOC(env->allocator, sizeof(axis2_handler_desc_t)); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + handler_desc->param_container = NULL; + handler_desc->name = NULL; + handler_desc->rules = NULL; + handler_desc->handler = NULL; + handler_desc->class_name = NULL; + handler_desc->parent = NULL; + + handler_desc->param_container = axutil_param_container_create(env); + if(!handler_desc->param_container) + { + + /** error code is already set by last param container create */ + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + + handler_desc->rules = axis2_phase_rule_create(env, NULL); + if(!handler_desc->rules) + { + + /** error code is already set by last param container create */ + axis2_handler_desc_free(handler_desc, env); + return NULL; + } + + if(name) + { + handler_desc->name = axutil_string_clone(name, env); + } + + return handler_desc; +} + +AXIS2_EXTERN const axutil_string_t *AXIS2_CALL +axis2_handler_desc_get_name( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env) +{ + return handler_desc->name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_desc_set_name( + axis2_handler_desc_t * handler_desc, + const axutil_env_t * env, + axutil_string_t * name) +{ + if(handler_desc->name) + { + axutil_string_free(handler_desc->name, env); + handler_desc->name = NULL; + } + + if(name) + { + handler_desc->name = axutil_string_clone(name, env); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_phase_rule_t *AXIS2_CALL +axis2_handler_desc_get_rules( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env) +{ + return handler_desc->rules; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_desc_set_rules( + axis2_handler_desc_t * handler_desc, + const axutil_env_t * env, + axis2_phase_rule_t * phase_rule) +{ + const axutil_string_t *str_name = axis2_handler_desc_get_name(handler_desc, env); + const axis2_char_t *name = axutil_string_get_buffer(str_name, env); + if(handler_desc->rules) + { + axis2_phase_rule_free(handler_desc->rules, env); + } + + if(phase_rule) + { + handler_desc->rules = axis2_phase_rule_clone(phase_rule, env); + if(!(handler_desc->rules)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Phase rule cloning failed for handler description %s", name); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_handler_desc_get_param( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env, + const axis2_char_t * name) +{ + return axutil_param_container_get_param(handler_desc->param_container, env, name); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_desc_add_param( + axis2_handler_desc_t * handler_desc, + const axutil_env_t * env, + axutil_param_t * param) +{ + const axutil_string_t *str_name = axis2_handler_desc_get_name(handler_desc, env); + const axis2_char_t *name = axutil_string_get_buffer(str_name, env); + axis2_char_t *param_name = axutil_param_get_name(param, env); + if(axutil_param_container_is_param_locked(handler_desc->parent, env, param_name)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PARAMETER_LOCKED_CANNOT_OVERRIDE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Parameter %s is locked for handler %s", + param_name, name); + return AXIS2_FAILURE; + } + + return axutil_param_container_add_param(handler_desc->param_container, env, param); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_handler_desc_get_all_params( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env) +{ + return axutil_param_container_get_params(handler_desc->param_container, env); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_handler_desc_is_param_locked( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + /* See if it is locked in parent */ + if(axutil_param_container_is_param_locked(handler_desc->parent, env, param_name)) + { + return AXIS2_TRUE; + } + + return axutil_param_container_is_param_locked(handler_desc->param_container, env, param_name); +} + +AXIS2_EXTERN axis2_handler_t *AXIS2_CALL +axis2_handler_desc_get_handler( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env) +{ + return handler_desc->handler; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_desc_set_handler( + axis2_handler_desc_t * handler_desc, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + /* Handler description is the place where the handler really lives. + Hence this is a deep copy and should be freed by the free function. */ + + if(handler_desc->handler && (handler_desc->handler != handler)) + { + axis2_handler_free(handler_desc->handler, env); + } + + if(handler) + handler_desc->handler = handler; /* Shallow copy, but free method + should free this */ + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_handler_desc_get_class_name( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env) +{ + return handler_desc->class_name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_desc_set_class_name( + axis2_handler_desc_t * handler_desc, + const axutil_env_t * env, + const axis2_char_t * class_name) +{ + if(handler_desc->class_name) + { + AXIS2_FREE(env->allocator, handler_desc->class_name); + } + + if(class_name) + { + handler_desc->class_name = axutil_strdup(env, class_name); + if(!handler_desc->class_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_handler_desc_get_parent( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env) +{ + return handler_desc->parent; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_desc_set_parent( + axis2_handler_desc_t * handler_desc, + const axutil_env_t * env, + axutil_param_container_t * parent) +{ + handler_desc->parent = parent; /* Shallow copy, because + the parent lives somewhere else */ + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_handler_desc_free( + axis2_handler_desc_t * handler_desc, + const axutil_env_t * env) +{ + if(handler_desc->param_container) + { + axutil_param_container_free(handler_desc->param_container, env); + } + + if(handler_desc->name) + { + axutil_string_free(handler_desc->name, env); + } + + if(handler_desc->rules) + { + axis2_phase_rule_free(handler_desc->rules, env); + } + + if(handler_desc->handler) + { + axis2_handler_free(handler_desc->handler, env); + } + + if(handler_desc->class_name) + { + AXIS2_FREE(env->allocator, handler_desc->class_name); + } + if(handler_desc) + { + AXIS2_FREE(env->allocator, handler_desc); + } + + return; +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_handler_desc_get_param_container( + const axis2_handler_desc_t * handler_desc, + const axutil_env_t * env) +{ + return handler_desc->param_container; +} + diff --git a/src/core/description/module_desc.c b/src/core/description/module_desc.c new file mode 100644 index 0000000..a5b27c7 --- /dev/null +++ b/src/core/description/module_desc.c @@ -0,0 +1,470 @@ +/* + * 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_module_desc.h> +#include <axis2_module.h> + +struct axis2_module_desc +{ + axis2_module_t *module; + axutil_qname_t *qname; + axis2_conf_t *parent; + + /** + * To store module operations , which are supposed to be added to a service + * the module is engaged to a service + */ + axutil_hash_t *ops; + + /** + * flow container that encapsulates the flows associated with the + * module + */ + axis2_flow_container_t *flow_container; + + /** + * parameter container that stores all the parameters associated with + * the module + */ + axutil_param_container_t *params; +}; + +AXIS2_EXTERN axis2_module_desc_t *AXIS2_CALL +axis2_module_desc_create( + const axutil_env_t * env) +{ + axis2_module_desc_t *module_desc = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + module_desc = (axis2_module_desc_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_module_desc_t)); + + if(!module_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + module_desc->qname = NULL; + module_desc->module = NULL; + module_desc->parent = NULL; + module_desc->params = NULL; + module_desc->flow_container = NULL; + module_desc->ops = NULL; + + module_desc->params = axutil_param_container_create(env); + if(!module_desc->params) + { + axis2_module_desc_free(module_desc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + module_desc->flow_container = axis2_flow_container_create(env); + if(!module_desc->flow_container) + { + axis2_module_desc_free(module_desc, env); +AXIS2_ERROR_SET (env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE) + return NULL; +} + +module_desc->ops = axutil_hash_make(env); +if (!module_desc->ops) +{ + axis2_module_desc_free(module_desc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; +} + +return module_desc; +} + +AXIS2_EXTERN axis2_module_desc_t *AXIS2_CALL +axis2_module_desc_create_with_qname( + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + axis2_module_desc_t *module_desc = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, qname, NULL); + + module_desc = axis2_module_desc_create(env); + if(!module_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + module_desc->qname = (axutil_qname_t *)qname; + + return module_desc; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_module_desc_free( + axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(module_desc->module) + { + axis2_module_shutdown(module_desc->module, env); + } + + if(module_desc->params) + { + axutil_param_container_free(module_desc->params, env); + } + + if(module_desc->flow_container) + { + axis2_flow_container_free(module_desc->flow_container, env); + } + + module_desc->parent = NULL; + + if(module_desc->qname) + { + axutil_qname_free(module_desc->qname, env); + } + + if(module_desc->ops) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(module_desc->ops, env); hi; hi = axutil_hash_next(env, hi)) + { + struct axis2_op *op = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + op = (struct axis2_op *)val; + if(op) + axis2_op_free(op, env); + val = NULL; + op = NULL; + + } + axutil_hash_free(module_desc->ops, env); + } + + if(module_desc) + { + AXIS2_FREE(env->allocator, module_desc); + } + + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_module_desc_free_void_arg( + void *module_desc, + const axutil_env_t * env) +{ + axis2_module_desc_t *module_desc_l = NULL; + + AXIS2_ENV_CHECK(env, void); + module_desc_l = (axis2_module_desc_t *)module_desc; + axis2_module_desc_free(module_desc_l, env); + return; +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_module_desc_get_in_flow( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return axis2_flow_container_get_in_flow(module_desc->flow_container, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_set_in_flow( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + axis2_flow_t * in_flow) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, in_flow, AXIS2_FAILURE); + + return axis2_flow_container_set_in_flow(module_desc->flow_container, env, in_flow); +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_module_desc_get_out_flow( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return axis2_flow_container_get_out_flow(module_desc->flow_container, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_set_out_flow( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + axis2_flow_t * out_flow) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, out_flow, AXIS2_FAILURE); + + return axis2_flow_container_set_out_flow(module_desc->flow_container, env, out_flow); +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_module_desc_get_fault_in_flow( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return axis2_flow_container_get_fault_in_flow(module_desc->flow_container, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_set_fault_in_flow( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + axis2_flow_t * falut_in_flow) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, falut_in_flow, AXIS2_FAILURE); + + return axis2_flow_container_set_fault_in_flow(module_desc->flow_container, env, falut_in_flow); +} + +AXIS2_EXTERN axis2_flow_t *AXIS2_CALL +axis2_module_desc_get_fault_out_flow( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return axis2_flow_container_get_fault_out_flow(module_desc->flow_container, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_set_fault_out_flow( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + axis2_flow_t * fault_out_flow) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, fault_out_flow, AXIS2_FAILURE); + + return axis2_flow_container_set_fault_out_flow(module_desc->flow_container, env, fault_out_flow); +} + +AXIS2_EXTERN const axutil_qname_t *AXIS2_CALL +axis2_module_desc_get_qname( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return module_desc->qname; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_set_qname( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, qname, AXIS2_FAILURE); + + if(module_desc->qname) + { + axutil_qname_free(module_desc->qname, env); + } + + module_desc->qname = axutil_qname_clone((axutil_qname_t *)qname, env); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_add_op( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + axis2_op_t * op) +{ + const axutil_qname_t *op_qname = NULL; + axis2_char_t *op_name = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, op, AXIS2_FAILURE); + + if(!(module_desc->ops)) + { + module_desc->ops = axutil_hash_make(env); + if(!module_desc->ops) + return AXIS2_FAILURE; + } + + op_qname = axis2_op_get_qname(op, env); + + if(!op_qname) + { + return AXIS2_FAILURE; + } + op_name = axutil_qname_to_string((axutil_qname_t *)op_qname, env); + axutil_hash_set(module_desc->ops, op_name, AXIS2_HASH_KEY_STRING, op); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_module_desc_get_all_ops( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return module_desc->ops; +} + +AXIS2_EXTERN axis2_conf_t *AXIS2_CALL +axis2_module_desc_get_parent( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return module_desc->parent; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_set_parent( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + axis2_conf_t * parent) +{ + AXIS2_PARAM_CHECK(env->error, parent, AXIS2_FAILURE); + + module_desc->parent = parent; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_add_param( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + axutil_param_t * param) +{ + axis2_char_t *param_name_l = NULL; + axis2_status_t ret_status = AXIS2_FAILURE; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + param_name_l = axutil_param_get_name(param, env); + if(!param_name_l) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_PARAM, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(AXIS2_TRUE == axis2_module_desc_is_param_locked(module_desc, env, param_name_l)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PARAMETER_LOCKED_CANNOT_OVERRIDE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + else + { + ret_status = axutil_param_container_add_param(module_desc->params, env, param); + } + return ret_status; +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_module_desc_get_param( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env, + const axis2_char_t * name) +{ + AXIS2_PARAM_CHECK(env->error, name, NULL); + + return axutil_param_container_get_param(module_desc->params, env, name); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_module_desc_get_all_params( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return axutil_param_container_get_params(module_desc->params, env); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_module_desc_is_param_locked( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + axis2_bool_t locked = AXIS2_FALSE; + axis2_bool_t ret_state = AXIS2_FALSE; + axutil_param_t *param_l = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FAILURE); + + /* checking the locked value of parent */ + if(!module_desc->parent) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_MODULE_DESC, AXIS2_FAILURE); + return AXIS2_FALSE; + } + locked = axis2_conf_is_param_locked(module_desc->parent, env, param_name); + + if(AXIS2_TRUE == locked) + { + ret_state = AXIS2_TRUE; + } + else + { + param_l = axis2_module_desc_get_param(module_desc, env, param_name); + if(param_l && AXIS2_TRUE == axutil_param_is_locked(param_l, env)) + ret_state = AXIS2_TRUE; + else + ret_state = AXIS2_FALSE; + + } + return ret_state; +} + +AXIS2_EXTERN axis2_module_t *AXIS2_CALL +axis2_module_desc_get_module( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return module_desc->module; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_module_desc_set_module( + axis2_module_desc_t * module_desc, + const axutil_env_t * env, + axis2_module_t * module) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module, AXIS2_FAILURE); + module_desc->module = module; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_module_desc_get_param_container( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return module_desc->params; +} + +AXIS2_EXTERN axis2_flow_container_t *AXIS2_CALL +axis2_module_desc_get_flow_container( + const axis2_module_desc_t * module_desc, + const axutil_env_t * env) +{ + return module_desc->flow_container; +} diff --git a/src/core/description/msg.c b/src/core/description/msg.c new file mode 100644 index 0000000..241253a --- /dev/null +++ b/src/core/description/msg.c @@ -0,0 +1,407 @@ +/* + * 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_msg.h> +#include <axutil_property.h> + +struct axis2_msg +{ + + /** parent operation */ + axis2_op_t *parent; + + /** list of phases that represent the flow */ + axutil_array_list_t *flow; + + /** name of the message */ + axis2_char_t *name; + + /** XML schema element qname */ + axutil_qname_t *element_qname; + + /** direction of message */ + axis2_char_t *direction; + + /** parameter container to hold message parameters */ + struct axutil_param_container *param_container; + + /** base description struct */ + axis2_desc_t *base; + + /** reference count of this object*/ + int ref; + +}; + +AXIS2_EXTERN axis2_msg_t *AXIS2_CALL +axis2_msg_create( + const axutil_env_t * env) +{ + axis2_msg_t *msg = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + msg = (axis2_msg_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_msg_t)); + + if(!msg) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + msg->param_container = NULL; + msg->parent = NULL; + msg->flow = NULL; + msg->name = NULL; + msg->element_qname = NULL; + msg->direction = NULL; + msg->base = NULL; + msg->ref = 1; + + msg->param_container = (axutil_param_container_t *)axutil_param_container_create(env); + if(!msg->param_container) + { + axis2_msg_free(msg, env); + return NULL; + } + + msg->flow = axutil_array_list_create(env, 0); + if(!msg->flow) + { + axis2_msg_free(msg, env); + return NULL; + } + + msg->base = axis2_desc_create(env); + if(!msg->base) + { + axis2_msg_free(msg, env); + return NULL; + } + + return msg; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_msg_free( + axis2_msg_t * msg, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(--(msg->ref) > 0) + { + return; + } + + if(msg->flow) + { + int i = 0, size = 0; + size = axutil_array_list_size(msg->flow, env); + for(i = 0; i < size; i++) + { + axis2_phase_t *phase = NULL; + phase = axutil_array_list_get(msg->flow, env, i); + if(phase) + axis2_phase_free(phase, env); + } + axutil_array_list_free(msg->flow, env); + } + + if(msg->name) + { + AXIS2_FREE(env->allocator, msg->name); + } + + if(msg->element_qname) + { + axutil_qname_free(msg->element_qname, env); + } + + if(msg->direction) + { + AXIS2_FREE(env->allocator, msg->direction); + } + + if(msg->param_container) + { + axutil_param_container_free(msg->param_container, env); + } + + if(msg->base) + { + axis2_desc_free(msg->base, env); + } + + msg->parent = NULL; + + if(msg) + { + AXIS2_FREE(env->allocator, msg); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_add_param( + axis2_msg_t * msg, + const axutil_env_t * env, + axutil_param_t * param) +{ + axis2_char_t *param_name = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FALSE); + + param_name = axutil_param_get_name(param, env); + if(AXIS2_TRUE == axis2_msg_is_param_locked(msg, env, param_name)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PARAMETER_LOCKED_CANNOT_OVERRIDE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return axutil_param_container_add_param(msg->param_container, env, param); +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_msg_get_param( + const axis2_msg_t * msg, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + AXIS2_PARAM_CHECK(env->error, param_name, NULL); + + return axutil_param_container_get_param(msg->param_container, env, param_name); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_get_all_params( + const axis2_msg_t * msg, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, msg->param_container, AXIS2_FALSE); + + return axutil_param_container_get_params(msg->param_container, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_set_parent( + axis2_msg_t * msg, + const axutil_env_t * env, + axis2_op_t * op) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + msg->parent = op; + if(op) + { + axis2_desc_set_parent(msg->base, env, axis2_op_get_base(op, env)); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_msg_get_parent( + const axis2_msg_t * msg, + const axutil_env_t * env) +{ + return msg->parent; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_msg_get_flow( + const axis2_msg_t * msg, + const axutil_env_t * env) +{ + return msg->flow; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_msg_is_param_locked( + axis2_msg_t * msg, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + axis2_op_t *parent_l = NULL; + axutil_param_t *param_l = NULL; + axis2_bool_t locked = AXIS2_FALSE; + + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FALSE); + + /* checking the locked status in parent */ + parent_l = axis2_msg_get_parent(msg, env); + if(parent_l) + { + locked = axis2_op_is_param_locked(parent_l, env, param_name); + } + if(AXIS2_TRUE == locked) + { + return AXIS2_TRUE; + } + else + { + param_l = axis2_msg_get_param(msg, env, param_name); + } + return (param_l && axutil_param_is_locked(param_l, env)); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_set_flow( + axis2_msg_t * msg, + const axutil_env_t * env, + axutil_array_list_t * flow) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(msg->flow) + { + axutil_array_list_free(msg->flow, env); + msg->flow = NULL; + } + if(flow) + { + msg->flow = flow; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_msg_get_direction( + const axis2_msg_t * msg, + const axutil_env_t * env) +{ + return msg->direction; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_set_direction( + axis2_msg_t * msg, + const axutil_env_t * env, + const axis2_char_t * direction) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(msg->direction) + { + AXIS2_FREE(env->allocator, msg->direction); + msg->direction = NULL; + } + + if(direction) + { + msg->direction = axutil_strdup(env, direction); + if(!(msg->direction)) + { + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axutil_qname_t *AXIS2_CALL +axis2_msg_get_element_qname( + const axis2_msg_t * msg, + const axutil_env_t * env) +{ + return msg->element_qname; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_set_element_qname( + axis2_msg_t * msg, + const axutil_env_t * env, + const axutil_qname_t * element_qname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(msg->element_qname) + { + axutil_qname_free(msg->element_qname, env); + msg->element_qname = NULL; + } + + if(element_qname) + { + msg->element_qname = axutil_qname_clone((axutil_qname_t *)element_qname, env); + if(!(msg->element_qname)) + { + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_msg_get_name( + const axis2_msg_t * msg, + const axutil_env_t * env) +{ + return msg->name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_set_name( + axis2_msg_t * msg, + const axutil_env_t * env, + const axis2_char_t * name) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(msg->name) + { + AXIS2_FREE(env->allocator, msg->name); + msg->name = NULL; + } + + if(name) + { + msg->name = axutil_strdup(env, name); + if(!(msg->name)) + { + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_desc_t *AXIS2_CALL +axis2_msg_get_base( + const axis2_msg_t * msg, + const axutil_env_t * env) +{ + return msg->base; +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_msg_get_param_container( + const axis2_msg_t * msg, + const axutil_env_t * env) +{ + return msg->param_container; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_msg_increment_ref( + axis2_msg_t * msg, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + msg->ref++; + return AXIS2_SUCCESS; +} diff --git a/src/core/description/op.c b/src/core/description/op.c new file mode 100644 index 0000000..0cf926c --- /dev/null +++ b/src/core/description/op.c @@ -0,0 +1,1383 @@ +/* + * 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_op.h> +#include <axutil_property.h> +#include <axis2_msg.h> +#include <axis2_desc.h> +#include <axis2_conf_ctx.h> +#include <axis2_module.h> + +struct axis2_op +{ + axis2_svc_t *parent; + axis2_desc_t *base; + axis2_msg_recv_t *msg_recv; + + int mep; + /* To store deploy time modules */ + axutil_array_list_t *module_qnames; + axutil_array_list_t *engaged_module_list; + axutil_array_list_t *wsamapping_list; + axis2_bool_t from_module; + axutil_qname_t *qname; + axis2_char_t *msg_exchange_pattern; + axis2_char_t *style; + + /* For REST support */ + axis2_char_t *rest_http_method; + axis2_char_t *rest_http_location; + + /** Parameter container to hold operation related parameters */ + struct axutil_param_container *param_container; +}; + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_op_create( + const axutil_env_t * env) +{ + axis2_op_t *op = NULL; + axis2_msg_t *msg = NULL; + + op = (axis2_op_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_op_t)); + + if(!op) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + return NULL; + } + + op->parent = NULL; + op->base = NULL; + op->msg_recv = NULL; + op->mep = AXIS2_MEP_CONSTANT_INVALID; + op->param_container = NULL; + op->module_qnames = axutil_array_list_create(env, 0); + op->engaged_module_list = NULL; + op->from_module = AXIS2_FALSE; + op->wsamapping_list = NULL; + op->qname = NULL; + op->msg_exchange_pattern = NULL; + op->style = NULL; + op->rest_http_method = NULL; + op->rest_http_location = NULL; + op->style = axutil_strdup(env, AXIS2_STYLE_DOC); + + op->param_container = (axutil_param_container_t *)axutil_param_container_create(env); + if(!op->param_container) + { + axis2_op_free(op, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Param container creation failed"); + return NULL; + } + + op->base = axis2_desc_create(env); + if(!op->base) + { + axis2_op_free(op, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Operation base creation failed"); + return NULL; + } + + /* Create and set up children messages */ + msg = axis2_msg_create(env); + if(!msg) + { + axis2_op_free(op, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Child message creation failed"); + return NULL; + } + axis2_msg_set_direction(msg, env, AXIS2_WSDL_MESSAGE_DIRECTION_IN); + axis2_msg_set_parent(msg, env, op); + axis2_op_add_msg(op, env, AXIS2_MSG_IN, msg); + + msg = axis2_msg_create(env); + if(!msg) + { + axis2_op_free(op, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Child message creation failed"); + return NULL; + } + axis2_msg_set_direction(msg, env, AXIS2_WSDL_MESSAGE_DIRECTION_OUT); + axis2_msg_set_parent(msg, env, op); + axis2_op_add_msg(op, env, AXIS2_MSG_OUT, msg); + + msg = axis2_msg_create(env); + if(!msg) + { + axis2_op_free(op, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Child message creation failed"); + return NULL; + } + axis2_msg_set_parent(msg, env, op); + axis2_msg_set_flow(msg, env, NULL); + axis2_op_add_msg(op, env, AXIS2_MSG_IN_FAULT, msg); + + msg = axis2_msg_create(env); + if(!msg) + { + axis2_op_free(op, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Child message creation failed"); + return NULL; + } + axis2_msg_set_parent(msg, env, op); + axis2_msg_set_flow(msg, env, NULL); + axis2_op_add_msg(op, env, AXIS2_MSG_OUT_FAULT, msg); + + axis2_op_set_msg_exchange_pattern(op, env, (axis2_char_t *)AXIS2_MEP_URI_IN_OUT); + + return op; +} + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_op_create_from_module( + const axutil_env_t * env) +{ + axis2_op_t *op = NULL; + + op = (axis2_op_t *)axis2_op_create(env); + op->from_module = AXIS2_TRUE; + return op; +} + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_op_create_with_qname( + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + axis2_op_t *op = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, qname, NULL); + + op = (axis2_op_t *)axis2_op_create(env); + + if(!op) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Operation creation failed for %s", + axutil_qname_get_localpart(qname, env)); + return NULL; + } + + status = axis2_op_set_qname(op, env, qname); + if(AXIS2_SUCCESS != status) + { + axis2_op_free(op, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting name failed for operation %s", + axutil_qname_get_localpart(qname, env)); + return NULL; + } + + return op; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_op_free( + axis2_op_t * op, + const axutil_env_t * env) +{ + if(op->base) + { + axis2_desc_free(op->base, env); + } + if(op->param_container) + { + axutil_param_container_free(op->param_container, env); + } + + op->parent = NULL; + + if(op->msg_recv) + { + axis2_msg_recv_free(op->msg_recv, env); + } + if(op->module_qnames) + { + int i = 0; + for(i = 0; i < axutil_array_list_size(op->module_qnames, env); i++) + { + axutil_qname_t *module_ref = NULL; + module_ref = axutil_array_list_get(op->module_qnames, env, i); + + if(module_ref) + { + axutil_qname_free(module_ref, env); + } + } + axutil_array_list_free(op->module_qnames, env); + } + if(op->engaged_module_list) + { + axutil_array_list_free(op->engaged_module_list, env); + } + if(op->wsamapping_list) + { + int i = 0; + int size = 0; + size = axutil_array_list_size(op->wsamapping_list, env); + for(i = 0; i < size; i++) + { + axis2_char_t *temp_str = axutil_array_list_get(op->wsamapping_list, env, i); + if(temp_str) + AXIS2_FREE(env->allocator, temp_str); + } + axutil_array_list_free(op->wsamapping_list, env); + } + + if(op->qname) + { + axutil_qname_free(op->qname, env); + } + + if(op->msg_exchange_pattern) + { + AXIS2_FREE(env->allocator, op->msg_exchange_pattern); + } + + if(op->style) + { + AXIS2_FREE(env->allocator, op->style); + } + + if(op->rest_http_method) + { + AXIS2_FREE(env->allocator, op->rest_http_method); + } + + if(op->rest_http_location) + { + AXIS2_FREE(env->allocator, op->rest_http_location); + } + + if(op) + { + AXIS2_FREE(env->allocator, op); + } + + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_op_free_void_arg( + void *op, + const axutil_env_t * env) +{ + axis2_op_t *op_l = NULL; + + op_l = (axis2_op_t *)op; + axis2_op_free(op_l, env); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_add_param( + axis2_op_t * op, + const axutil_env_t * env, + axutil_param_t * param) +{ + axis2_char_t *param_name = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FALSE); + + param_name = axutil_param_get_name(param, env); + if(AXIS2_TRUE == axis2_op_is_param_locked(op, env, param_name)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Parameter %s is locked, cannot override", + param_name); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PARAMETER_LOCKED_CANNOT_OVERRIDE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + else + { + status = axutil_param_container_add_param(op->param_container, env, param); + } + + return status; +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_op_get_param( + const axis2_op_t * op, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + axutil_param_t *param = NULL; + + AXIS2_PARAM_CHECK(env->error, param_name, NULL); + + param = axutil_param_container_get_param(op->param_container, env, param_name); + if(!param && op->parent) + { + param = axis2_svc_get_param(op->parent, env, param_name); + } + return param; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_remove_param + (axis2_op_t *op, + const axutil_env_t *env, + const axis2_char_t *param_name) +{ + axis2_status_t status = AXIS2_FAILURE; + status = axutil_param_container_delete_param(op->param_container, env, param_name); + return status; + + +} + + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_op_get_all_params( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return axutil_param_container_get_params(op->param_container, env); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_op_is_param_locked( + axis2_op_t * op, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + axis2_svc_t *parent = NULL; + axutil_param_t *param = NULL; + axis2_bool_t locked = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FALSE); + + /* Checking the locked value of parent */ + parent = axis2_op_get_parent(op, env); + if(parent) + { + locked = axis2_svc_is_param_locked(parent, env, param_name); + } + if(locked) + { + return AXIS2_TRUE; + } + param = axis2_op_get_param(op, env, param_name); + return (param && AXIS2_TRUE == axutil_param_is_locked(param, env)); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_rest_http_method( + axis2_op_t * op, + const axutil_env_t * env, + const axis2_char_t * rest_http_method) +{ + AXIS2_PARAM_CHECK(env->error, rest_http_method, AXIS2_FAILURE); + + if(op->rest_http_method) + { + AXIS2_FREE(env->allocator, op->rest_http_method); + } + op->rest_http_method = NULL; + if(rest_http_method) + { + op->rest_http_method = axutil_strdup(env, rest_http_method); + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_op_get_rest_http_method( + const axis2_op_t * op, + const axutil_env_t * env) +{ + if(!op) + { + return NULL; + } + if(op->rest_http_method) + { + return op->rest_http_method; + } + else + { + axutil_param_t *param = NULL; + + param = axis2_op_get_param(op, env, AXIS2_DEFAULT_REST_HTTP_METHOD); + + if(!param) + { + return "POST"; /* Added hard-coded string to avoid inclusion of HTTP + * Transport header + */ + } + return (axis2_char_t *)axutil_param_get_value(param, env); + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_rest_http_location( + axis2_op_t * op, + const axutil_env_t * env, + const axis2_char_t * rest_http_location) +{ + axis2_char_t *opname = NULL; + AXIS2_PARAM_CHECK(env->error, rest_http_location, AXIS2_FAILURE); + opname = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); + if(op->rest_http_location) + { + AXIS2_FREE(env->allocator, op->rest_http_location); + } + op->rest_http_location = NULL; + if(rest_http_location) + { + op->rest_http_location = axutil_strdup(env, rest_http_location); + return AXIS2_SUCCESS; + } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting rest http location failed for operation %s", + opname); + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_op_get_rest_http_location( + const axis2_op_t * op, + const axutil_env_t * env) +{ + if(!op) + { + return NULL; + } + return op->rest_http_location; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_parent( + axis2_op_t * op, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + AXIS2_PARAM_CHECK(env->error, svc, AXIS2_FAILURE); + + if(op->parent) + { + op->parent = NULL; + } + op->parent = svc; + if(svc) + { + axis2_desc_set_parent(op->base, env, axis2_svc_get_base(svc, env)); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_svc_t *AXIS2_CALL +axis2_op_get_parent( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->parent; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_msg_recv( + axis2_op_t * op, + const axutil_env_t * env, + struct axis2_msg_recv * msg_recv) +{ + AXIS2_PARAM_CHECK(env->error, msg_recv, AXIS2_FAILURE); + + if(op->msg_recv == msg_recv) + { + return AXIS2_SUCCESS; + } + if(op->msg_recv) + { + axis2_msg_recv_free(op->msg_recv, env); + op->msg_recv = NULL; + } + + op->msg_recv = msg_recv; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN struct axis2_msg_recv *AXIS2_CALL +axis2_op_get_msg_recv( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->msg_recv; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_qname( + axis2_op_t * op, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + if(op->qname) + { + axutil_qname_free(op->qname, env); + op->qname = NULL; + } + + if(qname) + { + op->qname = axutil_qname_clone((axutil_qname_t *)qname, env); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axutil_qname_t *AXIS2_CALL +axis2_op_get_qname( + void *op, + const axutil_env_t * env) +{ + return ((axis2_op_t *)op)->qname; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_msg_exchange_pattern( + axis2_op_t * op, + const axutil_env_t * env, + const axis2_char_t * pattern) +{ + AXIS2_PARAM_CHECK(env->error, pattern, AXIS2_FAILURE); + + if(op->msg_exchange_pattern) + { + AXIS2_FREE(env->allocator, op->msg_exchange_pattern); + op->msg_exchange_pattern = NULL; + } + + op->msg_exchange_pattern = axutil_strdup(env, pattern); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_op_get_msg_exchange_pattern( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->msg_exchange_pattern; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_op_get_style( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->style; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_style( + axis2_op_t * op, + const axutil_env_t * env, + const axis2_char_t * style) +{ + AXIS2_PARAM_CHECK(env->error, style, AXIS2_FAILURE); + + if(op->style) + { + AXIS2_FREE(env->allocator, op->style); + op->style = NULL; + } + + op->style = axutil_strdup(env, style); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_engage_module( + axis2_op_t * op, + const axutil_env_t * env, + axis2_module_desc_t * moduleref, + axis2_conf_t * conf) +{ + int index = 0; + int size = 0; + axutil_array_list_t *collection_module = NULL; + axis2_module_desc_t *module_desc = NULL; + axis2_phase_resolver_t *pr = NULL; + axis2_bool_t need_to_add = AXIS2_FALSE; + axis2_char_t *opname = NULL; + axis2_char_t *modname = NULL; + + AXIS2_PARAM_CHECK(env->error, moduleref, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + opname = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); + collection_module = op->engaged_module_list; + if(collection_module) + { + size = axutil_array_list_size(collection_module, env); + } + for(index = 0; index < size; index++) + { + const axutil_qname_t *qname1 = NULL; + const axutil_qname_t *qname2 = NULL; + + module_desc = (axis2_module_desc_t *)axutil_array_list_get(collection_module, env, index); + if(!module_desc) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Retrieving a module failed from operation %s engaged module" + " list", opname); + return AXIS2_FAILURE; + } + qname1 = axis2_module_desc_get_qname(module_desc, env); + qname2 = axis2_module_desc_get_qname(moduleref, env); + modname = axutil_qname_get_localpart(qname2, env); + if(axutil_qname_equals(qname1, env, qname2)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Module %s already engaged to operation %s", + modname, opname); + + need_to_add = AXIS2_FALSE; + return AXIS2_FAILURE; + } + + } + pr = axis2_phase_resolver_create_with_config(env, conf); + if(pr) + { + axis2_module_t *module = NULL; + axis2_status_t status = AXIS2_FAILURE; + + status = axis2_phase_resolver_engage_module_to_op(pr, env, op, moduleref); + if(AXIS2_SUCCESS != status) + { + /* Ignore the status */ + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_SUCCESS); + AXIS2_LOG_INFO(env->log, AXIS2_LOG_SI, + "Engaging module %s to operaion %s failed. But ignore this.", modname, opname); + } + module = axis2_module_desc_get_module(moduleref, env); + + if(need_to_add) + { + axutil_array_list_add(collection_module, env, moduleref); + } + } + else + { + return AXIS2_FAILURE; + } + axis2_phase_resolver_free(pr, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_add_to_engaged_module_list( + axis2_op_t * op, + const axutil_env_t * env, + axis2_module_desc_t * module_desc) +{ + axis2_module_desc_t *module_desc_l = NULL; + int size = 0; + int index = 0; + const axutil_qname_t *module_qname = NULL; + + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + + if(!op->engaged_module_list) + { + op->engaged_module_list = axutil_array_list_create(env, 0); + } + size = axutil_array_list_size(op->engaged_module_list, env); + + module_qname = axis2_module_desc_get_qname(module_desc, env); + for(index = 0; index < size; index++) + { + const axutil_qname_t *module_qname_l = NULL; + + module_desc_l = (axis2_module_desc_t *)axutil_array_list_get(op-> engaged_module_list, env, + index); + module_qname_l = axis2_module_desc_get_qname(module_desc_l, env); + + if(axutil_qname_equals(module_qname, env, module_qname_l)) + { + return AXIS2_SUCCESS; + } + + } + + return axutil_array_list_add(op->engaged_module_list, env, module_desc); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_remove_from_engaged_module_list( + axis2_op_t * op, + const axutil_env_t * env, + axis2_module_desc_t * module_desc) +{ + axis2_module_desc_t *module_desc_l = NULL; + int size = 0; + int index = 0; + const axutil_qname_t *module_qname = NULL; + + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, op->engaged_module_list, AXIS2_FAILURE); + + size = axutil_array_list_size(op->engaged_module_list, env); + + module_qname = axis2_module_desc_get_qname(module_desc, env); + for(index = 0; index < size; index++) + { + const axutil_qname_t *module_qname_l = NULL; + + module_desc_l = (axis2_module_desc_t *)axutil_array_list_get(op-> engaged_module_list, env, + index); + module_qname_l = axis2_module_desc_get_qname(module_desc_l, env); + + if(axutil_qname_equals(module_qname, env, module_qname_l)) + { + axutil_array_list_remove(op->engaged_module_list, env, index); + return AXIS2_SUCCESS; + } + + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_op_get_all_modules( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->engaged_module_list; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_op_get_axis_specific_mep_const( + axis2_op_t * op, + const axutil_env_t * env) +{ + int temp = 0; + axis2_char_t *opname = NULL; + + opname = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); + if(op->mep != AXIS2_MEP_CONSTANT_INVALID) + { + return op->mep; + } + + temp = AXIS2_MEP_CONSTANT_INVALID; + + if((axutil_strcmp(AXIS2_MEP_URI_IN_OUT, axis2_op_get_msg_exchange_pattern(op, env)) == 0) || + (axutil_strcmp(AXIS2_MEP_URI_IN_OUT_WSDL2, axis2_op_get_msg_exchange_pattern(op, env)) == 0)) + { + temp = AXIS2_MEP_CONSTANT_IN_OUT; + } + else if((axutil_strcmp(AXIS2_MEP_URI_IN_ONLY, axis2_op_get_msg_exchange_pattern(op, env)) == 0) + || (axutil_strcmp(AXIS2_MEP_URI_IN_ONLY_WSDL2, axis2_op_get_msg_exchange_pattern(op, env)) == 0)) + { + temp = AXIS2_MEP_CONSTANT_IN_ONLY; + } + else if((axutil_strcmp(AXIS2_MEP_URI_IN_OPTIONAL_OUT, axis2_op_get_msg_exchange_pattern(op, env))== 0) || + (axutil_strcmp(AXIS2_MEP_URI_IN_OPTIONAL_OUT_WSDL2, axis2_op_get_msg_exchange_pattern(op, env))== 0)) + { + temp = AXIS2_MEP_CONSTANT_IN_OPTIONAL_OUT; + } + else if((axutil_strcmp(AXIS2_MEP_URI_OUT_IN, axis2_op_get_msg_exchange_pattern(op, env)) == 0) || + (axutil_strcmp(AXIS2_MEP_URI_OUT_IN_WSDL2, axis2_op_get_msg_exchange_pattern(op, env)) == 0)) + { + temp = AXIS2_MEP_CONSTANT_OUT_IN; + } + else if((axutil_strcmp(AXIS2_MEP_URI_OUT_ONLY, axis2_op_get_msg_exchange_pattern(op, env)) == 0) || + (axutil_strcmp(AXIS2_MEP_URI_OUT_ONLY_WSDL2, axis2_op_get_msg_exchange_pattern(op, env)) == 0)) + { + temp = AXIS2_MEP_CONSTANT_OUT_ONLY; + } + else if((axutil_strcmp(AXIS2_MEP_URI_OUT_OPTIONAL_IN, axis2_op_get_msg_exchange_pattern(op, env)) == 0) || + (axutil_strcmp(AXIS2_MEP_URI_OUT_OPTIONAL_IN_WSDL2, axis2_op_get_msg_exchange_pattern(op, env)) == 0)) + { + temp = AXIS2_MEP_CONSTANT_OUT_OPTIONAL_IN; + } + else if((axutil_strcmp(AXIS2_MEP_URI_ROBUST_IN_ONLY, axis2_op_get_msg_exchange_pattern(op, env)) == 0) || + (axutil_strcmp(AXIS2_MEP_URI_ROBUST_IN_ONLY_WSDL2, axis2_op_get_msg_exchange_pattern(op, env)) == 0)) + { + temp = AXIS2_MEP_CONSTANT_ROBUST_IN_ONLY; + } + else if((axutil_strcmp(AXIS2_MEP_URI_ROBUST_OUT_ONLY, axis2_op_get_msg_exchange_pattern(op, env)) == 0) || + (axutil_strcmp(AXIS2_MEP_URI_ROBUST_OUT_ONLY_WSDL2, axis2_op_get_msg_exchange_pattern(op, env)) == 0)) + { + temp = AXIS2_MEP_CONSTANT_ROBUST_OUT_ONLY; + } + if(temp == AXIS2_MEP_CONSTANT_INVALID) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Could not map the MEP URI %s to an Axis2/C MEP constant value " + "in retrieving MEP for operation %s", axis2_op_get_msg_exchange_pattern(op, env), + opname); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_COULD_NOT_MAP_MEP_URI_TO_MEP_CONSTANT, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + op->mep = temp; + return op->mep; + +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_op_get_fault_in_flow( + const axis2_op_t * op, + const axutil_env_t * env) +{ + if(op->base) + { + axis2_msg_t *msg = NULL; + msg = axis2_desc_get_child(op->base, env, AXIS2_MSG_IN_FAULT); + if(msg) + { + return axis2_msg_get_flow(msg, env); + } + } + return NULL; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_op_get_fault_out_flow( + const axis2_op_t * op, + const axutil_env_t * env) +{ + if(op->base) + { + axis2_msg_t *msg = NULL; + msg = axis2_desc_get_child(op->base, env, AXIS2_MSG_OUT_FAULT); + if(msg) + { + return axis2_msg_get_flow(msg, env); + } + } + return NULL; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_op_get_out_flow( + const axis2_op_t * op, + const axutil_env_t * env) +{ + if(op->base) + { + axis2_msg_t *msg = NULL; + msg = axis2_desc_get_child(op->base, env, AXIS2_MSG_OUT); + if(msg) + { + return axis2_msg_get_flow(msg, env); + } + } + return NULL; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_op_get_in_flow( + const axis2_op_t * op, + const axutil_env_t * env) +{ + if(op->base) + { + axis2_msg_t *msg = NULL; + msg = axis2_desc_get_child(op->base, env, AXIS2_MSG_IN); + if(msg) + { + return axis2_msg_get_flow(msg, env); + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_fault_in_flow( + axis2_op_t * op, + const axutil_env_t * env, + axutil_array_list_t * list) +{ + AXIS2_PARAM_CHECK(env->error, list, AXIS2_FAILURE); + + if(op->base) + { + axis2_msg_t *msg = NULL; + msg = axis2_desc_get_child(op->base, env, AXIS2_MSG_IN_FAULT); + if(msg) + { + return axis2_msg_set_flow(msg, env, list); + } + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_fault_out_flow( + axis2_op_t * op, + const axutil_env_t * env, + axutil_array_list_t * list) +{ + AXIS2_PARAM_CHECK(env->error, list, AXIS2_FAILURE); + if(op->base) + { + axis2_msg_t *msg = NULL; + msg = axis2_desc_get_child(op->base, env, AXIS2_MSG_OUT_FAULT); + if(msg) + { + return axis2_msg_set_flow(msg, env, list); + } + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_out_flow( + axis2_op_t * op, + const axutil_env_t * env, + axutil_array_list_t * list) +{ + AXIS2_PARAM_CHECK(env->error, list, AXIS2_FAILURE); + + if(op->base) + { + axis2_msg_t *msg = NULL; + msg = axis2_desc_get_child(op->base, env, AXIS2_MSG_OUT); + if(msg) + { + return axis2_msg_set_flow(msg, env, list); + } + } + + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_in_flow( + axis2_op_t * op, + const axutil_env_t * env, + axutil_array_list_t * list) +{ + AXIS2_PARAM_CHECK(env->error, list, AXIS2_FAILURE); + + if(op->base) + { + axis2_msg_t *msg = NULL; + msg = axis2_desc_get_child(op->base, env, AXIS2_MSG_IN); + if(msg) + { + return axis2_msg_set_flow(msg, env, list); + } + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_add_module_qname( + axis2_op_t * op, + const axutil_env_t * env, + const axutil_qname_t * module_qname) +{ + axutil_qname_t *module_qname_l = NULL; + + AXIS2_PARAM_CHECK(env->error, module_qname, AXIS2_FAILURE); + module_qname_l = axutil_qname_clone((axutil_qname_t *)module_qname, env); + + return axutil_array_list_add(op->module_qnames, env, module_qname_l); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_op_get_all_module_qnames( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->module_qnames; +} + +AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL +axis2_op_find_op_ctx( + axis2_op_t * op, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx, + struct axis2_svc_ctx * svc_ctx) +{ + axis2_op_ctx_t *op_ctx = NULL; + axis2_relates_to_t *relates_to = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *opname = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + AXIS2_PARAM_CHECK(env->error, svc_ctx, NULL); + + opname = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); + relates_to = axis2_msg_ctx_get_relates_to(msg_ctx, env); + if(!relates_to) + { + op_ctx = axis2_op_ctx_create(env, op, svc_ctx); + if(!op_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating operation context failed for operation %s", opname); + return NULL; + } + } + else + { + axis2_conf_ctx_t *conf_ctx = NULL; + const axis2_char_t *value = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + value = axis2_relates_to_get_value(relates_to, env); + op_ctx = axis2_conf_ctx_get_op_ctx(conf_ctx, env, value); + if(!op_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Cannot correlate message to %s for operation %s", value, opname); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CANNOT_CORRELATE_MSG, AXIS2_FAILURE); + return NULL; + } + } + + status = axis2_op_register_op_ctx(op, env, msg_ctx, op_ctx); + if(AXIS2_FAILURE == status) + { + axis2_op_ctx_free(op_ctx, env); + return NULL; + } + else + { + return op_ctx; + } +} + +AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL +axis2_op_find_existing_op_ctx( + axis2_op_t * op, + const axutil_env_t * env, + const axis2_msg_ctx_t * msg_ctx) +{ + axis2_op_ctx_t *op_ctx = NULL; + axis2_relates_to_t *relates_to = NULL; + axis2_char_t *opname = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + opname = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + return op_ctx; + } + + relates_to = axis2_msg_ctx_get_relates_to(msg_ctx, env); + if(!relates_to) + { + return NULL; + } + else + { + axis2_conf_ctx_t *conf_ctx = NULL; + const axis2_char_t *value = NULL; + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + value = axis2_relates_to_get_value(relates_to, env); + op_ctx = axis2_conf_ctx_get_op_ctx(conf_ctx, env, value); + + if(!op_ctx) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "Cannot correlate message to %s for operation %s", value, opname); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CANNOT_CORRELATE_MSG, AXIS2_FAILURE); + return NULL; + } + } + + return op_ctx; + +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_register_op_ctx( + axis2_op_t * op, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_op_ctx_t * op_ctx) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + const axis2_char_t *msg_id = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *opname = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, op_ctx, AXIS2_FAILURE); + + opname = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(!conf_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Configuration context not found for message context while " + "registering operation context for operation %s", opname); + return AXIS2_FAILURE; + } + + status = axis2_msg_ctx_set_op_ctx(msg_ctx, env, op_ctx); + + if(AXIS2_SUCCESS != status) + { + axutil_hash_t *op_ctx_map = NULL; + + msg_id = axis2_msg_ctx_get_msg_id(msg_ctx, env); + if(msg_id) + { + op_ctx_map = (axutil_hash_t *)axis2_conf_ctx_get_op_ctx_map(conf_ctx, env); + axutil_hash_set(op_ctx_map, msg_id, AXIS2_HASH_KEY_STRING, NULL); + } + else + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "Message id not found for message context while registering operation context " + "for operation %s. The reason could be that there is no addressing enabled for " + "communication", opname); + } + } + if(axis2_op_ctx_get_is_complete(op_ctx, env)) + { + axis2_op_ctx_cleanup(op_ctx, env); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_add_msg_ctx_in_only( + axis2_op_t * op, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_op_ctx_t * op_ctx) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, op_ctx, AXIS2_FAILURE); + + if(!axis2_op_ctx_get_is_complete(op_ctx, env)) + { + axis2_msg_ctx_t **msg_ctxs = NULL; + msg_ctxs = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + msg_ctxs[AXIS2_WSDL_MESSAGE_LABEL_IN] = msg_ctx; + axis2_op_ctx_set_complete(op_ctx, env, AXIS2_TRUE); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid message; adding operation context for the " + "operation :%s is already completed", axutil_qname_get_localpart( + axis2_op_get_qname(op, env), env)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MESSAGE_ADDITION, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_add_msg_ctx_out_only( + axis2_op_t * op, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_op_ctx_t * op_ctx) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, op_ctx, AXIS2_FAILURE); + + if(!axis2_op_ctx_get_is_complete(op_ctx, env)) + { + axis2_msg_ctx_t **msg_ctxs = NULL; + msg_ctxs = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + msg_ctxs[AXIS2_WSDL_MESSAGE_LABEL_OUT] = msg_ctx; + axis2_op_ctx_set_complete(op_ctx, env, AXIS2_TRUE); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid message; adding operation context for the " + "operation :%s is already completed", axutil_qname_get_localpart( + axis2_op_get_qname(op, env), env)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MESSAGE_ADDITION, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_add_msg_ctx_in_out( + axis2_op_t * op, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_op_ctx_t * op_ctx) +{ + axis2_msg_ctx_t **mep = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + axis2_msg_ctx_t *out_msg_ctx = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, op_ctx, AXIS2_FAILURE); + + mep = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + in_msg_ctx = mep[AXIS2_WSDL_MESSAGE_LABEL_IN]; + out_msg_ctx = mep[AXIS2_WSDL_MESSAGE_LABEL_OUT]; + + if(in_msg_ctx && out_msg_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid message; adding operation context for the " + "operation :%s is invalid", axutil_qname_get_localpart(axis2_op_get_qname(op, env), + env)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MESSAGE_ADDITION, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(!in_msg_ctx) + { + mep[AXIS2_WSDL_MESSAGE_LABEL_IN] = msg_ctx; + } + else + { + mep[AXIS2_WSDL_MESSAGE_LABEL_OUT] = msg_ctx; + axis2_op_ctx_set_complete(op_ctx, env, AXIS2_TRUE); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_add_msg_ctx_out_in( + axis2_op_t * op, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_op_ctx_t * op_ctx) +{ + axis2_msg_ctx_t **mep = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + axis2_msg_ctx_t *out_msg_ctx = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, op_ctx, AXIS2_FAILURE); + + mep = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + in_msg_ctx = mep[AXIS2_WSDL_MESSAGE_LABEL_IN]; + out_msg_ctx = mep[AXIS2_WSDL_MESSAGE_LABEL_OUT]; + if(in_msg_ctx && out_msg_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid message; adding operation context for the " + "operation :%s is invalid", axutil_qname_get_localpart(axis2_op_get_qname(op, env), + env)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MESSAGE_ADDITION, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(!out_msg_ctx) + { + mep[AXIS2_WSDL_MESSAGE_LABEL_OUT] = msg_ctx; + } + else + { + mep[AXIS2_WSDL_MESSAGE_LABEL_IN] = msg_ctx; + axis2_op_ctx_set_complete(op_ctx, env, AXIS2_TRUE); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_t *AXIS2_CALL +axis2_op_get_msg( + const axis2_op_t * op, + const axutil_env_t * env, + const axis2_char_t * label) +{ + AXIS2_PARAM_CHECK(env->error, label, NULL); + + return (axis2_msg_t *)axis2_desc_get_child(op->base, env, label); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_add_msg( + axis2_op_t * op, + const axutil_env_t * env, + const axis2_char_t * label, + const axis2_msg_t * msg) +{ + AXIS2_PARAM_CHECK(env->error, label, AXIS2_FAILURE); + + return axis2_desc_add_child(op->base, env, label, msg); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_op_is_from_module( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->from_module; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_op_set_wsamapping_list( + axis2_op_t * op, + const axutil_env_t * env, + axutil_array_list_t * mapping_list) +{ + AXIS2_PARAM_CHECK(env->error, mapping_list, AXIS2_FAILURE); + + if(op->wsamapping_list) + { + int i = 0; + int size = 0; + size = axutil_array_list_size(op->wsamapping_list, env); + for(i = 0; i < size; i++) + { + axis2_char_t *temp_str = axutil_array_list_get(op->wsamapping_list, env, i); + if(temp_str) + AXIS2_FREE(env->allocator, temp_str); + } + axutil_array_list_free(op->wsamapping_list, env); + op->wsamapping_list = NULL; + } + op->wsamapping_list = mapping_list; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_op_get_wsamapping_list( + axis2_op_t * op, + const axutil_env_t * env) +{ + return op->wsamapping_list; +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_op_get_param_container( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->param_container; +} + +AXIS2_EXTERN axis2_desc_t *AXIS2_CALL +axis2_op_get_base( + const axis2_op_t * op, + const axutil_env_t * env) +{ + return op->base; +} + diff --git a/src/core/description/phase_rule.c b/src/core/description/phase_rule.c new file mode 100644 index 0000000..bb4cfea --- /dev/null +++ b/src/core/description/phase_rule.c @@ -0,0 +1,254 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_const.h> +#include <axis2_phase_rule.h> +#include <axutil_string.h> + +struct axis2_phase_rule +{ + + /** name of phase or handler before */ + axis2_char_t *before; + + /** name of phase or handler after */ + axis2_char_t *after; + + /** phase name */ + axis2_char_t *name; + + /** Is this first in phase? */ + axis2_bool_t first; + + /** Is this last in phase? */ + axis2_bool_t last; + +}; + +AXIS2_EXTERN axis2_phase_rule_t *AXIS2_CALL +axis2_phase_rule_create( + const axutil_env_t * env, + const axis2_char_t * name) +{ + axis2_phase_rule_t *phase_rule = NULL; + + phase_rule = AXIS2_MALLOC(env->allocator, sizeof(axis2_phase_rule_t)); + if(!phase_rule) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + return NULL; + } + + phase_rule->before = NULL; + phase_rule->after = NULL; + phase_rule->name = NULL; + phase_rule->first = AXIS2_FALSE; + phase_rule->last = AXIS2_FALSE; + + if(name) + { + phase_rule->name = axutil_strdup(env, name); + } + + return phase_rule; +} + +const axis2_char_t *AXIS2_CALL +axis2_phase_rule_get_before( + const axis2_phase_rule_t * phase_rule, + const axutil_env_t * env) +{ + return phase_rule->before; +} + +axis2_status_t AXIS2_CALL +axis2_phase_rule_set_before( + axis2_phase_rule_t * phase_rule, + const axutil_env_t * env, + const axis2_char_t * before) +{ + if(phase_rule->before) + { + AXIS2_FREE(env->allocator, phase_rule->before); + } + + if(before) + { + phase_rule->before = axutil_strdup(env, before); + if(!phase_rule->before) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_phase_rule_get_after( + const axis2_phase_rule_t * phase_rule, + const axutil_env_t * env) +{ + return phase_rule->after; +} + +axis2_status_t AXIS2_CALL +axis2_phase_rule_set_after( + axis2_phase_rule_t * phase_rule, + const axutil_env_t * env, + const axis2_char_t * after) +{ + if(phase_rule->after) + { + AXIS2_FREE(env->allocator, phase_rule->after); + } + + if(after) + { + phase_rule->after = axutil_strdup(env, after); + if(!phase_rule->after) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_phase_rule_get_name( + const axis2_phase_rule_t * phase_rule, + const axutil_env_t * env) +{ + return phase_rule->name; +} + +axis2_status_t AXIS2_CALL +axis2_phase_rule_set_name( + axis2_phase_rule_t * phase_rule, + const axutil_env_t * env, + const axis2_char_t * name) +{ + if(phase_rule->name) + { + AXIS2_FREE(env->allocator, phase_rule->name); + } + + if(name) + { + phase_rule->name = axutil_strdup(env, name); + if(!phase_rule->name) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_phase_rule_is_first( + const axis2_phase_rule_t * phase_rule, + const axutil_env_t * env) +{ + return phase_rule->first; +} + +axis2_status_t AXIS2_CALL +axis2_phase_rule_set_first( + axis2_phase_rule_t * phase_rule, + const axutil_env_t * env, + axis2_bool_t first) +{ + phase_rule->first = first; + return AXIS2_SUCCESS; +} + +axis2_bool_t AXIS2_CALL +axis2_phase_rule_is_last( + const axis2_phase_rule_t * phase_rule, + const axutil_env_t * env) +{ + return phase_rule->last; +} + +axis2_status_t AXIS2_CALL +axis2_phase_rule_set_last( + axis2_phase_rule_t * phase_rule, + const axutil_env_t * env, + axis2_bool_t last) +{ + phase_rule->last = last; + return AXIS2_SUCCESS; +} + +void AXIS2_CALL +axis2_phase_rule_free( + axis2_phase_rule_t * phase_rule, + const axutil_env_t * env) +{ + if(phase_rule->before) + { + AXIS2_FREE(env->allocator, phase_rule->before); + } + + if(phase_rule->after) + { + AXIS2_FREE(env->allocator, phase_rule->after); + } + + if(phase_rule->name) + { + AXIS2_FREE(env->allocator, phase_rule->name); + } + + AXIS2_FREE(env->allocator, phase_rule); + + return; +} + +axis2_phase_rule_t *AXIS2_CALL +axis2_phase_rule_clone( + axis2_phase_rule_t * phase_rule, + const axutil_env_t * env) +{ + axis2_phase_rule_t *phase_rule_new = NULL; + + phase_rule_new = axis2_phase_rule_create(env, NULL); + if(!phase_rule_new) + return NULL; + + axis2_phase_rule_set_before(phase_rule_new, env, axis2_phase_rule_get_before(phase_rule, env)); + + axis2_phase_rule_set_after(phase_rule_new, env, axis2_phase_rule_get_after(phase_rule, env)); + + axis2_phase_rule_set_name(phase_rule_new, env, axis2_phase_rule_get_name(phase_rule, env)); + + axis2_phase_rule_set_first(phase_rule_new, env, axis2_phase_rule_is_first(phase_rule, env)); + + axis2_phase_rule_set_last(phase_rule_new, env, axis2_phase_rule_is_last(phase_rule, env)); + + return phase_rule_new; +} + diff --git a/src/core/description/policy_include.c b/src/core/description/policy_include.c new file mode 100644 index 0000000..5ce93f8 --- /dev/null +++ b/src/core/description/policy_include.c @@ -0,0 +1,612 @@ +/* + * 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_policy_include.h> +#include <neethi_policy.h> +#include <neethi_engine.h> + +struct axis2_policy_include +{ + neethi_policy_t *policy; + + neethi_policy_t *effective_policy; + + neethi_registry_t *registry; + + axis2_desc_t *desc; + + axutil_hash_t *wrapper_elements; +}; + +typedef struct axis2_policy_wrapper +{ + int type; + void *value; +} axis2_policy_wrapper_t; + +AXIS2_EXTERN axis2_policy_include_t *AXIS2_CALL +axis2_policy_include_create( + const axutil_env_t * env) +{ + axis2_policy_include_t *policy_include = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + policy_include = (axis2_policy_include_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_policy_include_t)); + + if(!policy_include) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + policy_include->policy = NULL; + policy_include->effective_policy = NULL; + policy_include->registry = NULL; + policy_include->desc = NULL; + policy_include->wrapper_elements = NULL; + + policy_include->registry = neethi_registry_create(env); + if(!policy_include->registry) + { + axis2_policy_include_free(policy_include, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + policy_include->wrapper_elements = axutil_hash_make(env); + if(!policy_include->wrapper_elements) + { + axis2_policy_include_free(policy_include, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return policy_include; +} + +AXIS2_EXTERN axis2_policy_include_t *AXIS2_CALL +axis2_policy_include_create_with_desc( + const axutil_env_t * env, + axis2_desc_t * desc) +{ + axis2_policy_include_t *policy_include = NULL; + axis2_desc_t *parent_desc = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + policy_include = (axis2_policy_include_t *)axis2_policy_include_create(env); + + parent_desc = axis2_desc_get_parent(desc, env); + + if(policy_include->registry) + { + neethi_registry_free(policy_include->registry, env); + policy_include->registry = NULL; + } + + if(parent_desc) + { + axis2_policy_include_t *preant_policy_include = axis2_desc_get_policy_include(parent_desc, + env); + if(preant_policy_include) + { + policy_include->registry = neethi_registry_create_with_parent(env, + axis2_policy_include_get_registry(preant_policy_include, env)); + } + else + { + policy_include->registry = neethi_registry_create(env); + } + } + else + { + policy_include->registry = neethi_registry_create(env); + } + + policy_include->desc = desc; + + return policy_include; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_policy_include_free( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(policy_include->registry) + { + neethi_registry_free(policy_include->registry, env); + } + + if(policy_include->wrapper_elements) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(policy_include->wrapper_elements, env); hi; hi + = axutil_hash_next(env, hi)) + { + axis2_policy_wrapper_t *wrapper = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + wrapper = (axis2_policy_wrapper_t *)val; + if(wrapper) + AXIS2_FREE(env->allocator, wrapper); + val = NULL; + wrapper = NULL; + } + axutil_hash_free(policy_include->wrapper_elements, env); + } + + if(policy_include) + { + AXIS2_FREE(env->allocator, policy_include); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_set_registry( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + neethi_registry_t * registry) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(policy_include->registry) + { + neethi_registry_free(policy_include->registry, env); + } + + policy_include->registry = registry; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN neethi_registry_t *AXIS2_CALL +axis2_policy_include_get_registry( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + return policy_include->registry; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_set_policy( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + neethi_policy_t * policy) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(policy_include->wrapper_elements) + { + axutil_hash_free(policy_include->wrapper_elements, env); + policy_include->wrapper_elements = NULL; + } + + policy_include->wrapper_elements = axutil_hash_make(env); + + if(!neethi_policy_get_name(policy, env) && !neethi_policy_get_id(policy, env)) + { + neethi_policy_set_id(policy, env, axutil_uuid_gen(env)); + } + + if(policy_include->wrapper_elements) + { + axis2_policy_wrapper_t *wrapper = NULL; + + wrapper = (axis2_policy_wrapper_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_policy_wrapper_t)); + if(wrapper) + { + axis2_char_t *policy_name = NULL; + wrapper->type = AXIS2_ANON_POLICY; + wrapper->value = policy; + + policy_name = neethi_policy_get_name(policy, env); + + if(policy_name) + { + axutil_hash_set(policy_include->wrapper_elements, policy_name, + AXIS2_HASH_KEY_STRING, wrapper); + } + else + { + axutil_hash_set(policy_include->wrapper_elements, + neethi_policy_get_id(policy, env), AXIS2_HASH_KEY_STRING, wrapper); + } + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_update_policy( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + neethi_policy_t * policy) +{ + axis2_char_t *key; + axis2_policy_wrapper_t *wrapper = NULL; + + key = neethi_policy_get_name(policy, env); + if(!key) + key = neethi_policy_get_id(policy, env); + + if(!key) + { + return AXIS2_FAILURE; + } + + wrapper = axutil_hash_get(policy_include->wrapper_elements, key, AXIS2_HASH_KEY_STRING); + if(wrapper) + { + wrapper->value = policy; + return AXIS2_SUCCESS; + } + + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_set_effective_policy( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + neethi_policy_t * effective_policy) +{ + policy_include->effective_policy = effective_policy; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_set_desc( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + axis2_desc_t * desc) +{ + policy_include->desc = desc; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_desc_t *AXIS2_CALL +axis2_policy_include_get_desc( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + return policy_include->desc; +} + +AXIS2_EXTERN axis2_policy_include_t *AXIS2_CALL +axis2_policy_include_get_parent( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + if(policy_include->desc) + { + axis2_desc_t *parent = NULL; + parent = axis2_desc_get_parent(policy_include->desc, env); + if(parent) + { + return axis2_desc_get_policy_include(parent, env); + } + } + + return NULL; +} + +static axis2_status_t +axis2_policy_include_calculate_policy( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + neethi_policy_t *result = NULL; + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + for(hi = axutil_hash_first(policy_include->wrapper_elements, env); hi; hi = axutil_hash_next( + env, hi)) + { + axis2_policy_wrapper_t *wrapper = NULL; + + axutil_hash_this(hi, NULL, NULL, &val); + wrapper = (axis2_policy_wrapper_t *)val; + + if(wrapper) + { + neethi_policy_t *policy = NULL; + if(wrapper->type == AXIS2_POLICY_REF) + { + neethi_reference_t *reference = (neethi_reference_t *)wrapper->value; + if(reference) + { + /* TOOD add neethi_reference_normalize + policy = (neethi_policy_t*) neethi_reference_normalize( + reference, env, policy_include->registry, AXIS2_FALSE); + */ + } + } + else + { + policy = (neethi_policy_t *)wrapper->value; + } + + result = (result == NULL) ? (neethi_policy_t *)policy + : (neethi_policy_t *)neethi_engine_merge(env, result, policy); + } + } + + policy_include->policy = result; + return AXIS2_SUCCESS; +} + +static neethi_policy_t * +axis2_policy_include_calculate_effective_policy( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + neethi_policy_t *result; + axis2_policy_include_t *parent = NULL; + + parent = axis2_policy_include_get_parent(policy_include, env); + + if(parent) + { + neethi_policy_t *parent_policy = axis2_policy_include_get_effective_policy(parent, env); + + if(!parent_policy) + { + result = axis2_policy_include_get_policy(policy_include, env); + + } + else + { + if(axis2_policy_include_get_policy(policy_include, env)) + { + neethi_policy_t *temp_policy = NULL; + parent_policy = (neethi_policy_t *)neethi_engine_get_normalize(env, AXIS2_FALSE, + parent_policy); + temp_policy = axis2_policy_include_get_policy(policy_include, env); + temp_policy = (neethi_policy_t *)neethi_engine_get_normalize(env, AXIS2_FALSE, + temp_policy); + /* result = (neethi_policy_t*) neethi_engine_merge(env, parent_policy, + axis2_policy_include_get_policy(policy_include, env)); */ + result = (neethi_policy_t *)neethi_engine_merge(env, parent_policy, temp_policy); + + } + else + { + result = parent_policy; + } + } + } + else + { + result = axis2_policy_include_get_policy(policy_include, env); + } + + return result; + /*policy_include->effective_policy = result; + return AXIS2_SUCCESS; */ +} + +AXIS2_EXTERN neethi_policy_t *AXIS2_CALL +axis2_policy_include_get_policy( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + axis2_policy_include_calculate_policy(policy_include, env); + return policy_include->policy; +} + +AXIS2_EXTERN neethi_policy_t *AXIS2_CALL +axis2_policy_include_get_effective_policy( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + /*if (policy_include->effective_policy) + return policy_include->effective_policy; + */ + return axis2_policy_include_calculate_effective_policy(policy_include, env); + /*return policy_include->effective_policy; */ +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_policy_include_get_policy_elements( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + axutil_array_list_t *policy_elements_list = NULL; + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + policy_elements_list = axutil_array_list_create(env, 10); + + for(hi = axutil_hash_first(policy_include->wrapper_elements, env); hi; hi = axutil_hash_next( + env, hi)) + { + axis2_policy_wrapper_t *wrapper = NULL; + + axutil_hash_this(hi, NULL, NULL, &val); + wrapper = (axis2_policy_wrapper_t *)val; + + if(wrapper) + { + axutil_array_list_add(policy_elements_list, env, wrapper->value); + } + } + return policy_elements_list; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_policy_include_get_policy_elements_with_type( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + int type) +{ + axutil_array_list_t *policy_elements_list = NULL; + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + policy_elements_list = axutil_array_list_create(env, 10); + + for(hi = axutil_hash_first(policy_include->wrapper_elements, env); hi; hi = axutil_hash_next( + env, hi)) + { + axis2_policy_wrapper_t *wrapper = NULL; + + axutil_hash_this(hi, NULL, NULL, &val); + wrapper = (axis2_policy_wrapper_t *)val; + + if(wrapper && wrapper->type == type) + { + axutil_array_list_add(policy_elements_list, env, wrapper->value); + } + } + return policy_elements_list; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_register_policy( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + axis2_char_t * key, + neethi_policy_t * policy) +{ + if(policy_include->registry) + { + return neethi_registry_register(policy_include->registry, env, key, policy); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN neethi_policy_t *AXIS2_CALL +axis2_policy_include_get_policy_with_key( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + axis2_char_t * key) +{ + if(policy_include->registry) + { + return neethi_registry_lookup(policy_include->registry, env, key); + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_add_policy_element( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + int type, + neethi_policy_t * policy) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!neethi_policy_get_name(policy, env) && !neethi_policy_get_id(policy, env)) + { + axis2_char_t *uuid = axutil_uuid_gen(env); + neethi_policy_set_id(policy, env, uuid); + if(uuid) + { + AXIS2_FREE(env->allocator, uuid); + uuid = NULL; + } + } + + if(policy_include->wrapper_elements) + { + axis2_policy_wrapper_t *wrapper = NULL; + + wrapper = (axis2_policy_wrapper_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_policy_wrapper_t)); + if(wrapper) + { + axis2_char_t *policy_name = NULL; + wrapper->type = type; + wrapper->value = policy; + + policy_name = neethi_policy_get_name(policy, env); + if(!policy_name) + policy_name = neethi_policy_get_id(policy, env); + + if(policy_name) + { + axutil_hash_set(policy_include->wrapper_elements, policy_name, + AXIS2_HASH_KEY_STRING, wrapper); + if(policy_include->registry) + { + neethi_registry_register(policy_include->registry, env, policy_name, policy); + } + return AXIS2_SUCCESS; + } + } + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_add_policy_reference_element( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + int type, + neethi_reference_t * reference) +{ + axis2_policy_wrapper_t *wrapper = NULL; + + wrapper + = (axis2_policy_wrapper_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_policy_wrapper_t)); + if(wrapper) + { + wrapper->type = type; + wrapper->value = reference; + axutil_hash_set(policy_include->wrapper_elements, neethi_reference_get_uri(reference, env), + AXIS2_HASH_KEY_STRING, wrapper); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_remove_policy_element( + axis2_policy_include_t * policy_include, + const axutil_env_t * env, + axis2_char_t * policy_uri) +{ + if(policy_include->wrapper_elements) + { + axutil_hash_set(policy_include->wrapper_elements, policy_uri, AXIS2_HASH_KEY_STRING, NULL); + } + if(policy_include->registry) + { + neethi_registry_register(policy_include->registry, env, policy_uri, NULL); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_policy_include_remove_all_policy_element( + axis2_policy_include_t * policy_include, + const axutil_env_t * env) +{ + if(policy_include->wrapper_elements) + { + axutil_hash_free(policy_include->wrapper_elements, env); + } + return AXIS2_SUCCESS; +} diff --git a/src/core/description/svc.c b/src/core/description/svc.c new file mode 100644 index 0000000..72f4597 --- /dev/null +++ b/src/core/description/svc.c @@ -0,0 +1,1543 @@ +/* + * 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_svc.h> +#include <axis2_addr.h> +#include <axutil_property.h> +#include <axis2_module.h> +#include "../deployment/axis2_desc_builder.h" +#include <axis2_svc_skeleton.h> +#include <axutil_thread.h> +#include <axis2_core_utils.h> + +struct axis2_svc +{ + axis2_svc_grp_t *parent; + axis2_char_t *axis_svc_name; + + /** To keep last update time of the service */ + long last_update; + axis2_char_t *filename; + + /** To store module descriptions at deploy time parsing */ + axutil_array_list_t *module_list; + + /** Service description */ + axis2_char_t *svc_desc; + + /** wsdl file path */ + axis2_char_t *wsdl_path; + + /** service folder path */ + axis2_char_t *folder_path; + + /** + * WSDL related stuff + */ + axutil_hash_t *ns_map; + /* Count of the entries in the namespace map */ + int ns_count; + /* To keep the XML scheama either from WSDL or + * C2WSDL(in the future) + */ + axutil_array_list_t *schema_list; + + /** + * A table that keeps a mapping of unique XSD names (Strings) + * against the schema objects. This is populated in the first + * instance the schemas are asked for and then used to serve + * the subsequent requests + */ + axutil_hash_t *schema_mapping_table; + + /** + * This is where operations are kept + */ + axutil_hash_t *op_alias_map; + + /** + * This is where action mappings are kept + */ + axutil_hash_t *op_action_map; + + /** + * This is where REST mappings are kept + */ + axutil_hash_t *op_rest_map; + + /** + * Keeps track whether the schema locations are adjusted + */ + axis2_bool_t schema_loc_adjusted; + + /** + * A custom schema name prefix. if set this will be used to + * modify the schema names + */ + axis2_char_t *custom_schema_name_prefix; + + /** + * A custom schema name suffix. will be attached to the + * schema file name when the files are uniquely named. + * A good place to add a file extension if needed + */ + axis2_char_t *custom_schema_name_suffix; + /* To store the target namespace for the schema */ + axis2_char_t *schema_target_ns; + axis2_char_t *schema_target_ns_prefix; + /* To keep the service target name space */ + axis2_char_t *target_ns; + axis2_char_t *target_ns_prefix; + /* Used for schema name calculations */ + int sc_calc_count; + + void *impl_class; + axutil_qname_t *qname; + axis2_char_t *style; + axutil_array_list_t *engaged_module_list; + + /** Parameter container to hold service related parameters */ + struct axutil_param_container *param_container; + + /** Flow container that encapsulates the flow related data */ + struct axis2_flow_container *flow_container; + + /** Base description struct */ + axis2_desc_t *base; + + /* Mutex to avoid loading the same service dll twice */ + axutil_thread_mutex_t *mutex; +}; + +AXIS2_EXTERN axis2_svc_t *AXIS2_CALL +axis2_svc_create( + const axutil_env_t * env) +{ + axis2_svc_t *svc = NULL; + + svc = (axis2_svc_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_t)); + if(!svc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + svc->parent = NULL; + svc->axis_svc_name = NULL; + svc->filename = NULL; + svc->svc_desc = NULL; + svc->wsdl_path = NULL; + svc->folder_path = NULL; + svc->last_update = 0; + svc->param_container = NULL; + svc->flow_container = NULL; + svc->op_alias_map = NULL; + svc->op_action_map = NULL; + svc->op_rest_map = NULL; + svc->module_list = NULL; + svc->ns_map = NULL; + svc->ns_count = 0; + svc->schema_list = NULL; + svc->schema_mapping_table = NULL; + svc->schema_loc_adjusted = AXIS2_FALSE; + svc->custom_schema_name_prefix = NULL; + svc->custom_schema_name_suffix = NULL; + svc->schema_target_ns = NULL; + svc->schema_target_ns_prefix = NULL; + svc->target_ns = NULL; + svc->target_ns_prefix = NULL; + svc->sc_calc_count = 0; + svc->impl_class = NULL; + svc->qname = NULL; + svc->style = NULL; + svc->base = NULL; + + svc->param_container = axutil_param_container_create(env); + if(!svc->param_container) + { + axis2_svc_free(svc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service param container creation failed"); + return NULL; + } + + svc->flow_container = axis2_flow_container_create(env); + if(!svc->flow_container) + { + axis2_svc_free(svc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service flow container creation failed"); + return NULL; + } + + svc->op_alias_map = axutil_hash_make(env); + if(!svc->op_alias_map) + { + axis2_svc_free(svc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service operation alias map creation failed"); + return NULL; + } + + svc->op_action_map = axutil_hash_make(env); + if(!svc->op_action_map) + { + axis2_svc_free(svc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service operation action map creation failed"); + return NULL; + } + + svc->op_rest_map = axutil_hash_make(env); + if(!svc->op_rest_map) + { + axis2_svc_free(svc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service operation rest map creation failed"); + return NULL; + } + + /** Create module list of default size */ + svc->module_list = axutil_array_list_create(env, 0); + if(!svc->module_list) + { + axis2_svc_free(svc, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service module list creation failed"); + return NULL; + } + + svc->schema_list = axutil_array_list_create(env, AXIS2_ARRAY_LIST_DEFAULT_CAPACITY); + if(!svc->schema_list) + { + axis2_svc_free(svc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service schema list creation failed"); + return NULL; + } + + svc->engaged_module_list = axutil_array_list_create(env, AXIS2_ARRAY_LIST_DEFAULT_CAPACITY); + if(!svc->engaged_module_list) + { + axis2_svc_free(svc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service engaged modules list creation failed"); + return NULL; + } + + svc->schema_loc_adjusted = AXIS2_FALSE; + if(svc->schema_target_ns_prefix) + { + AXIS2_FREE(env->allocator, svc->schema_target_ns_prefix); + svc->schema_target_ns_prefix = NULL; + } + svc->schema_target_ns_prefix = axutil_strdup(env, "ns"); + + if(svc->target_ns) + { + AXIS2_FREE(env->allocator, svc->target_ns); + svc->target_ns = NULL; + } + svc->target_ns = axutil_strdup(env, "http://ws.apache.org/axis2"); + + if(svc->target_ns_prefix) + { + AXIS2_FREE(env->allocator, svc->target_ns_prefix); + svc->target_ns_prefix = NULL; + } + svc->target_ns_prefix = axutil_strdup(env, "tns"); + svc->sc_calc_count = 0; + + svc->base = axis2_desc_create(env); + if(!svc->base) + { + axis2_svc_free(svc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service base creation failed"); + return NULL; + } + svc->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT); + if(!svc->mutex) + { + axis2_svc_free(svc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service mutex creation failed"); + return NULL; + } + return svc; +} + +AXIS2_EXTERN axis2_svc_t *AXIS2_CALL +axis2_svc_create_with_qname( + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + axis2_svc_t *svc = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, qname, NULL); + + svc = axis2_svc_create(env); + if(!svc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service creation failed for name %s", + axutil_qname_get_localpart(qname, env)); + return NULL; + } + + status = axis2_svc_set_qname(svc, env, qname); + if(AXIS2_FAILURE == status) + { + axis2_svc_free(svc, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting name %s to service failed", + axutil_qname_get_localpart(qname, env)); + return NULL; + } + + return svc; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_free( + axis2_svc_t * svc, + const axutil_env_t * env) +{ + if(svc->impl_class) + { + AXIS2_SVC_SKELETON_FREE((axis2_svc_skeleton_t *)svc->impl_class, env); + } + if(svc->param_container) + { + axutil_param_container_free(svc->param_container, env); + } + + if(svc->flow_container) + { + axis2_flow_container_free(svc->flow_container, env); + } + + if(svc->filename) + { + AXIS2_FREE(env->allocator, svc->filename); + svc->filename = NULL; + } + + if(svc->svc_desc) + { + AXIS2_FREE(env->allocator, svc->svc_desc); + svc->svc_desc = NULL; + } + + svc->parent = NULL; + + if(svc->module_list) + { + int i = 0; + int size = 0; + + size = axutil_array_list_size(svc->module_list, env); + for(i = 0; i < size; i++) + { + axutil_qname_t *qname = NULL; + qname = axutil_array_list_get(svc->module_list, env, i); + if(qname) + { + axutil_qname_free(qname, env); + } + } + axutil_array_list_free(svc->module_list, env); + } + + if(svc->schema_list) + { + axutil_array_list_free(svc->schema_list, env); + } + + if(svc->engaged_module_list) + { + axutil_array_list_free(svc->engaged_module_list, env); + } + + if(svc->axis_svc_name) + { + AXIS2_FREE(env->allocator, svc->axis_svc_name); + svc->axis_svc_name = NULL; + } + + if(svc->op_alias_map) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + for(hi = axutil_hash_first(svc->op_alias_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + if(axis2_op_is_from_module((axis2_op_t *)val, env) == AXIS2_FALSE) + { + axis2_op_free((axis2_op_t *)val, env); + } + val = NULL; + } + } + + axutil_hash_free(svc->op_alias_map, env); + } + + if(svc->op_action_map) + { + axutil_hash_index_t *hi = NULL; + const void *key = NULL; + + for(hi = axutil_hash_first(svc->op_action_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, &key, NULL, NULL); + + if(key) + { + AXIS2_FREE(env->allocator, (axis2_char_t *)key); + key = NULL; + } + } + axutil_hash_free(svc->op_action_map, env); + } + + if(svc->op_rest_map) + { + axis2_core_utils_free_rest_map(env, svc->op_rest_map); + } + + if(svc->schema_target_ns_prefix) + { + AXIS2_FREE(env->allocator, svc->schema_target_ns_prefix); + svc->schema_target_ns_prefix = NULL; + } + + if(svc->target_ns) + { + AXIS2_FREE(env->allocator, svc->target_ns); + svc->target_ns = NULL; + } + + if(svc->wsdl_path) + { + AXIS2_FREE(env->allocator, svc->wsdl_path); + svc->wsdl_path = NULL; + } + + if(svc->folder_path) + { + AXIS2_FREE(env->allocator, svc->folder_path); + svc->folder_path = NULL; + } + + if(svc->target_ns_prefix) + { + AXIS2_FREE(env->allocator, svc->target_ns_prefix); + svc->target_ns_prefix = NULL; + } + + if(svc->qname) + { + axutil_qname_free(svc->qname, env); + } + + if(svc->style) + { + AXIS2_FREE(env->allocator, svc->style); + } + + if(svc->base) + { + axis2_desc_free(svc->base, env); + } + if(svc->mutex) + { + axutil_thread_mutex_destroy(svc->mutex); + } + if(svc) + { + AXIS2_FREE(env->allocator, svc); + svc = NULL; + } + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_add_op( + axis2_svc_t * svc, + const axutil_env_t * env, + axis2_op_t * op) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_msg_recv_t *msg_recv = NULL; + const axutil_qname_t *qname = NULL; + axis2_char_t *key = NULL; + const axis2_char_t *svcname = NULL; + axutil_array_list_t *mappings_list = NULL; + int size = 0; + int j = 0; + + AXIS2_PARAM_CHECK(env->error, op, AXIS2_FAILURE); + svcname = axis2_svc_get_name(svc, env); + qname = axis2_op_get_qname(op, env); + if(qname) + key = axutil_qname_get_localpart(qname, env); + mappings_list = axis2_op_get_wsamapping_list(op, env); + /* Adding action mappings into service */ + if(mappings_list) + size = axutil_array_list_size(mappings_list, env); + for(j = 0; j < size; j++) + { + axis2_char_t *mapping = NULL; + + mapping = (axis2_char_t *)axutil_array_list_get(mappings_list, env, j); + status = axis2_svc_add_mapping(svc, env, mapping, op); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding operation %s to service %s mapping list failed", svcname, key); + return status; + } + } + + status = axis2_op_set_parent(op, env, svc); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting service %s as operation %s parent failed", + svcname, key); + return status; + } + msg_recv = axis2_op_get_msg_recv(op, env); + if(msg_recv == NULL) + { + msg_recv = axis2_desc_builder_load_default_msg_recv(env); + axis2_op_set_msg_recv(op, env, msg_recv); + } + if(key) + { + /* If service defines the operation, then we should not override with module level + * operation. Module operations are global. If any setting to be modified, those operations + * can be defined in service */ + if(!axutil_hash_get(svc->op_alias_map, key, AXIS2_HASH_KEY_STRING)) + { + axutil_hash_set(svc->op_alias_map, key, AXIS2_HASH_KEY_STRING, op); + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_svc_get_op_with_qname( + const axis2_svc_t * svc, + const axutil_env_t * env, + const axutil_qname_t * op_qname) +{ + axis2_op_t *op = NULL; + axis2_char_t *nc_name = NULL; + + axis2_char_t *nc_tmp = NULL; + /* This is just for the sake of comparison, + * and must not be used to change the passed value + */ + axis2_bool_t is_matched = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, op_qname, NULL); + + nc_name = axutil_qname_get_localpart(op_qname, env); + nc_tmp = nc_name; + + op = axutil_hash_get(svc->op_alias_map, nc_tmp, AXIS2_HASH_KEY_STRING); + if(op) + { + return op; + } + op = axutil_hash_get(svc->op_action_map, nc_tmp, AXIS2_HASH_KEY_STRING); + if(op) + { + return op; + } + + if(*nc_tmp && svc->op_action_map) + { + axutil_hash_index_t *hi = NULL; + const void *key = NULL; + + for(hi = axutil_hash_first(svc->op_action_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, &key, NULL, NULL); + + nc_tmp = nc_name; + + if(key) + { + axis2_char_t *search = NULL; + axis2_bool_t match_start = AXIS2_TRUE; + axis2_char_t *search_tmp = NULL; + + search = (axis2_char_t *)key; + + if(!axutil_strchr(search, '*')) + { + if(axutil_strstr(nc_tmp, search)) + { + axis2_char_t *comp_tmp = NULL; + + comp_tmp = axutil_strstr(nc_tmp, search); + if(strlen(comp_tmp) == strlen(search)) + { + nc_tmp = (axis2_char_t *)key; + is_matched = AXIS2_TRUE; + break; + } + } + continue; + } + + if(search[0] == '*') + { + search++; + if(!*search) + { + nc_tmp = (axis2_char_t *)key; + is_matched = AXIS2_TRUE; + break; + } + else if(axutil_strchr(search, '*')) + { + continue; + } + match_start = AXIS2_FALSE; + } + while(search && *search) + { + int length = 0; + axis2_char_t *loc_tmp = NULL; + + if(search_tmp) + { + AXIS2_FREE(env->allocator, search_tmp); + search_tmp = NULL; + } + loc_tmp = axutil_strchr(search, '*'); + if(loc_tmp && *loc_tmp) + { + if(!loc_tmp[1]) + { + is_matched = AXIS2_TRUE; + break; + } + length = (int)(loc_tmp - search); + /* We are sure that the difference lies within the int range */ + search_tmp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, + sizeof(axis2_char_t) * (length + 1))); + strncpy(search_tmp, search, length); + search_tmp[length] = '\0'; + } + else if(axutil_strstr(nc_tmp, search)) + { + axis2_char_t *comp_tmp = NULL; + + comp_tmp = axutil_strstr(nc_tmp, search); + if(strlen(comp_tmp) == strlen(search)) + { + nc_tmp = (axis2_char_t *)key; + is_matched = AXIS2_TRUE; + break; + } + break; + } + else + { + break; + } + if(search_tmp && axutil_strstr(nc_tmp, search_tmp)) + { + if(match_start && !(axutil_strncmp(nc_tmp, search, length) == 0)) + { + break; + } + else if(!match_start) + { + match_start = AXIS2_TRUE; + } + } + else + { + break; + } + search += axutil_strlen(search_tmp) + 1; + nc_tmp = axutil_strstr(nc_tmp, search_tmp) + axutil_strlen(search_tmp); + } + if(search_tmp) + { + AXIS2_FREE(env->allocator, search_tmp); + search_tmp = NULL; + } + if(is_matched || !*search) + { + nc_tmp = (axis2_char_t *)key; + is_matched = AXIS2_TRUE; + break; + } + } + } + } + if(!is_matched) + { + nc_tmp = nc_name; + } + + op = axutil_hash_get(svc->op_alias_map, nc_tmp, AXIS2_HASH_KEY_STRING); + if(op) + { + return op; + } + return (axis2_op_t *)axutil_hash_get(svc->op_action_map, nc_tmp, AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_svc_get_rest_op_list_with_method_and_location( + const axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * method, + const axis2_char_t * location) +{ + axutil_array_list_t *op_list = NULL; + axis2_char_t *key = NULL; + axis2_char_t *loc_str = NULL; + axis2_char_t *loc_str_tmp = NULL; + axis2_char_t *rindex = NULL; + int plen; + + AXIS2_PARAM_CHECK(env->error, method, NULL); + AXIS2_PARAM_CHECK(env->error, location, NULL); + + loc_str_tmp = (axis2_char_t *)location; /* Casted to facilitate loop */ + if(loc_str_tmp[1] == '/') + { + loc_str_tmp++; + } /* ignore any '/' at the beginning */ + if(strchr(loc_str_tmp, '?')) + { + axis2_char_t *temp = NULL; + + temp = strchr(loc_str_tmp, '?'); + temp[0] = '\0'; + } /* ignore block after '?' */ + do + { + axis2_char_t *temp = NULL; + temp = strchr(loc_str_tmp, '{'); + if(temp) + { + loc_str_tmp = temp; + } + else + { + loc_str_tmp += strlen(loc_str_tmp); + break; + } + } + while(loc_str_tmp[1] && loc_str_tmp[1] == '{'); + + loc_str = (axis2_char_t *)axutil_strmemdup(location, (loc_str_tmp - location), env); + + rindex = axutil_rindex(loc_str, '/'); + if(rindex && *rindex) + { + loc_str_tmp = axutil_string_substring_ending_at(loc_str, (int)(rindex - loc_str)); + /* We are sure that the difference lies within the int range */ + } + else + { + loc_str_tmp = loc_str; + } + + plen = axutil_strlen(method) + axutil_strlen(loc_str_tmp) + 2; + key = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * plen)); + sprintf(key, "%s:%s", method, loc_str_tmp); + AXIS2_FREE(env->allocator, loc_str); + op_list = (axutil_array_list_t *)axutil_hash_get(svc->op_rest_map, key, AXIS2_HASH_KEY_STRING); + AXIS2_FREE(env->allocator, key); + return op_list; +} + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_svc_get_op_with_name( + const axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * nc_name) +{ + AXIS2_PARAM_CHECK(env->error, nc_name, NULL); + + return (axis2_op_t *)axutil_hash_get(svc->op_alias_map, nc_name, AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_svc_get_all_ops( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->op_alias_map; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_parent( + axis2_svc_t * svc, + const axutil_env_t * env, + axis2_svc_grp_t * svc_grp) +{ + AXIS2_PARAM_CHECK(env->error, svc_grp, AXIS2_FAILURE); + + svc->parent = svc_grp; + if(svc_grp) + { + axis2_desc_set_parent(svc->base, env, axis2_svc_grp_get_base(svc_grp, env)); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_svc_grp_t *AXIS2_CALL +axis2_svc_get_parent( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->parent; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_qname( + axis2_svc_t * svc, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + AXIS2_PARAM_CHECK(env->error, qname, AXIS2_FAILURE); + if(svc->qname) + { + axutil_qname_free(svc->qname, env); + } + + if(qname) + { + svc->qname = axutil_qname_clone((axutil_qname_t *)qname, env); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axutil_qname_t *AXIS2_CALL +axis2_svc_get_qname( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->qname; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_add_param( + axis2_svc_t * svc, + const axutil_env_t * env, + axutil_param_t * param) +{ + axis2_char_t *paramname = NULL; + const axis2_char_t *svcname = axis2_svc_get_name(svc, env); + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FAILURE); + paramname = axutil_param_get_name(param, env); + + if(axis2_svc_is_param_locked(svc, env, axutil_param_get_name(param, env))) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PARAMETER_LOCKED_CANNOT_OVERRIDE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Parameter %s is locked for service %s", paramname, + svcname); + return AXIS2_FAILURE; + } + return axutil_param_container_add_param(svc->param_container, env, param); +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_svc_get_param( + const axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * name) +{ + axutil_param_t *param = NULL; + AXIS2_PARAM_CHECK(env->error, name, NULL); + + param = axutil_param_container_get_param(svc->param_container, env, name); + if(!param && svc->parent) + { + param = axis2_svc_grp_get_param(svc->parent, env, name); + } + return param; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_remove_param( + const axis2_svc_t *svc, + const axutil_env_t *env, + const axis2_char_t *param_name) +{ + axis2_status_t status = AXIS2_FAILURE; + status = axutil_param_container_delete_param(svc->param_container, env, param_name); + return status; +} + + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_svc_get_all_params( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return axutil_param_container_get_params(svc->param_container, env); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_svc_is_param_locked( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + axis2_bool_t locked = AXIS2_FALSE; + axutil_param_t *param = NULL; + axis2_svc_grp_t *parent = NULL; + axis2_bool_t ret = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FALSE); + + /* Checking the locked value of parent */ + + parent = axis2_svc_get_parent(svc, env); + if(parent) + locked = axis2_svc_grp_is_param_locked(parent, env, param_name); + if(parent && locked) + { + return AXIS2_TRUE; + } + param = axis2_svc_get_param(svc, env, param_name); + if(param) + { + ret = axutil_param_is_locked(param, env); + } + return ret; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_engage_module( + axis2_svc_t * svc, + const axutil_env_t * env, + axis2_module_desc_t * module_desc, + axis2_conf_t * conf) +{ + axis2_phase_resolver_t *phase_resolver = NULL; + axis2_status_t status = AXIS2_FAILURE; + const axis2_char_t *svcname = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_svc_engage_module"); + + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + + svcname = axis2_svc_get_name(svc, env); + phase_resolver = axis2_phase_resolver_create_with_config(env, conf); + if(!phase_resolver) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase resolver failed for service %s", + svcname); + + return AXIS2_FAILURE; + } + + status = axis2_phase_resolver_engage_module_to_svc(phase_resolver, env, svc, module_desc); + if(status) + { + const axutil_qname_t *qname = NULL; + status = axutil_array_list_add(svc->engaged_module_list, env, module_desc); + qname = axis2_module_desc_get_qname(module_desc, env); + axis2_svc_add_module_qname(svc, env, qname); + } + + if(phase_resolver) + { + axis2_phase_resolver_free(phase_resolver, env); + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_svc_engage_module"); + + return status; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_svc_is_module_engaged( + axis2_svc_t * svc, + const axutil_env_t * env, + axutil_qname_t * module_qname) +{ + int i = 0, size = 0; + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_svc_is_module_engaged"); + size = axutil_array_list_size(svc->engaged_module_list, env); + for(i = 0; i < size; i++) + { + const axutil_qname_t *module_qname_l = NULL; + axis2_module_desc_t *module_desc_l = NULL; + + module_desc_l = (axis2_module_desc_t *)axutil_array_list_get(svc->engaged_module_list, env, + i); + module_qname_l = axis2_module_desc_get_qname(module_desc_l, env); + + if(axutil_qname_equals(module_qname, env, module_qname_l)) + { + return AXIS2_TRUE; + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_svc_is_module_engaged"); + return AXIS2_FALSE; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_svc_get_engaged_module_list( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->engaged_module_list; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_disengage_module( + axis2_svc_t * svc, + const axutil_env_t * env, + axis2_module_desc_t * module_desc, + axis2_conf_t * conf) +{ + axis2_phase_resolver_t *phase_resolver = NULL; + axis2_status_t status = AXIS2_FAILURE; + const axis2_char_t *svcname = NULL; + + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + svcname = axis2_svc_get_name(svc, env); + + phase_resolver = axis2_phase_resolver_create_with_config(env, conf); + if(!phase_resolver) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase resolver failed for service %s", + svcname); + return AXIS2_FAILURE; + } + status = axis2_phase_resolver_disengage_module_from_svc(phase_resolver, env, svc, module_desc); + + axis2_phase_resolver_free(phase_resolver, env); + + return status; +} + +/** + * Here we extract all operations defined in module.xml and built execution + * chains for them by calling axis2_phase_resolver_build_execution_chains_for_module_op() + * function. Within that function handlers of the modules defined for that + * operation are added to module operation chains appropriately. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_add_module_ops( + axis2_svc_t * svc, + const axutil_env_t * env, + axis2_module_desc_t * module_desc, + axis2_conf_t * conf) +{ + axutil_hash_t *map = NULL; + axutil_hash_index_t *index = NULL; + axis2_phase_resolver_t *phase_resolver = NULL; + axis2_op_t *op_desc = NULL; + axis2_status_t status = AXIS2_FAILURE; + const axis2_char_t *svcname = NULL; + axis2_char_t *modname = NULL; + axis2_char_t *opname = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_svc_add_module_ops"); + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + svcname = axis2_svc_get_name(svc, env); + modname = axutil_qname_get_localpart(axis2_module_desc_get_qname(module_desc, env), env); + map = axis2_module_desc_get_all_ops(module_desc, env); + phase_resolver = axis2_phase_resolver_create_with_config_and_svc(env, conf, svc); + if(!phase_resolver) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase resolver failed for service %s", + svcname); + return AXIS2_FAILURE; + } + for(index = axutil_hash_first(map, env); index; index = axutil_hash_next(env, index)) + { + void *v = NULL; + axutil_hash_this(index, NULL, NULL, &v); + op_desc = (axis2_op_t *)v; + opname = axutil_qname_get_localpart(axis2_op_get_qname(op_desc, env), env); + status = axis2_phase_resolver_build_execution_chains_for_module_op(phase_resolver, env, + op_desc); + + if(AXIS2_SUCCESS != status) + { + if(phase_resolver) + { + axis2_phase_resolver_free(phase_resolver, env); + } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Builidng module operation %s failed for module %s", opname, modname); + return status; + } + + status = axis2_svc_add_op(svc, env, op_desc); + if(AXIS2_SUCCESS != status) + { + if(phase_resolver) + { + axis2_phase_resolver_free(phase_resolver, env); + } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding operation %s to service %s failed", + opname, svcname); + return status; + } + + } + + if(phase_resolver) + { + axis2_phase_resolver_free(phase_resolver, env); + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_svc_add_module_ops"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_get_name( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + if(svc->qname) + { + return axutil_qname_get_localpart(svc->qname, env); + } + + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_name( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * axis_svc_name) +{ + AXIS2_PARAM_CHECK(env->error, axis_svc_name, AXIS2_FAILURE); + + if(svc->axis_svc_name) + { + AXIS2_FREE(env->allocator, svc->axis_svc_name); + svc->axis_svc_name = NULL; + } + svc->axis_svc_name = axutil_strdup(env, axis_svc_name); + if(!svc->axis_svc_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_last_update( + axis2_svc_t * svc, + const axutil_env_t * env) +{ + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN long AXIS2_CALL +axis2_svc_get_last_update( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->last_update; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_get_file_name( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->filename; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_file_name( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * filename) +{ + AXIS2_PARAM_CHECK(env->error, filename, AXIS2_FAILURE); + + if(svc->filename) + { + AXIS2_FREE(env->allocator, svc->filename); + svc->filename = NULL; + } + svc->filename = (axis2_char_t *)axutil_strdup(env, filename); + if(!svc->filename) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_get_svc_desc( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->svc_desc; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_svc_desc( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * svc_desc) +{ + AXIS2_PARAM_CHECK(env->error, svc_desc, AXIS2_FAILURE); + + if(svc->svc_desc) + { + AXIS2_FREE(env->allocator, svc->svc_desc); + svc->svc_desc = NULL; + } + svc->svc_desc = (axis2_char_t *)axutil_strdup(env, svc_desc); + if(!svc->svc_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_add_mapping( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * mapping_key, + axis2_op_t * op_desc) +{ + AXIS2_PARAM_CHECK(env->error, mapping_key, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, op_desc, AXIS2_FAILURE); + + axutil_hash_set(svc->op_action_map, axutil_strdup(env, mapping_key), AXIS2_HASH_KEY_STRING, + op_desc); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_add_rest_mapping( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * method, + const axis2_char_t * location, + axis2_op_t * op_desc) +{ + + axis2_char_t *mapping_url = NULL; + int key_len = 0; + axis2_char_t* question_char = NULL; + axis2_char_t* local_location_str = NULL; + axis2_status_t status = AXIS2_SUCCESS; + + local_location_str = (axis2_char_t *)location; /* Casted to facilitate loop */ + + /* skip the beginning '/' */ + if(*local_location_str == '/') + { + local_location_str++; + } + question_char = axutil_strchr(local_location_str, '?'); + if(question_char) + { + *question_char = '\0'; + } + + key_len = axutil_strlen(method) + axutil_strlen(local_location_str) + 2; + + mapping_url = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * key_len)); + if(!mapping_url) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create the rest mapping url"); + return AXIS2_FAILURE; + } + + sprintf(mapping_url, "%s:%s", method, local_location_str); + + status = axis2_core_utils_prepare_rest_mapping(env, mapping_url, svc->op_rest_map, op_desc); + + if(mapping_url) + { + AXIS2_FREE(env->allocator, mapping_url); + } + + /* restore the question character */ + if(question_char) + { + *question_char = '?'; + } + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_add_module_qname( + axis2_svc_t * svc, + const axutil_env_t * env, + const axutil_qname_t * module_qname) +{ + axutil_qname_t *qmodule_qname_l = NULL; + + AXIS2_PARAM_CHECK(env->error, module_qname, AXIS2_FAILURE); + + qmodule_qname_l = axutil_qname_clone((axutil_qname_t *)module_qname, env); + return axutil_array_list_add(svc->module_list, env, qmodule_qname_l); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_svc_get_all_module_qnames( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->module_list; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_get_target_ns( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->target_ns; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_target_ns( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * ns) +{ + AXIS2_PARAM_CHECK(env->error, ns, AXIS2_FAILURE); + + if(svc->target_ns) + { + AXIS2_FREE(env->allocator, svc->target_ns); + svc->target_ns = NULL; + } + svc->target_ns = axutil_strdup(env, ns); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_get_target_ns_prefix( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->target_ns_prefix; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_target_ns_prefix( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * prefix) +{ + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + + if(svc->target_ns_prefix) + { + AXIS2_FREE(env->allocator, svc->target_ns_prefix); + svc->target_ns_prefix = NULL; + } + svc->target_ns_prefix = axutil_strdup(env, prefix); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_svc_get_ns_map( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->ns_map; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_ns_map( + axis2_svc_t * svc, + const axutil_env_t * env, + axutil_hash_t * ns_map) +{ + axutil_hash_index_t *hi = NULL; + + AXIS2_PARAM_CHECK(env->error, ns_map, AXIS2_FAILURE); + + if(svc->ns_map) + { + for(hi = axutil_hash_first(svc->ns_map, env); hi; hi = axutil_hash_next(env, hi)) + { + void *value = NULL; + void *key = NULL; + axutil_hash_this(hi, (const void **)&key, NULL, (void **)&value); + if(key) + { + AXIS2_FREE(env->allocator, key); + key = NULL; + } + if(value) + { + AXIS2_FREE(env->allocator, value); + value = NULL; + } + } + axutil_hash_free(svc->ns_map, env); + } + svc->ns_map = ns_map; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_svc_swap_mapping_table( + axis2_svc_t * svc, + const axutil_env_t * env, + axutil_hash_t * orig_table) +{ + axutil_hash_t *new_table = NULL; + axutil_hash_index_t *hi = NULL; + + AXIS2_PARAM_CHECK(env->error, orig_table, NULL); + + new_table = axutil_hash_make(env); + + for(hi = axutil_hash_first(orig_table, env); env; hi = axutil_hash_next(env, hi)) + { + void *value = NULL; + void *key = NULL; + + axutil_hash_this(hi, (const void **)&key, NULL, (void **)&value); + axutil_hash_set(new_table, value, AXIS2_HASH_KEY_STRING, key); + } + return new_table; +} + +AXIS2_EXTERN void *AXIS2_CALL +axis2_svc_get_impl_class( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->impl_class; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_impl_class( + axis2_svc_t * svc, + const axutil_env_t * env, + void *impl_class) +{ + svc->impl_class = impl_class; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_svc_get_param_container( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->param_container; +} + +AXIS2_EXTERN axis2_flow_container_t *AXIS2_CALL +axis2_svc_get_flow_container( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->flow_container; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_get_svc_wsdl_path( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->wsdl_path; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_svc_wsdl_path( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * wsdl_path) +{ + AXIS2_PARAM_CHECK(env->error, wsdl_path, AXIS2_FAILURE); + svc->wsdl_path = (axis2_char_t *)axutil_strdup(env, wsdl_path); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_get_svc_folder_path( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->folder_path; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_set_svc_folder_path( + axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * folder_path) +{ + AXIS2_PARAM_CHECK(env->error, folder_path, AXIS2_FAILURE); + svc->folder_path = (axis2_char_t *)axutil_strdup(env, folder_path); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_desc_t *AXIS2_CALL +axis2_svc_get_base( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->base; +} + +AXIS2_EXTERN axutil_thread_mutex_t * AXIS2_CALL +axis2_svc_get_mutex( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->mutex; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_svc_get_rest_map( + const axis2_svc_t * svc, + const axutil_env_t * env) +{ + return svc->op_rest_map; +} + diff --git a/src/core/description/svc_grp.c b/src/core/description/svc_grp.c new file mode 100644 index 0000000..157b77a --- /dev/null +++ b/src/core/description/svc_grp.c @@ -0,0 +1,600 @@ +/* + * 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_svc_grp.h> +#include <axis2_conf_ctx.h> + +struct axis2_svc_grp +{ + + /** service group name */ + axis2_char_t *svc_grp_name; + + /** map of services */ + axutil_hash_t *svcs; + + /** to store service group modules QNames */ + axutil_array_list_t *module_qname_list; + + /** to store module ref at deploy time parsing */ + axis2_conf_t *parent; + + /** list of module references */ + axutil_array_list_t *module_list; + + /** parameter container to hold service related parameters */ + axutil_param_container_t *param_container; + + /** base description struct */ + axis2_desc_t *base; +}; + +AXIS2_EXTERN axis2_svc_grp_t *AXIS2_CALL +axis2_svc_grp_create( + const axutil_env_t * env) +{ + axis2_svc_grp_t *svc_grp = NULL; + svc_grp = (axis2_svc_grp_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_grp_t)); + + if(!svc_grp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + svc_grp->param_container = NULL; + svc_grp->module_qname_list = NULL; + svc_grp->svcs = NULL; + svc_grp->parent = NULL; + svc_grp->svc_grp_name = NULL; + svc_grp->module_list = NULL; + svc_grp->base = NULL; + + svc_grp->param_container = axutil_param_container_create(env); + if(!svc_grp->param_container) + { + axis2_svc_grp_free(svc_grp, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating parameter container failed"); + return NULL; + } + + svc_grp->module_qname_list = axutil_array_list_create(env, 20); + if(!svc_grp->module_qname_list) + { + axis2_svc_grp_free(svc_grp, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating module qnames list failed"); + return NULL; + } + + svc_grp->module_list = axutil_array_list_create(env, 0); + if(!svc_grp->module_list) + { + axis2_svc_grp_free(svc_grp, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating modules list failed"); + return NULL; + } + + svc_grp->svcs = axutil_hash_make(env); + if(!svc_grp->svcs) + { + axis2_svc_grp_free(svc_grp, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating services map failed"); + return NULL; + } + + svc_grp->base = axis2_desc_create(env); + if(!svc_grp->base) + { + axis2_svc_grp_free(svc_grp, env); + return NULL; + } + + return svc_grp; +} + +AXIS2_EXTERN axis2_svc_grp_t *AXIS2_CALL +axis2_svc_grp_create_with_conf( + const axutil_env_t * env, + axis2_conf_t * conf) +{ + axis2_svc_grp_t *svc_grp = NULL; + + AXIS2_PARAM_CHECK(env->error, conf, NULL); + + svc_grp = (axis2_svc_grp_t *)axis2_svc_grp_create(env); + if(svc_grp) + svc_grp->parent = conf; + if(conf) + { + axis2_desc_set_parent(svc_grp->base, env, axis2_conf_get_base(conf, env)); + } + + return svc_grp; + +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_svc_grp_free( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + if(svc_grp->param_container) + { + axutil_param_container_free(svc_grp->param_container, env); + } + + if(svc_grp->svc_grp_name) + { + AXIS2_FREE(env->allocator, svc_grp->svc_grp_name); + } + + if(svc_grp->svcs) + { + /* services are freed by arch_file_data */ + axutil_hash_free(svc_grp->svcs, env); + } + + if(svc_grp->module_qname_list) + { + axutil_array_list_free(svc_grp->module_qname_list, env); + } + + if(svc_grp->module_list) + { + axutil_array_list_free(svc_grp->module_list, env); + } + + if(svc_grp->base) + { + axis2_desc_free(svc_grp->base, env); + } + + if(svc_grp) + { + AXIS2_FREE(env->allocator, svc_grp); + } + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_set_name( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + const axis2_char_t * name) +{ + if(svc_grp->svc_grp_name) + AXIS2_FREE(env->allocator, svc_grp->svc_grp_name); + svc_grp->svc_grp_name = axutil_strdup(env, name); + if(!svc_grp->svc_grp_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No Memory"); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_svc_grp_get_name( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + return svc_grp->svc_grp_name; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_add_svc( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + axis2_status_t status = AXIS2_FAILURE; + const axutil_qname_t *svc_qname = NULL; + axis2_char_t *svc_name = NULL; + + AXIS2_PARAM_CHECK(env->error, svc, AXIS2_FAILURE); + + if(!svc_grp->svcs) + { + svc_grp->svcs = axutil_hash_make(env); + if(!svc_grp->svcs) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating services list failed"); + return AXIS2_FAILURE; + } + } + + svc_qname = axis2_svc_get_qname(svc, env); + svc_name = axutil_qname_to_string((axutil_qname_t *)svc_qname, env); + axutil_hash_set(svc_grp->svcs, svc_name, AXIS2_HASH_KEY_STRING, svc); + + status = axis2_svc_set_last_update(svc, env); + + if(AXIS2_SUCCESS != status) + { + /* remove the previously added service */ + axutil_hash_set(svc_grp->svcs, svc_name, AXIS2_HASH_KEY_STRING, NULL); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting last update failed for service %s", + svc_name); + + return status; + } + + status = axis2_svc_set_parent(svc, env, svc_grp); + if(AXIS2_SUCCESS != status) + { + /* remove the previously added service */ + axutil_hash_set(svc_grp->svcs, svc_name, AXIS2_HASH_KEY_STRING, NULL); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting parent failed for service %s", svc_name); + + return status; + } + + return status; +} + +AXIS2_EXTERN axis2_svc_t *AXIS2_CALL +axis2_svc_grp_get_svc( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + axis2_char_t *name = NULL; + + AXIS2_PARAM_CHECK(env->error, qname, NULL); + + name = axutil_qname_to_string((axutil_qname_t *)qname, env); + return (axis2_svc_t *)axutil_hash_get(svc_grp->svcs, name, AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_svc_grp_get_all_svcs( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + return svc_grp->svcs; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_remove_svc( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + const axutil_qname_t * svc_qname) +{ + axis2_svc_t *svc = NULL; + axis2_char_t *svc_name = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_name, AXIS2_FAILURE); + + svc = axis2_svc_grp_get_svc(svc_grp, env, svc_qname); + + svc_name = axutil_qname_to_string((axutil_qname_t *)svc_qname, env); + axutil_hash_set(svc_grp->svcs, svc_name, AXIS2_HASH_KEY_STRING, NULL); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_add_param( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + axutil_param_t * param) +{ + const axis2_char_t *svc_grp_name = axis2_svc_grp_get_name(svc_grp, env); + axis2_char_t *param_name = axutil_param_get_name(param, env); + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FAILURE); + if(axis2_svc_grp_is_param_locked(svc_grp, env, param_name)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PARAMETER_LOCKED_CANNOT_OVERRIDE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Parameter %s is locked for service group %s", + param_name, svc_grp_name); + return AXIS2_FAILURE; + } + return axutil_param_container_add_param(svc_grp->param_container, env, param); +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_svc_grp_get_param( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + const axis2_char_t * name) +{ + axutil_param_t *param = NULL; + AXIS2_PARAM_CHECK(env->error, name, NULL); + + param = axutil_param_container_get_param(svc_grp->param_container, env, name); + if(!param && svc_grp->parent) + { + param = axis2_conf_get_param(svc_grp->parent, env, name); + } + return param; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_remove_param( + const axis2_svc_grp_t *svc_grp, + const axutil_env_t *env, + const axis2_char_t *param_name) +{ + axis2_status_t status = AXIS2_FAILURE; + status = axutil_param_container_delete_param(svc_grp->param_container, env, param_name); + return status; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_svc_grp_get_all_params( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + return axutil_param_container_get_params(svc_grp->param_container, env); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_svc_grp_is_param_locked( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + axis2_bool_t locked = AXIS2_FALSE; + axis2_conf_t *parent = NULL; + axutil_param_t *param = NULL; + axis2_bool_t ret = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FALSE); + + parent = axis2_svc_grp_get_parent(svc_grp, env); + /* Checking the locked value of parent */ + if(parent) + { + locked = axis2_conf_is_param_locked(parent, env, param_name); + } + if(locked) + { + ret = AXIS2_TRUE; + } + param = axis2_svc_grp_get_param(svc_grp, env, param_name); + if(param && axutil_param_is_locked(param, env)) + { + ret = AXIS2_TRUE; + } + else + { + ret = AXIS2_FALSE; + } + return ret; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_add_module_qname( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + const axutil_qname_t * module_qname) +{ + return axutil_array_list_add(svc_grp->module_qname_list, env, module_qname); +} + +AXIS2_EXTERN axis2_conf_t *AXIS2_CALL +axis2_svc_grp_get_parent( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + return svc_grp->parent; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_set_parent( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + axis2_conf_t * parent) +{ + AXIS2_PARAM_CHECK(env->error, parent, AXIS2_FAILURE); + + if(svc_grp->parent) + axis2_conf_free(svc_grp->parent, env); + svc_grp->parent = parent; + if(parent) + { + axis2_desc_set_parent(svc_grp->base, env, axis2_conf_get_base(parent, env)); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_engage_module( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + const axutil_qname_t * module_name) +{ + int i = 0; + axis2_status_t status = AXIS2_FAILURE; + axutil_qname_t *modu = NULL; + axis2_char_t *modu_local = NULL; + axis2_char_t *module_name_local = NULL; + axutil_hash_t *svc_map = NULL; + axis2_phase_resolver_t *phase_resolver = NULL; + axis2_module_desc_t *module = NULL; + const axis2_char_t *svc_grp_name = axis2_svc_grp_get_name(svc_grp, env); + + int size = 0; + + AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE); + + size = axutil_array_list_size(svc_grp->module_qname_list, env); + for(i = 0; size; i++) + { + modu = axutil_array_list_get(svc_grp->module_qname_list, env, i); + modu_local = axutil_qname_get_localpart(modu, env); + module_name_local = axutil_qname_get_localpart(module_name, env); + if(!axutil_strcmp(modu_local, module_name_local)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MODULE_ALREADY_ENGAGED_TO_SVC_GRP, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Module %s is already engaged to service group %s", module_name_local, svc_grp_name); + + return AXIS2_FAILURE; + } + } + + svc_map = axis2_svc_grp_get_all_svcs(svc_grp, env); + if(!svc_map) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service map not found for service group %s", + svc_grp_name); + + return AXIS2_FAILURE; + } + + phase_resolver = axis2_phase_resolver_create_with_config(env, svc_grp->parent); + + if(!phase_resolver) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating phase resolver failed for service group %s", svc_grp_name); + + return AXIS2_FAILURE; + } + + module = axis2_conf_get_module(svc_grp->parent, env, module_name); + if(module) + { + axis2_svc_t *axis_svc = NULL; + axutil_hash_index_t *index = NULL; + + index = axutil_hash_first(svc_map, env); + while(index) + { + const axis2_char_t *svc_name = NULL; + void *v = NULL; + /* engage in per each service */ + axutil_hash_this(index, NULL, NULL, &v); + axis_svc = (axis2_svc_t *)v; + svc_name = axis2_svc_get_name(axis_svc, env); + status = axis2_phase_resolver_engage_module_to_svc(phase_resolver, env, axis_svc, + module); + + if(!status) + { + if(phase_resolver) + { + axis2_phase_resolver_free(phase_resolver, env); + } + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Engaging module %s to service %s failed", + module_name_local, svc_name); + + return status; + } + + index = axutil_hash_next(env, index); + } + } + + if(phase_resolver) + { + axis2_phase_resolver_free(phase_resolver, env); + } + + return axis2_svc_grp_add_module_qname(svc_grp, env, module_name); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_svc_grp_get_all_module_qnames( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + return svc_grp->module_qname_list; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_svc_grp_add_module_ref( + axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + const axutil_qname_t * moduleref) +{ + const axis2_char_t *svc_grp_name = NULL; + + AXIS2_PARAM_CHECK(env->error, moduleref, AXIS2_FAILURE); + svc_grp_name = axis2_svc_grp_get_name(svc_grp, env); + + if(!svc_grp->module_list) + { + svc_grp->module_list = axutil_array_list_create(env, 0); + if(!svc_grp->module_list) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating module list failed for service group %s", svc_grp_name); + return AXIS2_FAILURE; + } + } + + return axutil_array_list_add(svc_grp->module_list, env, moduleref); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_svc_grp_get_all_module_refs( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + return svc_grp->module_list; +} + +AXIS2_EXTERN axis2_svc_grp_ctx_t *AXIS2_CALL +axis2_svc_grp_get_svc_grp_ctx( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env, + axis2_conf_ctx_t * parent) +{ + axis2_svc_grp_ctx_t *svc_grp_ctx = NULL; + const axis2_char_t *svc_grp_name = NULL; + + AXIS2_PARAM_CHECK(env->error, parent, NULL); + svc_grp_name = axis2_svc_grp_get_name(svc_grp, env); + + svc_grp_ctx = axis2_svc_grp_ctx_create(env, (axis2_svc_grp_t *)svc_grp, parent); + if(!svc_grp_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating service group context failed for service group %s", svc_grp_name); + return NULL; + } + + return svc_grp_ctx; +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_svc_grp_get_param_container( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + return svc_grp->param_container; +} + +AXIS2_EXTERN axis2_desc_t *AXIS2_CALL +axis2_svc_grp_get_base( + const axis2_svc_grp_t * svc_grp, + const axutil_env_t * env) +{ + return svc_grp->base; +} + diff --git a/src/core/description/transport_in_desc.c b/src/core/description/transport_in_desc.c new file mode 100644 index 0000000..85885b6 --- /dev/null +++ b/src/core/description/transport_in_desc.c @@ -0,0 +1,305 @@ +/* + * 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_transport_in_desc.h> +#include <axis2_transport_receiver.h> + +struct axis2_transport_in_desc +{ + axis2_flow_t *in_flow; + axis2_flow_t *fault_in_flow; + AXIS2_TRANSPORT_ENUMS trans_enum; + + /** + * transport receiver will have a shallow copy, but will be freed by + * free function. + */ + axis2_transport_receiver_t *recv; + axis2_phase_t *in_phase; + axis2_phase_t *fault_phase; + + /** parameter container to hold transport in related parameters */ + axutil_param_container_t *param_container; +}; + +AXIS2_EXTERN axis2_transport_in_desc_t *AXIS2_CALL +axis2_transport_in_desc_create( + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS trans_enum) +{ + axis2_transport_in_desc_t *transport_in = NULL; + + transport_in = (axis2_transport_in_desc_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_transport_in_desc_t)); + + if(!transport_in) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + transport_in->trans_enum = trans_enum; + transport_in->in_phase = NULL; + transport_in->fault_phase = NULL; + transport_in->in_flow = NULL; + transport_in->fault_in_flow = NULL; + transport_in->recv = NULL; + transport_in->param_container = NULL; + + transport_in->param_container = axutil_param_container_create(env); + if(!transport_in->param_container) + { + axis2_transport_in_desc_free(transport_in, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return transport_in; +} + +void AXIS2_CALL +axis2_transport_in_desc_free( + axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env) +{ + if(transport_in->recv) + { + axis2_transport_receiver_free(transport_in->recv, env); + } + + if(transport_in->param_container) + { + axutil_param_container_free(transport_in->param_container, env); + } + + if(transport_in->in_flow) + { + axis2_flow_free(transport_in->in_flow, env); + } + + if(transport_in->fault_in_flow) + { + axis2_flow_free(transport_in->fault_in_flow, env); + } + + if(transport_in->in_phase) + { + axis2_phase_free(transport_in->in_phase, env); + } + + if(transport_in->fault_phase) + { + axis2_phase_free(transport_in->fault_phase, env); + } + + AXIS2_FREE(env->allocator, transport_in); + + return; +} + +void AXIS2_CALL +axis2_transport_in_desc_free_void_arg( + void *transport_in, + const axutil_env_t * env) +{ + axis2_transport_in_desc_t *transport_in_l = NULL; + + transport_in_l = (axis2_transport_in_desc_t *)transport_in; + axis2_transport_in_desc_free(transport_in_l, env); + return; +} + +AXIS2_TRANSPORT_ENUMS AXIS2_CALL +axis2_transport_in_desc_get_enum( + const axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env) +{ + return transport_in->trans_enum; +} + +axis2_status_t AXIS2_CALL +axis2_transport_in_desc_set_enum( + axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS trans_enum) +{ + transport_in->trans_enum = trans_enum; + return AXIS2_SUCCESS; +} + +axis2_flow_t *AXIS2_CALL +axis2_transport_in_desc_get_in_flow( + const axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env) +{ + return transport_in->in_flow; +} + +axis2_status_t AXIS2_CALL +axis2_transport_in_desc_set_in_flow( + axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env, + axis2_flow_t * in_flow) +{ + AXIS2_PARAM_CHECK(env->error, in_flow, AXIS2_FAILURE); + + if(transport_in->in_flow) + { + axis2_flow_free(transport_in->in_flow, env); + } + transport_in->in_flow = in_flow; + return AXIS2_SUCCESS; +} + +axis2_flow_t *AXIS2_CALL +axis2_transport_in_desc_get_fault_in_flow( + const axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env) +{ + return transport_in->fault_in_flow; +} + +axis2_status_t AXIS2_CALL +axis2_transport_in_desc_set_fault_in_flow( + axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env, + axis2_flow_t * fault_in_flow) +{ + AXIS2_PARAM_CHECK(env->error, fault_in_flow, AXIS2_FAILURE); + + if(transport_in->fault_in_flow) + { + axis2_flow_free(transport_in->fault_in_flow, env); + } + transport_in->fault_in_flow = fault_in_flow; + return AXIS2_SUCCESS; +} + +axis2_transport_receiver_t *AXIS2_CALL +axis2_transport_in_desc_get_recv( + const axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env) +{ + return transport_in->recv; +} + +axis2_status_t AXIS2_CALL +axis2_transport_in_desc_set_recv( + axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env, + axis2_transport_receiver_t * recv) +{ + AXIS2_PARAM_CHECK(env->error, recv, AXIS2_FAILURE); + + if(transport_in->recv) + { + axis2_transport_receiver_free(transport_in->recv, env); + } + + transport_in->recv = recv; + return AXIS2_SUCCESS; +} + +axis2_phase_t *AXIS2_CALL +axis2_transport_in_desc_get_in_phase( + const axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env) +{ + return transport_in->in_phase; +} + +axis2_status_t AXIS2_CALL +axis2_transport_in_desc_set_in_phase( + axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env, + axis2_phase_t * in_phase) +{ + AXIS2_PARAM_CHECK(env->error, in_phase, AXIS2_FAILURE); + + if(transport_in->in_phase) + { + axis2_phase_free(transport_in->in_phase, env); + } + transport_in->in_phase = in_phase; + return AXIS2_SUCCESS; +} + +axis2_phase_t *AXIS2_CALL +axis2_transport_in_desc_get_fault_phase( + const axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env) +{ + return transport_in->fault_phase; +} + +axis2_status_t AXIS2_CALL +axis2_transport_in_desc_set_fault_phase( + axis2_transport_in_desc_t * transport_in, + const axutil_env_t * env, + axis2_phase_t * fault_phase) +{ + AXIS2_PARAM_CHECK(env->error, fault_phase, AXIS2_FAILURE); + + if(transport_in->fault_phase) + { + axis2_phase_free(transport_in->fault_phase, env); + } + transport_in->fault_phase = fault_phase; + return AXIS2_SUCCESS; + +} + +axis2_status_t AXIS2_CALL +axis2_transport_in_desc_add_param( + axis2_transport_in_desc_t * transport_in_desc, + const axutil_env_t * env, + axutil_param_t * param) +{ + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FAILURE); + + return axutil_param_container_add_param(transport_in_desc-> param_container, env, param); +} + +axutil_param_t *AXIS2_CALL +axis2_transport_in_desc_get_param( + const axis2_transport_in_desc_t * transport_in_desc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + return axutil_param_container_get_param(transport_in_desc->param_container, env, param_name); +} + +axis2_bool_t AXIS2_CALL +axis2_transport_in_desc_is_param_locked( + axis2_transport_in_desc_t * transport_in_desc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FAILURE); + + return axutil_param_container_is_param_locked(transport_in_desc-> param_container, env, + param_name); +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_transport_in_desc_param_container( + const axis2_transport_in_desc_t * transport_in_desc, + const axutil_env_t * env) +{ + return transport_in_desc->param_container; +} + diff --git a/src/core/description/transport_out_desc.c b/src/core/description/transport_out_desc.c new file mode 100644 index 0000000..ec69f56 --- /dev/null +++ b/src/core/description/transport_out_desc.c @@ -0,0 +1,299 @@ +/* + * 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_transport_out_desc.h> + +struct axis2_transport_out_desc +{ + axis2_flow_t *out_flow; + axis2_flow_t *fault_out_flow; + AXIS2_TRANSPORT_ENUMS trans_enum; + axis2_transport_sender_t *sender; + axis2_phase_t *out_phase; + axis2_phase_t *fault_phase; + + /** parameter container that holds parameter */ + axutil_param_container_t *param_container; +}; + +AXIS2_EXTERN axis2_transport_out_desc_t *AXIS2_CALL +axis2_transport_out_desc_create( + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS trans_enum) +{ + axis2_transport_out_desc_t *transport_out = NULL; + + transport_out = (axis2_transport_out_desc_t *)AXIS2_MALLOC(env-> allocator, + sizeof(axis2_transport_out_desc_t)); + + if(!transport_out) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + transport_out->trans_enum = trans_enum; + transport_out->out_phase = NULL; + transport_out->fault_phase = NULL; + transport_out->out_flow = NULL; + transport_out->fault_out_flow = NULL; + transport_out->sender = NULL; + transport_out->param_container = NULL; + + transport_out->param_container = axutil_param_container_create(env); + if(!transport_out->param_container) + { + axis2_transport_out_desc_free(transport_out, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return transport_out; +} + +void AXIS2_CALL +axis2_transport_out_desc_free( + axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env) +{ + if(transport_out->sender) + { + AXIS2_TRANSPORT_SENDER_FREE(transport_out->sender, env); + } + + if(transport_out->param_container) + { + axutil_param_container_free(transport_out->param_container, env); + } + + if(transport_out->out_flow) + { + axis2_flow_free(transport_out->out_flow, env); + } + + if(transport_out->fault_out_flow) + { + axis2_flow_free(transport_out->fault_out_flow, env); + } + + if(transport_out->out_phase) + { + axis2_phase_free(transport_out->out_phase, env); + } + + if(transport_out->fault_phase) + { + axis2_phase_free(transport_out->fault_phase, env); + } + + AXIS2_FREE(env->allocator, transport_out); + + return; +} + +void AXIS2_CALL +axis2_transport_out_desc_free_void_arg( + void *transport_out, + const axutil_env_t * env) +{ + axis2_transport_out_desc_t *transport_out_l = NULL; + + transport_out_l = (axis2_transport_out_desc_t *)transport_out; + axis2_transport_out_desc_free(transport_out_l, env); + return; +} + +AXIS2_TRANSPORT_ENUMS AXIS2_CALL +axis2_transport_out_desc_get_enum( + const axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env) +{ + return transport_out->trans_enum; +} + +axis2_status_t AXIS2_CALL +axis2_transport_out_desc_set_enum( + axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS trans_enum) +{ + transport_out->trans_enum = trans_enum; + return AXIS2_SUCCESS; +} + +axis2_flow_t *AXIS2_CALL +axis2_transport_out_desc_get_out_flow( + const axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env) +{ + return transport_out->out_flow; +} + +axis2_status_t AXIS2_CALL +axis2_transport_out_desc_set_out_flow( + axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env, + axis2_flow_t * out_flow) +{ + AXIS2_PARAM_CHECK(env->error, out_flow, AXIS2_FAILURE); + + if(transport_out->out_flow) + { + axis2_flow_free(transport_out->out_flow, env); + } + transport_out->out_flow = out_flow; + return AXIS2_SUCCESS; +} + +axis2_flow_t *AXIS2_CALL +axis2_transport_out_desc_get_fault_out_flow( + const axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env) +{ + return transport_out->fault_out_flow; +} + +axis2_status_t AXIS2_CALL +axis2_transport_out_desc_set_fault_out_flow( + axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env, + axis2_flow_t * fault_out_flow) +{ + AXIS2_PARAM_CHECK(env->error, fault_out_flow, AXIS2_FAILURE); + + if(transport_out->fault_out_flow) + { + axis2_flow_free(transport_out->fault_out_flow, env); + } + transport_out->fault_out_flow = fault_out_flow; + return AXIS2_SUCCESS; +} + +axis2_transport_sender_t *AXIS2_CALL +axis2_transport_out_desc_get_sender( + const axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env) +{ + return transport_out->sender; +} + +axis2_status_t AXIS2_CALL +axis2_transport_out_desc_set_sender( + axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env, + axis2_transport_sender_t * sender) +{ + AXIS2_PARAM_CHECK(env->error, sender, AXIS2_FAILURE); + + if(transport_out->sender) + { + AXIS2_TRANSPORT_SENDER_FREE(transport_out->sender, env); + } + + transport_out->sender = sender; + return AXIS2_SUCCESS; +} + +axis2_phase_t *AXIS2_CALL +axis2_transport_out_desc_get_out_phase( + const axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env) +{ + return transport_out->out_phase; +} + +axis2_status_t AXIS2_CALL +axis2_transport_out_desc_set_out_phase( + axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env, + axis2_phase_t * out_phase) +{ + AXIS2_PARAM_CHECK(env->error, out_phase, AXIS2_FAILURE); + + if(transport_out->out_phase) + { + axis2_phase_free(transport_out->out_phase, env); + } + transport_out->out_phase = out_phase; + return AXIS2_SUCCESS; +} + +axis2_phase_t *AXIS2_CALL +axis2_transport_out_desc_get_fault_phase( + const axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env) +{ + return transport_out->fault_phase; +} + +axis2_status_t AXIS2_CALL +axis2_transport_out_desc_set_fault_phase( + axis2_transport_out_desc_t * transport_out, + const axutil_env_t * env, + axis2_phase_t * fault_phase) +{ + AXIS2_PARAM_CHECK(env->error, fault_phase, AXIS2_FAILURE); + + if(transport_out->fault_phase) + { + axis2_phase_free(transport_out->fault_phase, env); + } + transport_out->fault_phase = fault_phase; + return AXIS2_SUCCESS; + +} + +axis2_status_t AXIS2_CALL +axis2_transport_out_desc_add_param( + axis2_transport_out_desc_t * transport_out_desc, + const axutil_env_t * env, + axutil_param_t * param) +{ + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FAILURE); + + return axutil_param_container_add_param(transport_out_desc-> param_container, env, param); +} + +axutil_param_t *AXIS2_CALL +axis2_transport_out_desc_get_param( + const axis2_transport_out_desc_t * transport_out_desc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + return axutil_param_container_get_param(transport_out_desc->param_container, env, param_name); +} + +axis2_bool_t AXIS2_CALL +axis2_transport_out_desc_is_param_locked( + axis2_transport_out_desc_t * transport_out_desc, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FAILURE); + + return axutil_param_container_is_param_locked(transport_out_desc-> param_container, env, + param_name); +} + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_transport_out_desc_param_container( + const axis2_transport_out_desc_t * transport_out_desc, + const axutil_env_t * env) +{ + return transport_out_desc->param_container; +} + diff --git a/src/core/engine/Makefile.am b/src/core/engine/Makefile.am new file mode 100644 index 0000000..7b9598c --- /dev/null +++ b/src/core/engine/Makefile.am @@ -0,0 +1,47 @@ +lib_LTLIBRARIES=libaxis2_engine.la + +libaxis2_engine_la_SOURCES= ../transport/transport_receiver.c handler.c \ + conf.c \ + phase.c \ + disp_checker.c \ + addr_disp.c \ + rest_disp.c \ + req_uri_disp.c \ + disp.c \ + soap_action_disp.c \ + soap_body_disp.c \ + ctx_handler.c \ + engine.c + +libaxis2_engine_la_LDFLAGS = -version-info $(VERSION_NO) + +libaxis2_engine_la_LIBADD=$(top_builddir)/src/core/description/libaxis2_description.la \ + $(top_builddir)/src/core/receivers/libaxis2_receivers.la \ + $(top_builddir)/src/core/deployment/libaxis2_deployment.la \ + $(top_builddir)/src/core/context/libaxis2_context.la \ + $(top_builddir)/src/core/addr/libaxis2_addr.la \ + $(top_builddir)/src/core/clientapi/libaxis2_clientapi.la \ + $(top_builddir)/src/core/phaseresolver/libaxis2_phaseresolver.la \ + $(top_builddir)/src/core/util/libaxis2_core_utils.la \ + $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/neethi/src/libneethi.la \ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la +libaxis2_engine_la_LIBADD+=$(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la \ + $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la + + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/wsdl \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/util \ + -I$(top_builddir)/src/core/clientapi \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/neethi/include \ + -I$(top_builddir)/axiom/include + +EXTRA_DIST=axis2_disp_checker.h + diff --git a/src/core/engine/addr_disp.c b/src/core/engine/addr_disp.c new file mode 100644 index 0000000..a928e7a --- /dev/null +++ b/src/core/engine/addr_disp.c @@ -0,0 +1,255 @@ +/* + * 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_disp.h> +#include <axis2_handler_desc.h> +#include <axutil_string.h> +#include <axis2_relates_to.h> +#include <axis2_svc.h> +#include <axis2_const.h> +#include <axis2_conf_ctx.h> +#include <axis2_addr.h> +#include <axutil_utils.h> + +const axis2_char_t *AXIS2_ADDR_DISP_NAME = "addressing_based_dispatcher"; + +static axis2_status_t AXIS2_CALL axis2_addr_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx *msg_ctx); + +static axis2_svc_t *AXIS2_CALL axis2_addr_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env); + +static axis2_op_t *AXIS2_CALL axis2_addr_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc); + +axis2_disp_t *AXIS2_CALL +axis2_addr_disp_create( + const axutil_env_t * env) +{ + axis2_disp_t *disp = NULL; + axis2_handler_t *handler = NULL; + axutil_string_t *name = NULL; + + name = axutil_string_create_const(env, (axis2_char_t **)&AXIS2_ADDR_DISP_NAME); + if(!name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + disp = axis2_disp_create(env, name); + if(!disp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axutil_string_free(name, env); + return NULL; + } + + handler = axis2_disp_get_base(disp, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + axutil_string_free(name, env); + return NULL; + } + + axis2_handler_set_invoke(handler, env, axis2_addr_disp_invoke); + + axutil_string_free(name, env); + + return disp; +} + +static axis2_svc_t *AXIS2_CALL +axis2_addr_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axis2_endpoint_ref_t *endpoint_ref = NULL; + axis2_svc_t *svc = NULL; + + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + endpoint_ref = axis2_msg_ctx_get_to(msg_ctx, env); + + if(endpoint_ref) + { + const axis2_char_t *address = NULL; + + address = axis2_endpoint_ref_get_address(endpoint_ref, env); + if(address) + { + axis2_char_t **url_tokens = NULL; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Checking for service using WSA enpoint address : %s", address); + + if((axutil_strcmp(AXIS2_WSA_ANONYMOUS_URL, address) == 0) || (axutil_strcmp( + AXIS2_WSA_NAMESPACE_SUBMISSION, address) == 0)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Endpoint address cannot be the same as WSA namespace : %s", address); + return NULL; + } + + url_tokens = axutil_parse_request_url_for_svc_and_op(env, address); + + if(url_tokens) + { + if(url_tokens[0]) + { + axis2_conf_ctx_t *conf_ctx = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + axis2_conf_t *conf = NULL; + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + svc = axis2_conf_get_svc(conf, env, url_tokens[0]); + + if(svc) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Service found using WSA enpoint address"); + } + } + } + AXIS2_FREE(env->allocator, url_tokens[0]); + } + if(url_tokens[1]) + { + AXIS2_FREE(env->allocator, url_tokens[1]); + } + AXIS2_FREE(env->allocator, url_tokens); + url_tokens = NULL; + } + } + } + + return svc; +} + +static axis2_op_t *AXIS2_CALL +axis2_addr_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + const axis2_char_t *action = NULL; + axutil_qname_t *name = NULL; + axis2_op_t *op = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, svc, NULL); + + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + action = axis2_msg_ctx_get_wsa_action(msg_ctx, env); + + if(action) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Checking for operation using WSA Action : %s", + action); + + name = axutil_qname_create(env, action, NULL, NULL); + op = axis2_svc_get_op_with_qname(svc, env, name); + if(op) + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Operation found using WSA Action"); + axutil_qname_free(name, env); + } + + return op; +} + +static axis2_status_t AXIS2_CALL +axis2_addr_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx *msg_ctx) +{ + axis2_relates_to_t *relates_to = NULL; + + relates_to = axis2_msg_ctx_get_relates_to(msg_ctx, env); + + /** first check if we can dispatch using the relates_to */ + if(relates_to) + { + const axis2_char_t *relates_to_value = NULL; + relates_to_value = axis2_relates_to_get_value(relates_to, env); + if(relates_to_value && axutil_strcmp(relates_to_value, "") != 0) + { + axis2_conf_ctx_t *conf_ctx = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + axis2_op_ctx_t *op_ctx = NULL; + const axis2_char_t *msg_id = axis2_msg_ctx_get_msg_id(msg_ctx, env); + op_ctx = axis2_conf_ctx_get_op_ctx(conf_ctx, env, msg_id); + if(op_ctx) + { + axis2_op_t *op = NULL; + op = axis2_op_ctx_get_op(op_ctx, env); + if(op) + { + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_msg_ctx_set_op_ctx(msg_ctx, env, op_ctx); + axis2_msg_ctx_set_op(msg_ctx, env, op); + axis2_op_register_op_ctx(op, env, msg_ctx, op_ctx); + + svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); + if(svc_ctx) + { + axis2_svc_t *svc = NULL; + axis2_svc_grp_ctx_t *svc_grp_ctx = NULL; + axis2_msg_ctx_set_svc_ctx(msg_ctx, env, svc_ctx); + svc = axis2_svc_ctx_get_svc(svc_ctx, env); + if(svc) + { + axis2_msg_ctx_set_svc(msg_ctx, env, svc); + } + svc_grp_ctx = axis2_svc_ctx_get_parent(svc_ctx, env); + if(svc_grp_ctx) + { + axutil_string_t *svc_grp_ctx_id_str = axutil_string_create(env, + axis2_svc_grp_ctx_get_id(svc_grp_ctx, env)); + axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, svc_grp_ctx_id_str); + axutil_string_free(svc_grp_ctx_id_str, env); + } + return AXIS2_SUCCESS; + } + } + } + } + } + + } + + axis2_msg_ctx_set_find_svc(msg_ctx, env, axis2_addr_disp_find_svc); + axis2_msg_ctx_set_find_op(msg_ctx, env, axis2_addr_disp_find_op); + + return axis2_disp_find_svc_and_op(handler, env, msg_ctx); +} + diff --git a/src/core/engine/axis2_disp_checker.h b/src/core/engine/axis2_disp_checker.h new file mode 100644 index 0000000..a93ac51 --- /dev/null +++ b/src/core/engine/axis2_disp_checker.h @@ -0,0 +1,105 @@ + +/* +* 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_DISP_CHECKER_H +#define AXIS2_DISP_CHECKER_H + +/** + * @defgroup axis2_disp_checker dispatcher checker + * @ingroup axis2_engine + * dispatcher checker is responsible of checking the status of the dispatchers. + * @{ + */ + +/** + * @file axis2_disp_checker.h + */ + +#include <axis2_defines.h> +#include <axutil_string.h> +#include <axis2_handler.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** Type name for struct axis2_disp_checker */ + typedef struct axis2_disp_checker axis2_disp_checker_t; + + /** + * Gets the base handler. + * @param disp_checker pointer to dispatcher checker + * @param env pointer to environment struct + * @return pointer to base handler, returns a reference not a cloned copy + */ + AXIS2_EXTERN axis2_handler_t *AXIS2_CALL + axis2_disp_checker_get_base( + const axis2_disp_checker_t * disp_checker, + const axutil_env_t * env); + + /** + * Gets QName. + * @param disp_checker pointer to dispatcher checker + * @param env pointer to environment struct + * @return returns a pointer to the QName, returns a reference not a + * cloned copy + */ + AXIS2_EXTERN axutil_string_t *AXIS2_CALL + axis2_disp_checker_get_name( + const axis2_disp_checker_t * disp_checker, + const axutil_env_t * env); + + /** + * Sets QName. + * @param disp_checker pointer to dispatcher checker + * @param env pointer to environment struct + * @param name pointer to QName. A clone would be created within the method + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_disp_checker_set_name( + axis2_disp_checker_t * disp_checker, + const axutil_env_t * env, + const axutil_string_t * name); + + /** + * Frees dispatcher checker. + * @param disp_checker pointer to dispatcher checker + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_disp_checker_free( + axis2_disp_checker_t * disp_checker, + const axutil_env_t * env); + + /** + * Creates a dispatcher checker struct instance. + * @param env pointer to environment struct + * @return pointer to newly created dispatcher checker struct + */ + AXIS2_EXTERN axis2_disp_checker_t *AXIS2_CALL + axis2_disp_checker_create( + const axutil_env_t * env); + +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_DISP_CHECKER_H */ diff --git a/src/core/engine/conf.c b/src/core/engine/conf.c new file mode 100644 index 0000000..6e81392 --- /dev/null +++ b/src/core/engine/conf.c @@ -0,0 +1,1835 @@ +/* + * 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 <axis2_disp.h> +#include "axis2_disp_checker.h" +#include <axis2_conf.h> +#include <axutil_dir_handler.h> +#include <axis2_dep_engine.h> +#include <axis2_arch_reader.h> +#include <axis2_core_utils.h> + +struct axis2_conf +{ + axutil_hash_t *svc_grps; + axis2_transport_in_desc_t *transports_in[AXIS2_TRANSPORT_ENUM_MAX]; + axis2_transport_out_desc_t *transports_out[AXIS2_TRANSPORT_ENUM_MAX]; + + /** + * All the modules already engaged can be found here. + */ + axutil_array_list_t *engaged_module_list; + + /*To store all the available modules (including version) */ + axutil_hash_t *all_modules; + + /*To store mapping between default version to module name */ + axutil_hash_t *name_to_version_map; + axutil_array_list_t *out_phases; + axutil_array_list_t *in_fault_phases; + axutil_array_list_t *out_fault_phases; + + /* All the system specific phases are stored here */ + axutil_array_list_t *in_phases_upto_and_including_post_dispatch; + + axis2_phases_info_t *phases_info; + axutil_hash_t *all_svcs; + axutil_hash_t *all_init_svcs; + axutil_hash_t *msg_recvs; + axutil_hash_t *faulty_svcs; + axutil_hash_t *faulty_modules; + axis2_char_t *axis2_repo; + axis2_char_t *axis2_xml; + axis2_dep_engine_t *dep_engine; + axutil_array_list_t *handlers; + axis2_bool_t enable_mtom; + /*This is used in rampart */ + axis2_bool_t enable_security; + + /** Configuration parameter container */ + axutil_param_container_t *param_container; + + /** Base description struct */ + axis2_desc_t *base; + + /** Mark whether conf is built using axis2 XML*/ + axis2_bool_t axis2_flag; + +#if 0 +/* this seemed to be not used after 1.6.0 */ +/* This is a hack to keep rampart_context at client side */ +void *security_context; +#endif +}; + +AXIS2_EXTERN axis2_conf_t *AXIS2_CALL +axis2_conf_create( + const axutil_env_t * env) +{ + axis2_conf_t *conf = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_phase_t *phase = NULL; + int i = 0; + + AXIS2_ENV_CHECK(env, NULL); + + conf = (axis2_conf_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_conf_t)); + if(!conf) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + memset((void *)conf, 0, sizeof(axis2_conf_t)); + + conf->param_container = (axutil_param_container_t *)axutil_param_container_create(env); + if(!conf->param_container) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating parameter container failed"); + return NULL; + } + + conf->svc_grps = axutil_hash_make(env); + if(!conf->svc_grps) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating service group map failed"); + return NULL; + } + + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + conf->transports_in[i] = NULL; + } + + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + conf->transports_out[i] = NULL; + } + + conf->engaged_module_list = axutil_array_list_create(env, 0); + if(!conf->engaged_module_list) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating engaged module list failed"); + return NULL; + } + + conf->handlers = axutil_array_list_create(env, 0); + if(!conf->handlers) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating handler list failed"); + return NULL; + } + + conf->in_phases_upto_and_including_post_dispatch = axutil_array_list_create(env, 0); + if(!conf->in_phases_upto_and_including_post_dispatch) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating in phases list upto and including post dispatch failed"); + return NULL; + } + else + { + axis2_disp_t *uri_dispatch = NULL; + axis2_disp_t *addr_dispatch = NULL; + + phase = axis2_phase_create(env, AXIS2_PHASE_TRANSPORT_IN); + if(!phase) + { + axis2_conf_free(conf, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase %s failed", + AXIS2_PHASE_TRANSPORT_IN); + return NULL; + } + + /* In case of using security we need to find the service/operation parameters before the + * dispatch phase. This is required to give parameters to the security inflow.*/ + uri_dispatch = axis2_req_uri_disp_create(env); + if(uri_dispatch) + { + axis2_handler_t *handler = NULL; + handler = axis2_disp_get_base(uri_dispatch, env); + axis2_disp_free(uri_dispatch, env); + axis2_phase_add_handler_at(phase, env, 0, handler); + axutil_array_list_add(conf->handlers, env, axis2_handler_get_handler_desc(handler, env)); + } + + addr_dispatch = axis2_addr_disp_create(env); + if(addr_dispatch) + { + axis2_handler_t *handler = NULL; + handler = axis2_disp_get_base(addr_dispatch, env); + axis2_disp_free(addr_dispatch, env); + axis2_phase_add_handler_at(phase, env, 1, handler); + axutil_array_list_add(conf->handlers, env, axis2_handler_get_handler_desc(handler, env)); + } + + status + = axutil_array_list_add(conf->in_phases_upto_and_including_post_dispatch, env, phase); + if(AXIS2_SUCCESS != status) + { + axis2_conf_free(conf, env); + axis2_phase_free(phase, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding phase %s into in phases upto and including post dispatch list failed", + AXIS2_PHASE_TRANSPORT_IN); + return NULL; + } + + phase = axis2_phase_create(env, AXIS2_PHASE_PRE_DISPATCH); + if(!phase) + { + axis2_conf_free(conf, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase %s failed", + AXIS2_PHASE_PRE_DISPATCH); + return NULL; + } + + status + = axutil_array_list_add(conf->in_phases_upto_and_including_post_dispatch, env, phase); + if(AXIS2_SUCCESS != status) + { + axis2_conf_free(conf, env); + axis2_phase_free(phase, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding phase %s into in phases upto and including post dispatch list failed", + AXIS2_PHASE_PRE_DISPATCH); + return NULL; + } + } + + conf->all_svcs = axutil_hash_make(env); + if(!conf->all_svcs) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating all services map failed"); + return NULL; + } + + conf->all_init_svcs = axutil_hash_make(env); + if(!conf->all_init_svcs) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating all init services map failed"); + return NULL; + } + + conf->msg_recvs = axutil_hash_make(env); + if(!conf->msg_recvs) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating message receivers map failed."); + return NULL; + } + + conf->faulty_svcs = axutil_hash_make(env); + if(!conf->faulty_svcs) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating fault services map failed"); + return NULL; + } + + conf->faulty_modules = axutil_hash_make(env); + if(!conf->faulty_modules) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating fault modules map failed"); + return NULL; + } + + conf->all_modules = axutil_hash_make(env); + if(!conf->all_modules) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating all modules map failed"); + return NULL; + } + + conf->name_to_version_map = axutil_hash_make(env); + if(!conf->name_to_version_map) + { + axis2_conf_free(conf, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating name to version map failed"); + return NULL; + } + + conf->base = axis2_desc_create(env); + if(!conf->base) + { + axis2_conf_free(conf, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating Axis2 configuration base description failed"); + return NULL; + } + + return conf; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_conf_free( + axis2_conf_t * conf, + const axutil_env_t * env) +{ + int i = 0; + + if(!conf) + { + /* nothing to free */ + return; + } + + if(conf->param_container) + { + axutil_param_container_free(conf->param_container, env); + } + + if(conf->svc_grps) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(conf->svc_grps, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_svc_grp_t *svc_grp = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + svc_grp = (axis2_svc_grp_t *)val; + if(svc_grp) + { + axis2_svc_grp_free(svc_grp, env); + } + } + axutil_hash_free(conf->svc_grps, env); + } + + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + if(conf->transports_in[i]) + { + axis2_transport_in_desc_free(conf->transports_in[i], env); + } + } + + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + if(conf->transports_out[i]) + { + axis2_transport_out_desc_free(conf->transports_out[i], env); + } + } + + if(conf->dep_engine) + { + axis2_dep_engine_free(conf->dep_engine, env); + } + + if(conf->all_modules) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(conf->all_modules, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_module_desc_t *module_desc = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + module_desc = (axis2_module_desc_t *)val; + if(module_desc) + { + axis2_module_desc_free(module_desc, env); + } + } + axutil_hash_free(conf->all_modules, env); + } + + if(conf->name_to_version_map) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(conf->name_to_version_map, env); hi; hi = axutil_hash_next(env, + hi)) + { + axis2_char_t *module_ver = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + module_ver = (axis2_char_t *)val; + if(module_ver) + { + AXIS2_FREE(env->allocator, module_ver); + } + } + axutil_hash_free(conf->name_to_version_map, env); + } + + if(conf->engaged_module_list) + { + for(i = 0; i < axutil_array_list_size(conf->engaged_module_list, env); i++) + { + axutil_qname_t *module_desc_qname = NULL; + module_desc_qname = (axutil_qname_t *)axutil_array_list_get(conf->engaged_module_list, + env, i); + if(module_desc_qname) + { + axutil_qname_free(module_desc_qname, env); + } + } + axutil_array_list_free(conf->engaged_module_list, env); + } + + if(conf->out_phases) + { + for(i = 0; i < axutil_array_list_size(conf->out_phases, env); i++) + { + axis2_phase_t *phase = NULL; + phase = (axis2_phase_t *)axutil_array_list_get(conf->out_phases, env, i); + if(phase) + { + axis2_phase_free(phase, env); + } + } + axutil_array_list_free(conf->out_phases, env); + } + + if(conf->in_fault_phases) + { + for(i = 0; i < axutil_array_list_size(conf->in_fault_phases, env); i++) + { + axis2_phase_t *phase = NULL; + phase = (axis2_phase_t *)axutil_array_list_get(conf->in_fault_phases, env, i); + if(phase) + { + axis2_phase_free(phase, env); + } + } + axutil_array_list_free(conf->in_fault_phases, env); + } + + if(conf->out_fault_phases) + { + for(i = 0; i < axutil_array_list_size(conf->out_fault_phases, env); i++) + { + axis2_phase_t *phase = NULL; + phase = (axis2_phase_t *)axutil_array_list_get(conf->out_fault_phases, env, i); + if(phase) + { + axis2_phase_free(phase, env); + } + } + axutil_array_list_free(conf->out_fault_phases, env); + } + + if(conf->in_phases_upto_and_including_post_dispatch) + { + for(i = 0; i < axutil_array_list_size(conf-> in_phases_upto_and_including_post_dispatch, + env); i++) + { + axis2_phase_t *phase = NULL; + phase = (axis2_phase_t *)axutil_array_list_get( + conf-> in_phases_upto_and_including_post_dispatch, env, i); + if(phase) + { + axis2_phase_free(phase, env); + } + } + axutil_array_list_free(conf-> in_phases_upto_and_including_post_dispatch, env); + } + + if(conf->all_svcs) + { + axutil_hash_free(conf->all_svcs, env); + } + + if(conf->all_init_svcs) + { + axutil_hash_free(conf->all_init_svcs, env); + } + + if(conf->msg_recvs) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(conf->msg_recvs, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_msg_recv_t *msg_recv = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + msg_recv = (axis2_msg_recv_t *)val; + if(msg_recv) + { + axis2_msg_recv_free(msg_recv, env); + msg_recv = NULL; + } + } + axutil_hash_free(conf->msg_recvs, env); + } + + if(conf->faulty_svcs) + { + axutil_hash_free(conf->faulty_svcs, env); + } + + if(conf->faulty_modules) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(conf->faulty_modules, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_module_desc_t *module_desc = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + module_desc = (axis2_module_desc_t *)val; + if(module_desc) + { + axis2_module_desc_free(module_desc, env); + } + } + axutil_hash_free(conf->faulty_modules, env); + } + + if(conf->handlers) + { + int i = 0; + for(i = 0; i < axutil_array_list_size(conf->handlers, env); i++) + { + axis2_handler_desc_t *handler_desc = NULL; + handler_desc = (axis2_handler_desc_t *)axutil_array_list_get(conf->handlers, env, i); + if(handler_desc) + { + axis2_handler_desc_free(handler_desc, env); + } + } + axutil_array_list_free(conf->handlers, env); + } + + if(conf->axis2_repo) + { + AXIS2_FREE(env->allocator, conf->axis2_repo); + } + + if(conf->base) + { + axis2_desc_free(conf->base, env); + } + + if(conf->axis2_xml) + { + AXIS2_FREE(env->allocator, conf->axis2_xml); + } + + AXIS2_FREE(env->allocator, conf); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_add_svc_grp( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_svc_grp_t * svc_grp) +{ + axutil_hash_t *svcs = NULL; + axutil_hash_index_t *index_i = NULL; + axis2_char_t *svc_name = NULL; + const axis2_char_t *svc_grp_name = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_grp, AXIS2_FAILURE); + + svcs = axis2_svc_grp_get_all_svcs(svc_grp, env); + if(!conf->all_svcs) + { + conf->all_svcs = axutil_hash_make(env); + if(!conf->all_svcs) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating all services map failed"); + return AXIS2_FAILURE; + } + } + + index_i = axutil_hash_first(svcs, env); + while(index_i) + { + void *value = NULL; + axis2_svc_t *desc = NULL; + axis2_svc_t *temp_svc = NULL; + const axutil_qname_t *svc_qname = NULL; + + axutil_hash_this(index_i, NULL, NULL, &value); + desc = (axis2_svc_t *)value; + svc_qname = axis2_svc_get_qname(desc, env); + svc_name = axutil_qname_get_localpart(svc_qname, env); + temp_svc = axutil_hash_get(conf->all_svcs, svc_name, AXIS2_HASH_KEY_STRING); + + /* No two service names deployed in the engine can be same */ + if(temp_svc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_TWO_SVCS_CANNOT_HAVE_SAME_NAME, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "There is already a service called %s in the " + "all services list of axis2 configuration.", svc_name); + return AXIS2_FAILURE; + } + + index_i = axutil_hash_next(env, index_i); + } + + svcs = axis2_svc_grp_get_all_svcs(svc_grp, env); + index_i = axutil_hash_first(svcs, env); + + while(index_i) + { + void *value = NULL; + axis2_svc_t *desc = NULL; + + axutil_hash_this(index_i, NULL, NULL, &value); + desc = (axis2_svc_t *)value; + svc_name = axutil_qname_get_localpart(axis2_svc_get_qname(desc, env), env); + axutil_hash_set(conf->all_svcs, svc_name, AXIS2_HASH_KEY_STRING, desc); + index_i = axutil_hash_next(env, index_i); + } + + svc_grp_name = axis2_svc_grp_get_name(svc_grp, env); + if(!conf->svc_grps) + { + conf->svc_grps = axutil_hash_make(env); + if(!conf->svc_grps) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating service group map failed"); + return AXIS2_FAILURE; + } + } + + axutil_hash_set(conf->svc_grps, svc_grp_name, AXIS2_HASH_KEY_STRING, svc_grp); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_svc_grp_t *AXIS2_CALL +axis2_conf_get_svc_grp( + const axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * svc_grp_name) +{ + AXIS2_PARAM_CHECK(env->error, svc_grp_name, NULL); + + if(!conf->svc_grps) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_CONF, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Axis2 configuration does not contain a service group map"); + return NULL; + } + return (axis2_svc_grp_t *)(axutil_hash_get(conf->svc_grps, svc_grp_name, AXIS2_HASH_KEY_STRING)); +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_get_all_svc_grps( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->svc_grps; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_add_svc( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + axis2_phase_resolver_t *phase_resolver = NULL; + axis2_svc_grp_t *svc_grp = NULL; + const axis2_char_t *svc_grp_name = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, svc, AXIS2_FAILURE); + + /* We need to first create a service group with the same name as the + * service and make it the parent of service */ + svc_grp_name = axis2_svc_get_name(svc, env); + if(!svc_grp_name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service has no name set"); + return AXIS2_FAILURE; + } + + svc_grp = axis2_svc_grp_create(env); + if(!svc_grp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Creating service group as parent of service %s failed", svc_grp_name); + return AXIS2_FAILURE; + } + + status = axis2_svc_grp_set_name(svc_grp, env, svc_grp_name); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting name to service group failed"); + return status; + } + + status = axis2_svc_grp_set_parent(svc_grp, env, conf); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Setting parent to service group %s failed", + svc_grp_name); + return status; + } + + phase_resolver = axis2_phase_resolver_create_with_config_and_svc(env, conf, svc); + if(!phase_resolver) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase resolver failed for service %s", + axis2_svc_get_name(svc, env)); + return AXIS2_FAILURE; + } + + status = axis2_phase_resolver_build_execution_chains_for_svc(phase_resolver, env); + axis2_phase_resolver_free(phase_resolver, env); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Building chains failed within phase resolver " + "for service %s", axis2_svc_get_name(svc, env)); + return status; + } + + status = axis2_svc_grp_add_svc(svc_grp, env, svc); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding service %s to service group %s failed", + svc_grp_name, svc_grp_name); + return status; + } + + status = axis2_conf_add_svc_grp(conf, env, svc_grp); + return status; +} + +AXIS2_EXTERN axis2_svc_t *AXIS2_CALL +axis2_conf_get_svc( + const axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + AXIS2_PARAM_CHECK(env->error, svc_name, NULL); + + return axutil_hash_get(conf->all_svcs, svc_name, AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_remove_svc( + axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + AXIS2_PARAM_CHECK(env->error, svc_name, AXIS2_FAILURE); + + axutil_hash_set(conf->all_svcs, svc_name, AXIS2_HASH_KEY_STRING, NULL); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_add_param( + axis2_conf_t * conf, + const axutil_env_t * env, + axutil_param_t * param) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *param_name = axutil_param_get_name(param, env); + + AXIS2_PARAM_CHECK(env->error, param, AXIS2_FAILURE); + + if(axis2_conf_is_param_locked(conf, env, param_name)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PARAMETER_LOCKED_CANNOT_OVERRIDE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Parameter %s is locked for Axis2 configuration", + param_name); + return AXIS2_FAILURE; + } + else + { + status = axutil_param_container_add_param(conf->param_container, env, param); + } + return status; +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_conf_get_param( + const axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * name) +{ + AXIS2_PARAM_CHECK(env->error, name, NULL); + + if(!conf->param_container) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_PARAM_CONTAINER, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Param container is not set in axis2 configuraion"); + return NULL; + } + + return axutil_param_container_get_param(conf->param_container, env, name); + +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_conf_get_all_params( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return axutil_param_container_get_params(conf->param_container, env); + +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_conf_is_param_locked( + const axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * param_name) +{ + axutil_param_t *param = NULL; + + AXIS2_PARAM_CHECK(env->error, param_name, AXIS2_FALSE); + + param = axis2_conf_get_param(conf, env, param_name); + return (param && axutil_param_is_locked(param, env)); +} + +AXIS2_EXTERN axis2_transport_in_desc_t *AXIS2_CALL +axis2_conf_get_transport_in( + const axis2_conf_t * conf, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS trans_enum) +{ + return (axis2_transport_in_desc_t *)conf->transports_in[trans_enum]; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_add_transport_in( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_transport_in_desc_t * transport, + const AXIS2_TRANSPORT_ENUMS trans_enum) +{ + AXIS2_PARAM_CHECK(env->error, transport, AXIS2_FAILURE); + + conf->transports_in[trans_enum] = transport; + + return AXIS2_SUCCESS; + +} + +AXIS2_EXTERN axis2_transport_out_desc_t *AXIS2_CALL +axis2_conf_get_transport_out( + const axis2_conf_t * conf, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS trans_enum) +{ + return conf->transports_out[trans_enum]; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_add_transport_out( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_transport_out_desc_t * transport, + const AXIS2_TRANSPORT_ENUMS trans_enum) +{ + AXIS2_PARAM_CHECK(env->error, transport, AXIS2_FAILURE); + + conf->transports_out[trans_enum] = transport; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_transport_in_desc_t **AXIS2_CALL +axis2_conf_get_all_in_transports( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return (axis2_transport_in_desc_t **)conf->transports_in; +} + +AXIS2_EXTERN axis2_module_desc_t *AXIS2_CALL +axis2_conf_get_module( + const axis2_conf_t * conf, + const axutil_env_t * env, + const axutil_qname_t * qname) +{ + axis2_char_t *name = NULL; + axis2_module_desc_t *ret = NULL; + axis2_char_t *module_name = NULL; + axutil_qname_t *mod_qname = NULL; + const axis2_char_t *def_mod_ver = NULL; + + AXIS2_PARAM_CHECK(env->error, qname, NULL); + + name = axutil_qname_to_string((axutil_qname_t *)qname, env); + ret = (axis2_module_desc_t *)axutil_hash_get(conf->all_modules, name, AXIS2_HASH_KEY_STRING); + if(ret) + { + return ret; + } + module_name = axutil_qname_get_localpart(qname, env); + if(!module_name) + { + return NULL; + } + def_mod_ver = axis2_conf_get_default_module_version(conf, env, module_name); + mod_qname = axis2_core_utils_get_module_qname(env, name, def_mod_ver); + if(!mod_qname) + { + return NULL; + } + name = axutil_qname_to_string(mod_qname, env); + ret = (axis2_module_desc_t *)axutil_hash_get(conf->all_modules, name, AXIS2_HASH_KEY_STRING); + axutil_qname_free(mod_qname, env); + mod_qname = NULL; + return ret; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_conf_get_all_engaged_modules( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->engaged_module_list; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_conf_get_in_phases_upto_and_including_post_dispatch( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->in_phases_upto_and_including_post_dispatch; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_conf_get_out_flow( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->out_phases; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_conf_get_in_fault_flow( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->in_fault_phases; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_conf_get_out_fault_flow( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->out_fault_phases; +} + +AXIS2_EXTERN axis2_transport_out_desc_t **AXIS2_CALL +axis2_conf_get_all_out_transports( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return (axis2_transport_out_desc_t **)conf->transports_out; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_get_all_faulty_svcs( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->faulty_svcs; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_get_all_faulty_modules( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->faulty_modules; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_get_all_svcs( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + /*axutil_hash_t *sgs = NULL; + axutil_hash_index_t *index_i = NULL; + axutil_hash_index_t *index_j = NULL; + void *value = NULL; + void *value2 = NULL; + axis2_svc_grp_t *axis_svc_grp = NULL; + axutil_hash_t *svcs = NULL; + axis2_svc_t *svc = NULL; + axis2_char_t *svc_name = NULL; + */ + + /* Do we need to do all the following of retrieving all service groups and + * then add all services from each group to conf->all_svcs and then finally + * return conf->all_svcs?. We have already done this when + * adding each service group to the conf, so just returning conf->all_svcs + * here would be enough - Damitha */ + /*sgs = axis2_conf_get_all_svc_grps(conf, env); + index_i = axutil_hash_first(sgs, env); + while(index_i) + { + axutil_hash_this(index_i, NULL, NULL, &value); + axis_svc_grp = (axis2_svc_grp_t *)value; + svcs = axis2_svc_grp_get_all_svcs(axis_svc_grp, env); + index_j = axutil_hash_first(svcs, env); + while(index_j) + { + axutil_hash_this(index_j, NULL, NULL, &value2); + svc = (axis2_svc_t *)value2; + svc_name = axutil_qname_get_localpart(axis2_svc_get_qname(svc, env), env); + axutil_hash_set(conf->all_svcs, svc_name, AXIS2_HASH_KEY_STRING, svc); + + index_j = axutil_hash_next(env, index_j); + } + + index_i = axutil_hash_next(env, index_i); + }*/ + return conf->all_svcs; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_get_all_svcs_to_load( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + axutil_hash_t *sgs = NULL; + axutil_hash_index_t *index_i = NULL; + axutil_hash_index_t *index_j = NULL; + void *value = NULL; + void *value2 = NULL; + axis2_svc_grp_t *axis_svc_grp = NULL; + axutil_hash_t *svcs = NULL; + axis2_svc_t *svc = NULL; + axis2_char_t *svc_name = NULL; + + sgs = axis2_conf_get_all_svc_grps(conf, env); + index_i = axutil_hash_first(sgs, env); + while(index_i) + { + axutil_hash_this(index_i, NULL, NULL, &value); + axis_svc_grp = (axis2_svc_grp_t *)value; + svcs = axis2_svc_grp_get_all_svcs(axis_svc_grp, env); + index_j = axutil_hash_first(svcs, env); + while(index_j) + { + axutil_param_t *param = NULL; + axutil_hash_this(index_j, NULL, NULL, &value2); + svc = (axis2_svc_t *)value2; + svc_name = axutil_qname_get_localpart(axis2_svc_get_qname(svc, env), env); + param = axis2_svc_get_param(svc, env, AXIS2_LOAD_SVC_STARTUP); + if(param) + { + axutil_hash_set(conf->all_init_svcs, svc_name, AXIS2_HASH_KEY_STRING, svc); + } + + index_j = axutil_hash_next(env, index_j); + } + + index_i = axutil_hash_next(env, index_i); + } + return conf->all_init_svcs; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_conf_is_engaged( + axis2_conf_t * conf, + const axutil_env_t * env, + const axutil_qname_t * module_name) +{ + const axutil_qname_t *def_mod_qname = NULL; + axis2_module_desc_t *def_mod = NULL; + int i = 0; + int size = 0; + + AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FALSE); + + def_mod + = axis2_conf_get_default_module(conf, env, axutil_qname_get_localpart(module_name, env)); + if(def_mod) + { + def_mod_qname = axis2_module_desc_get_qname(def_mod, env); + } + + size = axutil_array_list_size(conf->engaged_module_list, env); + for(i = 0; i < size; i++) + { + axutil_qname_t *qname = NULL; + qname = (axutil_qname_t *)axutil_array_list_get(conf->engaged_module_list, env, i); + if(axutil_qname_equals(module_name, env, qname) || (def_mod_qname && axutil_qname_equals( + def_mod_qname, env, qname))) + { + return AXIS2_TRUE; + } + } + + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_phases_info_t *AXIS2_CALL +axis2_conf_get_phases_info( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->phases_info; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_phases_info( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_phases_info_t * phases_info) +{ + AXIS2_PARAM_CHECK(env->error, phases_info, AXIS2_FAILURE); + + if(conf->phases_info) + { + axis2_phases_info_free(phases_info, env); + conf->phases_info = NULL; + } + conf->phases_info = phases_info; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_add_msg_recv( + axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * key, + axis2_msg_recv_t * msg_recv) +{ + AXIS2_PARAM_CHECK(env->error, key, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_recv, AXIS2_FAILURE); + if(!conf->msg_recvs) + { + conf->msg_recvs = axutil_hash_make(env); + if(!conf->msg_recvs) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating message receiver map failed"); + return AXIS2_FAILURE; + } + } + axutil_hash_set(conf->msg_recvs, key, AXIS2_HASH_KEY_STRING, msg_recv); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_recv_t *AXIS2_CALL +axis2_conf_get_msg_recv( + const axis2_conf_t * conf, + const axutil_env_t * env, + axis2_char_t * key) +{ + return (axis2_msg_recv_t *)axutil_hash_get(conf->msg_recvs, key, AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_out_phases( + axis2_conf_t * conf, + const axutil_env_t * env, + axutil_array_list_t * out_phases) +{ + AXIS2_PARAM_CHECK(env->error, out_phases, AXIS2_FAILURE); + + if(conf->out_phases) + { + axutil_array_list_free(conf->out_phases, env); + conf->out_phases = NULL; + } + conf->out_phases = out_phases; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_conf_get_out_phases( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->out_phases; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_in_fault_phases( + axis2_conf_t * conf, + const axutil_env_t * env, + axutil_array_list_t * list) +{ + AXIS2_PARAM_CHECK(env->error, list, AXIS2_FAILURE); + + if(conf->in_fault_phases) + { + axutil_array_list_free(conf->in_fault_phases, env); + conf->in_fault_phases = NULL; + } + conf->in_fault_phases = list; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_out_fault_phases( + axis2_conf_t * conf, + const axutil_env_t * env, + axutil_array_list_t * list) +{ + AXIS2_PARAM_CHECK(env->error, list, AXIS2_FAILURE); + + if(conf->out_fault_phases) + { + axutil_array_list_free(conf->out_fault_phases, env); + conf->out_fault_phases = NULL; + } + conf->out_fault_phases = list; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_conf_get_all_modules( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->all_modules; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_add_module( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_module_desc_t * module) +{ + const axutil_qname_t *module_qname = NULL; + + AXIS2_PARAM_CHECK(env->error, module, AXIS2_FAILURE); + + axis2_module_desc_set_parent(module, env, conf); + + module_qname = axis2_module_desc_get_qname(module, env); + if(module_qname) + { + axis2_char_t *module_name = NULL; + module_name = axutil_qname_to_string((axutil_qname_t *)module_qname, env); + axutil_hash_set(conf->all_modules, module_name, AXIS2_HASH_KEY_STRING, module); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_default_dispatchers( + axis2_conf_t * conf, + const axutil_env_t * env) +{ + axis2_phase_t *dispatch = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_disp_t *rest_dispatch = NULL; + axis2_disp_t *soap_action_based_dispatch = NULL; + axis2_disp_t *soap_msg_body_based_dispatch = NULL; + axis2_handler_t *handler = NULL; + axis2_phase_t *post_dispatch = NULL; + axis2_disp_checker_t *disp_checker = NULL; + + dispatch = axis2_phase_create(env, AXIS2_PHASE_DISPATCH); + if(!dispatch) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase %s failed", AXIS2_PHASE_DISPATCH); + return AXIS2_FAILURE; + } + + rest_dispatch = axis2_rest_disp_create(env); + if(!rest_dispatch) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating rest dispatcher failed"); + return AXIS2_FAILURE; + } + + handler = axis2_disp_get_base(rest_dispatch, env); + axis2_disp_free(rest_dispatch, env); + axis2_phase_add_handler_at(dispatch, env, 0, handler); + axutil_array_list_add(conf->handlers, env, axis2_handler_get_handler_desc(handler, env)); + + soap_msg_body_based_dispatch = axis2_soap_body_disp_create(env); + if(!soap_msg_body_based_dispatch) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating soap body based dispatcher failed"); + return AXIS2_FAILURE; + } + + handler = axis2_disp_get_base(soap_msg_body_based_dispatch, env); + axis2_disp_free(soap_msg_body_based_dispatch, env); + axis2_phase_add_handler_at(dispatch, env, 1, handler); + axutil_array_list_add(conf->handlers, env, axis2_handler_get_handler_desc(handler, env)); + + soap_action_based_dispatch = axis2_soap_action_disp_create(env); + if(!soap_action_based_dispatch) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating soap action based dispatcher failed"); + return AXIS2_FAILURE; + } + + handler = axis2_disp_get_base(soap_action_based_dispatch, env); + axis2_disp_free(soap_action_based_dispatch, env); + axis2_phase_add_handler_at(dispatch, env, 2, handler); + axutil_array_list_add(conf->handlers, env, axis2_handler_get_handler_desc(handler, env)); + + status + = axutil_array_list_add(conf-> in_phases_upto_and_including_post_dispatch, env, dispatch); + if(AXIS2_SUCCESS != status) + { + axis2_phase_free(dispatch, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding dispatcher into in phases upto and including post dispatch list failed"); + return status; + } + + post_dispatch = axis2_phase_create(env, AXIS2_PHASE_POST_DISPATCH); + if(!post_dispatch) + { + axis2_phase_free(dispatch, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase %s failed", + AXIS2_PHASE_POST_DISPATCH); + return AXIS2_FAILURE; + } + + disp_checker = axis2_disp_checker_create(env); + handler = axis2_disp_checker_get_base(disp_checker, env); + axis2_disp_checker_free(disp_checker, env); + axis2_phase_add_handler_at(post_dispatch, env, 0, handler); + axutil_array_list_add(conf->handlers, env, axis2_handler_get_handler_desc(handler, env)); + handler = axis2_ctx_handler_create(env, NULL); + axis2_phase_add_handler_at(post_dispatch, env, 1, handler); + axutil_array_list_add(conf->handlers, env, axis2_handler_get_handler_desc(handler, env)); + + status = axutil_array_list_add(conf-> in_phases_upto_and_including_post_dispatch, env, + post_dispatch); + if(AXIS2_SUCCESS != status) + { + axis2_phase_free(dispatch, env); + axis2_phase_free(post_dispatch, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding post dispatcher into in phases upto and including post dispatch list failed"); + return status; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_dispatch_phase( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_phase_t * dispatch) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_handler_t *handler = NULL; + axis2_phase_t *post_dispatch = NULL; + axis2_disp_checker_t *disp_checker = NULL; + + AXIS2_PARAM_CHECK(env->error, dispatch, AXIS2_FAILURE); + + status + = axutil_array_list_add(conf-> in_phases_upto_and_including_post_dispatch, env, dispatch); + if(AXIS2_FAILURE == status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding dispatcher into in phases upto and including post dispatch list failed"); + return AXIS2_FAILURE; + } + + post_dispatch = axis2_phase_create(env, AXIS2_PHASE_POST_DISPATCH); + if(!post_dispatch) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating phase %s failed", + AXIS2_PHASE_POST_DISPATCH); + axis2_phase_free(dispatch, env); + return AXIS2_FAILURE; + } + + disp_checker = axis2_disp_checker_create(env); + + handler = axis2_disp_checker_get_base(disp_checker, env); + axis2_phase_add_handler_at(post_dispatch, env, 0, handler); + + status = axutil_array_list_add(conf-> in_phases_upto_and_including_post_dispatch, env, + post_dispatch); + if(AXIS2_FAILURE == status) + { + axis2_phase_free(dispatch, env); + axis2_phase_free(post_dispatch, env); + axis2_disp_checker_free(disp_checker, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding post dispatcher into in phases upto and including post dispatch list failed"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +/** + * For each module reference qname stored in dep_engine this function is called. + * All module_desc instances are stored in axis2_conf. So each module_desc + * is retrieved from there by giving module_qname and engaged globally by + * calling phase_resolvers engage_module_globally function. Modules are added + * to axis2_conf's engaged module list. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_engage_module( + axis2_conf_t * conf, + const axutil_env_t * env, + const axutil_qname_t * module_ref) +{ + axis2_module_desc_t *module_desc = NULL; + axis2_bool_t is_new_module = AXIS2_FALSE; + axis2_bool_t to_be_engaged = AXIS2_TRUE; + axis2_dep_engine_t *dep_engine = NULL; + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *file_name = NULL; + + AXIS2_PARAM_CHECK(env->error, module_ref, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + + module_desc = axis2_conf_get_module(conf, env, module_ref); + if(!module_desc) + { + axutil_file_t *file = NULL; + const axis2_char_t *repos_path = NULL; + axis2_arch_file_data_t *file_data = NULL; + axis2_char_t *temp_path1 = NULL; + axis2_char_t *temp_path2 = NULL; + axis2_char_t *temp_path3 = NULL; + axis2_char_t *path = NULL; + axutil_param_t *module_dir_param = NULL; + axis2_char_t *module_dir = NULL; + axis2_bool_t flag; + axis2_char_t *axis2_xml = NULL; + + file_name = axutil_qname_get_localpart(module_ref, env); + file = (axutil_file_t *)axis2_arch_reader_create_module_arch(env, file_name); + /* This flag is to check whether conf is built using axis2 + * xml configuration file instead of a repository. */ + flag = axis2_conf_get_axis2_flag(conf, env); + + if(!flag) + { + repos_path = axis2_conf_get_repo(conf, env); + temp_path1 = axutil_stracat(env, repos_path, AXIS2_PATH_SEP_STR); + temp_path2 = axutil_stracat(env, temp_path1, AXIS2_MODULE_FOLDER); + temp_path3 = axutil_stracat(env, temp_path2, AXIS2_PATH_SEP_STR); + path = axutil_stracat(env, temp_path3, file_name); + AXIS2_FREE(env->allocator, temp_path1); + AXIS2_FREE(env->allocator, temp_path2); + AXIS2_FREE(env->allocator, temp_path3); + } + else + { + /** + * This case is to obtain module path from the axis2.xml + */ + axis2_xml = (axis2_char_t *)axis2_conf_get_axis2_xml(conf, env); + module_dir_param = axis2_conf_get_param(conf, env, AXIS2_MODULE_DIR); + + if(module_dir_param) + { + module_dir = (axis2_char_t *)axutil_param_get_value(module_dir_param, env); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "moduleDir parameter not available in axis2.xml."); + + return AXIS2_FAILURE; + } + + temp_path1 = axutil_strcat(env, module_dir, AXIS2_PATH_SEP_STR, NULL); + path = axutil_strcat(env, temp_path1, file_name, NULL); + } + + axutil_file_set_path(file, env, path); + file_data = axis2_arch_file_data_create_with_type_and_file(env, AXIS2_MODULE, file); + if(!flag) + { + dep_engine = axis2_dep_engine_create_with_repos_name(env, repos_path); + } + else + { + dep_engine = axis2_dep_engine_create_with_axis2_xml(env, axis2_xml); + } + + axis2_dep_engine_set_current_file_item(dep_engine, env, file_data); + + /* this module_dir set the path of the module directory + * Pertaining to this module. This value will use inside the + * axis2_dep_engine_build_module function + */ + + axis2_dep_engine_set_module_dir(dep_engine, env, path); + + if(path) + { + AXIS2_FREE(env->allocator, path); + } + + if(file_data) + { + axis2_arch_file_data_free(file_data, env); + } + + module_desc = axis2_dep_engine_build_module(dep_engine, env, file, conf); + axutil_file_free(file, env); + is_new_module = AXIS2_TRUE; + } + + if(module_desc) + { + int size = 0; + int i = 0; + const axutil_qname_t *module_qname = NULL; + + size = axutil_array_list_size(conf->engaged_module_list, env); + module_qname = axis2_module_desc_get_qname(module_desc, env); + for(i = 0; i < size; i++) + { + axutil_qname_t *qname = NULL; + + qname = (axutil_qname_t *)axutil_array_list_get(conf->engaged_module_list, env, i); + if(axutil_qname_equals(module_qname, env, qname)) + { + to_be_engaged = AXIS2_FALSE; + } + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODULE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Either module description not set or building" + "module description failed for module %s", file_name); + + return AXIS2_FAILURE; + } + + if(to_be_engaged) + { + axis2_phase_resolver_t *phase_resolver = NULL; + axutil_qname_t *module_qref_l = NULL; + const axutil_qname_t *module_qname = NULL; + axis2_char_t *module_name = NULL; + + module_qname = axis2_module_desc_get_qname(module_desc, env); + module_name = axutil_qname_get_localpart(module_qname, env); + phase_resolver = axis2_phase_resolver_create_with_config(env, conf); + if(!phase_resolver) + { + return AXIS2_FAILURE; + } + + status = axis2_phase_resolver_engage_module_globally(phase_resolver, env, module_desc); + axis2_phase_resolver_free(phase_resolver, env); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Engaging module %s globally failed", + module_name); + return status; + } + module_qref_l = axutil_qname_clone((axutil_qname_t *)module_qname, env); + status = axutil_array_list_add(conf->engaged_module_list, env, module_qref_l); + } + + if(is_new_module) + { + status = axis2_conf_add_module(conf, env, module_desc); + } + + return status; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_conf_get_repo( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->axis2_repo; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_repo( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_char_t * repos_path) +{ + if(conf->axis2_repo) + { + AXIS2_FREE(env->allocator, conf->axis2_repo); + conf->axis2_repo = NULL; + } + conf->axis2_repo = axutil_strdup(env, repos_path); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_conf_get_axis2_xml( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return axutil_strdup(env, conf->axis2_xml); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_axis2_xml( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_char_t * axis2_xml) +{ + AXIS2_PARAM_CHECK(env->error, axis2_xml, AXIS2_FAILURE); + conf->axis2_xml = axutil_strdup(env, axis2_xml); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_dep_engine( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_dep_engine_t * dep_engine) +{ + conf->dep_engine = dep_engine; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_conf_get_default_module_version( + const axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * module_name) +{ + axutil_hash_t *def_ver_map = NULL; + AXIS2_PARAM_CHECK(env->error, module_name, NULL); + + def_ver_map = conf->name_to_version_map; + if(!def_ver_map) + { + return NULL; + } + return axutil_hash_get(def_ver_map, module_name, AXIS2_HASH_KEY_STRING); +} + +AXIS2_EXTERN axis2_module_desc_t *AXIS2_CALL +axis2_conf_get_default_module( + const axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * module_name) +{ + axis2_module_desc_t *ret_mod = NULL; + axis2_char_t *mod_name = NULL; + const axis2_char_t *mod_ver = NULL; + axutil_hash_t *all_modules = NULL; + axutil_qname_t *mod_qname = NULL; + + AXIS2_PARAM_CHECK(env->error, module_name, NULL); + + all_modules = conf->all_modules; + mod_ver = axis2_conf_get_default_module_version(conf, env, module_name); + + if(!mod_ver) + { + mod_name = axutil_strdup(env, module_name); + } + else + { + axis2_char_t *tmp_name = NULL; + tmp_name = axutil_stracat(env, module_name, "-"); + mod_name = axutil_stracat(env, tmp_name, mod_ver); + AXIS2_FREE(env->allocator, tmp_name); + } + mod_qname = axutil_qname_create(env, mod_name, NULL, NULL); + AXIS2_FREE(env->allocator, mod_name); + mod_name = NULL; + + if(!mod_qname) + { + return NULL; + } + ret_mod = (axis2_module_desc_t *)axutil_hash_get(all_modules, axutil_qname_to_string(mod_qname, + env), AXIS2_HASH_KEY_STRING); + + return ret_mod; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_add_default_module_version( + axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * module_name, + const axis2_char_t * module_version) +{ + axutil_hash_t *name_to_ver_map = NULL; + + AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module_version, AXIS2_FAILURE); + /* + * If we already have a default module version we don't put + * it again + */ + name_to_ver_map = conf->name_to_version_map; + + if(!axutil_hash_get(name_to_ver_map, module_name, AXIS2_HASH_KEY_STRING)) + { + axis2_char_t *new_entry = axutil_strdup(env, module_version); + if(!new_entry) + { + return AXIS2_FAILURE; + } + axutil_hash_set(name_to_ver_map, module_name, AXIS2_HASH_KEY_STRING, new_entry); + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_engage_module_with_version( + axis2_conf_t * conf, + const axutil_env_t * env, + const axis2_char_t * module_name, + const axis2_char_t * version_id) +{ + axutil_qname_t *module_qname = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE); + + module_qname = axis2_core_utils_get_module_qname(env, module_name, version_id); + if(!module_qname) + { + return AXIS2_FAILURE; + } + status = axis2_conf_engage_module(conf, env, module_qname); + axutil_qname_free(module_qname, env); + return status; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_conf_get_enable_mtom( + axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->enable_mtom; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_enable_mtom( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_bool_t enable_mtom) +{ + conf->enable_mtom = enable_mtom; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_conf_get_axis2_flag( + axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->axis2_flag; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_axis2_flag( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_bool_t axis2_flag) +{ + conf->axis2_flag = axis2_flag; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_conf_get_enable_security( + axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->enable_security; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_enable_security( + axis2_conf_t * conf, + const axutil_env_t * env, + axis2_bool_t enable_security) +{ + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + + conf->enable_security = enable_security; + return AXIS2_SUCCESS; +} + +#if 0 +/* this seemed to be not used after 1.6.0 */ +AXIS2_EXTERN void *AXIS2_CALL +axis2_conf_get_security_context( + axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->security_context; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_conf_set_security_context( + axis2_conf_t * conf, + const axutil_env_t * env, + void *security_context) +{ + AXIS2_PARAM_CHECK(env->error, conf, AXIS2_FAILURE); + + conf->security_context = (void *) security_context; + return AXIS2_SUCCESS; +} +#endif + +AXIS2_EXTERN axutil_param_container_t *AXIS2_CALL +axis2_conf_get_param_container( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->param_container; +} + +AXIS2_EXTERN axis2_desc_t *AXIS2_CALL +axis2_conf_get_base( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->base; +} + +AXIS2_EXTERN axutil_array_list_t * AXIS2_CALL +axis2_conf_get_handlers( + const axis2_conf_t * conf, + const axutil_env_t * env) +{ + return conf->handlers; +} + diff --git a/src/core/engine/ctx_handler.c b/src/core/engine/ctx_handler.c new file mode 100644 index 0000000..4cafaf5 --- /dev/null +++ b/src/core/engine/ctx_handler.c @@ -0,0 +1,204 @@ +/* + * 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_handler_desc.h> +#include <axutil_string.h> +#include <axis2_svc.h> +#include <axis2_conf_ctx.h> + +const axis2_char_t *AXIS2_CTX_HANDLER_NAME = "context_handler"; + +/** + * By the time the control comes to this handler, the dispatching must have + * happened so that the message context contains the service group, service and + * operation. This will then try to find the contexts for service group, service + * and the operation. + */ + +axis2_status_t AXIS2_CALL +axis2_ctx_handler_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx *msg_ctx); + +axis2_handler_t *AXIS2_CALL +axis2_ctx_handler_create( + const axutil_env_t * env, + const axutil_string_t * string) +{ + axis2_handler_t *handler = NULL; + axis2_handler_desc_t *handler_desc = NULL; + axutil_string_t *handler_string = NULL; + + if(string) + { + handler_string = axutil_string_clone((axutil_string_t *)string, env); + if(!(handler_string)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + else + { + /* create default string */ + handler_string = axutil_string_create_const(env, (axis2_char_t **)&AXIS2_CTX_HANDLER_NAME); + if(!handler_string) + { + return NULL; + } + } + + handler = axis2_handler_create(env); + if(!handler) + { + return NULL; + } + + /* handler desc of base handler */ + handler_desc = axis2_handler_desc_create(env, handler_string); + axutil_string_free(handler_string, env); + if(!handler_desc) + { + axis2_handler_free(handler, env); + return NULL; + } + + axis2_handler_init(handler, env, handler_desc); + + /* set the base struct's invoke op */ + axis2_handler_set_invoke(handler, env, axis2_ctx_handler_invoke); + + return handler; +} + +axis2_status_t AXIS2_CALL +axis2_ctx_handler_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + axis2_op_t *op = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_svc_grp_ctx_t *svc_grp_ctx = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_ctx_handler_invoke"); + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + svc_ctx = axis2_msg_ctx_get_svc_ctx(msg_ctx, env); + + if(op_ctx && svc_ctx) + { + svc_grp_ctx = axis2_svc_ctx_get_parent(svc_ctx, env); + if(svc_grp_ctx) + { + axutil_string_t *svc_grp_ctx_id_str = axutil_string_create(env, + axis2_svc_grp_ctx_get_id(svc_grp_ctx, env)); + axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, svc_grp_ctx_id_str); + axutil_string_free(svc_grp_ctx_id_str, env); + } + return AXIS2_SUCCESS; + } + + op = axis2_msg_ctx_get_op(msg_ctx, env); + if(op) + { + op_ctx = axis2_op_find_existing_op_ctx(op, env, msg_ctx); + } + + if(op_ctx) + { + axis2_op_register_op_ctx(op, env, msg_ctx, op_ctx); + svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); + if(svc_ctx) + { + axutil_string_t *svc_grp_ctx_id_str = NULL; + const axis2_char_t *grp_ctx_id = NULL; + + svc_grp_ctx = axis2_svc_ctx_get_parent(svc_ctx, env); + axis2_msg_ctx_set_svc_ctx(msg_ctx, env, svc_ctx); + axis2_msg_ctx_set_svc_grp_ctx(msg_ctx, env, svc_grp_ctx); + grp_ctx_id = axis2_svc_grp_ctx_get_id(svc_grp_ctx, env); + svc_grp_ctx_id_str = axutil_string_create(env, grp_ctx_id); + axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, svc_grp_ctx_id_str); + axutil_string_free(svc_grp_ctx_id_str, env); + } + + return AXIS2_SUCCESS; + } + else if(op) /* 2. if no op_ctx, create new op_ctx */ + { + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_bool_t use_pools = AXIS2_FALSE; + axutil_param_t *param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_PERSIST_OP_CTX); + + use_pools = (param && 0 == axutil_strcmp(AXIS2_VALUE_TRUE, axutil_param_get_value(param, + env))); + + if(use_pools) + { + axutil_allocator_switch_to_global_pool(env->allocator); + } + op_ctx = axis2_op_ctx_create(env, op, NULL); + if(!op_ctx) + { + axis2_char_t *op_name = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Could not create Operation context for operatoin %s", op_name); + + return AXIS2_FAILURE; + } + + axis2_msg_ctx_set_op_ctx(msg_ctx, env, op_ctx); + + axis2_op_register_op_ctx(op, env, msg_ctx, op_ctx); + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + if(!use_pools) + { + axutil_allocator_switch_to_global_pool(env->allocator); + } + + svc_grp_ctx = axis2_conf_ctx_fill_ctxs(conf_ctx, env, msg_ctx); + + if(!use_pools) + { + axutil_allocator_switch_to_local_pool(env->allocator); + } + } + + if(use_pools) + { + axutil_allocator_switch_to_local_pool(env->allocator); + } + } + + if(!svc_grp_ctx && (axis2_msg_ctx_get_server_side(msg_ctx, env))) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service group context not found"); + return AXIS2_FAILURE; + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_ctx_handler_invoke"); + + return AXIS2_SUCCESS; +} + diff --git a/src/core/engine/disp.c b/src/core/engine/disp.c new file mode 100644 index 0000000..51cb56d --- /dev/null +++ b/src/core/engine/disp.c @@ -0,0 +1,185 @@ +/* + * 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_disp.h> +#include <axis2_handler_desc.h> +#include <axutil_string.h> +#include <axis2_relates_to.h> +#include <axis2_svc.h> +#include <axis2_const.h> +#include <axis2_msg_ctx.h> + +const axis2_char_t *AXIS2_DISP_NAME = "abstract_dispatcher"; + +struct axis2_disp +{ + + /** base class, inherits from handler */ + axis2_handler_t *base; + + /** phase name */ + axutil_string_t *name; + + /** derived struct */ + void *derived; /* deep copy */ + int derived_type; +}; + +axis2_disp_t *AXIS2_CALL +axis2_disp_create( + const axutil_env_t * env, + const axutil_string_t * name) +{ + axis2_disp_t *disp = NULL; + axis2_handler_desc_t *handler_desc = NULL; + + disp = AXIS2_MALLOC(env->allocator, sizeof(axis2_disp_t)); + if(!disp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + disp->name = NULL; + disp->base = NULL; + + if(name) + { + disp->name = axutil_string_clone((axutil_string_t *)name, env); + if(!(disp->name)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_disp_free(disp, env); + return NULL; + } + } + else + { + /* create default name */ + disp->name = axutil_string_create_const(env, (axis2_char_t **)&AXIS2_DISP_NAME); + if(!(disp->name)) + { + axis2_disp_free(disp, env); + return NULL; + } + } + + disp->base = axis2_handler_create(env); + if(!disp->base) + { + axis2_disp_free(disp, env); + return NULL; + } + + /* handler desc of base handler */ + handler_desc = axis2_handler_desc_create(env, disp->name); + if(!handler_desc) + { + axis2_disp_free(disp, env); + return NULL; + } + + axis2_handler_init(disp->base, env, handler_desc); + + return disp; +} + +axis2_handler_t *AXIS2_CALL +axis2_disp_get_base( + const axis2_disp_t * disp, + const axutil_env_t * env) +{ + return disp->base; +} + +axutil_string_t *AXIS2_CALL +axis2_disp_get_name( + const axis2_disp_t * disp, + const axutil_env_t * env) +{ + return disp->name; +} + +axis2_status_t AXIS2_CALL +axis2_disp_set_name( + struct axis2_disp * disp, + const axutil_env_t * env, + axutil_string_t * name) +{ + if(disp->name) + { + axutil_string_free(disp->name, env); + } + + if(name) + { + disp->name = axutil_string_clone(name, env); + if(!(disp->name)) + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_disp_find_svc_and_op( + struct axis2_handler * handler, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + axis2_svc_t *axis_service = NULL; + axis2_op_t *op = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + axis_service = axis2_msg_ctx_get_svc(msg_ctx, env); + + if(!axis_service) + { + axis_service = axis2_msg_ctx_find_svc(msg_ctx, env); + if(axis_service) + { + axis2_msg_ctx_set_svc(msg_ctx, env, axis_service); + } + } + op = axis2_msg_ctx_get_op(msg_ctx, env); + if(!op) + { + op = axis2_msg_ctx_find_op(msg_ctx, env, axis_service); + + if(op) + { + axis2_msg_ctx_set_op(msg_ctx, env, op); + } + } + + return AXIS2_SUCCESS; +} + +void AXIS2_CALL +axis2_disp_free( + struct axis2_disp *disp, + const axutil_env_t * env) +{ + if(disp->name) + { + axutil_string_free(disp->name, env); + } + AXIS2_FREE(env->allocator, disp); + return; +} + diff --git a/src/core/engine/disp_checker.c b/src/core/engine/disp_checker.c new file mode 100644 index 0000000..b668a9a --- /dev/null +++ b/src/core/engine/disp_checker.c @@ -0,0 +1,284 @@ +/* + * 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_disp_checker.h" +#include <axis2_handler_desc.h> +#include <axutil_string.h> +#include <axis2_relates_to.h> +#include <axis2_svc.h> +#include <axis2_const.h> +#include <axis2_msg_ctx.h> +#include <axis2_op_ctx.h> +#include <axis2_svc_ctx.h> +#include <axis2_endpoint_ref.h> +#include <axiom_soap.h> +#include <axiom.h> + +const axis2_char_t *AXIS2_DISP_CHECKER_NAME = "dispatch_post_conditions_evaluator"; + +struct axis2_disp_checker +{ + + /** base class, inherits from handler */ + axis2_handler_t *base; + + /** phase name */ + axutil_string_t *name; +}; + +axis2_status_t AXIS2_CALL +axis2_disp_checker_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +axis2_disp_checker_t *AXIS2_CALL +axis2_disp_checker_create( + const axutil_env_t * env) +{ + axis2_disp_checker_t *disp_checker = NULL; + axis2_handler_desc_t *handler_desc = NULL; + + disp_checker = AXIS2_MALLOC(env->allocator, sizeof(axis2_disp_checker_t)); + if(!disp_checker) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + disp_checker->name = NULL; + disp_checker->base = NULL; + + /* create default name */ + disp_checker->name = axutil_string_create_const(env, (axis2_char_t **)&AXIS2_DISP_CHECKER_NAME); + + if(!(disp_checker->name)) + { + axis2_disp_checker_free(disp_checker, env); + return NULL; + } + + disp_checker->base = axis2_handler_create(env); + if(!disp_checker->base) + { + axis2_disp_checker_free(disp_checker, env); + return NULL; + } + axis2_handler_set_invoke(disp_checker->base, env, axis2_disp_checker_invoke); + + /* handler desc of base handler */ + handler_desc = axis2_handler_desc_create(env, disp_checker->name); + if(!handler_desc) + { + axis2_disp_checker_free(disp_checker, env); + return NULL; + } + + axis2_handler_init(disp_checker->base, env, handler_desc); + return disp_checker; +} + +axis2_handler_t *AXIS2_CALL +axis2_disp_checker_get_base( + const axis2_disp_checker_t * disp_checker, + const axutil_env_t * env) +{ + return disp_checker->base; +} + +axutil_string_t *AXIS2_CALL +axis2_disp_checker_get_name( + const axis2_disp_checker_t * disp_checker, + const axutil_env_t * env) +{ + return disp_checker->name; +} + +axis2_status_t AXIS2_CALL +axis2_disp_checker_set_name( + axis2_disp_checker_t * disp_checker, + const axutil_env_t * env, + const axutil_string_t * name) +{ + if(disp_checker->name) + { + axutil_string_free(disp_checker->name, env); + disp_checker->name = NULL; + } + + if(name) + { + disp_checker->name = axutil_string_clone((axutil_string_t *)name, env); + if(!(disp_checker->name)) + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +void AXIS2_CALL +axis2_disp_checker_free( + axis2_disp_checker_t * disp_checker, + const axutil_env_t * env) +{ + if(disp_checker->name) + { + axutil_string_free(disp_checker->name, env); + } + + AXIS2_FREE(env->allocator, disp_checker); + + return; +} + +axis2_status_t AXIS2_CALL +axis2_disp_checker_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_op_t *op = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_svc_t *svc = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_endpoint_ref_t *endpoint_ref = NULL; + const axis2_char_t *address = NULL; + axiom_soap_fault_t *soap_fault; + axiom_soap_envelope_t *soap_envelope; + axiom_soap_body_t *soap_body; + int soap_version = AXIOM_SOAP12; + axis2_char_t *fault_code = NULL; + + axis2_char_t exception[1024]; + axis2_char_t *wsa_action; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + /*if is client side, no point in proceeding */ + if(!(axis2_msg_ctx_get_server_side(msg_ctx, env))) + return AXIS2_SUCCESS; + + op = axis2_msg_ctx_get_op(msg_ctx, env); + + if(!op) + { + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); + if(op) + axis2_msg_ctx_set_op(msg_ctx, env, op); + } + } + + svc = axis2_msg_ctx_get_svc(msg_ctx, env); + + if(!svc) + { + svc_ctx = axis2_msg_ctx_get_svc_ctx(msg_ctx, env); + if(svc_ctx) + { + axis2_svc_t *tsvc = axis2_svc_ctx_get_svc(svc_ctx, env); + if(tsvc) + axis2_msg_ctx_set_svc(msg_ctx, env, tsvc); + } + } + endpoint_ref = axis2_msg_ctx_get_to(msg_ctx, env); + + if(endpoint_ref) + { + address = axis2_endpoint_ref_get_address(endpoint_ref, env); + } + + svc = axis2_msg_ctx_get_svc(msg_ctx, env); + if(!svc) + { + AXIS2_LOG_INFO(env->log, "Service Not found. Endpoint reference is : %s", + (address) ? address : "NULL"); + if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + soap_version = AXIOM_SOAP11; +fault_code = + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" + AXIOM_SOAP11_FAULT_CODE_RECEIVER; + } + else + { + fault_code = + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" + AXIOM_SOAP12_SOAP_FAULT_VALUE_RECEIVER; + + } + + soap_envelope = + axiom_soap_envelope_create_default_soap_envelope(env, soap_version); + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + soap_fault = + axiom_soap_fault_create_default_fault(env, soap_body, fault_code, + "Service Not Found", + soap_version); + + wsa_action = (axis2_char_t *)axis2_msg_ctx_get_wsa_action (msg_ctx, + env); + sprintf (exception, "Service Not Found, Endpoint referance address is %s and wsa\ + actions is %s", address, wsa_action); + + axiom_soap_fault_set_exception (soap_fault, env, exception); + axis2_msg_ctx_set_fault_soap_envelope(msg_ctx, env, soap_envelope); + return AXIS2_FAILURE; +} + +op = axis2_msg_ctx_get_op(msg_ctx, env); +if (!op) +{ + AXIS2_LOG_INFO(env->log, + "Operation Not found. Endpoint reference is : %s", + (address) ? address : "NULL"); + if (axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + soap_version = AXIOM_SOAP11; + fault_code = + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" + AXIOM_SOAP11_FAULT_CODE_RECEIVER; + } + else + { + fault_code = + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" + AXIOM_SOAP12_SOAP_FAULT_VALUE_RECEIVER; + } + + soap_envelope = + axiom_soap_envelope_create_default_soap_envelope(env, soap_version); + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + soap_fault = + axiom_soap_fault_create_default_fault(env, soap_body, fault_code, + "Operation Not Found", + soap_version); + + wsa_action = (axis2_char_t *)axis2_msg_ctx_get_wsa_action (msg_ctx, + env); + sprintf (exception, "Operation Not Found, Endpoint referance address is %s and wsa\ + actions is %s", address, wsa_action); + + axiom_soap_fault_set_exception (soap_fault, env, exception); + axis2_msg_ctx_set_fault_soap_envelope(msg_ctx, env, soap_envelope); + return AXIS2_FAILURE; +} +return AXIS2_SUCCESS; +} + diff --git a/src/core/engine/engine.c b/src/core/engine/engine.c new file mode 100644 index 0000000..a098ea1 --- /dev/null +++ b/src/core/engine/engine.c @@ -0,0 +1,915 @@ +/* + * 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_engine.h> +#include <axis2_const.h> +#include <axutil_hash.h> +#include <axiom_soap_const.h> +#include <axiom_soap_envelope.h> +#include <axiom_soap_body.h> +#include <axiom_soap_fault.h> +#include <axiom_soap_header.h> +#include <axiom_soap_header_block.h> +#include <axis2_transport_sender.h> +#include <axis2_addr.h> +#include <axutil_uuid_gen.h> + +struct axis2_engine +{ + /** Configuration context */ + axis2_conf_ctx_t *conf_ctx; +}; + +axis2_status_t +axis2_engine_check_must_understand_headers( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +AXIS2_EXTERN axis2_engine_t * AXIS2_CALL +axis2_engine_create( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_engine_t *engine = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + engine = AXIS2_MALLOC(env->allocator, sizeof(axis2_engine_t)); + if(!engine) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + engine->conf_ctx = NULL; + + if(conf_ctx) + { + engine->conf_ctx = conf_ctx; + } + + return engine; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_engine_free( + axis2_engine_t * engine, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, engine); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_engine_send( + axis2_engine_t * engine, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_status_t status = AXIS2_SUCCESS; + axis2_op_ctx_t *op_ctx = NULL; + axutil_array_list_t *phases = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "axis2_engine_send start"); + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + /* Find and invoke the phases */ + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); + if(op) + { + phases = axis2_op_get_out_flow(op, env); + } + } + + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + /* Message has paused, so rerun it from the position it stopped. + The handler which paused the message will be the first one to resume + invocation + */ + status = axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Resuming invocation of phases failed"); + return status; + } + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + axutil_array_list_t *global_out_phase = axis2_conf_get_out_phases(conf, env); + if(global_out_phase) + { + axis2_engine_invoke_phases(engine, env, global_out_phase, msg_ctx); + } + } + } + } + else + { + status = axis2_engine_invoke_phases(engine, env, phases, msg_ctx); + if(status != AXIS2_SUCCESS) + { + return status; + } + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + axutil_array_list_t *global_out_phase = axis2_conf_get_out_phases(conf, env); + if(global_out_phase) + { + axis2_engine_invoke_phases(engine, env, global_out_phase, msg_ctx); + } + } + } + } + + if(!(axis2_msg_ctx_is_paused(msg_ctx, env))) + { + /* Write the message to wire */ + axis2_transport_sender_t *transport_sender = NULL; + axis2_transport_out_desc_t *transport_out = axis2_msg_ctx_get_transport_out_desc(msg_ctx, + env); + + if(transport_out) + { + transport_sender = axis2_transport_out_desc_get_sender(transport_out, env); + if(!transport_sender) + return AXIS2_FAILURE; + + status = AXIS2_TRANSPORT_SENDER_INVOKE(transport_sender, env, msg_ctx); + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport sender invoke failed"); + return status; + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport out is not set in message context"); + return AXIS2_FAILURE; + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "axis2_engine_send end successfully"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_engine_receive( + axis2_engine_t * engine, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_op_t *op = NULL; + axutil_array_list_t *pre_calculated_phases = NULL; + axutil_array_list_t *op_specific_phases = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_receive"); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + + pre_calculated_phases = axis2_conf_get_in_phases_upto_and_including_post_dispatch(conf, env); + + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + /* The message has paused, so re-run them from the position they stopped. */ + axis2_engine_resume_invocation_phases(engine, env, pre_calculated_phases, msg_ctx); + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Message context is paused. So return here."); + return AXIS2_SUCCESS; + } + + /* Resume op specific phases */ + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + op = axis2_op_ctx_get_op(op_ctx, env); + op_specific_phases = axis2_op_get_in_flow(op, env); + axis2_engine_resume_invocation_phases(engine, env, op_specific_phases, msg_ctx); + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Message context is paused. So return here."); + return AXIS2_SUCCESS; + } + } + } + else + { + status = axis2_engine_invoke_phases(engine, env, pre_calculated_phases, msg_ctx); + if(status != AXIS2_SUCCESS) + { + if(axis2_msg_ctx_get_server_side(msg_ctx, env)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invoking pre-calculated phases failed"); + return status; + } + } + + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Message context is paused. So return here."); + return AXIS2_SUCCESS; + } + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + op = axis2_op_ctx_get_op(op_ctx, env); + op_specific_phases = axis2_op_get_in_flow(op, env); + status = axis2_engine_invoke_phases(engine, env, op_specific_phases, msg_ctx); + if(status != AXIS2_SUCCESS) + { + axis2_char_t *op_name = NULL; + op_name = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invoking operation specific phases failed for operation %s", op_name); + return status; + } + + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Message context is paused. So return here."); + return AXIS2_SUCCESS; + } + } + } + + if((axis2_msg_ctx_get_server_side(msg_ctx, env)) && !(axis2_msg_ctx_is_paused(msg_ctx, env))) + { + axis2_msg_recv_t *receiver = NULL; + + status = axis2_engine_check_must_understand_headers(env, msg_ctx); + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Check for must understand headers failed"); + return status; + } + + /* Invoke the message receivers */ + if(!op) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Operation not found"); + return AXIS2_FAILURE; + } + receiver = axis2_op_get_msg_recv(op, env); + if(!receiver) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Message receiver not set in operation description"); + return AXIS2_FAILURE; + } + status = axis2_msg_recv_receive(receiver, env, msg_ctx, axis2_msg_recv_get_derived( + receiver, env)); + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_engine_receive"); + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_engine_send_fault( + axis2_engine_t * engine, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_op_ctx_t *op_ctx = NULL; + axis2_status_t status = AXIS2_SUCCESS; + axutil_array_list_t *phases = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); + if(op) + { + phases = axis2_op_get_fault_out_flow(op, env); + } + } + + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + /* Message has paused, so rerun it from the position it stopped. + The handler which paused the message will be the first one to resume + invocation + */ + status = axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Resuming invoking the phases failed"); + return status; + } + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + axutil_array_list_t *global_out_fault_phase = axis2_conf_get_out_fault_flow(conf, + env); + if(global_out_fault_phase) + { + axis2_engine_invoke_phases(engine, env, global_out_fault_phase, msg_ctx); + } + } + } + } + else + { + status = axis2_engine_invoke_phases(engine, env, phases, msg_ctx); + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + axutil_array_list_t *global_out_fault_phase = axis2_conf_get_out_fault_flow(conf, + env); + if(global_out_fault_phase) + { + axis2_engine_invoke_phases(engine, env, global_out_fault_phase, msg_ctx); + } + } + } + } + + if(!(axis2_msg_ctx_is_paused(msg_ctx, env))) + { + /* Write the message to wire */ + axis2_transport_sender_t *transport_sender = NULL; + axis2_transport_out_desc_t *transport_out = axis2_msg_ctx_get_transport_out_desc(msg_ctx, + env); + + if(transport_out) + { + transport_sender = axis2_transport_out_desc_get_sender(transport_out, env); + + if(transport_sender) + { + AXIS2_TRANSPORT_SENDER_INVOKE(transport_sender, env, msg_ctx); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport sender not found"); + return AXIS2_FAILURE; + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport out is not set in message context"); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_engine_receive_fault( + axis2_engine_t * engine, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_op_ctx_t *op_ctx = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_receive_fault"); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + + if(!op_ctx) + { + /* If we do not have an op context that means this may be an incoming + dual channel response. So try to dispatch the service */ + axis2_conf_ctx_t *conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + axis2_conf_t *conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + axutil_array_list_t *phases = + axis2_conf_get_in_phases_upto_and_including_post_dispatch(conf, env); + if(phases) + { + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); + } + else + { + axis2_engine_invoke_phases(engine, env, phases, msg_ctx); + } + } + } + } + } + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + /* Find and execute the fault in flow handlers */ + if(op_ctx) + { + axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); + axutil_array_list_t *phases = axis2_op_get_fault_in_flow(op, env); + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); + } + else + { + axis2_engine_invoke_phases(engine, env, phases, msg_ctx); + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_engine_receive_fault"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_msg_ctx_t * AXIS2_CALL +axis2_engine_create_fault_msg_ctx( + axis2_engine_t * engine, + const axutil_env_t * env, + axis2_msg_ctx_t * processing_context, + const axis2_char_t * code_value, + const axis2_char_t * reason_text) +{ + axis2_msg_ctx_t *fault_ctx = NULL; + axis2_endpoint_ref_t *fault_to = NULL; + axis2_endpoint_ref_t *reply_to = NULL; + axutil_stream_t *stream = NULL; + axiom_soap_envelope_t *envelope = NULL; + const axis2_char_t *wsa_action = NULL; + const axis2_char_t *msg_id = NULL; + axis2_relates_to_t *relates_to = NULL; + axis2_char_t *msg_uuid = NULL; + axis2_msg_info_headers_t *msg_info_headers = NULL; + axis2_bool_t doing_rest = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, processing_context, NULL); + + if(axis2_msg_ctx_get_process_fault(processing_context, env)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_PROCESSING_FAULT_ALREADY, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creating fault message contex failed"); + return NULL; + } + + fault_ctx = axis2_msg_ctx_create(env, engine->conf_ctx, axis2_msg_ctx_get_transport_in_desc( + processing_context, env), axis2_msg_ctx_get_transport_out_desc(processing_context, env)); + + axis2_msg_ctx_set_process_fault(fault_ctx, env, AXIS2_TRUE); + + fault_to = axis2_msg_ctx_get_fault_to(processing_context, env); + if(fault_to) + { + const axis2_char_t *address = axis2_endpoint_ref_get_address(fault_to, env); + if(!address) + { + fault_to = NULL; + } + else if(axutil_strcmp(AXIS2_WSA_NONE_URL, address) == 0 || axutil_strcmp( + AXIS2_WSA_NONE_URL_SUBMISSION, address) == 0) + { + reply_to = axis2_msg_ctx_get_reply_to(processing_context, env); + if(reply_to) + { + axis2_msg_ctx_set_fault_to(fault_ctx, env, reply_to); + } + else + { + axis2_msg_ctx_set_fault_to(fault_ctx, env, fault_to); + } + } + else + { + axis2_msg_ctx_set_fault_to(fault_ctx, env, fault_to); + } + + } + + stream = axis2_msg_ctx_get_transport_out_stream(processing_context, env); + + if(stream) + { + axis2_msg_ctx_set_transport_out_stream(fault_ctx, env, stream); + } + + if(!fault_to && !stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NOWHERE_TO_SEND_FAULT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Soap fault target destination not found"); + return NULL; + } + + /* Set WSA action */ + msg_info_headers = axis2_msg_ctx_get_msg_info_headers(processing_context, env); + if(msg_info_headers) + { + wsa_action = axis2_msg_info_headers_get_action(msg_info_headers, env); + if(wsa_action) + { + /* + We have to use the action set by user, + cannot use the default always. + wsa_action = "http://www.w3.org/2005/08/addressing/fault"; */ + axis2_msg_ctx_set_wsa_action(fault_ctx, env, wsa_action); + } + } + + /* Set relates to */ + msg_id = axis2_msg_ctx_get_msg_id(processing_context, env); + + /* we can create with default Relates to namespace. + Actual namespace based on addressing version will be created in addressing out handler */ + relates_to = axis2_relates_to_create(env, msg_id, + AXIS2_WSA_RELATES_TO_RELATIONSHIP_TYPE_DEFAULT_VALUE); + axis2_msg_ctx_set_relates_to(fault_ctx, env, relates_to); + + /* Set msg id */ + msg_uuid = axutil_uuid_gen(env); + axis2_msg_ctx_set_message_id(fault_ctx, env, msg_uuid); + if(msg_uuid) + { + AXIS2_FREE(env->allocator, msg_uuid); + msg_uuid = NULL; + } + + /** Copy the property map from the current message context to the newly created fault message + context. */ + { + axis2_ctx_t *ctx = axis2_msg_ctx_get_base(processing_context, env); + axis2_ctx_t *fault_base_ctx = axis2_msg_ctx_get_base(fault_ctx, env); + + if(ctx && fault_ctx) + { + axis2_ctx_set_property_map(fault_base_ctx, env, axis2_ctx_get_property_map(ctx, env)); + } + + } + + + axis2_msg_ctx_set_op_ctx(fault_ctx, env, axis2_msg_ctx_get_op_ctx(processing_context, env)); + axis2_msg_ctx_set_process_fault(fault_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_server_side(fault_ctx, env, AXIS2_TRUE); + + envelope = axis2_msg_ctx_get_fault_soap_envelope(processing_context, env); + + if(!envelope) + { + if(axis2_msg_ctx_get_is_soap_11(processing_context, env)) + { + envelope = axiom_soap_envelope_create_default_soap_fault_envelope(env, code_value, + reason_text, AXIOM_SOAP11, NULL, NULL); + + } + else + { + envelope = axiom_soap_envelope_create_default_soap_fault_envelope(env, code_value, + reason_text, AXIOM_SOAP12, NULL, NULL); + } + + if(!envelope) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Creating default soap envelope failed"); + return NULL; + } + } + + doing_rest = axis2_msg_ctx_get_doing_rest(processing_context, env); + axis2_msg_ctx_set_doing_rest(fault_ctx, env, doing_rest); + + axis2_msg_ctx_set_soap_envelope(fault_ctx, env, envelope); + axis2_msg_ctx_set_out_transport_info(fault_ctx, env, axis2_msg_ctx_get_out_transport_info( + processing_context, env)); + return fault_ctx; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_engine_invoke_phases( + axis2_engine_t * engine, + const axutil_env_t * env, + axutil_array_list_t * phases, + axis2_msg_ctx_t * msg_ctx) +{ + int i = 0; + int count = 0; + axis2_status_t status = AXIS2_SUCCESS; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_invoke_phases"); + AXIS2_PARAM_CHECK(env->error, phases, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(phases) + count = axutil_array_list_size(phases, env); + for(i = 0; (i < count && !(axis2_msg_ctx_is_paused(msg_ctx, env))); i++) + { + axis2_phase_t *phase = (axis2_phase_t *)axutil_array_list_get(phases, env, i); + + status = axis2_phase_invoke(phase, env, msg_ctx); + + if(status != AXIS2_SUCCESS) + { + const axis2_char_t *phase_name = axis2_phase_get_name(phase, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invoking phase %s failed", phase_name); + return status; + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "End:axis2_engine_invoke_phases"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_engine_resume_invocation_phases( + axis2_engine_t * engine, + const axutil_env_t * env, + axutil_array_list_t * phases, + axis2_msg_ctx_t * msg_ctx) +{ + int i = 0; + int count = 0; + axis2_bool_t found_match = AXIS2_FALSE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_resume_invocation_phases"); + AXIS2_PARAM_CHECK(env->error, phases, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + axis2_msg_ctx_set_paused(msg_ctx, env, AXIS2_FALSE); + + count = axutil_array_list_size(phases, env); + + for(i = 0; i < count && !(axis2_msg_ctx_is_paused(msg_ctx, env)); i++) + { + axis2_phase_t *phase = (axis2_phase_t *)axutil_array_list_get(phases, env, i); + const axis2_char_t *phase_name = axis2_phase_get_name(phase, env); + const axis2_char_t *paused_phase_name = axis2_msg_ctx_get_paused_phase_name(msg_ctx, env); + /* Skip invoking handlers until we find the paused phase */ + if(phase_name && paused_phase_name && 0 == axutil_strcmp(phase_name, paused_phase_name)) + { + int paused_handler_i = -1; + found_match = AXIS2_TRUE; + + paused_handler_i = axis2_msg_ctx_get_current_handler_index(msg_ctx, env); + /* Invoke the paused handler and rest of the handlers of the paused + * phase */ + axis2_phase_invoke_start_from_handler(phase, env, paused_handler_i, msg_ctx); + } + else + { + /* Now we have found the paused phase and invoked the rest of the + * handlers of that phase, invoke all the phases after that */ + if(found_match) + { + axis2_phase_invoke(phase, env, msg_ctx); + } + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "End:axis2_engine_resume_invocation_phases"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t * AXIS2_CALL +axis2_engine_get_receiver_fault_code( + const axis2_engine_t * engine, + const axutil_env_t * env, + const axis2_char_t * soap_namespace) +{ + if(axutil_strcmp(AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI, soap_namespace)) + return AXIOM_SOAP12_FAULT_CODE_RECEIVER; + return AXIOM_SOAP11_FAULT_CODE_RECEIVER; +} + +axis2_status_t +axis2_engine_check_must_understand_headers( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_soap_header_t *soap_header = NULL; + axutil_hash_t *header_block_ht = NULL; + axutil_hash_index_t *hash_index = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + if(!soap_envelope) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Soap envelope not found in message context"); + return AXIS2_FAILURE; + } + + soap_header = axiom_soap_envelope_get_header(soap_envelope, env); + if(!soap_header) + return AXIS2_SUCCESS; + + header_block_ht = axiom_soap_header_get_all_header_blocks(soap_header, env); + if(!header_block_ht) + return AXIS2_SUCCESS; + + for(hash_index = axutil_hash_first(header_block_ht, env); hash_index; hash_index + = axutil_hash_next(env, hash_index)) + { + void *hb = NULL; + axiom_soap_header_block_t *header_block = NULL; + axis2_char_t *role = NULL; + + axutil_hash_this(hash_index, NULL, NULL, &hb); + header_block = (axiom_soap_header_block_t *)hb; + + if(header_block) + { + if(axiom_soap_header_block_is_processed(header_block, env) + || !axiom_soap_header_block_get_must_understand(header_block, env)) + { + continue; + } + + /* If this header block is not targeted to me then its not my + problem. Currently this code only supports the "next" role; we + need to fix this to allow the engine/service to be in one or more + additional roles and then to check that any headers targeted for + that role too have been dealt with. */ + role = axiom_soap_header_block_get_role(header_block, env); + + if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env) != AXIS2_TRUE) + { + /* SOAP 1.2 */ + if(!role || axutil_strcmp(role, AXIOM_SOAP12_SOAP_ROLE_NEXT) != 0) + { + axiom_soap_envelope_t *temp_env = + axiom_soap_envelope_create_default_soap_fault_envelope(env, + "soapenv:MustUnderstand", "Header not understood", AXIOM_SOAP12, NULL, + NULL); + axis2_msg_ctx_set_fault_soap_envelope(msg_ctx, env, temp_env); + axis2_msg_ctx_set_wsa_action(msg_ctx, env, + "http://www.w3.org/2005/08/addressing/fault"); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Must understand soap fault occured"); + return AXIS2_FAILURE; + } + } + else + { + /* SOAP 1.1 */ + if(!role || axutil_strcmp(role, AXIOM_SOAP11_SOAP_ACTOR_NEXT) != 0) + { + axiom_soap_envelope_t *temp_env = + axiom_soap_envelope_create_default_soap_fault_envelope(env, + "soapenv:MustUnderstand", "Header not understood", AXIOM_SOAP11, NULL, + NULL); + axis2_msg_ctx_set_fault_soap_envelope(msg_ctx, env, temp_env); + axis2_msg_ctx_set_wsa_action(msg_ctx, env, + "http://www.w3.org/2005/08/addressing/fault"); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Must understand soap fault occured"); + return AXIS2_FAILURE; + } + + } + + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_engine_resume_receive( + axis2_engine_t * engine, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axutil_array_list_t *phases = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_resume_receive"); + /* Find and invoke the phases */ + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + phases = axis2_conf_get_in_phases_upto_and_including_post_dispatch(conf, env); + + axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); + /* Invoking the message receiver */ + if(axis2_msg_ctx_get_server_side(msg_ctx, env) && !axis2_msg_ctx_is_paused(msg_ctx, env)) + { + /* Invoke the message receivers */ + axis2_op_ctx_t *op_ctx = NULL; + + status = axis2_engine_check_must_understand_headers(env, msg_ctx); + + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Checking for must understand headers failed"); + return status; + } + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); + if(op) + { + axis2_msg_recv_t *receiver = NULL; + receiver = axis2_op_get_msg_recv(op, env); + if(!receiver) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Message receiver not set in operation description"); + return AXIS2_FAILURE; + } + status = axis2_msg_recv_receive(receiver, env, msg_ctx, axis2_msg_recv_get_derived( + receiver, env)); + } + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_engine_resume_receive"); + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_engine_resume_send( + axis2_engine_t * engine, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_op_ctx_t *op_ctx = NULL; + axutil_array_list_t *phases = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_resume_send"); + /* Invoke the phases */ + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); + if(op) + { + phases = axis2_op_get_out_flow(op, env); + } + } + axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); + + /* Invoking transport sender */ + if(!axis2_msg_ctx_is_paused(msg_ctx, env)) + { + /* Write the message to the wire */ + axis2_transport_out_desc_t *transport_out = NULL; + axis2_transport_sender_t *sender = NULL; + transport_out = axis2_msg_ctx_get_transport_out_desc(msg_ctx, env); + if(transport_out) + { + sender = axis2_transport_out_desc_get_sender(transport_out, env); + if(sender) + { + status = AXIS2_TRANSPORT_SENDER_INVOKE(sender, env, msg_ctx); + } + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_engine_resume_send"); + return status; +} + diff --git a/src/core/engine/handler.c b/src/core/engine/handler.c new file mode 100644 index 0000000..e9edf24 --- /dev/null +++ b/src/core/engine/handler.c @@ -0,0 +1,133 @@ +/* + * 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_handler.h> +#include <axis2_handler_desc.h> + +struct axis2_handler +{ + + /** handler description. This is a reference, hence a shallow copy. */ + axis2_handler_desc_t *handler_desc; + + /** + * Invoke is called to do the actual work assigned to the handler. + * The phase that owns the handler is responsible for calling invoke + * on top of the handler. Those structs that implement the interface + * of the handler should implement the logic for invoke and assign the + * respective function pointer to invoke operation. + * @param handler pointer to handler + * @param env pointer to environment struct + * @param msg_ctx pointer to message context + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + axis2_status_t(AXIS2_CALL * invoke)( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx); +}; + +AXIS2_EXTERN axis2_handler_t *AXIS2_CALL +axis2_handler_create( + const axutil_env_t * env) +{ + axis2_handler_t *handler = NULL; + + handler = AXIS2_MALLOC(env->allocator, sizeof(axis2_handler_t)); + if(!handler) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY); + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE); + return NULL; + } + + handler->handler_desc = NULL; + + return handler; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_handler_free( + axis2_handler_t * handler, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, handler); + return; +} + +AXIS2_EXTERN const axutil_string_t *AXIS2_CALL +axis2_handler_get_name( + const axis2_handler_t * handler, + const axutil_env_t * env) +{ + if(!(handler->handler_desc)) + return NULL; + + return axis2_handler_desc_get_name(handler->handler_desc, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + return handler->invoke(handler, env, msg_ctx); +} + +AXIS2_EXTERN axutil_param_t *AXIS2_CALL +axis2_handler_get_param( + const axis2_handler_t * handler, + const axutil_env_t * env, + const axis2_char_t * name) +{ + if(!(handler->handler_desc)) + return NULL; + + return axis2_handler_desc_get_param(handler->handler_desc, env, name); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_init( + axis2_handler_t * handler, + const axutil_env_t * env, + axis2_handler_desc_t * handler_desc) +{ + handler->handler_desc = handler_desc; + axis2_handler_desc_set_handler(handler_desc, env, handler); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_handler_desc_t *AXIS2_CALL +axis2_handler_get_handler_desc( + const axis2_handler_t * handler, + const axutil_env_t * env) +{ + return handler->handler_desc; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_handler_set_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + AXIS2_HANDLER_INVOKE func) +{ + handler->invoke = func; + return AXIS2_SUCCESS; +} + diff --git a/src/core/engine/phase.c b/src/core/engine/phase.c new file mode 100644 index 0000000..a37ff95 --- /dev/null +++ b/src/core/engine/phase.c @@ -0,0 +1,1275 @@ +/* + * 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 <axutil_string.h> +#include <axis2_phase.h> +#include <axutil_array_list.h> +#include <axis2_msg_ctx.h> +#include <axis2_const.h> + +static axis2_status_t +axis2_phase_add_unique( + const axutil_env_t * env, + axutil_array_list_t * list, + axis2_handler_t * handler); + +static axis2_status_t +axis2_phase_remove_unique( + const axutil_env_t * env, + axutil_array_list_t * list, + axis2_handler_t * handler); + +struct axis2_phase +{ + + /** phase name */ + axis2_char_t *name; + + /** array list of handlers */ + axutil_array_list_t *handlers; + + /** first handler of phase */ + axis2_handler_t *first_handler; + + /** first handler of phase set? */ + axis2_bool_t first_handler_set; + + /** last handler of phase */ + axis2_handler_t *last_handler; + + /** last handler of phase set? */ + axis2_bool_t last_handler_set; + + /** + * handler_first and handler_last are the same handler + * that is for this phase there is only one handler + */ + axis2_bool_t is_one_handler; + + int ref; +}; + +AXIS2_EXTERN axis2_phase_t *AXIS2_CALL +axis2_phase_create( + const axutil_env_t * env, + const axis2_char_t * phase_name) +{ + axis2_phase_t *phase = NULL; + + phase = AXIS2_MALLOC(env->allocator, sizeof(axis2_phase_t)); + if(!phase) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return NULL; + } + + phase->name = NULL; + phase->handlers = NULL; + phase->first_handler = NULL; + phase->first_handler_set = AXIS2_FALSE; + phase->last_handler = NULL; + phase->last_handler_set = AXIS2_FALSE; + phase->is_one_handler = AXIS2_FALSE; + phase->ref = 1; + + phase->handlers = axutil_array_list_create(env, 10); + if(!(phase->handlers)) + { + + /** error is already set by last method array list container create */ + axis2_phase_free(phase, env); + return NULL; + } + + if(phase_name) + { + phase->name = axutil_strdup(env, phase_name); + if(!(phase->name)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + axis2_phase_free(phase, env); + return NULL; + } + } + + return phase; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_add_handler_at( + axis2_phase_t * phase, + const axutil_env_t * env, + const int index, + axis2_handler_t * handler) +{ + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "axis2_handler_t *%s added to the index %d of the phase %s", axutil_string_get_buffer( + axis2_handler_get_name(handler, env), env), index, phase->name); + + return axutil_array_list_add_at(phase->handlers, env, index, handler); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_add_handler( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + AXIS2_LOG_INFO(env->log, "Handler %s added to phase %s", axutil_string_get_buffer( + axis2_handler_get_name(handler, env), env), phase->name); + + return axis2_phase_add_unique(env, phase->handlers, handler); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_remove_handler( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + AXIS2_LOG_INFO(env->log, "Handler %s romoved from phase %s", axutil_string_get_buffer( + axis2_handler_get_name(handler, env), env), phase->name); + + return axis2_phase_remove_unique(env, phase->handlers, handler); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_invoke( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + int index = 0, size = 0; + axis2_status_t status = AXIS2_SUCCESS; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_invoke"); + axis2_msg_ctx_set_paused_phase_name(msg_ctx, env, phase->name); + if(phase->first_handler) + { + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + AXIS2_LOG_INFO(env->log, "Message context is paused in the phase %s", phase->name); + return AXIS2_SUCCESS; + } + else + { + const axis2_char_t *handler_name = axutil_string_get_buffer(axis2_handler_get_name( + phase->first_handler, env), env); + AXIS2_LOG_INFO(env->log, "Invoke the first handler %s within the phase %s", + handler_name, phase->name); + + status = axis2_handler_invoke(phase->first_handler, env, msg_ctx); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Handler %s invoke failed within phase %s", + handler_name, phase->name); + return status; + } + } + } + /* Invoking the rest of handlers except first_handler and last_handler */ + size = axutil_array_list_size(phase->handlers, env); + while(index < size) + { + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + break; + } + else + { + axis2_handler_t *handler = (axis2_handler_t *)axutil_array_list_get(phase->handlers, + env, index); + if(handler) + { + const axis2_char_t *handler_name = axutil_string_get_buffer(axis2_handler_get_name( + handler, env), env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Invoke the handler %s within the phase %s", handler_name, phase->name); + + /* Test code. This is used when valgrind is used to find leaks in Axis2/C modules.*/ + /*if(!axutil_strcmp(handler_name, "SandeshaGlobalInHandler") || !axutil_strcmp( + handler_name, "SandeshaInHandler")) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "dam_handler_name %s. dam_phase_name %s", handler_name, phase->name); + if(!axutil_strcmp(handler_name, "SandeshaGlobalInHandler")) + { + status = sandesha2_global_in_handler_invoke(phase->first_handler, env, msg_ctx); + } + if(!axutil_strcmp(handler_name, "SandeshaInHandler")) + { + status = sandesha2_in_handler_invoke(phase->first_handler, env, msg_ctx); + } + } + else*/ + status = axis2_handler_invoke(handler, env, msg_ctx); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler %s invoke failed within phase %s", handler_name, phase->name); + return status; + } + /* index increment should be done after the invoke function. If the invocation + failed this handler is taken care of and no need to revoke again */ + index++; + axis2_msg_ctx_set_current_handler_index(msg_ctx, env, index); + } + } + } + + /* If phase last handler is there invoke it here */ + if(phase->last_handler) + { + if(axis2_msg_ctx_is_paused(msg_ctx, env)) + { + AXIS2_LOG_INFO(env->log, "Message context is paused in the phase %s", phase->name); + return AXIS2_SUCCESS; + } + else + { + const axis2_char_t *handler_name = axutil_string_get_buffer(axis2_handler_get_name( + phase->last_handler, env), env); + AXIS2_LOG_INFO(env->log, "Invoke the last handler %s within the phase %s", + handler_name, phase->name); + + status = axis2_handler_invoke(phase->last_handler, env, msg_ctx); + if(!status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler %s invoke failed within phase %s", handler_name, phase->name); + return status; + } + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_invoke"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_phase_get_name( + const axis2_phase_t * phase, + const axutil_env_t * env) +{ + return phase->name; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_phase_get_handler_count( + const axis2_phase_t * phase, + const axutil_env_t * env) +{ + return axutil_array_list_size(phase->handlers, env); +} + +AXIS2_EXTERN int AXIS2_CALL +_axis2_phase_get_before_after( + axis2_handler_t * handler, + const axutil_env_t * env) +{ + const axis2_char_t *before = NULL, *after = NULL; + axis2_handler_desc_t *handler_desc = NULL; + axis2_phase_rule_t *rules = NULL; + const axis2_char_t *name = axutil_string_get_buffer(axis2_handler_get_name(handler, env), env); + + handler_desc = axis2_handler_get_handler_desc(handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set for the Handler %s", name); + return AXIS2_FAILURE; + } + + rules = axis2_handler_desc_get_rules(handler_desc, env); + if(!rules) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler rules are not set for the Handler Description %s", name); + return AXIS2_FAILURE; + } + + before = axis2_phase_rule_get_before(rules, env); + after = axis2_phase_rule_get_after(rules, env); + + if(before && after) + { + if(!axutil_strcmp(before, after)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BEFORE_AFTER_HANDLERS_SAME, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Both before and after handlers cannot be the same"); + return AXIS2_FAILURE; + } + return AXIS2_PHASE_BOTH_BEFORE_AFTER; + } + else if(before) + { + return AXIS2_PHASE_BEFORE; + } + else if(after) + { + return AXIS2_PHASE_AFTER; + } + else + { + return AXIS2_PHASE_ANYWHERE; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_set_first_handler( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + const axis2_char_t *handler_name = axutil_string_get_buffer( + axis2_handler_get_name(handler, env), env); + const axis2_char_t *phase_name = axis2_phase_get_name(phase, env); + if(phase->first_handler_set) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PHASE_FIRST_HANDLER_ALREADY_SET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "First handler of phase already set, so cannot set handler %s " + "in to the phase %s as first handler", handler_name, phase_name); + return AXIS2_FAILURE; + } + else + { + if(_axis2_phase_get_before_after(handler, env) != AXIS2_PHASE_ANYWHERE) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_PHASE_FIRST_HANDLER, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid first handler %s set for the Phase %s", handler_name, phase_name); + return AXIS2_FAILURE; + } + phase->first_handler = handler; + phase->first_handler_set = AXIS2_TRUE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_set_last_handler( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + const axis2_char_t *handler_name = axutil_string_get_buffer( + axis2_handler_get_name(handler, env), env); + const axis2_char_t *phase_name = axis2_phase_get_name(phase, env); + if(phase->last_handler_set) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PHASE_LAST_HANDLER_ALREADY_SET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Last handler of phase already set, so cannot set handler %s " + "in to the phase %s as last handler", handler_name, phase_name); + return AXIS2_FAILURE; + } + else + { + if(_axis2_phase_get_before_after(handler, env) != AXIS2_PHASE_ANYWHERE) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_PHASE_LAST_HANDLER, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid last handler %s set for the Phase %s", + handler_name, phase_name); + return AXIS2_FAILURE; + } + phase->last_handler = handler; + phase->last_handler_set = AXIS2_TRUE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_add_handler_desc( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_desc_t * handler_desc) +{ + axis2_phase_rule_t *rules = NULL; + axis2_handler_t *handler = NULL; + axis2_status_t status = AXIS2_SUCCESS; + axis2_bool_t first = AXIS2_FALSE, last = AXIS2_FALSE; + const axis2_char_t *handler_desc_name = axutil_string_get_buffer(axis2_handler_desc_get_name( + handler_desc, env), env); + if(phase->is_one_handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_PHASE_ADD_HANDLER_INVALID, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Only one handler allowed for phase %s, adding handler %s is not " + "allowed", phase->name, handler_desc_name); + return AXIS2_FAILURE; + } + else + { + rules = axis2_handler_desc_get_rules(handler_desc, env); + if(!rules) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler rules are not set for the Hanlder Description %s " + "within phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + first = axis2_phase_rule_is_first(rules, env); + last = axis2_phase_rule_is_last(rules, env); + + if(first && last) + { + if(axutil_array_list_size(phase->handlers, env) > 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_RULES, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid handler rules, so unable to add handler %s to " + "phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + handler = axis2_handler_desc_get_handler(handler_desc, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler is not set for the Handler Description %s " + "within phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + /*status = axutil_array_list_add(phase->handlers, env, handler); */ + status = axis2_phase_add_unique(env, phase->handlers, handler); + if(status) + phase->is_one_handler = AXIS2_TRUE; + return status; + } + else if(first) + { + handler = axis2_handler_desc_get_handler(handler_desc, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler is not set for the Handler Description %s " + "within phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + return axis2_phase_set_first_handler(phase, env, handler); + } + else if(last) + { + handler = axis2_handler_desc_get_handler(handler_desc, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler is not set for the Handler Description %s " + "within phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + return axis2_phase_set_last_handler(phase, env, handler); + } + else + { + handler = axis2_handler_desc_get_handler(handler_desc, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler is not set for the Handler Description %s " + "within phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + return axis2_phase_insert_handler_desc(phase, env, handler_desc); + } + } +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +_axis2_phase_is_valid_before( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + axis2_phase_rule_t *rules = NULL; + axis2_handler_desc_t *handler_desc = NULL; + const axis2_char_t *first_handler_name = NULL, *before = NULL; + + if(phase->first_handler) + { + handler_desc = axis2_handler_get_handler_desc(phase->first_handler, env); + if(!handler_desc) + return AXIS2_TRUE; + + first_handler_name = axutil_string_get_buffer( + axis2_handler_desc_get_name(handler_desc, env), env); + + if(!first_handler_name) + return AXIS2_TRUE; + + handler_desc = axis2_handler_get_handler_desc(handler, env); + if(!handler_desc) + return AXIS2_TRUE; + + rules = axis2_handler_desc_get_rules(handler_desc, env); + if(!rules) + return AXIS2_TRUE; + + before = axis2_phase_rule_get_before(rules, env); + if(!before) + return AXIS2_TRUE; + + if(!axutil_strcmp(first_handler_name, before)) + return AXIS2_FALSE; + else + return AXIS2_TRUE; + + } + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +_axis2_phase_is_valid_after( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + axis2_phase_rule_t *rules = NULL; + axis2_handler_desc_t *handler_desc = NULL; + const axis2_char_t *last_handler_name = NULL, *after = NULL; + + if(phase->last_handler) + { + handler_desc = axis2_handler_get_handler_desc(phase->last_handler, env); + if(!handler_desc) + return AXIS2_TRUE; + + last_handler_name = axutil_string_get_buffer( + axis2_handler_desc_get_name(handler_desc, env), env); + + if(!last_handler_name) + return AXIS2_TRUE; + + handler_desc = axis2_handler_get_handler_desc(handler, env); + if(!handler_desc) + return AXIS2_TRUE; + + rules = axis2_handler_desc_get_rules(handler_desc, env); + if(!rules) + return AXIS2_TRUE; + + after = axis2_phase_rule_get_after(rules, env); + if(!after) + return AXIS2_TRUE; + + if(!axutil_strcmp(last_handler_name, after)) + return AXIS2_FALSE; + else + return AXIS2_TRUE; + + } + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_insert_before( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + axis2_phase_rule_t *rules = NULL; + axis2_handler_desc_t *handler_desc = NULL; + const axis2_char_t *handler_name = NULL, *before = NULL; + int i = 0; + int size = 0; + const axis2_char_t *name = axutil_string_get_buffer(axis2_handler_get_name(handler, env), env); + const axis2_char_t *handler_desc_name = NULL; + + handler_desc = axis2_handler_get_handler_desc(handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set in the handler %s within phase %s", name, phase->name); + return AXIS2_FAILURE; + } + handler_desc_name = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, env), + env); + + rules = axis2_handler_desc_get_rules(handler_desc, env); + if(!rules) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler rules are not set in the handler description %s within " + "phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + before = axis2_phase_rule_get_before(rules, env); + if(!before) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Rule `before` is not set in the handler rules for handler %s " + "within phase %s", name, phase->name); + return AXIS2_FAILURE; + } + + if(phase->last_handler) + { + const axis2_char_t *last_handler_name = axutil_string_get_buffer(axis2_handler_get_name( + phase->last_handler, env), env); + handler_desc = axis2_handler_get_handler_desc(phase->last_handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set in the last handler %s of " + "phase %s", last_handler_name, phase->name); + return AXIS2_FAILURE; + } + + handler_name + = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, env), env); + if(!handler_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler name is not set in the handler description for " + "last handler %s within phase %s", last_handler_name, phase->name); + return AXIS2_FAILURE; + } + + if(!axutil_strcmp(before, handler_name)) + { + /*return axutil_array_list_add(phase->handlers, env, handler); */ + return axis2_phase_add_unique(env, phase->handlers, handler); + } + } + + size = axutil_array_list_size(phase->handlers, env); + + for(i = 0; i < size; i++) + { + axis2_handler_t *temp_handler = (axis2_handler_t *)axutil_array_list_get(phase->handlers, + env, i); + if(temp_handler) + { + const axis2_char_t *temp_handler_name = axutil_string_get_buffer( + axis2_handler_get_name(temp_handler, env), env); + handler_desc = axis2_handler_get_handler_desc(temp_handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler Description is not set for the Handler %s " + "within phase %s", temp_handler_name, phase->name); + return AXIS2_FAILURE; + } + + handler_name = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, env), + env); + if(!handler_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler name is not set in the handler description for " + "handler %s within phase %s", temp_handler_name, phase->name); + return AXIS2_FAILURE; + } + + if(!axutil_strcmp(before, handler_name)) + { + return axutil_array_list_add_at(phase->handlers, env, i, handler); + } + } + } + /* add as the last handler */ + /* return axutil_array_list_add(phase->handlers, env, handler); */ + return axis2_phase_add_unique(env, phase->handlers, handler); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_insert_after( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + axis2_phase_rule_t *rules = NULL; + axis2_handler_desc_t *handler_desc = NULL; + const axis2_char_t *handler_name = NULL; + const axis2_char_t *after = NULL; + int i = 0; + int size = 0; + const axis2_char_t *name = axutil_string_get_buffer(axis2_handler_get_name(handler, env), env); + const axis2_char_t *handler_desc_name = NULL; + + handler_desc = axis2_handler_get_handler_desc(handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set in the handler %s within phase %s", name, phase->name); + return AXIS2_FAILURE; + } + handler_desc_name = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, env), + env); + rules = axis2_handler_desc_get_rules(handler_desc, env); + if(!rules) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler rules are not set in the handler description %s within " + "phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + after = axis2_phase_rule_get_after(rules, env); + if(!after) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Rule `after` is not set in the handler rules for handler desc " + "%s within phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + if(phase->first_handler) + { + const axis2_char_t *first_handler_name = axutil_string_get_buffer(axis2_handler_get_name( + phase->first_handler, env), env); + handler_desc = axis2_handler_get_handler_desc(phase->first_handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set in the first handler %s " + "within phase %s", first_handler_name, phase->name); + return AXIS2_FAILURE; + } + + handler_name + = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, env), env); + if(!handler_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler name is not set in the handler description for " + "handler %s within phase %s", name, phase->name); + return AXIS2_FAILURE; + } + + if(!axutil_strcmp(after, handler_name)) + { + return axutil_array_list_add_at(phase->handlers, env, 0, handler); + } + } + + size = axutil_array_list_size(phase->handlers, env); + + for(i = 0; i < size; i++) + { + axis2_handler_t *temp_handler = (axis2_handler_t *)axutil_array_list_get(phase->handlers, + env, i); + if(temp_handler) + { + const axis2_char_t *temp_handler_name = axutil_string_get_buffer( + axis2_handler_get_name(temp_handler, env), env); + handler_desc = axis2_handler_get_handler_desc(temp_handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set in the handler %s within" + " phase %s", temp_handler_name, phase->name); + return AXIS2_FAILURE; + } + + handler_name = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, env), + env); + if(!handler_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler name is not set in the handler description %s " + "within phase %s", temp_handler_name, phase->name); + return AXIS2_FAILURE; + } + + if(!axutil_strcmp(after, handler_name)) + { + if(i == (size - 1)) + { + return axis2_phase_add_unique(env, phase->handlers, handler); + } + else + return axutil_array_list_add_at(phase->handlers, env, i + 1, handler); + } + } + } + + if(size > 0) + return axutil_array_list_add_at(phase->handlers, env, 0, handler); + else + { + return axis2_phase_add_unique(env, phase->handlers, handler); + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_insert_before_and_after( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_t * handler) +{ + int before = -1; + int after = -1; + axis2_phase_rule_t *rules = NULL; + axis2_handler_desc_t *handler_desc = NULL; + const axis2_char_t *before_handler_name = NULL, *after_handler_name = NULL, *after_name = NULL, + *before_name = NULL, *handler_name = NULL; + int i = 0; + int size = 0; + const axis2_char_t *name = axutil_string_get_buffer(axis2_handler_get_name(handler, env), env); + const axis2_char_t *handler_desc_name = NULL; + + handler_desc = axis2_handler_get_handler_desc(handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set in the handler %s within phase %s", name, phase->name); + return AXIS2_FAILURE; + } + handler_desc_name = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, env), + env); + + rules = axis2_handler_desc_get_rules(handler_desc, env); + if(!rules) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler rules are not set in the handler description %s within " + "phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + before_name = axis2_phase_rule_get_before(rules, env); + if(!before_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Rule `before` is not set in the handler rules for handler desc " + " %s within phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + after_name = axis2_phase_rule_get_after(rules, env); + if(!after_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Rule `after` is not set in the handler rules for handler desc " + "%s within phase %s", handler_desc_name, phase->name); + return AXIS2_FAILURE; + } + + if(phase->first_handler) + { + const axis2_char_t *first_handler_name = axutil_string_get_buffer(axis2_handler_get_name( + phase->first_handler, env), env); + handler_desc = axis2_handler_get_handler_desc(phase->first_handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set in the first handler %s " + "within phase %s", first_handler_name, phase->name); + return AXIS2_FAILURE; + } + + before_handler_name = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, + env), env); + if(!before_handler_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler name is not set in the handler description for the " + "first handler %s within phase %s", first_handler_name, phase->name); + return AXIS2_FAILURE; + } + } + + if(phase->last_handler) + { + const axis2_char_t *last_handler_name = axutil_string_get_buffer(axis2_handler_get_name( + phase->last_handler, env), env); + handler_desc = axis2_handler_get_handler_desc(phase->last_handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description is not set in the last handler %s " + "within phase %s", last_handler_name, phase->name); + return AXIS2_FAILURE; + } + + after_handler_name = axutil_string_get_buffer( + axis2_handler_desc_get_name(handler_desc, env), env); + if(!after_handler_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler name is not set in the handler description for the " + "last handler %s within phase %s", last_handler_name, phase->name); + return AXIS2_FAILURE; + } + } + + if(before_handler_name && after_handler_name) + { + if(!axutil_strcmp(before_handler_name, before_name) && !axutil_strcmp(after_handler_name, + after_name)) + { + return axis2_phase_add_unique(env, phase->handlers, handler); + } + } + + if(after_handler_name) + { + if(!axutil_strcmp(after_handler_name, after_name)) + after = 0; + } + + size = axutil_array_list_size(phase->handlers, env); + + if(after_handler_name) + { + if(!axutil_strcmp(before_handler_name, before_name)) + before = size; + } + + for(i = 0; i < size; i++) + { + axis2_handler_t *temp_handler = (axis2_handler_t *)axutil_array_list_get(phase->handlers, + env, i); + if(temp_handler) + { + const axis2_char_t *temp_handler_name = axutil_string_get_buffer( + axis2_handler_get_name(temp_handler, env), env); + handler_desc = axis2_handler_get_handler_desc(temp_handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler Description is not set for the Handler %s " + "within phase %s", temp_handler_name, phase->name); + return AXIS2_FAILURE; + } + + handler_name = axutil_string_get_buffer(axis2_handler_desc_get_name(handler_desc, env), + env); + if(!handler_name) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler name is not set in the handler Description for " + "handler %s within phase %s", temp_handler_name, phase->name); + return AXIS2_FAILURE; + } + + if(!axutil_strcmp(handler_name, after_name)) + after = i; + if(!axutil_strcmp(handler_name, before_name)) + before = i; + } + + if((after >= 0) && (before >= 0)) + { + /*both the before and after indexes have been found */ + if(after > before) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Both the before and after indexes have been found and " + "`after` comes before `before` which is wrong within " + "phase %s", phase->name); + return AXIS2_FAILURE; + } + else + { + if(after + 1 < size) + { + return axutil_array_list_add_at(phase->handlers, env, after + 1, handler); + } + else + { + return axis2_phase_add_unique(env, phase->handlers, handler); + } + } + } + } + return axis2_phase_add_unique(env, phase->handlers, handler); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_insert_handler_desc( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_desc_t * handler_desc) +{ + int type = 0; + axis2_handler_t *handler = NULL; + axis2_status_t status = AXIS2_FAILURE; + const axis2_char_t *handler_desc_name = axutil_string_get_buffer(axis2_handler_desc_get_name( + handler_desc, env), env); + const axis2_char_t *handler_name = NULL; + handler = axis2_handler_desc_get_handler(handler_desc, env); + + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Handler is not set in the handler description %s", + handler_desc_name); + return AXIS2_FAILURE; + } + handler_name = axutil_string_get_buffer(axis2_handler_get_name(handler, env), env); + + if(!_axis2_phase_is_valid_after(phase, env, handler)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid Handler State for the handler %s within the phase %s", handler_name, + phase->name); + return AXIS2_FAILURE; + } + + if(!_axis2_phase_is_valid_before(phase, env, handler)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid Handler State for the handler %s within the phase %s", handler_name, + phase->name); + return AXIS2_FAILURE; + } + + type = _axis2_phase_get_before_after(handler, env); + + switch(type) + { + case 0: /*AXIS2_BOTH_BEFORE_AFTER: */ + status = axis2_phase_insert_before_and_after(phase, env, handler); + break; + case 1: /*AXIS2_BEFORE: */ + status = axis2_phase_insert_before(phase, env, handler); + break; + case 2: /*AXIS2_AFTER: */ + status = axis2_phase_insert_after(phase, env, handler); + break; + case 3: /*AXIS2_ANYWHERE: */ + status = axis2_phase_add_unique(env, phase->handlers, handler); + break; + default: + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler description %s insertion failed within the phase %s", handler_desc_name, + phase->name); + status = AXIS2_FAILURE; + break; + } + return status; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_phase_get_all_handlers( + const axis2_phase_t * phase, + const axutil_env_t * env) +{ + return phase->handlers; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_invoke_start_from_handler( + axis2_phase_t * phase, + const axutil_env_t * env, + const int paused_handler_index, + axis2_msg_ctx_t * msg_ctx) +{ + int i = 0, size = 0; + axis2_status_t status = AXIS2_SUCCESS; + + axis2_msg_ctx_set_paused_phase_name(msg_ctx, env, phase->name); + + size = axutil_array_list_size(phase->handlers, env); + for(i = paused_handler_index; i < size; i++) + { + axis2_handler_t *handler = + (axis2_handler_t *)axutil_array_list_get(phase->handlers, env, i); + if(handler) + { + const axis2_char_t *handler_name = axutil_string_get_buffer(axis2_handler_get_name( + handler, env), env); + int index = -1; + + axis2_handler_desc_t *handler_desc = axis2_handler_get_handler_desc(handler, env); + if(!handler_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid Handler State for the handler %s within phase %s", handler_name, + phase->name); + return AXIS2_FAILURE; + } + + axis2_handler_invoke(handler, env, msg_ctx); + index = axis2_msg_ctx_get_current_handler_index(msg_ctx, env); + axis2_msg_ctx_set_current_handler_index(msg_ctx, env, (index + 1)); + } + } + return status; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_phase_free( + axis2_phase_t * phase, + const axutil_env_t * env) +{ + if(--(phase->ref) > 0) + { + return; + } + + if(phase->name) + { + AXIS2_FREE(env->allocator, phase->name); + } + + if(phase->handlers) + { + axutil_array_list_free(phase->handlers, env); + } + AXIS2_FREE(env->allocator, phase); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_remove_handler_desc( + axis2_phase_t * phase, + const axutil_env_t * env, + axis2_handler_desc_t * handler_desc) +{ + axis2_handler_t *handler; + const axis2_char_t *handler_desc_name = axutil_string_get_buffer(axis2_handler_desc_get_name( + handler_desc, env), env); + handler = axis2_handler_desc_get_handler(handler_desc, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler is not set in the Handler Description %s within phase %s", handler_desc_name, + phase->name); + return AXIS2_FAILURE; + } + return axis2_phase_remove_unique(env, phase->handlers, handler); +} + +static axis2_status_t +axis2_phase_add_unique( + const axutil_env_t * env, + axutil_array_list_t * list, + axis2_handler_t * handler) +{ + int i = 0, size = 0; + axis2_bool_t add_handler = AXIS2_TRUE; + const axutil_string_t *handler_name = NULL; + + handler_name = axis2_handler_get_name(handler, env); + size = axutil_array_list_size(list, env); + for(i = 0; i < size; i++) + { + axis2_handler_t *obj = NULL; + const axutil_string_t *obj_name = NULL; + + obj = (axis2_handler_t *)axutil_array_list_get(list, env, i); + obj_name = axis2_handler_get_name(obj, env); + if(obj == handler) + { + add_handler = AXIS2_FALSE; + break; + } + else if(!axutil_strcmp(axutil_string_get_buffer(handler_name, env), + axutil_string_get_buffer(obj_name, env))) + { + add_handler = AXIS2_FALSE; + break; + } + } + if(add_handler) + axutil_array_list_add(list, env, handler); + return AXIS2_SUCCESS; +} + +static axis2_status_t +axis2_phase_remove_unique( + const axutil_env_t * env, + axutil_array_list_t * list, + axis2_handler_t * handler) +{ + int i = 0, size = 0; + axis2_bool_t remove_handler = AXIS2_FALSE; + const axutil_string_t *handler_name = NULL; + + handler_name = axis2_handler_get_name(handler, env); + size = axutil_array_list_size(list, env); + for(i = 0; i < size; i++) + { + axis2_handler_t *obj = NULL; + const axutil_string_t *obj_name = NULL; + + obj = (axis2_handler_t *)axutil_array_list_get(list, env, i); + obj_name = axis2_handler_get_name(obj, env); + if(obj == handler) + { + remove_handler = AXIS2_TRUE; + break; + } + else if(!axutil_strcmp(axutil_string_get_buffer(handler_name, env), + axutil_string_get_buffer(obj_name, env))) + { + remove_handler = AXIS2_TRUE; + break; + } + } + if(remove_handler) + axutil_array_list_remove(list, env, i); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_increment_ref( + axis2_phase_t * phase, + const axutil_env_t * env) +{ + phase->ref++; + return AXIS2_SUCCESS; +} + diff --git a/src/core/engine/req_uri_disp.c b/src/core/engine/req_uri_disp.c new file mode 100644 index 0000000..dbc89b7 --- /dev/null +++ b/src/core/engine/req_uri_disp.c @@ -0,0 +1,206 @@ +/* + * 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_disp.h> +#include <axis2_handler_desc.h> +#include <axutil_string.h> +#include <axis2_relates_to.h> +#include <axis2_svc.h> +#include <axis2_const.h> +#include <axis2_conf_ctx.h> +#include <axis2_addr.h> +#include <axutil_utils.h> + +const axis2_char_t *AXIS2_REQ_URI_DISP_NAME = "request_uri_based_dispatcher"; + +axis2_status_t AXIS2_CALL +axis2_req_uri_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx *msg_ctx); + +axis2_svc_t *AXIS2_CALL axis2_req_uri_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env); + +axis2_op_t *AXIS2_CALL axis2_req_uri_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc); + +AXIS2_EXTERN axis2_disp_t *AXIS2_CALL +axis2_req_uri_disp_create( + const axutil_env_t * env) +{ + axis2_disp_t *disp = NULL; + axis2_handler_t *handler = NULL; + axutil_string_t *name = NULL; + + name = axutil_string_create_const(env, (axis2_char_t **)&AXIS2_REQ_URI_DISP_NAME); + + disp = axis2_disp_create(env, name); + if(!disp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + handler = axis2_disp_get_base(disp, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + return NULL; + } + + axis2_handler_set_invoke(handler, env, axis2_req_uri_disp_invoke); + + axutil_string_free(name, env); + + return disp; +} + +axis2_svc_t *AXIS2_CALL +axis2_req_uri_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axis2_endpoint_ref_t *endpoint_ref = NULL; + axis2_svc_t *svc = NULL; + + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + endpoint_ref = axis2_msg_ctx_get_to(msg_ctx, env); + + if(endpoint_ref) + { + const axis2_char_t *address = NULL; + + address = axis2_endpoint_ref_get_address(endpoint_ref, env); + if(address) + { + axis2_char_t **url_tokens = NULL; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Checking for service using target endpoint address : %s", address); + + url_tokens = axutil_parse_request_url_for_svc_and_op(env, address); + + if(url_tokens) + { + if(url_tokens[0]) + { + axis2_conf_ctx_t *conf_ctx = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + axis2_conf_t *conf = NULL; + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + svc = axis2_conf_get_svc(conf, env, url_tokens[0]); + if(svc) + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Service found using target endpoint address"); + } + } + AXIS2_FREE(env->allocator, url_tokens[0]); + + if(url_tokens[1]) + { + AXIS2_FREE(env->allocator, url_tokens[1]); + } + + } + AXIS2_FREE(env->allocator, url_tokens); + url_tokens = NULL; + } + } + } + + return svc; +} + +axis2_op_t *AXIS2_CALL +axis2_req_uri_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + axis2_endpoint_ref_t *endpoint_ref = NULL; + axis2_op_t *op = NULL; + + AXIS2_PARAM_CHECK(env->error, svc, NULL); + + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + endpoint_ref = axis2_msg_ctx_get_to(msg_ctx, env); + + if(endpoint_ref) + { + const axis2_char_t *address = NULL; + + address = axis2_endpoint_ref_get_address(endpoint_ref, env); + if(address) + { + axis2_char_t **url_tokens = NULL; + + url_tokens = axutil_parse_request_url_for_svc_and_op(env, address); + + if(url_tokens) + { + if(url_tokens[1]) + { + axutil_qname_t *op_qname = NULL; + AXIS2_LOG_DEBUG( + env->log, + AXIS2_LOG_SI, + "Checking for operation using \ + target endpoint uri fragment : %s", + url_tokens[1]); + op_qname = axutil_qname_create(env, url_tokens[1], NULL, NULL); + op = axis2_svc_get_op_with_name(svc, env, axutil_qname_get_localpart(op_qname, + env)); + axutil_qname_free(op_qname, env); + if(op) + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Operation found using target endpoint uri fragment"); + } + if(url_tokens[0]) + AXIS2_FREE(env->allocator, url_tokens[0]); + if(url_tokens[1]) + AXIS2_FREE(env->allocator, url_tokens[1]); + AXIS2_FREE(env->allocator, url_tokens); + } + } + } + + return op; +} + +axis2_status_t AXIS2_CALL +axis2_req_uri_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + axis2_msg_ctx_set_find_svc(msg_ctx, env, axis2_req_uri_disp_find_svc); + axis2_msg_ctx_set_find_op(msg_ctx, env, axis2_req_uri_disp_find_op); + return axis2_disp_find_svc_and_op(handler, env, msg_ctx); +} + diff --git a/src/core/engine/rest_disp.c b/src/core/engine/rest_disp.c new file mode 100644 index 0000000..4782568 --- /dev/null +++ b/src/core/engine/rest_disp.c @@ -0,0 +1,350 @@ +/* + * 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_disp.h> +#include <axis2_handler_desc.h> +#include <axutil_string.h> +#include <axis2_relates_to.h> +#include <axis2_svc.h> +#include <axis2_const.h> +#include <axis2_conf_ctx.h> +#include <axis2_addr.h> +#include <axutil_utils.h> +#include <axiom_soap_builder.h> +#include <axiom_soap_body.h> +#include <axiom_soap_const.h> +#include <axis2_http_transport.h> +#include <axis2_core_utils.h> + + +const axis2_char_t *AXIS2_REST_DISP_NAME = "rest_dispatcher"; + +axis2_status_t AXIS2_CALL +axis2_rest_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx *msg_ctx); + +axis2_svc_t *AXIS2_CALL axis2_rest_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env); + +axis2_op_t *AXIS2_CALL axis2_rest_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc); + +axis2_op_t *AXIS2_CALL +axis2_rest_disp_get_rest_op_with_method_and_location( + const axis2_svc_t * svc, + const axutil_env_t * env, + const axis2_char_t * method, + const axis2_char_t * location, + int * param_count, + axis2_char_t **** params); + +AXIS2_EXTERN axis2_disp_t *AXIS2_CALL +axis2_rest_disp_create( + const axutil_env_t * env) +{ + axis2_disp_t *disp = NULL; + axis2_handler_t *handler = NULL; + axutil_string_t *name = NULL; + + name = axutil_string_create_const(env, (axis2_char_t **)&AXIS2_REST_DISP_NAME); + + disp = axis2_disp_create(env, name); + if(!disp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + handler = axis2_disp_get_base(disp, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + return NULL; + } + + axis2_handler_set_invoke(handler, env, axis2_rest_disp_invoke); + + axutil_string_free(name, env); + + return disp; +} + +axis2_svc_t *AXIS2_CALL +axis2_rest_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axis2_endpoint_ref_t *endpoint_ref = NULL; + axis2_svc_t *svc = NULL; + + if(!axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + endpoint_ref = axis2_msg_ctx_get_to(msg_ctx, env); + + if(endpoint_ref) + { + const axis2_char_t *address = NULL; + + address = axis2_endpoint_ref_get_address(endpoint_ref, env); + if(address) + { + axis2_char_t **url_tokens = NULL; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Checking for service using target endpoint address : %s", address); + + url_tokens = axutil_parse_request_url_for_svc_and_op(env, address); + + if(url_tokens) + { + if(url_tokens[0]) + { + axis2_conf_ctx_t *conf_ctx = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + axis2_conf_t *conf = NULL; + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + svc = axis2_conf_get_svc(conf, env, url_tokens[0]); + if(svc) + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Service found using target endpoint address"); + } + } + AXIS2_FREE(env->allocator, url_tokens[0]); + + if(url_tokens[1]) + { + AXIS2_FREE(env->allocator, url_tokens[1]); + } + + } + AXIS2_FREE(env->allocator, url_tokens); + url_tokens = NULL; + } + } + } + + return svc; +} + +axis2_op_t *AXIS2_CALL +axis2_rest_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + axis2_endpoint_ref_t *endpoint_ref = NULL; + axis2_op_t *op = NULL; + axiom_soap_envelope_t *soap_env = NULL; + axiom_soap_body_t *soap_body = NULL; + axiom_element_t *body_child = NULL; + axiom_node_t *body_child_node = NULL; + axiom_node_t *body_element_node = NULL; + axis2_bool_t soap_env_exists = AXIS2_TRUE; + int i = 0; + + axutil_array_list_t *param_keys = NULL; + axutil_array_list_t *param_values = NULL; + + AXIS2_PARAM_CHECK(env->error, svc, NULL); + + if(!axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + endpoint_ref = axis2_msg_ctx_get_to(msg_ctx, env); + + if(endpoint_ref) + { + const axis2_char_t *address = NULL; + + address = axis2_endpoint_ref_get_address(endpoint_ref, env); + if(address) + { + axis2_char_t **url_tokens = NULL; + + url_tokens = axutil_parse_request_url_for_svc_and_op(env, address); + + if(url_tokens) + { + if(url_tokens[0]) + { + axis2_char_t *location = NULL; + + location = strstr(address, url_tokens[0]); + if(location) + { + const axis2_char_t *method = NULL; + + location += strlen(url_tokens[0]); + param_keys = axutil_array_list_create(env, 10); + if(!param_keys) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create the live rest parameter maps"); + return NULL; + } + param_values = axutil_array_list_create(env, 10); + + if(!param_values) + { + axutil_array_list_free(param_keys, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create the live rest parameter maps"); + return NULL; + } + method = axis2_msg_ctx_get_rest_http_method(msg_ctx, env); + op = axis2_core_utils_get_rest_op_with_method_and_location(svc, env, + method, location, param_keys, param_values); + } + } + if(url_tokens[0]) + AXIS2_FREE(env->allocator, url_tokens[0]); + if(url_tokens[1]) + AXIS2_FREE(env->allocator, url_tokens[1]); + AXIS2_FREE(env->allocator, url_tokens); + } + } + } + + if(!op) + { + if(param_keys) + { + for(i = 0; i < axutil_array_list_size(param_keys, env); i++) + { + void *value = axutil_array_list_get(param_keys, env, i); + AXIS2_FREE(env->allocator, value); + } + axutil_array_list_free(param_keys, env); + } + if(param_values) + { + for(i = 0; i < axutil_array_list_size(param_values, env); i++) + { + void *value = axutil_array_list_get(param_values, env, i); + AXIS2_FREE(env->allocator, value); + } + axutil_array_list_free(param_values, env); + } + return NULL; + } + + soap_env = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + + if(!soap_env) + { + soap_env_exists = AXIS2_FALSE; + soap_env = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11); + } + if(soap_env) + { + soap_body = axiom_soap_envelope_get_body(soap_env, env); + } + if(!soap_body) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL, AXIS2_FAILURE); + + if(param_keys) + { + for(i = 0; i < axutil_array_list_size(param_keys, env); i++) + { + void *value = axutil_array_list_get(param_keys, env, i); + AXIS2_FREE(env->allocator, value); + } + axutil_array_list_free(param_keys, env); + } + if(param_values) + { + for(i = 0; i < axutil_array_list_size(param_values, env); i++) + { + void *value = axutil_array_list_get(param_values, env, i); + AXIS2_FREE(env->allocator, value); + } + axutil_array_list_free(param_values, env); + } + return NULL; + } + + body_element_node = axiom_soap_body_get_base_node(soap_body, env); + + if(body_element_node) + { + body_child_node = axiom_node_get_first_child(body_element_node, env); + } + + if(!body_child_node) + { + body_child = axiom_element_create_with_qname(env, NULL, axis2_op_get_qname(op, env), + &body_child_node); + axiom_soap_body_add_child(soap_body, env, body_child_node); + } + + if(param_keys && param_values) + { + for(i = 0; i < axutil_array_list_size(param_keys, env); i++) + { + axis2_char_t *param_key = NULL; + axis2_char_t *param_value = NULL; + + axiom_node_t *node = NULL; + axiom_element_t *element = NULL; + + param_key = axutil_array_list_get(param_keys, env, i); + param_value = axutil_array_list_get(param_values, env, i); + + element = axiom_element_create(env, NULL, param_key, NULL, &node); + axiom_element_set_text(element, env, param_value, node); + axiom_node_add_child(body_child_node, env, node); + + AXIS2_FREE(env->allocator, param_key); + AXIS2_FREE(env->allocator, param_value); + } + + axutil_array_list_free(param_keys, env); + axutil_array_list_free(param_values, env); + } + + if(!soap_env_exists) + { + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_env); + } + + return op; +} + +axis2_status_t AXIS2_CALL +axis2_rest_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + axis2_msg_ctx_set_find_svc(msg_ctx, env, axis2_rest_disp_find_svc); + axis2_msg_ctx_set_find_op(msg_ctx, env, axis2_rest_disp_find_op); + return axis2_disp_find_svc_and_op(handler, env, msg_ctx); +} + diff --git a/src/core/engine/soap_action_disp.c b/src/core/engine/soap_action_disp.c new file mode 100644 index 0000000..10d6fa4 --- /dev/null +++ b/src/core/engine/soap_action_disp.c @@ -0,0 +1,155 @@ +/* + * 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_disp.h> +#include <axis2_handler_desc.h> +#include <axutil_string.h> +#include <axis2_relates_to.h> +#include <axis2_svc.h> +#include <axis2_const.h> +#include <axis2_conf_ctx.h> +#include <axis2_addr.h> +#include <axutil_utils.h> + +const axis2_char_t *AXIS2_SOAP_ACTION_DISP_NAME = "soap_action_based_dispatcher"; + +axis2_status_t AXIS2_CALL +axis2_soap_action_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx *msg_ctx); + +axis2_svc_t *AXIS2_CALL axis2_soap_action_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env); + +axis2_op_t *AXIS2_CALL axis2_soap_action_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc); + +axis2_disp_t *AXIS2_CALL +axis2_soap_action_disp_create( + const axutil_env_t * env) +{ + axis2_disp_t *disp = NULL; + axis2_handler_t *handler = NULL; + axutil_string_t *name = NULL; + + name = axutil_string_create_const(env, (axis2_char_t **)&AXIS2_SOAP_ACTION_DISP_NAME); + + disp = axis2_disp_create(env, name); + if(!disp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + handler = axis2_disp_get_base(disp, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + return NULL; + } + + axis2_handler_set_invoke(handler, env, axis2_soap_action_disp_invoke); + + axutil_string_free(name, env); + + return disp; +} + +axis2_svc_t *AXIS2_CALL +axis2_soap_action_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Checking for service using SOAPAction is not implemented"); + return NULL; +} + +axis2_op_t *AXIS2_CALL +axis2_soap_action_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + const axis2_char_t *action = NULL; + axutil_qname_t *name = NULL; + axis2_op_t *op = NULL; + + AXIS2_PARAM_CHECK(env->error, svc, NULL); + + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + action = axutil_string_get_buffer(axis2_msg_ctx_get_soap_action(msg_ctx, env), env); + + if(action) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Checking for operation using SOAPAction : %s", + action); + + if(!op) + { + const axis2_char_t *op_name = NULL; + op_name = axutil_rindex(action, '/'); + + if(op_name) + { + op_name += 1; + } + else + { + op_name = action; + } + + if(op_name) + { + op = axis2_svc_get_op_with_name(svc, env, op_name); + } + } + + if(!op) + { + name = axutil_qname_create(env, action, NULL, NULL); + op = axis2_svc_get_op_with_qname(svc, env, name); + axutil_qname_free(name, env); + } + + if(op) + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Operation found using SOAPAction"); + } + return op; +} + +axis2_status_t AXIS2_CALL +axis2_soap_action_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + axis2_msg_ctx_set_find_svc(msg_ctx, env, axis2_soap_action_disp_find_svc); + axis2_msg_ctx_set_find_op(msg_ctx, env, axis2_soap_action_disp_find_op); + + return axis2_disp_find_svc_and_op(handler, env, msg_ctx); +} + diff --git a/src/core/engine/soap_body_disp.c b/src/core/engine/soap_body_disp.c new file mode 100644 index 0000000..702a988 --- /dev/null +++ b/src/core/engine/soap_body_disp.c @@ -0,0 +1,231 @@ +/* + * 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_disp.h> +#include <axis2_handler_desc.h> +#include <axutil_string.h> +#include <axis2_svc.h> +#include <axis2_const.h> +#include <axis2_conf_ctx.h> +#include <axutil_utils.h> +#include <axiom_soap_envelope.h> +#include <axiom_soap_body.h> + +const axis2_char_t *AXIS2_SOAP_MESSAGE_BODY_DISP_NAME = "soap_message_body_based_dispatcher"; + +axis2_status_t AXIS2_CALL +axis2_soap_body_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx *msg_ctx); + +axis2_svc_t *AXIS2_CALL axis2_soap_body_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env); + +axis2_op_t *AXIS2_CALL axis2_soap_body_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc); + +axis2_disp_t *AXIS2_CALL +axis2_soap_body_disp_create( + const axutil_env_t * env) +{ + axis2_disp_t *disp = NULL; + axis2_handler_t *handler = NULL; + axutil_string_t *name = NULL; + + name = axutil_string_create_const(env, (axis2_char_t **)&AXIS2_SOAP_MESSAGE_BODY_DISP_NAME); + + disp = axis2_disp_create(env, name); + if(!disp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + handler = axis2_disp_get_base(disp, env); + if(!handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_HANDLER_STATE, AXIS2_FAILURE); + return NULL; + } + + axis2_handler_set_invoke(handler, env, axis2_soap_body_disp_invoke); + + axutil_string_free(name, env); + + return disp; +} + +axis2_svc_t *AXIS2_CALL +axis2_soap_body_disp_find_svc( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axis2_svc_t *svc = NULL; + + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + if(soap_envelope) + { + axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + if(soap_body) + { + axiom_node_t *body_node = axiom_soap_body_get_base_node(soap_body, env); + if(body_node) + { + axiom_node_t *body_first_child_node = axiom_node_get_first_element(body_node, env); + + if(body_first_child_node) + { + if(axiom_node_get_node_type(body_first_child_node, env) == AXIOM_ELEMENT) + { + axiom_element_t *element = NULL; + element = (axiom_element_t *)axiom_node_get_data_element( + body_first_child_node, env); + if(element) + { + axiom_namespace_t *ns = axiom_element_get_namespace(element, env, + body_first_child_node); + if(ns) + { + axis2_char_t *uri = axiom_namespace_get_uri(ns, env); + if(uri) + { + axis2_char_t **url_tokens = NULL; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Checking for service " + "using SOAP message body's " + "first child's namespace " + "URI : %s", uri); + + url_tokens = axutil_parse_request_url_for_svc_and_op(env, uri); + + if(url_tokens) + { + if(url_tokens[0]) + { + axis2_conf_ctx_t *conf_ctx = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + axis2_conf_t *conf = NULL; + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + svc = axis2_conf_get_svc(conf, env, + url_tokens[0]); + if(svc) + AXIS2_LOG_DEBUG(env-> log, AXIS2_LOG_SI, + "Service found " + "using SOAP message" + "body's first " + "child's namespace URI"); + } + } + AXIS2_FREE(env->allocator, url_tokens[0]); + } + + AXIS2_FREE(env->allocator, url_tokens); + url_tokens = NULL; + } + } + } + } + } + } + } + } + } + + return svc; +} + +axis2_op_t *AXIS2_CALL +axis2_soap_body_disp_find_op( + axis2_msg_ctx_t * msg_ctx, + const axutil_env_t * env, + axis2_svc_t * svc) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axis2_op_t *op = NULL; + + AXIS2_PARAM_CHECK(env->error, svc, NULL); + + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + return NULL; + + soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + if(soap_envelope) + { + axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + if(soap_body) + { + axiom_node_t *body_node = axiom_soap_body_get_base_node(soap_body, env); + if(body_node) + { + axiom_node_t *body_first_child_node = axiom_node_get_first_element(body_node, env); + + if(body_first_child_node) + { + if(axiom_node_get_node_type(body_first_child_node, env) == AXIOM_ELEMENT) + { + axiom_element_t *element = NULL; + element = (axiom_element_t *)axiom_node_get_data_element( + body_first_child_node, env); + if(element) + { + axis2_char_t *element_name = axiom_element_get_localname(element, env); + if(element_name) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Checking for operation using SOAP message" + "body's first child's local name : %s", element_name); + + op = axis2_svc_get_op_with_name(svc, env, element_name); + + if(op) + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Operation found using SOAP message " + "body's first child's local name"); + + } + } + } + } + } + } + } + return op; +} + +axis2_status_t AXIS2_CALL +axis2_soap_body_disp_invoke( + axis2_handler_t * handler, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + axis2_msg_ctx_set_find_svc(msg_ctx, env, axis2_soap_body_disp_find_svc); + axis2_msg_ctx_set_find_op(msg_ctx, env, axis2_soap_body_disp_find_op); + return axis2_disp_find_svc_and_op(handler, env, msg_ctx); +} + diff --git a/src/core/phaseresolver/Makefile.am b/src/core/phaseresolver/Makefile.am new file mode 100644 index 0000000..62724f2 --- /dev/null +++ b/src/core/phaseresolver/Makefile.am @@ -0,0 +1,9 @@ +noinst_LTLIBRARIES = libaxis2_phaseresolver.la + +libaxis2_phaseresolver_la_SOURCES = phase_holder.c \ + phase_resolver.c + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/axiom/include \ + -I$(top_builddir)/util/include diff --git a/src/core/phaseresolver/phase_holder.c b/src/core/phaseresolver/phase_holder.c new file mode 100644 index 0000000..f371dd4 --- /dev/null +++ b/src/core/phaseresolver/phase_holder.c @@ -0,0 +1,243 @@ +/* + * 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_phase_holder.h> + +struct axis2_phase_holder +{ + axutil_array_list_t *phase_list; +}; + +AXIS2_EXTERN axis2_phase_holder_t *AXIS2_CALL +axis2_phase_holder_create( + const axutil_env_t * env) +{ + axis2_phase_holder_t *phase_holder = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + phase_holder = (axis2_phase_holder_t *)AXIS2_MALLOC(env-> allocator, + sizeof(axis2_phase_holder_t)); + + if(!phase_holder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + phase_holder->phase_list = NULL; + + return phase_holder; +} + +AXIS2_EXTERN axis2_phase_holder_t *AXIS2_CALL +axis2_phase_holder_create_with_phases( + const axutil_env_t * env, + axutil_array_list_t * phases) +{ + axis2_phase_holder_t *phase_holder = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + if(!phases) + { + return NULL; + } + + phase_holder = (axis2_phase_holder_t *)axis2_phase_holder_create(env); + phase_holder->phase_list = phases; + + return phase_holder; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_phase_holder_free( + axis2_phase_holder_t * phase_holder, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(phase_holder) + { + AXIS2_FREE(env->allocator, phase_holder); + } + + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_phase_holder_is_phase_exist( + axis2_phase_holder_t * phase_holder, + const axutil_env_t * env, + const axis2_char_t * phase_name) +{ + int size = 0; + int i = 0; + axis2_phase_t *phase = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, phase_name, AXIS2_FALSE); + + size = axutil_array_list_size(phase_holder->phase_list, env); + + for(i = 0; i < size; i++) + { + const axis2_char_t *phase_name_l = NULL; + + phase = (axis2_phase_t *)axutil_array_list_get(phase_holder-> phase_list, env, i); + phase_name_l = axis2_phase_get_name(phase, env); + if(0 == axutil_strcmp(phase_name_l, phase_name)) + { + return AXIS2_TRUE; + } + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_holder_add_handler( + axis2_phase_holder_t * phase_holder, + const axutil_env_t * env, + axis2_handler_desc_t * handler) +{ + const axis2_char_t *phase_name = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "axis2_phase_holder_add_handler start"); + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, handler, AXIS2_FAILURE); + + phase_name = axis2_phase_rule_get_name(axis2_handler_desc_get_rules(handler, env), env); + if(AXIS2_TRUE == axis2_phase_holder_is_phase_exist(phase_holder, env, phase_name)) + { + axis2_phase_t *phase = NULL; + + phase = axis2_phase_holder_get_phase(phase_holder, env, phase_name); + status = axis2_phase_add_handler_desc(phase, env, handler); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Add handler %s to phase %s", + axutil_string_get_buffer(axis2_handler_desc_get_name(handler, env), env), phase_name); + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_PHASE, AXIS2_FAILURE); + status = AXIS2_FAILURE; + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "axis2_phase_holder_add_handler end status = %s", + status ? "SUCCESS" : "FAILURE"); + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_holder_remove_handler( + axis2_phase_holder_t * phase_holder, + const axutil_env_t * env, + axis2_handler_desc_t * handler) +{ + const axis2_char_t *phase_name = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "axis2_phase_holder_remove_handler start"); + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, handler, AXIS2_FAILURE); + + phase_name = axis2_phase_rule_get_name(axis2_handler_desc_get_rules(handler, env), env); + if(AXIS2_TRUE == axis2_phase_holder_is_phase_exist(phase_holder, env, phase_name)) + { + axis2_phase_t *phase = NULL; + + phase = axis2_phase_holder_get_phase(phase_holder, env, phase_name); + status = axis2_phase_remove_handler_desc(phase, env, handler); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Remove handler %s from phase %s", + axutil_string_get_buffer(axis2_handler_desc_get_name(handler, env), env), phase_name); + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_PHASE, AXIS2_FAILURE); + status = AXIS2_FAILURE; + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "axis2_phase_holder_remove_handler end status = %s", + status ? "SUCCESS" : "FAILURE"); + return status; +} + +AXIS2_EXTERN axis2_phase_t *AXIS2_CALL +axis2_phase_holder_get_phase( + const axis2_phase_holder_t * phase_holder, + const axutil_env_t * env, + const axis2_char_t * phase_name) +{ + int size = 0; + int i = 0; + axis2_phase_t *phase = NULL; + + AXIS2_PARAM_CHECK(env->error, phase_name, NULL); + + size = axutil_array_list_size(phase_holder->phase_list, env); + + for(i = 0; i < size; i++) + { + const axis2_char_t *phase_name_l = NULL; + phase = (axis2_phase_t *)axutil_array_list_get(phase_holder-> phase_list, env, i); + phase_name_l = axis2_phase_get_name(phase, env); + if(0 == axutil_strcmp(phase_name_l, phase_name)) + { + return phase; + } + } + + return NULL; +} + +/* This function is deprecated */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_holder_build_transport_handler_chain( + axis2_phase_holder_t * phase_holder, + const axutil_env_t * env, + axis2_phase_t * phase, + axutil_array_list_t * handlers) +{ + axis2_handler_t *handler = NULL; + int size = 0; + int status = AXIS2_FAILURE; + int i = 0; + axis2_handler_desc_t *handler_desc = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, phase, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, handlers, AXIS2_FAILURE); + + size = axutil_array_list_size(handlers, env); + + for(i = 0; i < size; i++) + { + handler_desc = (axis2_handler_desc_t *)axutil_array_list_get(handlers, env, i); + status = axis2_handler_init(handler, env, handler_desc); + if(AXIS2_FAILURE == status) + { + return status; + } + + status = axis2_handler_desc_set_handler(handler_desc, env, handler); + if(AXIS2_FAILURE == status) + { + return status; + } + + status = axis2_phase_add_handler(phase, env, handler); + } + return status; +} diff --git a/src/core/phaseresolver/phase_resolver.c b/src/core/phaseresolver/phase_resolver.c new file mode 100644 index 0000000..c291456 --- /dev/null +++ b/src/core/phaseresolver/phase_resolver.c @@ -0,0 +1,2016 @@ +/* + * 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_phase_resolver.h> +#include <axutil_property.h> +#include <axis2_addr.h> +/* + * It is important to understand the following relationships between the + * functions defined here and else where. + * axis2_phase_resolver_engage_module_globally->axis2_svc_add_module_ops-> + * ->axis2_phase_resolver_build_execution_chains_for_module_op->axis2_phase_resolver_build_execution_chains_for_op + * and + * axis2_phase_resolver_engage_module_to_svc->axis2_svc_add_module_ops-> + * ->axis2_phase_resolver_build_execution_chains_for_module_op->axis2_phase_resolver_build_execution_chains_for_op + */ +struct axis2_phase_resolver +{ + + /** axis2 configuration */ + axis2_conf_t *axis2_config; + + /** service */ + axis2_svc_t *svc; +}; + +static axis2_status_t +axis2_phase_resolver_build_execution_chains_for_op( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + int type, + axis2_op_t * op); + +static axis2_status_t +axis2_phase_resolver_add_module_handlers_to_system_defined_phases( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_module_desc_t * module_desc); + +static axis2_status_t +axis2_phase_resolver_add_module_handlers_to_user_defined_phases( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + struct axis2_svc *svc, + struct axis2_module_desc *module_desc); + +/* Deprecated and no longer used */ +static axis2_status_t +axis2_phase_resolver_build_in_transport_chains( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_transport_in_desc_t * transport); + +/* Deprecated and no longer used */ +static axis2_status_t +axis2_phase_resolver_build_out_transport_chains( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_transport_out_desc_t * transport); + +static axis2_status_t +axis2_phase_resolver_add_to_handler_list( + const axutil_env_t * env, + axutil_array_list_t *handler_list, + axis2_op_t *op, + axis2_module_desc_t * module_desc, + int type); + +AXIS2_EXTERN axis2_phase_resolver_t *AXIS2_CALL +axis2_phase_resolver_create( + const axutil_env_t * env) +{ + axis2_phase_resolver_t *phase_resolver = NULL; + + phase_resolver = (axis2_phase_resolver_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_phase_resolver_t)); + + if(!phase_resolver) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory."); + return NULL; + } + + phase_resolver->axis2_config = NULL; + phase_resolver->svc = NULL; + + return phase_resolver; +} + +AXIS2_EXTERN axis2_phase_resolver_t *AXIS2_CALL +axis2_phase_resolver_create_with_config( + const axutil_env_t * env, + axis2_conf_t * axis2_config) +{ + axis2_phase_resolver_t *phase_resolver = NULL; + + AXIS2_PARAM_CHECK(env->error, axis2_config, NULL); + + phase_resolver = (axis2_phase_resolver_t *)axis2_phase_resolver_create(env); + + phase_resolver->axis2_config = axis2_config; + + return phase_resolver; +} + +AXIS2_EXTERN axis2_phase_resolver_t *AXIS2_CALL +axis2_phase_resolver_create_with_config_and_svc( + const axutil_env_t * env, + axis2_conf_t * axis2_config, + axis2_svc_t * svc) +{ + axis2_phase_resolver_t *phase_resolver = NULL; + + AXIS2_PARAM_CHECK(env->error, axis2_config, NULL); + + phase_resolver = (axis2_phase_resolver_t *)axis2_phase_resolver_create(env); + + if(!phase_resolver) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No Memory."); + return NULL; + } + phase_resolver->axis2_config = axis2_config; + + phase_resolver->svc = svc; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Service name is : %s", axis2_svc_get_name( + phase_resolver->svc, env)); + + return phase_resolver; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_phase_resolver_free( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env) +{ + if(phase_resolver) + { + AXIS2_FREE(env->allocator, phase_resolver); + } + + return; +} + +/** + * This is in general called to engage a module to the axis2 engine. In other words modules handlers + * are added into all global and operation specific phases appropriately. Where these handlers + * should go is determined by the module handler specific descriptions in module.xml file. Also + * module operations are added to service and built exeuction chains for those operations as well. + * First add all the handlers defined for system phases are added into system phases. Then module + * operations are added into each service. At the same time execution chains for these module + * operations are built as well. Then handlers defined for user phases are added into user defined + * pahses. + */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_resolver_engage_module_globally( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_module_desc_t * module_desc) +{ + axis2_status_t status = AXIS2_FAILURE; + axutil_qname_t *qname_addressing = NULL; + axutil_hash_t *svcs = NULL; + + const axutil_qname_t *mod_qname = NULL; + axis2_char_t *mod_name = NULL; + axutil_hash_t *all_ops = NULL; + axutil_hash_index_t *index_j = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_resolver_engage_module_globally"); + + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + + mod_qname = axis2_module_desc_get_qname(module_desc, env); + mod_name = axutil_qname_get_localpart(mod_qname, env); + + /* Add module handlers into global phases */ + status = axis2_phase_resolver_add_module_handlers_to_system_defined_phases(phase_resolver, env, + module_desc); + + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Engaging module %s to global chain failed", + mod_name); + return status; + } + + /* Module is engaged to all the services */ + svcs = axis2_conf_get_all_svcs(phase_resolver->axis2_config, env); + if(!svcs) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "There are no services in the axis2 configuration"); + return AXIS2_FAILURE; + } + + qname_addressing = axutil_qname_create(env, AXIS2_MODULE_ADDRESSING, NULL, NULL); + + for(index_j = axutil_hash_first(svcs, env); index_j; index_j = axutil_hash_next(env, index_j)) + { + axis2_svc_t *svc = NULL; + void *w = NULL; + axis2_svc_grp_t *parent = NULL; + const axis2_char_t *svc_name = NULL; + const axis2_char_t *svc_grp_name = NULL; + + axutil_hash_this(index_j, NULL, NULL, &w); + svc = (axis2_svc_t *)w; + svc_name = axis2_svc_get_name(svc, env); + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "svc name is:%s", svc_name); + + /* Module operations are added to service and built execution chains for operations. */ + status = axis2_svc_add_module_ops(svc, env, module_desc, phase_resolver->axis2_config); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding module operations for module %s to service %s failed", mod_name, svc_name); + axutil_qname_free(qname_addressing, env); + return status; + } + + /* Call this function to add module handlers into service operation phases */ + status = axis2_phase_resolver_add_module_handlers_to_user_defined_phases(phase_resolver, + env, svc, module_desc); + + if(AXIS2_SUCCESS != status) + { + axutil_qname_free(qname_addressing, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Engaging module %s to service %s failed", + mod_name, svc_name); + + return status; + } + + if(axutil_qname_equals(mod_qname, env, qname_addressing)) + { + /* If addressing module then all operations which are not module + * operations with a wsa mapping parameter is added to the + * service's wsa-mapping list*/ + all_ops = axis2_svc_get_all_ops(svc, env); + if(all_ops) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + for(hi = axutil_hash_first(all_ops, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + if(!axis2_op_is_from_module((axis2_op_t *)val, env)) + { + axis2_op_t *op_desc = NULL; + axutil_array_list_t *params = NULL; + int j = 0; + int sizej = 0; + + op_desc = (axis2_op_t *)val; + params = axis2_op_get_all_params(op_desc, env); + /* Adding wsa-mapping into service */ + sizej = axutil_array_list_size(params, env); + for(j = 0; j < sizej; j++) + { + axutil_param_t *param = NULL; + axis2_char_t *param_name = NULL; + + param = axutil_array_list_get(params, env, j); + param_name = axutil_param_get_name(param, env); + if(!axutil_strcmp(param_name, AXIS2_WSA_MAPPING)) + { + axis2_char_t *key = NULL; + key = (axis2_char_t *)axutil_param_get_value(param, env); + axis2_svc_add_mapping(svc, env, key, op_desc); + } + } + } + val = NULL; + } + } + } + } + + parent = axis2_svc_get_parent(svc, env); + if(parent) + { + axutil_array_list_t *modules = NULL; + int j = 0; + int sizej = 0; + axis2_bool_t add_to_group = AXIS2_TRUE; + svc_grp_name = axis2_svc_grp_get_name(parent, env); + + modules = axis2_svc_grp_get_all_module_qnames(parent, env); + sizej = axutil_array_list_size(modules, env); + for(j = 0; j < sizej; j++) + { + axutil_qname_t *module = NULL; + + module = (axutil_qname_t *)axutil_array_list_get(modules, env, j); + if(axutil_qname_equals(mod_qname, env, module)) + { + add_to_group = AXIS2_FALSE; + break; + } + } + + if(add_to_group) + { + status = axis2_svc_grp_add_module_qname(parent, env, mod_qname); + } + } + + if(AXIS2_SUCCESS != status) + { + axutil_qname_free(qname_addressing, env); + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding module %s to service group %s failed", + mod_name, svc_grp_name); + + return status; + } + } + + axutil_qname_free(qname_addressing, env); + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_resolver_engage_module_globally"); + + return status; +} + +/** + * This function is called to engage a module to a service specifically. In other words all module + * handlers defined for user phases are added into user defined phases and all module handlers + * defined for system defined phases are added into system defined phases. Note that user defined + * phases are in the flows taken from operation and system defined phases are in the flows taken + * from conf. Where each module handler should go is determined by module handler descriptions in + * module.xml file. + * First we add the operations defined in the module into the service and built execution chains for + * them. Then for all the operations of the service we check whether the module + * already engaged to operation. If not engage it to service operation. Also if the module is newly + * engaged to operation add the module qnname to the engaged module list of the operation. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_resolver_engage_module_to_svc( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_svc_t * svc, + axis2_module_desc_t * module_desc) +{ + axutil_hash_t *ops = NULL; + axutil_hash_index_t *index_i = NULL; + axis2_status_t status = AXIS2_FAILURE; + const axutil_qname_t *module_d_qname = NULL; + axis2_char_t *modname_d = NULL; + const axis2_char_t *svcname = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_resolver_engage_module_to_svc"); + + module_d_qname = axis2_module_desc_get_qname(module_desc, env); + modname_d = axutil_qname_get_localpart(module_d_qname, env); + svcname = axis2_svc_get_name(svc, env); + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Module %s will be engaged to %s", modname_d, svcname); + + ops = axis2_svc_get_all_ops(svc, env); + if(!ops) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service %s has no operation", svcname); + + return AXIS2_FAILURE; + } + + /* Module operations are added to service and built execution chains */ + status = axis2_svc_add_module_ops(svc, env, module_desc, phase_resolver->axis2_config); + + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding module operations from module %s into service %s failed", modname_d, svcname); + + return status; + } + + for(index_i = axutil_hash_first(ops, env); index_i; index_i = axutil_hash_next(env, index_i)) + { + axutil_array_list_t *modules = NULL; + axis2_op_t *op_desc = NULL; + int size = 0; + int j = 0; + void *v = NULL; + axis2_bool_t engaged = AXIS2_FALSE; + axis2_char_t *opname = NULL; + + axutil_hash_this(index_i, NULL, NULL, &v); + op_desc = (axis2_op_t *)v; + + opname = axutil_qname_get_localpart(axis2_op_get_qname(op_desc, env), env); + + modules = axis2_op_get_all_modules(op_desc, env); + if(modules) + { + size = axutil_array_list_size(modules, env); + } + + for(j = 0; j < size; j++) + { + axis2_module_desc_t *module_desc_l = NULL; + const axutil_qname_t *module_d_qname_l = NULL; + + module_desc_l = axutil_array_list_get(modules, env, j); + module_d_qname_l = axis2_module_desc_get_qname(module_desc_l, env); + if(axutil_qname_equals(module_d_qname, env, module_d_qname_l)) + { + engaged = AXIS2_TRUE; + status = AXIS2_SUCCESS; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Module %s already engaged to operation %s of service %s", modname_d, opname, + svcname); + + break; + } + } + + if(!engaged) + { + status = axis2_phase_resolver_engage_module_to_op(phase_resolver, env, op_desc, + module_desc); + + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Engaging module %s to operation %s failed.", modname_d, opname); + + return status; + } + + status = axis2_op_add_to_engaged_module_list(op_desc, env, module_desc); + } + + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_resolver_engage_module_to_svc"); + + return status; +} + +/** + * In this function all the handlers in each flow of the module description are added to the phases + * of the operation(user define phases) and phases of the conf(system defined phases). First handlers + * for system defined phases are added. Then handlers for operation specific phases are added. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_resolver_engage_module_to_op( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_op_t * axis_op, + axis2_module_desc_t * module_desc) +{ + int type = 0; + axis2_phase_holder_t *phase_holder = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_resolver_engage_module_to_op"); + AXIS2_PARAM_CHECK(env->error, axis_op, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + + for(type = 1; type < 5; type++) + { + axis2_flow_t *flow = NULL; + axis2_char_t *flowname = NULL; + axutil_array_list_t *phases = NULL; + + switch(type) + { + case AXIS2_IN_FLOW: + { + phases = axis2_op_get_in_flow(axis_op, env); + break; + } + case AXIS2_OUT_FLOW: + { + phases = axis2_op_get_out_flow(axis_op, env); + break; + } + case AXIS2_FAULT_IN_FLOW: + { + phases = axis2_op_get_fault_in_flow(axis_op, env); + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + phases = axis2_op_get_fault_out_flow(axis_op, env); + break; + } + } + + if(phases) + { + phase_holder = axis2_phase_holder_create_with_phases(env, phases); + } + + switch(type) + { + case AXIS2_IN_FLOW: + { + flow = axis2_module_desc_get_in_flow(module_desc, env); + flowname = "in flow"; + break; + } + case AXIS2_OUT_FLOW: + { + flow = axis2_module_desc_get_out_flow(module_desc, env); + flowname = "out flow"; + break; + } + case AXIS2_FAULT_IN_FLOW: + { + flow = axis2_module_desc_get_fault_in_flow(module_desc, env); + flowname = "fault in flow"; + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + flow = axis2_module_desc_get_fault_out_flow(module_desc, env); + flowname = "fault out flow"; + break; + } + } + + if(flow && phase_holder) + { + int j = 0; + int handler_count = 0; + + handler_count = axis2_flow_get_handler_count(flow, env); + for(j = 0; j < handler_count; j++) + { + /* For all handlers in the flow from the module description */ + axis2_handler_desc_t *metadata = NULL; + const axis2_char_t *phase_name = NULL; + axis2_phase_rule_t *phase_rule = NULL; + const axutil_string_t *handlersname = NULL; + const axis2_char_t *handlername = NULL; + axis2_status_t status = AXIS2_FAILURE; + + metadata = axis2_flow_get_handler(flow, env, j); + handlersname = axis2_handler_desc_get_name(metadata, env); + handlername = axutil_string_get_buffer(handlersname, env); + phase_rule = axis2_handler_desc_get_rules(metadata, env); + phase_name = axis2_phase_rule_get_name(phase_rule, env); + + /* For user/operation specific phases */ + if((axutil_strcmp(AXIS2_PHASE_TRANSPORT_IN, phase_name)) && (axutil_strcmp( + AXIS2_PHASE_DISPATCH, phase_name)) && (axutil_strcmp(AXIS2_PHASE_POST_DISPATCH, + phase_name)) && (axutil_strcmp(AXIS2_PHASE_PRE_DISPATCH, phase_name))) + { + status = axis2_phase_holder_add_handler(phase_holder, env, metadata); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Handler %s inclusion failed for %s phase within flow %s. Phase might" + "not available in axis2.xml", handlername, phase_name, phase_name, + flowname); + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + axis2_phase_holder_free(phase_holder, env); + return status; + } + + } + + /* For System defined phases */ + if((!axutil_strcmp(AXIS2_PHASE_TRANSPORT_IN, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_DISPATCH, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_POST_DISPATCH, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_PRE_DISPATCH, phase_name))) + { + axutil_array_list_t *phase_list = NULL; + axis2_phase_holder_t *phase_holder = NULL; + + phase_list = axis2_conf_get_in_phases_upto_and_including_post_dispatch( + phase_resolver->axis2_config, env); + + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + phase_holder = NULL; + } + + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + + status = axis2_phase_holder_add_handler(phase_holder, env, metadata); + axis2_phase_holder_free(phase_holder, env); + phase_holder = NULL; + + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding handler %s to phase %s within flow %s failed", handlername, + phase_name, flowname); + + return status; + } + } + } + } + + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + phase_holder = NULL; + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_resolver_engage_module_to_op"); + + return AXIS2_SUCCESS; +} + +/** + * The caller function first set the service into the phase resolver. Then call this function to + * build execution chains for that services operations. Within this function it just call + * axis2_phase_resolver_build_execution_chains_for_op() function to build exection chains for + * each operation. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_resolver_build_execution_chains_for_svc( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env) +{ + axutil_hash_index_t *index_i = 0; + axis2_status_t status = AXIS2_FAILURE; + axis2_op_t *op = NULL; + axutil_hash_t *ops = NULL; + + if(!(phase_resolver->svc)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No service set to phase resolver"); + return AXIS2_FAILURE; + } + + ops = axis2_svc_get_all_ops(phase_resolver->svc, env); + + for(index_i = axutil_hash_first(ops, env); index_i; index_i = axutil_hash_next(env, index_i)) + { + void *v = NULL; + int j = 0; + + axutil_hash_this(index_i, NULL, NULL, &v); + op = (axis2_op_t *)v; + for(j = 1; j < 5; j++) + { + status = axis2_phase_resolver_build_execution_chains_for_op(phase_resolver, env, j, op); + } + } + + return status; +} + +/** + * For operation passed as parameter, build execution chains. To do this get all engaged modules + * from the axis2 configuration and for each module get the all handlers to be add to the operation + * specific phases. Then for each operation specific phases add those handlers. It should be noted + * that by the time this function is called the module handlers are already added to system specific + * phases. This function is called from axis2_phase_resolver_build_execution_chains_for_svc() + * function and axis2_phase_resolver_build_execution_chains_for_module_op() function. + */ +static axis2_status_t +axis2_phase_resolver_build_execution_chains_for_op( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + int type, + axis2_op_t *op) +{ + axutil_array_list_t *handler_list = NULL; + axutil_array_list_t *moduleqnames = NULL; + int i = 0; + int size = 0; + int status = AXIS2_FAILURE; + axis2_char_t *flowname = NULL; + axis2_phase_holder_t *phase_holder = NULL; + axutil_array_list_t *engaged_module_list_for_parent_svc = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "Entry:axis2_phase_resolver_build_execution_chains_for_op"); + + handler_list = axutil_array_list_create(env, 0); + if(!handler_list) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + + /* Engage handlers from axis2.xml and from modules */ + moduleqnames = axis2_conf_get_all_engaged_modules(phase_resolver->axis2_config, env); + + size = axutil_array_list_size(moduleqnames, env); + + for(i = 0; i < size; i++) + { + axis2_char_t *modulename = NULL; + axutil_qname_t *moduleqname = NULL; + axis2_module_desc_t *module_desc = NULL; + + moduleqname = (axutil_qname_t *)axutil_array_list_get(moduleqnames, env, i); + modulename = axutil_qname_get_localpart(moduleqname, env); + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Module name is:%s", modulename); + + module_desc = axis2_conf_get_module(phase_resolver->axis2_config, env, moduleqname); + if(!module_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODULE_REF, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Module description not found in axis2 configuration for name %s", modulename); + + if(handler_list) + { + axutil_array_list_free(handler_list, env); + } + + return AXIS2_FAILURE; + } + + status = axis2_phase_resolver_add_to_handler_list(env, handler_list, op, module_desc, type); + if(AXIS2_SUCCESS != status) + { + if(handler_list) + { + axutil_array_list_free(handler_list, env); + } + return AXIS2_FAILURE; + } + + axis2_op_add_to_engaged_module_list(op, env, module_desc); + } + + engaged_module_list_for_parent_svc + = axis2_svc_get_engaged_module_list(phase_resolver->svc, env); + size = axutil_array_list_size(engaged_module_list_for_parent_svc, env); + + for(i = 0; i < size; i++) + { + axis2_char_t *modulename = NULL; + axutil_qname_t *moduleqname = NULL; + axis2_module_desc_t *module_desc = NULL; + + module_desc = axutil_array_list_get(engaged_module_list_for_parent_svc, env, i); + if(!module_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_MODULE_REF, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Module description not found in engaged module list for service %s", + axis2_svc_get_name(phase_resolver->svc, env)); + + if(handler_list) + { + axutil_array_list_free(handler_list, env); + } + + return AXIS2_FAILURE; + } + + moduleqname = (axutil_qname_t *)axis2_module_desc_get_qname(module_desc, env); + modulename = axutil_qname_get_localpart(moduleqname, env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Module name is:%s", modulename); + + status = axis2_phase_resolver_add_to_handler_list(env, handler_list, op, module_desc, type); + if(AXIS2_SUCCESS != status) + { + if(handler_list) + { + axutil_array_list_free(handler_list, env); + } + return AXIS2_FAILURE; + } + + axis2_op_add_to_engaged_module_list(op, env, module_desc); + } + + if(0 == axutil_array_list_size(handler_list, env)) + { + /* No flows configured */ + if(handler_list) + { + axutil_array_list_free(handler_list, env); + } + + return AXIS2_SUCCESS; + } + + switch(type) + { + case AXIS2_IN_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_op_get_in_flow(op, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + flowname = "in flow"; + break; + } + case AXIS2_OUT_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_op_get_out_flow(op, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + flowname = "out flow"; + break; + } + case AXIS2_FAULT_IN_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_op_get_fault_in_flow(op, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + flowname = "fault in flow"; + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_op_get_fault_out_flow(op, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + flowname = "fault out flow"; + break; + } + } + + size = axutil_array_list_size(handler_list, env); + for(i = 0; i < size; i++) + { + axis2_handler_desc_t *metadata = NULL; + + metadata = (axis2_handler_desc_t *)axutil_array_list_get(handler_list, env, i); + if(phase_holder) + { + status = axis2_phase_holder_add_handler(phase_holder, env, metadata); + if(!status) + { + break; + } + } + } + + /* Free the locally created handler_list*/ + if(handler_list) + { + axutil_array_list_free(handler_list, env); + } + + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "Exit:axis2_phase_resolver_build_execution_chains_for_op"); + + return status; +} + +/** + * For module operation build execution chains. This is called by axis2_svc_add_module_ops() function. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_resolver_build_execution_chains_for_module_op( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_op_t * op) +{ + int i = 0; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "Entry:axis2_phase_resolver_build_execution_chains_for_module_op"); + AXIS2_PARAM_CHECK(env->error, op, AXIS2_FAILURE); + + for(i = 1; i < 5; i++) + { + status = axis2_phase_resolver_build_execution_chains_for_op(phase_resolver, env, i, op); + if(!status) + { + break; + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "Exit:axis2_phase_resolver_build_execution_chains_for_module_op"); + return status; +} + +/** + * Take the phases for each flow from the axis2 configuration, take all the handlers of each flow + * from the module description and then each handler is added into the corresponding global phase. + * This function is called from function axis2_phase_resolver_engage_module_globally() to add + * module handlers into global phases. + */ +static axis2_status_t +axis2_phase_resolver_add_module_handlers_to_system_defined_phases( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_module_desc_t * module_desc) +{ + int type = 0; + axis2_status_t status = AXIS2_FAILURE; + axis2_phase_holder_t *phase_holder = NULL; + const axutil_qname_t *modqname = NULL; + axis2_char_t *modname = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "Entry:axis2_phase_resolver_add_module_handlers_to_system_defined_phases"); + + modqname = axis2_module_desc_get_qname(module_desc, env); + modname = axutil_qname_get_localpart(modqname, env); + for(type = 1; type < 5; type++) + { + axis2_flow_t *flow = NULL; + axis2_char_t *flow_name = NULL; + + switch(type) + { + case AXIS2_IN_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_conf_get_in_phases_upto_and_including_post_dispatch( + phase_resolver->axis2_config, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + if(!phase_holder) + continue; + break; + } + case AXIS2_OUT_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_conf_get_out_flow(phase_resolver->axis2_config, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + if(!phase_holder) + continue; + break; + } + case AXIS2_FAULT_IN_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_conf_get_in_fault_flow(phase_resolver-> axis2_config, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + if(!phase_holder) + continue; + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_conf_get_out_fault_flow(phase_resolver-> axis2_config, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + if(!phase_holder) + continue; + break; + } + } + + /* Modules referred by axis2.xml */ + switch(type) + { + case AXIS2_IN_FLOW: + { + flow = axis2_module_desc_get_in_flow(module_desc, env); + flow_name = "in flow"; + break; + } + case AXIS2_OUT_FLOW: + { + flow = axis2_module_desc_get_out_flow(module_desc, env); + flow_name = "out flow"; + break; + } + case AXIS2_FAULT_IN_FLOW: + { + flow = axis2_module_desc_get_fault_in_flow(module_desc, env); + flow_name = "fault in flow"; + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + flow = axis2_module_desc_get_fault_out_flow(module_desc, env); + flow_name = "fault out flow"; + break; + } + } + if(flow) + { + int j = 0; + for(j = 0; j < axis2_flow_get_handler_count(flow, env); j++) + { + axis2_handler_desc_t *metadata = NULL; + const axis2_char_t *phase_name = NULL; + axis2_phase_rule_t *phase_rule = NULL; + const axutil_string_t *handlersname = NULL; + const axis2_char_t *handlername = NULL; + + metadata = axis2_flow_get_handler(flow, env, j); + handlersname = axis2_handler_desc_get_name(metadata, env); + handlername = axutil_string_get_buffer(handlersname, env); + phase_rule = axis2_handler_desc_get_rules(metadata, env); + if(phase_rule) + { + phase_name = axis2_phase_rule_get_name(phase_rule, env); + } + if(!phase_name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Phase rules for handler %s has no name", handlername); + return AXIS2_FAILURE; + } + if((!axutil_strcmp(AXIS2_PHASE_TRANSPORT_IN, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_DISPATCH, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_POST_DISPATCH, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_PRE_DISPATCH, phase_name))) + { + /* If a global phase add the module handler*/ + status = axis2_phase_holder_add_handler(phase_holder, env, metadata); + if(!status) + { + axis2_phase_holder_free(phase_holder, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding handler %s of module %s to phase %s of " + "flow %s failed", handlername, modname, phase_name, flow_name); + return status; + } + } + } + } + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "Exit:axis2_phase_resolver_add_module_handlers_to_system_defined_phases"); + return AXIS2_SUCCESS; +} + +/** + * For each operation of the service first check whether module is already engaged to operation. + * If not take each operations flows and add the module handlers into them appropriately. This + * function is called from function axis2_phase_resolver_engage_module_globally() to add handlers + * from module into each services all operations. + */ +static axis2_status_t +axis2_phase_resolver_add_module_handlers_to_user_defined_phases( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_svc_t * svc, + axis2_module_desc_t * module_desc) +{ + axutil_hash_t *ops = NULL; + axis2_bool_t engaged = AXIS2_FALSE; + axutil_hash_index_t *index_i = NULL; + int type = 0; + axis2_status_t status = AXIS2_FAILURE; + axis2_phase_holder_t *phase_holder = NULL; + const axis2_char_t *svc_name = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "Entry:axis2_phase_resolver_add_module_handlers_to_user_defined_phases"); + + AXIS2_PARAM_CHECK(env->error, svc, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + svc_name = axis2_svc_get_name(svc, env); + ops = axis2_svc_get_all_ops(svc, env); + if(!ops) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No operations for the service %s", svc_name); + return AXIS2_FAILURE; + } + + for(index_i = axutil_hash_first(ops, env); index_i; index_i = axutil_hash_next(env, index_i)) + { + void *v = NULL; + axis2_op_t *op_desc = NULL; + int j = 0; + axutil_array_list_t *modules = NULL; + axis2_flow_t *flow = NULL; + axis2_char_t *flowname = NULL; + const axutil_qname_t *module_desc_qname = NULL; + axis2_char_t *module_desc_name = NULL; + int size = 0; + axis2_char_t *op_name = NULL; + + axutil_hash_this(index_i, NULL, NULL, &v); + op_desc = (axis2_op_t *)v; + op_name = axutil_qname_get_localpart(axis2_op_get_qname(op_desc, env), env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Operation name is : %s", op_name); + + /* Get all modules engaged to the operation */ + modules = axis2_op_get_all_modules(op_desc, env); + module_desc_qname = axis2_module_desc_get_qname(module_desc, env); + module_desc_name = axutil_qname_get_localpart(module_desc_qname, env); + if(modules) + { + size = axutil_array_list_size(modules, env); + } + + /* Checking whether module is already engaged to operation */ + for(j = 0; j < size; j++) + { + axis2_module_desc_t *module_desc_l = NULL; + const axutil_qname_t *module_desc_qname_l = NULL; + + module_desc_l = (axis2_module_desc_t *)axutil_array_list_get(modules, env, j); + + module_desc_qname_l = axis2_module_desc_get_qname(module_desc_l, env); + if(axutil_qname_equals(module_desc_qname_l, env, module_desc_qname)) + { + engaged = AXIS2_TRUE; + break; + } + } + + if(engaged) + { + continue; + } + + for(type = 1; type < 5; type++) + { + switch(type) + { + case AXIS2_IN_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_op_get_in_flow(op_desc, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + break; + } + case AXIS2_OUT_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_op_get_out_flow(op_desc, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + break; + } + case AXIS2_FAULT_IN_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_op_get_fault_in_flow(op_desc, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + axutil_array_list_t *phase_list = NULL; + + phase_list = axis2_op_get_fault_out_flow(op_desc, env); + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + break; + } + } + + /* Process modules referred by axis2.xml */ + + switch(type) + { + case AXIS2_IN_FLOW: + { + flow = axis2_module_desc_get_in_flow(module_desc, env); + flowname = "in flow"; + break; + } + case AXIS2_OUT_FLOW: + { + flow = axis2_module_desc_get_out_flow(module_desc, env); + flowname = "out flow"; + break; + } + case AXIS2_FAULT_IN_FLOW: + { + flow = axis2_module_desc_get_fault_in_flow(module_desc, env); + flowname = "fault in flow"; + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + flow = axis2_module_desc_get_fault_out_flow(module_desc, env); + flowname = "fault out flow"; + break; + } + } + + if(flow) + { + int handler_count = 0; + + handler_count = axis2_flow_get_handler_count(flow, env); + for(j = 0; j < handler_count; j++) + { + axis2_handler_desc_t *metadata = NULL; + const axis2_char_t *phase_name = NULL; + axis2_phase_rule_t *phase_rule = NULL; + const axutil_string_t *handlersname = NULL; + const axis2_char_t *handlername = NULL; + + metadata = axis2_flow_get_handler(flow, env, j); + handlersname = axis2_handler_desc_get_name(metadata, env); + handlername = axutil_string_get_buffer(handlersname, env); + phase_rule = axis2_handler_desc_get_rules(metadata, env); + if(phase_rule) + { + phase_name = axis2_phase_rule_get_name(phase_rule, env); + } + if(!phase_name) + { + AXIS2_LOG_ERROR( + env->log, + AXIS2_LOG_SI, + "Handler rules for the handler description %s within flow %s has no name", + handlername, flowname); + + return AXIS2_FAILURE; + } + + /* If phase is not a system defined phase, add module handler to it */ + if((axutil_strcmp(AXIS2_PHASE_TRANSPORT_IN, phase_name)) && (axutil_strcmp( + AXIS2_PHASE_DISPATCH, phase_name)) && (axutil_strcmp( + AXIS2_PHASE_POST_DISPATCH, phase_name)) && (axutil_strcmp( + AXIS2_PHASE_PRE_DISPATCH, phase_name))) + { + if(phase_holder) + { + status = axis2_phase_holder_add_handler(phase_holder, env, metadata); + if(!status) + { + axis2_phase_holder_free(phase_holder, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding handler desc %s to" + "phase %s within flow %s failed", handlername, phase_name, + flowname); + + return status; + } + } + } + } + } + + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + } + } + status = axis2_op_add_to_engaged_module_list(op_desc, env, module_desc); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding module description %s to engaged " + "module list of operation %s failed", module_desc_name, op_name); + + return status; + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "Exit:axis2_phase_resolver_add_module_handlers_to_user_defined_phases"); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_resolver_disengage_module_from_svc( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_svc_t * svc, + axis2_module_desc_t * module_desc) +{ + axutil_hash_t *ops = NULL; + axutil_hash_index_t *index_i = NULL; + axis2_status_t status = AXIS2_FAILURE; + const axutil_qname_t *module_d_qname = NULL; + const axis2_char_t *svc_name = axis2_svc_get_name(svc, env); + axis2_char_t *modname_d = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_resolver_disengage_module_from_svc"); + + ops = axis2_svc_get_all_ops(svc, env); + if(!ops) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Service %s has no operation", svc_name); + return AXIS2_FAILURE; + } + + module_d_qname = axis2_module_desc_get_qname(module_desc, env); + modname_d = axutil_qname_get_localpart(module_d_qname, env); + for(index_i = axutil_hash_first(ops, env); index_i; index_i = axutil_hash_next(env, index_i)) + { + axutil_array_list_t *modules = NULL; + axis2_op_t *op_desc = NULL; + int size = 0; + int j = 0; + void *v = NULL; + axis2_bool_t engaged = AXIS2_FALSE; + const axutil_qname_t *opqname = NULL; + axis2_char_t *opname = NULL; + + axutil_hash_this(index_i, NULL, NULL, &v); + op_desc = (axis2_op_t *)v; + opqname = axis2_op_get_qname(op_desc, env); + opname = axutil_qname_get_localpart(opqname, env); + modules = axis2_op_get_all_modules(op_desc, env); + if(modules) + { + size = axutil_array_list_size(modules, env); + } + for(j = 0; j < size; j++) + { + axis2_module_desc_t *module_desc_l = NULL; + const axutil_qname_t *module_d_qname_l = NULL; + + module_desc_l = axutil_array_list_get(modules, env, j); + module_d_qname_l = axis2_module_desc_get_qname(module_desc_l, env); + if(axutil_qname_equals(module_d_qname, env, module_d_qname_l)) + { + engaged = AXIS2_TRUE; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Module %s already engaged.", modname_d); + break; + } + } + + if(engaged) + { + status = axis2_phase_resolver_disengage_module_from_op(phase_resolver, env, op_desc, + module_desc); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Disengaging module %s from operation %s failed", modname_d, opname); + return status; + } + + status = axis2_op_remove_from_engaged_module_list(op_desc, env, module_desc); + } + + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_resolver_disengage_module_from_svc"); + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_resolver_disengage_module_from_op( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_op_t * axis_op, + axis2_module_desc_t * module_desc) +{ + int type = 0; + axis2_phase_holder_t *phase_holder = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_resolver_disengage_module_from_op"); + AXIS2_PARAM_CHECK(env->error, axis_op, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, module_desc, AXIS2_FAILURE); + + for(type = 1; type < 5; type++) + { + axis2_flow_t *flow = NULL; + axis2_char_t *flowname = NULL; + axutil_array_list_t *phases = NULL; + + switch(type) + { + case AXIS2_IN_FLOW: + { + phases = axis2_op_get_in_flow(axis_op, env); + break; + } + case AXIS2_OUT_FLOW: + { + phases = axis2_op_get_out_flow(axis_op, env); + break; + } + case AXIS2_FAULT_IN_FLOW: + { + phases = axis2_op_get_fault_in_flow(axis_op, env); + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + phases = axis2_op_get_fault_out_flow(axis_op, env); + break; + } + } + + if(phases) + { + phase_holder = axis2_phase_holder_create_with_phases(env, phases); + } + + switch(type) + { + case AXIS2_IN_FLOW: + { + flow = axis2_module_desc_get_in_flow(module_desc, env); + flowname = "in flow"; + break; + } + case AXIS2_OUT_FLOW: + { + flow = axis2_module_desc_get_out_flow(module_desc, env); + flowname = "out flow"; + break; + } + case AXIS2_FAULT_IN_FLOW: + { + flow = axis2_module_desc_get_fault_in_flow(module_desc, env); + flowname = "fault in flow"; + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + flow = axis2_module_desc_get_fault_out_flow(module_desc, env); + flowname = "fault out flow"; + break; + } + } + + if(flow && phase_holder) + { + int j = 0; + int handler_count = 0; + + handler_count = axis2_flow_get_handler_count(flow, env); + for(j = 0; j < handler_count; j++) + { + axis2_handler_desc_t *metadata = NULL; + const axis2_char_t *phase_name = NULL; + axis2_phase_rule_t *phase_rule = NULL; + const axutil_string_t *handlersname = NULL; + const axis2_char_t *handlername = NULL; + axis2_status_t status = AXIS2_FAILURE; + + metadata = axis2_flow_get_handler(flow, env, j); + handlersname = axis2_handler_desc_get_name(metadata, env); + handlername = axutil_string_get_buffer(handlersname, env); + phase_rule = axis2_handler_desc_get_rules(metadata, env); + phase_name = axis2_phase_rule_get_name(phase_rule, env); + if((axutil_strcmp(AXIS2_PHASE_TRANSPORT_IN, phase_name)) && (axutil_strcmp( + AXIS2_PHASE_DISPATCH, phase_name)) && (axutil_strcmp(AXIS2_PHASE_POST_DISPATCH, + phase_name)) && (axutil_strcmp(AXIS2_PHASE_PRE_DISPATCH, phase_name))) + { + status = axis2_phase_holder_remove_handler(phase_holder, env, metadata); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Handler %s Removal failed for %s phase within flow %s", handlername, + phase_name, flowname); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + axis2_phase_holder_free(phase_holder, env); + return status; + } + + } + if((!axutil_strcmp(AXIS2_PHASE_TRANSPORT_IN, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_DISPATCH, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_POST_DISPATCH, phase_name)) || (!axutil_strcmp( + AXIS2_PHASE_PRE_DISPATCH, phase_name))) + { + axutil_array_list_t *phase_list = NULL; + axis2_phase_holder_t *phase_holder = NULL; + + phase_list = axis2_conf_get_in_phases_upto_and_including_post_dispatch( + phase_resolver->axis2_config, env); + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + phase_holder = NULL; + } + phase_holder = axis2_phase_holder_create_with_phases(env, phase_list); + + status = axis2_phase_holder_remove_handler(phase_holder, env, metadata); + axis2_phase_holder_free(phase_holder, env); + phase_holder = NULL; + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Removing handler %s from phase %s within flow %s failed", handlername, + phase_name, flowname); + return status; + } + } + } + } + + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + phase_holder = NULL; + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_resolver_disengage_module_from_op"); + return AXIS2_SUCCESS; +} + +/* This function is deprecated and no longer used */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_phase_resolver_build_transport_chains( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env) +{ + axis2_transport_in_desc_t **transports_in = NULL; + axis2_transport_out_desc_t **transports_out = NULL; + int index_i = 0; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_resolver_build_transport_chains"); + + transports_in = axis2_conf_get_all_in_transports(phase_resolver->axis2_config, env); + if(!transports_in) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_TRANSPORT_IN_CONFIGURED, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No transport in descriptions configured"); + return AXIS2_SUCCESS; + } + + transports_out = axis2_conf_get_all_out_transports(phase_resolver->axis2_config, env); + if(!transports_out) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_TRANSPORT_OUT_CONFIGURED, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No transport out descriptions configured"); + return AXIS2_SUCCESS; + } + + for(index_i = 0; index_i < AXIS2_TRANSPORT_ENUM_MAX; index_i++) + { + if(transports_in[index_i]) + { + status = axis2_phase_resolver_build_in_transport_chains(phase_resolver, env, + transports_in[index_i]); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Building transport in chains failed"); + return status; + } + } + } + + for(index_i = 0; index_i < AXIS2_TRANSPORT_ENUM_MAX; index_i++) + { + if(transports_out[index_i]) + { + status = axis2_phase_resolver_build_out_transport_chains(phase_resolver, env, + transports_out[index_i]); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Building transport out chains failed"); + return status; + } + } + } + + /* If transport in or transport out maps are not null but still they don't + * have chains configured then we return success, because there are no + * chains to process. + */ + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_resolver_build_transport_chains"); + return AXIS2_SUCCESS; +} + +/** + * This function is called from function + * axis2_phase_resolver_build_transport_chains(). + * This function is deprecated and no longer used. + */ +static axis2_status_t +axis2_phase_resolver_build_in_transport_chains( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_transport_in_desc_t * transport) +{ + int type = 0; + int j = 0; + axis2_status_t status = AXIS2_FAILURE; + axutil_array_list_t *handlers = NULL; + AXIS2_TRANSPORT_ENUMS transport_enum = axis2_transport_in_desc_get_enum(transport, env); + ; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_resolver_build_in_transport_chains"); + AXIS2_PARAM_CHECK(env->error, transport, AXIS2_FAILURE); + + for(type = 1; type < 4; type++) + { + axis2_flow_t *flow = NULL; + axis2_char_t *flowname = NULL; + axis2_phase_t *phase = NULL; + + switch(type) + { + case AXIS2_IN_FLOW: + { + flow = axis2_transport_in_desc_get_in_flow(transport, env); + phase = axis2_transport_in_desc_get_in_phase(transport, env); + flowname = "in flow"; + break; + } + case AXIS2_FAULT_IN_FLOW: + { + flow = axis2_transport_in_desc_get_fault_in_flow(transport, env); + phase = axis2_transport_in_desc_get_fault_phase(transport, env); + flowname = "fault in flow"; + break; + } + } + if(flow) + { + axis2_phase_holder_t *phase_holder = NULL; + int size = 0; + + size = axis2_flow_get_handler_count(flow, env); + handlers = axutil_array_list_create(env, 0); + for(j = 0; j < size; j++) + { + axis2_handler_desc_t *metadata = NULL; + axis2_phase_rule_t *rule = NULL; + const axis2_char_t *handlername = NULL; + const axutil_string_t *handlersname = NULL; + + metadata = axis2_flow_get_handler(flow, env, j); + handlersname = axis2_handler_desc_get_name(metadata, env); + handlername = axutil_string_get_buffer(handlersname, env); + rule = axis2_handler_desc_get_rules(metadata, env); + if(rule) + { + status = axis2_phase_rule_set_name(rule, env, AXIS2_TRANSPORT_PHASE); + } + if(AXIS2_SUCCESS != status) + { + if(handlers) + { + axis2_handler_desc_t *handler_d = NULL; + int i = 0; + int size = 0; + + size = axutil_array_list_size(handlers, env); + for(i = 0; i < size; i++) + { + handler_d = axutil_array_list_get(handlers, env, i); + axis2_handler_desc_free(handler_d, env); + } + axutil_array_list_free(handlers, env); + } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting name %s to phase rules for handler %s failed" + "for in transport %d within flow %s", AXIS2_TRANSPORT_PHASE, + handlername, transport_enum, flowname); + return status; + } + status = axutil_array_list_add(handlers, env, metadata); + if(AXIS2_SUCCESS != status) + { + if(handlers) + { + axis2_handler_desc_t *handler_d = NULL; + int i = 0; + int size = 0; + + size = axutil_array_list_size(handlers, env); + for(i = 0; i < size; i++) + { + handler_d = axutil_array_list_get(handlers, env, i); + axis2_handler_desc_free(handler_d, env); + } + axutil_array_list_free(handlers, env); + } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding handler %s from in transport %d to handler " + "list failed within flow %s", handlername, transport_enum, flowname); + return status; + } + } + phase_holder = axis2_phase_holder_create(env); + if(!phase_holder) + { + if(handlers) + { + axis2_handler_desc_t *handler_d = NULL; + int i = 0; + int size = 0; + + size = axutil_array_list_size(handlers, env); + for(i = 0; i < size; i++) + { + handler_d = axutil_array_list_get(handlers, env, i); + axis2_handler_desc_free(handler_d, env); + } + axutil_array_list_free(handlers, env); + } + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + + status = axis2_phase_holder_build_transport_handler_chain(phase_holder, env, phase, + handlers); + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + } + } + else + { + /* Do nothing */ + } + } + if(handlers) + { + axutil_array_list_free(handlers, env); + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_resolver_build_in_transport_chains"); + return status; +} + +/** + * This function is called from function + * axis2_phase_resolver_build_transport_chains(). + * This is deprecated and no longer used. + */ +static axis2_status_t +axis2_phase_resolver_build_out_transport_chains( + axis2_phase_resolver_t * phase_resolver, + const axutil_env_t * env, + axis2_transport_out_desc_t * transport) +{ + int type = 0; + axis2_status_t status = AXIS2_FAILURE; + axutil_array_list_t *handlers = NULL; + AXIS2_TRANSPORT_ENUMS transport_enum = axis2_transport_out_desc_get_enum(transport, env); + ; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_resolver_build_out_transport_chains"); + AXIS2_PARAM_CHECK(env->error, transport, AXIS2_FAILURE); + for(type = 1; type < 5; type++) + { + axis2_flow_t *flow = NULL; + axis2_char_t *flowname = NULL; + axis2_phase_t *phase = NULL; + + switch(type) + { + case AXIS2_OUT_FLOW: + { + flow = axis2_transport_out_desc_get_out_flow(transport, env); + phase = axis2_transport_out_desc_get_out_phase(transport, env); + flowname = "out flow"; + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + flow = axis2_transport_out_desc_get_fault_out_flow(transport, env); + phase = axis2_transport_out_desc_get_fault_phase(transport, env); + flowname = "fault out flow"; + break; + } + } + + if(flow) + { + axis2_phase_holder_t *phase_holder = NULL; + int hndlr_count = 0; + int j = 0; + hndlr_count = axis2_flow_get_handler_count(flow, env); + if(AXIS2_SUCCESS != AXIS2_ERROR_GET_STATUS_CODE(env->error)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, ""); + return AXIS2_ERROR_GET_STATUS_CODE(env->error); + } + handlers = axutil_array_list_create(env, 0); + + for(j = 0; j < hndlr_count; j++) + { + axis2_handler_desc_t *metadata = NULL; + axis2_phase_rule_t *rule = NULL; + const axis2_char_t *handlername = NULL; + const axutil_string_t *handlersname = NULL; + + metadata = axis2_flow_get_handler(flow, env, j); + handlersname = axis2_handler_desc_get_name(metadata, env); + handlername = axutil_string_get_buffer(handlersname, env); + + rule = axis2_handler_desc_get_rules(metadata, env); + if(rule) + { + status = axis2_phase_rule_set_name(rule, env, AXIS2_TRANSPORT_PHASE); + } + if(AXIS2_SUCCESS != status) + { + if(handlers) + { + axis2_handler_desc_t *handler_d = NULL; + int i = 0; + int size = 0; + + size = axutil_array_list_size(handlers, env); + for(i = 0; i < size; i++) + { + handler_d = axutil_array_list_get(handlers, env, i); + axis2_handler_desc_free(handler_d, env); + } + axutil_array_list_free(handlers, env); + } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Setting name %s to phase rules for handler %s failed" + "for out transport %d within flow %s", AXIS2_TRANSPORT_PHASE, + handlername, transport_enum, flowname); + return status; + } + + status = axutil_array_list_add(handlers, env, metadata); + if(AXIS2_FAILURE == status) + { + if(handlers) + { + axis2_handler_desc_t *handler_d = NULL; + int i = 0; + int size = 0; + + size = axutil_array_list_size(handlers, env); + for(i = 0; i < size; i++) + { + handler_d = axutil_array_list_get(handlers, env, i); + axis2_handler_desc_free(handler_d, env); + } + axutil_array_list_free(handlers, env); + } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding handler %s from out transport %d to handler " + "list failed within flow %s", handlername, transport_enum, flowname); + return status; + } + } + phase_holder = axis2_phase_holder_create(env); + if(!phase_holder) + { + if(handlers) + { + axis2_handler_desc_t *handler_d = NULL; + int i = 0; + int size = 0; + + size = axutil_array_list_size(handlers, env); + for(i = 0; i < size; i++) + { + handler_d = axutil_array_list_get(handlers, env, i); + axis2_handler_desc_free(handler_d, env); + } + axutil_array_list_free(handlers, env); + } + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory"); + return AXIS2_FAILURE; + } + + status = axis2_phase_holder_build_transport_handler_chain(phase_holder, env, phase, + handlers); + if(phase_holder) + { + axis2_phase_holder_free(phase_holder, env); + } + } + else + { + /* Do nothing */ + } + } + if(handlers) + { + axutil_array_list_free(handlers, env); + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_resolver_build_out_transport_chains"); + return status; +} + +/** + * This function is called from axis2_phase_resolver_build_execution_chains_for_op() function. + */ +static axis2_status_t +axis2_phase_resolver_add_to_handler_list( + const axutil_env_t * env, + axutil_array_list_t *handler_list, + axis2_op_t *op, + axis2_module_desc_t * module_desc, + int type) +{ + axis2_flow_t *flow = NULL; + axis2_char_t *flowname = NULL; + const axutil_qname_t *opqname = NULL; + axis2_char_t *opname = NULL; + axis2_status_t status = AXIS2_FAILURE; + + opqname = axis2_op_get_qname(op, env); + opname = axutil_qname_get_localpart(opqname, env); + + switch(type) + { + case AXIS2_IN_FLOW: + { + flow = axis2_module_desc_get_in_flow(module_desc, env); + flowname = "in flow"; + break; + } + case AXIS2_OUT_FLOW: + { + flow = axis2_module_desc_get_out_flow(module_desc, env); + flowname = "out flow"; + break; + } + case AXIS2_FAULT_IN_FLOW: + { + flow = axis2_module_desc_get_fault_in_flow(module_desc, env); + flowname = "fault in flow"; + break; + } + case AXIS2_FAULT_OUT_FLOW: + { + flow = axis2_module_desc_get_fault_out_flow(module_desc, env); + flowname = "fault out flow"; + break; + } + } + + if(flow) + { + int j = 0; + int count = 0; + + /* Ignore all the errors upto now */ + AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_SUCCESS); + + count = axis2_flow_get_handler_count(flow, env); + /*if(AXIS2_SUCCESS != AXIS2_ERROR_GET_STATUS_CODE(env->error)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Getting hanlder count for the flow %s failed", + flowname); + + return AXIS2_ERROR_GET_STATUS_CODE(env->error); + }*/ + + for(j = 0; j < count; j++) + { + axis2_handler_desc_t *metadata = NULL; + const axis2_char_t *phase_name = NULL; + axis2_phase_rule_t *phase_rule = NULL; + const axutil_string_t *handlername = NULL; + const axis2_char_t *handlername_buff = NULL; + + metadata = axis2_flow_get_handler(flow, env, j); + handlername = axis2_handler_desc_get_name(metadata, env); + handlername_buff = axutil_string_get_buffer(handlername, env); + phase_rule = axis2_handler_desc_get_rules(metadata, env); + phase_name = axis2_phase_rule_get_name(phase_rule, env); + if(!phase_name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Phase rules name null for the handler description %s within flow %s", + handlername_buff, flowname); + + return AXIS2_FAILURE; + } + + /* If user defined phases */ + if((axutil_strcmp(AXIS2_PHASE_TRANSPORT_IN, phase_name)) && (axutil_strcmp( + AXIS2_PHASE_DISPATCH, phase_name)) && (axutil_strcmp(AXIS2_PHASE_POST_DISPATCH, + phase_name)) && (axutil_strcmp(AXIS2_PHASE_PRE_DISPATCH, phase_name))) + { + status = axutil_array_list_add(handler_list, env, metadata); + if(AXIS2_SUCCESS != status) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Adding handler description %s failed for phase %s within flow %s", + handlername_buff, phase_name, flowname); + + return status; + } + } + else + { + AXIS2_LOG_DEBUG( + env->log, + AXIS2_LOG_SI, + "Trying to add this handler %s to system pre defined phases , but those " + "handlers are already added to global chain which run irrespective of the service", + handlername_buff); + } + } + } + + return AXIS2_SUCCESS; +} + diff --git a/src/core/receivers/Makefile.am b/src/core/receivers/Makefile.am new file mode 100644 index 0000000..8b12372 --- /dev/null +++ b/src/core/receivers/Makefile.am @@ -0,0 +1,11 @@ +noinst_LTLIBRARIES = libaxis2_receivers.la + +libaxis2_receivers_la_SOURCES = msg_recv.c \ + raw_xml_in_out_msg_recv.c \ + svr_callback.c + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/util \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/receivers/msg_recv.c b/src/core/receivers/msg_recv.c new file mode 100644 index 0000000..87bcc1d --- /dev/null +++ b/src/core/receivers/msg_recv.c @@ -0,0 +1,560 @@ +/* + * 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_msg_recv.h> +#include <axutil_param.h> +#include <axis2_description.h> +#include <axutil_class_loader.h> +#include <axis2_engine.h> +#include <axis2_core_utils.h> +#include <axutil_property.h> +#include <axiom_soap_envelope.h> +#include <axiom_soap_body.h> +#include <axutil_thread.h> + +struct axis2_msg_recv +{ + axis2_char_t *scope; + /** + * conf ctx is added to pass for the load_and_init_svc method + */ + axis2_conf_ctx_t *conf_ctx; + + void *derived; + + /** + * This contain in out synchronous business invoke logic + * @param msg_recv pointer to message receiver + * @param env pointer to environment struct + * @param in_msg_ctx pointer to in message context + * @param out_msg_ctx pointer to out message context + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + axis2_status_t + ( + AXIS2_CALL * invoke_business_logic) + ( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + struct axis2_msg_ctx * in_msg_ctx, + struct axis2_msg_ctx * out_msg_ctx); + + /** + * This method is called from axis2_engine_receive method. This method's + * actual implementation is decided from the create method of the + * extended message receiver object. There depending on the synchronous or + * asynchronous type, receive method is assigned with the synchronous or + * asynchronous implementation of receive. + * @see raw_xml_in_out_msg_recv_create method where receive is assigned + * to receive_sync + * @param msg_recv pointer to message receiver + * @param env pointer to environment struct + * @param in_msg_ctx pointer to in message context + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + axis2_status_t + ( + AXIS2_CALL * receive) + ( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + struct axis2_msg_ctx * in_msg_ctx, + void *callback_recv_param); + + axis2_status_t + ( + AXIS2_CALL *load_and_init_svc) +( axis2_msg_recv_t *msg_recv, +const axutil_env_t *env, +struct axis2_svc *svc); + +}; + +static axis2_status_t AXIS2_CALL +axis2_msg_recv_receive_impl( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + void *callback_recv_param); + +static axis2_status_t AXIS2_CALL +axis2_msg_recv_load_and_init_svc_impl( + axis2_msg_recv_t *msg_recv, + const axutil_env_t *env, + struct axis2_svc *svc) +{ + axutil_param_t *impl_info_param = NULL; + void *impl_class = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + if(!svc) + { + return AXIS2_FAILURE; + } + + impl_class = axis2_svc_get_impl_class(svc, env); + if(impl_class) + { + return AXIS2_SUCCESS; + } + /* When we load the DLL we have to make sure that only one thread will load it */ + axutil_thread_mutex_lock(axis2_svc_get_mutex(svc, env)); + /* If more than one thread tries to acquires the lock, first thread loads the DLL. + Others should not load the DLL */ + impl_class = axis2_svc_get_impl_class(svc, env); + if(impl_class) + { + axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env)); + return AXIS2_SUCCESS; + } + impl_info_param = axis2_svc_get_param(svc, env, AXIS2_SERVICE_CLASS); + if(!impl_info_param) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE); + axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env)); + return AXIS2_FAILURE; + } + + axutil_allocator_switch_to_global_pool(env->allocator); + + axutil_class_loader_init(env); + + impl_class = axutil_class_loader_create_dll(env, impl_info_param); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "loading the services from msg_recv_load_and_init_svc"); + + if(impl_class) + { + axis2_conf_t *conf = NULL; + conf = axis2_conf_ctx_get_conf(msg_recv->conf_ctx, env); + AXIS2_SVC_SKELETON_INIT((axis2_svc_skeleton_t *)impl_class, env); + } + + axis2_svc_set_impl_class(svc, env, impl_class); + + axutil_allocator_switch_to_local_pool(env->allocator); + axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env)); + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT axis2_msg_recv_t *AXIS2_CALL +axis2_msg_recv_create( + const axutil_env_t * env) +{ + axis2_msg_recv_t *msg_recv = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + msg_recv = (axis2_msg_recv_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_msg_recv_t)); + + if(!msg_recv) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + msg_recv->conf_ctx = NULL; + msg_recv->scope = axutil_strdup(env, "app*"); + msg_recv->derived = NULL; + msg_recv->load_and_init_svc = axis2_msg_recv_load_and_init_svc_impl; + msg_recv->receive = axis2_msg_recv_receive_impl; + return msg_recv; +} + +AXIS2_EXPORT void AXIS2_CALL +axis2_msg_recv_free( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(msg_recv->scope) + { + AXIS2_FREE(env->allocator, msg_recv->scope); + } + + if(msg_recv) + { + AXIS2_FREE(env->allocator, msg_recv); + } + + return; +} + +AXIS2_EXPORT axis2_svc_skeleton_t *AXIS2_CALL +axis2_msg_recv_make_new_svc_obj( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + struct axis2_svc *svc = NULL; + struct axis2_op_ctx *op_ctx = NULL; + struct axis2_svc_ctx *svc_ctx = NULL; + axutil_param_t *impl_info_param = NULL; + void *impl_class = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); + svc = axis2_svc_ctx_get_svc(svc_ctx, env); + if(!svc) + { + return NULL; + } + + impl_class = axis2_svc_get_impl_class(svc, env); + if(impl_class) + { + return impl_class; + } + else + { + /* When we load the DLL we have to make sure that only one thread will load it */ + axutil_thread_mutex_lock(axis2_svc_get_mutex(svc, env)); + /* If more than one thread tries to acquires the lock, first thread loads the DLL. + Others should not load the DLL */ + impl_class = axis2_svc_get_impl_class(svc, env); + if(impl_class) + { + axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env)); + return impl_class; + } + impl_info_param = axis2_svc_get_param(svc, env, AXIS2_SERVICE_CLASS); + if(!impl_info_param) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE); + axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env)); + return NULL; + } + + axutil_allocator_switch_to_global_pool(env->allocator); + + axutil_class_loader_init(env); + + impl_class = axutil_class_loader_create_dll(env, impl_info_param); + + if(impl_class) + { + AXIS2_SVC_SKELETON_INIT((axis2_svc_skeleton_t *)impl_class, env); + } + + axis2_svc_set_impl_class(svc, env, impl_class); + + axutil_allocator_switch_to_local_pool(env->allocator); + axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env)); + return impl_class; + } +} + +/*AXIS2_EXPORT axis2_svc_skeleton_t *AXIS2_CALL +axis2_msg_recv_get_impl_obj( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + struct axis2_msg_ctx * msg_ctx) +{ + struct axis2_svc *svc = NULL; + struct axis2_op_ctx *op_ctx = NULL; + struct axis2_svc_ctx *svc_ctx = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); + svc = axis2_svc_ctx_get_svc(svc_ctx, env); + if(!svc) + { + return NULL; + } + + return axis2_msg_recv_make_new_svc_obj(msg_recv, env, msg_ctx); +}*/ + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_set_scope( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + const axis2_char_t * scope) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, scope, AXIS2_FAILURE); + + if(msg_recv->scope) + { + AXIS2_FREE(env->allocator, msg_recv->scope); + } + msg_recv->scope = axutil_strdup(env, scope); + if(!msg_recv->scope) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT axis2_char_t *AXIS2_CALL +axis2_msg_recv_get_scope( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env) +{ + return msg_recv->scope; +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_delete_svc_obj( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_svc_t *svc = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axutil_param_t *impl_info_param = NULL; + axutil_param_t *scope_param = NULL; + axis2_char_t *param_value = NULL; + axutil_dll_desc_t *dll_desc = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); + svc = axis2_svc_ctx_get_svc(svc_ctx, env); + if(!svc) + { + return AXIS2_FAILURE; + } + + scope_param = axis2_svc_get_param(svc, env, AXIS2_SCOPE); + if(scope_param) + { + param_value = axutil_param_get_value(scope_param, env); + } + if(param_value && (0 == axutil_strcmp(AXIS2_APPLICATION_SCOPE, param_value))) + { + return AXIS2_SUCCESS; + } + + impl_info_param = axis2_svc_get_param(svc, env, AXIS2_SERVICE_CLASS); + if(!impl_info_param) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + dll_desc = axutil_param_get_value(impl_info_param, env); + return axutil_class_loader_delete_dll(env, dll_desc); +} + +static axis2_status_t AXIS2_CALL +axis2_msg_recv_receive_impl( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + void *callback_recv_param) +{ + axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_engine_t *engine = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "[axis2]Entry:axis2_msg_recv_receive_impl"); + out_msg_ctx = axis2_core_utils_create_out_msg_ctx(env, msg_ctx); + if(!out_msg_ctx) + { + return AXIS2_FAILURE; + } + op_ctx = axis2_msg_ctx_get_op_ctx(out_msg_ctx, env); + if(!op_ctx) + { + axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx); + axis2_msg_ctx_free(out_msg_ctx, env); + return AXIS2_FAILURE; + } + + status = axis2_op_ctx_add_msg_ctx(op_ctx, env, out_msg_ctx); + if(!status) + { + axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx); + axis2_msg_ctx_free(out_msg_ctx, env); + return status; + } + status = axis2_op_ctx_add_msg_ctx(op_ctx, env, msg_ctx); + + if(!status) + { + return status; + } + + status = axis2_msg_recv_invoke_business_logic(msg_recv, env, msg_ctx, out_msg_ctx); + if(AXIS2_SUCCESS != status) + { + axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx); + axis2_msg_ctx_free(out_msg_ctx, env); + return status; + } + svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); + conf_ctx = axis2_svc_ctx_get_conf_ctx(svc_ctx, env); + engine = axis2_engine_create(env, conf_ctx); + if(!engine) + { + axis2_msg_ctx_free(out_msg_ctx, env); + return AXIS2_FAILURE; + } + if(axis2_msg_ctx_get_soap_envelope(out_msg_ctx, env)) + { + axiom_soap_envelope_t *soap_envelope = axis2_msg_ctx_get_soap_envelope(out_msg_ctx, env); + if(soap_envelope) + { + axiom_soap_body_t *body = axiom_soap_envelope_get_body(soap_envelope, env); + if(body) + { + /* in case of a SOAP fault, we got to return failure so that + transport gets to know that it should send 500 */ + if(axiom_soap_body_has_fault(body, env)) + { + status = AXIS2_FAILURE; + axis2_msg_ctx_set_fault_soap_envelope(msg_ctx, env, soap_envelope); + axis2_msg_ctx_set_soap_envelope(out_msg_ctx, env, NULL); + } + else + { + /* if it is two way and not a fault then send through engine. + if it is one way we do not need to do an engine send */ + status = axis2_engine_send(engine, env, out_msg_ctx); + } + } + } + } + axis2_engine_free(engine, env); + + /* Reset the out message context to avoid double freeing at http worker. For example if this is + * not done here both in and out message context will try to free the transport out stream + * which will result in memory corruption. + */ + if(!axis2_msg_ctx_is_paused(out_msg_ctx, env) && !axis2_msg_ctx_is_keep_alive(out_msg_ctx, env)) + { + axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx); + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "[axis2]Exit:axis2_msg_recv_receive_impl"); + return status; +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_set_invoke_business_logic( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + AXIS2_MSG_RECV_INVOKE_BUSINESS_LOGIC func) +{ + msg_recv->invoke_business_logic = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_invoke_business_logic( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + struct axis2_msg_ctx * in_msg_ctx, + struct axis2_msg_ctx * out_msg_ctx) +{ + return msg_recv->invoke_business_logic(msg_recv, env, in_msg_ctx, out_msg_ctx); +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_set_derived( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + void *derived) +{ + msg_recv->derived = derived; + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT void *AXIS2_CALL +axis2_msg_recv_get_derived( + const axis2_msg_recv_t * msg_recv, + const axutil_env_t * env) +{ + return msg_recv->derived; +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_set_receive( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + AXIS2_MSG_RECV_RECEIVE func) +{ + msg_recv->receive = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_receive( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + void *callback_recv_param) +{ + return msg_recv->receive(msg_recv, env, msg_ctx, callback_recv_param); +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_set_load_and_init_svc( + axis2_msg_recv_t *msg_recv, + const axutil_env_t *env, + AXIS2_MSG_RECV_LOAD_AND_INIT_SVC func) +{ + msg_recv->load_and_init_svc = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_msg_recv_load_and_init_svc( + axis2_msg_recv_t *msg_recv, + const axutil_env_t *env, + struct axis2_svc *svc) +{ + if(msg_recv->load_and_init_svc) + { + return msg_recv->load_and_init_svc(msg_recv, env, svc); + } + else + { + /* message receivers without physical service (e.g : programatical service injection) */ + return AXIS2_SUCCESS; + } +} +AXIS2_EXPORT void AXIS2_CALL + axis2_msg_recv_set_conf_ctx(axis2_msg_recv_t *msg_recv, + const axutil_env_t *env, + struct axis2_conf_ctx *conf_ctx) +{ + msg_recv->conf_ctx = conf_ctx; +} + +AXIS2_EXPORT struct axis2_conf_ctx* AXIS2_CALL +axis2_msg_recv_get_conf_ctx( + axis2_msg_recv_t *msg_recv, + const axutil_env_t *env) +{ + if(msg_recv) + return msg_recv->conf_ctx; + return NULL; +} diff --git a/src/core/receivers/raw_xml_in_out_msg_recv.c b/src/core/receivers/raw_xml_in_out_msg_recv.c new file mode 100644 index 0000000..4bb2de8 --- /dev/null +++ b/src/core/receivers/raw_xml_in_out_msg_recv.c @@ -0,0 +1,442 @@ +/* + * 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_raw_xml_in_out_msg_recv.h> +#include <string.h> +#include <axiom_element.h> +#include <axiom_soap_envelope.h> +#include <axiom_soap_header.h> +#include <axiom_soap_body.h> +#include <axiom_soap_fault.h> +#include <axiom_soap.h> + +static axis2_status_t AXIS2_CALL +axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_msg_ctx_t * new_msg_ctx); + +AXIS2_EXTERN axis2_msg_recv_t *AXIS2_CALL +axis2_raw_xml_in_out_msg_recv_create( + const axutil_env_t * env) +{ + axis2_msg_recv_t *msg_recv = NULL; + axis2_status_t status = AXIS2_FAILURE; + + msg_recv = axis2_msg_recv_create(env); + if(!msg_recv) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + status = axis2_msg_recv_set_scope(msg_recv, env, AXIS2_APPLICATION_SCOPE); + if(!status) + { + axis2_msg_recv_free(msg_recv, env); + return NULL; + } + + axis2_msg_recv_set_invoke_business_logic(msg_recv, env, + axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync); + + return msg_recv; +} + +static axis2_status_t AXIS2_CALL +axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync( + axis2_msg_recv_t * msg_recv, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_msg_ctx_t * new_msg_ctx) +{ + axis2_svc_skeleton_t *svc_obj = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_op_t *op_desc = NULL; + const axis2_char_t *style = NULL; + axiom_node_t *om_node = NULL; + axiom_element_t *om_element = NULL; + axis2_char_t *local_name = NULL; + axiom_node_t *result_node = NULL; + axiom_node_t *body_content_node = NULL; + axiom_element_t *body_content_element = NULL; + axiom_soap_envelope_t *default_envelope = NULL; + axiom_soap_body_t *out_body = NULL; + axiom_soap_header_t *out_header = NULL; + axiom_soap_fault_t *soap_fault = NULL; + axiom_node_t *out_node = NULL; + axis2_status_t status = AXIS2_SUCCESS; + axis2_bool_t skel_invoked = AXIS2_FALSE; + const axis2_char_t *soap_ns = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + int soap_version = AXIOM_SOAP12; + axiom_namespace_t *env_ns = NULL; + axiom_node_t *fault_node = NULL; + axiom_soap_fault_detail_t *fault_detail; + axis2_bool_t is_fault = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, new_msg_ctx, AXIS2_FAILURE); + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "[axis2]Entry:axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync"); + + /* get the implementation class for the Web Service */ + svc_obj = axis2_msg_recv_make_new_svc_obj(msg_recv, env, msg_ctx); + + if(!svc_obj) + { + const axis2_char_t *svc_name = NULL; + axis2_svc_t *svc = axis2_msg_ctx_get_svc(msg_ctx, env); + + if(svc) + { + svc_name = axis2_svc_get_name(svc, env); + } + else + { + svc_name = "unknown"; + } + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Impl object for service '%s' not set in message receiver. %d :: %s", svc_name, + env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error)); + + status = AXIS2_FAILURE; + } + else + { + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + op_desc = axis2_op_ctx_get_op(op_ctx, env); + + style = axis2_op_get_style(op_desc, env); + if(0 == axutil_strcmp(AXIS2_STYLE_DOC, style)) + { + axiom_soap_envelope_t *envelope = NULL; + axiom_soap_body_t *body = NULL; + + envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + body = axiom_soap_envelope_get_body(envelope, env); + om_node = axiom_soap_body_get_base_node(body, env); + om_element = axiom_node_get_data_element(om_node, env); + om_node = axiom_node_get_first_element(om_node, env); + } + else if(0 == axutil_strcmp(AXIS2_STYLE_RPC, style)) + { + axiom_soap_envelope_t *envelope = NULL; + axiom_soap_body_t *body = NULL; + axiom_node_t *op_node = NULL; + axiom_element_t *op_element = NULL; + + envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + body = axiom_soap_envelope_get_body(envelope, env); + op_node = axiom_soap_body_get_base_node(body, env); + op_element = axiom_node_get_data_element(op_node, env); + if(op_element) + { + local_name = axiom_element_get_localname(op_element, env); + if(local_name) + { + axutil_array_list_t *function_arr = NULL; + int i = 0; + int size = 0; + axis2_bool_t matches = AXIS2_FALSE; + + function_arr = svc_obj->func_array; + if(function_arr) + { + size = axutil_array_list_size(function_arr, env); + } + + for(i = 0; i < size; i++) + { + axis2_char_t *function_name = NULL; + + function_name = (axis2_char_t *)axutil_array_list_get(function_arr, env, i); + if(!axutil_strcmp(function_name, local_name)) + { + matches = AXIS2_TRUE; + + } + } + + if(matches) + { + om_node = axiom_node_get_first_child(op_node, env); + om_element = axiom_node_get_data_element(om_node, env); + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_OM_ELEMENT_MISMATCH, AXIS2_FAILURE); + status = AXIS2_FAILURE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_OM_ELEMENT_INVALID_STATE, AXIS2_FAILURE); + status = AXIS2_FAILURE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_RPC_NEED_MATCHING_CHILD, AXIS2_FAILURE); + status = AXIS2_FAILURE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_UNKNOWN_STYLE, AXIS2_FAILURE); + status = AXIS2_FAILURE; + } + + if(status == AXIS2_SUCCESS) + { + skel_invoked = AXIS2_TRUE; + result_node = AXIS2_SVC_SKELETON_INVOKE(svc_obj, env, om_node, new_msg_ctx); + } + + if(result_node) + { + if(0 == axutil_strcmp(style, AXIS2_STYLE_RPC)) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *res_name = NULL; + + res_name = axutil_stracat(env, local_name, "Response"); + ns = axiom_namespace_create(env, "http://soapenc/", "res"); + if(!ns) + { + status = AXIS2_FAILURE; + } + else + { + body_content_element = axiom_element_create(env, NULL, res_name, ns, + &body_content_node); + axiom_node_add_child(body_content_node, env, result_node); + } + } + else + { + body_content_node = result_node; + } + } + else + { + axis2_char_t *mep = (axis2_char_t *)axis2_op_get_msg_exchange_pattern(op_desc, env); + if(axutil_strcmp(mep, AXIS2_MEP_URI_IN_ONLY) && axutil_strcmp(mep, + AXIS2_MEP_URI_ROBUST_IN_ONLY)) + { + status = AXIS2_ERROR_GET_STATUS_CODE(env->error); + if(status == AXIS2_SUCCESS) + { + axis2_msg_ctx_set_no_content(new_msg_ctx, env, AXIS2_TRUE); + } + else + { + axis2_msg_ctx_set_status_code(msg_ctx, env, axis2_msg_ctx_get_status_code( + new_msg_ctx, env)); + } + /* The new_msg_ctx is passed to the service. The status code must + * be taken from here and set to the old message context which is + * used by the worker when the request processing fails. + */ + if(svc_obj->ops->on_fault) + { + fault_node = AXIS2_SVC_SKELETON_ON_FAULT(svc_obj, env, om_node); + } + is_fault = AXIS2_TRUE; + } + else + { + /* If we have a in only message result node is NULL. We create fault only if + * an error is set + */ + status = AXIS2_ERROR_GET_STATUS_CODE(env->error); + if(status == AXIS2_SUCCESS) + { + axis2_msg_ctx_set_no_content(new_msg_ctx, env, AXIS2_TRUE); + } + else + { + axis2_msg_ctx_set_status_code(msg_ctx, env, axis2_msg_ctx_get_status_code( + new_msg_ctx, env)); + if(!axutil_strcmp(mep, AXIS2_MEP_URI_ROBUST_IN_ONLY)) + { + /* The new_msg_ctx is passed to the service. The status code must + * be taken from here and set to the old message context which is + * used by the worker when the request processing fails. + */ + if(svc_obj->ops->on_fault) + { + fault_node = AXIS2_SVC_SKELETON_ON_FAULT(svc_obj, env, om_node); + } + is_fault = AXIS2_TRUE; + } + } + } + } + } + + if(msg_ctx && axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + soap_ns = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; /* default is 1.2 */ + soap_version = AXIOM_SOAP11; + } + + if(axis2_msg_ctx_get_soap_envelope(new_msg_ctx, env)) + { + /* service implementation has set the envelope, + useful when setting a SOAP fault. + No need to further process */ + return AXIS2_SUCCESS; + } + + /* create the soap envelope here */ + env_ns = axiom_namespace_create(env, soap_ns, "soapenv"); + if(!env_ns) + { + return AXIS2_FAILURE; + } + + default_envelope = axiom_soap_envelope_create(env, env_ns); + + if(!default_envelope) + { + return AXIS2_FAILURE; + } + + out_header = axiom_soap_header_create_with_parent(env, default_envelope); + if(!out_header) + { + return AXIS2_FAILURE; + } + + out_body = axiom_soap_body_create_with_parent(env, default_envelope); + if(!out_body) + { + return AXIS2_FAILURE; + } + + out_node = axiom_soap_body_get_base_node(out_body, env); + if(!out_node) + { + return AXIS2_FAILURE; + } + + if(status != AXIS2_SUCCESS || is_fault) + { + /* something went wrong. set a SOAP Fault */ + const axis2_char_t *fault_value_str = "soapenv:Sender"; + const axis2_char_t *fault_reason_str = NULL; + const axis2_char_t *err_msg = NULL; + + if(!skel_invoked) + { + if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { +fault_value_str = + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" + AXIOM_SOAP11_FAULT_CODE_RECEIVER; + } + else + { + fault_value_str = + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" + AXIOM_SOAP12_SOAP_FAULT_VALUE_RECEIVER; + } + } + + err_msg = AXIS2_ERROR_GET_MESSAGE(env->error); + if (err_msg && axutil_strcmp(err_msg, "")) + { + if(!axutil_strcmp(err_msg, "No Error")) + { + fault_reason_str = "An error has occurred, but could not determine exact details"; + } + else + { + fault_reason_str = err_msg; + } + } + else + { + fault_reason_str = "An error has occurred, but could not determine exact details"; + } + + soap_fault = axiom_soap_fault_create_default_fault(env, out_body, fault_value_str, + fault_reason_str, soap_version); + + if (fault_node) + { + axiom_node_t *fault_detail_node = NULL; + + fault_detail = axiom_soap_fault_detail_create_with_parent(env, soap_fault); + fault_detail_node = axiom_soap_fault_detail_get_base_node(fault_detail, env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "fault_detail:%s", axiom_node_to_string( + fault_detail_node, env)); + + axiom_soap_fault_detail_add_detail_entry(fault_detail, env, fault_node); + } +} + +if (body_content_node) +{ + axiom_node_add_child(out_node, env, body_content_node); + status = axis2_msg_ctx_set_soap_envelope(new_msg_ctx, env, default_envelope); +} +else if (soap_fault) +{ + axis2_msg_ctx_set_soap_envelope(new_msg_ctx, env, default_envelope); + status = AXIS2_SUCCESS; +} +else +{ + /* we should free the memory as the envelope is not used, one way case */ + axiom_soap_envelope_free(default_envelope, env); + default_envelope = NULL; +} + +AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, + "[axis2]Exit:axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync"); + +return status; +} + +AXIS2_EXPORT int +axis2_get_instance( + struct axis2_msg_recv **inst, + const axutil_env_t * env) +{ + *inst = axis2_raw_xml_in_out_msg_recv_create(env); + if(!(*inst)) + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT int +axis2_remove_instance( + struct axis2_msg_recv *inst, + const axutil_env_t * env) +{ + if(inst) + { + axis2_msg_recv_free(inst, env); + } + return AXIS2_SUCCESS; +} diff --git a/src/core/receivers/svr_callback.c b/src/core/receivers/svr_callback.c new file mode 100644 index 0000000..2fe68b1 --- /dev/null +++ b/src/core/receivers/svr_callback.c @@ -0,0 +1,112 @@ +/* + * 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_svr_callback.h> +#include <axis2_engine.h> + +struct axis2_svr_callback +{ + axis2_char_t *scope; +}; + +AXIS2_EXPORT axis2_svr_callback_t *AXIS2_CALL +axis2_svr_callback_create( + const axutil_env_t * env) +{ + axis2_svr_callback_t *svr_callback = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + svr_callback = (axis2_svr_callback_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_svr_callback_t)); + + if(!svr_callback) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return svr_callback; +} + +AXIS2_EXPORT void AXIS2_CALL +axis2_svr_callback_free( + axis2_svr_callback_t * svr_callback, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(svr_callback) + { + AXIS2_FREE(env->allocator, svr_callback); + } + + return; +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_svr_callback_handle_result( + axis2_svr_callback_t * svr_callback, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_engine_t *engine = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_op_ctx_t *op_ctx = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); + conf_ctx = axis2_svc_ctx_get_conf_ctx(svc_ctx, env); + engine = axis2_engine_create(env, conf_ctx); + if(!engine) + { + return AXIS2_FAILURE; + } + return axis2_engine_send(engine, env, msg_ctx); +} + +AXIS2_EXPORT axis2_status_t AXIS2_CALL +axis2_svr_callback_handle_fault( + axis2_svr_callback_t * svr_callback, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_engine_t *engine = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_msg_ctx_t *fault_ctx = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); + conf_ctx = axis2_svc_ctx_get_conf_ctx(svc_ctx, env); + engine = axis2_engine_create(env, conf_ctx); + if(!engine) + { + return AXIS2_FAILURE; + } + + fault_ctx = axis2_engine_create_fault_msg_ctx(engine, env, msg_ctx, NULL, NULL); + return axis2_engine_send_fault(engine, env, fault_ctx); +} diff --git a/src/core/transport/Makefile.am b/src/core/transport/Makefile.am new file mode 100644 index 0000000..eff5f72 --- /dev/null +++ b/src/core/transport/Makefile.am @@ -0,0 +1,8 @@ +SUBDIRS=http $(TCP_DIR) $(AMQP_DIR) +DIST_SUBDIRS=http tcp amqp +EXTRA_DIST=Makefile.am amqp/server/axis2_amqp_server/axis2_amqp_server.h \ +amqp/receiver/axis2_amqp_receiver.h amqp/receiver/qpid_receiver/axis2_qpid_receiver.h \ +amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.h amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.h \ +amqp/util/axis2_amqp_defines.h amqp/util/axis2_amqp_util.h amqp/sender/qpid_sender/axis2_qpid_sender_interface.h \ +amqp/sender/qpid_sender/axis2_qpid_sender.h amqp/sender/axis2_amqp_sender.h + diff --git a/src/core/transport/amqp/Makefile.am b/src/core/transport/amqp/Makefile.am new file mode 100644 index 0000000..ca5e58d --- /dev/null +++ b/src/core/transport/amqp/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = util \
+ receiver \
+ server \
+ sender
diff --git a/src/core/transport/amqp/receiver/Makefile.am b/src/core/transport/amqp/receiver/Makefile.am new file mode 100644 index 0000000..4e16b0f --- /dev/null +++ b/src/core/transport/amqp/receiver/Makefile.am @@ -0,0 +1,25 @@ +SUBDIRS = qpid_receiver
+
+lib_LTLIBRARIES = libaxis2_amqp_receiver.la
+
+libaxis2_amqp_receiver_la_SOURCES = axis2_amqp_receiver.c
+
+libaxis2_amqp_receiver_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \
+ $(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver/libaxis2_qpid_receiver.la
+
+libaxis2_amqp_receiver_la_LDFLAGS = -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport/amqp/util \
+ -I$(top_builddir)/src/core/transport/amqp/receiver \
+ -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \
+ -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
+
diff --git a/src/core/transport/amqp/receiver/axis2_amqp_receiver.c b/src/core/transport/amqp/receiver/axis2_amqp_receiver.c new file mode 100644 index 0000000..5ff69af --- /dev/null +++ b/src/core/transport/amqp/receiver/axis2_amqp_receiver.c @@ -0,0 +1,275 @@ +/*
+ * 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_amqp_util.h>
+#include <axis2_amqp_defines.h>
+#include <axis2_amqp_receiver.h>
+
+static const axis2_transport_receiver_ops_t amqp_receiver_ops =
+{
+ axis2_amqp_receiver_init,
+ axis2_amqp_receiver_start,
+ axis2_amqp_receiver_get_reply_to_epr,
+ axis2_amqp_receiver_get_conf_ctx,
+ axis2_amqp_receiver_is_running,
+ axis2_amqp_receiver_stop,
+ axis2_amqp_receiver_free
+};
+
+AXIS2_EXTERN axis2_transport_receiver_t* AXIS2_CALL
+axis2_amqp_receiver_create(
+ const axutil_env_t* env,
+ const axis2_char_t* repo,
+ const axis2_char_t* qpid_broker_ip,
+ int qpid_broker_port)
+{
+ AXIS2_ENV_CHECK(env, NULL);
+
+ axis2_amqp_receiver_resource_pack_t* receiver_resource_pack = NULL;
+
+ receiver_resource_pack = (axis2_amqp_receiver_resource_pack_t*)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_amqp_receiver_resource_pack_t));
+
+ if(!receiver_resource_pack)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ receiver_resource_pack->receiver.ops = &amqp_receiver_ops;
+ receiver_resource_pack->qpid_receiver = NULL;
+ receiver_resource_pack->conf_ctx = NULL;
+ receiver_resource_pack->conf_ctx_private = NULL;
+
+ if(repo)
+ {
+ /**
+ * 1. We first create a private conf ctx which is owned by this server
+ * we only free this private conf context. We should never free the
+ * receiver_impl->conf_ctx because it may be owned by any other object which
+ * may lead to double free.
+ *
+ * 2. The Qpid broker IP and port are set in conf_ctx at two different places.
+ * If the repo is specified, they are set here. Otherwise, they are set
+ * in axis2_amqp_receiver_init method.
+ */
+ axutil_property_t* property = NULL;
+ const axis2_char_t* broker_ip = NULL;
+ int* broker_port = (int*)AXIS2_MALLOC(env->allocator, sizeof(int));
+ *broker_port = AXIS2_QPID_NULL_CONF_INT;
+
+ receiver_resource_pack->conf_ctx_private = axis2_build_conf_ctx(env, repo);
+ if(!receiver_resource_pack->conf_ctx_private)
+ {
+ axis2_amqp_receiver_free((axis2_transport_receiver_t *)receiver_resource_pack, env);
+ return NULL;
+ }
+
+ /* Set broker IP */
+ broker_ip = qpid_broker_ip ? qpid_broker_ip : AXIS2_QPID_DEFAULT_BROKER_IP;
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0,
+ (void*)broker_ip);
+ axis2_conf_ctx_set_property(receiver_resource_pack->conf_ctx_private, env,
+ AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP, property);
+
+ /* Set broker port */
+ *broker_port = (qpid_broker_port != AXIS2_QPID_NULL_CONF_INT) ? qpid_broker_port
+ : AXIS2_QPID_DEFAULT_BROKER_PORT;
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0,
+ (void*)broker_port);
+ axis2_conf_ctx_set_property(receiver_resource_pack->conf_ctx_private, env,
+ AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT, property);
+
+ receiver_resource_pack->conf_ctx = receiver_resource_pack->conf_ctx_private;
+ }
+
+ return &(receiver_resource_pack->receiver);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_receiver_init(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx,
+ axis2_transport_in_desc_t* in_desc)
+{
+ axis2_amqp_receiver_resource_pack_t* receiver_resource_pack = NULL;
+ axutil_property_t* property = NULL;
+ const axis2_char_t* broker_ip = NULL;
+ int* broker_port = (int*)AXIS2_MALLOC(env->allocator, sizeof(int));
+ *broker_port = AXIS2_QPID_NULL_CONF_INT;
+
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+
+ receiver_resource_pack = AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(receiver);
+ receiver_resource_pack->conf_ctx = conf_ctx;
+
+ /* Set broker IP */
+ broker_ip = axis2_amqp_util_get_in_desc_conf_value_string(in_desc, env,
+ AXIS2_AMQP_CONF_QPID_BROKER_IP);
+ if(!broker_ip)
+ {
+ broker_ip = AXIS2_QPID_DEFAULT_BROKER_IP;
+ }
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0,
+ (void*)broker_ip);
+ axis2_conf_ctx_set_property(receiver_resource_pack->conf_ctx, env,
+ AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP, property);
+
+ /* Set broker port */
+ *broker_port = axis2_amqp_util_get_in_desc_conf_value_int(in_desc, env,
+ AXIS2_AMQP_CONF_QPID_BROKER_PORT);
+ if(*broker_port == AXIS2_QPID_NULL_CONF_INT)
+ {
+ *broker_port = AXIS2_QPID_DEFAULT_BROKER_PORT;
+ }
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0,
+ (void*)broker_port);
+ axis2_conf_ctx_set_property(receiver_resource_pack->conf_ctx, env,
+ AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT, property);
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_receiver_start(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+
+ axis2_status_t status = AXIS2_FAILURE;
+
+ axis2_amqp_receiver_resource_pack_t* amqp_receiver_resource_pack = NULL;
+ axis2_qpid_receiver_resource_pack_t* qpid_receiver_resource_pack = NULL;
+
+ amqp_receiver_resource_pack = AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(receiver);
+
+ /* Create Qpid Receiver */
+ qpid_receiver_resource_pack = axis2_qpid_receiver_create(env,
+ amqp_receiver_resource_pack->conf_ctx);
+
+ if(qpid_receiver_resource_pack)
+ {
+ amqp_receiver_resource_pack->qpid_receiver = qpid_receiver_resource_pack;
+
+ status = axis2_qpid_receiver_start(qpid_receiver_resource_pack, env);
+ }
+
+ return status;
+}
+
+AXIS2_EXTERN axis2_endpoint_ref_t* AXIS2_CALL
+axis2_amqp_receiver_get_reply_to_epr(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env,
+ const axis2_char_t* svc_name)
+{
+ return NULL;
+}
+
+AXIS2_EXTERN axis2_conf_ctx_t* AXIS2_CALL
+axis2_amqp_receiver_get_conf_ctx(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env)
+{
+ AXIS2_ENV_CHECK(env, NULL);
+
+ return AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(receiver)->conf_ctx;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_amqp_receiver_is_running(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env)
+{
+ return AXIS2_TRUE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_receiver_stop(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env)
+{
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_amqp_receiver_free(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env)
+{
+ AXIS2_ENV_CHECK(env, void);
+
+ axis2_amqp_receiver_resource_pack_t* receiver_resource_pack = NULL;
+ receiver_resource_pack = AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(receiver);
+
+ if(receiver_resource_pack->qpid_receiver)
+ {
+ axis2_qpid_receiver_free(receiver_resource_pack->qpid_receiver, env);
+ receiver_resource_pack->qpid_receiver = NULL;
+ }
+
+ if(receiver_resource_pack->conf_ctx_private)
+ {
+ axis2_conf_ctx_free(receiver_resource_pack->conf_ctx_private, env);
+ receiver_resource_pack->conf_ctx_private = NULL;
+ }
+
+ receiver_resource_pack->conf_ctx = NULL; /* Do not free this. It may be owned by some other object */
+
+ AXIS2_FREE(env->allocator, receiver_resource_pack);
+}
+
+/* Library Exports */
+
+AXIS2_EXPORT int
+#ifndef AXIS2_STATIC_DEPLOY
+axis2_get_instance(
+#else
+ axis2_amqp_receiver_get_instance(
+#endif
+ struct axis2_transport_receiver** inst,
+ const axutil_env_t* env)
+{
+ int status = AXIS2_SUCCESS;
+
+ *inst = axis2_amqp_receiver_create(env, NULL, NULL, AXIS2_QPID_NULL_CONF_INT);
+ if(!(*inst))
+ {
+ status = AXIS2_FAILURE;
+ }
+
+ return status;
+}
+
+AXIS2_EXPORT int
+#ifndef AXIS2_STATIC_DEPLOY
+axis2_remove_instance(
+#else
+ axis2_amqp_receiver_remove_instance(
+#endif
+ axis2_transport_receiver_t* inst,
+ const axutil_env_t* env)
+{
+ if(inst)
+ {
+ axis2_transport_receiver_free(inst, env);
+ }
+
+ return AXIS2_SUCCESS;
+}
diff --git a/src/core/transport/amqp/receiver/axis2_amqp_receiver.h b/src/core/transport/amqp/receiver/axis2_amqp_receiver.h new file mode 100644 index 0000000..209e2bb --- /dev/null +++ b/src/core/transport/amqp/receiver/axis2_amqp_receiver.h @@ -0,0 +1,82 @@ +/*
+* 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_AMQP_RECEIVER_H
+#define AXIS2_AMQP_RECEIVER_H
+
+#include <axis2_transport_receiver.h>
+#include <axis2_conf_init.h>
+#include <axis2_qpid_receiver_interface.h>
+
+typedef struct axis2_amqp_receiver_resource_pack
+{
+ axis2_transport_receiver_t receiver;
+ axis2_qpid_receiver_resource_pack_t* qpid_receiver;
+ axis2_conf_ctx_t* conf_ctx;
+ axis2_conf_ctx_t* conf_ctx_private;
+}
+axis2_amqp_receiver_resource_pack_t;
+
+#define AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(amqp_receiver) \
+ ((axis2_amqp_receiver_resource_pack_t*)(amqp_receiver))
+
+AXIS2_EXTERN axis2_transport_receiver_t* AXIS2_CALL
+axis2_amqp_receiver_create(
+ const axutil_env_t* env,
+ const axis2_char_t* repo,
+ const axis2_char_t* qpid_broker_ip,
+ int qpid_broker_port);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_receiver_init(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx,
+ axis2_transport_in_desc_t* in_desc);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_receiver_start(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env);
+
+AXIS2_EXTERN axis2_endpoint_ref_t* AXIS2_CALL
+axis2_amqp_receiver_get_reply_to_epr(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env,
+ const axis2_char_t* svc_name);
+
+AXIS2_EXTERN axis2_conf_ctx_t* AXIS2_CALL
+axis2_amqp_receiver_get_conf_ctx(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env);
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_amqp_receiver_is_running(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_receiver_stop(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env);
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_amqp_receiver_free(
+ axis2_transport_receiver_t* receiver,
+ const axutil_env_t* env);
+
+#endif
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/Makefile.am b/src/core/transport/amqp/receiver/qpid_receiver/Makefile.am new file mode 100644 index 0000000..3ecdf34 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/Makefile.am @@ -0,0 +1,29 @@ +SUBDIRS = request_processor
+
+lib_LTLIBRARIES = libaxis2_qpid_receiver.la
+
+libaxis2_qpid_receiver_la_SOURCES = axis2_qpid_receiver.cpp \
+ axis2_qpid_receiver_interface.cpp \
+ axis2_qpid_receiver_listener.cpp
+
+libaxis2_qpid_receiver_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \
+ $(QPID_HOME)/lib/libqpidclient.la \
+ $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \
+ $(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver/request_processor/libaxis2_amqp_request_processor.la
+
+libaxis2_qpid_receiver_la_LDFLAGS = g++ -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver \
+ -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver/request_processor \
+ -I$(top_builddir)/src/core/transport/amqp/util \
+ -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include \
+ -I$(QPID_HOME)/include
+
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.cpp b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.cpp new file mode 100644 index 0000000..140ab0e --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.cpp @@ -0,0 +1,167 @@ +/*
+ * 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
+ *
+ * tcp://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 <qpid/client/Connection.h>
+#include <qpid/client/Session.h>
+#include <qpid/client/SubscriptionManager.h>
+#include <axis2_amqp_request_processor.h>
+#include <axis2_amqp_defines.h>
+#include <axis2_amqp_util.h>
+#include <axis2_qpid_receiver_listener.h>
+#include <axis2_qpid_receiver.h>
+#include <list>
+
+Axis2QpidReceiver::Axis2QpidReceiver(
+ const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx)
+{
+ this->env = env;
+ this->conf_ctx = conf_ctx;
+}
+
+Axis2QpidReceiver::~Axis2QpidReceiver(
+ void)
+{
+}
+
+bool
+Axis2QpidReceiver::start(
+ void)
+{
+ if(!conf_ctx)
+ return false;
+
+ Connection connection;
+ axis2_bool_t serverSide = AXIS2_TRUE;
+
+ serverSide = axis2_amqp_util_conf_ctx_get_server_side(conf_ctx, env);
+
+ while(true)
+ {
+ try
+ {
+ std::list<string> queueNameList;
+ string qpidBrokerIP = axis2_amqp_util_conf_ctx_get_qpid_broker_ip(conf_ctx, env);
+ int qpidBrokerPort = axis2_amqp_util_conf_ctx_get_qpid_broker_port(conf_ctx, env);
+
+ /* Check if Client Side and Resolve Dynamic Queue Name */
+ if(serverSide == AXIS2_TRUE) /* Server side */
+ {
+ std::cout << "Connecting to Qpid Broker on " << qpidBrokerIP << ":"
+ << qpidBrokerPort << " ... ";
+ }
+
+ /* Create Connection to Qpid Broker */
+ connection.open(qpidBrokerIP, qpidBrokerPort);
+
+ if(serverSide == AXIS2_TRUE) /* Server side */
+ {
+ /* Create queue for each service. Queue name is equal to service name */
+ axis2_conf_t* conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(!conf)
+ return false;
+
+ axutil_hash_t* serviceMap = axis2_conf_get_all_svcs(conf, env);
+ if(!serviceMap)
+ return false;
+
+ axutil_hash_index_t* serviceHI = NULL;
+ void* serviceValue = NULL;
+
+ for(serviceHI = axutil_hash_first(serviceMap, env); serviceHI; serviceHI
+ = axutil_hash_next(env, serviceHI))
+ {
+ axutil_hash_this(serviceHI, NULL, NULL, &serviceValue);
+
+ axis2_svc_t* service = (axis2_svc_t*)serviceValue;
+ if(!service)
+ return false;
+
+ axis2_char_t* serviceName = axutil_qname_get_localpart(axis2_svc_get_qname(
+ service, env), env);
+ if(!serviceName)
+ return false;
+
+ queueNameList.push_back(serviceName);
+ }
+
+ std::cout << "CONNECTED" << std::endl;
+ }
+ else /* Client side separate listener in dual-channel case */
+ {
+ string queueName = axis2_amqp_util_conf_ctx_get_dual_channel_queue_name(conf_ctx,
+ env);
+
+ queueNameList.push_back(queueName);
+ }
+
+ /* Create new session */
+ Session session = connection.newSession();
+
+ /* Create Subscription manager */
+ SubscriptionManager subscriptionManager(session);
+
+ Axis2QpidReceiverListener qpidReceiverListener(env, conf_ctx);
+
+ /* Subscribe to queues */
+ while(!queueNameList.empty())
+ {
+ string queueName = queueNameList.front();
+
+ session.queueDeclare(arg::queue = queueName, arg::autoDelete = true);
+ session.exchangeBind(arg::exchange = AXIS2_AMQP_EXCHANGE_DIRECT, arg::queue
+ = queueName, arg::bindingKey = queueName);
+
+ subscriptionManager.subscribe(qpidReceiverListener, queueName);
+
+ queueNameList.pop_front();
+ }
+
+ /* Listen and Wait */
+ if(serverSide == AXIS2_TRUE) /* Server side */
+ {
+ std::cout << "Started Axis2 AMQP Server ..." << std::endl;
+ }
+
+ subscriptionManager.run();
+
+ return true;
+ }
+ catch(const std::exception& e)
+ {
+ connection.close();
+
+ if(serverSide == AXIS2_TRUE) /* Server side */
+ {
+ std::cout << "FAILED" << std::endl;
+ }
+
+ sleep(5);
+ }
+ }
+
+ connection.close();
+
+ return false;
+}
+
+bool
+Axis2QpidReceiver::shutdown(
+ void)
+{
+ return true;
+}
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.h b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.h new file mode 100644 index 0000000..66108d5 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.h @@ -0,0 +1,39 @@ +/*
+ * 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
+ *
+ * tcp://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_QPID_RECEIVER_H
+#define AXIS2_QPID_RECEIVER_H
+
+#include <axutil_env.h>
+#include <axis2_conf_init.h>
+
+class Axis2QpidReceiver
+{
+ public:
+ Axis2QpidReceiver(const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx);
+ ~Axis2QpidReceiver(void);
+
+ bool start(void);
+ bool shutdown(void);
+
+ private:
+ const axutil_env_t* env;
+ axis2_conf_ctx_t* conf_ctx;
+};
+
+#endif
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.cpp b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.cpp new file mode 100644 index 0000000..79faa86 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.cpp @@ -0,0 +1,102 @@ +/*
+* 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_qpid_receiver.h>
+#include <axis2_qpid_receiver_interface.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+AXIS2_EXTERN axis2_qpid_receiver_resource_pack_t* AXIS2_CALL
+axis2_qpid_receiver_create(
+ const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx)
+{
+ AXIS2_ENV_CHECK(env, NULL);
+
+ axis2_qpid_receiver_resource_pack_t* resource_pack = NULL;
+
+ resource_pack = (axis2_qpid_receiver_resource_pack_t*)AXIS2_MALLOC
+ (env->allocator, sizeof(axis2_qpid_receiver_resource_pack_t));
+
+ if (!resource_pack)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ /* Create Qpid Receiver */
+ Axis2QpidReceiver* qpid_receiver = new Axis2QpidReceiver(env, conf_ctx);
+
+ resource_pack->qpid_receiver = qpid_receiver;
+
+ return resource_pack;
+}
+
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_qpid_receiver_start(
+ axis2_qpid_receiver_resource_pack_t* receiver_resource_pack,
+ const axutil_env_t* env)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+
+ axis2_status_t status = AXIS2_FAILURE;
+
+ /* Start Qpid Receiver */
+ Axis2QpidReceiver* qpid_receiver = (Axis2QpidReceiver*)receiver_resource_pack->qpid_receiver;
+
+ if ((qpid_receiver) && (qpid_receiver->start()))
+ {
+ status = AXIS2_SUCCESS;
+ }
+
+ return status;
+}
+
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_qpid_receiver_is_running(
+ axis2_qpid_receiver_resource_pack_t* receiver_resource_pack,
+ const axutil_env_t* env)
+{
+ return AXIS2_TRUE;
+}
+
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_qpid_receiver_free(
+ axis2_qpid_receiver_resource_pack_t* receiver_resource_pack,
+ const axutil_env_t* env)
+{
+ AXIS2_ENV_CHECK(env, void);
+
+ if (receiver_resource_pack)
+ {
+ Axis2QpidReceiver* qpid_receiver = (Axis2QpidReceiver*)receiver_resource_pack->qpid_receiver;
+ if (qpid_receiver)
+ delete qpid_receiver;
+
+ AXIS2_FREE(env->allocator, receiver_resource_pack);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.h b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.h new file mode 100644 index 0000000..d141dfc --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.h @@ -0,0 +1,58 @@ +/*
+* 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_QPID_RECEIVER_INTERFACE_H
+#define AXIS2_QPID_RECEIVER_INTERFACE_H
+
+#include <axis2_util.h>
+#include <axis2_conf_init.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct axis2_qpid_receiver_resource_pack
+ {
+ void* qpid_receiver;
+ }axis2_qpid_receiver_resource_pack_t;
+
+ AXIS2_EXTERN axis2_qpid_receiver_resource_pack_t* AXIS2_CALL
+ axis2_qpid_receiver_create(
+ const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx);
+
+ AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axis2_qpid_receiver_start(
+ axis2_qpid_receiver_resource_pack_t* receiver_resource_pack,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+ axis2_qpid_receiver_is_running(
+ axis2_qpid_receiver_resource_pack_t* receiver_resource_pack,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN void AXIS2_CALL
+ axis2_qpid_receiver_free(
+ axis2_qpid_receiver_resource_pack_t* receiver_resource_pack,
+ const axutil_env_t* env);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.cpp b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.cpp new file mode 100644 index 0000000..63717ca --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.cpp @@ -0,0 +1,123 @@ +/*
+ * 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
+ *
+ * tcp://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_amqp_request_processor.h>
+#include <axis2_amqp_defines.h>
+#include <axis2_amqp_util.h>
+#include <axis2_qpid_receiver_listener.h>
+#include <axis2_qpid_receiver.h>
+#include <string>
+
+Axis2QpidReceiverListener::Axis2QpidReceiverListener(
+ const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx)
+{
+ this->env = env;
+ this->conf_ctx = conf_ctx;
+}
+
+Axis2QpidReceiverListener::~Axis2QpidReceiverListener(
+ void)
+{
+}
+
+void
+Axis2QpidReceiverListener::received(
+ Message& message)
+{
+ AXIS2_ENV_CHECK(env, void);
+
+ axis2_amqp_request_processor_resource_pack_t* request_data = NULL;
+#ifdef AXIS2_SVR_MULTI_THREADED
+ axutil_thread_t* worker_thread = NULL;
+#endif
+
+ request_data = (axis2_amqp_request_processor_resource_pack_t*)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_amqp_request_processor_resource_pack_t));
+
+ if(!request_data)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Memory Allocation Error");
+ return;
+ }
+
+ request_data->env = (axutil_env_t*)env;
+ request_data->conf_ctx = conf_ctx;
+
+ /* Create a Local Copy of Request Content */
+ std::string message_data = message.getData();
+ axis2_char_t* request_content =
+ (axis2_char_t*)AXIS2_MALLOC(env->allocator, message_data.size());
+ memcpy(request_content, message_data.c_str(), message_data.size());
+
+ request_data->request_content = request_content;
+ request_data->content_length = message_data.size();
+
+ /* Set ReplyTo */
+ request_data->reply_to = NULL;
+ if(message.getMessageProperties().hasReplyTo())
+ {
+ /* Create a Local Copy of ReplyTo */
+ std::string reply_to_tmp = message.getMessageProperties().getReplyTo().getRoutingKey();
+ axis2_char_t* reply_to = (axis2_char_t*)AXIS2_MALLOC(env->allocator, reply_to_tmp.size()
+ + 1);
+ strcpy(reply_to, reply_to_tmp.c_str());
+
+ request_data->reply_to = reply_to;
+ }
+
+ /* Copy AMQP headers */
+ /* Content-Type */
+ request_data->content_type = NULL;
+ std::string content_type_tmp = message.getHeaders().getAsString(AXIS2_AMQP_HEADER_CONTENT_TYPE);
+ if(!content_type_tmp.empty())
+ {
+ axis2_char_t* content_type = (axis2_char_t*)AXIS2_MALLOC(env->allocator,
+ content_type_tmp.size() + 1);
+ strcpy(content_type, content_type_tmp.c_str());
+
+ request_data->content_type = content_type;
+ }
+
+ /* SOAPAction */
+ request_data->soap_action = NULL;
+ std::string soap_action_tmp = message.getHeaders().getAsString(AXIS2_AMQP_HEADER_SOAP_ACTION);
+ if(!soap_action_tmp.empty())
+ {
+ axis2_char_t* soap_action = (axis2_char_t*)AXIS2_MALLOC(env->allocator,
+ soap_action_tmp.size() + 1);
+ strcpy(soap_action, soap_action_tmp.c_str());
+
+ request_data->soap_action = soap_action;
+ }
+
+#ifdef AXIS2_SVR_MULTI_THREADED
+ worker_thread = axutil_thread_pool_get_thread(env->thread_pool,
+ axis2_amqp_request_processor_thread_function,
+ (void*)request_data);
+
+ if (!worker_thread)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create Thread");
+ return;
+ }
+
+ axutil_thread_pool_thread_detach(env->thread_pool, worker_thread);
+#else
+ axis2_amqp_request_processor_thread_function(NULL, (void*)request_data);
+#endif
+}
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.h b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.h new file mode 100644 index 0000000..d5923db --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.h @@ -0,0 +1,43 @@ +/*
+ * 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
+ *
+ * tcp://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_QPID_RECEIVER_LISTENER_H
+#define AXIS2_QPID_RECEIVER_LISTENER_H
+
+#include <qpid/client/MessageListener.h>
+#include <qpid/client/Message.h>
+#include <axutil_env.h>
+#include <axis2_conf_init.h>
+
+using namespace qpid::client;
+using namespace qpid::framing;
+
+class Axis2QpidReceiverListener : public MessageListener
+{
+ public:
+ Axis2QpidReceiverListener(const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx);
+ ~Axis2QpidReceiverListener(void);
+
+ private:
+ virtual void received(Message& message);
+
+ const axutil_env_t* env;
+ axis2_conf_ctx_t* conf_ctx;
+};
+
+#endif
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/request_processor/Makefile.am b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/Makefile.am new file mode 100644 index 0000000..77cac4a --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/Makefile.am @@ -0,0 +1,20 @@ +lib_LTLIBRARIES = libaxis2_amqp_request_processor.la
+
+libaxis2_amqp_request_processor_la_SOURCES = axis2_amqp_request_processor.c
+
+libaxis2_amqp_request_processor_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la
+
+libaxis2_amqp_request_processor_la_LDFLAGS = -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver/request_processor \
+ -I$(top_builddir)/src/core/transport/amqp/util \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
+
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.c b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.c new file mode 100644 index 0000000..0e0c9f8 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.c @@ -0,0 +1,334 @@ +/*
+ * 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 <signal.h>
+#include <axiom.h>
+#include <axiom_soap.h>
+#include <axis2_engine.h>
+#include <axiom_mime_parser.h>
+#include <axutil_http_chunked_stream.h>
+#include <axis2_amqp_defines.h>
+#include <axis2_amqp_util.h>
+#include <axis2_amqp_request_processor.h>
+
+void* AXIS2_THREAD_FUNC
+axis2_amqp_request_processor_thread_function(
+ axutil_thread_t* thread,
+ void* request_data)
+{
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_env_t* env = NULL;
+ axutil_env_t* thread_env = NULL;
+ axis2_amqp_request_processor_resource_pack_t* request_resource_pack = NULL;
+
+#ifndef WIN32
+#ifdef AXIS2_SVR_MULTI_THREADED
+ signal(SIGPIPE, SIG_IGN);
+#endif
+#endif
+
+ request_resource_pack = (axis2_amqp_request_processor_resource_pack_t*)request_data;
+
+ env = request_resource_pack->env;
+ thread_env = axutil_init_thread_env(env);
+
+ /* Process Request */
+ status = axis2_amqp_process_request(thread_env, request_resource_pack);
+
+ if(status == AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_INFO(thread_env->log, "Request Processed Successfully");
+ }
+ else
+ {
+ AXIS2_LOG_WARNING(thread_env->log, AXIS2_LOG_SI, "Error while Processing Request");
+ }
+
+ AXIS2_FREE(thread_env->allocator, request_resource_pack->request_content);
+ AXIS2_FREE(thread_env->allocator, request_resource_pack->reply_to);
+ AXIS2_FREE(thread_env->allocator, request_resource_pack->content_type);
+ AXIS2_FREE(thread_env->allocator, request_resource_pack->soap_action);
+
+ AXIS2_FREE(thread_env->allocator, request_resource_pack);
+
+ if(thread_env)
+ {
+ thread_env = NULL;
+ }
+
+#ifdef AXIS2_SVR_MULTI_THREADED
+ axutil_thread_pool_exit_thread(env->thread_pool, thread);
+#endif
+
+ return NULL;
+}
+
+axis2_status_t
+axis2_amqp_process_request(
+ const axutil_env_t* env,
+ axis2_amqp_request_processor_resource_pack_t* request_resource_pack)
+{
+ axiom_xml_reader_t* xml_reader = NULL;
+ axiom_stax_builder_t* stax_builder = NULL;
+ axiom_soap_builder_t* soap_builder = NULL;
+ axis2_transport_out_desc_t* out_desc = NULL;
+ axis2_transport_in_desc_t* in_desc = NULL;
+ axis2_msg_ctx_t* msg_ctx = NULL;
+ axiom_soap_envelope_t* soap_envelope = NULL;
+ axis2_engine_t* engine = NULL;
+ const axis2_char_t* soap_ns_uri = NULL;
+ axis2_bool_t is_soap_11 = AXIS2_FALSE;
+ axis2_char_t *soap_body_str = NULL;
+ int soap_body_len = 0;
+ axis2_bool_t is_mtom = AXIS2_FALSE;
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_hash_t *binary_data_map = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axutil_property_t* reply_to_property = NULL;
+
+ /* Create msg_ctx */
+ if(!request_resource_pack->conf_ctx)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Conf Context not Available");
+ return AXIS2_FAILURE;
+ }
+
+ out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(
+ request_resource_pack->conf_ctx, env), env, AXIS2_TRANSPORT_ENUM_AMQP);
+ if(!out_desc)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport Out Descriptor not Found");
+ return AXIS2_FAILURE;
+ }
+
+ in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(request_resource_pack->conf_ctx,
+ env), env, AXIS2_TRANSPORT_ENUM_AMQP);
+ if(!in_desc)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport In Descriptor not Found");
+ return AXIS2_FAILURE;
+ }
+
+ /* Create msg_ctx */
+ msg_ctx = axis2_msg_ctx_create(env, request_resource_pack->conf_ctx, in_desc, out_desc);
+
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+ /* Handle MTOM */
+ if(strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_MULTIPART_RELATED))
+ {
+ axis2_char_t* mime_boundary = axis2_amqp_util_get_value_from_content_type(env,
+ request_resource_pack->content_type, AXIS2_AMQP_HEADER_CONTENT_TYPE_MIME_BOUNDARY);
+
+ if(mime_boundary)
+ {
+ axiom_mime_parser_t *mime_parser = NULL;
+ int soap_body_len = 0;
+ axutil_param_t *buffer_size_param = NULL;
+ axutil_param_t *max_buffers_param = NULL;
+ axutil_param_t *attachment_dir_param = NULL;
+ axis2_char_t *value_size = NULL;
+ axis2_char_t *value_num = NULL;
+ axis2_char_t *value_dir = NULL;
+ int size = 0;
+ int num = 0;
+
+ mime_parser = axiom_mime_parser_create(env);
+
+ buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE);
+ if(buffer_size_param)
+ {
+ value_size = (axis2_char_t*)axutil_param_get_value(buffer_size_param, env);
+ if(value_size)
+ {
+ size = atoi(value_size);
+ axiom_mime_parser_set_buffer_size(mime_parser, env, size);
+ }
+ }
+
+ max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS);
+ if(max_buffers_param)
+ {
+ value_num = (axis2_char_t*)axutil_param_get_value(max_buffers_param, env);
+ if(value_num)
+ {
+ num = atoi(value_num);
+ axiom_mime_parser_set_max_buffers(mime_parser, env, num);
+ }
+ }
+
+ /* If this paramter is there mime_parser will cached the attachment
+ * using to the directory for large attachments. */
+ attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR);
+ if(attachment_dir_param)
+ {
+ value_dir = (axis2_char_t*)axutil_param_get_value(attachment_dir_param, env);
+ if(value_dir)
+ {
+ axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
+ }
+ }
+
+ if(mime_parser)
+ {
+ axis2_callback_info_t *callback_ctx = NULL;
+ axutil_stream_t *stream = NULL;
+
+ callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t));
+
+ stream = axutil_stream_create_basic(env);
+ if(stream)
+ {
+ axutil_stream_write(stream, env, request_resource_pack->request_content,
+ request_resource_pack->content_length);
+ callback_ctx->env = env;
+ callback_ctx->in_stream = stream;
+ callback_ctx->content_length = request_resource_pack->content_length;
+ callback_ctx->unread_len = request_resource_pack->content_length;
+ callback_ctx->chunked_stream = NULL;
+ }
+
+ /*binary_data_map =
+ axiom_mime_parser_parse(mime_parser, env,
+ axis2_amqp_util_on_data_request,
+ (void*)callback_ctx,
+ mime_boundary);*/
+ if(!binary_data_map)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env);
+ soap_body_len = axiom_mime_parser_get_soap_body_len(mime_parser, env);
+
+ axutil_stream_free(stream, env);
+ AXIS2_FREE(env->allocator, callback_ctx);
+ axiom_mime_parser_free(mime_parser, env);
+ }
+
+ AXIS2_FREE(env->allocator, mime_boundary);
+ }
+
+ is_mtom = AXIS2_TRUE;
+ }
+ else
+ {
+ soap_body_str = request_resource_pack->request_content;
+ soap_body_len = request_resource_pack->content_length;
+ }
+
+ soap_body_len = axutil_strlen(soap_body_str);
+
+ xml_reader = axiom_xml_reader_create_for_memory(env, soap_body_str, soap_body_len, NULL,
+ AXIS2_XML_PARSER_TYPE_BUFFER);
+ if(!xml_reader)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create XML Reader");
+ return AXIS2_FAILURE;
+ }
+
+ stax_builder = axiom_stax_builder_create(env, xml_reader);
+ if(!stax_builder)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create StAX Builder");
+ return AXIS2_FAILURE;
+ }
+
+ soap_ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
+
+ if(request_resource_pack->content_type)
+ {
+ if(strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML))
+ {
+ is_soap_11 = AXIS2_TRUE;
+ soap_ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI;
+ }
+ /*if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_APPL_SOAP))
+ {
+ is_soap_11 = AXIS2_FALSE;
+ soap_ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
+ }
+ else if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML))
+ {
+ is_soap_11 = AXIS2_TRUE;
+ soap_ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI;
+ }*/
+ }
+
+ soap_builder = axiom_soap_builder_create(env, stax_builder, soap_ns_uri);
+ if(!soap_builder)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create SOAP Builder");
+ return AXIS2_FAILURE;
+ }
+
+ if(binary_data_map)
+ {
+ axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map);
+ }
+
+ soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
+
+ soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
+
+ if(!soap_body)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ /* SOAPAction */
+ if(request_resource_pack->soap_action)
+ {
+ axis2_msg_ctx_set_soap_action(msg_ctx, env, axutil_string_create(env,
+ request_resource_pack->soap_action));
+ }
+
+ /* SOAP version */
+ axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap_11);
+
+ /* Set ReplyTo in the msg_ctx as a property. This is used by the server when
+ * 1. WS-A is not in use
+ * 2. ReplyTo is an anonymous EPR - Sandesha2/Dual-channel */
+ reply_to_property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, 0, 0,
+ (void*)request_resource_pack->reply_to);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO,
+ reply_to_property);
+
+ engine = axis2_engine_create(env, request_resource_pack->conf_ctx);
+
+ if(AXIS2_TRUE == axiom_soap_body_has_fault(soap_body, env))
+ {
+ status = axis2_engine_receive_fault(engine, env, msg_ctx);
+ }
+ else
+ {
+ status = axis2_engine_receive(engine, env, msg_ctx);
+ }
+
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ }
+
+ if(soap_body_str && is_mtom)
+ {
+ AXIS2_FREE(env->allocator, soap_body_str);
+ }
+
+ return status;
+}
diff --git a/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.h b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.h new file mode 100644 index 0000000..97f13b2 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.h @@ -0,0 +1,55 @@ +/*
+ * 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_AMQP_REQUEST_PROCESSOR_H
+#define AXIS2_AMQP_REQUEST_PROCESSOR_H
+
+#include <axutil_env.h>
+#include <axis2_conf_init.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct axis2_amqp_request_processor_resource_pack
+ {
+ axutil_env_t* env;
+ axis2_conf_ctx_t* conf_ctx;
+ axis2_char_t* request_content;
+ int content_length;
+ axis2_char_t* reply_to;
+ axis2_char_t* content_type;
+ axis2_char_t* soap_action;
+ } axis2_amqp_request_processor_resource_pack_t;
+
+ /* The worker thread function */
+ void* AXIS2_THREAD_FUNC
+ axis2_amqp_request_processor_thread_function(
+ axutil_thread_t* thread,
+ void* request_data);
+
+ axis2_status_t
+ axis2_amqp_process_request(
+ const axutil_env_t* env,
+ axis2_amqp_request_processor_resource_pack_t* request_resource_pack);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/core/transport/amqp/sender/Makefile.am b/src/core/transport/amqp/sender/Makefile.am new file mode 100644 index 0000000..8af0c7b --- /dev/null +++ b/src/core/transport/amqp/sender/Makefile.am @@ -0,0 +1,26 @@ +SUBDIRS = qpid_sender
+
+lib_LTLIBRARIES = libaxis2_amqp_sender.la
+
+libaxis2_amqp_sender_la_SOURCES = axis2_amqp_sender.c
+
+libaxis2_amqp_sender_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \
+ $(top_builddir)/src/core/transport/amqp/sender/qpid_sender/libaxis2_qpid_sender.la
+
+libaxis2_amqp_sender_la_LDFLAGS = -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport/amqp/util \
+ -I$(top_builddir)/src/core/transport/amqp/receiver \
+ -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver \
+ -I$(top_builddir)/src/core/transport/amqp/sender \
+ -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
+
diff --git a/src/core/transport/amqp/sender/axis2_amqp_sender.c b/src/core/transport/amqp/sender/axis2_amqp_sender.c new file mode 100644 index 0000000..aae5496 --- /dev/null +++ b/src/core/transport/amqp/sender/axis2_amqp_sender.c @@ -0,0 +1,344 @@ +/*
+ * 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 <axiom_soap.h>
+#include <axis2_transport_in_desc.h>
+#include <axis2_amqp_defines.h>
+#include <axis2_amqp_util.h>
+#include <axis2_amqp_receiver.h>
+#include <axis2_amqp_sender.h>
+
+static const axis2_transport_sender_ops_t amqp_sender_ops =
+{
+ axis2_amqp_sender_init,
+ axis2_amqp_sender_invoke,
+ axis2_amqp_sender_clean_up,
+ axis2_amqp_sender_free
+};
+
+AXIS2_EXTERN axis2_transport_sender_t* AXIS2_CALL
+axis2_amqp_sender_create(
+ const axutil_env_t* env)
+{
+ AXIS2_ENV_CHECK(env, NULL);
+
+ axis2_amqp_sender_resource_pack_t* sender_resource_pack = NULL;
+
+ sender_resource_pack = (axis2_amqp_sender_resource_pack_t*)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_amqp_sender_resource_pack_t));
+
+ if(!sender_resource_pack)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ sender_resource_pack->sender.ops = &amqp_sender_ops;
+ sender_resource_pack->conf_ctx = NULL;
+
+ return &(sender_resource_pack->sender);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_sender_init(
+ axis2_transport_sender_t* sender,
+ const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx,
+ axis2_transport_out_desc_t* out_desc)
+{
+ axis2_amqp_sender_resource_pack_t* sender_resource_pack = NULL;
+ axutil_property_t* property = NULL;
+ int* request_timeout = (int*)AXIS2_MALLOC(env->allocator, sizeof(int));
+ *request_timeout = AXIS2_QPID_NULL_CONF_INT;
+
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+
+ sender_resource_pack = AXIS2_AMQP_SENDER_TO_RESOURCE_PACK(sender);
+ sender_resource_pack->conf_ctx = conf_ctx;
+
+ /* Set request timeout */
+ *request_timeout = axis2_amqp_util_get_out_desc_conf_value_int(out_desc, env,
+ AXIS2_AMQP_CONF_QPID_REQUEST_TIMEOUT);
+ if(*request_timeout == AXIS2_QPID_NULL_CONF_INT)
+ {
+ *request_timeout = AXIS2_QPID_DEFAULT_REQUEST_TIMEOUT;
+ }
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0,
+ (void*)request_timeout);
+ axis2_conf_ctx_set_property(sender_resource_pack->conf_ctx, env,
+ AXIS2_AMQP_CONF_CTX_PROPERTY_REQUEST_TIMEOUT, property);
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_sender_invoke(
+ axis2_transport_sender_t* sender,
+ const axutil_env_t* env,
+ axis2_msg_ctx_t* msg_ctx)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ axiom_soap_envelope_t* request_soap_envelope = NULL;
+ axiom_xml_writer_t* xml_writer = NULL;
+ axiom_output_t* request_om_output = NULL;
+ axis2_char_t* request_content = NULL;
+ axis2_bool_t is_server = AXIS2_TRUE;
+ axis2_bool_t is_soap_11 = AXIS2_FALSE;
+ axutil_string_t* content_type = NULL;
+ const axis2_char_t* soap_action = NULL;
+ axis2_bool_t do_mtom = AXIS2_FALSE;
+ axis2_bool_t status = AXIS2_FAILURE;
+
+ request_soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
+
+ xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
+ AXIS2_XML_PARSER_TYPE_BUFFER);
+ if(!xml_writer)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create XML Writer");
+ return AXIS2_FAILURE;
+ }
+
+ request_om_output = axiom_output_create(env, xml_writer);
+ if(!request_om_output)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create OM Output");
+ axiom_xml_writer_free(xml_writer, env);
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ is_soap_11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env);
+
+ /* Set SOAP version */
+ axiom_output_set_soap11(request_om_output, env, is_soap_11);
+
+ /* Content-Type */
+ if(AXIS2_TRUE == is_soap_11)
+ {
+ /* SOAP1.1 */
+ content_type = axutil_string_create(env, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML);
+ }
+ else
+ {
+ /* SOAP1.2 */
+ content_type = axutil_string_create(env, AXIS2_AMQP_HEADER_ACCEPT_APPL_SOAP);
+ }
+
+ /* SOAP action */
+ soap_action = axutil_string_get_buffer(axis2_msg_ctx_get_soap_action(msg_ctx, env), env);
+
+ if(!soap_action)
+ soap_action = "";
+
+ /* Handle MTOM */
+ do_mtom = axis2_msg_ctx_get_doing_mtom(msg_ctx, env);
+
+ axiom_output_set_do_optimize(request_om_output, env, do_mtom);
+ axiom_soap_envelope_serialize(request_soap_envelope, env, request_om_output, AXIS2_FALSE);
+
+ if(do_mtom)
+ {
+ axis2_status_t mtom_status = AXIS2_FAILURE;
+ axutil_array_list_t* mime_parts = NULL;
+
+ mtom_status = axiom_output_flush(request_om_output, env);
+
+ if(mtom_status == AXIS2_SUCCESS)
+ {
+ mime_parts = axiom_output_get_mime_parts(request_om_output, env);
+ if(!mime_parts)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Unable to create the mime part list from request_om_output");
+
+ return AXIS2_FAILURE;
+ }
+ else
+ {
+ axis2_msg_ctx_set_mime_parts(msg_ctx, env, mime_parts);
+ }
+ }
+
+ content_type = axutil_string_create(env, axiom_output_get_content_type(request_om_output,
+ env));
+ }
+
+ request_content = (axis2_char_t*)axiom_xml_writer_get_xml(xml_writer, env);
+ if(!request_content)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Serialize the SOAP Envelope");
+ return AXIS2_FAILURE;
+ }
+
+ is_server = axis2_amqp_util_msg_ctx_get_server_side(msg_ctx, env);
+
+ if(is_server)
+ {
+ status = axis2_qpid_send(request_content, env, axutil_string_get_buffer(content_type, env),
+ soap_action, msg_ctx);
+ }
+ else
+ {
+ if(AXIS2_TRUE == axis2_amqp_util_msg_ctx_get_use_separate_listener(msg_ctx, env)) /* Dual Channel */
+ {
+ status = axis2_qpid_send(request_content, env, axutil_string_get_buffer(content_type,
+ env), soap_action, msg_ctx);
+ }
+ else
+ {
+ axis2_op_t* op = NULL;
+ const axis2_char_t* mep = NULL;
+
+ op = axis2_msg_ctx_get_op(msg_ctx, env);
+
+ if(op)
+ {
+ mep = axis2_op_get_msg_exchange_pattern(op, env);
+ }
+
+ axis2_amqp_response_t* response = NULL;
+ response = axis2_qpid_send_receive(request_content, env, axutil_string_get_buffer(
+ content_type, env), soap_action, msg_ctx);
+
+ if(response)
+ {
+ /* Create in stream */
+ if(response->data)
+ {
+ axutil_stream_t* in_stream = NULL;
+ axutil_property_t* property = NULL;
+
+ in_stream = axutil_stream_create_basic(env);
+ axutil_stream_write(in_stream, env, response->data, response->length);
+
+ property = axutil_property_create(env);
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_free_func(property, env, axutil_stream_free_void_arg);
+ axutil_property_set_value(property, env, in_stream);
+
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property);
+ }
+
+ if(mep)
+ {
+ if(0 == axutil_strcmp(mep, AXIS2_MEP_URI_OUT_IN)) /* Out-In */
+ {
+ axiom_soap_envelope_t* response_soap_envelope = NULL;
+
+ response_soap_envelope = axis2_amqp_util_get_soap_envelope(response, env,
+ msg_ctx);
+ if(response_soap_envelope)
+ {
+ axis2_msg_ctx_set_response_soap_envelope(msg_ctx, env,
+ response_soap_envelope);
+ }
+ }
+ }
+
+ status = AXIS2_SUCCESS;
+
+ axis2_msg_ctx_set_status_code(msg_ctx, env, status);
+
+ axis2_amqp_response_free(response, env);
+ }
+ else
+ {
+ if(mep)
+ {
+ if(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY) == 0 || axutil_strcmp(mep,
+ AXIS2_MEP_URI_ROBUST_OUT_ONLY) == 0) /* One-way */
+ {
+ status = AXIS2_SUCCESS;
+
+ /* Set status code in msg_ctx */
+ axis2_msg_ctx_set_status_code(msg_ctx, env, status);
+ }
+ }
+ }
+ }
+ }
+
+ if(content_type)
+ axutil_string_free(content_type, env);
+
+ return status;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_sender_clean_up(
+ axis2_transport_sender_t* sender,
+ const axutil_env_t* env,
+ axis2_msg_ctx_t* msg_ctx)
+{
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_amqp_sender_free(
+ axis2_transport_sender_t* sender,
+ const axutil_env_t* env)
+{
+ AXIS2_ENV_CHECK(env, void);
+
+ axis2_amqp_sender_resource_pack_t* sender_resource_pack = NULL;
+ sender_resource_pack = AXIS2_AMQP_SENDER_TO_RESOURCE_PACK(sender);
+
+ AXIS2_FREE(env->allocator, sender_resource_pack);
+}
+
+/* Library Exports */
+
+AXIS2_EXPORT int
+#ifndef AXIS2_STATIC_DEPLOY
+axis2_get_instance(
+#else
+ axis2_amqp_sender_get_instance(
+#endif
+ struct axis2_transport_sender** inst,
+ const axutil_env_t* env)
+{
+ int status = AXIS2_SUCCESS;
+
+ *inst = axis2_amqp_sender_create(env);
+ if(!(*inst))
+ {
+ status = AXIS2_FAILURE;
+ }
+
+ return status;
+}
+
+AXIS2_EXPORT int
+#ifndef AXIS2_STATIC_DEPLOY
+axis2_remove_instance(
+#else
+ axis2_amqp_sender_remove_instance(
+#endif
+ axis2_transport_sender_t* inst,
+ const axutil_env_t* env)
+{
+ if(inst)
+ {
+ axis2_transport_sender_free(inst, env);
+ }
+
+ return AXIS2_SUCCESS;
+}
+
diff --git a/src/core/transport/amqp/sender/axis2_amqp_sender.h b/src/core/transport/amqp/sender/axis2_amqp_sender.h new file mode 100644 index 0000000..b523347 --- /dev/null +++ b/src/core/transport/amqp/sender/axis2_amqp_sender.h @@ -0,0 +1,63 @@ +/*
+ * 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_AMQP_SENDER_H
+#define AXIS2_AMQP_SENDER_H
+
+#include <axutil_env.h>
+#include <axis2_conf_ctx.h>
+#include <axis2_transport_sender.h>
+#include <axis2_qpid_sender_interface.h>
+
+typedef struct axis2_amqp_sender_resource_pack
+{
+ axis2_transport_sender_t sender;
+ axis2_conf_ctx_t* conf_ctx;
+}
+axis2_amqp_sender_resource_pack_t;
+
+#define AXIS2_AMQP_SENDER_TO_RESOURCE_PACK(amqp_sender) \
+ ((axis2_amqp_sender_resource_pack_t*)(amqp_sender))
+
+AXIS2_EXTERN axis2_transport_sender_t* AXIS2_CALL
+axis2_amqp_sender_create(const axutil_env_t* env);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_sender_init(
+ axis2_transport_sender_t* sender,
+ const axutil_env_t* env,
+ axis2_conf_ctx_t* conf_ctx,
+ axis2_transport_out_desc_t* out_desc);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_sender_invoke(
+ axis2_transport_sender_t* sender,
+ const axutil_env_t* env,
+ axis2_msg_ctx_t* msg_ctx);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_amqp_sender_clean_up(
+ axis2_transport_sender_t* sender,
+ const axutil_env_t* env,
+ axis2_msg_ctx_t* msg_ctx);
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_amqp_sender_free(
+ axis2_transport_sender_t* sender,
+ const axutil_env_t* env);
+
+#endif
diff --git a/src/core/transport/amqp/sender/qpid_sender/Makefile.am b/src/core/transport/amqp/sender/qpid_sender/Makefile.am new file mode 100644 index 0000000..46dcb5e --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/Makefile.am @@ -0,0 +1,23 @@ +lib_LTLIBRARIES = libaxis2_qpid_sender.la
+
+libaxis2_qpid_sender_la_SOURCES = axis2_qpid_sender.cpp \
+ axis2_qpid_sender_interface.cpp
+
+libaxis2_qpid_sender_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \
+ $(QPID_HOME)/lib/libqpidclient.la
+
+libaxis2_qpid_sender_la_LDFLAGS = g++ -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \
+ -I$(top_builddir)/src/core/transport/amqp/util \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include \
+ -I$(QPID_HOME)/include
+
diff --git a/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.cpp b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.cpp new file mode 100644 index 0000000..7f0799b --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.cpp @@ -0,0 +1,242 @@ +/*
+ * 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
+ *
+ * tcp://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 <qpid/client/Connection.h>
+#include <qpid/client/Session.h>
+#include <qpid/client/Message.h>
+#include <qpid/client/SubscriptionManager.h>
+#include <qpid/sys/Time.h>
+#include <axis2_amqp_defines.h>
+#include <axiom_mime_part.h>
+#include <axis2_qpid_sender.h>
+#include <fstream>
+
+using namespace std;
+using namespace qpid::client;
+using namespace qpid::framing;
+
+Axis2QpidSender::Axis2QpidSender(
+ string qpidBrokerIP,
+ int qpidBrokerPort,
+ const axutil_env_t* env)
+{
+ this->qpidBrokerIP = qpidBrokerIP;
+ this->qpidBrokerPort = qpidBrokerPort;
+ this->env = env;
+ this->responseContent = "";
+ this->responseContentType = "";
+}
+
+Axis2QpidSender::~Axis2QpidSender(
+ void)
+{
+}
+
+bool
+Axis2QpidSender::SendReceive(
+ string messageContent,
+ string toQueueName,
+ bool isSOAP11,
+ string contentType,
+ string soapAction,
+ axutil_array_list_t* mime_parts,
+ int timeout)
+{
+ bool status = false;
+ this->responseContent = "";
+ this->responseContentType = "";
+
+ try
+ {
+ Connection connection;
+ connection.open(qpidBrokerIP, qpidBrokerPort);
+
+ Session session = connection.newSession();
+
+ /* Declare Private Queue */
+ string replyToQueueName = AXIS2_AMQP_TEMP_QUEUE_NAME_PREFIX;
+ replyToQueueName.append(axutil_uuid_gen(env));
+
+ session.queueDeclare(arg::queue = replyToQueueName, arg::autoDelete = true);
+ session.exchangeBind(arg::exchange = AXIS2_AMQP_EXCHANGE_DIRECT, arg::queue
+ = replyToQueueName, arg::bindingKey = replyToQueueName);
+
+ /* Create Message */
+ Message reqMessage;
+
+ reqMessage.getDeliveryProperties().setRoutingKey(toQueueName);
+ reqMessage.getMessageProperties().setReplyTo(ReplyTo(AXIS2_AMQP_EXCHANGE_DIRECT,
+ replyToQueueName));
+
+ reqMessage.getHeaders().setString(AXIS2_AMQP_HEADER_CONTENT_TYPE, contentType);
+ reqMessage.getHeaders().setString(AXIS2_AMQP_HEADER_SOAP_ACTION, soapAction);
+
+ if(mime_parts)
+ {
+ string mimeBody;
+ GetMimeBody(mime_parts, mimeBody);
+
+ messageContent.clear();/* MIME parts include SOAP envelop */
+
+ messageContent.append(mimeBody);
+ }
+
+ reqMessage.setData(messageContent);
+
+ session.messageTransfer(arg::content = reqMessage, arg::destination
+ = AXIS2_AMQP_EXCHANGE_DIRECT);
+
+ /* Create subscription manager */
+ SubscriptionManager subscriptionManager(session);
+
+ Message resMessage;
+ qpid::sys::Duration reqTimeout(timeout * AXIS2_AMQP_NANOSEC_PER_MILLISEC);
+
+ if(subscriptionManager.get(resMessage, replyToQueueName, reqTimeout))
+ {
+ responseContent = resMessage.getData();
+ responseContentType = resMessage.getHeaders().getAsString(
+ AXIS2_AMQP_HEADER_CONTENT_TYPE);
+
+ status = true;
+ }
+
+ connection.close();
+ }
+ catch(const std::exception& e)
+ {
+ }
+
+ return status;
+}
+
+bool
+Axis2QpidSender::Send(
+ string messageContent,
+ string toQueueName,
+ string replyToQueueName,
+ bool isSOAP11,
+ string contentType,
+ string soapAction,
+ axutil_array_list_t* mime_parts)
+{
+ bool status = false;
+
+ try
+ {
+ Connection connection;
+ connection.open(qpidBrokerIP, qpidBrokerPort);
+
+ Session session = connection.newSession();
+
+ /* Create Message */
+ Message message;
+
+ message.getDeliveryProperties().setRoutingKey(toQueueName);
+
+ if(!replyToQueueName.empty()) /* Client dual-channel */
+ {
+ message.getMessageProperties().setReplyTo(ReplyTo(AXIS2_AMQP_EXCHANGE_DIRECT,
+ replyToQueueName));
+
+ session.queueDeclare(arg::queue = replyToQueueName);
+ session.exchangeBind(arg::exchange = AXIS2_AMQP_EXCHANGE_DIRECT, arg::queue
+ = replyToQueueName, arg::bindingKey = replyToQueueName);
+ }
+
+ message.getHeaders().setString(AXIS2_AMQP_HEADER_CONTENT_TYPE, contentType);
+ message.getHeaders().setString(AXIS2_AMQP_HEADER_SOAP_ACTION, soapAction);
+
+ if(mime_parts)
+ {
+ string mimeBody;
+ GetMimeBody(mime_parts, mimeBody);
+
+ messageContent.clear();/* MIME parts include SOAP envelop */
+
+ messageContent.append(mimeBody);
+ }
+
+ message.setData(messageContent);
+
+ session.messageTransfer(arg::content = message, arg::destination
+ = AXIS2_AMQP_EXCHANGE_DIRECT);
+
+ connection.close();
+
+ status = true;
+ }
+ catch(const std::exception& e)
+ {
+ }
+
+ return status;
+}
+
+void
+Axis2QpidSender::GetMimeBody(
+ axutil_array_list_t* mime_parts,
+ string& mimeBody)
+{
+ int i = 0;
+ axiom_mime_part_t *mime_part = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+
+ if(!mime_parts)
+ return;
+
+ 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)
+ {
+ mimeBody.append(mime_part->part, mime_part->part_size);
+ }
+ else if(mime_part->type == AXIOM_MIME_PART_FILE)
+ {
+ int length;
+ char* buffer;
+
+ ifstream file;
+ file.open(mime_part->file_name, ios::binary);
+
+ file.seekg(0, ios::end);
+ length = file.tellg();
+ file.seekg(0, ios::beg);
+
+ buffer = new char[length];
+
+ file.read(buffer, length);
+ file.close();
+
+ mimeBody.append(buffer, length);
+
+ delete[] buffer;
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unknown mime type");
+ return;
+ }
+
+ if(status == AXIS2_FAILURE)
+ {
+ break;
+ }
+ }
+}
diff --git a/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.h b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.h new file mode 100644 index 0000000..8c94cfa --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.h @@ -0,0 +1,49 @@ +/*
+ * 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
+ *
+ * tcp://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_QPID_SENDER_H
+#define AXIS2_QPID_SENDER_H
+
+#include <axis2_util.h>
+#include <sstream>
+#include <string>
+
+using std::string;
+
+class Axis2QpidSender
+{
+ public:
+ Axis2QpidSender(string qpidBrokerIP, int qpidBrokerPort, const axutil_env_t* env);
+ ~Axis2QpidSender(void);
+
+ bool SendReceive(string messageContent, string toQueueName, bool isSOAP11,
+ string contentType, string soapAction, axutil_array_list_t* mime_parts, int timeout);
+ bool Send(string messageContent, string toQueueName, string replyToQueueName, bool isSOAP11,
+ string contentType, string soapAction, axutil_array_list_t* mime_parts);
+
+ string responseContent;
+ string responseContentType;
+
+ private:
+ void GetMimeBody(axutil_array_list_t* mime_parts, string& mimeBody);
+
+ string qpidBrokerIP;
+ int qpidBrokerPort;
+ const axutil_env_t* env;
+};
+
+#endif
diff --git a/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.cpp b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.cpp new file mode 100644 index 0000000..ac4f51e --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.cpp @@ -0,0 +1,130 @@ +/*
+* 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_amqp_util.h>
+#include <axis2_qpid_sender.h>
+#include <axis2_qpid_sender_interface.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+AXIS2_EXTERN axis2_amqp_response_t* AXIS2_CALL
+axis2_qpid_send_receive(
+ const axis2_char_t* request_content,
+ const axutil_env_t* env,
+ const axis2_char_t* content_type,
+ const axis2_char_t* soap_action,
+ axis2_msg_ctx_t* msg_ctx)
+{
+ axis2_amqp_destination_info_t* destination_info = NULL;
+ destination_info = axis2_amqp_util_msg_ctx_get_destination_info(msg_ctx, env);
+
+ if (!destination_info || !destination_info->broker_ip ||
+ !destination_info->broker_port || !destination_info->queue_name)
+ {
+ return NULL;
+ }
+
+ axis2_bool_t is_soap_11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env);
+ axutil_array_list_t* mime_parts = axis2_msg_ctx_get_mime_parts(msg_ctx, env);
+ int timeout = axis2_amqp_util_msg_ctx_get_request_timeout(msg_ctx, env);
+
+ /* Get Response */
+ Axis2QpidSender qpid_sender(destination_info->broker_ip,
+ destination_info->broker_port, env);
+
+ bool status = qpid_sender.SendReceive(request_content, destination_info->queue_name,
+ is_soap_11, content_type, soap_action, mime_parts, timeout);
+
+ axis2_amqp_destination_info_free(destination_info, env);
+
+ if (!status)
+ {
+ return NULL;
+ }
+
+ /* Create response */
+ axis2_amqp_response_t* response = (axis2_amqp_response_t*)AXIS2_MALLOC(
+ env->allocator, sizeof(axis2_amqp_response_t));
+
+ /* Data */
+ response->data = AXIS2_MALLOC(env->allocator, qpid_sender.responseContent.size());
+ memcpy(response->data, qpid_sender.responseContent.c_str(),
+ qpid_sender.responseContent.size());
+
+ /* Length */
+ response->length = qpid_sender.responseContent.size();
+
+ /* ContentType */
+ response->content_type = (axis2_char_t*)AXIS2_MALLOC(
+ env->allocator, qpid_sender.responseContentType.size() + 1);
+ strcpy(response->content_type, qpid_sender.responseContentType.c_str());
+
+ return response;
+}
+
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_qpid_send(
+ const axis2_char_t* request_content,
+ const axutil_env_t* env,
+ const axis2_char_t* content_type,
+ const axis2_char_t* soap_action,
+ axis2_msg_ctx_t* msg_ctx)
+{
+ axis2_amqp_destination_info_t* destination_info = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ string reply_to_queue_name = "";
+
+ destination_info = axis2_amqp_util_msg_ctx_get_destination_info(msg_ctx, env);
+
+ if (!destination_info || !destination_info->broker_ip ||
+ !destination_info->broker_port || !destination_info->queue_name)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ axis2_bool_t is_soap_11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env);
+ axutil_array_list_t* mime_parts = axis2_msg_ctx_get_mime_parts(msg_ctx, env);
+
+ /* If client side, find reply_to_queue_name */
+ if (!axis2_msg_ctx_get_server_side(msg_ctx, env))
+ {
+ axis2_conf_ctx_t* conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+
+ axis2_char_t* queue_name =
+ axis2_amqp_util_conf_ctx_get_dual_channel_queue_name(conf_ctx, env);
+ if (queue_name)
+ reply_to_queue_name = queue_name;
+ }
+
+ Axis2QpidSender qpid_sender(destination_info->broker_ip,
+ destination_info->broker_port, env);
+
+ status = qpid_sender.Send(request_content, destination_info->queue_name,
+ reply_to_queue_name, is_soap_11, content_type, soap_action, mime_parts);
+
+ axis2_amqp_destination_info_free(destination_info, env);
+
+ return status;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.h b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.h new file mode 100644 index 0000000..94e232f --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.h @@ -0,0 +1,50 @@ +/*
+* 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_QPID_SENDER_INTERFACE_H
+#define AXIS2_QPID_SENDER_INTERFACE_H
+
+#include <axis2_util.h>
+#include <axis2_conf_init.h>
+#include <axis2_amqp_util.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+AXIS2_EXTERN axis2_amqp_response_t* AXIS2_CALL
+axis2_qpid_send_receive(
+ const axis2_char_t* request_content,
+ const axutil_env_t* env,
+ const axis2_char_t* content_type,
+ const axis2_char_t* soap_action,
+ axis2_msg_ctx_t* msg_ctx);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_qpid_send(
+ const axis2_char_t* request_content,
+ const axutil_env_t* env,
+ const axis2_char_t* content_type,
+ const axis2_char_t* soap_action,
+ axis2_msg_ctx_t* msg_ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/core/transport/amqp/server/Makefile.am b/src/core/transport/amqp/server/Makefile.am new file mode 100644 index 0000000..2de6967 --- /dev/null +++ b/src/core/transport/amqp/server/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = axis2_amqp_server
diff --git a/src/core/transport/amqp/server/axis2_amqp_server/Makefile.am b/src/core/transport/amqp/server/axis2_amqp_server/Makefile.am new file mode 100644 index 0000000..643827f --- /dev/null +++ b/src/core/transport/amqp/server/axis2_amqp_server/Makefile.am @@ -0,0 +1,33 @@ +prgbindir = $(bindir)
+
+prgbin_PROGRAMS = axis2_amqp_server
+
+AM_CFLAGS = -g -pthread
+
+axis2_amqp_server_SOURCES = axis2_amqp_server.c
+
+axis2_amqp_server_LDADD = $(LDFLAGS) \
+ $(top_builddir)/axiom/src/om/libaxis2_axiom.la \
+ $(top_builddir)/util/src/libaxutil.la \
+ $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la \
+ $(top_builddir)/src/core/description/libaxis2_description.la \
+ $(top_builddir)/src/core/deployment/libaxis2_deployment.la \
+ $(top_builddir)/src/core/context/libaxis2_context.la \
+ $(top_builddir)/src/core/clientapi/libaxis2_clientapi.la \
+ $(top_builddir)/src/core/engine/libaxis2_engine.la \
+ $(top_builddir)/neethi/src/libneethi.la \
+ $(top_builddir)/src/core/transport/amqp/receiver/libaxis2_amqp_receiver.la \
+ $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \
+ -lpthread
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/deploymenti \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/transport/amqp/receiver \
+ -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver \
+ -I$(top_builddir)/src/core/transport/amqp/util \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
diff --git a/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.c b/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.c new file mode 100644 index 0000000..9f69283 --- /dev/null +++ b/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.c @@ -0,0 +1,232 @@ +/*
+ * 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
+ *
+ * tcp://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 <stdio.h>
+#include <stdlib.h>
+#include <axutil_error_default.h>
+#include <axutil_log_default.h>
+#include <axutil_thread_pool.h>
+#include <signal.h>
+#include <axutil_types.h>
+#include <ctype.h>
+#include <axiom_xml_reader.h>
+#include <axis2_amqp_server.h>
+#include <axis2_amqp_receiver.h>
+#include <axis2_qpid_receiver_interface.h>
+
+axis2_transport_receiver_t* receiver = NULL;
+axutil_env_t* server_env = NULL;
+
+axutil_env_t*
+init_server_env(
+ axutil_allocator_t* allocator,
+ const axis2_char_t* log_file_name)
+{
+ axutil_error_t* error = axutil_error_create(allocator);
+ axutil_log_t* log = axutil_log_create(allocator, NULL, log_file_name);
+ axutil_thread_pool_t* thread_pool = axutil_thread_pool_init(allocator);
+ axutil_env_t* env = axutil_env_create_with_error_log_thread_pool(allocator, error, log,
+ thread_pool);
+
+ axiom_xml_reader_init();
+
+ return env;
+}
+
+void
+server_exit(
+ int status)
+{
+ if(receiver)
+ {
+ axis2_transport_receiver_free(receiver, server_env);
+ }
+
+ if(server_env)
+ {
+ axutil_env_free(server_env);
+ }
+
+ axiom_xml_reader_cleanup();
+
+ exit(status);
+}
+
+void
+show_usage(
+ axis2_char_t* prog_name)
+{
+ fprintf(stdout, "\n Usage : %s", prog_name);
+ fprintf(stdout, " [-i QPID_BROKER_IP]");
+ fprintf(stdout, " [-p QPID_BROKER_PORT]");
+ fprintf(stdout, " [-r REPO_PATH]");
+ fprintf(stdout, " [-l LOG_LEVEL]");
+ fprintf(stdout, " [-f LOG_FILE]\n");
+ fprintf(stdout, " [-s LOG_FILE_SIZE]\n");
+ fprintf(stdout, " Options :\n");
+ fprintf(stdout, "\t-i QPID_BROKER_IP \t Qpid broker IP, default is 127.0.0.1\n");
+ fprintf(stdout,
+ "\t-p QPID_BROKER_PORT \t the port on which the Qpid broker listens, default is 5672\n");
+ fprintf(stdout, "\t-r REPO_PATH \t\t repository path, default is ../\n");
+ fprintf(stdout, "\t-l LOG_LEVEL\t\t log level, available log levels:"
+ "\n\t\t\t\t\t 0 - critical 1 - errors 2 - warnings"
+ "\n\t\t\t\t\t 3 - information 4 - debug 5- user 6 - trace"
+ "\n\t\t\t\t\t Default log level is 4(debug).\n");
+#ifndef WIN32
+ fprintf(stdout, "\t-f LOG_FILE\t\t log file, default is $AXIS2C_HOME/logs/axis2.log"
+ "\n\t\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n");
+#else
+ fprintf(stdout,
+ "\t-f LOG_FILE\t\t log file, default is %%AXIS2C_HOME%%\\logs\\axis2.log"
+ "\n\t\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n");
+#endif
+ fprintf(stdout,
+ "\t-s LOG_FILE_SIZE\t Maximum log file size in mega bytes, default maximum size is 1MB.\n");
+ fprintf(stdout, " Help :\n\t-h \t\t\t display this help screen.\n\n");
+}
+
+#ifndef WIN32
+
+void
+sig_handler(
+ int signal)
+{
+ switch(signal)
+ {
+ case SIGINT:
+ AXIS2_LOG_INFO(server_env->log, "Received signal SIGINT.Server shutting down");
+ axis2_amqp_receiver_stop(receiver, server_env);
+ AXIS2_LOG_INFO(server_env->log, "Shutdown complete ...");
+
+ server_exit(0);
+
+ case SIGPIPE:
+ AXIS2_LOG_INFO(server_env->log, "Received signal SIGPIPE.Client request serve aborted");
+ return;
+
+ case SIGSEGV:
+ fprintf(stderr, "Received deadly signal SIGSEGV. Terminating ...\n");
+ _exit(-1);
+ }
+}
+
+#endif
+
+int
+main(
+ int argc,
+ char* argv[])
+{
+ axutil_allocator_t* allocator = NULL;
+ extern char* optarg;
+ extern int optopt;
+ int c;
+ const axis2_char_t* qpid_broker_ip = NULL;
+ int qpid_broker_port = AXIS2_QPID_NULL_CONF_INT;
+ const axis2_char_t* repo_path = AXIS2_AMQP_SERVER_REPO_PATH;
+ axutil_log_levels_t log_level = AXIS2_LOG_LEVEL_DEBUG;
+ const axis2_char_t* log_file_name = AXIS2_AMQP_SERVER_LOG_FILE_NAME;
+ int log_file_size = AXUTIL_LOG_FILE_SIZE;
+
+ while((c = AXIS2_GETOPT(argc, argv, "i:p:r:l:f:s:h")) != -1)
+ {
+ switch(c)
+ {
+ case 'i':
+ qpid_broker_ip = optarg;
+ break;
+
+ case 'p':
+ qpid_broker_port = AXIS2_ATOI(optarg);
+ break;
+
+ case 'r':
+ repo_path = optarg;
+ break;
+
+ case 'l':
+ log_level = AXIS2_ATOI(optarg);
+ if(log_level < AXIS2_LOG_LEVEL_CRITICAL)
+ log_level = AXIS2_LOG_LEVEL_CRITICAL;
+ if(log_level > AXIS2_LOG_LEVEL_TRACE)
+ log_level = AXIS2_LOG_LEVEL_TRACE;
+ break;
+
+ case 'f':
+ log_file_name = optarg;
+ break;
+
+ case 's':
+ log_file_size = 1024 * 1024 * AXIS2_ATOI(optarg);
+ break;
+
+ case 'h':
+ show_usage(argv[0]);
+ return 0;
+
+ case ':':
+ fprintf(stderr, "\nOption -%c requires an operand\n", optopt);
+ show_usage(argv[0]);
+ return -1;
+
+ case '?':
+ if(isprint(optopt))
+ fprintf(stderr, "\nUnknown option `-%c'.\n", optopt);
+ show_usage(argv[0]);
+ return -1;
+ }
+ }
+
+ allocator = axutil_allocator_init(NULL);
+ if(!allocator)
+ {
+ server_exit(-1);
+ }
+
+ server_env = init_server_env(allocator, log_file_name);
+ server_env->log->level = log_level;
+ server_env->log->size = log_file_size;
+
+ axutil_error_init();
+
+#ifndef WIN32
+ signal(SIGINT, sig_handler);
+ signal(SIGPIPE, sig_handler);
+#endif
+
+ AXIS2_LOG_INFO(server_env->log, "Starting Axis2 AMQP Server ...");
+ AXIS2_LOG_INFO(server_env->log, "Repo Location : %s", repo_path);
+
+ receiver = axis2_amqp_receiver_create(server_env, repo_path, qpid_broker_ip, qpid_broker_port);
+ if(!receiver)
+ {
+ AXIS2_LOG_ERROR(server_env->log, AXIS2_LOG_SI,
+ "Server creation failed: Error code:" " %d :: %s", server_env->error->error_number,
+ AXIS2_ERROR_GET_MESSAGE(server_env->error));
+ server_exit(-1);
+ }
+
+ if(axis2_amqp_receiver_start(receiver, server_env) == AXIS2_FAILURE)
+ {
+ AXIS2_LOG_ERROR(server_env->log, AXIS2_LOG_SI,
+ "Server start failed: Error code:" " %d :: %s", server_env->error->error_number,
+ AXIS2_ERROR_GET_MESSAGE(server_env->error));
+ server_exit(-1);
+ }
+
+ return 0;
+}
diff --git a/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.h b/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.h new file mode 100644 index 0000000..82a200e --- /dev/null +++ b/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.h @@ -0,0 +1,41 @@ +/*
+ * 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
+ *
+ * tcp://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_AMQP_SERVER_H
+#define AXIS2_AMQP_SERVER_H
+
+#include <axis2_amqp_defines.h>
+#include <platforms/axutil_platform_auto_sense.h>
+
+axutil_env_t*
+init_server_env(axutil_allocator_t* allocator,
+ const axis2_char_t* log_file_name);
+
+void
+server_exit(int status);
+
+void
+show_usage(axis2_char_t* prog_name);
+
+#ifndef WIN32
+
+void
+sig_handler(int signal);
+
+#endif
+
+#endif
diff --git a/src/core/transport/amqp/util/Makefile.am b/src/core/transport/amqp/util/Makefile.am new file mode 100644 index 0000000..2b27d76 --- /dev/null +++ b/src/core/transport/amqp/util/Makefile.am @@ -0,0 +1,18 @@ +lib_LTLIBRARIES = libaxis2_amqp_util.la + +libaxis2_amqp_util_la_SOURCES = axis2_amqp_util.c + +libaxis2_amqp_util_la_LIBADD = $(top_builddir)/util/src/libaxutil.la + +libaxis2_amqp_util_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport/amqp/util \ + -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include + diff --git a/src/core/transport/amqp/util/axis2_amqp_defines.h b/src/core/transport/amqp/util/axis2_amqp_defines.h new file mode 100644 index 0000000..a892e9e --- /dev/null +++ b/src/core/transport/amqp/util/axis2_amqp_defines.h @@ -0,0 +1,65 @@ +/*
+ * 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_AMQP_DEFINES_H
+#define AXIS2_AMQP_DEFINES_H
+
+#include <axiom_mime_const.h>
+
+#define AXIS2_AMQP_EXCHANGE_DIRECT "amq.direct"
+
+#define AXIS2_AMQP_CONF_QPID_BROKER_IP "qpid_broker_ip"
+#define AXIS2_AMQP_CONF_QPID_BROKER_PORT "qpid_broker_port"
+#define AXIS2_AMQP_CONF_QPID_REQUEST_TIMEOUT "request_timeout"
+
+#define AXIS2_QPID_DEFAULT_BROKER_IP "127.0.0.1"
+#define AXIS2_QPID_DEFAULT_BROKER_PORT 5672
+#define AXIS2_QPID_DEFAULT_REQUEST_TIMEOUT 500
+#define AXIS2_QPID_NULL_CONF_INT -1
+
+#define AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP "qpid_broker_ip"
+#define AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT "qpid_broker_port"
+#define AXIS2_AMQP_CONF_CTX_PROPERTY_REQUEST_TIMEOUT "request_timeout"
+#define AXIS2_AMQP_CONF_CTX_PROPERTY_QUEUE_NAME "queue_name"
+
+#define AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO "qpid_reply_to"
+
+#define AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML "text/xml"
+#define AXIS2_AMQP_HEADER_ACCEPT_APPL_SOAP "application/soap+xml"
+#define AXIS2_AMQP_HEADER_ACCEPT_MULTIPART_RELATED AXIOM_MIME_TYPE_MULTIPART_RELATED
+#define AXIS2_AMQP_HEADER_CONTENT_TYPE_MIME_BOUNDARY "boundary"
+#define AXIS2_AMQP_HEADER_SOAP_ACTION "SOAPAction"
+#define AXIS2_AMQP_HEADER_CONTENT_TYPE "Content-Type"
+
+#define AXIS2_AMQP_TEMP_QUEUE_NAME_PREFIX "TempQueue"
+
+#define AXIS2_AMQP_SERVER_LOG_FILE_NAME "axis2_amqp_server.log"
+#define AXIS2_AMQP_SERVER_REPO_PATH "../"
+
+#define AXIS2_AMQP_EPR_PREFIX "amqp:"
+#define AXIS2_AMQP_EPR_SERVICE_PREFIX "services"
+#define AXIS2_AMQP_EPR_ANON_SERVICE_NAME "__ANONYMOUS_SERVICE__"
+
+#define AXIS2_AMQP_EQ '='
+#define AXIS2_AMQP_SEMI_COLON ';'
+#define AXIS2_AMQP_ESC_NULL '\0'
+#define AXIS2_AMQP_DOUBLE_QUOTE '"'
+#define AXIS2_AMQP_B_SLASH '\\'
+
+#define AXIS2_AMQP_NANOSEC_PER_MILLISEC 1000*1000
+
+#endif
diff --git a/src/core/transport/amqp/util/axis2_amqp_util.c b/src/core/transport/amqp/util/axis2_amqp_util.c new file mode 100644 index 0000000..cfef4a9 --- /dev/null +++ b/src/core/transport/amqp/util/axis2_amqp_util.c @@ -0,0 +1,823 @@ +/*
+ * 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 <axiom.h>
+#include <axiom_mime_parser.h>
+#include <axis2_util.h>
+#include <axis2_addr.h>
+#include <axutil_http_chunked_stream.h>
+#include <axis2_amqp_defines.h>
+#include <axis2_amqp_util.h>
+
+AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+axis2_amqp_util_get_in_desc_conf_value_string(
+ axis2_transport_in_desc_t* in_desc,
+ const axutil_env_t* env,
+ const axis2_char_t* param_name)
+{
+ axutil_param_t* param = NULL;
+ axis2_char_t* value = NULL;
+
+ param = (axutil_param_t*)axutil_param_container_get_param(
+ axis2_transport_in_desc_param_container(in_desc, env), env, param_name);
+ if(param)
+ {
+ value = axutil_param_get_value(param, env);
+ }
+
+ return value;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_amqp_util_get_in_desc_conf_value_int(
+ axis2_transport_in_desc_t* in_desc,
+ const axutil_env_t* env,
+ const axis2_char_t* param_name)
+{
+ axis2_char_t* value_str = NULL;
+ int value = AXIS2_QPID_NULL_CONF_INT;
+
+ value_str = axis2_amqp_util_get_in_desc_conf_value_string(in_desc, env, param_name);
+ if(value_str)
+ {
+ value = atoi(value_str);
+ }
+
+ return value;
+}
+
+AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+axis2_amqp_util_get_out_desc_conf_value_string(
+ axis2_transport_out_desc_t* out_desc,
+ const axutil_env_t* env,
+ const axis2_char_t* param_name)
+{
+ axutil_param_t* param = NULL;
+ axis2_char_t* value = NULL;
+
+ param = (axutil_param_t*)axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(out_desc, env), env, param_name);
+ if(param)
+ {
+ value = axutil_param_get_value(param, env);
+ }
+
+ return value;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_amqp_util_get_out_desc_conf_value_int(
+ axis2_transport_out_desc_t* out_desc,
+ const axutil_env_t* env,
+ const axis2_char_t* param_name)
+{
+ axis2_char_t* value_str = NULL;
+ int value = AXIS2_QPID_NULL_CONF_INT;
+
+ value_str = axis2_amqp_util_get_out_desc_conf_value_string(out_desc, env, param_name);
+ if(value_str)
+ {
+ value = atoi(value_str);
+ }
+
+ return value;
+}
+
+AXIS2_EXTERN axiom_soap_envelope_t* AXIS2_CALL
+axis2_amqp_util_get_soap_envelope(
+ axis2_amqp_response_t* response,
+ const axutil_env_t* env,
+ axis2_msg_ctx_t* msg_ctx)
+{
+ axiom_xml_reader_t* xml_reader = NULL;
+ axiom_stax_builder_t* stax_builder = NULL;
+ axiom_soap_builder_t* soap_builder = NULL;
+ axiom_soap_envelope_t* soap_envelope = NULL;
+ const axis2_char_t* soap_ns_uri = NULL;
+ axis2_char_t *soap_body_str = NULL;
+ int soap_body_len = 0;
+ axis2_bool_t is_mtom = AXIS2_FALSE;
+ axutil_hash_t *binary_data_map = NULL;
+ axis2_bool_t is_soap_11 = AXIS2_FALSE;
+
+ if(!response || !response->data || !response->content_type)
+ {
+ return NULL;
+ }
+
+ is_soap_11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env);
+
+ /* Handle MTOM */
+ if(strstr(response->content_type, AXIS2_AMQP_HEADER_ACCEPT_MULTIPART_RELATED))
+ {
+ axis2_char_t* mime_boundary = axis2_amqp_util_get_value_from_content_type(env,
+ response->content_type, AXIS2_AMQP_HEADER_CONTENT_TYPE_MIME_BOUNDARY);
+
+ if(mime_boundary)
+ {
+ axiom_mime_parser_t *mime_parser = NULL;
+ int soap_body_len = 0;
+ axutil_param_t *buffer_size_param = NULL;
+ axutil_param_t *max_buffers_param = NULL;
+ axutil_param_t *attachment_dir_param = NULL;
+ axis2_char_t *value_size = NULL;
+ axis2_char_t *value_num = NULL;
+ axis2_char_t *value_dir = NULL;
+ int size = 0;
+ int num = 0;
+
+ mime_parser = axiom_mime_parser_create(env);
+
+ buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE);
+
+ if(buffer_size_param)
+ {
+ value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env);
+
+ if(value_size)
+ {
+ size = atoi(value_size);
+ axiom_mime_parser_set_buffer_size(mime_parser, env, size);
+ }
+ }
+
+ max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS);
+
+ if(max_buffers_param)
+ {
+ value_num = (axis2_char_t*)axutil_param_get_value(max_buffers_param, env);
+
+ if(value_num)
+ {
+ num = atoi(value_num);
+ axiom_mime_parser_set_max_buffers(mime_parser, env, num);
+ }
+ }
+
+ attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR);
+
+ if(attachment_dir_param)
+ {
+ value_dir = (axis2_char_t*)axutil_param_get_value(attachment_dir_param, env);
+
+ if(value_dir)
+ {
+ axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
+ }
+ }
+
+ if(mime_parser)
+ {
+ axis2_callback_info_t* callback_ctx = NULL;
+ axutil_stream_t* stream = NULL;
+
+ callback_ctx = (axis2_callback_info_t*)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_callback_info_t));
+
+ stream = axutil_stream_create_basic(env);
+
+ if(stream)
+ {
+ axutil_stream_write(stream, env, response->data, response->length);
+ callback_ctx->env = env;
+ callback_ctx->in_stream = stream;
+ callback_ctx->content_length = response->length;
+ callback_ctx->unread_len = response->length;
+ callback_ctx->chunked_stream = NULL;
+ }
+
+ /*binary_data_map =
+ axiom_mime_parser_parse(mime_parser, env,
+ axis2_amqp_util_on_data_request,
+ (void*)callback_ctx,
+ mime_boundary);*/
+
+ if(!binary_data_map)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ soap_body_len = axiom_mime_parser_get_soap_body_len(mime_parser, env);
+
+ soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env);
+
+ axutil_stream_free(stream, env);
+ AXIS2_FREE(env->allocator, callback_ctx);
+ axiom_mime_parser_free(mime_parser, env);
+ }
+
+ AXIS2_FREE(env->allocator, mime_boundary);
+ }
+
+ is_mtom = AXIS2_TRUE;
+ }
+ else
+ {
+ soap_body_str = response->data;
+ soap_body_len = axutil_strlen(response->data);
+ }
+
+ soap_body_len = axutil_strlen(soap_body_str);
+
+ xml_reader = axiom_xml_reader_create_for_memory(env, soap_body_str, soap_body_len, NULL,
+ AXIS2_XML_PARSER_TYPE_BUFFER);
+ if(!xml_reader)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create XML Reader");
+ return NULL;
+ }
+
+ stax_builder = axiom_stax_builder_create(env, xml_reader);
+ if(!stax_builder)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create StAX Builder");
+ return NULL;
+ }
+
+ soap_ns_uri = is_soap_11 ? AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI
+ : AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
+
+ soap_builder = axiom_soap_builder_create(env, stax_builder, soap_ns_uri);
+ if(!soap_builder)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create SOAP Builder");
+ return NULL;
+ }
+
+ if(binary_data_map)
+ {
+ axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map);
+ }
+
+ soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
+
+ if(soap_envelope)
+ {
+ /* hack to get around MTOM problem */
+ axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
+
+ if(soap_body)
+ {
+ axiom_soap_body_has_fault(soap_body, env);
+ }
+ }
+
+ return soap_envelope;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_amqp_util_conf_ctx_get_server_side(
+ axis2_conf_ctx_t* conf_ctx,
+ const axutil_env_t* env)
+{
+ axutil_property_t* property = NULL;
+ axis2_char_t* value = NULL;
+
+ property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_IS_SVR_SIDE);
+ if(!property)
+ return AXIS2_TRUE;
+
+ value = (axis2_char_t*)axutil_property_get_value(property, env);
+ if(!value)
+ return AXIS2_TRUE;
+
+ return (axutil_strcmp(value, AXIS2_VALUE_TRUE) == 0) ? AXIS2_TRUE : AXIS2_FALSE;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_amqp_util_get_value_from_content_type(
+ const axutil_env_t * env,
+ const axis2_char_t * content_type,
+ const axis2_char_t * key)
+{
+ axis2_char_t *tmp = NULL;
+ axis2_char_t *tmp_content_type = NULL;
+ axis2_char_t *tmp2 = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, content_type, NULL);
+ AXIS2_PARAM_CHECK(env->error, key, NULL);
+
+ tmp_content_type = axutil_strdup(env, content_type);
+
+ if(!tmp_content_type)
+ {
+ return NULL;
+ }
+
+ tmp = strstr(tmp_content_type, key);
+
+ if(!tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp_content_type);
+ return NULL;
+ }
+
+ tmp = strchr(tmp, AXIS2_AMQP_EQ);
+ tmp2 = strchr(tmp, AXIS2_AMQP_SEMI_COLON);
+
+ if(tmp2)
+ {
+ *tmp2 = AXIS2_AMQP_ESC_NULL;
+ }
+
+ if(!tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp_content_type);
+ return NULL;
+ }
+
+ tmp2 = axutil_strdup(env, tmp + 1);
+
+ AXIS2_FREE(env->allocator, tmp_content_type);
+
+ if(*tmp2 == AXIS2_AMQP_DOUBLE_QUOTE)
+ {
+ tmp = tmp2;
+ tmp2 = axutil_strdup(env, tmp + 1);
+ tmp2[strlen(tmp2) - 1] = AXIS2_AMQP_ESC_NULL;
+
+ if(tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp);
+ tmp = NULL;
+ }
+ }
+
+ /* handle XOP */
+ if(*tmp2 == AXIS2_AMQP_B_SLASH && *(tmp2 + 1) == '\"')
+ {
+ tmp = tmp2;
+ tmp2 = axutil_strdup(env, tmp + 2);
+ tmp2[strlen(tmp2) - 3] = AXIS2_AMQP_ESC_NULL;
+
+ if(tmp)
+ {
+ AXIS2_FREE(env->allocator, tmp);
+ tmp = NULL;
+ }
+ }
+
+ return tmp2;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_amqp_util_on_data_request(
+ char* buffer,
+ int size,
+ void* ctx)
+{
+ const axutil_env_t* env = NULL;
+ int len = -1;
+ axis2_callback_info_t* cb_ctx = (axis2_callback_info_t*)ctx;
+ axutil_stream_t* in_stream = NULL;
+
+ if(!buffer || !ctx)
+ {
+ return 0;
+ }
+
+ if(cb_ctx->unread_len <= 0 && -1 != cb_ctx->content_length)
+ {
+ return 0;
+ }
+
+ env = ((axis2_callback_info_t*)ctx)->env;
+
+ in_stream = (axutil_stream_t*)((axis2_callback_info_t *)ctx)->in_stream;
+ --size; /* reserve space to insert trailing null */
+
+ len = axutil_stream_read(in_stream, env, buffer, size);
+
+ if(len > 0)
+ {
+ buffer[len] = AXIS2_AMQP_ESC_NULL;
+ ((axis2_callback_info_t*)ctx)->unread_len -= len;
+ }
+ else if(len == 0)
+ {
+ ((axis2_callback_info_t*)ctx)->unread_len = 0;
+ }
+
+ return len;
+}
+
+AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+axis2_amqp_util_conf_ctx_get_dual_channel_queue_name(
+ axis2_conf_ctx_t* conf_ctx,
+ const axutil_env_t* env)
+{
+ axutil_property_t* property = NULL;
+ axis2_char_t* queue_name = NULL;
+ axis2_char_t* value = NULL;
+
+ /* Get property */
+ property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_AMQP_CONF_CTX_PROPERTY_QUEUE_NAME);
+ if(!property) /* Very first call */
+ {
+ property = axutil_property_create(env);
+
+ axis2_conf_ctx_set_property(conf_ctx, env, AXIS2_AMQP_CONF_CTX_PROPERTY_QUEUE_NAME,
+ property);
+ }
+
+ /* Get queue name */
+ value = (axis2_char_t*)axutil_property_get_value(property, env);
+
+ /* AMQP listener and the sender are the two parties that are
+ * interested in the queue. Either party can create the queue.
+ * If the queue is already created by one party, "value" is
+ * not NULL. If "value" is NULL, that mean the caller of
+ * this method is supposed to create the queue */
+ if(value)
+ {
+ queue_name = (axis2_char_t*)AXIS2_MALLOC(env->allocator, axutil_strlen(value) + 1);
+ strcpy(queue_name, value);
+
+ /*axutil_property_set_value(property, env, NULL);*/
+ }
+ else
+ {
+ /* Create new queue name */
+ queue_name = axutil_stracat(env, AXIS2_AMQP_TEMP_QUEUE_NAME_PREFIX, axutil_uuid_gen(env));
+
+ /* Put queue name in the conf_ctx so that the sender will know */
+ axutil_property_set_value(property, env, (void*)queue_name);
+ }
+
+ return queue_name;
+}
+
+AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+axis2_amqp_util_conf_ctx_get_qpid_broker_ip(
+ axis2_conf_ctx_t* conf_ctx,
+ const axutil_env_t* env)
+{
+ axutil_property_t* property = NULL;
+ void* value = NULL;
+ axis2_char_t* broker_ip = AXIS2_QPID_DEFAULT_BROKER_IP;
+
+ property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP);
+
+ if(property)
+ {
+ value = axutil_property_get_value(property, env);
+
+ if(value)
+ {
+ broker_ip = (axis2_char_t*)value;
+ }
+ }
+
+ return broker_ip;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_amqp_util_conf_ctx_get_qpid_broker_port(
+ axis2_conf_ctx_t* conf_ctx,
+ const axutil_env_t* env)
+{
+ axutil_property_t* property = NULL;
+ void* value = NULL;
+ int broker_port = AXIS2_QPID_DEFAULT_BROKER_PORT;
+
+ property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT);
+
+ if(property)
+ {
+ value = axutil_property_get_value(property, env);
+
+ if(value)
+ {
+ broker_port = *(int*)value;
+ }
+ }
+
+ return broker_port;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_amqp_util_msg_ctx_get_use_separate_listener(
+ axis2_msg_ctx_t* msg_ctx,
+ const axutil_env_t* env)
+{
+ axutil_property_t* property = NULL;
+ axis2_char_t* value = NULL;
+ axis2_bool_t use_separate_listener = AXIS2_FALSE;
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_USE_SEPARATE_LISTENER);
+
+ if(property)
+ {
+ value = (axis2_char_t*)axutil_property_get_value(property, env);
+
+ if(value && (axutil_strcmp(AXIS2_VALUE_TRUE, value) == 0))
+ {
+ use_separate_listener = AXIS2_TRUE;
+ }
+ }
+
+ return use_separate_listener;
+}
+
+AXIS2_EXTERN axis2_amqp_destination_info_t* AXIS2_CALL
+axis2_amqp_util_msg_ctx_get_destination_info(
+ axis2_msg_ctx_t* msg_ctx,
+ const axutil_env_t* env)
+{
+ /* The destination URI that is expected by this method
+ * should be of one of the following formats
+ * 1. amqp://IP:PORT/services/SERVICE_NAME
+ * 2. jms:/SERVICE_NAME?java.naming.provider.url=tcp://IP:PORT...
+ * 3. TempQueue... */
+
+ axis2_endpoint_ref_t* endpoint_ref = NULL;
+ axis2_amqp_destination_info_t* destination_info = NULL;
+
+ destination_info = (axis2_amqp_destination_info_t*)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_amqp_destination_info_t));
+
+ destination_info->broker_ip = NULL;
+ destination_info->broker_port = AXIS2_QPID_NULL_CONF_INT;
+ destination_info->queue_name = NULL;
+
+ endpoint_ref = axis2_msg_ctx_get_to(msg_ctx, env);
+
+ if(endpoint_ref)
+ {
+ const axis2_char_t* endpoint_address_original = NULL;
+ axis2_char_t* endpoint_address = NULL;
+ char* substr = NULL;
+ char* token = NULL;
+ endpoint_address_original = axis2_endpoint_ref_get_address(endpoint_ref, env);
+
+ if(!endpoint_address_original)
+ return NULL;
+
+ endpoint_address = (axis2_char_t*)AXIS2_MALLOC(env->allocator, (sizeof(axis2_char_t)
+ * axutil_strlen(endpoint_address_original)) + 1);
+ strcpy((char*)endpoint_address, (char*)endpoint_address_original);
+
+ if((substr = strstr(endpoint_address, AXIS2_AMQP_EPR_PREFIX))) /* Start with amqp: */
+ {
+ if(strstr(endpoint_address, AXIS2_AMQP_EPR_ANON_SERVICE_NAME))
+ {
+ /* Server reply to dual-channel client */
+ axutil_property_t* property = NULL;
+ property = axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO);
+
+ if(property)
+ {
+ axis2_char_t* queue_name = (axis2_char_t*)axutil_property_get_value(property,
+ env);
+
+ if(queue_name)
+ {
+ destination_info->queue_name = (axis2_char_t*)AXIS2_MALLOC(env->allocator,
+ (sizeof(axis2_char_t) * strlen(queue_name)) + 1);
+ strcpy(destination_info->queue_name, queue_name);
+ }
+ }
+ }
+ else
+ {
+ substr += strlen(AXIS2_AMQP_EPR_PREFIX) + 2; /* 2 -> "//" */
+ if(substr) /* IP:PORT/services/SERVICE_NAME */
+ {
+ token = strtok(substr, ":");
+ if(token) /* IP */
+ {
+ axis2_char_t* broker_ip = (axis2_char_t*)AXIS2_MALLOC(env->allocator,
+ (sizeof(axis2_char_t) * strlen(token)) + 1);
+ strcpy(broker_ip, token);
+ destination_info->broker_ip = broker_ip;
+
+ token = strtok(NULL, "/"); /* PORT */
+ if(token)
+ {
+ destination_info->broker_port = atoi(token);
+
+ token = strtok(NULL, "#"); /* ... services/SERVICE_NAME */
+ if(token)
+ {
+ if((substr = strstr(token, AXIS2_AMQP_EPR_SERVICE_PREFIX)))
+ {
+ substr += strlen(AXIS2_AMQP_EPR_SERVICE_PREFIX) + 1; /* 1 -> "/" */
+ if(substr)
+ {
+ axis2_char_t* queue_name = (axis2_char_t*)AXIS2_MALLOC(
+ env->allocator, (sizeof(axis2_char_t) * strlen(substr))
+ + 1);
+ strcpy(queue_name, substr);
+ destination_info->queue_name = queue_name;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if(0 == strcmp(endpoint_address, AXIS2_WSA_ANONYMOUS_URL)) /* Required to work with Sandesha2 */
+ {
+ axutil_property_t* property = NULL;
+ property = axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO);
+
+ if(property)
+ {
+ axis2_char_t* queue_name = (axis2_char_t*)axutil_property_get_value(property, env);
+
+ if(queue_name)
+ {
+ destination_info->queue_name = (axis2_char_t*)AXIS2_MALLOC(env->allocator,
+ (sizeof(axis2_char_t) * strlen(queue_name)) + 1);
+ strcpy(destination_info->queue_name, queue_name);
+ }
+ }
+ }
+ else if((substr = strstr(endpoint_address, "jms:/")) && (substr == endpoint_address))
+ {
+
+ }
+
+ AXIS2_FREE(env->allocator, endpoint_address);
+ }
+ else
+ {
+ /* Single-channel blocking */
+ axutil_property_t* property = NULL;
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO);
+
+ if(property)
+ {
+ axis2_char_t* queue_name = (axis2_char_t*)axutil_property_get_value(property, env);
+
+ if(queue_name)
+ {
+ destination_info->queue_name = (axis2_char_t*)AXIS2_MALLOC(env->allocator,
+ (sizeof(axis2_char_t) * strlen(queue_name)) + 1);
+ strcpy(destination_info->queue_name, queue_name);
+ }
+ }
+ }
+
+ /* Get broker IP/Port from conf_ctx if they are not
+ * found in the destination URI */
+ if(!destination_info->broker_ip)
+ {
+ axis2_conf_ctx_t* conf_ctx = NULL;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ axutil_property_t* property = NULL;
+ property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP);
+
+ if(property)
+ {
+ axis2_char_t* broker_ip = (axis2_char_t*)axutil_property_get_value(property, env);
+
+ if(broker_ip)
+ {
+ destination_info->broker_ip = (axis2_char_t*)AXIS2_MALLOC(env->allocator,
+ (sizeof(axis2_char_t) * strlen(broker_ip)) + 1);
+ strcpy(destination_info->broker_ip, broker_ip);
+ }
+ }
+
+ }
+ }
+
+ if(AXIS2_QPID_NULL_CONF_INT == destination_info->broker_port)
+ {
+ axis2_conf_ctx_t* conf_ctx = NULL;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ axutil_property_t* property = NULL;
+ property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT);
+
+ if(property)
+ {
+ void* value = axutil_property_get_value(property, env);
+
+ if(value)
+ {
+ destination_info->broker_port = *(int*)value;
+ }
+ }
+ }
+ }
+
+ return destination_info;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_amqp_util_msg_ctx_get_request_timeout(
+ axis2_msg_ctx_t* msg_ctx,
+ const axutil_env_t* env)
+{
+ axis2_conf_ctx_t* conf_ctx = NULL;
+ axutil_property_t* property = NULL;
+ void* value = NULL;
+ int request_timeout = AXIS2_QPID_DEFAULT_REQUEST_TIMEOUT;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+
+ if(conf_ctx)
+ {
+ property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_AMQP_CONF_CTX_PROPERTY_REQUEST_TIMEOUT);
+
+ if(property)
+ {
+ value = axutil_property_get_value(property, env);
+
+ if(value)
+ {
+ request_timeout = *(int*)value;
+ }
+ }
+ }
+
+ return request_timeout;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_amqp_util_msg_ctx_get_server_side(
+ axis2_msg_ctx_t* msg_ctx,
+ const axutil_env_t* env)
+{
+ axis2_conf_ctx_t* conf_ctx = NULL;
+ axis2_bool_t is_server = AXIS2_FALSE;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+
+ if(conf_ctx)
+ {
+ is_server = axis2_amqp_util_conf_ctx_get_server_side(conf_ctx, env);
+ }
+
+ return is_server;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_amqp_response_free(
+ axis2_amqp_response_t* response,
+ const axutil_env_t* env)
+{
+ if(response)
+ {
+ if(response->data)
+ {
+ AXIS2_FREE(env->allocator, response->data);
+ }
+
+ if(response->content_type)
+ {
+ AXIS2_FREE(env->allocator, response->content_type);
+ }
+
+ AXIS2_FREE(env->allocator, response);
+ }
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_amqp_destination_info_free(
+ axis2_amqp_destination_info_t* destination_info,
+ const axutil_env_t* env)
+{
+ if(destination_info)
+ {
+ if(destination_info->broker_ip)
+ {
+ AXIS2_FREE(env->allocator, destination_info->broker_ip);
+ }
+
+ if(destination_info->queue_name)
+ {
+ AXIS2_FREE(env->allocator, destination_info->queue_name);
+ }
+
+ AXIS2_FREE(env->allocator, destination_info);
+ }
+}
+
diff --git a/src/core/transport/amqp/util/axis2_amqp_util.h b/src/core/transport/amqp/util/axis2_amqp_util.h new file mode 100644 index 0000000..0b3abbb --- /dev/null +++ b/src/core/transport/amqp/util/axis2_amqp_util.h @@ -0,0 +1,143 @@ +/*
+ * 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_AMQP_UTIL_H
+#define AXIS2_AMQP_UTIL_H
+
+#include <axis2_transport_in_desc.h>
+#include <axutil_param_container.h>
+#include <axiom_soap.h>
+#include <axis2_conf_ctx.h>
+#include <axutil_stream.h>
+#include <axis2_amqp_defines.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct axis2_amqp_response
+ {
+ void* data;
+ int length;
+ axis2_char_t* content_type;
+ } axis2_amqp_response_t;
+
+ typedef struct axis2_amqp_destination_info
+ {
+ axis2_char_t* broker_ip;
+ int broker_port;
+ axis2_char_t* queue_name;
+ } axis2_amqp_destination_info_t;
+
+ AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+ axis2_amqp_util_get_in_desc_conf_value_string(
+ axis2_transport_in_desc_t* in_desc,
+ const axutil_env_t* env,
+ const axis2_char_t* param_name);
+
+ AXIS2_EXTERN int AXIS2_CALL
+ axis2_amqp_util_get_in_desc_conf_value_int(
+ axis2_transport_in_desc_t* in_desc,
+ const axutil_env_t* env,
+ const axis2_char_t* param_name);
+
+ AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+ axis2_amqp_util_get_out_desc_conf_value_string(
+ axis2_transport_out_desc_t* out_desc,
+ const axutil_env_t* env,
+ const axis2_char_t* param_name);
+
+ AXIS2_EXTERN int AXIS2_CALL
+ axis2_amqp_util_get_out_desc_conf_value_int(
+ axis2_transport_out_desc_t* out_desc,
+ const axutil_env_t* env,
+ const axis2_char_t* param_name);
+
+ AXIS2_EXTERN axiom_soap_envelope_t* AXIS2_CALL
+ axis2_amqp_util_get_soap_envelope(
+ axis2_amqp_response_t* response,
+ const axutil_env_t* env,
+ axis2_msg_ctx_t* msg_ctx);
+
+ AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+ axis2_amqp_util_conf_ctx_get_server_side(
+ axis2_conf_ctx_t* conf_ctx,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+ axis2_amqp_util_get_value_from_content_type(
+ const axutil_env_t * env,
+ const axis2_char_t * content_type,
+ const axis2_char_t * key);
+
+ AXIS2_EXTERN int AXIS2_CALL
+ axis2_amqp_util_on_data_request(
+ char *buffer,
+ int size,
+ void *ctx);
+
+ AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+ axis2_amqp_util_conf_ctx_get_dual_channel_queue_name(
+ axis2_conf_ctx_t* conf_ctx,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN axis2_char_t* AXIS2_CALL
+ axis2_amqp_util_conf_ctx_get_qpid_broker_ip(
+ axis2_conf_ctx_t* conf_ctx,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN int AXIS2_CALL
+ axis2_amqp_util_conf_ctx_get_qpid_broker_port(
+ axis2_conf_ctx_t* conf_ctx,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+ axis2_amqp_util_msg_ctx_get_use_separate_listener(
+ axis2_msg_ctx_t* msg_ctx,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN axis2_amqp_destination_info_t* AXIS2_CALL
+ axis2_amqp_util_msg_ctx_get_destination_info(
+ axis2_msg_ctx_t* msg_ctx,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN int AXIS2_CALL
+ axis2_amqp_util_msg_ctx_get_request_timeout(
+ axis2_msg_ctx_t* msg_ctx,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+ axis2_amqp_util_msg_ctx_get_server_side(
+ axis2_msg_ctx_t* msg_ctx,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN void AXIS2_CALL
+ axis2_amqp_response_free(
+ axis2_amqp_response_t* response,
+ const axutil_env_t* env);
+
+ AXIS2_EXTERN void AXIS2_CALL
+ axis2_amqp_destination_info_free(
+ axis2_amqp_destination_info_t* destination_info,
+ const axutil_env_t* env);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/core/transport/http/Makefile.am b/src/core/transport/http/Makefile.am new file mode 100644 index 0000000..cc23d78 --- /dev/null +++ b/src/core/transport/http/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = sender receiver server diff --git a/src/core/transport/http/common/Makefile.am b/src/core/transport/http/common/Makefile.am new file mode 100644 index 0000000..8aaa2c6 --- /dev/null +++ b/src/core/transport/http/common/Makefile.am @@ -0,0 +1,29 @@ +lib_LTLIBRARIES = libaxis2_http_common.la + +libaxis2_http_common_la_LIBADD=$(top_builddir)/util/src/libaxutil.la\ + $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la + +libaxis2_http_common_la_SOURCES = http_header.c\ + http_out_transport_info.c\ + http_request_line.c\ + http_simple_request.c\ + http_simple_response.c\ + http_status_line.c\ + http_accept_record.c\ + http_response_writer.c\ + simple_http_svr_conn.c\ + http_worker.c + + +libaxis2_http_common_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport\ + -I$(top_builddir)/src/core/transport/http \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/http/common/http_accept_record.c b/src/core/transport/http/common/http_accept_record.c new file mode 100644 index 0000000..25f15b1 --- /dev/null +++ b/src/core/transport/http/common/http_accept_record.c @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_accept_record.h> +#include <axutil_string.h> +#include <axutil_types.h> +#include <stdio.h> +#include <stdlib.h> +#include <axis2_http_transport.h> + +struct axis2_http_accept_record +{ + axis2_char_t *name; + float quality; + int level; + axis2_char_t *record; +}; + +AXIS2_EXTERN axis2_http_accept_record_t *AXIS2_CALL +axis2_http_accept_record_create( + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_char_t *tmp_accept_record = NULL; + axis2_char_t *tmp = NULL; + axis2_http_accept_record_t *accept_record = NULL; + float quality = 1.0; + int level = -1; + axis2_char_t *name = NULL; + + AXIS2_PARAM_CHECK(env->error, str, NULL); + + tmp_accept_record = (axis2_char_t *)axutil_strdup(env, str); + if(!tmp_accept_record) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to strdup string %s", str); + return NULL; + } + + accept_record = (axis2_http_accept_record_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_accept_record_t)); + + if(!accept_record) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)accept_record, 0, sizeof(axis2_http_accept_record_t)); + accept_record->record = axutil_strtrim(env, tmp_accept_record, AXIS2_SPACE_COMMA); + + tmp = strchr(tmp_accept_record, AXIS2_Q); + if(tmp) + { + *tmp = AXIS2_ESC_NULL; + tmp++; + tmp = axutil_strtrim(env, tmp, AXIS2_EQ_N_SEMICOLON); + if(tmp) + { + sscanf(tmp, "%f", &quality); + AXIS2_FREE(env->allocator, tmp); + } + } + + tmp = strstr(tmp_accept_record, AXIS2_LEVEL); + if(tmp) + { + *tmp = AXIS2_ESC_NULL; + tmp++; + tmp = axutil_strtrim(env, tmp, AXIS2_EQ_N_SEMICOLON); + if(tmp) + { + sscanf(tmp, "%d", &level); + AXIS2_FREE(env->allocator, tmp); + } + } + + tmp = axutil_strtrim(env, tmp_accept_record, AXIS2_SPACE_SEMICOLON); + if(tmp) + { + name = tmp; + } + + if(!name || quality > 1.0 || quality < 0.0) + { + axis2_http_accept_record_free(accept_record, env); + return NULL; + } + + accept_record->name = name; + accept_record->quality = quality; + accept_record->level = level; + + AXIS2_FREE(env->allocator, tmp_accept_record); + return accept_record; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_accept_record_free( + axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + + if(!accept_record) + { + return; + } + + if(accept_record->name) + { + AXIS2_FREE(env->allocator, accept_record->name); + } + if(accept_record->record) + { + AXIS2_FREE(env->allocator, accept_record->record); + } + AXIS2_FREE(env->allocator, accept_record); + return; +} + +AXIS2_EXTERN float AXIS2_CALL +axis2_http_accept_record_get_quality_factor( + const axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + return accept_record->quality; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_accept_record_get_name( + const axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + return accept_record->name; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_accept_record_get_level( + const axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + return accept_record->level; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_accept_record_to_string( + axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + return accept_record->record; +} diff --git a/src/core/transport/http/common/http_header.c b/src/core/transport/http/common/http_header.c new file mode 100644 index 0000000..3ea2ffc --- /dev/null +++ b/src/core/transport/http/common/http_header.c @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_header.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <stdio.h> +#include <string.h> + +struct axis2_http_header +{ + axis2_char_t *name; + axis2_char_t *value; +}; + +AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL +axis2_http_header_create( + const axutil_env_t * env, + const axis2_char_t * name, + const axis2_char_t * value) +{ + axis2_http_header_t *http_header = NULL; + http_header = (axis2_http_header_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_header_t)); + if(!http_header) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)http_header, 0, sizeof(axis2_http_header_t)); + http_header->name = (axis2_char_t *)axutil_strdup(env, name); + http_header->value = (axis2_char_t *)axutil_strdup(env, value); + + return http_header; +} + +/** + * Creates http header object from a string having format "header_name: header_value" + * (e.g. "SOAPAction: urn:hello") + * @param env pointer to environment struct + * @param str pointer to str + */ +AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL +axis2_http_header_create_by_str( + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_char_t *tmp_str = NULL; + axis2_char_t *ch = NULL; + axis2_char_t *ch2 = NULL; + axis2_http_header_t *ret = NULL; + int tmp_str_len = 0; + AXIS2_PARAM_CHECK(env->error, str, NULL); + + /* + tmp_str = axutil_strdup(env, str); + if(!tmp_str) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to strdup string, %s", str); + return NULL; + } + */ + /* + * strdup is removed to increase the performance. This method is called from + * axis2_simple_http_svr_conn_read_request and axis2_http_client_recieve_header and both of them + * passes a temporary string. hence we can modify the contents without doing a strdup. + * Above code is commented after 1.6.0 . If no issue is found until 1.8.0, above can be removed + */ + tmp_str = (axis2_char_t *)str; + + /* remove trailing \r\n */ + tmp_str_len = axutil_strlen(tmp_str); + if((tmp_str_len >= 2) && (AXIS2_RETURN == tmp_str[tmp_str_len - 2])) + { + tmp_str[tmp_str_len - 2] = AXIS2_ESC_NULL; + } + + /* get http header */ + ch = strchr((const char *)tmp_str, AXIS2_COLON); + if(!ch) + { + /*AXIS2_FREE(env->allocator, tmp_str);*/ + return NULL; + } + *ch = AXIS2_ESC_NULL; + + /* get http header value */ + ch2 = ++ch; + + /* skip spaces */ + while(AXIS2_SPACE == *ch2) + { + ++ch2; + } + + ret = axis2_http_header_create(env, tmp_str, ch2); + /*AXIS2_FREE(env->allocator, tmp_str);*/ + return ret; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_header_free( + axis2_http_header_t * http_header, + const axutil_env_t * env) +{ + + if(!http_header) + { + return; + } + + if(http_header->name) + { + AXIS2_FREE(env->allocator, http_header->name); + } + if(http_header->value) + { + AXIS2_FREE(env->allocator, http_header->value); + } + + AXIS2_FREE(env->allocator, http_header); + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_header_to_external_form( + axis2_http_header_t * http_header, + const axutil_env_t * env) +{ + axis2_ssize_t len = 0; + axis2_char_t *external_form = NULL; + + AXIS2_PARAM_CHECK(env->error, http_header, NULL); + + len = axutil_strlen(http_header->name) + axutil_strlen(http_header->value) + 8; + external_form = (axis2_char_t *)AXIS2_MALLOC(env->allocator, len); + sprintf(external_form, "%s: %s%s", http_header->name, http_header->value, AXIS2_HTTP_CRLF); + return external_form; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_header_get_name( + const axis2_http_header_t * http_header, + const axutil_env_t * env) +{ + return http_header->name; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_header_get_value( + const axis2_http_header_t * http_header, + const axutil_env_t * env) +{ + return http_header->value; +} diff --git a/src/core/transport/http/common/http_out_transport_info.c b/src/core/transport/http/common/http_out_transport_info.c new file mode 100644 index 0000000..b70ee6c --- /dev/null +++ b/src/core/transport/http/common/http_out_transport_info.c @@ -0,0 +1,353 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_out_transport_info.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> + +#define AXIS2_INTF_TO_IMPL(out_transport_info) \ + ((axis2_http_out_transport_info_t *) \ + (out_transport_info)) + +axis2_status_t AXIS2_CALL +axis2_out_transport_info_impl_set_content_type( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + return axis2_http_out_transport_info_set_content_type(http_transport_info, env, content_type); +} + +axis2_status_t AXIS2_CALL +axis2_out_transport_info_impl_set_char_encoding( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + return axis2_http_out_transport_info_set_char_encoding(http_transport_info, env, encoding); +} + +axis2_status_t AXIS2_CALL +axis2_out_transport_info_impl_set_cookie_header( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * set_cookie) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + return axis2_http_out_transport_info_set_cookie_header(http_transport_info, env, set_cookie); +} + +axis2_status_t AXIS2_CALL +axis2_out_transport_info_impl_set_session( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * session_id, + const axis2_char_t * session_value) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + return axis2_http_out_transport_info_set_session(http_transport_info, env, session_id, + session_value); +} + +void AXIS2_CALL +axis2_out_transport_info_impl_free( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + axis2_http_out_transport_info_free(http_transport_info, env); + return; +} + +static const axis2_out_transport_info_ops_t ops_var = { + axis2_out_transport_info_impl_set_content_type, + axis2_out_transport_info_impl_set_char_encoding, + axis2_out_transport_info_impl_set_cookie_header, + axis2_out_transport_info_impl_set_session, + axis2_out_transport_info_impl_free }; + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_impl_set_content_type( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + axis2_char_t *tmp1 = NULL; + axis2_char_t *tmp2 = NULL; + + AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE); + if(http_out_transport_info->encoding) + { + axis2_char_t *charset_pos = axutil_strcasestr(content_type, AXIS2_CHARSET); + if(!charset_pos) + { + /* if "charset" not found in content_type string */ + tmp1 = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_CHARSET); + tmp2 = axutil_stracat(env, tmp1, http_out_transport_info->encoding); + axis2_http_simple_response_set_header(http_out_transport_info-> response, env, + axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, tmp2)); + AXIS2_FREE(env->allocator, tmp1); + AXIS2_FREE(env->allocator, tmp2); + } + else + { + /* "charset" is found in content_type string */ + axis2_http_simple_response_set_header(http_out_transport_info-> response, env, + axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, content_type)); + } + } + else + { + /* no http_out_transport_info->encoding */ + if(http_out_transport_info->response) + { + axis2_http_simple_response_set_header(http_out_transport_info-> response, env, + axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, content_type)); + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_impl_set_char_encoding( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE); + if(http_out_transport_info->encoding) + { + AXIS2_FREE(env->allocator, http_out_transport_info->encoding); + } + http_out_transport_info->encoding = axutil_strdup(env, encoding); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_impl_set_cookie_header( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * set_cookie) +{ + AXIS2_PARAM_CHECK(env->error, set_cookie, AXIS2_FAILURE); + if(http_out_transport_info->response) + { + axis2_http_simple_response_set_header(http_out_transport_info-> response, env, + axis2_http_header_create(env, AXIS2_HTTP_HEADER_SET_COOKIE, set_cookie)); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_impl_set_session( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * session_id, + const axis2_char_t * session_value) +{ + AXIS2_PARAM_CHECK(env->error, session_id, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, session_value, AXIS2_FAILURE); + if(http_out_transport_info->server) + { + env->set_session_fn((void *) http_out_transport_info->server, session_id, session_value); + } + return AXIS2_SUCCESS; +} +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_impl_free( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env) +{ + + if(!http_out_transport_info) + { + return; + } + + if(http_out_transport_info->response) + { + axis2_http_simple_response_free(http_out_transport_info->response, env); + } + if(http_out_transport_info->encoding) + { + AXIS2_FREE(env->allocator, http_out_transport_info->encoding); + } + AXIS2_FREE(env->allocator, http_out_transport_info); + return; +} + +AXIS2_EXTERN axis2_http_out_transport_info_t *AXIS2_CALL +axis2_http_out_transport_info_create( + const axutil_env_t * env, + axis2_http_simple_response_t * response) +{ + axis2_http_out_transport_info_t *http_out_transport_info = NULL; + + http_out_transport_info = (axis2_http_out_transport_info_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_out_transport_info_t)); + + if(!http_out_transport_info) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)http_out_transport_info, 0, sizeof(axis2_http_out_transport_info_t)); + http_out_transport_info->out_transport.ops = &ops_var; + http_out_transport_info->response = response; + http_out_transport_info->encoding = NULL; + http_out_transport_info->set_char_encoding = NULL; + http_out_transport_info->set_content_type = NULL; + http_out_transport_info->set_cookie_header = NULL; + http_out_transport_info->set_session = NULL; + http_out_transport_info->free_function = NULL; + + http_out_transport_info->set_char_encoding + = axis2_http_out_transport_info_impl_set_char_encoding; + http_out_transport_info->set_content_type = axis2_http_out_transport_info_impl_set_content_type; + http_out_transport_info->set_cookie_header = axis2_http_out_transport_info_impl_set_cookie_header; + http_out_transport_info->set_session = axis2_http_out_transport_info_impl_set_session; + http_out_transport_info->free_function = axis2_http_out_transport_info_impl_free; + + return http_out_transport_info; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_free( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env) +{ + http_out_transport_info->free_function(http_out_transport_info, env); + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_free_void_arg( + void *transport_info, + const axutil_env_t * env) +{ + axis2_http_out_transport_info_t *transport_info_l = NULL; + + transport_info_l = AXIS2_INTF_TO_IMPL(transport_info); + axis2_http_out_transport_info_free(transport_info_l, env); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_set_content_type( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + return http_out_transport_info->set_content_type(http_out_transport_info, env, content_type); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_set_char_encoding( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + return http_out_transport_info->set_char_encoding(http_out_transport_info, env, encoding); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_set_cookie_header( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * set_cookie) +{ + return http_out_transport_info->set_cookie_header(http_out_transport_info, env, set_cookie); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_set_session( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * session_id, + const axis2_char_t * session_value) +{ + return http_out_transport_info->set_session(http_out_transport_info, env, session_id, + session_value); +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_char_encoding_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + axis2_status_t(AXIS2_CALL * set_char_encoding) + (axis2_http_out_transport_info_t *, + const axutil_env_t *, + const axis2_char_t *)) +{ + out_transport_info->set_char_encoding = set_char_encoding; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_content_type_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + axis2_status_t(AXIS2_CALL * + set_content_type) (axis2_http_out_transport_info_t *, + const axutil_env_t *, + const axis2_char_t *)) +{ + out_transport_info->set_content_type = set_content_type; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_cookie_header_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + axis2_status_t(AXIS2_CALL * + set_cookie_header) (axis2_http_out_transport_info_t *, + const axutil_env_t *, + const axis2_char_t *)) +{ + out_transport_info->set_cookie_header = set_cookie_header; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_session_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + axis2_status_t(AXIS2_CALL * + set_session) (axis2_http_out_transport_info_t *, + const axutil_env_t *, + const axis2_char_t *, + const axis2_char_t *)) +{ + out_transport_info->set_session = set_session; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_free_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + void (AXIS2_CALL * free_function) (axis2_http_out_transport_info_t *, + const axutil_env_t *)) +{ + out_transport_info->free_function = free_function; +} + diff --git a/src/core/transport/http/common/http_request_line.c b/src/core/transport/http/common/http_request_line.c new file mode 100644 index 0000000..f12cbba --- /dev/null +++ b/src/core/transport/http/common/http_request_line.c @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_request_line.h> +#include <axutil_string.h> +#include <string.h> +#include <axis2_http_transport.h> +#include <stdio.h> + +struct axis2_http_request_line +{ + axis2_char_t *http_version; + axis2_char_t *method; + axis2_char_t *uri; +}; + +AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL +axis2_http_request_line_create( + const axutil_env_t * env, + const axis2_char_t * method, + const axis2_char_t * uri, + const axis2_char_t * http_version) +{ + axis2_http_request_line_t *request_line = NULL; + + AXIS2_PARAM_CHECK(env->error, method, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); + AXIS2_PARAM_CHECK(env->error, http_version, NULL); + + request_line = (axis2_http_request_line_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_request_line_t)); + + if(!request_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)request_line, 0, sizeof(axis2_http_request_line_t)); + request_line->method = (axis2_char_t *)axutil_strdup(env, method); + request_line->uri = (axis2_char_t *)axutil_strdup(env, uri); + request_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version); + + return request_line; +} + +void AXIS2_CALL +axis2_http_request_line_free( + axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + + if(!request_line) + { + return; + } + + if(request_line->method) + { + AXIS2_FREE(env->allocator, request_line->method); + } + if(request_line->uri) + { + AXIS2_FREE(env->allocator, request_line->uri); + } + if(request_line->http_version) + { + AXIS2_FREE(env->allocator, request_line->http_version); + } + + AXIS2_FREE(env->allocator, request_line); + return; +} + +/** + * Parses a line "<http method> <uri location> <http version>CRLF" and creates http_request_line + * object. E.g "POST /axis2/services/echo HTTP/1.1\r\n" + * @param env pointer to environment struct + * @param str pointer to the line to be parsed + * @return created object if success. NULL otherwise + */ +AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL +axis2_http_request_line_parse_line( + const axutil_env_t * env, + const axis2_char_t * str) +{ + /*axis2_char_t *req_line = NULL;*/ + axis2_char_t *method = NULL; + axis2_char_t *uri = NULL; + axis2_char_t *http_version = NULL; + axis2_http_request_line_t *ret = NULL; + axis2_char_t *tmp = NULL; + int i = 0; + + if(!str) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid parameter is given to parse"); + return NULL; + } + + tmp = axutil_strstr(str, AXIS2_HTTP_CRLF); + if(!tmp) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + + i = (int)(tmp - str); /* We are sure that the difference lies within the int range */ + + /* + req_line = AXIS2_MALLOC(env->allocator, i * sizeof(axis2_char_t) + 1); + if(!req_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memcpy(req_line, str, i * sizeof(axis2_char_t)); + req_line[i] = AXIS2_ESC_NULL; + tmp = req_line; + */ + /* we don't need to do a malloc and memcpy, because this method is only used by + * axis2_simple_http_svr_conn_read_request and it passes a temporary string. So, we can just + * set it as req_line and set the escape characters. this is done after 1.6.0 and if no issues + * found until 1.8.0, above code comment can be removed after 1.8.0 + */ + + tmp = (axis2_char_t *)str; + tmp[i] = AXIS2_ESC_NULL; + + /* find http method */ + method = tmp; + tmp = strchr(tmp, AXIS2_SPACE); + if(!tmp) + { + /*AXIS2_FREE(env->allocator, req_line);*/ + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + *tmp++ = AXIS2_ESC_NULL; + + /* find URI */ + uri = tmp; + tmp = strrchr(tmp, AXIS2_SPACE); + if(!tmp) + { + /*AXIS2_FREE(env->allocator, req_line);*/ + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + *tmp++ = AXIS2_ESC_NULL; + + /* find HTTP version */ + http_version = tmp; + ret = axis2_http_request_line_create(env, method, uri, http_version); + /*AXIS2_FREE(env->allocator, req_line);*/ + + return ret; +} + +axis2_char_t *AXIS2_CALL +axis2_http_request_line_get_method( + const axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + return request_line->method; +} + +axis2_char_t *AXIS2_CALL +axis2_http_request_line_get_http_version( + const axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + return request_line->http_version; +} + +axis2_char_t *AXIS2_CALL +axis2_http_request_line_get_uri( + const axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + return request_line->uri; +} + +axis2_char_t *AXIS2_CALL +axis2_http_request_line_to_string( + axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + int alloc_len = 0; + axis2_char_t *ret = NULL; + + alloc_len = axutil_strlen(request_line->method) + axutil_strlen(request_line->uri) + + axutil_strlen(request_line->http_version) + 6; + /* 5 = 2 * spaces + '/' +CR + LF + '\0' */ + + ret = AXIS2_MALLOC(env->allocator, alloc_len * sizeof(axis2_char_t)); + if(!ret) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(request_line->uri[0] != AXIS2_F_SLASH) + { + sprintf(ret, "%s /%s %s%s", request_line->method, request_line->uri, + request_line->http_version, AXIS2_HTTP_CRLF); + } + else + { + sprintf(ret, "%s %s %s%s", request_line->method, request_line->uri, + request_line->http_version, AXIS2_HTTP_CRLF); + } + return ret; +} diff --git a/src/core/transport/http/common/http_response_writer.c b/src/core/transport/http/common/http_response_writer.c new file mode 100644 index 0000000..eec2422 --- /dev/null +++ b/src/core/transport/http/common/http_response_writer.c @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_response_writer.h> +#include <axutil_array_list.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> + +struct axis2_http_response_writer +{ + axutil_stream_t *stream; + axis2_char_t *encoding; +}; + +AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL +axis2_http_response_writer_create( + const axutil_env_t * env, + axutil_stream_t * stream) +{ + return axis2_http_response_writer_create_with_encoding(env, stream, + AXIS2_HTTP_DEFAULT_CONTENT_CHARSET); +} + +AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL +axis2_http_response_writer_create_with_encoding( + const axutil_env_t * env, + axutil_stream_t * stream, + const axis2_char_t * encoding) +{ + axis2_http_response_writer_t *response_writer = NULL; + response_writer = (axis2_http_response_writer_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_response_writer_t)); + if(!response_writer) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + response_writer->stream = stream; + response_writer->encoding = (axis2_char_t *)axutil_strdup(env, encoding); + return response_writer; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_response_writer_free( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, response_writer->encoding); + AXIS2_FREE(env->allocator, response_writer); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_response_writer_get_encoding( + const axis2_http_response_writer_t * response_writer, + const axutil_env_t * env) +{ + return response_writer->encoding; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_write_char( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + char c) +{ + int write = -1; + if(!response_writer->stream) + { + return AXIS2_FAILURE; + } + + write = axutil_stream_write(response_writer->stream, env, &c, 1); + if(write < 0) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_write_buf( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + char *buf, + int offset, + axis2_ssize_t len) +{ + int write = -1; + + AXIS2_PARAM_CHECK(env->error, response_writer, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE); + + if(!response_writer->stream) + { + return AXIS2_FAILURE; + } + write = axutil_stream_write(response_writer->stream, env, buf, len); + if(write < 0) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_print_str( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + const char *str) +{ + int write = -1; + int len = -1; + + len = axutil_strlen(str); + if(!response_writer->stream) + { + return AXIS2_FAILURE; + } + write = axutil_stream_write(response_writer->stream, env, str, len); + + if(write < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "failed to write to stream string %s of length %d", str, len); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_print_int( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + int i) +{ + axis2_char_t int_str[10]; + sprintf(int_str, "%10d", i); + return axis2_http_response_writer_print_str(response_writer, env, int_str); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_println_str( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + const char *str) +{ + if(AXIS2_SUCCESS == axis2_http_response_writer_print_str(response_writer, env, str)) + { + return axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_println( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env) +{ + return axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF); +} diff --git a/src/core/transport/http/common/http_simple_request.c b/src/core/transport/http/common/http_simple_request.c new file mode 100644 index 0000000..9e10ce1 --- /dev/null +++ b/src/core/transport/http/common/http_simple_request.c @@ -0,0 +1,433 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_simple_request.h> +#include <axutil_array_list.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> +#include <string.h> +#include <axutil_types.h> + +struct axis2_http_simple_request +{ + axis2_http_request_line_t *request_line; + axutil_array_list_t *header_group; + axutil_stream_t *stream; + axis2_bool_t owns_stream; +}; + +AXIS2_EXTERN axis2_http_simple_request_t *AXIS2_CALL +axis2_http_simple_request_create( + const axutil_env_t * env, + axis2_http_request_line_t * request_line, + axis2_http_header_t ** http_headers, + axis2_ssize_t http_hdr_count, + axutil_stream_t * content) +{ + axis2_http_simple_request_t *simple_request = NULL; + simple_request = (axis2_http_simple_request_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_simple_request_t)); + if(!simple_request) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)simple_request, 0, sizeof(axis2_http_simple_request_t)); + simple_request->request_line = request_line; + simple_request->stream = content; + + if(!(simple_request->stream)) + { + simple_request->stream = axutil_stream_create_basic(env); + if(!simple_request->stream) + { + axis2_http_simple_request_free(simple_request, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + simple_request->owns_stream = AXIS2_TRUE; + } + + if((http_hdr_count > 0) && http_headers) + { + int i = 0; + simple_request->header_group = axutil_array_list_create(env, http_hdr_count); + + for(i = 0; i < (int)http_hdr_count; i++) + /* We are sure that the difference lies within the int range */ + { + axutil_array_list_add(simple_request->header_group, env, (void *)http_headers[i]); + } + } + + return simple_request; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_simple_request_free( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + /* free the stream only if we own it. Otherwise shouldn't free the stream + * since it belongs to the socket + */ + if(simple_request->owns_stream) + { + axutil_stream_free(simple_request->stream, env); + } + + if(simple_request->request_line) + { + axis2_http_request_line_free(simple_request->request_line, env); + } + + if(simple_request->header_group) + { + int i = 0; + axis2_http_header_t *tmp = NULL; + for(i = 0; i < axutil_array_list_size(simple_request->header_group, env); i++) + { + tmp = (axis2_http_header_t*)axutil_array_list_get(simple_request->header_group, env, i); + axis2_http_header_free(tmp, env); + } + axutil_array_list_free(simple_request->header_group, env); + } + AXIS2_FREE(env->allocator, simple_request); +} + +AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL +axis2_http_simple_request_get_request_line( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + return simple_request->request_line; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_simple_request_set_request_line( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + axis2_http_request_line_t * request_line) +{ + AXIS2_PARAM_CHECK(env->error, request_line, AXIS2_FAILURE); + simple_request->request_line = request_line; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_simple_request_contains_header( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + const axis2_char_t * name) +{ + int i = 0; + axis2_char_t *header_name = NULL; + int count = 0; + + AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); + + if(!simple_request->header_group) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "http simple request \ +does not contain headers, unable to find: %s header", name); + return AXIS2_FALSE; + } + + count = axutil_array_list_size(simple_request->header_group, env); + + if(0 == count) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "http simple request \ +contains zero headers, unable to find: %s header", name); + return AXIS2_FALSE; + } + + for(i = 0; i < count; i++) + { + header_name = axis2_http_header_get_name((axis2_http_header_t *)axutil_array_list_get( + simple_request->header_group, env, i), env); + if(0 == axutil_strcasecmp(name, header_name)) + { + return AXIS2_TRUE; + } + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_http_simple_request_get_headers( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + return simple_request->header_group; +} + +AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL +axis2_http_simple_request_get_first_header( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axutil_array_list_t *header_group = NULL; + int i = 0; + int count = 0; + + AXIS2_PARAM_CHECK(env->error, str, NULL); + + header_group = simple_request->header_group; + if(!simple_request->header_group) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "http simple request does not contain any headers; unable to find: %s header", str); + return NULL; + } + + if(0 == axutil_array_list_size(header_group, env)) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "http simple request contain zero headers, unable to find: %s header", str); + return NULL; + } + + count = axutil_array_list_size(header_group, env); + for(i = 0; i < count; i++) + { + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(str, tmp_name)) + { + return tmp_header; + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_simple_request_remove_headers( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + int i = 0; + int count = 0; + axutil_array_list_t *header_group = NULL; + + AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE); + + header_group = simple_request->header_group; + + if(!header_group) + { + /* Even though we couldn't complete the op, we are sure that the + * requred header is no more in the request. So we can proceed without a + * problem. + */ + return AXIS2_SUCCESS; + } + + count = axutil_array_list_size(header_group, env); + + for(i = 0; i < count; i++) + { + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(str, tmp_name)) + { + axis2_http_header_free(tmp_header, env); + axutil_array_list_remove(header_group, env, i); + break; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_simple_request_add_header( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + axis2_http_header_t * header) +{ + AXIS2_PARAM_CHECK(env->error, header, AXIS2_FAILURE); + + if(!simple_request->header_group) + { + simple_request->header_group = axutil_array_list_create(env, 1); + } + return axutil_array_list_add(simple_request->header_group, env, header); +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_http_simple_request_get_content_type( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + + tmp_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + return axis2_http_header_get_value(tmp_header, env); + } + + return AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_http_simple_request_get_charset( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + + tmp_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + axis2_char_t *value = axis2_http_header_get_value(tmp_header, env); + axis2_char_t *charset = (axis2_char_t *)strstr((char *)value, + (char *)AXIS2_HTTP_CHAR_SET_ENCODING); + if(charset) + { + charset = strchr((char *)charset, AXIS2_EQ); + return charset; + } + } + + return AXIS2_HTTP_DEFAULT_CONTENT_CHARSET; +} + +AXIS2_EXTERN axis2_ssize_t AXIS2_CALL +axis2_http_simple_request_get_content_length( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + int error_return = -1; + + tmp_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH); + if(tmp_header) + { + return AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env)); + } + return error_return; +} + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axis2_http_simple_request_get_body( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + return simple_request->stream; +} + +AXIS2_EXTERN axis2_ssize_t AXIS2_CALL +axis2_http_simple_request_get_body_bytes( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + char **buf) +{ + axutil_stream_t *body = NULL; + char *tmp_buf = NULL; + char *tmp_buf2 = NULL; + char *tmp_buf3 = NULL; + int length = 0; + int read_len = 0; + + body = simple_request->stream; + if(!body) + { + *buf = (char *)AXIS2_MALLOC(env->allocator, 1); + *buf[0] = '\0'; + return 0; + } + + length = axis2_http_simple_request_get_content_length(simple_request, env); + if(length > 0) + { + *buf = (char *)AXIS2_MALLOC(env->allocator, length + 1); + read_len = axutil_stream_read(body, env, *buf, length + 1); + return read_len; + } + + tmp_buf2 = AXIS2_MALLOC(env->allocator, 128 * sizeof(char)); + while(axutil_stream_read(body, env, tmp_buf2, 128) > 0) + { + tmp_buf3 = axutil_stracat(env, tmp_buf, tmp_buf2); + if(tmp_buf) + { + AXIS2_FREE(env->allocator, tmp_buf); + tmp_buf = NULL; + } + tmp_buf = tmp_buf3; + + } + + if(tmp_buf2) + { + AXIS2_FREE(env->allocator, tmp_buf2); + tmp_buf2 = NULL; + } + + if(tmp_buf) + { + *buf = tmp_buf; + return axutil_strlen(tmp_buf); + } + + *buf = (char *)AXIS2_MALLOC(env->allocator, 1); + *buf[0] = AXIS2_ESC_NULL; + return 0; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_simple_request_set_body_string( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + void *str, + unsigned int str_len) +{ + axutil_stream_t *body_stream = NULL; + + AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE); + + body_stream = simple_request->stream; + if(!body_stream) + { + body_stream = axutil_stream_create_basic(env); + if(!body_stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "unable to create stream\ +for stream %s of %d length", (axis2_char_t *)str, str_len); + return AXIS2_FAILURE; + } + simple_request->stream = body_stream; + simple_request->owns_stream = AXIS2_TRUE; + } + + axutil_stream_write(body_stream, env, str, str_len); + return AXIS2_SUCCESS; +} diff --git a/src/core/transport/http/common/http_simple_response.c b/src/core/transport/http/common/http_simple_response.c new file mode 100644 index 0000000..74acb80 --- /dev/null +++ b/src/core/transport/http/common/http_simple_response.c @@ -0,0 +1,615 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <axis2_http_simple_response.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> +#include <stdio.h> +#include <string.h> +#include <axutil_types.h> +#include <axiom_mime_part.h> + +#define AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE 2048 + +struct axis2_http_simple_response +{ + axis2_http_status_line_t *status_line; + axutil_array_list_t *header_group; + axutil_stream_t *stream; + axutil_array_list_t *mime_parts; + axis2_char_t *mtom_sending_callback_name; +}; + +AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL +axis2_http_simple_response_create( + const axutil_env_t * env, + axis2_http_status_line_t * status_line, + const axis2_http_header_t ** http_headers, + const axis2_ssize_t http_hdr_count, + axutil_stream_t * content) +{ + axis2_http_simple_response_t *ret = NULL; + ret = axis2_http_simple_response_create_default(env); + if(!ret) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 http simple response creation failed"); + return NULL; + } + + ret->status_line = status_line; + if(http_hdr_count > 0 && http_headers) + { + int i = 0; + ret->header_group = axutil_array_list_create(env, http_hdr_count); + + for(i = 0; i < (int)http_hdr_count; i++) + /* We are sure that the difference lies within the int range */ + { + axutil_array_list_add(ret->header_group, env, (void *)http_headers[i]); + } + } + ret->stream = content; + return ret; +} + +AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL +axis2_http_simple_response_create_default( + const axutil_env_t * env) +{ + axis2_http_simple_response_t *simple_response = NULL; + simple_response = (axis2_http_simple_response_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_simple_response_t)); + if(!simple_response) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)simple_response, 0, sizeof(axis2_http_simple_response_t)); + return simple_response; +} + +void AXIS2_CALL +axis2_http_simple_response_free( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + if(simple_response->status_line) + { + axis2_http_status_line_free(simple_response->status_line, env); + } + + if(simple_response->header_group) + { + int i = 0; + for(i = 0; i < axutil_array_list_size(simple_response->header_group, env); i++) + { + void *tmp = NULL; + tmp = axutil_array_list_get(simple_response-> header_group, env, i); + if(tmp) + { + axis2_http_header_free((axis2_http_header_t *)tmp, env); + } + } + axutil_array_list_free(simple_response->header_group, env); + } + + if(simple_response->mime_parts) + { + int i = 0; + for(i = 0; i < axutil_array_list_size(simple_response->mime_parts, env); i++) + { + void *mime_part = NULL; + mime_part = axutil_array_list_get(simple_response->mime_parts, env, i); + if(mime_part) + { + axiom_mime_part_free((axiom_mime_part_t *)mime_part, env); + } + } + axutil_array_list_free(simple_response->mime_parts, env); + } + + /* Stream is not freed. Assumption : stream doesn't belong to the response */ + + AXIS2_FREE(env->allocator, simple_response); +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_status_line( + struct axis2_http_simple_response * simple_response, + const axutil_env_t * env, + const axis2_char_t * http_ver, + const int status_code, + const axis2_char_t * phrase) +{ + if(!http_ver || !phrase || !status_code) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "invalid parameter given"); + return AXIS2_FAILURE; + } + + if(simple_response->status_line) + { + axis2_http_status_line_free(simple_response->status_line, env); + } + + simple_response->status_line = axis2_http_status_line_create_with_values( + env, http_ver, status_code, phrase); + if(!simple_response->status_line) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "http status line creation failed for string %s %3d %s", http_ver, status_code, phrase); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_phrase( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + return NULL; + } + + return axis2_http_status_line_get_reason_phrase(simple_response-> status_line, env); +} + +int AXIS2_CALL +axis2_http_simple_response_get_status_code( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + return -1; + } + return axis2_http_status_line_get_status_code(simple_response->status_line, env); +} + +axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_http_version( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + + return NULL; + } + return axis2_http_status_line_get_http_version(simple_response->status_line, env); +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_http_version( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_char_t *http_version) +{ + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + + return AXIS2_FAILURE; + } + axis2_http_status_line_set_http_version(simple_response->status_line, env, http_version); + return AXIS2_SUCCESS; +} + +axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_status_line( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + + return NULL; + } + return axis2_http_status_line_to_string(simple_response->status_line, env); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_http_simple_response_get_headers( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + return simple_response->header_group; +} + +axutil_array_list_t *AXIS2_CALL +axis2_http_simple_response_extract_headers( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + axutil_array_list_t *temp = NULL; + temp = simple_response->header_group; + if(temp) + { + simple_response->header_group = NULL; + } + return temp; +} + +axis2_http_header_t *AXIS2_CALL +axis2_http_simple_response_get_first_header( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + int i = 0; + int count = 0; + axutil_array_list_t *header_group = NULL; + + AXIS2_PARAM_CHECK(env->error, str, NULL); + + header_group = simple_response->header_group; + if(!simple_response->header_group) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 simple response , headers not available"); + return NULL; + } + + if(0 == axutil_array_list_size(header_group, env)) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "axis2 simple response , contains zero headers"); + + return NULL; + } + + count = axutil_array_list_size(header_group, env); + + for(i = 0; i < count; i++) + { + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(str, tmp_name)) + { + return tmp_header; + } + } + return NULL; + +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_remove_headers( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axutil_array_list_t *header_group = NULL; + int i = 0; + int count = 0; + + AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE); + + header_group = simple_response->header_group; + if(!header_group) + { + /* Even though we couldn't complete the op, we are sure that the + * required header is no more in the request. So we can proceed without a + * problem. + */ + return AXIS2_SUCCESS; + } + + count = axutil_array_list_size(header_group, env); + for(i = 0; i < count; i++) + { + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(str, tmp_name)) + { + axis2_http_header_free(tmp_header, env); + axutil_array_list_remove(header_group, env, i); + break; + } + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_header( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_http_header_t * header) +{ + int i = 0; + int count = 0; + axutil_array_list_t *header_group = NULL; + + AXIS2_PARAM_CHECK(env->error, header, AXIS2_FAILURE); + + if(!simple_response->header_group) + { + simple_response->header_group = axutil_array_list_create(env, 10); + axutil_array_list_add(simple_response->header_group, env, header); + return AXIS2_SUCCESS; + } + + /* If a header with the same name exists search and remove the old header */ + header_group = simple_response->header_group; + count = axutil_array_list_size(header_group, env); + for(i = 0; i < count; i++) + { + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(axis2_http_header_get_name(header, env), tmp_name)) + { + axis2_http_header_free(tmp_header, env); + axutil_array_list_set(header_group, env, i, header); + return AXIS2_SUCCESS; + } + } + + /* if header is not found, then we have to add it */ + axutil_array_list_add(header_group, env, header); + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_charset( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + + tmp_header = axis2_http_simple_response_get_first_header(simple_response, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + axis2_char_t *value = axis2_http_header_get_value(tmp_header, env); + axis2_char_t *charset = (axis2_char_t *)strstr((char *)value, + (char *)AXIS2_HTTP_CHAR_SET_ENCODING); + if(charset) + { + charset = strchr((char *)charset, AXIS2_EQ); + return charset; + } + } + + return AXIS2_HTTP_DEFAULT_CONTENT_CHARSET; +} + +axis2_ssize_t AXIS2_CALL +axis2_http_simple_response_get_content_length( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + int error_return = -1; + + tmp_header = axis2_http_simple_response_get_first_header(simple_response, env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH); + if(tmp_header) + { + return AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env)); + } + return error_return; +} + +const axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_content_type( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + + tmp_header = axis2_http_simple_response_get_first_header(simple_response, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + return axis2_http_header_get_value(tmp_header, env); + } + + return AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN; +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_body_string( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_char_t * str) +{ + axutil_stream_t *body_stream = NULL; + + AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE); + + body_stream = simple_response->stream; + if(!body_stream) + { + body_stream = axutil_stream_create_basic(env); + if(!body_stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to create basic stream for string %s", + str); + return AXIS2_FAILURE; + } + simple_response->stream = body_stream; + } + axutil_stream_write(body_stream, env, str, axutil_strlen(str)); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_body_stream( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axutil_stream_t * stream) +{ + /* + * We don't free the stream + * Problem in freeing is most of the time the stream doesn't belong + * to the http_simple_response + */ + simple_response->stream = stream; + return AXIS2_SUCCESS; +} + +axutil_stream_t *AXIS2_CALL +axis2_http_simple_response_get_body( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + return simple_response->stream; +} + +axis2_ssize_t AXIS2_CALL +axis2_http_simple_response_get_body_bytes( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_char_t ** buffer) +{ + axutil_stream_t *tmp_stream = NULL; + axis2_bool_t loop_state = AXIS2_TRUE; + int return_size = -1; + + if(!simple_response->stream) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_BODY, AXIS2_FAILURE); + return return_size; + } + tmp_stream = axutil_stream_create_basic(env); + while(loop_state) + { + int read = 0; + int write = 0; + char buf[AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE]; + + read = axutil_stream_read(simple_response->stream, env, buf, + AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE); + if(read < 0) + { + break; + } + write = axutil_stream_write(tmp_stream, env, buf, read); + if(read < (AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE - 1)) + { + break; + } + } + return_size = axutil_stream_get_len(tmp_stream, env); + + if(return_size > 0) + { + *buffer = (char *)AXIS2_MALLOC(env->allocator, sizeof(char) * (return_size + 1)); + + if(!buffer) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return -1; + } + + return_size = axutil_stream_read(tmp_stream, env, *buffer, return_size + 1); + } + axutil_stream_free(tmp_stream, env); + return return_size; +} + +axis2_bool_t AXIS2_CALL +axis2_http_simple_response_contains_header( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + const axis2_char_t * name) +{ + axis2_char_t *header_name = NULL; + int count = 0; + int i = 0; + + AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); + if(!simple_response->header_group) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 simple response , headers not available"); + return AXIS2_FALSE; + } + + count = axutil_array_list_size(simple_response->header_group, env); + if(0 == count) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "axis2 simple response , contains zero headers"); + return AXIS2_FALSE; + } + + for(i = 0; i < count; i++) + { + axis2_http_header_t *header = (axis2_http_header_t *)axutil_array_list_get( + simple_response->header_group, env, i); + header_name = axis2_http_header_get_name(header, env); + if(0 == axutil_strcasecmp(name, header_name)) + { + return AXIS2_TRUE; + } + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_http_simple_response_get_mime_parts( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + + return simple_response->mime_parts; + +} + +void AXIS2_EXTERN AXIS2_CALL +axis2_http_simple_response_set_mime_parts( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axutil_array_list_t *mime_parts) +{ + + simple_response->mime_parts = mime_parts; + +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_mtom_sending_callback_name( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + return simple_response->mtom_sending_callback_name; +} + +void AXIS2_EXTERN AXIS2_CALL +axis2_http_simple_response_set_mtom_sending_callback_name( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_char_t *mtom_sending_callback_name) +{ + simple_response->mtom_sending_callback_name = + mtom_sending_callback_name; +} diff --git a/src/core/transport/http/common/http_status_line.c b/src/core/transport/http/common/http_status_line.c new file mode 100644 index 0000000..fdf0fea --- /dev/null +++ b/src/core/transport/http/common/http_status_line.c @@ -0,0 +1,267 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_status_line.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <string.h> +#include <stdio.h> +#include <axutil_types.h> + +struct axis2_http_status_line +{ + axis2_char_t *line; + axis2_char_t *http_version; + axis2_char_t *status_code; + axis2_char_t *reason_phrase; +}; + +AXIS2_EXTERN axis2_http_status_line_t *AXIS2_CALL +axis2_http_status_line_create( + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_char_t *tmp_status_line = NULL; + axis2_char_t *reason_phrase = NULL; + axis2_char_t *status_code = NULL; + axis2_char_t *http_version = NULL; + int i = 0; + axis2_char_t *tmp = NULL; + axis2_http_status_line_t *status_line = NULL; + + status_line = (axis2_http_status_line_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_status_line_t)); + + if(!status_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)status_line, 0, sizeof(axis2_http_status_line_t)); + status_line->line = (axis2_char_t *)axutil_strdup(env, str); + + /* extract status code, phrase and version from given string */ + tmp = strstr(str, AXIS2_HTTP_CRLF); + if(!tmp) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + + i = (int)(tmp - str); /* We are sure that the difference lies within the int range */ + + tmp_status_line = AXIS2_MALLOC(env->allocator, i * sizeof(axis2_char_t) + 1); + if(!tmp_status_line) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memcpy(tmp_status_line, str, i * sizeof(axis2_char_t)); + tmp_status_line[i] = AXIS2_ESC_NULL; + tmp = tmp_status_line; + + /* get HTTP version */ + http_version = tmp; + tmp = strchr(tmp, AXIS2_SPACE); + if(!tmp) + { + AXIS2_FREE(env->allocator, tmp_status_line); + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + *tmp++ = AXIS2_ESC_NULL; + + /* get status code */ + status_code = tmp; + tmp = strchr(tmp, AXIS2_SPACE); + if(!tmp) + { + AXIS2_FREE(env->allocator, tmp_status_line); + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + *tmp++ = AXIS2_ESC_NULL; + + /* get reason phrase */ + reason_phrase = tmp; + + /* populate values */ + status_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version); + status_line->status_code = (axis2_char_t *)axutil_strdup(env, status_code); + status_line->reason_phrase = (axis2_char_t *)axutil_strdup(env, reason_phrase); + AXIS2_FREE(env->allocator, tmp_status_line); + + if(!status_line->http_version || !status_line->reason_phrase || !status_line->status_code) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return status_line; +} + +AXIS2_EXTERN axis2_http_status_line_t *AXIS2_CALL +axis2_http_status_line_create_with_values( + const axutil_env_t * env, + const axis2_char_t * http_ver, + const int status_code, + const axis2_char_t * phrase) +{ + axis2_http_status_line_t *status_line = NULL; + status_line = (axis2_http_status_line_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_status_line_t)); + if(!status_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)status_line, 0, sizeof(axis2_http_status_line_t)); + + status_line->status_code = AXIS2_MALLOC(env->allocator, 6 * sizeof(axis2_char_t *)); + if(!status_line->status_code) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_http_status_line_free(status_line, env); + return NULL; + } + sprintf(status_line->status_code, "%3d", status_code); + + status_line->http_version = axutil_strdup(env, http_ver); + status_line->reason_phrase = axutil_strdup(env, phrase); + if(!status_line->http_version || !status_line->reason_phrase) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + status_line->line = axutil_strcat(env, http_ver, " ", status_line->status_code, " ", phrase, + AXIS2_HTTP_CRLF, NULL); + if(!status_line->line) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return status_line; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_status_line_free( + axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + + if(!status_line) + { + return; + } + + if(status_line->line) + { + AXIS2_FREE(env->allocator, status_line->line); + } + if(status_line->http_version) + { + AXIS2_FREE(env->allocator, status_line->http_version); + } + if(status_line->status_code) + { + AXIS2_FREE(env->allocator, status_line->status_code); + } + if(status_line->reason_phrase) + { + AXIS2_FREE(env->allocator, status_line->reason_phrase); + } + + AXIS2_FREE(env->allocator, status_line); + return; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_status_line_get_status_code( + const axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + if(status_line->status_code) + { + return AXIS2_ATOI(status_line->status_code); + } + else + { + return AXIS2_CRITICAL_FAILURE; + } + +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_status_line_get_http_version( + const axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + return status_line->http_version; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_status_line_set_http_version( + axis2_http_status_line_t * status_line, + const axutil_env_t * env, + axis2_char_t *http_version) +{ + if(status_line->http_version) + { + AXIS2_FREE(env->allocator, status_line->http_version); + status_line->http_version = NULL; + } + + status_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version); + +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_status_line_get_reason_phrase( + const axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + return status_line->reason_phrase; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_status_line_starts_with_http( + axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + if(0 == axutil_strncasecmp(status_line->line, AXIS2_HTTP, 4)) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_status_line_to_string( + axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + return status_line->line; +} diff --git a/src/core/transport/http/common/http_worker.c b/src/core/transport/http/common/http_worker.c new file mode 100644 index 0000000..26ccce3 --- /dev/null +++ b/src/core/transport/http/common/http_worker.c @@ -0,0 +1,2064 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_worker.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <axis2_conf.h> +#include <axutil_string.h> +#include <axis2_msg_ctx.h> +#include <axis2_http_request_line.h> +#include <axis2_http_out_transport_info.h> +#include <axis2_http_transport_utils.h> +#include <axis2_http_accept_record.h> +#include <axis2_op_ctx.h> +#include <axis2_engine.h> +#include <axutil_uuid_gen.h> +#include <axutil_url.h> +#include <axutil_property.h> +#include <axiom_soap.h> +#include <string.h> +#include <axutil_string_util.h> +#include <stdio.h> +#include <stdlib.h> +#include <platforms/axutil_platform_auto_sense.h> + +struct axis2_http_worker +{ + axis2_conf_ctx_t *conf_ctx; + int svr_port; + axis2_bool_t is_application_client_side; +}; + +static axis2_status_t +axis2_http_worker_set_response_headers( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_simple_http_svr_conn_t * svr_conn, + axis2_http_simple_request_t * simple_request, + axis2_http_simple_response_t * simple_response, + axis2_ssize_t content_length); + +static axutil_hash_t * +axis2_http_worker_get_headers( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_http_simple_request_t * request); + +static axis2_http_simple_response_t * +axis2_http_worker_create_simple_response( + axis2_http_worker_t *http_worker, + const axutil_env_t *env); + +AXIS2_EXTERN axis2_http_worker_t *AXIS2_CALL +axis2_http_worker_create( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_http_worker_t *http_worker = NULL; + + http_worker = (axis2_http_worker_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_worker_t)); + + if(!http_worker) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + http_worker->conf_ctx = conf_ctx; + http_worker->svr_port = 9090; /* default - must set later */ + http_worker->is_application_client_side = AXIS2_FALSE; /* default is creating for application + server side */ + + return http_worker; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_worker_free( + axis2_http_worker_t * http_worker, + const axutil_env_t * env) +{ + http_worker->conf_ctx = NULL; + AXIS2_FREE(env->allocator, http_worker); + return; +} + +/* Each in-coming request is passed into this function for process. Basically http method to deliver + * is deduced here and call appropriate http processing function. + * eg. transport_utils_process_http_post_request() function. Once this function call done it will go + * through engine inflow phases and finally hit the message receiver for the operation. + */ +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_worker_process_request( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_simple_http_svr_conn_t * svr_conn, + axis2_http_simple_request_t * simple_request) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_msg_ctx_t *msg_ctx = NULL; + axutil_stream_t *request_body = NULL; + + /* Creating out_stream as basic stream */ + axutil_stream_t *out_stream = axutil_stream_create_basic(env); + axis2_http_simple_response_t *response = NULL; + + /* Transport in and out descriptions */ + axis2_transport_out_desc_t *out_desc = NULL; + axis2_transport_in_desc_t *in_desc = NULL; + + axis2_char_t *http_version = NULL; + axis2_char_t *soap_action = NULL; + axutil_string_t *soap_action_str = NULL; + axis2_bool_t processed = AXIS2_FALSE; + axis2_status_t status = AXIS2_FAILURE; + int content_length = -1; + axis2_http_header_t *encoding_header = NULL; + axis2_char_t *encoding_header_value = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_char_t *svr_ip = NULL; + axis2_char_t *peer_ip = NULL; + axutil_url_t *request_url = NULL; + axis2_http_out_transport_info_t *http_out_transport_info = NULL; + axutil_hash_t *headers = NULL; + axis2_char_t *url_external_form = NULL; + axis2_char_t *svc_grp_uuid = NULL; + axis2_char_t *path = NULL; + axutil_property_t *peer_property = NULL; + + /* REST processing variables */ + axis2_bool_t is_get = AXIS2_FALSE; + axis2_bool_t is_head = AXIS2_FALSE; + axis2_bool_t is_put = AXIS2_FALSE; + axis2_bool_t is_delete = AXIS2_FALSE; + axis2_bool_t request_handled = AXIS2_FALSE; + + /* HTTP and Proxy authentication */ + axis2_char_t *cookie_header_value = NULL; + /*axis2_char_t *set_cookie_header_value = NULL; + axis2_http_header_t *set_cookie_header = NULL; + axis2_http_header_t *connection_header = NULL;*/ + axis2_http_header_t *cookie_header = NULL; + axis2_char_t *accept_header_value = NULL; + axis2_http_header_t *accept_header = NULL; + axis2_char_t *accept_charset_header_value = NULL; + axis2_http_header_t *accept_charset_header = NULL; + axis2_char_t *accept_language_header_value = NULL; + axis2_http_header_t *accept_language_header = NULL; + + axis2_char_t *http_method = NULL; + axis2_http_request_line_t *request_line = NULL; + + axutil_hash_t *request_params = NULL; + axis2_char_t *request_uri = NULL; + axis2_char_t *url_ext_form = NULL; + const axis2_char_t *content_type = NULL; + + axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + axis2_msg_ctx_t **msg_ctx_map = NULL; + + AXIS2_PARAM_CHECK(env->error, svr_conn, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, simple_request, AXIS2_FALSE); + + conf_ctx = http_worker->conf_ctx; + if(!conf_ctx) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE); + return AXIS2_FALSE; + } + + content_length = axis2_http_simple_request_get_content_length(simple_request, env); + request_line = axis2_http_simple_request_get_request_line(simple_request, env); + http_method = axis2_http_request_line_get_method(request_line, env); + + http_version = axis2_http_request_line_get_http_version(request_line, env); + if(!http_version) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE); + return AXIS2_FALSE; + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Client HTTP version %s", http_version); + + encoding_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING); + if(encoding_header) + { + encoding_header_value = axis2_http_header_get_value(encoding_header, env); + } + + response = axis2_http_worker_create_simple_response(http_worker, env); + if(!response) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot create http simple response"); + return AXIS2_FALSE; + } + + /* if length is not given and it is not chunked, then return error to client */ + if((content_length < 0) && encoding_header_value + && (0 != axutil_strcmp(encoding_header_value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))) + { + if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_POST) + || 0 == axutil_strcasecmp(http_method, AXIS2_HTTP_PUT)) + { + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_LENGTH_REQUIRED_CODE_VAL, + AXIS2_HTTP_RESPONSE_LENGTH_REQUIRED_CODE_NAME); + + status = axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + axis2_http_simple_response_free(response, env); + return status; + } + } + + request_body = axis2_http_simple_request_get_body(simple_request, env); + + out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_HTTP); + in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_HTTP); + + msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc); + axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); + + cookie_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_COOKIE); + if(cookie_header) + { + char *session_str = NULL; + axis2_char_t *session_id = NULL; + + cookie_header_value = axis2_http_header_get_value(cookie_header, env); + session_id = axis2_http_transport_utils_get_session_id_from_cookie(env, + cookie_header_value); + if(session_id) + session_str = env->get_session_fn((void *) conf_ctx, session_id); + if(session_str) + axis2_http_transport_utils_set_session(env, msg_ctx, session_str); + } + + /*connection_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONNECTION); + if(connection_header) + { + axutil_property_t *connection_header_property = NULL; + axis2_char_t *connection_header_value = NULL; + connection_header_value = axis2_http_header_get_value(connection_header, env); + connection_header_property = axutil_property_create_with_args(env, + AXIS2_SCOPE_REQUEST, 0, 0, connection_header_value); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONNECTION, + connection_header_property); + }*/ + + /* Server and Peer IP's */ + svr_ip = axis2_simple_http_svr_conn_get_svr_ip(svr_conn, env); + peer_ip = axis2_simple_http_svr_conn_get_peer_ip(svr_conn, env); + + if(peer_ip) + { + peer_property = axutil_property_create(env); + axutil_property_set_value(peer_property, env, axutil_strdup(env, peer_ip)); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_SVR_PEER_IP_ADDR, peer_property); + } + + path = axis2_http_request_line_get_uri(request_line, env); + + request_url = axutil_url_create(env, AXIS2_HTTP_PROTOCOL, svr_ip, http_worker->svr_port, path); + if(request_url) + { + url_external_form = axutil_url_to_external_form(request_url, env); + } + + if(!url_external_form) + { + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL, AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME); + status = axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + axis2_http_simple_response_free(response, env); + response = NULL; + return status; + } + + accept_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_ACCEPT); + if(accept_header) + { + accept_header_value = axis2_http_header_get_value(accept_header, env); + } + if(accept_header_value) + { + axutil_array_list_t *accept_header_field_list = NULL; + axutil_array_list_t *accept_record_list = NULL; + accept_header_field_list = axutil_tokenize(env, accept_header_value, AXIS2_COMMA); + if(accept_header_field_list && axutil_array_list_size(accept_header_field_list, env) > 0) + { + axis2_char_t *token = NULL; + accept_record_list = axutil_array_list_create(env, axutil_array_list_size( + accept_header_field_list, env)); + do + { + if(token) + { + axis2_http_accept_record_t *rec = NULL; + rec = axis2_http_accept_record_create(env, token); + if(rec) + { + axutil_array_list_add(accept_record_list, env, rec); + } + AXIS2_FREE(env->allocator, token); + } + token = (axis2_char_t *)axutil_array_list_remove(accept_header_field_list, env, 0); + } + while(token); + } + if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0) + { + axis2_msg_ctx_set_http_accept_record_list(msg_ctx, env, accept_record_list); + } + } + + accept_charset_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_ACCEPT_CHARSET); + if(accept_charset_header) + { + accept_charset_header_value = axis2_http_header_get_value(accept_charset_header, env); + } + if(accept_charset_header_value) + { + axutil_array_list_t *accept_charset_header_field_list = NULL; + axutil_array_list_t *accept_charset_record_list = NULL; + accept_charset_header_field_list = axutil_tokenize(env, accept_charset_header_value, + AXIS2_COMMA); + if(accept_charset_header_field_list && axutil_array_list_size( + accept_charset_header_field_list, env) > 0) + { + axis2_char_t *token = NULL; + accept_charset_record_list = axutil_array_list_create(env, axutil_array_list_size( + accept_charset_header_field_list, env)); + do + { + if(token) + { + axis2_http_accept_record_t *rec = NULL; + rec = axis2_http_accept_record_create(env, token); + if(rec) + { + axutil_array_list_add(accept_charset_record_list, env, rec); + } + AXIS2_FREE(env->allocator, token); + } + token = (axis2_char_t *)axutil_array_list_remove(accept_charset_header_field_list, + env, 0); + } + while(token); + } + + if(accept_charset_record_list && axutil_array_list_size(accept_charset_record_list, env) + > 0) + { + axis2_msg_ctx_set_http_accept_charset_record_list(msg_ctx, env, + accept_charset_record_list); + } + } + + accept_language_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_ACCEPT_LANGUAGE); + if(accept_language_header) + { + accept_language_header_value = axis2_http_header_get_value(accept_language_header, env); + } + + if(accept_language_header_value) + { + axutil_array_list_t *accept_language_header_field_list = NULL; + axutil_array_list_t *accept_language_record_list = NULL; + accept_language_header_field_list = axutil_tokenize(env, accept_language_header_value, + AXIS2_COMMA); + if(accept_language_header_field_list && axutil_array_list_size( + accept_language_header_field_list, env) > 0) + { + axis2_char_t *token = NULL; + accept_language_record_list = axutil_array_list_create(env, axutil_array_list_size( + accept_language_header_field_list, env)); + do + { + if(token) + { + axis2_http_accept_record_t *rec = NULL; + rec = axis2_http_accept_record_create(env, token); + if(rec) + { + axutil_array_list_add(accept_language_record_list, env, rec); + } + AXIS2_FREE(env->allocator, token); + } + token = (axis2_char_t *)axutil_array_list_remove(accept_language_header_field_list, + env, 0); + } + while(token); + } + if(accept_language_record_list && axutil_array_list_size(accept_language_record_list, env) + > 0) + { + axis2_msg_ctx_set_http_accept_language_record_list(msg_ctx, env, + accept_language_record_list); + } + } + + /* Here out_stream is set into the in message context. out_stream is copied from in message context + * into the out message context later in core_utils_create_out_msg_ctx() function. The buffer in + * out_stream is finally filled with the soap envelope in http_transport_sender_invoke() function. + * To avoid double freeing of out_stream we reset the out message context at the end of engine + * receive function. + */ + axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream); + + headers = axis2_http_worker_get_headers(http_worker, env, simple_request); + axis2_msg_ctx_set_transport_headers(msg_ctx, env, headers); + + svc_grp_uuid = axutil_uuid_gen(env); + if(svc_grp_uuid) + { + axutil_string_t *svc_grp_uuid_str = axutil_string_create_assume_ownership(env, + &svc_grp_uuid); + axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, svc_grp_uuid_str); + axutil_string_free(svc_grp_uuid_str, env); + } + + http_out_transport_info = axis2_http_out_transport_info_create(env, response); + axis2_msg_ctx_set_out_transport_info(msg_ctx, env, &(http_out_transport_info->out_transport)); + + if(axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_SOAP_ACTION)) + { + soap_action = axis2_http_header_get_value(axis2_http_simple_request_get_first_header( + simple_request, env, AXIS2_HTTP_HEADER_SOAP_ACTION), env); + soap_action_str = axutil_string_create(env, soap_action); + } + + if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_GET)) + { + is_get = AXIS2_TRUE; + } + else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_HEAD)) + { + is_head = AXIS2_TRUE; + } + else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_DELETE)) + { + is_delete = AXIS2_TRUE; + } + else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_PUT)) + { + is_put = AXIS2_TRUE; + } + + request_uri = axis2_http_request_line_get_uri(request_line, env); + request_params = axis2_http_transport_utils_get_request_params(env, request_uri); + url_ext_form = axutil_url_to_external_form(request_url, env); + + content_type = axis2_http_simple_request_get_content_type(simple_request, env); + + if(is_get || is_head || is_delete) + { + + if(is_get) + { + /* HTTP GET */ + processed = axis2_http_transport_utils_process_http_get_request(env, msg_ctx, + request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx, + request_params); + } + else if(is_delete) + { + /* HTTP DELETE */ + processed = axis2_http_transport_utils_process_http_delete_request(env, msg_ctx, + request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx, + request_params); + } + else if(is_head) + { + /* HTTP HEAD */ + processed = axis2_http_transport_utils_process_http_head_request(env, msg_ctx, + request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx, + request_params); + } + + if(AXIS2_FALSE == processed) + { + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_char_t *wsdl = NULL; + axis2_bool_t is_services_path = AXIS2_FALSE; + + if(!is_delete) + { + axis2_char_t *temp = NULL; + /* check whether request url have "/services" */ + temp = strstr(axutil_url_get_path(request_url, env), AXIS2_REQUEST_URL_PREFIX); + if(temp) + { + temp += strlen(AXIS2_REQUEST_URL_PREFIX); + if(*temp == AXIS2_F_SLASH) + { + temp++; + } + if(!*temp || *temp == AXIS2_Q_MARK || *temp == AXIS2_H_MARK) + { + is_services_path = AXIS2_TRUE; + } + } + + } + + /* processing request for WSDL via "?wsdl" */ + wsdl = strstr(url_external_form, AXIS2_REQUEST_WSDL); + if(is_services_path) + { + /* request for service */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_OK_CODE_VAL, AXIS2_HTTP_RESPONSE_OK_CODE_NAME); + body_string = axis2_http_transport_utils_get_services_html(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(!is_delete && wsdl) + { + /* Request is not for delete and ask for wsdl */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_OK_CODE_VAL, AXIS2_HTTP_RESPONSE_OK_CODE_NAME); + body_string = axis2_http_transport_utils_get_services_static_wsdl(env, conf_ctx, + url_external_form); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_APPLICATION_XML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND) + { + + /* Processing SVC or Operation Not found case */ + axutil_array_list_t *method_list = NULL; + int size = 0; + method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env); + size = axutil_array_list_size(method_list, env); + if(method_list && size) + { + axis2_http_header_t *allow_header = NULL; + axis2_char_t *method_list_str = NULL; + axis2_char_t *temp; + int i = 0; + method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29); + + if(!method_list_str) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FALSE); + } + + temp = method_list_str; + for(i = 0; i < size; i++) + { + if(i) + { + sprintf(temp, AXIS2_COMMA_SPACE_STR); + temp += 2; + } + sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env, + i)); + temp += strlen(temp); + } + *temp = AXIS2_ESC_NULL; + + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL, + AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME); + + body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx); + allow_header = axis2_http_header_create(env, AXIS2_HTTP_HEADER_ALLOW, + method_list_str); + axis2_http_simple_response_set_header(response, env, allow_header); + AXIS2_FREE(env->allocator, method_list_str); + } + else + { + /* 404 Not Found */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME); + + body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx); + } + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL) + { + /* 400 Bad Request */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME); + + body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL) + { + + /* 408 , Request Time Out */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL, + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME); + + body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL) + { + /* 409, Conflict */ + + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL, AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME); + + body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL) + { + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_GONE_CODE_VAL, AXIS2_HTTP_RESPONSE_GONE_CODE_NAME); + + body_string = axis2_http_transport_utils_get_gone(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL) + { + /* 412 Precondition failed */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL, + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME); + + body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL) + { + /* 413 entity too large */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL, + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME); + + body_string + = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL) + { + /* 503, Service Unavailable*/ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME); + + body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else + { + /* 500 Internal Server Error */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME); + + body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + + if(body_string) + { + axis2_char_t str_len[10]; + if(!is_head) + { + axis2_http_simple_response_set_body_string(response, env, body_string); + } + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, simple_request, + response, 0); + + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + } + } + else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_POST) || is_put) + { + if(is_put) + { + axutil_property_t *property = NULL; + if(http_worker->is_application_client_side) + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE, 0, + AXIS2_VALUE_TRUE); + } + else + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE, + 0, AXIS2_VALUE_FALSE); + } + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE, + property); + status = axis2_http_transport_utils_process_http_put_request(env, msg_ctx, + request_body, out_stream, content_type, content_length, soap_action_str, + url_ext_form); + + } + else + { + axutil_property_t *property = NULL; + if(http_worker->is_application_client_side) + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE, 0, + AXIS2_VALUE_TRUE); + } + else + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE, + 0, AXIS2_VALUE_FALSE); + } + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE, + property); + status = axis2_http_transport_utils_process_http_post_request(env, msg_ctx, + request_body, out_stream, content_type, content_length, soap_action_str, + url_ext_form); + + } + if(url_ext_form) + AXIS2_FREE(env->allocator, url_ext_form); + if(AXIS2_FAILURE == status && (is_put || axis2_msg_ctx_get_doing_rest(msg_ctx, env))) + { + /* Failure Occur while processing REST */ + + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND) + { + axutil_array_list_t *method_list = NULL; + int size = 0; + method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env); + size = axutil_array_list_size(method_list, env); + if(method_list && size) + { + axis2_http_header_t *allow_header = NULL; + axis2_char_t *method_list_str = NULL; + axis2_char_t *temp; + int i = 0; + method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29); + if(!method_list_str) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FALSE); + } + + temp = method_list_str; + for(i = 0; i < size; i++) + { + if(i) + { + sprintf(temp, AXIS2_COMMA_SPACE_STR); + temp += 2; + } + sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env, + i)); + temp += strlen(temp); + } + *temp = AXIS2_ESC_NULL; + + /* 405 Method Not Allowed */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL, + AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME); + + body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx); + allow_header = axis2_http_header_create(env, AXIS2_HTTP_HEADER_ALLOW, + method_list_str); + axis2_http_simple_response_set_header(response, env, allow_header); + AXIS2_FREE(env->allocator, method_list_str); + } + else + { + /* 404 Not Found */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME); + + body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx); + } + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL) + { + /* 400, Bad Request */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME); + + body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL) + { + /* 408, Request Timeout */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL, + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME); + + body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL) + { + /* 409, Conflict Types */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL, AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME); + + body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL) + { + /* 410, Gone. Resource no longer available */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_GONE_CODE_VAL, AXIS2_HTTP_RESPONSE_GONE_CODE_NAME); + + body_string = axis2_http_transport_utils_get_gone(env, conf_ctx); + + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL) + { + /*410, Precondition for the url failed */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL, + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME); + + body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL) + { + /* 413, Request entity too large */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL, + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME); + + body_string + = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL) + { + /* 513, Service Unavailable */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME); + + body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else + { + /* 500, Internal Server Error */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME); + + body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx); + + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + + if(body_string) + { + axis2_char_t str_len[10]; + if(!is_head) + { + axis2_http_simple_response_set_body_string(response, env, body_string); + } + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, simple_request, + response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + } + else if(status == AXIS2_FAILURE) + { + axis2_msg_ctx_t *fault_ctx = NULL; + axis2_engine_t *engine = axis2_engine_create(env, conf_ctx); + axis2_http_request_line_t *req_line = NULL; + axis2_http_status_line_t *tmp_stat_line = NULL; + axis2_char_t status_line_str[100]; + axutil_property_t *http_error_property = NULL; + axis2_char_t *http_error_value = NULL; + axis2_char_t *fault_code = NULL; + int status_code = 0; + axis2_char_t *reason_phrase = NULL; + int stream_len = 0; + + if(!engine) + { + return AXIS2_FALSE; + } + + http_error_property = axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_HTTP_TRANSPORT_ERROR); + + if(http_error_property) + http_error_value = (axis2_char_t *)axutil_property_get_value(http_error_property, + env); + + if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX AXIS2_COLON_STR + AXIOM_SOAP11_FAULT_CODE_SENDER; + } + else + { + fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX AXIS2_COLON_STR + AXIOM_SOAP12_SOAP_FAULT_VALUE_SENDER; + } + + fault_ctx = axis2_engine_create_fault_msg_ctx(engine, env, msg_ctx, + fault_code, + axutil_error_get_message + (env->error)); + req_line = + axis2_http_simple_request_get_request_line(simple_request, env); + if (req_line) + { + if (!http_error_value) + { + sprintf(status_line_str, "%s %s\r\n", + http_version, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR); + } + else + { + sprintf(status_line_str, "%s %s", + http_version, + http_error_value); + } + } + else + { + sprintf(status_line_str, "%s %s\r\n", + AXIS2_HTTP_HEADER_PROTOCOL_11, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR); + } + + tmp_stat_line = axis2_http_status_line_create(env, status_line_str); + + if (!http_error_value) + { + axis2_engine_send_fault(engine, env, fault_ctx); + } + + status_code = axis2_http_status_line_get_status_code(tmp_stat_line, env); + reason_phrase = axis2_http_status_line_get_reason_phrase(tmp_stat_line, env); + + axis2_http_simple_response_set_status_line(response, env, + http_version, + status_code, + reason_phrase); + + axis2_http_simple_response_set_body_stream(response, env, + out_stream); + + stream_len = axutil_stream_get_len (out_stream, env); + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, + stream_len); + + status = axis2_simple_http_svr_conn_write_response(svr_conn, env, + response); + request_handled = AXIS2_TRUE; + if(tmp_stat_line) + { + axis2_http_status_line_free(tmp_stat_line, env); + tmp_stat_line = NULL; + } + } + } + else + { + /* Other case than, PUT, DELETE, HEAD, GET and POST */ + /* 501, Request method is not implemented */ + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_http_simple_response_set_status_line( + response, env, + http_version, + AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_NAME); + + body_string = + axis2_http_transport_utils_get_not_implemented(env, + conf_ctx); + cont_type = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + + if (body_string) + { + axis2_char_t str_len[10]; + axis2_http_simple_response_set_body_string(response, env, + body_string); + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, + str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + } + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if (op_ctx) + { + /*axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t **msg_ctx_map = NULL;*/ + axis2_char_t *language_str = NULL; + + msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; + if (out_msg_ctx) + { + language_str = axis2_msg_ctx_get_content_language(out_msg_ctx, env); + } + + if (language_str && *language_str && !request_handled) + { + axis2_http_header_t *language = NULL; + language = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LANGUAGE, + language_str); + axis2_http_simple_response_set_header(response, env, language); + } + } + + if (!request_handled) + { + axis2_bool_t do_rest = AXIS2_FALSE; + axis2_bool_t response_written = AXIS2_FALSE; + if (is_get || is_head || is_put || is_delete || + axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + { + do_rest = AXIS2_TRUE; + } + + if ((accept_header_value || accept_charset_header_value || + accept_language_header_value) && do_rest) + { + axis2_char_t *content_type_header_value = NULL; + axis2_http_header_t *content_type_header = NULL; + axis2_char_t *temp = NULL; + axis2_char_t *language_header_value = NULL; + axis2_http_header_t *language_header = NULL; + content_type_header = axis2_http_simple_response_get_first_header( + response, + env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + + language_header = axis2_http_simple_response_get_first_header( + response, + env, + AXIS2_HTTP_HEADER_CONTENT_LANGUAGE); + + if (content_type_header) + { + content_type_header_value = axis2_http_header_get_value(content_type_header, + env); + } + + if (content_type_header_value) + { + temp = axutil_strdup(env, content_type_header_value); + } + + if (language_header) + { + language_header_value = axis2_http_header_get_value(language_header, + env); + } + + if (temp) + { + axis2_char_t *content_type = NULL; + axis2_char_t *char_set = NULL; + axis2_char_t *temp2 = NULL; + + temp2 = strchr(temp, AXIS2_SEMI_COLON); + if (temp2) + { + *temp2 = AXIS2_ESC_NULL; + temp2++; + char_set = axutil_strcasestr(temp2, AXIS2_HTTP_CHAR_SET_ENCODING); + } + + if (char_set) + { + char_set = axutil_strltrim(env, char_set, AXIS2_SPACE_TAB_EQ); + } + + content_type = axutil_strtrim(env, temp, NULL); + + if (temp) + { + AXIS2_FREE(env->allocator, temp); + temp = NULL; + } + + if (content_type && accept_header_value && + !axutil_strcasestr(accept_header_value, content_type)) + { + temp2 = strchr(content_type, AXIS2_F_SLASH); + if (temp2) + { + *temp2 = AXIS2_ESC_NULL; + temp = AXIS2_MALLOC(env->allocator, + sizeof(axis2_char_t) * + ((int)strlen(content_type) + 3)); + if (!temp) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FALSE; + } + + sprintf(temp, "%s/*", content_type); + if (!axutil_strcasestr(accept_header_value, temp) && + !strstr(accept_header_value, AXIS2_HTTP_HEADER_ACCEPT_ALL)) + { + /* 406, Not Acceptable */ + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME); + + body_string = + axis2_http_transport_utils_get_not_acceptable(env, + conf_ctx); + cont_type = + axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + if (body_string) + { + axis2_char_t str_len[10]; + axis2_http_simple_response_set_body_string(response, env, + body_string); + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = + axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, + str_len); + + axis2_http_simple_response_set_header(response, + env, + cont_len); + } + + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + response_written = AXIS2_TRUE; + } + AXIS2_FREE(env->allocator, temp); + } + } + + if (content_type) + { + AXIS2_FREE(env->allocator, content_type); + } + + if (char_set) + { + temp2 = strchr(char_set, AXIS2_EQ); + } + + if (temp2) + { + ++temp2; + } + + if (char_set && accept_charset_header_value && + !axutil_strcasestr(accept_charset_header_value, char_set) && + !axutil_strcasestr(accept_charset_header_value, temp2)) + { + /* 406, Not Acceptable */ + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME); + body_string = + axis2_http_transport_utils_get_not_acceptable(env, + conf_ctx); + cont_type = + axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + if (body_string) + { + axis2_char_t str_len[10]; + axis2_http_simple_response_set_body_string(response, env, + body_string); + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, + str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + response_written = AXIS2_TRUE; + } + if (char_set) + { + AXIS2_FREE(env->allocator, char_set); + } + } + + if (language_header_value) + { + if (accept_language_header_value && + !axutil_strcasestr(accept_language_header_value, + language_header_value)) + { + /* 406, Not acceptable */ + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME); + + body_string = + axis2_http_transport_utils_get_not_acceptable(env, + conf_ctx); + cont_type = + axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + axis2_http_simple_response_remove_headers( + response, + env, + AXIS2_HTTP_HEADER_CONTENT_LANGUAGE); + + if (body_string) + { + axis2_char_t str_len[10]; + axis2_http_simple_response_set_body_string(response, env, + body_string); + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, + str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + response_written = AXIS2_TRUE; + } + } + } + + if (!response_written) + { + /* If in there is a soap message is to to be sent in the back channel then we go inside this + * block. Somewhere in the receiveing end axis2_op_ctx_set_response_written() function has + * been called by this time to indicate to append the message into the http back channel. + */ + if (op_ctx && axis2_op_ctx_get_response_written(op_ctx, env)) + { + if (do_rest) + { + /*axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + axis2_msg_ctx_t **msg_ctx_map = NULL;*/ + + /*msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];*/ + in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN]; + if (in_msg_ctx) + { + /* TODO: Add neccessary handling */ + } + if (out_msg_ctx) + { + int size = 0; + axutil_array_list_t *output_header_list = NULL; + output_header_list = + axis2_msg_ctx_get_http_output_headers(out_msg_ctx, + env); + if (output_header_list) + { + size = axutil_array_list_size(output_header_list, + env); + } + while (size) + { + axis2_http_header_t *simple_header = NULL; + size--; + simple_header = (axis2_http_header_t *) + axutil_array_list_get(output_header_list, + env, size); + axis2_http_simple_response_set_header(response, + env, + simple_header); + } + + if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) + { + int status_code = 0; + axis2_char_t *status_code_str = NULL; + status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); + + switch (status_code) + { + case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_CONTINUE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_ACK_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_ACK_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_GONE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME; + break; + default: + status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL; + status_code_str = + AXIS2_HTTP_RESPONSE_OK_CODE_NAME; + break; + } + + axis2_http_simple_response_set_status_line(response, env, + http_version, + status_code, + status_code_str); + request_handled = AXIS2_TRUE; + } + } + } + + if (!request_handled) + { + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_OK_CODE_VAL, + AXIS2_HTTP_RESPONSE_OK_CODE_NAME); + + if (!is_head) + { + /* This is where we append the message into the http back channel.*/ + axis2_http_simple_response_set_body_stream(response, env, out_stream); + } + } + } + else if (op_ctx) + { + /* If response is not written */ + if (do_rest) + { + /*axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + axis2_msg_ctx_t **msg_ctx_map = NULL;*/ + + msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; + in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN]; + if (in_msg_ctx) + { + /* TODO: Add neccssary handling */ + } + if (out_msg_ctx) + { + int size = 0; + axutil_array_list_t *output_header_list = NULL; + output_header_list = + axis2_msg_ctx_get_http_output_headers(out_msg_ctx, + env); + if (output_header_list) + { + size = axutil_array_list_size(output_header_list, + env); + } + + while (size) + { + axis2_http_header_t *simeple_header = NULL; + size--; + simeple_header = (axis2_http_header_t *) + axutil_array_list_get(output_header_list, + env, size); + axis2_http_simple_response_set_header(response, env, + simeple_header); + } + + if (axis2_msg_ctx_get_no_content(out_msg_ctx, env)) + { + if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) + { + int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); + axis2_char_t *status_code_str = NULL; + switch (status_code) + { + case AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME; + break; + default: + status_code = + AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL; + status_code_str = + AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_NAME; + break; + } + axis2_http_simple_response_set_status_line( + response, env, http_version, + status_code, + status_code_str); + } + else + { + /* status code not available in msg_ctx */ + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL, + AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_NAME); + } + + request_handled = AXIS2_TRUE; + } + else if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) + { + int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); + axis2_char_t *status_code_str = NULL; + switch (status_code) + { + case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_CONTINUE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_OK_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_OK_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_GONE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME; + break; + default: + status_code = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL; + status_code_str = + AXIS2_HTTP_RESPONSE_ACK_CODE_NAME; + break; + } + axis2_http_simple_response_set_status_line( + response, env, http_version, + status_code, + status_code_str); + + request_handled = AXIS2_TRUE; + } + } + } + if (!request_handled) + { + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_ACK_CODE_VAL, + AXIS2_HTTP_RESPONSE_ACK_CODE_NAME); + } + } + else + { + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_ACK_CODE_VAL, + AXIS2_HTTP_RESPONSE_ACK_CODE_NAME); + } + + if (!response_written) + { + int stream_len = 0; + stream_len = axutil_stream_get_len(out_stream, env); + + /*axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, + stream_len);*/ + + /* This is where it actually write to the wire in the http back channel + * append case. */ + if(out_msg_ctx) + { + axutil_array_list_t *mime_parts = NULL; + mime_parts = axis2_msg_ctx_get_mime_parts(out_msg_ctx, env); + /* If mime_parts is there then that means we send MTOM. So + * in order to send MTOM we are enabling HTTP1.1 and cunk transfer + * encoding */ + + if(mime_parts) + { + axis2_http_header_t *transfer_enc_header = NULL; + axutil_param_t *callback_name_param = NULL; + axis2_char_t *mtom_sending_callback_name = NULL; + + /* Getting the sender callback name paramter if it is + * specified in the configuration file */ + + callback_name_param = axis2_msg_ctx_get_parameter(out_msg_ctx, env , + AXIS2_MTOM_SENDING_CALLBACK); + if(callback_name_param) + { + mtom_sending_callback_name = + (axis2_char_t *) axutil_param_get_value (callback_name_param, env); + if(mtom_sending_callback_name) + { + axis2_http_simple_response_set_mtom_sending_callback_name( + response, env, mtom_sending_callback_name); + } + } + + axis2_http_simple_response_set_mime_parts(response, env, mime_parts); + + axis2_http_simple_response_set_http_version(response, env, + AXIS2_HTTP_HEADER_PROTOCOL_11); + + transfer_enc_header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED); + + axis2_http_simple_response_set_header(response, env, + transfer_enc_header); + + /* In the chunking case content-length is zero */ + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, + 0); + } + else + { + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, + stream_len); + } + } + status = axis2_simple_http_svr_conn_write_response(svr_conn, + env, + response); + } + } + } + + if (url_external_form) + { + AXIS2_FREE(env->allocator, url_external_form); + url_external_form = NULL; + } + if (op_ctx) + { + axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + axis2_msg_ctx_t **msg_ctx_map = NULL; + axis2_char_t *msg_id = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + + out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; + in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN]; + + if (out_msg_ctx) + { + axis2_msg_ctx_free(out_msg_ctx, env); + out_msg_ctx = NULL; + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL; + } + + if (in_msg_ctx) + { + msg_id = axutil_strdup(env, axis2_msg_ctx_get_msg_id(in_msg_ctx, env)); + conf_ctx = axis2_msg_ctx_get_conf_ctx(in_msg_ctx, env); + + axis2_msg_ctx_free(in_msg_ctx, env); + in_msg_ctx = NULL; + msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL; + } + + if (!axis2_op_ctx_is_in_use(op_ctx, env)) + { + axis2_op_ctx_destroy_mutex(op_ctx, env); + if (conf_ctx && msg_id) + { + axis2_conf_ctx_register_op_ctx(conf_ctx, env, msg_id, NULL); + + AXIS2_FREE(env->allocator, msg_id); + } + axis2_op_ctx_free(op_ctx, env); + } + + } /* Done freeing message contexts */ + + msg_ctx = NULL; + axutil_url_free(request_url, env); + axutil_string_free(soap_action_str, env); + request_url = NULL; + return status; +} + +static axis2_status_t +axis2_http_worker_set_response_headers( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_simple_http_svr_conn_t * svr_conn, + axis2_http_simple_request_t * simple_request, + axis2_http_simple_response_t * simple_response, + axis2_ssize_t content_length) +{ + axis2_http_header_t *conn_header = NULL; + + AXIS2_PARAM_CHECK(env->error, svr_conn, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, simple_request, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, simple_response, AXIS2_FAILURE); + + if(AXIS2_FALSE == axis2_http_simple_response_contains_header(simple_response, env, + AXIS2_HTTP_HEADER_CONNECTION)) + { + conn_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONNECTION); + if(conn_header) + { + axis2_char_t *value = NULL; + value = axis2_http_header_get_value(conn_header, env); + + if(0 == axutil_strcasecmp(value, AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE)) + { + /* Comment these until keep alive support is completed for simple Axis2/C server */ + /*axis2_http_header_t *header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE); + + axis2_http_simple_response_set_header(simple_response, env, header); + axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_TRUE);*/ + } + + if(0 == axutil_strcasecmp(value, AXIS2_HTTP_HEADER_CONNECTION_CLOSE)) + { + axis2_http_header_t *header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_CLOSE); + + axis2_http_simple_response_set_header(simple_response, env, header); + axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE); + } + } + else + { /* Connection Header not available */ + axis2_char_t *http_version = NULL; + http_version = axis2_http_simple_response_get_http_version(simple_response, env); + if(http_version && !axutil_strcasecmp(http_version, AXIS2_HTTP_HEADER_PROTOCOL_11)) + { + /* Comment these until keep alive support is completed for simple Axis2/C server */ + /*axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_TRUE);*/ + /* Instead add following to always send close connection header to indicate that + * we don't support http keep alive yet in simple Axis2/C server + */ + axis2_http_header_t *header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_CLOSE); + + axis2_http_simple_response_set_header(simple_response, env, header); + /*axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE);*/ + } + else + { + axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE); + } + } + + if(!axis2_http_simple_response_contains_header(simple_response, env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING)) + { + if(AXIS2_FALSE == axis2_http_simple_request_contains_header(simple_request, env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING)) + { + if(0 != content_length) + { + axis2_char_t content_len_str[10]; + axis2_http_header_t *content_len_hdr = NULL; + + sprintf(content_len_str, "%d", content_length); + content_len_hdr = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, content_len_str); + axis2_http_simple_response_set_header(simple_response, env, content_len_hdr); + } + } + else + { + /* Having Transfer encoding Header */ + axis2_http_header_t *transfer_enc_header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED); + + axis2_http_simple_response_set_header(simple_response, env, transfer_enc_header); + } + } + } + return AXIS2_SUCCESS; +} + +static axutil_hash_t * +axis2_http_worker_get_headers( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_http_simple_request_t * request) +{ + axutil_array_list_t *header_list = NULL; + int hdr_count = 0; + int i = 0; + axutil_hash_t *header_map = NULL; + + AXIS2_PARAM_CHECK(env->error, request, NULL); + + header_list = axis2_http_simple_request_get_headers(request, env); + if(!header_list) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "http simple request" + "doesn't contain a header list"); + return NULL; + } + hdr_count = axutil_array_list_size(header_list, env); + if(0 == hdr_count) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "http simple request , " + "header list contains zero headers"); + return NULL; + } + + for(i = 0; i < hdr_count; i++) + { + axis2_http_header_t *tmp_hdr = NULL; + tmp_hdr = axutil_array_list_get(header_list, env, i); + if(!tmp_hdr) + { + continue; + } + if(!header_map) + { + header_map = axutil_hash_make(env); + if(!header_map) + { + return NULL; + } + } + axutil_hash_set(header_map, axis2_http_header_get_name(tmp_hdr, env), + AXIS2_HASH_KEY_STRING, tmp_hdr); + } + return header_map; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_worker_set_svr_port( + axis2_http_worker_t * worker, + const axutil_env_t * env, + int port) +{ + worker->svr_port = port; + return AXIS2_SUCCESS; +} +#if 0 +static axis2_char_t * +axis2_http_worker_get_server_time( + axis2_http_worker_t * http_worker, + const axutil_env_t * env) +{ + time_t tp; + char *time_str; + tp = time(&tp); + time_str = ctime(&tp); + if(!time_str) + { + return NULL; + } + if(AXIS2_NEW_LINE == time_str[strlen(time_str) - 1]) + { + time_str[strlen(time_str) - 1] = AXIS2_ESC_NULL; + } + /* We use the ANSI C Date Format, which is Legal according to RFC2616, + * Section 3.3.1. We are not a HTTP/1.1 only server, and thus, it suffices. + */ + return time_str; +} +#endif + +static axis2_http_simple_response_t * +axis2_http_worker_create_simple_response( + axis2_http_worker_t *http_worker, + const axutil_env_t *env) +{ + axis2_http_simple_response_t *response = NULL; + response = axis2_http_simple_response_create_default(env); + if(response) + { + axis2_http_header_t *server = NULL; + axis2_http_header_t *server_date = NULL; + axis2_char_t *date_str = NULL; + char *date_str_tmp = NULL; + time_t tp; + size_t date_str_len = 0; + + /* create "Date: xxxx GMT" HTTP header */ + tp = time(&tp); + date_str_tmp = ctime(&tp); + if(!date_str_tmp) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot get server time"); + return NULL; + } + + date_str_len = strlen(date_str_tmp); + if(AXIS2_NEW_LINE == date_str_tmp[date_str_len - 1]) + { + date_str_len -= 1; + date_str_tmp[date_str_len] = AXIS2_ESC_NULL; + } + /* We use the ANSI C Date Format, which is Legal according to RFC2616, + * Section 3.3.1. We are not a HTTP/1.1 only server, and thus, it suffices. + */ + + date_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (date_str_len + 5)); + if(!date_str) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + + } + sprintf(date_str, "%s GMT", date_str_tmp); + server_date = axis2_http_header_create(env, AXIS2_HTTP_HEADER_DATE, date_str); + AXIS2_FREE(env->allocator, date_str); + axis2_http_simple_response_set_header(response, env, server_date); + + /* create "Server: Axis2C/x.x.x (Simple Axis2 HTTP Server)" HTTP Header */ + server = axis2_http_header_create(env, AXIS2_HTTP_HEADER_SERVER, + AXIS2_HTTP_HEADER_SERVER_AXIS2C AXIS2_HTTP_SERVER); + axis2_http_simple_response_set_header(response, env, server); + } + return response; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_worker_set_is_application_client_side( + axis2_http_worker_t *http_worker, + const axutil_env_t *env, + axis2_bool_t application_client_side) +{ + http_worker->is_application_client_side = application_client_side; +} + + diff --git a/src/core/transport/http/common/simple_http_svr_conn.c b/src/core/transport/http/common/simple_http_svr_conn.c new file mode 100644 index 0000000..a68c48e --- /dev/null +++ b/src/core/transport/http/common/simple_http_svr_conn.c @@ -0,0 +1,504 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_simple_http_svr_conn.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> +#include <axutil_network_handler.h> +#include <axutil_http_chunked_stream.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <string.h> +#include <axis2_http_simple_response.h> +#include <axis2_http_transport_utils.h> + +struct axis2_simple_http_svr_conn +{ + int socket; + axutil_stream_t *stream; + axis2_bool_t keep_alive; +}; + +static axis2_char_t * +axis2_simple_http_svr_conn_read_line( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env); + +AXIS2_EXTERN axis2_simple_http_svr_conn_t *AXIS2_CALL +axis2_simple_http_svr_conn_create( + const axutil_env_t * env, + int sockfd) +{ + axis2_simple_http_svr_conn_t *svr_conn = NULL; + svr_conn = (axis2_simple_http_svr_conn_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_simple_http_svr_conn_t)); + if(!svr_conn) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "server connection failed. Insufficient memory"); + return NULL; + } + + memset((void *)svr_conn, 0, sizeof(axis2_simple_http_svr_conn_t)); + svr_conn->socket = sockfd; + + if(-1 != svr_conn->socket) + { + svr_conn->stream = axutil_stream_create_socket(env, svr_conn->socket); + if(!svr_conn->stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "socket creation failed, socket %d", sockfd); + axis2_simple_http_svr_conn_free(svr_conn, env); + return NULL; + } + } + return svr_conn; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_simple_http_svr_conn_free( + axis2_simple_http_svr_conn_t *svr_conn, + const axutil_env_t * env) +{ + axis2_simple_http_svr_conn_close(svr_conn, env); + AXIS2_FREE(env->allocator, svr_conn); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_close( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + axutil_stream_free(svr_conn->stream, env); + if(-1 != svr_conn->socket) + { + axutil_network_handler_close_socket(env, svr_conn->socket); + svr_conn->socket = -1; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_simple_http_svr_conn_is_open( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + if(-1 != svr_conn->socket) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_set_keep_alive( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env, + axis2_bool_t keep_alive) +{ + svr_conn->keep_alive = keep_alive; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_simple_http_svr_conn_is_keep_alive( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return svr_conn->keep_alive; +} + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axis2_simple_http_svr_conn_get_stream( + const axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return svr_conn->stream; +} + +AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL +axis2_simple_http_svr_conn_get_writer( + const axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return axis2_http_response_writer_create(env, svr_conn->stream); +} + +AXIS2_EXTERN axis2_http_simple_request_t *AXIS2_CALL +axis2_simple_http_svr_conn_read_request( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + axis2_char_t* str_line = NULL; + axis2_bool_t end_of_headers = AXIS2_FALSE; + axis2_http_request_line_t *request_line = NULL; + axis2_http_simple_request_t *request = NULL; + + /* read first line of the request (which is <HTTP METHOD> <URI> <HTTP VERSION> CRLF */ + str_line = axis2_simple_http_svr_conn_read_line(svr_conn, env); + if(str_line) + { + request_line = axis2_http_request_line_parse_line(env, str_line); + AXIS2_FREE(env->allocator, str_line); + str_line = NULL; + } + + if(!request_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + request = axis2_http_simple_request_create(env, request_line, NULL, 0, svr_conn->stream); + + /* now read the headers until we find a line only having CRLF */ + while(AXIS2_FALSE == end_of_headers) + { + str_line = axis2_simple_http_svr_conn_read_line(svr_conn, env); + if(!str_line) + { + /*if nothing is read, this loop should be broken. Otherwise, going to be endless loop */ + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "reading http header failed"); + break; + } + + if(0 == axutil_strcmp(str_line, AXIS2_HTTP_CRLF)) + { + /* line contains only CRLF, so should be end of headers */ + end_of_headers = AXIS2_TRUE; + } + else + { + axis2_http_header_t *tmp_header = axis2_http_header_create_by_str(env, str_line); + if(tmp_header) + { + axis2_http_simple_request_add_header(request, env, tmp_header); + } + } + + AXIS2_FREE(env->allocator, str_line); + str_line = NULL; + } + return request; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_write_response( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env, + axis2_http_simple_response_t * response) +{ + axis2_http_response_writer_t *response_writer = NULL; + axutil_array_list_t *headers = NULL; + axutil_stream_t *response_stream = NULL; + axis2_char_t *response_body = NULL; + int body_size = 0; + + axis2_http_header_t *enc_header = NULL; + axis2_bool_t chuked_encoding = AXIS2_FALSE; + axis2_char_t *status_line = NULL; + axis2_bool_t binary_content = AXIS2_FALSE; + axis2_char_t *content_type = NULL; + + AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE); + + response_writer = axis2_http_response_writer_create(env, svr_conn->stream); + if(!response_writer) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create http response writer"); + return AXIS2_FAILURE; + } + + content_type = (axis2_char_t *)axis2_http_simple_response_get_content_type(response, env); + if(content_type) + { + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED) + && strstr(content_type,AXIS2_HTTP_HEADER_ACCEPT_XOP_XML)) + { + binary_content = AXIS2_TRUE; + } + } + + enc_header = axis2_http_simple_response_get_first_header(response, env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING); + if(enc_header) + { + axis2_char_t *enc_value = axis2_http_header_get_value(enc_header, env); + if(enc_value && (0 == axutil_strcmp(enc_value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))) + { + chuked_encoding = AXIS2_TRUE; + + /* remove the content length header */ + axis2_http_simple_response_remove_headers(response, env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH); + } + } + + /* print status line */ + status_line = axis2_http_simple_response_get_status_line(response, env); + if(!status_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + axis2_http_response_writer_print_str(response_writer, env, status_line); + + headers = axis2_http_simple_response_get_headers(response, env); + if(headers) + { + int i = 0; + int count = axutil_array_list_size(headers, env); + for(; i < count; i++) + { + axis2_http_header_t *header = + (axis2_http_header_t *)axutil_array_list_get(headers, env, i); + if(header) + { + axis2_char_t *header_ext_form = axis2_http_header_to_external_form(header, env); + axis2_http_response_writer_print_str(response_writer, env, header_ext_form); + AXIS2_FREE(env->allocator, header_ext_form); + } + } + } + + /* write empty line after http headers */ + axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF); + + /* write the body */ + response_stream = axis2_http_simple_response_get_body(response, env); + if(response_stream) + { + body_size = axutil_stream_get_len(response_stream, env); + response_body = axutil_stream_get_buffer(response_stream, env); + axutil_stream_flush_buffer(response_stream, env); + response_body[body_size] = AXIS2_ESC_NULL; + } + + if(body_size <= 0 && !binary_content) + { + /* no body available to write. Note that this is not an error. We might want to write only + * status information and hence, this is a valid case */ + axis2_http_response_writer_free(response_writer, env); + return AXIS2_SUCCESS; + } + + if(!chuked_encoding && !binary_content) + { + /* This sending a normal SOAP response without chunk transfer encoding */ + axis2_status_t write_stat = AXIS2_FAILURE; + write_stat = axis2_http_response_writer_println_str(response_writer, env, response_body); + if(write_stat != AXIS2_SUCCESS) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_RESPONSE, AXIS2_FAILURE); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + } + else if(!binary_content) + { + /* Sending a normal SOAP response enabling http chunking */ + axutil_http_chunked_stream_t *chunked_stream = NULL; + int left = body_size; + chunked_stream = axutil_http_chunked_stream_create(env, svr_conn->stream); + while(left > 0) + { + int len = -1; + len = axutil_http_chunked_stream_write(chunked_stream, env, response_body, body_size); + if(len <= 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot write data to chunked stream"); + axutil_http_chunked_stream_free(chunked_stream, env); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + left -= len; + } + axutil_http_chunked_stream_write_last_chunk(chunked_stream, env); + axutil_http_chunked_stream_free(chunked_stream, env); + } + else + { + /* In the MTOM case we enable chunking in order to send the attachment */ + axutil_http_chunked_stream_t *chunked_stream = NULL; + axis2_status_t write_stat = AXIS2_FAILURE; + axutil_array_list_t *mime_parts = NULL; + axis2_char_t *mtom_sending_callback_name = NULL; + + mime_parts = axis2_http_simple_response_get_mime_parts(response, env); + if(!mime_parts) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No mime parts are given"); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + + /* If the callback name is not there, then we will check whether there + * is any mime_parts which has type callback. If we found then no point + * of continuing we should return a failure */ + mtom_sending_callback_name = axis2_http_simple_response_get_mtom_sending_callback_name( + response, env); + if(!mtom_sending_callback_name) + { + if(axis2_http_transport_utils_is_callback_required(env, mime_parts)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Sender callback not specified"); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + } + + chunked_stream = axutil_http_chunked_stream_create(env, svr_conn->stream); + write_stat = axis2_http_transport_utils_send_mtom_message(chunked_stream, env, mime_parts, + mtom_sending_callback_name); + axutil_http_chunked_stream_free(chunked_stream, env); + + if(write_stat != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "writing mime parts failed"); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + } + + axis2_http_response_writer_free(response_writer, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_set_rcv_timeout( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env, + int timeout) +{ + return axutil_network_handler_set_sock_option(env, svr_conn->socket, SO_RCVTIMEO, timeout); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_set_snd_timeout( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env, + int timeout) +{ + return axutil_network_handler_set_sock_option(env, svr_conn->socket, SO_SNDTIMEO, timeout); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_simple_http_svr_conn_get_svr_ip( + const axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return axutil_network_handler_get_svr_ip(env, svr_conn->socket); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_simple_http_svr_conn_get_peer_ip( + const axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return axutil_network_handler_get_peer_ip(env, svr_conn->socket); +} + +static axis2_char_t * +axis2_simple_http_svr_conn_read_line( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + axis2_char_t* str_line = NULL; + axis2_char_t tmp_buf[2048]; + int read = -1; + + /* peek for 2047 characters to verify whether it contains CRLF character */ + while((read = axutil_stream_peek_socket(svr_conn->stream, env, tmp_buf, 2048 - 1)) > 0) + { + axis2_char_t *start = tmp_buf; + axis2_char_t *end = NULL; + tmp_buf[read] = AXIS2_ESC_NULL; + end = strstr(tmp_buf, AXIS2_HTTP_CRLF); + if(end) + { + axis2_char_t *buffer = NULL; + if(str_line) + { + /* header is more than 2048 character. this is not a common case, and not optimized + * for performance (reading in a temp buffer and then strcat to get final buffer */ + buffer = tmp_buf; + } + else + { + /* header is less than 2048 characters, this is the common case. So to improve + * the performance, the buffer is malloc and then used to read the stream. */ + buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, end - start + 3); + } + + /* read the data including CRLF (hence the size = end - start + 2) */ + read = axutil_stream_read(svr_conn->stream, env, buffer, end - start + 2); + if(read > 0) + { + buffer[read] = AXIS2_ESC_NULL; + + if(str_line) + { + axis2_char_t* tmp_str_line = NULL; + tmp_str_line = axutil_stracat(env, str_line, buffer); + if(tmp_str_line) + { + AXIS2_FREE(env->allocator, str_line); + str_line = tmp_str_line; + } + } + else + { + str_line = buffer; + } + } + else + { + /* read returns 0 or negative value, this could be an error */ + if(str_line) + { + AXIS2_FREE(env->allocator, str_line); + str_line = NULL; + } + else + { + AXIS2_FREE(env->allocator, buffer); + } + } + break; + } + else + { + /* not reached end yet */ + read = axutil_stream_read(svr_conn->stream, env, tmp_buf, 2048 - 1); + if(read > 0) + { + axis2_char_t* tmp_str_line = NULL; + tmp_buf[read] = AXIS2_ESC_NULL; + tmp_str_line = axutil_stracat(env, str_line, tmp_buf); + if(tmp_str_line) + { + if(str_line) + { + AXIS2_FREE(env->allocator, str_line); + } + str_line = tmp_str_line; + } + } + } + } + + return str_line; +} diff --git a/src/core/transport/http/receiver/Makefile.am b/src/core/transport/http/receiver/Makefile.am new file mode 100644 index 0000000..0af4e22 --- /dev/null +++ b/src/core/transport/http/receiver/Makefile.am @@ -0,0 +1,21 @@ +lib_LTLIBRARIES = libaxis2_http_receiver.la +libaxis2_http_receiver_la_LIBADD=$(top_builddir)/util/src/libaxutil.la\ + $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la + + +libaxis2_http_receiver_la_SOURCES = http_receiver.c\ + http_svr_thread.c + + +libaxis2_http_receiver_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport\ + -I$(top_builddir)/src/core/transport/http \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/http/receiver/http_receiver.c b/src/core/transport/http/receiver/http_receiver.c new file mode 100644 index 0000000..c8517b0 --- /dev/null +++ b/src/core/transport/http/receiver/http_receiver.c @@ -0,0 +1,508 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_server.h> +#include <axis2_http_transport.h> +#include <axis2_http_svr_thread.h> +#include <axis2_transport_in_desc.h> +#include <axutil_param_container.h> +#include <axutil_url.h> +#include <axutil_network_handler.h> +#include <axis2_conf_init.h> +#include <stdlib.h> + + +/** + * @brief HTTP Client struct impl + * Axis2 HTTP Client impl + */ + +typedef struct axis2_http_server_impl +{ + axis2_transport_receiver_t http_server; + axis2_http_svr_thread_t *svr_thread; + int port; + axis2_char_t *svr_ip; + axis2_conf_ctx_t *conf_ctx; + axis2_conf_ctx_t *conf_ctx_private; + axis2_bool_t is_application_client_side; +} axis2_http_server_impl_t; + +#define AXIS2_INTF_TO_IMPL(http_server) \ + ((axis2_http_server_impl_t *)(http_server)) + +/***************************** Function headers *******************************/ + +static axis2_status_t AXIS2_CALL +axis2_http_server_init( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_transport_in_desc_t * in_desc); + +static axis2_status_t AXIS2_CALL +axis2_http_server_start( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_http_server_stop( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +static axis2_conf_ctx_t *AXIS2_CALL +axis2_http_server_get_conf_ctx( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +static axis2_endpoint_ref_t *AXIS2_CALL +axis2_http_server_get_reply_to_epr( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + const axis2_char_t * svc_name); + +static axis2_endpoint_ref_t *AXIS2_CALL +axis2_http_server_get_epr_for_service( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + const axis2_char_t * svc_name); + +static axis2_bool_t AXIS2_CALL +axis2_http_server_is_running( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +static void AXIS2_CALL +axis2_http_server_set_is_application_client_side( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + axis2_bool_t is_application_client_side); + +static void AXIS2_CALL +axis2_http_server_free( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +static axis2_char_t* AXIS2_CALL +axis2_http_server_get_server_ip( +axis2_transport_receiver_t *transport_receiver, +const axutil_env_t *env); + +static void AXIS2_CALL +axis2_http_server_set_server_ip( +axis2_transport_receiver_t *transport_receiver, +const axutil_env_t *env, + axis2_char_t *serverip); + +static const axis2_transport_receiver_ops_t http_transport_receiver_ops_var = { + axis2_http_server_init, + axis2_http_server_start, + axis2_http_server_get_reply_to_epr, + axis2_http_server_get_epr_for_service, + axis2_http_server_get_server_ip, + axis2_http_server_set_server_ip, + axis2_http_server_get_conf_ctx, + axis2_http_server_is_running, + axis2_http_server_set_is_application_client_side, + axis2_http_server_stop, + axis2_http_server_free }; + +AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL +axis2_http_server_create( + const axutil_env_t * env, + const axis2_char_t * repo, + const int port) +{ + axis2_http_server_impl_t *server_impl = NULL; + + server_impl = (axis2_http_server_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_server_impl_t)); + + if(!server_impl) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + server_impl->svr_thread = NULL; + server_impl->conf_ctx = NULL; + server_impl->conf_ctx_private = NULL; + server_impl->port = port; + server_impl->svr_ip = NULL; + server_impl->is_application_client_side = AXIS2_FALSE; + + server_impl->http_server.ops = &http_transport_receiver_ops_var; + + if(repo) + { + axis2_transport_in_desc_t *transport_in = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_receiver_t *receiver = NULL; + /** + * We first create a private conf ctx which is owned by this server + * we only free this private conf context. We should never free the + * server_impl->conf_ctx because it may own to any other object which + * may lead to double free + */ + server_impl->conf_ctx_private = axis2_build_conf_ctx(env, repo); + + if(!server_impl->conf_ctx_private) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "unable to create private configuration context for repo path %s", repo); + axis2_http_server_free((axis2_transport_receiver_t *)server_impl, env); + return NULL; + } + conf = axis2_conf_ctx_get_conf(server_impl->conf_ctx_private, env); + transport_in = axis2_conf_get_transport_in(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + receiver = axis2_transport_in_desc_get_recv(transport_in, env); + AXIS2_INTF_TO_IMPL(receiver)->port = port; + + server_impl->conf_ctx = server_impl->conf_ctx_private; + } + + return &(server_impl->http_server); +} + +AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL +axis2_http_server_create_with_file( + const axutil_env_t * env, + const axis2_char_t * file, + const int port) +{ + axis2_http_server_impl_t *server_impl = NULL; + + server_impl = (axis2_http_server_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_server_impl_t)); + + if(!server_impl) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + server_impl->svr_thread = NULL; + server_impl->conf_ctx = NULL; + server_impl->conf_ctx_private = NULL; + server_impl->port = port; + server_impl->svr_ip = NULL; + server_impl->http_server.ops = &http_transport_receiver_ops_var; + + if(file) + { + axis2_transport_in_desc_t *transport_in = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_receiver_t *receiver = NULL; + /** + * We first create a private conf ctx which is owned by this server + * we only free this private conf context. We should never free the + * server_impl->conf_ctx because it may own to any other object which + * may lead to double free + */ + server_impl->conf_ctx_private = axis2_build_conf_ctx_with_file(env, file); + + if(!server_impl->conf_ctx_private) + { + axis2_http_server_free((axis2_transport_receiver_t *)server_impl, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "unable to create configuration context for file %s", file); + return NULL; + } + conf = axis2_conf_ctx_get_conf(server_impl->conf_ctx_private, env); + transport_in = axis2_conf_get_transport_in(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + receiver = axis2_transport_in_desc_get_recv(transport_in, env); + AXIS2_INTF_TO_IMPL(receiver)->port = port; + + + server_impl->conf_ctx = server_impl->conf_ctx_private; + } + + return &(server_impl->http_server); +} + +static void AXIS2_CALL +axis2_http_server_free( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + axis2_http_server_impl_t *server_impl = NULL; + + if(!server) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "failure, server value is null , nothing to free"); + return; + } + + server_impl = AXIS2_INTF_TO_IMPL(server); + if(server_impl->svr_thread) + { + axis2_http_svr_thread_destroy(server_impl->svr_thread, env); + axis2_http_svr_thread_free(server_impl->svr_thread, env); + server_impl->svr_thread = NULL; + } + + if(server_impl->conf_ctx_private) + { + axis2_conf_ctx_free(server_impl->conf_ctx_private, env); + server_impl->conf_ctx_private = NULL; + } + + /** + * Do not free this. It may own to some other object + */ + server_impl->conf_ctx = NULL; + + AXIS2_FREE(env->allocator, server_impl); +} + +static axis2_status_t AXIS2_CALL +axis2_http_server_init( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_transport_in_desc_t * in_desc) +{ + axis2_http_server_impl_t *server_impl = NULL; + axis2_char_t *port_str = NULL; + axutil_param_t *param = NULL; + + AXIS2_PARAM_CHECK(env->error, server, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, in_desc, AXIS2_FAILURE); + + server_impl = AXIS2_INTF_TO_IMPL(server); + + server_impl->conf_ctx = conf_ctx; + param = (axutil_param_t *)axutil_param_container_get_param( + axis2_transport_in_desc_param_container(in_desc, env), env, AXIS2_PORT_STRING); + if(param) + { + port_str = axutil_param_get_value(param, env); + } + + if(port_str) + { + server_impl->port = atoi(port_str); + } + return AXIS2_SUCCESS; +} + +static axis2_status_t AXIS2_CALL +axis2_http_server_start( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + axis2_http_server_impl_t *server_impl = NULL; + axis2_http_worker_t *worker = NULL; + + server_impl = AXIS2_INTF_TO_IMPL(server); + server_impl->svr_thread = axis2_http_svr_thread_create(env, server_impl->port); + if(!server_impl->svr_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to create server thread for port %d", + server_impl->port); + return AXIS2_FAILURE; + } + + worker = axis2_http_worker_create(env, server_impl->conf_ctx); + if(!worker) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 http worker creation failed"); + axis2_http_svr_thread_free(server_impl->svr_thread, env); + return AXIS2_FAILURE; + } + axis2_http_worker_set_is_application_client_side(worker, env, + server_impl->is_application_client_side); + axis2_http_worker_set_svr_port(worker, env, server_impl->port); + {/** Obtain server IP and set it + axis2_transport_in_desc_t *transport_in = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_receiver_t *receiver = NULL; + conf = axis2_conf_ctx_get_conf(server_impl->conf_ctx_private, env); + transport_in = axis2_conf_get_transport_in(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + receiver = axis2_transport_in_desc_get_recv(transport_in, env); + if(receiver) + { + int listen_socket = axis2_http_svr_thread_get_listen_socket(server_impl->svr_thread, env); + server_impl->svr_ip = axutil_network_handler_get_svr_ip(env, listen_socket); + AXIS2_INTF_TO_IMPL(receiver)->svr_ip = server_impl->svr_ip; + } + */ + } + AXIS2_LOG_INFO(env->log, "Starting HTTP server thread"); + axis2_http_svr_thread_set_worker(server_impl->svr_thread, env, worker); + axis2_http_svr_thread_run(server_impl->svr_thread, env); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_server_stop( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + AXIS2_LOG_INFO(env->log, "Terminating HTTP server thread"); + if(AXIS2_INTF_TO_IMPL(server)->svr_thread) + { + axis2_http_svr_thread_destroy(AXIS2_INTF_TO_IMPL(server)->svr_thread, env); + } + AXIS2_LOG_INFO(env->log, "Successfully terminated HTTP server thread"); + return AXIS2_SUCCESS; +} + +static axis2_conf_ctx_t *AXIS2_CALL +axis2_http_server_get_conf_ctx( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + return AXIS2_INTF_TO_IMPL(server)->conf_ctx; +} + +static axis2_endpoint_ref_t *AXIS2_CALL +axis2_http_server_get_reply_to_epr( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + axis2_endpoint_ref_t *epr = NULL; + const axis2_char_t *host_address = NULL; + axis2_char_t *svc_path = NULL; + axutil_url_t *url = NULL; + + host_address = AXIS2_DEFAULT_HOST_ADDRESS; /* TODO : get from axis2.xml */ + svc_path = axutil_stracat(env, AXIS2_DEFAULT_SVC_PATH, svc_name); + url = axutil_url_create(env, AXIS2_HTTP_PROTOCOL, host_address, + AXIS2_INTF_TO_IMPL(server)->port, svc_path); + + AXIS2_FREE(env->allocator, svc_path); + if(!url) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create reply to epr for service %s.", + svc_name); + return NULL; + } + epr = axis2_endpoint_ref_create(env, axutil_url_to_external_form(url, env)); + axutil_url_free(url, env); + return epr; +} + +static axis2_endpoint_ref_t *AXIS2_CALL +axis2_http_server_get_epr_for_service( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + axis2_endpoint_ref_t *epr = NULL; + const axis2_char_t *host_address = NULL; + axis2_char_t *svc_path = NULL; + axutil_url_t *url = NULL; + + if(AXIS2_INTF_TO_IMPL(server)->svr_ip) + { + host_address = AXIS2_INTF_TO_IMPL(server)->svr_ip; + }else + { + host_address = AXIS2_DEFAULT_HOST_ADDRESS; /* TODO : get from axis2.xml */ + } + svc_path = axutil_stracat(env, AXIS2_DEFAULT_SVC_PATH, svc_name); + + url = axutil_url_create(env, AXIS2_HTTP_PROTOCOL, host_address, + AXIS2_INTF_TO_IMPL(server)->port, svc_path); + + AXIS2_FREE(env->allocator, svc_path); + if(!url) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create reply to epr for service %s.", + svc_name); + return NULL; + } + epr = axis2_endpoint_ref_create(env, axutil_url_to_external_form(url, env)); + axutil_url_free(url, env); + return epr; +} + +static axis2_bool_t AXIS2_CALL +axis2_http_server_is_running( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + axis2_http_server_impl_t *server_impl = NULL; + server_impl = AXIS2_INTF_TO_IMPL(server); + if(server_impl->svr_thread) + { + return axis2_http_svr_thread_is_running(server_impl->svr_thread, env); + } + return AXIS2_FALSE; +} + +static void AXIS2_CALL +axis2_http_server_set_is_application_client_side( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + axis2_bool_t is_application_client_side) +{ + axis2_http_server_impl_t *server_impl = NULL; + server_impl = AXIS2_INTF_TO_IMPL(server); + server_impl->is_application_client_side = is_application_client_side; +} + +static axis2_char_t* AXIS2_CALL +axis2_http_server_get_server_ip( +axis2_transport_receiver_t *server, +const axutil_env_t *env) +{ + return AXIS2_INTF_TO_IMPL(server)->svr_ip; +} + +static void AXIS2_CALL +axis2_http_server_set_server_ip( +axis2_transport_receiver_t *server, +const axutil_env_t *env, + axis2_char_t *serverip) +{ + AXIS2_INTF_TO_IMPL(server)->svr_ip = serverip; +} + +/** + * Following block distinguish the exposed part of the dll. + */ +AXIS2_EXPORT int +axis2_get_instance( + struct axis2_transport_receiver **inst, + const axutil_env_t * env) +{ + *inst = axis2_http_server_create(env, NULL, -1); + if(!(*inst)) + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT int +axis2_remove_instance( + axis2_transport_receiver_t * inst, + const axutil_env_t * env) +{ + if(inst) + { + axis2_transport_receiver_free(inst, env); + } + return AXIS2_SUCCESS; +} + diff --git a/src/core/transport/http/receiver/http_svr_thread.c b/src/core/transport/http/receiver/http_svr_thread.c new file mode 100644 index 0000000..1806815 --- /dev/null +++ b/src/core/transport/http/receiver/http_svr_thread.c @@ -0,0 +1,315 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <platforms/axutil_platform_auto_sense.h> +#include <axis2_http_svr_thread.h> +#include <axis2_http_server.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> +#include <axutil_network_handler.h> +#include <axis2_http_simple_request.h> +#include <axis2_simple_http_svr_conn.h> +#include <axutil_url.h> +#include <axutil_error_default.h> +#include <axiom_xml_reader.h> +#include <signal.h> + +AXIS2_EXPORT int axis2_http_socket_read_timeout = AXIS2_HTTP_DEFAULT_SO_TIMEOUT; + +struct axis2_http_svr_thread +{ + int listen_socket; + axis2_bool_t stopped; + axis2_http_worker_t *worker; + int port; +}; + +typedef struct axis2_http_svr_thd_args +{ + axutil_env_t *env; + axis2_socket_t socket; + axis2_http_worker_t *worker; + axutil_thread_t *thread; +} axis2_http_svr_thd_args_t; + +static void *AXIS2_THREAD_FUNC +axis2_svr_thread_worker_func( + axutil_thread_t * thd, + void *data); + +axis2_http_svr_thread_t *AXIS2_CALL +axis2_http_svr_thread_create( + const axutil_env_t * env, + int port) +{ + axis2_http_svr_thread_t *svr_thread = NULL; + + svr_thread = (axis2_http_svr_thread_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_svr_thread_t)); + + if(!svr_thread) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)svr_thread, 0, sizeof(axis2_http_svr_thread_t)); + + svr_thread->port = port; + svr_thread->listen_socket = (int)axutil_network_handler_create_server_socket(env, + svr_thread->port); + if(-1 == svr_thread->listen_socket) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Http server thread socket creation failed."); + axis2_http_svr_thread_free((axis2_http_svr_thread_t *)svr_thread, env); + return NULL; + } + + return svr_thread; +} + +void AXIS2_CALL +axis2_http_svr_thread_free( + axis2_http_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + if(!svr_thread) + { + return; + } + + if(svr_thread->worker) + { + axis2_http_worker_free(svr_thread->worker, env); + svr_thread->worker = NULL; + } + if(-1 != svr_thread->listen_socket) + { + axutil_network_handler_close_socket(env, svr_thread->listen_socket); + svr_thread->listen_socket = -1; + } + svr_thread->stopped = AXIS2_TRUE; + + AXIS2_FREE(env->allocator, svr_thread); +} + +axis2_status_t AXIS2_CALL +axis2_http_svr_thread_run( + axis2_http_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + while(AXIS2_FALSE == svr_thread->stopped) + { + int socket = -1; + axis2_http_svr_thd_args_t *arg_list = NULL; +#ifdef AXIS2_SVR_MULTI_THREADED + axutil_thread_t *worker_thread = NULL; +#endif + + socket = (int)axutil_network_handler_svr_socket_accept(env, svr_thread-> listen_socket); + if(!svr_thread->worker) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "Worker not ready yet. Cannot serve the request"); + axutil_network_handler_close_socket(env, socket); + continue; + } + + arg_list = AXIS2_MALLOC(env->allocator, sizeof(axis2_http_svr_thd_args_t)); + if(!arg_list) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Memory allocation error in the svr thread loop"); + continue; + } + + arg_list->env = (axutil_env_t *)env; + arg_list->socket = socket; + arg_list->worker = svr_thread->worker; +#ifdef AXIS2_SVR_MULTI_THREADED + worker_thread = axutil_thread_pool_get_thread(env->thread_pool, + axis2_svr_thread_worker_func, (void *) arg_list); + if (!worker_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Thread creation failed server thread loop"); + continue; + } + axutil_thread_pool_thread_detach(env->thread_pool, worker_thread); +#else + axis2_svr_thread_worker_func(NULL, (void *)arg_list); +#endif + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_svr_thread_destroy( + axis2_http_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + if(AXIS2_TRUE == svr_thread->stopped) + { + return AXIS2_SUCCESS; + } + + svr_thread->stopped = AXIS2_TRUE; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Terminating HTTP server thread."); + if(svr_thread->listen_socket) + { + axutil_network_handler_close_socket(env, svr_thread->listen_socket); + svr_thread->listen_socket = -1; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_svr_thread_get_local_port( + const axis2_http_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + return svr_thread->port; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_svr_thread_is_running( + axis2_http_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + return !(svr_thread->stopped); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_svr_thread_set_worker( + axis2_http_svr_thread_t * svr_thread, + const axutil_env_t * env, + axis2_http_worker_t * worker) +{ + AXIS2_PARAM_CHECK(env->error, worker, AXIS2_FAILURE); + svr_thread->worker = worker; + return AXIS2_SUCCESS; +} + +/** + * Thread worker function. + */ +static void *AXIS2_THREAD_FUNC +axis2_svr_thread_worker_func( + axutil_thread_t * thd, + void *data) +{ + struct AXIS2_PLATFORM_TIMEB t1, t2; + axis2_simple_http_svr_conn_t *svr_conn = NULL; + axis2_http_simple_request_t *request = NULL; + int millisecs = 0; + double secs = 0; + axis2_http_worker_t *tmp = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_env_t *env = NULL; + axis2_socket_t socket; + axutil_env_t *thread_env = NULL; + axis2_http_svr_thd_args_t *arg_list = NULL; + +#ifndef WIN32 +#ifdef AXIS2_SVR_MULTI_THREADED + signal(SIGPIPE, SIG_IGN); +#endif +#endif + + if(!data) + { + return NULL; + } + arg_list = (axis2_http_svr_thd_args_t *)data; + + env = arg_list->env; + thread_env = axutil_init_thread_env(env); + + IF_AXIS2_LOG_DEBUG_ENABLED(env->log) + { + AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t1); + } + + socket = arg_list->socket; + svr_conn = axis2_simple_http_svr_conn_create(thread_env, (int)socket); + if(!svr_conn) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "creating simple_http_svr_connection failed"); + return NULL; + } + + axis2_simple_http_svr_conn_set_rcv_timeout(svr_conn, thread_env, axis2_http_socket_read_timeout); + + /* read HTTPMethod, URL, HTTP Version and http headers. Leave the remaining in the stream */ + request = axis2_simple_http_svr_conn_read_request(svr_conn, thread_env); + if(!request) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not create request"); + return NULL; + } + + tmp = arg_list->worker; + status = axis2_http_worker_process_request(tmp, thread_env, svr_conn, request); + axis2_simple_http_svr_conn_free(svr_conn, thread_env); + axis2_http_simple_request_free(request, thread_env); + + IF_AXIS2_LOG_DEBUG_ENABLED(env->log) + { + AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t2); + millisecs = t2.millitm - t1.millitm; + secs = difftime(t2.time, t1.time); + if(millisecs < 0) + { + millisecs += 1000; + secs--; + } + secs += millisecs / 1000.0; + +#if defined(WIN32) + AXIS2_LOG_DEBUG(thread_env->log, AXIS2_LOG_SI, "Request processed..."); +#else + AXIS2_LOG_DEBUG(thread_env->log, AXIS2_LOG_SI, "Request processed in %.3f seconds", secs); +#endif + } + + if(status == AXIS2_SUCCESS) + { + AXIS2_LOG_DEBUG(thread_env->log, AXIS2_LOG_SI, "Request served successfully"); + } + else + { + AXIS2_LOG_WARNING(thread_env->log, AXIS2_LOG_SI, "Error occurred in processing request "); + } + + AXIS2_FREE(thread_env->allocator, arg_list); + axutil_free_thread_env(thread_env); + thread_env = NULL; + +#ifdef AXIS2_SVR_MULTI_THREADED + axutil_thread_pool_exit_thread(env->thread_pool, thd); +#endif + + return NULL; +} + +AXIS2_EXTERN int AXIS2_CALL + axis2_http_svr_thread_get_listen_socket( + axis2_http_svr_thread_t *svr_thread, + const axutil_env_t *env) +{ + return svr_thread->listen_socket; + +} diff --git a/src/core/transport/http/sender/Makefile.am b/src/core/transport/http/sender/Makefile.am new file mode 100644 index 0000000..399ed39 --- /dev/null +++ b/src/core/transport/http/sender/Makefile.am @@ -0,0 +1,51 @@ +SUBDIRS=ssl libcurl +lib_LTLIBRARIES = libaxis2_http_sender.la + + + +if AXIS2_LIBCURL_ENABLED +LIBCURL_SOURCES=libcurl/axis2_libcurl.c\ + libcurl/libcurl_stream.c +LIBCURL_LIBS=-lssl -lcrypto -lcurl -ldl -lz +else +LIBCURL_SOURCES= +LIBCURL_LIBS= +endif + + +if AXIS2_SSL_ENABLED +SSL_SOURCES = ssl/ssl_stream.c\ + ssl/ssl_utils.c +SSL_LIBS = -lssl -lcrypto +else +SSL_SOURCES= +SSL_LIBS= +endif + +libaxis2_http_sender_la_SOURCES = http_transport_sender.c \ + http_sender.c \ + http_client.c \ + $(SSL_SOURCES) \ + $(LIBCURL_SOURCES) + +libaxis2_http_sender_la_LIBADD = $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la\ + $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la\ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la\ + $(top_builddir)/util/src/libaxutil.la\ + $(LIBCURL_LIBS)\ + $(SSL_LIBS) + + +libaxis2_http_sender_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport\ + -I$(top_builddir)/src/core/transport/http \ + -I$(top_builddir)/src/core/transport/http/sender/libcurl \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/http/sender/http_client.c b/src/core/transport/http/sender/http_client.c new file mode 100644 index 0000000..80e7ee3 --- /dev/null +++ b/src/core/transport/http/sender/http_client.c @@ -0,0 +1,965 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_client.h> +#include <axis2_http_transport.h> +#include <axutil_stream.h> +#include <axutil_string.h> +#include <axutil_network_handler.h> +#include <axis2_http_request_line.h> +#include <axis2_http_header.h> +#include <axis2_http_status_line.h> +#include <axutil_http_chunked_stream.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <axiom_mime_part.h> +#include <axis2_http_transport_utils.h> + +#ifdef AXIS2_SSL_ENABLED +#include "ssl/ssl_stream.h" +#endif + +struct axis2_http_client +{ + int sockfd; + axutil_stream_t *data_stream; + axutil_url_t *url; + axis2_http_simple_response_t *response; + axis2_bool_t request_sent; + int timeout; + axis2_bool_t proxy_enabled; + axis2_char_t *proxy_host; + int proxy_port; + axis2_char_t *proxy_host_port; + axis2_bool_t dump_input_msg; + axis2_char_t *server_cert; + axis2_char_t *key_file; + axis2_char_t *req_body; + int req_body_size; + + /* These are for mtom case */ + axutil_array_list_t *mime_parts; + axis2_bool_t doing_mtom; + axis2_char_t *mtom_sending_callback_name; +}; + +AXIS2_EXTERN axis2_http_client_t *AXIS2_CALL +axis2_http_client_create( + const axutil_env_t * env, + axutil_url_t * url) +{ + axis2_http_client_t *http_client = NULL; + + http_client = (axis2_http_client_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_client_t)); + + if(!http_client) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset(http_client, 0, sizeof(axis2_http_client_t)); + + http_client->url = url; + http_client->data_stream = NULL; + http_client->sockfd = -1; + http_client->response = NULL; + http_client->request_sent = AXIS2_FALSE; + + /* default timeout is 60000 milliseconds */ + http_client->timeout = AXIS2_HTTP_DEFAULT_CONNECTION_TIMEOUT; + http_client->proxy_enabled = AXIS2_FALSE; + http_client->proxy_port = 0; + http_client->proxy_host = NULL; + http_client->proxy_host_port = NULL; + http_client->dump_input_msg = AXIS2_FALSE; + http_client->server_cert = NULL; + http_client->key_file = NULL; + http_client->req_body = NULL; + http_client->req_body_size = 0; + http_client->mime_parts = NULL; + http_client->doing_mtom = AXIS2_FALSE; + http_client->mtom_sending_callback_name = NULL; + + return http_client; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_client_free( + axis2_http_client_t * http_client, + const axutil_env_t * env) +{ + if(http_client->proxy_host) + { + AXIS2_FREE(env->allocator, http_client->proxy_host); + } + if(http_client->proxy_host_port) + { + AXIS2_FREE(env->allocator, http_client->proxy_host_port); + } + if(http_client->url) + { + axutil_url_free(http_client->url, env); + } + if(http_client->response) + { + axis2_http_simple_response_free(http_client->response, env); + } + if(-1 != http_client->sockfd) + { + axutil_network_handler_close_socket(env, http_client->sockfd); + http_client->sockfd = -1; + } + + if(http_client->req_body) + { + AXIS2_FREE(env->allocator, http_client->req_body); + } + + /* There is no other appropriate place to free the mime_part list when a + * particular client send requests. */ + + if(http_client->mime_parts) + { + int i = 0; + for(i = 0; i < axutil_array_list_size(http_client->mime_parts, env); i++) + { + axiom_mime_part_t *mime_part = NULL; + mime_part = (axiom_mime_part_t *)axutil_array_list_get(http_client->mime_parts, env, i); + if(mime_part) + { + axiom_mime_part_free(mime_part, env); + } + } + axutil_array_list_free(http_client->mime_parts, env); + } + + AXIS2_FREE(env->allocator, http_client); + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_client_free_void_arg( + void *client, + const axutil_env_t * env) +{ + axis2_http_client_t *client_l = NULL; + + client_l = (axis2_http_client_t *)client; + axis2_http_client_free(client_l, env); + return; +} + +/* This is the main method which writes to the socket in the case of a client + * sends an http_request. Previously this method does not distinguish between a + * mtom request and non mtom request. Because what finally it had was the + * complete buffer with the request. But now MTOM invocations are done + * differently in order to support large attachments so this method should + * distinguish those invocations */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_send( + axis2_http_client_t * client, + const axutil_env_t * env, + axis2_http_simple_request_t * request, + axis2_char_t * ssl_pp) +{ + char *wire_format = NULL; + axutil_array_list_t *headers = NULL; + char *str_header = NULL; + char *str_request_line = NULL; + int written = 0; + axis2_status_t status = AXIS2_FAILURE; + axis2_bool_t chunking_enabled = AXIS2_FALSE; + axis2_char_t *host = NULL; + unsigned int port = 0; + + /* In the MTOM case request body is not set. Instead mime_parts + array_list is there */ + + if(client->req_body) + { + AXIS2_FREE(env->allocator, client->req_body); + client->req_body = NULL; + } + if(!client->req_body && !(client->doing_mtom)) + { + client->req_body_size = axis2_http_simple_request_get_body_bytes(request, env, + &client->req_body); + } + + if(client->dump_input_msg == AXIS2_TRUE) + { + return AXIS2_SUCCESS; + } + + if(!client->url) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_URL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Request url not set"); + return AXIS2_FAILURE; + } + + host = axutil_url_get_host(client->url, env); + port = axutil_url_get_port(client->url, env); + + if(client->proxy_enabled) + { + if(!client->proxy_host || client->proxy_port <= 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy port or Host not set"); + return AXIS2_FAILURE; + } + + if(client->sockfd < 0) + { + client->sockfd = (int)axutil_network_handler_open_socket(env, client->proxy_host, + client->proxy_port); + } + } + else + { + /*Proxy is not enabled*/ + + if(client->sockfd < 0) + { + client->sockfd = (int)axutil_network_handler_open_socket(env, host, port); + } + } + + if(client->sockfd < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Socket Creation failed."); + return AXIS2_FAILURE; + } + + if(client->timeout > 0) + { + /*Set the receiving time out*/ + axutil_network_handler_set_sock_option(env, client->sockfd, SO_RCVTIMEO, client->timeout); + /*Set the sending time out*/ + + axutil_network_handler_set_sock_option(env, client->sockfd, SO_SNDTIMEO, client->timeout); + } + + if(0 == axutil_strcasecmp(axutil_url_get_protocol(client->url, env), AXIS2_TRANSPORT_URL_HTTPS)) + { +#ifdef AXIS2_SSL_ENABLED + if (client->proxy_enabled) + { + if (AXIS2_SUCCESS != axis2_http_client_connect_ssl_host(client, env, host, port)) + { + axutil_network_handler_close_socket(env, client->sockfd); + client->sockfd = -1; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTPS connection creation failed"); + return AXIS2_FAILURE; + } + } + client->data_stream = + axutil_stream_create_ssl(env, client->sockfd, axis2_http_client_get_server_cert(client, + env), axis2_http_client_get_key_file(client, env), ssl_pp); +#else + axutil_network_handler_close_socket(env, client->sockfd); + client->sockfd = -1; + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_TRANSPORT_PROTOCOL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid Transport Protocol, HTTPS transport not enabled."); + + return AXIS2_FAILURE; +#endif + } + else + { + client->data_stream = axutil_stream_create_socket(env, client->sockfd); + } + + if(!client->data_stream) + { + axutil_network_handler_close_socket(env, client->sockfd); + client->sockfd = -1; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Data stream creation failed for Host %s and %d port", host, port); + + return AXIS2_FAILURE; + } + + /*Accessing HTTP headers*/ + + headers = axis2_http_simple_request_get_headers(request, env); + if(headers) + { + int header_count = axutil_array_list_size(headers, env); + int i = 0; + char *str_header2 = NULL; + for(i = 0; i < header_count; i++) + { + axis2_char_t *header_ext_form = NULL; + axis2_http_header_t *tmp_header = (axis2_http_header_t *)axutil_array_list_get(headers, + env, i); + + if(!tmp_header) + { + /* This continue is added as a safey mechanism, + * However I see a problem with this logic, AFAIC + * see there can't be null headers in the headers + * array list, because number of headers in "headers" + * array list count with axutil_array_list_size, + * therefore this check and continue might not have a + * real effect.*/ + + continue; + } + + /* check whether we have transfer encoding and then see whether the + * value is "chunked" */ + if(!axutil_strcmp(axis2_http_header_get_name(tmp_header, env), + AXIS2_HTTP_HEADER_TRANSFER_ENCODING) && !axutil_strcmp(axis2_http_header_get_value( + tmp_header, env), AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)) + { + chunking_enabled = AXIS2_TRUE; + } + + header_ext_form = axis2_http_header_to_external_form(tmp_header, env); + + /* str_header2 is to hold intermediate value of str_header */ + str_header2 = axutil_stracat(env, str_header, header_ext_form); + if(str_header) + { + AXIS2_FREE(env->allocator, str_header); + str_header = NULL; + } + if(header_ext_form) + { + AXIS2_FREE(env->allocator, header_ext_form); + header_ext_form = NULL; + } + + /* str_header has all HTTP headers to send. */ + str_header = str_header2; + } + } + + if(AXIS2_FALSE == client->proxy_enabled) + { + str_request_line = axis2_http_request_line_to_string( + axis2_http_simple_request_get_request_line(request, env), env); + } + else + { + /* proxy enabled case */ + + /* we need the request line in the format + * POST http://host:port/path HTTP/1.x if we have enabled proxies + */ + axis2_char_t *host_port_str = NULL; + axis2_char_t *host = axutil_url_get_host(client->url, env); + axis2_http_request_line_t *request_line = axis2_http_simple_request_get_request_line( + request, env); + axis2_char_t *path = axis2_http_request_line_get_uri(request_line, env); + + host_port_str = AXIS2_MALLOC(env->allocator, axutil_strlen(host) + axutil_strlen(path) + 20 + * sizeof(axis2_char_t)); + + if(!host_port_str) + { + axutil_network_handler_close_socket(env, client->sockfd); + client->sockfd = -1; + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Memory allocation failed for host %s and %s path", host, path); + + return AXIS2_FAILURE; + } + + sprintf(host_port_str, "http://%s:%d%s", host, axutil_url_get_port(client->url, env), path); + str_request_line = AXIS2_MALLOC(env->allocator, axutil_strlen(host_port_str) + 20 + * sizeof(axis2_char_t)); + + if(!str_request_line) + { + axutil_network_handler_close_socket(env, client->sockfd); + client->sockfd = -1; + AXIS2_FREE(env->allocator, host_port_str); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "memory allocation failed for host %s and %s path", host, path); + + return AXIS2_FAILURE; + } + + sprintf(str_request_line, "%s %s %s\r\n", axis2_http_request_line_get_method(request_line, + env), host_port_str, axis2_http_request_line_get_http_version(request_line, env)); + + AXIS2_FREE(env->allocator, host_port_str); + host_port_str = NULL; + + } + + /* Here first we send the http header part */ + + wire_format = axutil_stracat(env, str_request_line, str_header); + AXIS2_FREE(env->allocator, str_header); + str_header = NULL; + AXIS2_FREE(env->allocator, str_request_line); + str_request_line = NULL; + written + = axutil_stream_write(client->data_stream, env, wire_format, axutil_strlen(wire_format)); + AXIS2_FREE(env->allocator, wire_format); + wire_format = NULL; + + /* Then we write the two new line charaters before the http body*/ + + written = axutil_stream_write(client->data_stream, env, AXIS2_HTTP_CRLF, 2); + + /* When sending MTOM it is bit different. We keep the attachment + other + mime headers in an array_list and send them one by one */ + + if(client->doing_mtom) + { + axis2_status_t status = AXIS2_SUCCESS; + axutil_http_chunked_stream_t *chunked_stream = NULL; + + /* If the callback name is not there, then we will check whether there + * is any mime_parts which has type callback. If we found then no point + * of continuing we should return a failure */ + + if(!(client->mtom_sending_callback_name)) + { + if(axis2_http_transport_utils_is_callback_required(env, client->mime_parts)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Sender callback not specified"); + return AXIS2_FAILURE; + } + } + + /* For MTOM we automatically enabled chunking */ + chunked_stream = axutil_http_chunked_stream_create(env, client->data_stream); + + /* This method will write the Attachment + data to the wire */ + + status = axis2_http_transport_utils_send_mtom_message(chunked_stream, env, + client->mime_parts, client->mtom_sending_callback_name); + + axutil_http_chunked_stream_free(chunked_stream, env); + chunked_stream = NULL; + + } + /* Non MTOM case */ + else if(client->req_body_size > 0 && client->req_body) + { + int len = 0; + written = 0; + + /* Keep on writing data in a loop until we finised + with all the data in the buffer */ + + if(!chunking_enabled) + { + status = AXIS2_SUCCESS; + while(written < client->req_body_size) + { + len = 0; + len = axutil_stream_write(client->data_stream, env, client->req_body + written, + client->req_body_size - written); + if(-1 == len) + { + status = AXIS2_FAILURE; + break; + } + else + { + written += len; + } + } + } + else + { + /* Not MTOM but chunking is enabled */ + axutil_http_chunked_stream_t *chunked_stream = NULL; + chunked_stream = axutil_http_chunked_stream_create(env, client->data_stream); + status = AXIS2_SUCCESS; + if(!chunked_stream) + { + axutil_network_handler_close_socket(env, client->sockfd); + client->sockfd = -1; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creatoin of chunked stream failed"); + return AXIS2_FAILURE; + } + + while(written < client->req_body_size) + { + written = axutil_http_chunked_stream_write(chunked_stream, env, client->req_body, + client->req_body_size); + + if(-1 == written) + { + status = AXIS2_FAILURE; + break; + } + } + + if(AXIS2_SUCCESS == status) + { + /* Writing the trailing null charactor */ + axutil_http_chunked_stream_write_last_chunk(chunked_stream, env); + } + + axutil_http_chunked_stream_free(chunked_stream, env); + } + } + + client->request_sent = AXIS2_TRUE; + return status; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_client_recieve_header( + axis2_http_client_t * client, + const axutil_env_t * env) +{ + int status_code = -1; + axis2_http_status_line_t *status_line = NULL; + axis2_char_t str_status_line[512]; + axis2_char_t tmp_buf[3]; + axis2_char_t str_header[512]; + int read = 0; + int http_status = 0; + axis2_bool_t end_of_line = AXIS2_FALSE; + axis2_bool_t end_of_headers = AXIS2_FALSE; + + if(-1 == client->sockfd || !client->data_stream || AXIS2_FALSE == client->request_sent) + { + axis2_char_t *host; + unsigned int port; + host = axutil_url_get_host(client->url, env); + port = axutil_url_get_port(client->url, env); + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "client data stream null or socket error for host \ +%s and %d port", host, port); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_REQUEST_NOT_SENT, AXIS2_FAILURE); + return -1; + } + + /* read the status line */ + do + { + memset(str_status_line, 0, 512); + while((read = axutil_stream_read(client->data_stream, env, tmp_buf, 1)) > 0) + { + /* "read" variable is number of characters read by stream */ + tmp_buf[read] = '\0'; + strcat(str_status_line, tmp_buf); + if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF)) + { + end_of_line = AXIS2_TRUE; + break; + } + } + + if(read < 0) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "http client , response timed out"); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE); + return -1; + } + else if(read == 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_SERVER_SHUTDOWN, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response error, Server Shutdown"); + return 0; + } + + status_line = axis2_http_status_line_create(env, str_status_line); + if(!status_line) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2_http_status_line_create failed for \ +str_status_line %s", str_status_line); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + http_status = 0; + continue; + + } + http_status = axis2_http_status_line_get_status_code(status_line, env); + + } + while(AXIS2_HTTP_RESPONSE_OK_CODE_VAL > http_status); + + if(client->response) + axis2_http_simple_response_free(client->response, env); + client->response = axis2_http_simple_response_create_default(env); + axis2_http_simple_response_set_status_line(client->response, env, + axis2_http_status_line_get_http_version(status_line, env), + axis2_http_status_line_get_status_code(status_line, env), + axis2_http_status_line_get_reason_phrase(status_line, env)); + + /* now read the headers */ + memset(str_header, 0, 512); + end_of_line = AXIS2_FALSE; + while(AXIS2_FALSE == end_of_headers) + { + while((read = axutil_stream_read(client->data_stream, env, tmp_buf, 1)) > 0) + { + tmp_buf[read] = '\0'; + strcat(str_header, tmp_buf); + if(0 != strstr(str_header, AXIS2_HTTP_CRLF)) + { + end_of_line = AXIS2_TRUE; + break; + } + } + if(AXIS2_TRUE == end_of_line) + { + if(0 == axutil_strcmp(str_header, AXIS2_HTTP_CRLF)) + { + end_of_headers = AXIS2_TRUE; + } + else + { + axis2_http_header_t *tmp_header = axis2_http_header_create_by_str(env, str_header); + memset(str_header, 0, 512); + if(tmp_header) + { + axis2_http_simple_response_set_header(client->response, env, tmp_header); + } + } + } + end_of_line = AXIS2_FALSE; + } + axis2_http_simple_response_set_body_stream(client->response, env, client->data_stream); + if(status_line) + { + status_code = axis2_http_status_line_get_status_code(status_line, env); + axis2_http_status_line_free(status_line, env); + status_line = NULL; + } + + if(AXIS2_FALSE == axis2_http_simple_response_contains_header(client->response, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE) && 202 != status_code + && axis2_http_simple_response_get_content_length(client->response, env) > 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_CONTENT_TYPE_MISSING, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response does not contain" " Content-Type"); + return -1; + } + return status_code; +} + +AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL +axis2_http_client_get_response( + const axis2_http_client_t * client, + const axutil_env_t * env) +{ + return client->response; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_url( + axis2_http_client_t * client, + const axutil_env_t * env, + axutil_url_t * url) +{ + AXIS2_PARAM_CHECK(env->error, url, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE); + + if(client->url) + { + axutil_url_free(client->url, env); + client->url = NULL; + } + client->url = url; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_url_t *AXIS2_CALL +axis2_http_client_get_url( + const axis2_http_client_t * client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, client, NULL); + return client->url; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_timeout( + axis2_http_client_t * client, + const axutil_env_t * env, + int timeout_ms) +{ + AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE); + client->timeout = timeout_ms; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_client_get_timeout( + const axis2_http_client_t * client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE); + return client->timeout; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_proxy( + axis2_http_client_t * client, + const axutil_env_t * env, + axis2_char_t * proxy_host, + int proxy_port) +{ + AXIS2_PARAM_CHECK(env->error, proxy_host, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE); + + if(proxy_port <= 0) + { + return AXIS2_FAILURE; + } + + client->proxy_port = proxy_port; + if(client->proxy_host) + { + AXIS2_FREE(env->allocator, client->proxy_host); + client->proxy_host = NULL; + } + + if(client->proxy_host_port) + { + AXIS2_FREE(env->allocator, client->proxy_host_port); + client->proxy_host_port = NULL; + } + + client->proxy_host = axutil_strdup(env, proxy_host); + if(!client->proxy_host) + { + return AXIS2_FAILURE; + } + + client->proxy_host_port = AXIS2_MALLOC(env->allocator, axutil_strlen(proxy_host) + 10 + * sizeof(axis2_char_t)); + + sprintf(client->proxy_host_port, "%s:%d", proxy_host, proxy_port); + client->proxy_enabled = AXIS2_TRUE; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_client_get_proxy( + const axis2_http_client_t * client, + const axutil_env_t * env) +{ + AXIS2_PARAM_CHECK(env->error, client, NULL); + return client->proxy_host_port; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_connect_ssl_host( + axis2_http_client_t * client, + const axutil_env_t * env, + axis2_char_t * host, + int port) +{ + axutil_stream_t *tmp_stream = NULL; + axis2_char_t *connect_string = NULL; + axis2_char_t str_status_line[512]; + axis2_char_t tmp_buf[3]; + int read = 0; + axis2_bool_t end_of_line = AXIS2_FALSE; + axis2_bool_t end_of_response = AXIS2_FALSE; + axis2_http_status_line_t *status_line = NULL; + + AXIS2_PARAM_CHECK(env->error, host, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, client->url, AXIS2_FAILURE); + /* This host and port will use for give undersandable log messages + * */ + + if(port <= 0) + { + return AXIS2_FAILURE; + } + + tmp_stream = axutil_stream_create_socket(env, client->sockfd); + if(!tmp_stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "unable to create open socket for ssl host %s and %d \ +port", host, port); + return AXIS2_FAILURE; + } + + connect_string = AXIS2_MALLOC(env->allocator, axutil_strlen(host) * sizeof(axis2_char_t) + 30 + * sizeof(axis2_char_t)); + sprintf(connect_string, "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port); + axutil_stream_write(tmp_stream, env, connect_string, axutil_strlen(connect_string) + * sizeof(axis2_char_t)); + + memset(str_status_line, 0, 512); + while((read = axutil_stream_read(tmp_stream, env, tmp_buf, 1)) > 0) + { + tmp_buf[read] = '\0'; + strcat(str_status_line, tmp_buf); + if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF)) + { + end_of_line = AXIS2_TRUE; + break; + } + } + if(read < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, connect_string); + axutil_stream_free(tmp_stream, env); + return AXIS2_FAILURE; + } + status_line = axis2_http_status_line_create(env, str_status_line); + if(!status_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, connect_string); + axutil_stream_free(tmp_stream, env); + return AXIS2_FAILURE; + } + if(200 != axis2_http_status_line_get_status_code(status_line, env)) + { + AXIS2_FREE(env->allocator, connect_string); + axutil_stream_free(tmp_stream, env); + return AXIS2_FAILURE; + } + /* We need to empty the stream before we return + */ + memset(str_status_line, 0, 512); + while(AXIS2_FALSE == end_of_response) + { + while((read = axutil_stream_read(tmp_stream, env, tmp_buf, 1)) > 0) + { + tmp_buf[read] = '\0'; + strcat(str_status_line, tmp_buf); + if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF)) + { + end_of_line = AXIS2_TRUE; + break; + } + } + if(AXIS2_TRUE == end_of_line) + { + if(0 == axutil_strcmp(str_status_line, AXIS2_HTTP_CRLF)) + { + end_of_response = AXIS2_TRUE; + } + } + } + AXIS2_FREE(env->allocator, connect_string); + axutil_stream_free(tmp_stream, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_dump_input_msg( + axis2_http_client_t * client, + const axutil_env_t * env, + axis2_bool_t dump_input_msg) +{ + client->dump_input_msg = dump_input_msg; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_server_cert( + axis2_http_client_t * client, + const axutil_env_t * env, + axis2_char_t * server_cert) +{ + AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, server_cert, AXIS2_FAILURE); + client->server_cert = server_cert; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_client_get_server_cert( + const axis2_http_client_t * client, + const axutil_env_t * env) +{ + return client->server_cert; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_key_file( + axis2_http_client_t * client, + const axutil_env_t * env, + axis2_char_t * key_file) +{ + AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, key_file, AXIS2_FAILURE); + client->key_file = key_file; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_client_get_key_file( + const axis2_http_client_t * client, + const axutil_env_t * env) +{ + return client->key_file; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_mime_parts( + axis2_http_client_t * client, + const axutil_env_t * env, + axutil_array_list_t *mime_parts) +{ + client->mime_parts = mime_parts; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_http_client_get_mime_parts( + const axis2_http_client_t * client, + const axutil_env_t * env) +{ + return client->mime_parts; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_doing_mtom( + axis2_http_client_t * client, + const axutil_env_t * env, + axis2_bool_t doing_mtom) +{ + client->doing_mtom = doing_mtom; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_client_get_doing_mtom( + const axis2_http_client_t * client, + const axutil_env_t * env) +{ + return client->doing_mtom; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_client_set_mtom_sending_callback_name( + axis2_http_client_t * client, + const axutil_env_t * env, + axis2_char_t *callback_name) +{ + client->mtom_sending_callback_name = callback_name; + return AXIS2_SUCCESS; +} diff --git a/src/core/transport/http/sender/http_sender.c b/src/core/transport/http/sender/http_sender.c new file mode 100644 index 0000000..56f11e0 --- /dev/null +++ b/src/core/transport/http/sender/http_sender.c @@ -0,0 +1,3332 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_sender.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <axis2_http_transport_utils.h> +#include <string.h> +#include <axiom_output.h> +#include <axis2_op_ctx.h> +#include <axis2_ctx.h> +#include <axis2_conf_ctx.h> +#include <axis2_http_client.h> +#include <axiom_xml_writer.h> +#include <axutil_property.h> +#include <axutil_param.h> +#include <axutil_types.h> +#include <axutil_generic_obj.h> +#include <axutil_uuid_gen.h> +#include <axutil_digest_calc.h> +#include <axis2_const.h> +#include <axis2_util.h> +#include <axiom_soap.h> +#include <axutil_version.h> + +#ifdef AXIS2_LIBCURL_ENABLED +#include "libcurl/axis2_libcurl.h" +#else +#define CLIENT_NONCE_LENGTH 8 +#endif + +struct axis2_http_sender +{ + axis2_char_t *http_version; + axis2_bool_t chunked; + int so_timeout; + axiom_output_t *om_output; + axis2_http_client_t *client; + axis2_bool_t is_soap; + axis2_bool_t keep_alive; +}; + +#ifndef AXIS2_LIBCURL_ENABLED +static void +axis2_http_sender_add_header_list( + axis2_http_simple_request_t * request, + const axutil_env_t * env, + axutil_array_list_t * array_list); + +static axis2_status_t +axis2_http_sender_configure_proxy( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +static axis2_status_t +axis2_http_sender_configure_server_cert( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +static axis2_status_t +axis2_http_sender_configure_key_file( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +static axis2_status_t +axis2_http_sender_configure_http_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request); + +static axis2_status_t +axis2_http_sender_configure_proxy_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request); + +static axis2_status_t +axis2_http_sender_set_http_auth_type( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request); + +static axis2_status_t +axis2_http_sender_set_proxy_auth_type( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request); + +static axis2_status_t +axis2_http_sender_configure_http_basic_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request); + +static axis2_status_t +axis2_http_sender_configure_proxy_basic_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request); + +static axis2_status_t +axis2_http_sender_configure_http_digest_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request, + axis2_char_t * header_data); + +static axis2_status_t +axis2_http_sender_configure_proxy_digest_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request, + axis2_char_t * header_data); + + + +#endif + +static axutil_hash_t * +axis2_http_sender_connection_map_create( + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx); + +static void +axis2_http_sender_connection_map_remove( + axutil_hash_t *connection_map, + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx, + axis2_http_client_t *http_client); + +static void +axis2_http_sender_connection_map_add( + axutil_hash_t *connection_map, + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx, + axis2_http_client_t *http_client); + +static axis2_http_client_t * +axis2_http_sender_connection_map_get( + axutil_hash_t *connection_map, + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx); + +static void AXIS2_CALL +axis2_http_sender_connection_map_free( + void *cm_void, + const axutil_env_t *env); + +AXIS2_EXTERN axis2_http_sender_t *AXIS2_CALL +axis2_http_sender_create( + const axutil_env_t * env) +{ + axis2_http_sender_t *sender = NULL; + + sender = (axis2_http_sender_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_sender_t)); + + if(!sender) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset(sender, 0, sizeof(axis2_http_sender_t)); + sender->http_version = (axis2_char_t *)AXIS2_HTTP_HEADER_PROTOCOL_11; + sender->so_timeout = AXIS2_HTTP_DEFAULT_SO_TIMEOUT; + /* unlike the java impl we don't have a default om output + * it should be explicitly set and it's a MUST + */ + sender->om_output = NULL; + sender->chunked = AXIS2_FALSE; + sender->client = NULL; + sender->keep_alive = AXIS2_TRUE; + + return sender; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_sender_free( + axis2_http_sender_t * sender, + const axutil_env_t * env) +{ + if(sender->http_version) + { + AXIS2_FREE(env->allocator, sender->http_version); + } + + /* Do not free this here since it will be required in later processing + * of the response soap message + */ + sender->client = NULL; + AXIS2_FREE(env->allocator, sender); + return; +} + +#ifndef AXIS2_LIBCURL_ENABLED +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_sender_send( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axiom_soap_envelope_t * out, + const axis2_char_t * str_url, + const axis2_char_t * soap_action) +{ + axis2_http_simple_request_t *request = NULL; + axis2_http_request_line_t *request_line = NULL; + + /* url is to hold url given in str_url */ + axutil_url_t *url = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *buffer = NULL; + unsigned int buffer_size = 0; + const axis2_char_t *char_set_enc = NULL; + axutil_string_t *char_set_enc_str = NULL; + int status_code = -1; + axis2_http_simple_response_t *response = NULL; + axis2_char_t *content_type = NULL; + axis2_bool_t content_type_deepl_copy = AXIS2_TRUE; + axis2_byte_t *output_stream = NULL; + int output_stream_size = 0; + axis2_bool_t doing_mtom = AXIS2_FALSE; + axutil_property_t *dump_property = NULL; + axutil_param_t *ssl_pp_param = NULL; + /* ssl passphrase */ + axis2_char_t *ssl_pp = NULL; + axutil_property_t *ssl_pp_property = NULL; + axutil_property_t *test_auth_property = NULL; + axis2_char_t *test_auth_property_value = NULL; + axis2_bool_t test_proxy_auth = AXIS2_FALSE; + axis2_bool_t test_http_auth = AXIS2_FALSE; + + /* http proxy authentication */ + axutil_property_t *proxy_auth_property = NULL; + axis2_char_t *proxy_auth_property_value = NULL; + axis2_bool_t force_proxy_auth = AXIS2_FALSE; + axis2_bool_t force_proxy_auth_with_head = AXIS2_FALSE; + axutil_property_t *http_auth_property = NULL; + axis2_char_t *http_auth_property_value = NULL; + axis2_bool_t force_http_auth = AXIS2_FALSE; + axis2_bool_t force_http_auth_with_head = AXIS2_FALSE; + axutil_property_t *content_type_property = NULL; + axutil_hash_t *content_type_hash = NULL; + axis2_char_t *content_type_value = NULL; + axutil_property_t *method = NULL; + axis2_char_t *method_value = NULL; + + /* handling REST requests */ + axis2_bool_t send_via_get = AXIS2_FALSE; + axis2_bool_t send_via_head = AXIS2_FALSE; + axis2_bool_t send_via_delete = AXIS2_FALSE; + axis2_bool_t send_via_put = AXIS2_FALSE; + axiom_node_t *data_out = NULL; + axiom_node_t *body_node = NULL; + axiom_soap_body_t *soap_body = NULL; + axis2_bool_t is_soap = AXIS2_TRUE; + axis2_bool_t add_keepalive_header = AXIS2_FALSE; + + /* http header property to get HTTP headers from msg_ctx and give + * it to http_sender */ + axutil_property_t *http_property = NULL; + axutil_array_list_t *array_list; + axis2_bool_t http_auth_header_added = AXIS2_FALSE; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *write_xml_declaration_param = NULL; + axutil_hash_t *transport_attrs = NULL; + axis2_bool_t write_xml_declaration = AXIS2_FALSE; + axutil_property_t *property = NULL;/* Property for holding http client */ + /*axis2_char_t *header_value = NULL;*/ + axis2_char_t *cookie_str = NULL; + axutil_hash_t *connection_map = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_sender_send"); + soap_body = axiom_soap_envelope_get_body(out, env); + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, out, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, str_url, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, soap_action, AXIS2_FAILURE); + + if(AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + { + is_soap = AXIS2_FALSE; + } + else + { + is_soap = AXIS2_TRUE; + } + + url = axutil_url_parse_string(env, str_url); + + if(!is_soap) + { + if(soap_body) + { + body_node = axiom_soap_body_get_base_node(soap_body, env); + } + if(body_node) + { + data_out = axiom_node_get_first_element(body_node, env); + } + + method = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_METHOD); + if(method) + { + method_value = (axis2_char_t *)axutil_property_get_value(method, env); + } + + /* The default is POST */ + if(method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_GET)) + { + send_via_get = AXIS2_TRUE; + } + else if(method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_HEAD)) + { + send_via_head = AXIS2_TRUE; + } + else if(method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_PUT)) + { + send_via_put = AXIS2_TRUE; + } + else if(method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_DELETE)) + { + send_via_delete = AXIS2_TRUE; + } + } + + if(!url) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "url is null for string %s", str_url); + return AXIS2_FAILURE; + } + + /*if(sender->client) + { + axis2_http_client_free(sender->client, env); + sender->client = NULL; + }*/ + + /* This property may be set by the application client. This get the priority over the keep alive + * parameter set in the axix2.xml + */ + property = (axutil_property_t *) axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE); + if(property) + { + axis2_char_t *keep_alive_value = NULL; + + keep_alive_value = axutil_property_get_value(property, env); + if(!axutil_strcmp(keep_alive_value, AXIS2_VALUE_FALSE)) + { + sender->keep_alive = AXIS2_FALSE; + } + } + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + } + + /* Because keep alive is not still supported at callback receiver we check + * for client side + */ + if(sender->keep_alive && !axis2_msg_ctx_get_server_side(msg_ctx, env)) + { + axutil_property_t *connection_map_property = NULL; + + connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env, + AXIS2_HTTP_CONNECTION_MAP); + if(!connection_map_property) + { + connection_map = axis2_http_sender_connection_map_create(env, msg_ctx); + if(!connection_map) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else + { + connection_map = axutil_property_get_value(connection_map_property, env); + if(connection_map) + { + sender->client = axis2_http_sender_connection_map_get(connection_map, env, msg_ctx); + } + } + if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_10)) + { + add_keepalive_header = AXIS2_TRUE; + } + } /* End if sender->keep_alive */ + if(!sender->client) + { + sender->client = axis2_http_client_create(env, url); + } + if(!sender->client) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "sender->client creation failed for url %s", url); + return AXIS2_FAILURE; + } + /* configure proxy settings if we have set so + */ + + axis2_http_sender_configure_proxy(sender, env, msg_ctx); + + if(conf) + { + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + } + + if(trans_desc) + { + /* get xml declaration details from axis2.xml */ + write_xml_declaration_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_XML_DECLARATION); + } + + if(write_xml_declaration_param) + { + /* accessing attributes of the HTTP transport's , xml + * declaration element from axis2.xml*/ + + transport_attrs = axutil_param_get_attributes(write_xml_declaration_param, env); + if(transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *write_xml_declaration_attr = NULL; + axis2_char_t *write_xml_declaration_attr_value = NULL; + + obj + = axutil_hash_get(transport_attrs, AXIS2_ADD_XML_DECLARATION, AXIS2_HASH_KEY_STRING); + if(obj) + { + write_xml_declaration_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, + env); + } + + if(write_xml_declaration_attr) + { + write_xml_declaration_attr_value = axiom_attribute_get_value( + write_xml_declaration_attr, env); + } + + if(write_xml_declaration_attr_value && 0 == axutil_strcasecmp( + write_xml_declaration_attr_value, AXIS2_VALUE_TRUE)) + { + write_xml_declaration = AXIS2_TRUE; + } + } + } + + if(write_xml_declaration) + { + axiom_output_write_xml_version_encoding(sender->om_output, env); + } + + if(!send_via_get && !send_via_head && !send_via_delete) + { + /* processing POST and PUT methods */ + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "msg_ctx_id:%s", axis2_msg_ctx_get_msg_id(msg_ctx, + env)); + + doing_mtom = axis2_msg_ctx_get_doing_mtom(msg_ctx, env); + + if(!sender->om_output) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_OM_OUTPUT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", AXIS2_ERROR_GET_MESSAGE(env->error)); + return AXIS2_FAILURE; + } + + xml_writer = axiom_output_get_xml_writer(sender->om_output, env); + + char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env); + + if(!char_set_enc_str) + { + /* if there is no character encoding details available + * use default one. + * #define AXIS2_DEFAULT_CHAR_SET_ENCODING "UTF-8" + */ + char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING; + } + else + { + char_set_enc = axutil_string_get_buffer(char_set_enc_str, env); + } + + if(!send_via_put && is_soap) + { + /* HTTP POST case */ + /* dump property use to dump message without sending */ + dump_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_DUMP_INPUT_MSG_TRUE); + if(dump_property) + { + axis2_char_t *dump_true = axutil_property_get_value(dump_property, env); + if(0 == axutil_strcmp(dump_true, AXIS2_VALUE_TRUE)) + { + axis2_http_client_set_dump_input_msg(sender->client, env, AXIS2_TRUE); + } + } + + axiom_output_set_do_optimize(sender->om_output, env, doing_mtom); + axiom_soap_envelope_serialize(out, env, sender->om_output, AXIS2_FALSE); + } + else if(is_soap) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Attempt to send SOAP message using HTTP PUT failed"); + return AXIS2_FAILURE; + } + else + { + if(!data_out) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "body node payload is NULL"); + return AXIS2_FAILURE; + } + axiom_node_serialize(data_out, env, sender->om_output); + } + + if(doing_mtom) + { + axutil_param_t *callback_name_param = NULL; + axis2_status_t mtom_status = AXIS2_FAILURE; + axutil_array_list_t *mime_parts = NULL; + axis2_char_t *mtom_sending_callback_name = NULL; + + /* Getting the sender callback name paramter if it is + * specified in the configuration file */ + + callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env, + AXIS2_MTOM_SENDING_CALLBACK); + if(callback_name_param) + { + mtom_sending_callback_name = (axis2_char_t *)axutil_param_get_value( + callback_name_param, env); + if(mtom_sending_callback_name) + { + axis2_http_client_set_mtom_sending_callback_name(sender->client, env, + mtom_sending_callback_name); + } + } + + /* Here we put all the attachment related stuff in a array_list + After this method we have the message in parts */ + + mtom_status = axiom_output_flush(sender->om_output, env); + if(mtom_status == AXIS2_FAILURE) + { + return mtom_status; + } + /* HTTP client should distinguish an MTOM invocation because the way + of sending the message in MTOM case is different */ + axis2_http_client_set_doing_mtom(sender->client, env, doing_mtom); + + /* HTTP client will keep this mime_parts, which it will send in chunks at + th end */ + mime_parts = axiom_output_get_mime_parts(sender->om_output, env); + if(mime_parts) + { + axis2_http_client_set_mime_parts(sender->client, env, mime_parts); + } + } + else + { + buffer = axiom_xml_writer_get_xml(xml_writer, env); + } + + if(!(buffer || doing_mtom)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "NULL xml returned from xml writer"); + return AXIS2_FAILURE; + } + + if(!send_via_put) + { + /* HTTP POST */ + axis2_char_t *path_with_query = NULL; + + path_with_query = axutil_strcat(env, axutil_url_get_path(url, env), + axutil_url_get_query(url, env), NULL); + request_line = axis2_http_request_line_create(env, AXIS2_HTTP_POST, path_with_query, + sender->http_version); + AXIS2_FREE(env->allocator, path_with_query); + } + else + { + /* HTTP PUT */ + request_line = axis2_http_request_line_create(env, AXIS2_HTTP_PUT, axutil_url_get_path( + url, env), sender->http_version); + } + } + else + { + /* Processing HTTP GET, HEAD and DELETE */ + + axis2_char_t *request_params = NULL; + axis2_char_t *path = NULL; + + request_params = axis2_http_sender_get_param_string(sender, env, msg_ctx); + + if(request_params) + { + /* substituting AXIS2_Q_MARK for "?" */ + path = axutil_strcat(env, axutil_url_get_path(url, env), AXIS2_Q_MARK_STR, + request_params, NULL); + AXIS2_FREE(env->allocator, request_params); + request_params = NULL; + } + else + { + path = axutil_strdup(env, axutil_url_get_path(url, env)); + } + + if(send_via_get) + { + request_line = axis2_http_request_line_create(env, AXIS2_HTTP_GET, path, + sender->http_version); + } + else if(send_via_head) + { + request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD, path, + sender->http_version); + } + else if(send_via_delete) + { + request_line = axis2_http_request_line_create(env, AXIS2_HTTP_DELETE, path, + sender->http_version); + } + + if(path) + { + AXIS2_FREE(env->allocator, path); + path = NULL; + } + } + + request = axis2_http_simple_request_create(env, request_line, NULL, 0, NULL); + if(add_keepalive_header) + { + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONNECTION, + AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE); + } + /** + * If there is a session related stuff handle it + */ + /*header_value = axis2_http_transport_utils_get_session(env, msg_ctx); + if(header_value) + { + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SET_COOKIE, header_value); + }*/ + + /** + * In the client side sender if a cookie is sent by server add it to the http header + */ + cookie_str = axis2_http_transport_utils_read_from_cookie_store(env, msg_ctx); + if(cookie_str) + { + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_COOKIE, cookie_str); + } + + /* User-Agent:Axis2/C header */ + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_USER_AGENT, AXIS2_USER_AGENT); + + http_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_HEADER_PROPERTY); + if(http_property) + { + array_list = (axutil_array_list_t *)axutil_property_get_value(http_property, env); + axis2_http_sender_add_header_list(request, env, array_list); + } + + if(!send_via_get && !send_via_head && !send_via_put && !send_via_delete && AXIS2_TRUE + == axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + if(AXIS2_ESC_DOUBLE_QUOTE != *soap_action) + { + axis2_char_t *tmp_soap_action = NULL; + tmp_soap_action = AXIS2_MALLOC(env->allocator, (axutil_strlen(soap_action) + 5) + * sizeof(axis2_char_t)); + sprintf(tmp_soap_action, "\"%s\"", soap_action); + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SOAP_ACTION, + tmp_soap_action); + AXIS2_FREE(env->allocator, tmp_soap_action); + } + else + { + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SOAP_ACTION, + (const axis2_char_t *)soap_action); + } + } + else if(AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding of SOAP Action Failed for REST request"); + + return AXIS2_FAILURE; + } + + if(!send_via_get && !send_via_head && !send_via_delete) + { + /* processing PUT and POST */ + buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env); + + if(AXIS2_FALSE == sender->chunked) + { + axis2_char_t tmp_buf[10]; + if(!buffer) + { + buffer_size = output_stream_size; + } + + if(buffer_size) + { + sprintf(tmp_buf, "%d", buffer_size); + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONTENT_LENGTH, + tmp_buf); + } + } + else + { + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_TRANSFER_ENCODING, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED); + } + + if(!send_via_put && is_soap) + { + /* HTTP POST */ + if(doing_mtom) + { + content_type = (axis2_char_t *)axiom_output_get_content_type(sender-> om_output, + env); + if(AXIS2_TRUE != axis2_msg_ctx_get_is_soap_11(msg_ctx, env) && axutil_strcmp( + soap_action, "")) + { + /* handle SOAP action for SOAP 1.2 case */ + axis2_char_t *temp_content_type = NULL; + temp_content_type + = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_ACTION); + content_type = temp_content_type; + temp_content_type = axutil_stracat(env, content_type, soap_action); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + temp_content_type = axutil_stracat(env, content_type, + AXIS2_ESC_DOUBLE_QUOTE_STR); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + } + else + { + content_type_deepl_copy = AXIS2_FALSE; + } + } + else if(AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + /* SOAP 1.1 without MTOM */ + axis2_char_t *temp_content_type = NULL; + content_type = (axis2_char_t *)AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML; + content_type = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_CHARSET); + temp_content_type = axutil_stracat(env, content_type, char_set_enc); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + } + else + { + /* SOAP 1.2 without MTOM */ + axis2_char_t *temp_content_type = NULL; + content_type = (axis2_char_t *)AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP; + content_type = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_CHARSET); + temp_content_type = axutil_stracat(env, content_type, char_set_enc); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + if(axutil_strcmp(soap_action, "")) + { + temp_content_type + = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_ACTION); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + temp_content_type = axutil_stracat(env, content_type, soap_action); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + temp_content_type = axutil_stracat(env, content_type, + AXIS2_ESC_DOUBLE_QUOTE_STR); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + } + } + } + else if(is_soap) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Attempt to send SOAP message using HTTP PUT failed"); + return AXIS2_FAILURE; + } + else + { + content_type_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_USER_DEFINED_HTTP_HEADER_CONTENT_TYPE); + + if(content_type_property) + { + content_type_hash = (axutil_hash_t *)axutil_property_get_value( + content_type_property, env); + if(content_type_hash) + { + content_type_value = (char *)axutil_hash_get(content_type_hash, + AXIS2_HTTP_HEADER_CONTENT_TYPE, AXIS2_HASH_KEY_STRING); + } + } + + if(content_type_value) + { + content_type = content_type_value; + } + else + { + content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML; + } + + content_type_deepl_copy = AXIS2_FALSE; + } + + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONTENT_TYPE, + content_type); + + if(content_type_deepl_copy && content_type) + { + AXIS2_FREE(env->allocator, content_type); + content_type = NULL; + } + /* Finished Processing PUT and POST */ + } + + if(0 == axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_11)) + { + /* HTTP 1.1 */ + axis2_char_t *header = NULL; + int host_len = 0; + host_len = axutil_strlen(axutil_url_get_host(url, env)); + header = AXIS2_MALLOC(env->allocator, host_len + 10 * sizeof(axis2_char_t)); + sprintf(header, "%s:%d", axutil_url_get_host(url, env), axutil_url_get_port(url, env)); + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_HOST, header); + AXIS2_FREE(env->allocator, header); + header = NULL; + } + + /* If this is a normal invocation the buffer has the full SOAP message + which needs to be send. In the MTOM case instead of this buffer + it has the mime_parts array_list */ + + if(!doing_mtom) + { + axis2_http_simple_request_set_body_string(request, env, buffer, buffer_size); + } + + /* HTTPS request processing */ + axis2_http_sender_configure_server_cert(sender, env, msg_ctx); + + axis2_http_sender_configure_key_file(sender, env, msg_ctx); + + axis2_http_sender_get_timeout_values(sender, env, msg_ctx); + axis2_http_client_set_timeout(sender->client, env, sender->so_timeout); + + ssl_pp_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_PASSPHRASE); + + if(ssl_pp_property) + { + ssl_pp = (axis2_char_t *)axutil_property_get_value(ssl_pp_property, env); + } + else + { + ssl_pp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_PASSPHRASE); + + if(ssl_pp_param) + { + ssl_pp = axutil_param_get_value(ssl_pp_param, env); + } + } + + test_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_TEST_PROXY_AUTH); + if(test_auth_property) + { + test_auth_property_value = (axis2_char_t *)axutil_property_get_value(test_auth_property, + env); + } + + if(test_auth_property_value && 0 == axutil_strcmp(test_auth_property_value, AXIS2_VALUE_TRUE)) + { + test_proxy_auth = AXIS2_TRUE; + } + + test_auth_property = NULL; + test_auth_property_value = NULL; + + test_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_TEST_HTTP_AUTH); + if(test_auth_property) + { + test_auth_property_value = (axis2_char_t *)axutil_property_get_value(test_auth_property, + env); + } + + if(test_auth_property_value && 0 == axutil_strcmp(test_auth_property_value, AXIS2_VALUE_TRUE)) + { + test_http_auth = AXIS2_TRUE; + } + + if(!test_proxy_auth) + { + proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_FORCE_PROXY_AUTH); + } + if(proxy_auth_property) + { + proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property, + env); + } + + if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value, AXIS2_VALUE_TRUE)) + { + force_proxy_auth = AXIS2_TRUE; + } + + proxy_auth_property = NULL; + proxy_auth_property_value = NULL; + + if(force_proxy_auth) + { + proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_PROXY_AUTH_TYPE); + } + + if(proxy_auth_property) + { + proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property, + env); + } + + if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value, + AXIS2_PROXY_AUTH_TYPE_DIGEST)) + { + force_proxy_auth = AXIS2_FALSE; + force_proxy_auth_with_head = AXIS2_TRUE; + } + + if(!test_http_auth) + { + http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_FORCE_HTTP_AUTH); + } + + if(http_auth_property) + { + http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property, + env); + } + + if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value, AXIS2_VALUE_TRUE)) + { + force_http_auth = AXIS2_TRUE; + } + + http_auth_property = NULL; + http_auth_property_value = NULL; + + if(force_http_auth) + { + http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_HTTP_AUTH_TYPE); + } + + if(http_auth_property) + { + http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property, + env); + } + + if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value, + AXIS2_HTTP_AUTH_TYPE_DIGEST)) + { + force_http_auth = AXIS2_FALSE; + force_http_auth_with_head = AXIS2_TRUE; + } + + axis2_msg_ctx_set_auth_type(msg_ctx, env, NULL); + + if(force_proxy_auth || force_proxy_auth_with_head) + { + status_code = AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL; + } + else + { + /* NOT forcing proxy authentication */ + if(force_http_auth) + { + axis2_status_t auth_status; + auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request); + + if(auth_status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in setting HTTP Authentication header"); + } + http_auth_header_added = AXIS2_TRUE; + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + } + + else if(force_http_auth_with_head) + { + axis2_http_request_line_t *head_request_line = NULL; + axis2_http_request_line_t *temp = NULL; + + temp = axis2_http_simple_request_get_request_line(request, env); + head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD, + axis2_http_request_line_get_uri(temp, env), + axis2_http_request_line_get_http_version(temp, env)); + axis2_http_simple_request_set_request_line(request, env, head_request_line); + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + axis2_http_simple_request_set_request_line(request, env, temp); + axis2_http_request_line_free(head_request_line, env); + + if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL) + { + axis2_status_t auth_status; + auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request); + + if(auth_status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in setting HTTP Authentication\ + header"); + } + http_auth_header_added = AXIS2_TRUE; + } + + if(status_code != AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL) + { + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + + if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL) + { + http_auth_header_added = AXIS2_FALSE; + force_http_auth_with_head = AXIS2_FALSE; + } + } + } + else + { + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + } + } + + if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code + && !test_proxy_auth) + { + if(force_proxy_auth_with_head) + { + axis2_http_request_line_t *head_request_line = NULL; + axis2_http_request_line_t *temp = NULL; + + temp = axis2_http_simple_request_get_request_line(request, env); + head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD, + axis2_http_request_line_get_uri(temp, env), + axis2_http_request_line_get_http_version(temp, env)); + axis2_http_simple_request_set_request_line(request, env, head_request_line); + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + axis2_http_simple_request_set_request_line(request, env, temp); + axis2_http_request_line_free(head_request_line, env); + + if(status_code == AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL) + { + axis2_status_t auth_status; + auth_status = axis2_http_sender_configure_proxy_auth(sender, env, msg_ctx, request); + + if(auth_status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in setting Proxy Authentication\ + header"); + } + + if((force_http_auth_with_head || force_http_auth) && !http_auth_header_added) + { + status_code = AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL; + } + else + { + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + } + } + else if(status_code != AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL) + { + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + } + + /* Proxies have no idea about HTTP Methods therefore, if + * it fails no need to re-check */ + if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed"); + axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE); + } + } + else + { + + /* not forcing proxy auth with head */ + axis2_status_t auth_status; + auth_status = axis2_http_sender_configure_proxy_auth(sender, env, msg_ctx, request); + + if(auth_status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in setting Proxy Authentication \ +header"); + } + + if((force_http_auth_with_head || force_http_auth) && !http_auth_header_added) + { + status_code = AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL; + } + else + { + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + + if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed"); + axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE); + } + } + } + } + else if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code) + { + axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE); + axis2_http_sender_set_proxy_auth_type(sender, env, msg_ctx, request); + } + + if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code && !test_http_auth) + { + if(!http_auth_header_added) + { + if(force_proxy_auth_with_head) + { + axis2_http_request_line_t *head_request_line = NULL; + axis2_http_request_line_t *temp = NULL; + + temp = axis2_http_simple_request_get_request_line(request, env); + head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD, + axis2_http_request_line_get_uri(temp, env), + axis2_http_request_line_get_http_version(temp, env)); + axis2_http_simple_request_set_request_line(request, env, head_request_line); + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + axis2_http_simple_request_set_request_line(request, env, temp); + axis2_http_request_line_free(head_request_line, env); + + if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL) + { + axis2_status_t auth_status; + auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, + request); + + if(auth_status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in setting HTTP Authentication \ +header"); + } + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL) + { + axis2_status_t auth_status; + auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, + request); + + if(auth_status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in setting HTTP \ +Authentication header"); + } + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + } + + } + } + else + { + axis2_status_t auth_status; + auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request); + + if(auth_status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in setting HTTP Authentication \ +header"); + } + + status_code = axis2_http_client_send(sender->client, env, request, ssl_pp); + + status_code = axis2_http_client_recieve_header(sender->client, env); + } + + if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP Authentication failed"); + axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE); + } + + if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed"); + axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE); + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP Authentication failed"); + axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE); + } + } + else if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code) + { + axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE); + axis2_http_sender_set_http_auth_type(sender, env, msg_ctx, request); + } + + axis2_http_simple_request_free(request, env); + request = NULL; + + if(output_stream) + { + AXIS2_FREE(env->allocator, output_stream); + output_stream = NULL; + } + + if(status_code < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "status_code < 0"); + return AXIS2_FAILURE; + } + + axis2_msg_ctx_set_status_code(msg_ctx, env, status_code); + + /* Start processing response */ + response = axis2_http_client_get_response(sender->client, env); + if(!is_soap) + { + return axis2_http_sender_process_response(sender, env, msg_ctx, response); + } + else if(AXIS2_HTTP_RESPONSE_OK_CODE_VAL == status_code || AXIS2_HTTP_RESPONSE_ACK_CODE_VAL + == status_code) + { + return axis2_http_sender_process_response(sender, env, msg_ctx, response); + } + else if(AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL == status_code) + { + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_header_val = NULL; + axis2_op_t *op = NULL; + + op = axis2_msg_ctx_get_op(msg_ctx, env); + if(op) + { + const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE); + /* handle one way case */ + + if(!axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "mep is AXIS2_MEP_URI_OUT_ONLY"); + return AXIS2_FAILURE; + } + } + + /* set an error to indicate error code status */ + tmp_header = axis2_http_simple_response_get_first_header(response, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + tmp_header_val = axis2_http_header_get_value(tmp_header, env); + } + + if(tmp_header_val && (axutil_strstr(tmp_header_val, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP) + || axutil_strstr(tmp_header_val, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))) + { + return axis2_http_sender_process_response(sender, env, msg_ctx, response); + } + } + + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE); + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_sender_send"); + return AXIS2_FAILURE; +} +#endif + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_sender_set_chunked( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_bool_t chunked) +{ + sender->chunked = chunked; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_sender_set_om_output( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + sender->om_output = om_output; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_sender_get_header_info( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_response_t * response) +{ + axutil_array_list_t *headers = NULL; + axis2_char_t *charset = NULL; + int i = 0; + axis2_bool_t response_chunked = AXIS2_FALSE; + int *content_length = NULL; + axutil_property_t *property = NULL; + axis2_char_t *content_type = NULL; + int status_code = 0; + axis2_bool_t set_cookie_header_present = AXIS2_FALSE; + axis2_bool_t connection_header_present = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, sender, AXIS2_FAILURE); + + headers = axis2_http_simple_response_get_headers(response, env); + if(headers == NULL) + { + return AXIS2_SUCCESS; + } + + for(i = 0; i < axutil_array_list_size(headers, env); i++) + { + axis2_http_header_t *header = axutil_array_list_get(headers, env, i); + axis2_char_t *name = axis2_http_header_get_name((axis2_http_header_t *)header, env); + if(name) + { + if(0 == axutil_strcasecmp(name, AXIS2_HTTP_HEADER_TRANSFER_ENCODING) && 0 + == axutil_strcasecmp(axis2_http_header_get_value(header, env), + AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)) + { + axis2_char_t *transfer_encoding = NULL; + transfer_encoding = axutil_strdup(env, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED); + response_chunked = AXIS2_TRUE; + axis2_msg_ctx_set_transfer_encoding(msg_ctx, env, transfer_encoding); + + } + if(0 != axutil_strcasecmp(name, AXIS2_HTTP_HEADER_CONTENT_TYPE)) + { + axis2_char_t *tmp_charset = NULL; + axis2_char_t *content_type = axis2_http_header_get_value(header, env); + tmp_charset = strstr(content_type, AXIS2_HTTP_CHAR_SET_ENCODING); + if(charset) + { + charset = axutil_strdup(env, tmp_charset); + break; + } + } + if(!axutil_strcasecmp(name, AXIS2_HTTP_HEADER_SET_COOKIE)) + { + axis2_char_t *cookie_str = axis2_http_header_get_value(header, env); + if(cookie_str) + { + axis2_http_transport_utils_store_cookie(env, msg_ctx, cookie_str); + } + set_cookie_header_present = AXIS2_TRUE; + } + + if(!axutil_strcasecmp(name, AXIS2_HTTP_HEADER_CONNECTION)) + { + axis2_char_t *connection_header_value = NULL; + axutil_property_t *connection_map_property = NULL; + axutil_hash_t *connection_map = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + connection_header_present = AXIS2_TRUE; + connection_header_value = axis2_http_header_get_value(header, env); + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env, + AXIS2_HTTP_CONNECTION_MAP); + + if(connection_map_property) + { + connection_map = axutil_property_get_value(connection_map_property, env); + } + /** + * In HTTP1.1 if connection header has value close then drop the connection + */ + if(connection_header_value && !axutil_strcasecmp(connection_header_value, "close")) + { + if(connection_map) + { + axis2_http_sender_connection_map_remove(connection_map, env, + msg_ctx, sender->client); + } + } + else if(connection_header_value && !axutil_strcasecmp(connection_header_value, + "Keep-Alive")) + { + if(connection_map) + { + axis2_http_sender_connection_map_add(connection_map, env, + msg_ctx, sender->client); + } + } + } /* End if name is connection */ + } /* End if name of the header present */ + } + if(!set_cookie_header_present) /* We need to remove any cookie set previously for this endpoint */ + { + axis2_http_transport_utils_store_cookie(env, msg_ctx, NULL); + } + if(!connection_header_present) /* No connection header present */ + { + /** In HTTP1.0 if there is no keep alive header sent back from server we drop the + * connection + */ + axutil_property_t *connection_map_property = NULL; + axutil_hash_t *connection_map = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + + connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env, + AXIS2_HTTP_CONNECTION_MAP); + if(connection_map_property) + { + connection_map = axutil_property_get_value(connection_map_property, env); + } /* End if connectin_map_property */ + if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_10)) + { + if(connection_map) + { + axis2_http_sender_connection_map_remove(connection_map, env, msg_ctx, + sender->client); + } + } /* End if http version 1.0 */ + else if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_11)) + { + /** + * If keep alive enabled we store the http client for reuse. + */ + if(connection_map) + { + axis2_http_sender_connection_map_add(connection_map, env, msg_ctx, + sender->client); + } + } /* End if http version 1.1 */ + } /* End if !connection_header_present */ + + content_type = (axis2_char_t *)axis2_http_simple_response_get_content_type(response, env); + if(content_type) + { + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED) && strstr(content_type, + AXIS2_HTTP_HEADER_ACCEPT_XOP_XML)) + { + axis2_ctx_t *axis_ctx = axis2_op_ctx_get_base(axis2_msg_ctx_get_op_ctx(msg_ctx, env), + env); + property = axutil_property_create(env); + axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_value(property, env, axutil_strdup(env, content_type)); + axis2_ctx_set_property(axis_ctx, env, MTOM_RECIVED_CONTENT_TYPE, property); + } + } + + if(charset) + { + axis2_ctx_t *axis_ctx = axis2_op_ctx_get_base(axis2_msg_ctx_get_op_ctx(msg_ctx, env), env); + if(axis_ctx) + { + property = axutil_property_create(env); + axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_value(property, env, charset); + axis2_ctx_set_property(axis_ctx, env, AXIS2_CHARACTER_SET_ENCODING, property); + } + } + + if(AXIS2_FALSE == response_chunked) + { + int tmp_len = 0; + content_length = AXIS2_MALLOC(env->allocator, sizeof(int)); + if(!content_length) + { + return AXIS2_FAILURE; + } + tmp_len = axis2_http_simple_response_get_content_length(response, env); + memcpy(content_length, &tmp_len, sizeof(int)); + property = axutil_property_create(env); + axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_value(property, env, content_length); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, property); + } + + status_code = axis2_http_simple_response_get_status_code(response, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_sender_process_response( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_response_t * response) +{ + axutil_stream_t *in_stream = NULL; + axutil_property_t *property = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_sender_process_response"); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE); + + in_stream = axis2_http_simple_response_get_body(response, env); + if(!in_stream) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_STREAM_IN_RESPONSE_BODY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + axis2_http_sender_get_header_info(sender, env, msg_ctx, response); + axis2_msg_ctx_set_http_output_headers(msg_ctx, env, axis2_http_simple_response_extract_headers( + response, env)); + property = axutil_property_create(env); + axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_free_func(property, env, axutil_stream_free_void_arg); + axutil_property_set_value(property, env, in_stream); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property); + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_sender_process_response"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_sender_get_timeout_values( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_char_t *so_str = NULL; + axis2_char_t *connection_str = NULL; + axutil_param_t *tmp_param = NULL; + axutil_property_t *property = NULL; + + AXIS2_PARAM_CHECK(env->error, sender, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + /* check if timeout has been set by user using options + * with axis2_options_set_timeout_in_milli_seconds + */ + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_CONNECTION_TIMEOUT); + if(property) + { + axis2_char_t *value = axutil_property_get_value(property, env); + if(value) + { + sender->so_timeout = AXIS2_ATOI(value); + return AXIS2_SUCCESS; + } + } + + tmp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_HTTP_SO_TIMEOUT); + + if(tmp_param) + { + so_str = (axis2_char_t *)axutil_param_get_value(tmp_param, env); + if(so_str) + { + sender->so_timeout = AXIS2_ATOI(so_str); + return AXIS2_SUCCESS; + } + } + + tmp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_HTTP_CONNECTION_TIMEOUT); + if(tmp_param) + { + connection_str = (axis2_char_t *)axutil_param_get_value(tmp_param, env); + if(connection_str) + { + sender->so_timeout = AXIS2_ATOI(connection_str); + return AXIS2_SUCCESS; + } + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_sender_set_http_version( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_char_t * version) +{ + sender->http_version = axutil_strdup(env, version); + if(!sender->http_version) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +#ifndef AXIS2_LIBCURL_ENABLED +static void +axis2_http_sender_add_header_list( + axis2_http_simple_request_t * request, + const axutil_env_t * env, + axutil_array_list_t * array_list) +{ + int ii = 0; + int kk = 0; + axis2_http_header_t *http_header = NULL; + ii = axutil_array_list_size(array_list, env); + for(; kk < ii; kk++) + { + http_header = (axis2_http_header_t *)axutil_array_list_get(array_list, env, kk); + axis2_http_simple_request_add_header(request, env, http_header); + } +} + +static axis2_status_t +axis2_http_sender_configure_proxy( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *proxy_param = NULL; + axutil_hash_t *transport_attrs = NULL; + axis2_char_t *proxy_host = NULL; + axis2_char_t *proxy_port = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(!conf_ctx) + { + return AXIS2_FAILURE; + } + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(!conf) + { + return AXIS2_FAILURE; + } + + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + if(!trans_desc) + { + return AXIS2_FAILURE; + } + + proxy_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container( + trans_desc, env), env, AXIS2_HTTP_PROXY_API); + if(!proxy_param) + { + proxy_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container( + trans_desc, env), env, AXIS2_HTTP_PROXY); + } + if(proxy_param) + { + transport_attrs = axutil_param_get_attributes(proxy_param, env); + if(transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *host_attr = NULL; + axiom_attribute_t *port_attr = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING); + if(!obj) + { + return AXIS2_FAILURE; + } + host_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + if(!host_attr) + { + return AXIS2_FAILURE; + } + proxy_host = axiom_attribute_get_value(host_attr, env); + if(!proxy_host) + { + return AXIS2_FAILURE; + } + /* Now we get the port */ + obj = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING); + port_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + if(!port_attr) + { + return AXIS2_FAILURE; + } + proxy_port = axiom_attribute_get_value(port_attr, env); + if(!proxy_port) + { + return AXIS2_FAILURE; + } + } + } + if(proxy_port && proxy_host) + { + axis2_http_client_set_proxy(sender->client, env, proxy_host, AXIS2_ATOI(proxy_port)); + } + return AXIS2_SUCCESS; +} +#endif + +#ifndef AXIS2_LIBCURL_ENABLED +static axis2_status_t +axis2_http_sender_configure_server_cert( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axutil_property_t *server_cert_property = NULL; + axutil_param_t *server_cert_param = NULL; + axis2_char_t *server_cert = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + server_cert_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_SERVER_CERT); + if(server_cert_property) + { + server_cert = (axis2_char_t *)axutil_property_get_value(server_cert_property, env); + } + else + { + server_cert_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_SERVER_CERT); + if(server_cert_param) + { + server_cert = (axis2_char_t *)axutil_param_get_value(server_cert_param, env); + } + } + + if(server_cert) + { + status = axis2_http_client_set_server_cert(sender->client, env, server_cert); + } + + return status; +} +#endif + +#ifndef AXIS2_LIBCURL_ENABLED +static axis2_status_t +axis2_http_sender_configure_key_file( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axutil_property_t *key_file_property = NULL; + axutil_param_t *key_file_param = NULL; + axis2_char_t *key_file = NULL; + axis2_status_t status = AXIS2_FAILURE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + key_file_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_KEY_FILE); + if(key_file_property) + { + key_file = (axis2_char_t *)axutil_property_get_value(key_file_property, env); + } + else + { + key_file_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_KEY_FILE); + if(key_file_param) + { + key_file = (axis2_char_t *)axutil_param_get_value(key_file_param, env); + } + } + + if(key_file) + { + status = axis2_http_client_set_key_file(sender->client, env, key_file); + } + + return status; +} +#endif + +#ifndef AXIS2_LIBCURL_ENABLED +static axis2_status_t +axis2_http_sender_configure_http_basic_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request) +{ + axutil_property_t *http_auth_un = NULL; + axutil_property_t *http_auth_pw = NULL; + axis2_char_t *uname = NULL; + axis2_char_t *passwd = NULL; + + http_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME); + http_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD); + if(http_auth_un && http_auth_pw) + { + uname = (axis2_char_t *)axutil_property_get_value(http_auth_un, env); + passwd = (axis2_char_t *)axutil_property_get_value(http_auth_pw, env); + } + if(!uname || !passwd) + { + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *http_auth_param = NULL; + axutil_hash_t *transport_attrs = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + } + } + if(trans_desc) + { + http_auth_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, + AXIS2_HTTP_AUTHENTICATION); + if(http_auth_param) + { + transport_attrs = axutil_param_get_attributes(http_auth_param, env); + if(transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *username_attr = NULL; + axiom_attribute_t *password_attr = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_USERNAME, + AXIS2_HASH_KEY_STRING); + if(obj) + { + username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if(username_attr) + { + uname = axiom_attribute_get_value(username_attr, env); + } + obj = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_PASSWORD, + AXIS2_HASH_KEY_STRING); + if(obj) + { + password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if(password_attr) + { + passwd = axiom_attribute_get_value(password_attr, env); + } + } + } + } + } + if(uname && passwd) + { + int elen; + int plen = axutil_strlen(uname) + axutil_strlen(passwd) + 1; + axis2_char_t *to_encode = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, + sizeof(axis2_char_t) * plen + 1)); + axis2_char_t *encoded = NULL; + axis2_char_t *auth_str = NULL; + sprintf(to_encode, "%s:%s", uname, passwd); + elen = axutil_base64_encode_len(plen); + encoded = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * elen)); + auth_str + = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 6))); + axutil_base64_encode(encoded, to_encode, plen); + sprintf(auth_str, "%s %s", AXIS2_HTTP_AUTH_TYPE_BASIC, encoded); + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_AUTHORIZATION, auth_str); + + AXIS2_FREE(env->allocator, to_encode); + to_encode = NULL; + AXIS2_FREE(env->allocator, encoded); + encoded = NULL; + AXIS2_FREE(env->allocator, auth_str); + auth_str = NULL; + + return AXIS2_SUCCESS; + } + + return AXIS2_FAILURE; + +} + +static axis2_status_t +axis2_http_sender_configure_proxy_basic_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request) +{ + axutil_property_t *proxy_auth_un = NULL; + axutil_property_t *proxy_auth_pw = NULL; + axis2_char_t *uname = NULL; + axis2_char_t *passwd = NULL; + + proxy_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME); + proxy_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD); + + if(proxy_auth_un && proxy_auth_pw) + { + uname = (axis2_char_t *)axutil_property_get_value(proxy_auth_un, env); + passwd = (axis2_char_t *)axutil_property_get_value(proxy_auth_pw, env); + } + if(!uname || !passwd) + { + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *proxy_param = NULL; + axutil_hash_t *transport_attrs = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + } + } + if(trans_desc) + { + proxy_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, + AXIS2_HTTP_PROXY_API); + if(!proxy_param) + { + proxy_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, + AXIS2_HTTP_PROXY); + } + if(proxy_param) + { + transport_attrs = axutil_param_get_attributes(proxy_param, env); + if(transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *username_attr = NULL; + axiom_attribute_t *password_attr = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME, + AXIS2_HASH_KEY_STRING); + if(obj) + { + username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if(username_attr) + { + uname = axiom_attribute_get_value(username_attr, env); + } + obj = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD, + AXIS2_HASH_KEY_STRING); + if(obj) + { + password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if(password_attr) + { + passwd = axiom_attribute_get_value(password_attr, env); + } + } + } + } + } + if(uname && passwd) + { + int elen; + int plen = axutil_strlen(uname) + axutil_strlen(passwd) + 1; + axis2_char_t *to_encode = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, + sizeof(axis2_char_t) * plen + 1)); + axis2_char_t *encoded = NULL; + axis2_char_t *auth_str = NULL; + sprintf(to_encode, "%s:%s", uname, passwd); + elen = axutil_base64_encode_len(plen); + encoded = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * elen)); + auth_str + = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 6))); + axutil_base64_encode(encoded, to_encode, plen); + sprintf(auth_str, "%s %s", AXIS2_PROXY_AUTH_TYPE_BASIC, encoded); + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_PROXY_AUTHORIZATION, + auth_str); + + AXIS2_FREE(env->allocator, to_encode); + to_encode = NULL; + AXIS2_FREE(env->allocator, encoded); + encoded = NULL; + AXIS2_FREE(env->allocator, auth_str); + auth_str = NULL; + + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} +#endif + +#ifndef AXIS2_LIBCURL_ENABLED +static axis2_status_t +axis2_http_sender_configure_http_digest_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request, + axis2_char_t * header_data) +{ + axutil_property_t *http_auth_un = NULL; + axutil_property_t *http_auth_pw = NULL; + axis2_char_t *uname = NULL; + axis2_char_t *passwd = NULL; + + if(!header_data || !*header_data) + return AXIS2_FAILURE; + + http_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME); + http_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD); + if(http_auth_un && http_auth_pw) + { + uname = (axis2_char_t *)axutil_property_get_value(http_auth_un, env); + passwd = (axis2_char_t *)axutil_property_get_value(http_auth_pw, env); + } + if(!uname || !passwd) + { + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *http_auth_param = NULL; + axutil_hash_t *transport_attrs = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + } + } + if(trans_desc) + { + http_auth_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, + AXIS2_HTTP_AUTHENTICATION); + if(http_auth_param) + { + transport_attrs = axutil_param_get_attributes(http_auth_param, env); + if(transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *username_attr = NULL; + axiom_attribute_t *password_attr = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_USERNAME, + AXIS2_HASH_KEY_STRING); + if(obj) + { + username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if(username_attr) + { + uname = axiom_attribute_get_value(username_attr, env); + } + obj = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_PASSWORD, + AXIS2_HASH_KEY_STRING); + if(obj) + { + password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if(password_attr) + { + passwd = axiom_attribute_get_value(password_attr, env); + } + } + } + } + } + if(uname && passwd) + { + int elen = 0; /* length of header content */ + int print_const = 5; /* constant accounts for printing the + quoatation marks, comma, and space */ + int response_length = 32; + axis2_char_t *temp = NULL; + axis2_char_t *alloc_temp = NULL; + axis2_char_t *algo = AXIS2_HTTP_AUTHORIZATION_REQUEST_ALGORITHM_MD5; + axis2_char_t *realm = NULL; + axis2_char_t *qop = NULL; + axis2_char_t *nonce = NULL; + axis2_char_t *opaque = NULL; + axis2_char_t *cnonce = NULL; + axis2_char_t *nc = NULL; + axutil_digest_hash_hex_t h_a1; + axutil_digest_hash_hex_t h_a2; + axutil_digest_hash_hex_t response; + axis2_char_t *auth_str = NULL; + axutil_property_t *method = NULL; + axis2_char_t *method_value = NULL; + axis2_char_t *url = NULL; + + url = axis2_http_request_line_get_uri(axis2_http_simple_request_get_request_line(request, + env), env); + + if(!url) + { + return AXIS2_FAILURE; + } + + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI) + + axutil_strlen(url); + + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME) + + axutil_strlen(uname); + + method = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_METHOD); + if(method) + { + method_value = (axis2_char_t *)axutil_property_get_value(method, env); + } + else + { + method_value = AXIS2_HTTP_POST; + } + + temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM); + if(temp) + { + realm = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE); + if(realm) + { + realm++; + temp = axutil_strchr(realm, AXIS2_ESC_DOUBLE_QUOTE); + alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (temp - realm + 1))); + strncpy(alloc_temp, realm, (temp - realm)); + if(alloc_temp) + alloc_temp[temp - realm] = AXIS2_ESC_NULL; + realm = alloc_temp; + alloc_temp = NULL; + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM) + + axutil_strlen(realm); + } + else + { + return AXIS2_FAILURE; + } + } + + temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP); + if(temp) + { + qop = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE); + if(qop) + { + qop++; + temp = axutil_strchr(qop, AXIS2_ESC_DOUBLE_QUOTE); + alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (temp - qop + 1))); + strncpy(alloc_temp, qop, (temp - qop)); + if(alloc_temp) + alloc_temp[temp - qop] = AXIS2_ESC_NULL; + qop = alloc_temp; + alloc_temp = NULL; + } + } + + temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE); + if(temp) + { + nonce = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE); + if(nonce) + { + nonce++; + temp = axutil_strchr(nonce, AXIS2_ESC_DOUBLE_QUOTE); + alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (temp - nonce + 1))); + strncpy(alloc_temp, nonce, (temp - nonce)); + if(alloc_temp) + alloc_temp[temp - nonce] = AXIS2_ESC_NULL; + nonce = alloc_temp; + alloc_temp = NULL; + + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE) + + axutil_strlen(nonce); + } + else + { + if(realm) + AXIS2_FREE(env->allocator, realm); + return AXIS2_FAILURE; + } + } + + temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE); + if(temp) + { + opaque = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE); + if(opaque) + { + opaque++; + temp = axutil_strchr(opaque, AXIS2_ESC_DOUBLE_QUOTE); + alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (temp - opaque + 1))); + strncpy(alloc_temp, opaque, (temp - opaque)); + if(alloc_temp) + alloc_temp[temp - opaque] = AXIS2_ESC_NULL; + opaque = alloc_temp; + alloc_temp = NULL; + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE) + + axutil_strlen(opaque); + } + else + { + if(realm) + AXIS2_FREE(env->allocator, realm); + if(nonce) + AXIS2_FREE(env->allocator, nonce); + return AXIS2_FAILURE; + } + } + + if(qop) + { + nc = AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE; + temp = qop; + if(!axutil_strstr(temp, AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH)) + { + return AXIS2_FAILURE; + } + AXIS2_FREE(env->allocator, qop); + qop = AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH; + temp = axutil_uuid_gen(env); + cnonce = temp; + temp += CLIENT_NONCE_LENGTH; + if(temp) + *temp = AXIS2_ESC_NULL; + elen += 11 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE) + + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT) + + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE) + + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + CLIENT_NONCE_LENGTH + + axutil_strlen(qop); + } + + axutil_digest_calc_get_h_a1(env, algo, uname, realm, passwd, cnonce, nonce, h_a1); + axutil_digest_calc_get_response(env, h_a1, nonce, nc, cnonce, qop, method_value, url, h_a2, + response); + + elen += 4 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE) + axutil_strlen( + AXIS2_HTTP_AUTH_TYPE_DIGEST) + response_length; + + auth_str + = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 1))); + temp = auth_str; + sprintf(temp, "%s %s=\"%s\", ", AXIS2_HTTP_AUTH_TYPE_DIGEST, + AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME, uname); + temp += ((int)strlen(AXIS2_HTTP_AUTH_TYPE_DIGEST) + (int)strlen( + AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME) + (int)strlen(uname) + 6); + if(realm) + { + sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM, realm); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM) + (int)strlen(realm) + + 5); + } + if(nonce) + { + sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE, nonce); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE) + (int)strlen(nonce) + + 5); + } + sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI, url); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI) + (int)strlen(url) + 5); + if(qop) + { + sprintf(temp, "%s=%s, %s=%s, %s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP, + qop, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT, nc, + AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE, cnonce); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + (int)strlen(qop) + + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT) + (int)strlen(nc) + + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE) + (int)strlen( + cnonce) + 11); + } + if(opaque) + { + sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE, opaque); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE) + (int)strlen( + opaque) + 5); + } + sprintf(temp, "%s=\"%s\"", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE, response); + + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_AUTHORIZATION, auth_str); + if(realm) + AXIS2_FREE(env->allocator, realm); + if(nonce) + AXIS2_FREE(env->allocator, nonce); + if(cnonce) + AXIS2_FREE(env->allocator, cnonce); + if(opaque) + AXIS2_FREE(env->allocator, opaque); + if(auth_str) + AXIS2_FREE(env->allocator, auth_str); + auth_str = NULL; + + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +static axis2_status_t +axis2_http_sender_configure_proxy_digest_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request, + axis2_char_t * header_data) +{ + axutil_property_t *proxy_auth_un = NULL; + axutil_property_t *proxy_auth_pw = NULL; + axis2_char_t *uname = NULL; + axis2_char_t *passwd = NULL; + + if(!header_data || !*header_data) + return AXIS2_FAILURE; + + proxy_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME); + proxy_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD); + + if(proxy_auth_un && proxy_auth_pw) + { + uname = (axis2_char_t *)axutil_property_get_value(proxy_auth_un, env); + passwd = (axis2_char_t *)axutil_property_get_value(proxy_auth_pw, env); + } + if(!uname || !passwd) + { + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *proxy_param = NULL; + axutil_hash_t *transport_attrs = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + } + } + if(trans_desc) + { + proxy_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, + AXIS2_HTTP_PROXY_API); + if(!proxy_param) + { + proxy_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, + AXIS2_HTTP_PROXY); + } + if(proxy_param) + { + transport_attrs = axutil_param_get_attributes(proxy_param, env); + + if(transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *username_attr = NULL; + axiom_attribute_t *password_attr = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME, + AXIS2_HASH_KEY_STRING); + if(obj) + { + username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if(username_attr) + { + uname = axiom_attribute_get_value(username_attr, env); + } + + obj = NULL; + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD, + AXIS2_HASH_KEY_STRING); + if(obj) + { + password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if(password_attr) + { + passwd = axiom_attribute_get_value(password_attr, env); + } + } + } + } + } + if(uname && passwd) + { + int elen = 0; /* length of header content */ + int print_const = 5; /* constant accounts for printing the + quoatation marks, comma, and space */ + int response_length = 32; + axis2_char_t *temp = NULL; + axis2_char_t *alloc_temp = NULL; + axis2_char_t *algo = AXIS2_HTTP_AUTHORIZATION_REQUEST_ALGORITHM_MD5; + axis2_char_t *realm = NULL; + axis2_char_t *qop = NULL; + axis2_char_t *nonce = NULL; + axis2_char_t *opaque = NULL; + axis2_char_t *cnonce = NULL; + axis2_char_t *nc = NULL; + axutil_digest_hash_hex_t h_a1; + axutil_digest_hash_hex_t h_a2; + axutil_digest_hash_hex_t response; + axis2_char_t *auth_str = NULL; + axutil_property_t *method = NULL; + axis2_char_t *method_value = NULL; + axis2_char_t *url = NULL; + + url = axis2_http_request_line_get_uri(axis2_http_simple_request_get_request_line(request, + env), env); + + if(!url) + { + return AXIS2_FAILURE; + } + + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI) + + axutil_strlen(url); + + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME) + + axutil_strlen(uname); + + method = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_METHOD); + if(method) + { + method_value = (axis2_char_t *)axutil_property_get_value(method, env); + } + else + { + method_value = AXIS2_HTTP_POST; + } + + temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM); + if(temp) + { + realm = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE); + if(realm) + { + realm++; + temp = axutil_strchr(realm, AXIS2_ESC_DOUBLE_QUOTE); + alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (temp - realm + 1))); + strncpy(alloc_temp, realm, (temp - realm)); + if(alloc_temp) + alloc_temp[temp - realm] = AXIS2_ESC_NULL; + realm = alloc_temp; + alloc_temp = NULL; + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM) + + axutil_strlen(realm); + } + else + { + return AXIS2_FAILURE; + } + } + + temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP); + if(temp) + { + qop = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE); + if(qop) + { + qop++; + temp = axutil_strchr(qop, AXIS2_ESC_DOUBLE_QUOTE); + alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (temp - qop + 1))); + strncpy(alloc_temp, qop, (temp - qop)); + if(alloc_temp) + alloc_temp[temp - qop] = AXIS2_ESC_NULL; + qop = alloc_temp; + alloc_temp = NULL; + } + } + + temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE); + if(temp) + { + nonce = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE); + if(nonce) + { + nonce++; + temp = axutil_strchr(nonce, AXIS2_ESC_DOUBLE_QUOTE); + alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (temp - nonce + 1))); + strncpy(alloc_temp, nonce, (temp - nonce)); + if(alloc_temp) + alloc_temp[temp - nonce] = AXIS2_ESC_NULL; + nonce = alloc_temp; + alloc_temp = NULL; + + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE) + + axutil_strlen(nonce); + } + else + { + if(realm) + AXIS2_FREE(env->allocator, realm); + return AXIS2_FAILURE; + } + } + + temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE); + if(temp) + { + opaque = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE); + if(opaque) + { + opaque++; + temp = axutil_strchr(opaque, AXIS2_ESC_DOUBLE_QUOTE); + alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (temp - opaque + 1))); + strncpy(alloc_temp, opaque, (temp - opaque)); + if(alloc_temp) + alloc_temp[temp - opaque] = AXIS2_ESC_NULL; + opaque = alloc_temp; + alloc_temp = NULL; + elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE) + + axutil_strlen(opaque); + } + else + { + if(realm) + AXIS2_FREE(env->allocator, realm); + if(nonce) + AXIS2_FREE(env->allocator, nonce); + return AXIS2_FAILURE; + } + } + + if(qop) + { + nc = AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE; + temp = qop; + if(!axutil_strstr(temp, AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH)) + { + return AXIS2_FAILURE; + } + AXIS2_FREE(env->allocator, qop); + qop = AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH; + temp = axutil_uuid_gen(env); + cnonce = temp; + temp += CLIENT_NONCE_LENGTH; + if(temp) + *temp = AXIS2_ESC_NULL; + elen += 11 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE) + + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT) + + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE) + + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + CLIENT_NONCE_LENGTH + + axutil_strlen(qop); + } + + axutil_digest_calc_get_h_a1(env, algo, uname, realm, passwd, cnonce, nonce, h_a1); + axutil_digest_calc_get_response(env, h_a1, nonce, nc, cnonce, qop, method_value, url, h_a2, + response); + + elen += 4 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE) + axutil_strlen( + AXIS2_PROXY_AUTH_TYPE_DIGEST) + response_length; + + auth_str + = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 1))); + temp = auth_str; + sprintf(temp, "%s %s=\"%s\", ", AXIS2_PROXY_AUTH_TYPE_DIGEST, + AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME, uname); + temp += ((int)strlen(AXIS2_HTTP_AUTH_TYPE_DIGEST) + (int)strlen( + AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME) + (int)strlen(uname) + 6); + if(realm) + { + sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM, realm); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM) + (int)strlen(realm) + + 5); + } + if(nonce) + { + sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE, nonce); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE) + (int)strlen(nonce) + + 5); + } + sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI, url); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI) + (int)strlen(url) + 5); + if(qop) + { + sprintf(temp, "%s=%s, %s=%s, %s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP, + qop, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT, nc, + AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE, cnonce); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + (int)strlen(qop) + + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT) + (int)strlen(nc) + + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE) + (int)strlen( + cnonce) + 11); + } + if(opaque) + { + sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE, opaque); + temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE) + (int)strlen( + opaque) + 5); + } + sprintf(temp, "%s=\"%s\"", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE, response); + axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_PROXY_AUTHORIZATION, + auth_str); + if(realm) + { + AXIS2_FREE(env->allocator, realm); + } + + if(nonce) + { + AXIS2_FREE(env->allocator, nonce); + } + + if(cnonce) + { + AXIS2_FREE(env->allocator, cnonce); + } + + if(opaque) + { + AXIS2_FREE(env->allocator, opaque); + } + + if(auth_str) + { + AXIS2_FREE(env->allocator, auth_str); + } + + auth_str = NULL; + + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} +#endif + +#ifndef AXIS2_LIBCURL_ENABLED +static axis2_status_t +axis2_http_sender_configure_http_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request) +{ + axis2_char_t *auth_type = NULL; + axis2_status_t status = AXIS2_FALSE; + axutil_property_t *http_auth_property = NULL; + axis2_char_t *http_auth_property_value = NULL; + axis2_bool_t force_http_auth = AXIS2_FALSE; + axutil_property_t *http_auth_type_property = NULL; + axis2_char_t *http_auth_type_property_value = NULL; + axis2_char_t *auth_type_end = NULL; + + http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_FORCE_HTTP_AUTH); + if(http_auth_property) + { + http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property, + env); + } + + if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value, AXIS2_VALUE_TRUE)) + { + force_http_auth = AXIS2_TRUE; + } + + if(force_http_auth) + { + http_auth_type_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_HTTP_AUTH_TYPE); + if(http_auth_type_property) + { + http_auth_type_property_value = (axis2_char_t *)axutil_property_get_value( + http_auth_type_property, env); + } + + if(http_auth_type_property_value) + { + auth_type = http_auth_type_property_value; + } + } + if(!force_http_auth || axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0) + { + axis2_http_header_t *auth_header = NULL; + axis2_http_simple_response_t *response = NULL; + + response = axis2_http_client_get_response(sender->client, env); + + if(response) + { + auth_header = axis2_http_simple_response_get_first_header(response, env, + AXIS2_HTTP_HEADER_WWW_AUTHENTICATE); + } + + if(auth_header) + { + auth_type = axis2_http_header_get_value(auth_header, env); + } + + if(auth_type) + { + auth_type_end = axutil_strchr(auth_type, ' '); + *auth_type_end = AXIS2_ESC_NULL; + auth_type_end++; + /*Read the realm and the rest stuff now from auth_type_end */ + } + if(force_http_auth && axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) != 0) + { + auth_type = NULL; + } + } + if(auth_type) + { + if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0) + { + status = axis2_http_sender_configure_http_basic_auth(sender, env, msg_ctx, request); + } + else if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0) + { + status = axis2_http_sender_configure_http_digest_auth(sender, env, msg_ctx, request, + auth_type_end); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not" + "supported", auth_type); + } + } + else + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE); + } + + return status; +} + +static axis2_status_t +axis2_http_sender_configure_proxy_auth( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request) +{ + axis2_char_t *auth_type = NULL; + axis2_status_t status = AXIS2_FALSE; + axutil_property_t *proxy_auth_property = NULL; + axis2_char_t *proxy_auth_property_value = NULL; + axis2_bool_t force_proxy_auth = AXIS2_FALSE; + axutil_property_t *proxy_auth_type_property = NULL; + axis2_char_t *proxy_auth_type_property_value = NULL; + axis2_char_t *auth_type_end = NULL; + + proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_FORCE_PROXY_AUTH); + if(proxy_auth_property) + { + proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property, + env); + } + + if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value, AXIS2_VALUE_TRUE)) + { + force_proxy_auth = AXIS2_TRUE; + } + + if(force_proxy_auth) + { + proxy_auth_type_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_PROXY_AUTH_TYPE); + if(proxy_auth_type_property) + { + proxy_auth_type_property_value = (axis2_char_t *)axutil_property_get_value( + proxy_auth_type_property, env); + } + + if(proxy_auth_type_property_value) + { + auth_type = proxy_auth_type_property_value; + } + } + else + { + axis2_http_header_t *auth_header = NULL; + axis2_http_simple_response_t *response = NULL; + + response = axis2_http_client_get_response(sender->client, env); + + if(response) + { + auth_header = axis2_http_simple_response_get_first_header(response, env, + AXIS2_HTTP_HEADER_PROXY_AUTHENTICATE); + } + + if(auth_header) + { + auth_type = axis2_http_header_get_value(auth_header, env); + } + + if(auth_type) + { + auth_type_end = axutil_strchr(auth_type, ' '); + *auth_type_end = AXIS2_ESC_NULL; + auth_type_end++; + /*Read the realm and the rest stuff now from auth_type_end */ + } + } + if(auth_type) + { + if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0) + { + status = axis2_http_sender_configure_proxy_basic_auth(sender, env, msg_ctx, request); + } + else if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0) + { + status = axis2_http_sender_configure_proxy_digest_auth(sender, env, msg_ctx, request, + auth_type_end); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type); + } + } + else + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE); + } + + return status; +} +#endif + +#ifndef AXIS2_LIBCURL_ENABLED +static axis2_status_t +axis2_http_sender_set_http_auth_type( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request) +{ + axis2_char_t *auth_type = NULL; + axis2_status_t status = AXIS2_FALSE; + axis2_char_t *auth_type_end = NULL; + axis2_http_header_t *auth_header = NULL; + axis2_http_simple_response_t *response = NULL; + + response = axis2_http_client_get_response(sender->client, env); + + if(response) + { + auth_header = axis2_http_simple_response_get_first_header(response, env, + AXIS2_HTTP_HEADER_WWW_AUTHENTICATE); + } + + if(auth_header) + { + auth_type = axis2_http_header_get_value(auth_header, env); + } + + if(auth_type) + { + auth_type_end = axutil_strchr(auth_type, ' '); + *auth_type_end = AXIS2_ESC_NULL; + auth_type_end++; + /*Read the realm and the rest stuff now from auth_type_end */ + } + + if(auth_type) + { + if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0) + { + status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE_BASIC); + } + else if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0) + { + status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE_DIGEST); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type); + } + } + else + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE); + } + return status; +} + +static axis2_status_t +axis2_http_sender_set_proxy_auth_type( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_http_simple_request_t * request) +{ + axis2_char_t *auth_type = NULL; + axis2_status_t status = AXIS2_FALSE; + axis2_char_t *auth_type_end = NULL; + axis2_http_header_t *auth_header = NULL; + axis2_http_simple_response_t *response = NULL; + + response = axis2_http_client_get_response(sender->client, env); + + if(response) + { + auth_header = axis2_http_simple_response_get_first_header(response, env, + AXIS2_HTTP_HEADER_PROXY_AUTHENTICATE); + } + + if(auth_header) + { + auth_type = axis2_http_header_get_value(auth_header, env); + } + + if(auth_type) + { + auth_type_end = axutil_strchr(auth_type, ' '); + *auth_type_end = AXIS2_ESC_NULL; + auth_type_end++; + /*Read the realm and the rest stuff now from auth_type_end */ + } + + if(auth_type) + { + if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0) + { + status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_PROXY_AUTH_TYPE_BASIC); + } + else if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0) + { + status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_PROXY_AUTH_TYPE_DIGEST); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type); + } + } + else + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE); + } + return status; +} +#endif + +#ifdef AXIS2_LIBCURL_ENABLED +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_libcurl_http_send (axis2_libcurl_t * curl, + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axiom_soap_envelope_t * out, + const axis2_char_t * str_url, + const axis2_char_t * soap_action) +{ + return axis2_libcurl_send (curl, sender->om_output, + env, msg_ctx, out, str_url, soap_action); +} +#endif + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_sender_get_param_string( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axiom_soap_envelope_t *soap_env = NULL; + axiom_soap_body_t *soap_body = NULL; + axiom_node_t *body_node = NULL; + axiom_node_t *data_node = NULL; + axiom_element_t *data_element = NULL; + axiom_child_element_iterator_t *iterator = NULL; + axutil_array_list_t *param_list = NULL; + axis2_char_t *param_string = NULL; + int i = 0; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + + soap_env = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + if(!soap_env) + { + return NULL; + } + soap_body = axiom_soap_envelope_get_body(soap_env, env); + body_node = axiom_soap_body_get_base_node(soap_body, env); + if(!body_node) + { + /* This could be the situation where service client does not provide + * a xml payload and instead add url parameters to the endpoint url + */ + return NULL; + } + data_node = axiom_node_get_first_child(body_node, env); + if(!data_node) + { + return NULL; + } + + param_list = axutil_array_list_create(env, AXIS2_ARRAY_LIST_DEFAULT_CAPACITY); + + data_element = axiom_node_get_data_element(data_node, env); + + iterator = axiom_element_get_child_elements(data_element, env, data_node); + + if(iterator) + { + while(AXIS2_TRUE == AXIOM_CHILD_ELEMENT_ITERATOR_HAS_NEXT(iterator, env)) + { + axiom_node_t *node = NULL; + axiom_element_t *element = NULL; + axis2_char_t *name = NULL; + axis2_char_t *value = NULL; + axis2_char_t *encoded_value = NULL; + + node = AXIOM_CHILD_ELEMENT_ITERATOR_NEXT(iterator, env); + element = axiom_node_get_data_element(node, env); + name = axiom_element_get_localname(element, env); + value = axiom_element_get_text(element, env, node); + if(value) + { + encoded_value = (axis2_char_t *)AXIS2_MALLOC(env->allocator, strlen(value)); + memset(encoded_value, 0, strlen(value)); + encoded_value = axutil_url_encode(env, encoded_value, value, (int)strlen(value)); + /* We are sure that the difference lies within the int range */ + + axutil_array_list_add(param_list, env, axutil_strcat(env, name, "=", encoded_value, + NULL)); + AXIS2_FREE(env->allocator, encoded_value); + encoded_value = NULL; + } + } + } + for(i = 0; i < axutil_array_list_size(param_list, env); i++) + { + axis2_char_t *tmp_string = NULL; + axis2_char_t *pair = NULL; + + pair = axutil_array_list_get(param_list, env, i); + if(i == 0) + { + tmp_string = axutil_stracat(env, param_string, pair); + } + else + { + tmp_string = axutil_strcat(env, param_string, AXIS2_AND_SIGN, pair, NULL); + } + + if(param_string) + { + AXIS2_FREE(env->allocator, param_string); + param_string = NULL; + } + AXIS2_FREE(env->allocator, pair); + param_string = tmp_string; + } + axutil_array_list_free(param_list, env); + return param_string; +} + +void AXIS2_CALL +axis2_http_sender_util_add_header( + const axutil_env_t * env, + axis2_http_simple_request_t * request, + axis2_char_t * header_name, + const axis2_char_t * header_value) +{ + axis2_http_header_t *http_header; + http_header = axis2_http_header_create(env, header_name, header_value); + axis2_http_simple_request_add_header(request, env, http_header); +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_sender_set_keep_alive( + axis2_http_sender_t * sender, + const axutil_env_t * env, + axis2_bool_t keep_alive) +{ + sender->keep_alive = keep_alive; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_sender_get_keep_alive( + axis2_http_sender_t * sender, + const axutil_env_t * env) +{ + return sender->keep_alive; +} + +static axutil_hash_t * +axis2_http_sender_connection_map_create( + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx) +{ + axutil_hash_t *connection_map = NULL; + connection_map = axutil_hash_make(env); + if(!connection_map) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + } + else + { + axis2_conf_ctx_t *conf_ctx = NULL; + axutil_property_t *connection_map_property = NULL; + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + connection_map_property = axutil_property_create_with_args(env, AXIS2_SCOPE_SESSION, + AXIS2_TRUE, axis2_http_sender_connection_map_free, connection_map); + axis2_conf_ctx_set_property(conf_ctx, env, AXIS2_HTTP_CONNECTION_MAP, + connection_map_property); + } + return connection_map; +} + +static void +axis2_http_sender_connection_map_remove( + axutil_hash_t *connection_map, + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx, + axis2_http_client_t *http_client) +{ + axutil_property_t *property = NULL; + axis2_endpoint_ref_t *endpoint = NULL; + /** + * Put the http client into message context with own value true so that it will be freed + * after response processed + */ + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE, + axis2_http_client_free_void_arg, http_client); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_CLIENT, property); + endpoint = axis2_msg_ctx_get_to(msg_ctx, env); + if(endpoint) + { + const axis2_char_t *address = NULL; + address = axis2_endpoint_ref_get_address(endpoint, env); + if(address) + { + axutil_url_t *url = NULL; + url = axutil_url_parse_string(env, address); + if(url) + { + axis2_char_t *server = axutil_url_get_server(url, env); + if(server) + { + axutil_hash_set(connection_map, server, AXIS2_HASH_KEY_STRING, NULL); + } + axutil_url_free(url, env); + } + } + } +} + +static void +axis2_http_sender_connection_map_add( + axutil_hash_t *connection_map, + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx, + axis2_http_client_t *http_client) +{ + axutil_property_t *property = NULL; + axis2_endpoint_ref_t *endpoint = NULL; + /** + * Put the http client into message context. Is this neccessary? + */ + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE, + axis2_http_client_free_void_arg, http_client); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_CLIENT, property); + endpoint = axis2_msg_ctx_get_to(msg_ctx, env); + if(endpoint) + { + const axis2_char_t *address = NULL; + address = axis2_endpoint_ref_get_address(endpoint, env); + if(address) + { + axutil_url_t *url = NULL; + url = axutil_url_parse_string(env, address); + if(url) + { + axis2_char_t *server = axutil_url_get_server(url, env); + if(server) + { + axutil_hash_set(connection_map, axutil_strdup(env, server), + AXIS2_HASH_KEY_STRING, http_client); + } + axutil_url_free(url, env); + } + } + } +} + +static axis2_http_client_t * +axis2_http_sender_connection_map_get( + axutil_hash_t *connection_map, + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx) +{ + axis2_http_client_t *http_client = NULL; + axis2_endpoint_ref_t *endpoint = NULL; + endpoint = axis2_msg_ctx_get_to(msg_ctx, env); + if(endpoint) + { + const axis2_char_t *address = NULL; + address = axis2_endpoint_ref_get_address(endpoint, env); + if(address) + { + axutil_url_t *url = NULL; + url = axutil_url_parse_string(env, address); + if(url) + { + axis2_char_t *server = axutil_url_get_server(url, env); + if(server) + { + http_client = axutil_hash_get(connection_map, server, AXIS2_HASH_KEY_STRING); + } + axutil_url_free(url, env); + } + } + } + return http_client; +} + +static void AXIS2_CALL +axis2_http_sender_connection_map_free( + void *cm_void, + const axutil_env_t *env) +{ + void *val = NULL; + const void *key = NULL; + axutil_hash_index_t *hi = NULL; + axutil_hash_t *ht = (axutil_hash_t *)cm_void; + + for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_char_t *name = NULL; + axis2_http_client_t *value = NULL; + + axutil_hash_this(hi, &key, NULL, &val); + name = (axis2_char_t *) key; + if(name) + { + AXIS2_FREE(env->allocator, name); + } + value = (axis2_http_client_t *) val; + if(value) + { + axis2_http_client_free(value, env); + } + } + axutil_hash_free(ht, env); +} + diff --git a/src/core/transport/http/sender/http_transport_sender.c b/src/core/transport/http/sender/http_transport_sender.c new file mode 100644 index 0000000..3ef55b0 --- /dev/null +++ b/src/core/transport/http/sender/http_transport_sender.c @@ -0,0 +1,859 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_transport_sender.h> +#include <axutil_string.h> +#include <axis2_endpoint_ref.h> +#include <axis2_addr.h> +#include <axiom_xml_writer.h> +#include <axiom_output.h> +#include <axis2_http_transport_utils.h> +#include <axutil_generic_obj.h> +#include <axis2_http_out_transport_info.h> +#include <axis2_http_transport.h> +#include <axis2_http_sender.h> +#include <axiom_soap_body.h> +#include <axutil_types.h> +#include <axiom_soap_fault_detail.h> +#include <axis2_msg_ctx.h> + +#ifdef AXIS2_LIBCURL_ENABLED +#include "libcurl/axis2_libcurl.h" +#endif + +/** + * HTTP Transport Sender struct impl + * Axis2 HTTP Transport Sender impl + */ + +typedef struct axis2_http_transport_sender_impl +{ + axis2_transport_sender_t transport_sender; + axis2_char_t *http_version; + axis2_bool_t chunked; + int connection_timeout; + int so_timeout; + axis2_bool_t keep_alive; +#ifdef AXIS2_LIBCURL_ENABLED + axis2_libcurl_t *libcurl; +#endif +} axis2_http_transport_sender_impl_t; + +#define AXIS2_WS_RM_ANONYMOUS_URL "http://docs.oasis-open.org/ws-rx/wsmc/200702/anonymous?id=" +#define AXIS2_INTF_TO_IMPL(transport_sender) \ + ((axis2_http_transport_sender_impl_t *)\ + (transport_sender)) + +/***************************** Function headers *******************************/ +axis2_status_t AXIS2_CALL +axis2_http_transport_sender_invoke( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +axis2_status_t AXIS2_CALL +axis2_http_transport_sender_clean_up( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +axis2_status_t AXIS2_CALL +axis2_http_transport_sender_init( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_transport_out_desc_t * out_desc); + +axis2_status_t AXIS2_CALL +axis2_http_transport_sender_write_message( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_endpoint_ref_t * epr, + axiom_soap_envelope_t * out, + axiom_output_t * om_output); + +void AXIS2_CALL axis2_http_transport_sender_free( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env); + +static const axis2_transport_sender_ops_t http_transport_sender_ops_var = { + axis2_http_transport_sender_init, axis2_http_transport_sender_invoke, + axis2_http_transport_sender_clean_up, axis2_http_transport_sender_free }; + +axis2_transport_sender_t *AXIS2_CALL +axis2_http_transport_sender_create( + const axutil_env_t * env) +{ + axis2_http_transport_sender_impl_t *transport_sender_impl = NULL; + + transport_sender_impl = (axis2_http_transport_sender_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_transport_sender_impl_t)); + + if(!transport_sender_impl) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)transport_sender_impl, 0, sizeof(axis2_http_transport_sender_impl_t)); + + transport_sender_impl->http_version = axutil_strdup(env, AXIS2_HTTP_HEADER_PROTOCOL_11); + transport_sender_impl->chunked = AXIS2_TRUE; + transport_sender_impl->connection_timeout = AXIS2_HTTP_DEFAULT_CONNECTION_TIMEOUT; + transport_sender_impl->so_timeout = AXIS2_HTTP_DEFAULT_SO_TIMEOUT; + transport_sender_impl->keep_alive = AXIS2_TRUE; + transport_sender_impl->transport_sender.ops = &http_transport_sender_ops_var; + +#ifdef AXIS2_LIBCURL_ENABLED + transport_sender_impl->libcurl = axis2_libcurl_create(env); + if (!transport_sender_impl->libcurl) + { + AXIS2_FREE(env->allocator, transport_sender_impl); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } +#endif + + return &(transport_sender_impl->transport_sender); +} + +void AXIS2_CALL +axis2_http_transport_sender_free( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env) +{ + + axis2_http_transport_sender_impl_t *transport_sender_impl = NULL; + if(!transport_sender) + { + return; + } + + transport_sender_impl = AXIS2_INTF_TO_IMPL(transport_sender); + + if(transport_sender_impl->http_version) + { + AXIS2_FREE(env->allocator, transport_sender_impl->http_version); + transport_sender_impl->http_version = NULL; + } + +#ifdef AXIS2_LIBCURL_ENABLED + if (transport_sender_impl->libcurl) + { + axis2_libcurl_free(transport_sender_impl->libcurl, env); + } +#endif + + AXIS2_FREE(env->allocator, transport_sender_impl); + return; +} + +axis2_status_t AXIS2_CALL +axis2_http_transport_sender_invoke( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + const axis2_char_t *char_set_enc = NULL; + axutil_string_t *char_set_enc_str = NULL; + axis2_endpoint_ref_t *epr = NULL; + axis2_char_t *transport_url = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axiom_output_t *om_output = NULL; + axis2_char_t *buffer = NULL; + axiom_soap_envelope_t *soap_data_out = NULL; + axis2_bool_t do_mtom; + axutil_property_t *property = NULL; + axiom_node_t *data_out = NULL; + int buffer_size = 0; + axis2_status_t status = AXIS2_SUCCESS; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *write_xml_declaration_param = NULL; + axutil_hash_t *transport_attrs = NULL; + axis2_bool_t write_xml_declaration = AXIS2_FALSE; + axis2_bool_t fault = AXIS2_FALSE; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_sender_invoke"); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env); + if(char_set_enc_str) + { + char_set_enc = axutil_string_get_buffer(char_set_enc_str, env); + } + + if(!char_set_enc) + { + axis2_op_ctx_t *op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + axis2_ctx_t *ctx = axis2_op_ctx_get_base(op_ctx, env); + if(ctx) + { + property = axis2_ctx_get_property(ctx, env, AXIS2_CHARACTER_SET_ENCODING); + if(property) + { + char_set_enc = axutil_property_get_value(property, env); + property = NULL; + } + } + } + } + + /** + * If we still can't find the char set enc we will + * use default + */ + if(!char_set_enc) + { + char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING; + } + + do_mtom = axis2_http_transport_utils_do_write_mtom(env, msg_ctx); + + transport_url = axis2_msg_ctx_get_transport_url(msg_ctx, env); + if(transport_url) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "transport_url:%s", transport_url); + epr = axis2_endpoint_ref_create(env, transport_url); + } + else + { + /* when transport url is not available in msg_ctx */ + axis2_endpoint_ref_t *ctx_epr = axis2_msg_ctx_get_to(msg_ctx, env); + if(ctx_epr) + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "ctx_epr:%s", axis2_endpoint_ref_get_address( + ctx_epr, env)); + + if(ctx_epr && axutil_strcmp(AXIS2_WSA_ANONYMOUS_URL_SUBMISSION, + axis2_endpoint_ref_get_address(ctx_epr, env)) && axutil_strcmp(AXIS2_WSA_ANONYMOUS_URL, + axis2_endpoint_ref_get_address(ctx_epr, env)) && !(axutil_strstr( + axis2_endpoint_ref_get_address(ctx_epr, env), AXIS2_WS_RM_ANONYMOUS_URL))) + { + epr = ctx_epr; + } + } + + soap_data_out = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + if(!soap_data_out) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_SOAP_ENVELOPE_IN_MSG_CTX, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", AXIS2_ERROR_GET_MESSAGE(env->error)); + return AXIS2_SUCCESS; + } + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Could not create xml_writer for \ +AXIS2_XML_PARSER_TYPE_BUFFER"); + return AXIS2_FAILURE; + } + + om_output = axiom_output_create(env, xml_writer); + if(!om_output) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Could not create om_output for xml writer of \ +AXIS2_XML_PARSER_TYPE_BUFFER"); + axiom_xml_writer_free(xml_writer, env); + xml_writer = NULL; + return AXIS2_FAILURE; + } + + /* setting SOAP version for OM_OUTPUT. */ + axiom_output_set_soap11(om_output, env, axis2_msg_ctx_get_is_soap_11(msg_ctx, env)); + + /* This is the case where normal client send the requet using a http_client*/ + + if(epr) + { + if(axutil_strcmp(AXIS2_WSA_NONE_URL_SUBMISSION, axis2_endpoint_ref_get_address(epr, env)) + == 0 || axutil_strcmp(AXIS2_WSA_NONE_URL, axis2_endpoint_ref_get_address(epr, env)) + == 0) + { + epr = NULL; + } + else + { + status = axis2_http_transport_sender_write_message(transport_sender, env, msg_ctx, epr, + soap_data_out, om_output); + } + } + + /* If no endpoint reference could be derived from the the message context. It could well be the + * single channel two way scenario in the application server side send. + */ + if(!epr) + { + axutil_stream_t *out_stream = axis2_msg_ctx_get_transport_out_stream(msg_ctx, env); + + if(AXIS2_TRUE == axis2_msg_ctx_get_server_side(msg_ctx, env)) + { + axis2_http_out_transport_info_t *out_info = NULL; + axis2_bool_t is_soap11 = AXIS2_FALSE; + axis2_op_ctx_t *op_ctx = NULL; + /*axis2_char_t *header_value = NULL;*/ + + out_info = (axis2_http_out_transport_info_t *)axis2_msg_ctx_get_out_transport_info( + msg_ctx, env); + + if(!out_info) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_OUT_TRNSPORT_INFO_NULL, AXIS2_FAILURE); + axiom_output_free(om_output, env); + om_output = NULL; + xml_writer = NULL; + return AXIS2_FAILURE; + } + /*header_value = axis2_http_transport_utils_get_session(env, msg_ctx); + if(header_value) + { + AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_COOKIE_HEADER(out_info, env, header_value); + }*/ + + is_soap11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env); + + AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CHAR_ENCODING(out_info, env, char_set_enc); + if(AXIS2_TRUE == is_soap11) + { + /* SOAP1.1 */ + AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML); + } + else + { + /* SOAP1.2 */ + AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env, + AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP); + } + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + } + + if(conf) + { + /* get access to HTTP transport for sending */ + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + } + + if(trans_desc) + { + + /* accessing parameter in axis2.xml which set to have + * an ability to send xml versoin processing + * instruction <?xml version = "1.0"?> */ + write_xml_declaration_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, + AXIS2_XML_DECLARATION); + } + + if(write_xml_declaration_param) + { + transport_attrs = axutil_param_get_attributes(write_xml_declaration_param, env); + if(transport_attrs) + { + /* Accessing attribute values */ + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *write_xml_declaration_attr = NULL; + axis2_char_t *write_xml_declaration_attr_value = NULL; + + obj = axutil_hash_get(transport_attrs, AXIS2_ADD_XML_DECLARATION, + AXIS2_HASH_KEY_STRING); + if(obj) + { + write_xml_declaration_attr + = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + + if(write_xml_declaration_attr) + { + write_xml_declaration_attr_value = axiom_attribute_get_value( + write_xml_declaration_attr, env); + } + + if(write_xml_declaration_attr_value && 0 == axutil_strcasecmp( + write_xml_declaration_attr_value, AXIS2_VALUE_TRUE)) + { + write_xml_declaration = AXIS2_TRUE; + } + } + } + + if(write_xml_declaration) + { + axiom_output_write_xml_version_encoding(om_output, env); + } + + if(AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + { + axiom_node_t *body_node = NULL; + /* axis2_bool_t fault = AXIS2_FALSE;*/ + axiom_soap_fault_t *soap_fault; + axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_data_out, env); + axiom_soap_fault_detail_t *soap_fault_detial; + + if(!soap_body) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL, + AXIS2_FAILURE); + axiom_output_free(om_output, env); + om_output = NULL; + xml_writer = NULL; + return AXIS2_FAILURE; + } + + fault = axiom_soap_body_has_fault(soap_body, env); + + if(fault == AXIS2_TRUE) + { + soap_fault = axiom_soap_body_get_fault(soap_body, env); + + if(!soap_fault) + { + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Rest fault has occur, error described below"); + axiom_output_free(om_output, env); + om_output = NULL; + xml_writer = NULL; + return AXIS2_FAILURE; + } + + soap_fault_detial = axiom_soap_fault_get_detail(soap_fault, env); + + if(!soap_fault_detial) + { + axiom_output_free(om_output, env); + om_output = NULL; + xml_writer = NULL; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Returning failure to obtain soap_fault_detail from soap_fault"); + return AXIS2_FAILURE; + } + + body_node = axiom_soap_fault_detail_get_base_node(soap_fault_detial, env); + if(!body_node) + { + axiom_output_free(om_output, env); + om_output = NULL; + xml_writer = NULL; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "failure to get base node from soap_fault_detail."); + return AXIS2_FAILURE; + } + + } + else + { + + body_node = axiom_soap_body_get_base_node(soap_body, env); + if(!body_node) + { + axiom_output_free(om_output, env); + om_output = NULL; + xml_writer = NULL; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "failure to get base node from soap_body."); + return AXIS2_FAILURE; + } + } + + data_out = axiom_node_get_first_element(body_node, env); + + if(!data_out || axiom_node_get_node_type(data_out, env) != AXIOM_ELEMENT) + { + axiom_output_free(om_output, env); + om_output = NULL; + xml_writer = NULL; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "unable to get first element from soap_body, base node."); + return AXIS2_FAILURE; + } + + axiom_node_serialize(data_out, env, om_output); + buffer = (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env); + buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env); + axutil_stream_write(out_stream, env, buffer, buffer_size); + /* Finish Rest Processing */ + + } + else + { + axiom_soap_body_t *body = NULL; + + body = axiom_soap_envelope_get_body(soap_data_out, env); + fault = axiom_soap_body_has_fault(body, env); + + /* SOAP Processing */ + axiom_output_set_do_optimize(om_output, env, do_mtom); + axiom_soap_envelope_serialize(soap_data_out, env, om_output, AXIS2_FALSE); + if(do_mtom && !fault) + { + axis2_status_t mtom_status = AXIS2_FAILURE; + axis2_char_t *content_type = NULL; + axutil_array_list_t *mime_parts = NULL; + + /*Create the attachment related data and put them to an + *array_list */ + mtom_status = axiom_output_flush(om_output, env); + if(mtom_status == AXIS2_SUCCESS) + { + mime_parts = axiom_output_get_mime_parts(om_output, env); + if(!mime_parts) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Unable to create the mime_part list from om_output"); + return AXIS2_FAILURE; + } + else + { + axis2_msg_ctx_set_mime_parts(msg_ctx, env, mime_parts); + } + } + /*om_out put has the details of content_type */ + content_type = (axis2_char_t *)axiom_output_get_content_type(om_output, env); + AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env, content_type); + } + else + { + buffer = (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env); + buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env); + + /* This is where it actually fill the buffer in out_stream. In application server + * side this is the out_stream passed to the in message context from http_worker + * function and then copied to the out message context. + */ + axutil_stream_write(out_stream, env, buffer, buffer_size); + } + } + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + axis2_op_ctx_set_response_written(op_ctx, env, AXIS2_TRUE); + } + } + + axiom_output_free(om_output, env); + om_output = NULL; + xml_writer = NULL; + + if(transport_url) + { + if(epr) + { + axis2_endpoint_ref_free(epr, env); + epr = NULL; + } + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_sender_invoke"); + return status; +} + +axis2_status_t AXIS2_CALL +axis2_http_transport_sender_clean_up( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE); + /* + * Clean up is not used. If the http sender needs + * to be cleaned up it should be done here. + */ + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_http_transport_sender_init( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_transport_out_desc_t * out_desc) +{ + axutil_param_t *version_param = NULL; + axis2_char_t *version = NULL; + axis2_char_t *temp = NULL; + axutil_param_t *temp_param = NULL; + + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, out_desc, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE); + + /* Getting HTTP version from axis2.xml */ + version_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container( + out_desc, env), env, AXIS2_HTTP_PROTOCOL_VERSION); + + if(version_param) + { + version = axutil_param_get_value(version_param, env); + } + + if(version) + { + /* handling HTTP 1.1 */ + if(0 == axutil_strcmp(version, AXIS2_HTTP_HEADER_PROTOCOL_11)) + { + axis2_char_t *encoding = NULL; + axutil_param_t *encoding_param = NULL; + if(AXIS2_INTF_TO_IMPL(transport_sender)->http_version) + { + AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(transport_sender)->http_version); + } + + AXIS2_INTF_TO_IMPL(transport_sender)->http_version = axutil_strdup(env, version); + AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive = AXIS2_TRUE; + encoding_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(out_desc, env), env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING); + + if(encoding_param) + { + encoding = axutil_param_get_value(encoding_param, env); + } + + if(encoding && 0 + == axutil_strcmp(encoding, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)) + { + AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_TRUE; + } + else + { + AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_FALSE; + } + + } + else if(0 == axutil_strcmp(version, AXIS2_HTTP_HEADER_PROTOCOL_10)) + { + axutil_param_t *keepalive_param = NULL; + + /* Handling HTTP 1.0 */ + if(AXIS2_INTF_TO_IMPL(transport_sender)->http_version) + { + AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(transport_sender)->http_version); + } + AXIS2_INTF_TO_IMPL(transport_sender)->http_version = axutil_strdup(env, version); + AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_FALSE; + keepalive_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(out_desc, env), env, + AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE); + if(keepalive_param) + { + axis2_char_t *keepalive_value = NULL; + keepalive_value = axutil_param_get_value(keepalive_param, env); + if(!axutil_strcmp(keepalive_value, AXIS2_VALUE_FALSE)) + { + AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive = AXIS2_FALSE; + } + } + } + } + else + { + /* HTTP version is not available in axis2.xml */ + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + /* Getting HTTP_SO_TIMEOUT value from axis2.xml */ + temp_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container( + out_desc, env), env, AXIS2_HTTP_SO_TIMEOUT); + + if(temp_param) + { + temp = axutil_param_get_value(temp_param, env); + } + + if(temp) + { + AXIS2_INTF_TO_IMPL(transport_sender)->so_timeout = AXIS2_ATOI(temp); + } + + /* Getting HTTP_CONNECTION_TIMEOUT from axis2.xml */ + temp + = (axis2_char_t *)axutil_param_container_get_param( + axis2_transport_out_desc_param_container(out_desc, env), env, + AXIS2_HTTP_CONNECTION_TIMEOUT); + if(temp_param) + { + temp = axutil_param_get_value(temp_param, env); + } + + /* set axis2.xml connection timeout value to http_sender */ + if(temp) + { + AXIS2_INTF_TO_IMPL(transport_sender)->connection_timeout = AXIS2_ATOI(temp); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_http_transport_sender_write_message( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_endpoint_ref_t * epr, + axiom_soap_envelope_t * out, + axiom_output_t * om_output) +{ + const axis2_char_t *soap_action = NULL; + const axis2_char_t *url = NULL; + axis2_http_sender_t *sender = NULL; + axis2_status_t status = AXIS2_FAILURE; + const axis2_char_t *soap_ns_uri = NULL; + axiom_soap_envelope_t *response_envelope = NULL; + axis2_op_t *op = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, epr, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, out, AXIS2_FAILURE); + + /* epr is already passed NULL checking */ + url = axis2_endpoint_ref_get_address(epr, env); + + soap_action = axutil_string_get_buffer(axis2_msg_ctx_get_soap_action(msg_ctx, env), env); + + if(!soap_action) + { + soap_action = ""; + } + + sender = axis2_http_sender_create(env); + + if(!sender) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "http sender creation failed"); + return AXIS2_FAILURE; + } + axis2_http_sender_set_keep_alive(sender, env, AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive); + + /* For the MTOM case we should on chunking. And for chunking to work the + * protocol should be http 1.1*/ + + if(axis2_msg_ctx_get_doing_mtom(msg_ctx, env)) + { + AXIS2_HTTP_SENDER_SET_CHUNKED(sender, env, AXIS2_TRUE); + AXIS2_HTTP_SENDER_SET_HTTP_VERSION(sender, env, AXIS2_HTTP_HEADER_PROTOCOL_11); + } + else + { + AXIS2_HTTP_SENDER_SET_CHUNKED(sender, env, AXIS2_INTF_TO_IMPL(transport_sender)->chunked); + AXIS2_HTTP_SENDER_SET_HTTP_VERSION(sender, env, + AXIS2_INTF_TO_IMPL(transport_sender)->http_version); + } + AXIS2_HTTP_SENDER_SET_OM_OUTPUT(sender, env, om_output); + +#ifdef AXIS2_LIBCURL_ENABLED + AXIS2_LOG_DEBUG (env->log, AXIS2_LOG_SI, "using axis2 libcurl http sender."); + status = + axis2_libcurl_http_send(AXIS2_INTF_TO_IMPL(transport_sender)->libcurl, + sender, env, msg_ctx, out, url, soap_action); +#else + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "using axis2 native http sender."); + status = AXIS2_HTTP_SENDER_SEND(sender, env, msg_ctx, out, url, soap_action); +#endif + + AXIS2_HTTP_SENDER_FREE(sender, env); + sender = NULL; + + /* if the send was not successful, do not process any response */ + if(status != AXIS2_SUCCESS) + return status; + + op = axis2_msg_ctx_get_op(msg_ctx, env); + if(op) + { + /* handle one way case */ + const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "OP name axutil_qname_get_localpart = %s", mep); + if(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY) == 0 || axutil_strcmp(mep, + AXIS2_MEP_URI_ROBUST_OUT_ONLY) == 0 || axutil_strcmp(mep, AXIS2_MEP_URI_IN_ONLY) == 0) + { + return status; + } + else + { + /* AXIS2_MEP_URI_IN_OUT case , we have a response this + * time */ + soap_ns_uri + = axis2_msg_ctx_get_is_soap_11(msg_ctx, env) ? AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI + : AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + response_envelope = axis2_http_transport_utils_create_soap_msg(env, msg_ctx, + soap_ns_uri); + if(response_envelope) + { + axis2_msg_ctx_set_response_soap_envelope(msg_ctx, env, response_envelope); + } + } + } + + return status; +} + +/** + * Following block distinguish the exposed part of the dll. + */ + +/* When building for static deployment, give the get and remove methods + * unique names. This avoids having the linker fail with duplicate symbol + * errors. + */ + +AXIS2_EXPORT int +#ifndef AXIS2_STATIC_DEPLOY +axis2_get_instance( +#else + axis2_http_transport_sender_get_instance( +#endif + struct axis2_transport_sender **inst, + const axutil_env_t * env) +{ + *inst = axis2_http_transport_sender_create(env); + if(!(*inst)) + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT int +#ifndef AXIS2_STATIC_DEPLOY +axis2_remove_instance( +#else + axis2_http_transport_sender_remove_instance( +#endif + axis2_transport_sender_t * inst, + const axutil_env_t * env) +{ + if(inst) + { + AXIS2_TRANSPORT_SENDER_FREE(inst, env); + } + return AXIS2_SUCCESS; +} + diff --git a/src/core/transport/http/sender/libcurl/Makefile.am b/src/core/transport/http/sender/libcurl/Makefile.am new file mode 100644 index 0000000..90e5ce6 --- /dev/null +++ b/src/core/transport/http/sender/libcurl/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST= axis2_libcurl.h axis2_libcurl.c libcurl_stream.h libcurl_stream.c + diff --git a/src/core/transport/http/sender/libcurl/axis2_libcurl.c b/src/core/transport/http/sender/libcurl/axis2_libcurl.c new file mode 100644 index 0000000..834e69b --- /dev/null +++ b/src/core/transport/http/sender/libcurl/axis2_libcurl.c @@ -0,0 +1,1169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef AXIS2_LIBCURL_ENABLED + +#include "axis2_libcurl.h" +#include <axiom_soap.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <axiom_output.h> +#include <axis2_op_ctx.h> +#include <axis2_ctx.h> +#include <axis2_conf_ctx.h> +#include <axis2_http_client.h> +#include <axiom_xml_writer.h> +#include <axutil_property.h> +#include <axutil_param.h> +#include <axutil_types.h> +#include <axutil_generic_obj.h> +#include <axis2_const.h> +#include <axis2_util.h> +#include <stdlib.h> +#include <axis2_http_sender.h> +#include <axis2_http_transport.h> +#include "libcurl_stream.h" + +static int ref = 0; + +struct axis2_libcurl +{ + axis2_char_t *memory; + axutil_array_list_t *alist; + unsigned int size; + const axutil_env_t *env; + char errorbuffer[CURL_ERROR_SIZE]; + CURL *handler; + axis2_bool_t cookies; +}; + +static size_t +axis2_libcurl_write_memory_callback( + void *ptr, + size_t size, + size_t nmemb, + void *data); + +static size_t +axis2_libcurl_header_callback( + void *ptr, + size_t size, + size_t nmemb, + void *data); + +static axis2_char_t * +axis2_libcurl_get_content_type( + axis2_libcurl_t *curl, + const axutil_env_t * env); + +static int +axis2_libcurl_get_content_length( + axis2_libcurl_t *curl, + const axutil_env_t * env); + +static axis2_http_header_t * +axis2_libcurl_get_first_header( + axis2_libcurl_t *curl, + const axutil_env_t * env, + const axis2_char_t * str); + +static void +axis2_libcurl_free_headers( + axis2_libcurl_t *curl, + const axutil_env_t * env); + +static axis2_status_t +axis2_libcurl_set_options( + CURL *handler, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +axis2_status_t AXIS2_CALL +axis2_libcurl_send( + axis2_libcurl_t *data, + axiom_output_t * om_output, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axiom_soap_envelope_t * out, + const axis2_char_t * str_url, + const axis2_char_t * soap_action) +{ + struct curl_slist *headers = NULL; + axiom_soap_body_t *soap_body; + axis2_bool_t is_soap = AXIS2_TRUE; + axis2_bool_t send_via_get = AXIS2_FALSE; + axis2_bool_t send_via_head = AXIS2_FALSE; + axis2_bool_t send_via_put = AXIS2_FALSE; + axis2_bool_t send_via_delete = AXIS2_FALSE; + axis2_bool_t doing_mtom = AXIS2_FALSE; + axiom_node_t *body_node = NULL; + axiom_node_t *data_out = NULL; + axutil_property_t *method = NULL; + axis2_char_t *method_value = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *buffer = NULL; + unsigned int buffer_size = 0; + int content_length = -1; + axis2_char_t *content_type = NULL; + axis2_char_t *content_len = AXIS2_HTTP_HEADER_CONTENT_LENGTH_; + const axis2_char_t *char_set_enc = NULL; + axis2_char_t *content = AXIS2_HTTP_HEADER_CONTENT_TYPE_; + axis2_char_t *soap_action_header = AXIS2_HTTP_HEADER_SOAP_ACTION_; + axutil_stream_t *in_stream; + axutil_property_t *trans_in_property; + axutil_string_t *char_set_enc_str; + axis2_byte_t *output_stream = NULL; + int output_stream_size = 0; + CURL *handler; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *write_xml_declaration_param = NULL; + axutil_hash_t *transport_attrs = NULL; + axis2_bool_t write_xml_declaration = AXIS2_FALSE; + axutil_property_t *property; + int *response_length = NULL; + axis2_http_status_line_t *status_line = NULL; + axis2_char_t *status_line_str = NULL; + axis2_char_t *tmp_strcat = NULL; + int status_code = 0; + + AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, data->handler, AXIS2_FAILURE); + + handler = data->handler; + curl_easy_reset(handler); + curl_easy_setopt(handler, CURLOPT_ERRORBUFFER, &data->errorbuffer); + headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_USER_AGENT_AXIS2C); + headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_ACCEPT_); + headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_EXPECT_); + + if(AXIS2_FAILURE == axis2_libcurl_set_options(handler, env, msg_ctx)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[axis2libcurl]Setting options in Libcurl failed"); + return AXIS2_FAILURE; + } + + if (AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + { + is_soap = AXIS2_FALSE; + } + else + { + is_soap = AXIS2_TRUE; + } + + if (!is_soap) + { + soap_body = axiom_soap_envelope_get_body(out, env); + if (!soap_body) + { + AXIS2_HANDLE_ERROR(env, + AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + body_node = axiom_soap_body_get_base_node(soap_body, env); + if (!body_node) + { + AXIS2_HANDLE_ERROR(env, + AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL, + AXIS2_FAILURE); + + return AXIS2_FAILURE; + } + data_out = axiom_node_get_first_element(body_node, env); + + method = (axutil_property_t *) axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_HTTP_METHOD); + + if (method) + { + method_value = + (axis2_char_t *) axutil_property_get_value(method, env); + } + + /* The default is POST */ + if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_GET)) + { + send_via_get = AXIS2_TRUE; + } + else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_HEAD)) + { + send_via_head = AXIS2_TRUE; + } + else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_PUT)) + { + send_via_put = AXIS2_TRUE; + } + else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_DELETE)) + { + send_via_delete = AXIS2_TRUE; + } + } + + conf_ctx = axis2_msg_ctx_get_conf_ctx (msg_ctx, env); + if (conf_ctx) + { + conf = axis2_conf_ctx_get_conf (conf_ctx, env); + } + + if (conf) + { + trans_desc = axis2_conf_get_transport_out (conf, + env, AXIS2_TRANSPORT_ENUM_HTTP); + } + + if (trans_desc) + { + write_xml_declaration_param = + axutil_param_container_get_param + (axis2_transport_out_desc_param_container (trans_desc, env), env, + AXIS2_XML_DECLARATION); + } + + if (write_xml_declaration_param) + { + transport_attrs = + axutil_param_get_attributes (write_xml_declaration_param, env); + if (transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *write_xml_declaration_attr = NULL; + axis2_char_t *write_xml_declaration_attr_value = NULL; + + obj = axutil_hash_get (transport_attrs, AXIS2_ADD_XML_DECLARATION, + AXIS2_HASH_KEY_STRING); + if (obj) + { + write_xml_declaration_attr = (axiom_attribute_t *) + axutil_generic_obj_get_value (obj, + env); + } + if (write_xml_declaration_attr) + { + write_xml_declaration_attr_value = + axiom_attribute_get_value (write_xml_declaration_attr, env); + } + if (write_xml_declaration_attr_value && + 0 == axutil_strcasecmp (write_xml_declaration_attr_value, + AXIS2_VALUE_TRUE)) + { + write_xml_declaration = AXIS2_TRUE; + } + } + } + + if (write_xml_declaration) + { + axiom_output_write_xml_version_encoding (om_output, env); + } + + if (!send_via_get && !send_via_head && !send_via_delete) + { + xml_writer = axiom_output_get_xml_writer(om_output, env); + + char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env); + + if (!char_set_enc_str) + { + char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING; + } + else + { + char_set_enc = axutil_string_get_buffer(char_set_enc_str, env); + } + + if (!send_via_put && is_soap) + { + doing_mtom = axis2_msg_ctx_get_doing_mtom(msg_ctx, env); + + axiom_output_set_do_optimize(om_output, env, doing_mtom); + axiom_soap_envelope_serialize(out, env, om_output, AXIS2_FALSE); + if (AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + if (AXIS2_ESC_DOUBLE_QUOTE != *soap_action) + { + axis2_char_t *tmp_soap_action = NULL; + tmp_soap_action = + AXIS2_MALLOC(env->allocator, + (axutil_strlen(soap_action) + + 5) * sizeof(axis2_char_t)); + sprintf(tmp_soap_action, "\"%s\"", soap_action); + tmp_strcat = axutil_stracat(env, soap_action_header,tmp_soap_action); + headers = curl_slist_append(headers, tmp_strcat); + AXIS2_FREE(env->allocator, tmp_strcat); + AXIS2_FREE(env->allocator, tmp_soap_action); + } + else + { + tmp_strcat = axutil_stracat(env, soap_action_header, soap_action); + headers = curl_slist_append(headers, tmp_strcat ); + AXIS2_FREE(env->allocator, tmp_strcat); + } + } + + if (doing_mtom) + { + /*axiom_output_flush(om_output, env, &output_stream, + &output_stream_size);*/ + axiom_output_flush(om_output, env); + content_type = + (axis2_char_t *) axiom_output_get_content_type(om_output, + env); + if (AXIS2_TRUE != axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + if (axutil_strcmp(soap_action, "")) + { + /* handle SOAP action for SOAP 1.2 case */ + axis2_char_t *temp_content_type = NULL; + temp_content_type = axutil_stracat (env, + content_type, + AXIS2_CONTENT_TYPE_ACTION); + content_type = temp_content_type; + temp_content_type = axutil_stracat (env, + content_type, + soap_action); + AXIS2_FREE (env->allocator, content_type); + content_type = temp_content_type; + temp_content_type = + axutil_stracat (env, content_type, + AXIS2_ESC_DOUBLE_QUOTE_STR); + AXIS2_FREE (env->allocator, content_type); + content_type = temp_content_type; + } + } + } + else if (AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + axis2_char_t *temp_content_type = NULL; + content_type = + (axis2_char_t *) AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML; + content_type = axutil_stracat(env, content_type, + AXIS2_CONTENT_TYPE_CHARSET); + temp_content_type = + axutil_stracat(env, content_type, char_set_enc); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + } + else + { + axis2_char_t *temp_content_type = NULL; + content_type = + (axis2_char_t *) AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP; + content_type = axutil_stracat(env, content_type, + AXIS2_CONTENT_TYPE_CHARSET); + temp_content_type = + axutil_stracat(env, content_type, char_set_enc); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + if (axutil_strcmp(soap_action, "")) + { + temp_content_type = + axutil_stracat(env, content_type, + AXIS2_CONTENT_TYPE_ACTION); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + temp_content_type = + axutil_stracat(env, content_type, soap_action); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + } + temp_content_type = axutil_stracat(env, content_type, + AXIS2_SEMI_COLON_STR); + AXIS2_FREE(env->allocator, content_type); + content_type = temp_content_type; + } + } + else if (is_soap) + { + AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI, "Attempt to send SOAP" + "message using HTTP PUT failed"); + return AXIS2_FAILURE; + } + else + { + axutil_property_t *content_type_property = NULL; + axutil_hash_t *content_type_hash = NULL; + axis2_char_t *content_type_value = NULL; + + axiom_node_serialize(data_out, env, om_output); + content_type_property = + (axutil_property_t *) + axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_USER_DEFINED_HTTP_HEADER_CONTENT_TYPE); + + if (content_type_property) + { + content_type_hash = + (axutil_hash_t *) + axutil_property_get_value(content_type_property, env); + + if (content_type_hash) + { + content_type_value = + (char *) axutil_hash_get(content_type_hash, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HASH_KEY_STRING); + } + } + + if (content_type_value) + { + content_type = content_type_value; + } + else + { + content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML; + } + + } + + buffer = axiom_xml_writer_get_xml(xml_writer, env); + if (!doing_mtom) + { + buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env); + } + else + buffer_size = output_stream_size; + { + char tmp_buf[10]; + sprintf(tmp_buf, "%d", buffer_size); + tmp_strcat = axutil_stracat(env, content_len, tmp_buf); + headers = curl_slist_append(headers, tmp_strcat); + AXIS2_FREE(env->allocator, tmp_strcat); + tmp_strcat = NULL; + + tmp_strcat = axutil_stracat(env, content, content_type); + headers = curl_slist_append(headers, tmp_strcat); + AXIS2_FREE(env->allocator, tmp_strcat); + tmp_strcat = NULL; + } + + if (!doing_mtom) + { + curl_easy_setopt(handler, CURLOPT_POSTFIELDSIZE, buffer_size); + curl_easy_setopt(handler, CURLOPT_POSTFIELDS, buffer); + } + else + { + curl_easy_setopt(handler, CURLOPT_POSTFIELDSIZE, + output_stream_size); + curl_easy_setopt(handler, CURLOPT_POSTFIELDS, output_stream); + } + + if (send_via_put) + { + curl_easy_setopt(handler, CURLOPT_CUSTOMREQUEST, AXIS2_HTTP_PUT); + } + curl_easy_setopt(handler, CURLOPT_URL, str_url); + } + else + { + axis2_char_t *request_param; + axis2_char_t *url_encode; + request_param = + (axis2_char_t *) axis2_http_sender_get_param_string(NULL, env, + msg_ctx); + url_encode = axutil_strcat(env, str_url, AXIS2_Q_MARK_STR, + request_param, NULL); + if (send_via_get) + { + curl_easy_setopt(handler, CURLOPT_HTTPGET, 1); + } + else if (send_via_head) + { + curl_easy_setopt(handler, CURLOPT_NOBODY, 1); + } + else if (send_via_delete) + { + curl_easy_setopt(handler, CURLOPT_CUSTOMREQUEST, AXIS2_HTTP_DELETE); + } + curl_easy_setopt(handler, CURLOPT_URL, url_encode); + } + + { + axis2_bool_t manage_session; + manage_session = axis2_msg_ctx_get_manage_session(msg_ctx, env); + if (manage_session == AXIS2_TRUE) + { + if (data->cookies == AXIS2_FALSE) + { + /* Ensure cookies enabled to manage session */ + /* Pass empty cookie string to enable cookies */ + curl_easy_setopt(handler, CURLOPT_COOKIEFILE, " "); + data->cookies = AXIS2_TRUE; + } + } + else if (data->cookies == AXIS2_TRUE) + { + /* Pass special string ALL to reset cookies if any have been enabled. */ + /* If cookies have ever been enabled, we reset every time as long as + manage_session is false, as there is no clear curl option to + turn off the cookie engine once enabled. */ + curl_easy_setopt(handler, CURLOPT_COOKIELIST, AXIS2_ALL); + } + } + + curl_easy_setopt(handler, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(handler, CURLOPT_WRITEFUNCTION, + axis2_libcurl_write_memory_callback); + curl_easy_setopt(handler, CURLOPT_WRITEDATA, data); + + curl_easy_setopt (handler, CURLOPT_HEADERFUNCTION, axis2_libcurl_header_callback); + + curl_easy_setopt (handler, CURLOPT_WRITEHEADER, data); + + /* Free response data from previous request */ + if( data->size ) + { + if (data->memory) + { + AXIS2_FREE(data->env->allocator, data->memory); + } + data->size = 0; + } + + if (curl_easy_perform(handler)) + { + AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI, "%s", &data->errorbuffer); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + in_stream = axutil_stream_create_libcurl(env, data->memory, data->size); + trans_in_property = axutil_property_create(env); + axutil_property_set_scope(trans_in_property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_free_func(trans_in_property, env, + libcurl_stream_free); + axutil_property_set_value(trans_in_property, env, in_stream); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, + trans_in_property); + + if (axutil_array_list_size(data->alist, env) > 0) + { + status_line_str = axutil_array_list_get(data->alist, env, 0); + if (status_line_str) + { + status_line = axis2_http_status_line_create(env, status_line_str); + } + } + + if (status_line) + { + status_code = axis2_http_status_line_get_status_code(status_line, env); + } + + axis2_msg_ctx_set_status_code (msg_ctx, env, status_code); + AXIS2_FREE(data->env->allocator, content_type); + content_type = axis2_libcurl_get_content_type(data, env); + + if (content_type) + { + if (strstr (content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED) + && strstr (content_type, AXIS2_HTTP_HEADER_ACCEPT_XOP_XML)) + { + axis2_ctx_t *axis_ctx = + axis2_op_ctx_get_base (axis2_msg_ctx_get_op_ctx (msg_ctx, env), + env); + property = axutil_property_create (env); + axutil_property_set_scope (property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_value (property, + env, axutil_strdup (env, content_type)); + axis2_ctx_set_property (axis_ctx, + env, MTOM_RECIVED_CONTENT_TYPE, property); + } + } + + content_length = axis2_libcurl_get_content_length(data, env); + if (content_length >= 0) + { + response_length = AXIS2_MALLOC (env->allocator, sizeof (int)); + memcpy (response_length, &content_length, sizeof (int)); + property = axutil_property_create (env); + axutil_property_set_scope (property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_value (property, env, response_length); + axis2_msg_ctx_set_property (msg_ctx, env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, property); + } + + curl_slist_free_all (headers); + /* release the read http headers. */ + /* (commenting out the call below is a clever way to force a premature EOF + condition in subsequent messages, as they will be read using the content-length + of the first message.) */ + axis2_libcurl_free_headers(data, env); + AXIS2_FREE(data->env->allocator, content_type); + axis2_http_status_line_free( status_line, env); + + return AXIS2_SUCCESS; +} + +static size_t +axis2_libcurl_write_memory_callback( + void *ptr, + size_t size, + size_t nmemb, + void *data) +{ + size_t realsize = size * nmemb; + axis2_libcurl_t *curl = (axis2_libcurl_t *) data; + axis2_char_t *buffer = + (axis2_char_t *) AXIS2_MALLOC(curl->env->allocator, + curl->size + realsize + 1); + if (buffer) + { + if (curl->size) + { + memcpy(&(buffer[0]), curl->memory, curl->size); + AXIS2_FREE(curl->env->allocator, curl->memory); + } + + memcpy(&(buffer[curl->size]), ptr, realsize); + curl->size += (int)realsize; + /* We are sure that the difference lies within the int range */ + buffer[curl->size] = 0; + curl->memory = buffer; + } + return realsize; +} + +static size_t +axis2_libcurl_header_callback( + void *ptr, + size_t size, + size_t nmemb, + void *data) +{ + axis2_char_t *memory; + size_t realsize = size * nmemb; + axis2_libcurl_t *curl = (axis2_libcurl_t *) data; + memory = (axis2_char_t *)AXIS2_MALLOC(curl->env->allocator, realsize + 1); + if (memory) + { + memcpy(&(memory[0]), ptr, realsize); + memory[realsize] = 0; + axutil_array_list_add(curl->alist, curl->env, memory); + } + return realsize; +} + +axis2_libcurl_t * AXIS2_CALL +axis2_libcurl_create( + const axutil_env_t * env) +{ + axis2_libcurl_t *curl = NULL; + CURLcode code; + + if (!ref) + { + /* curl_global_init is not thread-safe so it would be better + to do this, as well as the test and increment of ref, under + mutex if one is available, or as part of an + axis2_initialize() if a global initialize is created. + Otherwise the client application should perform the the + curl_global_init itself in a thread-safe fashion. + */ + code = curl_global_init(CURL_GLOBAL_ALL); + if (code) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "libcurl curl_global_init failed, error: %d", code); + return NULL; + } + ref++; + } + + curl = + (axis2_libcurl_t *) AXIS2_MALLOC(env->allocator, + sizeof(axis2_libcurl_t)); + if (curl) + { + curl->memory = 0; + curl->size = 0; + curl->alist = axutil_array_list_create(env, 15); + curl->env = env; + curl->handler = curl_easy_init(); + curl->cookies = AXIS2_FALSE; + if ((!curl->alist) || (!curl->handler)) + { + axis2_libcurl_free(curl, env); + curl = 0; + } + } + return curl; +} + +void AXIS2_CALL +axis2_libcurl_free( + axis2_libcurl_t *curl, + const axutil_env_t * env) +{ + if (!curl) + { + return; + } + + if (curl->handler) + { + curl_easy_cleanup (curl->handler); + } + if (curl->alist) + { + axis2_libcurl_free_headers(curl, env); + axutil_array_list_free(curl->alist, env); + curl->alist = NULL; + } + if (curl->memory) + { + AXIS2_FREE(env->allocator, curl->memory); + } + + AXIS2_FREE(env->allocator, curl); +} + +static void +axis2_libcurl_free_headers( + axis2_libcurl_t *curl, + const axutil_env_t * env) +{ + int count = 0; + axutil_array_list_t *header_group = curl->alist; + if (header_group) + { + while ((count = axutil_array_list_size(header_group, env)) > 0) + { + axis2_char_t *header = axutil_array_list_remove(header_group, env, count-1); + AXIS2_FREE(env->allocator, header); + } + } +} + +static axis2_http_header_t * +axis2_libcurl_get_first_header( + axis2_libcurl_t *curl, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_header_str = NULL; + axis2_char_t *tmp_name = NULL; + int i = 0; + int count = 0; + axutil_array_list_t *header_group = NULL; + + AXIS2_PARAM_CHECK(env->error, curl, NULL); + AXIS2_PARAM_CHECK(env->error, str, NULL); + + header_group = curl->alist; + if (!header_group) + { + return NULL; + } + + if (0 == axutil_array_list_size(header_group, env)) + { + return NULL; + } + + count = axutil_array_list_size(header_group, env); + + for (i = 0; i < count; i++) + { + tmp_header_str = (axis2_char_t *) axutil_array_list_get(header_group, + env, i); + if(!tmp_header_str) + { + continue; + } + tmp_header = (axis2_http_header_t *) axis2_http_header_create_by_str(env, tmp_header_str); + if(!tmp_header) + { + continue; + } + + tmp_name = axis2_http_header_get_name(tmp_header, env); + if (0 == axutil_strcasecmp(str, tmp_name)) + { + return tmp_header; + } + else + { + axis2_http_header_free( tmp_header, env ); + } + + } + return NULL; +} + +static int +axis2_libcurl_get_content_length( + axis2_libcurl_t *curl, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header; + int rtn_value = -1; + + tmp_header = axis2_libcurl_get_first_header + (curl, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH); + if (tmp_header) + { + rtn_value = AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env)); + axis2_http_header_free( tmp_header, env ); + } + return rtn_value; +} + +static axis2_char_t * +axis2_libcurl_get_content_type( + axis2_libcurl_t *curl, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header; + axis2_char_t *rtn_value = NULL; + + tmp_header = axis2_libcurl_get_first_header + (curl, env, AXIS2_HTTP_HEADER_CONTENT_TYPE); + if (tmp_header) + { + rtn_value = axutil_strdup (env, axis2_http_header_get_value(tmp_header, env) ); + axis2_http_header_free( tmp_header, env ); + } + else + { + rtn_value = axutil_strdup (env, AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN); + } + + return rtn_value; +} + +/** + * axis2_libcurl_set_auth_options maps authentication AXIS2/C options to + * libcURL options. + * + * CURLOPT_USERPWD - char * user:password for authentication + * CURLOPT_HTTPAUTH - long bitmask which authentication methods to use + */ +static axis2_status_t +axis2_libcurl_set_auth_options( + CURL *handler, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axutil_property_t *property = NULL; + axis2_char_t *uname = NULL; + axis2_char_t *passwd = NULL; + axis2_char_t *auth_type = NULL; + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME); + if (property) + { + uname = (axis2_char_t *) axutil_property_get_value(property, env); + } + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD); + if (property) + { + passwd = (axis2_char_t *) axutil_property_get_value(property, env); + } + if (uname && passwd) + { + axis2_char_t buffer[256]; + strncpy(buffer, uname, 256); + strncat(buffer, ":", 256); + strncat(buffer, passwd, 256); + curl_easy_setopt(handler, CURLOPT_USERPWD, buffer); + } + + property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE); + + if (property) + { + auth_type = (axis2_char_t *) axutil_property_get_value(property, env); + } + + if (auth_type && 0 == axutil_strcmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC)) + { + curl_easy_setopt(handler, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + } + else + { + /* Uses anonymous connection.*/ + } + + return AXIS2_SUCCESS; +} + +/** + * axis2_libcurl_set_proxy_options maps proxy AXIS2/C options to + * libcURL options. + * + * CURLOPT_PROXY - char * proxy hostname + * CURLOPT_PROXYPORT - long proxy listen port + * CURLOPT_PROXYUSERPWD - char * user:password to authenticate to proxy + * + * TODO: + * CURLOPT_PROXYTYPE - long enum type of proxy (HTTP, SOCKS) + * CURLOPT_PROXYAUTH - long bitmask which authentication methods to use for proxy + */ +static axis2_status_t +axis2_libcurl_set_proxy_options( + CURL *handler, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *proxy_param = NULL; + axutil_hash_t *transport_attrs = NULL; + axutil_property_t *property = NULL; + axis2_char_t *uname = NULL; + axis2_char_t *passwd = NULL; + axis2_char_t *proxy_host = NULL; + axis2_char_t *proxy_port = NULL; + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME); + if (property) + { + uname = (axis2_char_t *) axutil_property_get_value(property, env); + } + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD); + if (property) + { + passwd = (axis2_char_t *) axutil_property_get_value(property, env); + } + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if (conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if (conf) + { + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP); + } + } + if (trans_desc) + { + proxy_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_HTTP_PROXY_API); + if (!proxy_param) + { + proxy_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_HTTP_PROXY); + } + if (proxy_param) + { + transport_attrs = axutil_param_get_attributes(proxy_param, env); + } + } + + if (transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *attr = NULL; + + if (!uname || !passwd) + { + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME, AXIS2_HASH_KEY_STRING); + if (obj) + { + attr = (axiom_attribute_t *) axutil_generic_obj_get_value(obj, env); + } + if (attr) + { + uname = axiom_attribute_get_value(attr, env); + } + + attr = NULL; + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD, AXIS2_HASH_KEY_STRING); + if (obj) + { + attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if (attr) + { + passwd = axiom_attribute_get_value(attr, env); + } + } + + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING); + if (obj) + { + attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if (attr) + { + proxy_host = axiom_attribute_get_value(attr, env); + } + if (proxy_host) + { + curl_easy_setopt(handler, CURLOPT_PROXY, proxy_host); + } + + attr = NULL; + obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING); + if (obj) + { + attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env); + } + if (attr) + { + proxy_port = axiom_attribute_get_value(attr, env); + } + if (proxy_port) + { + curl_easy_setopt(handler, CURLOPT_PROXYPORT, AXIS2_ATOI(proxy_port)); + } + } + if (uname && passwd) + { + axis2_char_t buffer[256]; + strncpy(buffer, uname, 256); + strncat(buffer, ":", 256); + strncat(buffer, passwd, 256); + curl_easy_setopt(handler, CURLOPT_PROXYUSERPWD, buffer); + } + + return AXIS2_SUCCESS; +} + +/** + * axis2_libcurl_set_ssl_options maps SSL AXIS2/C options to + * libcURL options. + * + * CURLOPT_SSL_VERIFYHOST - long enum whether to verify the server identity + * CURLOPT_SSL_VERIFYPEER - long boolean whether to verify the server certificate + */ +static axis2_status_t +axis2_libcurl_set_ssl_options( + CURL *handler, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axutil_property_t *property = NULL; + axis2_char_t *verify_peer = NULL; + axis2_char_t *verify_host = NULL; + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_VERIFY_PEER); + if (property) + { + verify_peer = (axis2_char_t *)axutil_property_get_value(property, env); + } + if (verify_peer) + { + if (0 == axutil_strcasecmp(verify_peer, AXIS2_VALUE_TRUE)) + { + curl_easy_setopt(handler, CURLOPT_SSL_VERIFYPEER, 1); + } + else + { + curl_easy_setopt(handler, CURLOPT_SSL_VERIFYPEER, 0); + } + } + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_VERIFY_HOST); + if (property) + { + verify_host = (axis2_char_t *)axutil_property_get_value(property, env); + } + if (verify_host) + { + curl_easy_setopt(handler, CURLOPT_SSL_VERIFYHOST, AXIS2_ATOI(verify_host)); + } + + return AXIS2_SUCCESS; +} + +/** + * axis2_libcurl_set_connection_options maps connection AXIS2/C options to + * libcURL options. + * CURLOPT_CONNECTTIMEOUT_MS - long connection timeout in milliseconds + * CURLOPT_TIMEOUT_MS - long transfer timeout in milliseconds + */ +static axis2_status_t +axis2_libcurl_set_connection_options( + CURL *handler, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axutil_property_t *property = NULL; + long long_property_value = 0; + + /* check if timeout has been set by user using options + * with axis2_options_set_timeout_in_milli_seconds + */ + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_CONNECTION_TIMEOUT); + if (property) + { + axis2_char_t *value = axutil_property_get_value(property, env); + if (value) + { + long_property_value = AXIS2_ATOI(value); + curl_easy_setopt(handler, CURLOPT_CONNECTTIMEOUT_MS, long_property_value); + } + } + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_SO_TIMEOUT); + if (property) + { + axis2_char_t *value = axutil_property_get_value(property, env); + if (value) + { + long_property_value = AXIS2_ATOI(value); + curl_easy_setopt(handler, CURLOPT_TIMEOUT_MS, long_property_value); + } + } + + return AXIS2_SUCCESS; +} + +/** + * axis2_libcurl_set_options maps the AXIS2/C options to libcURL options. + */ +static axis2_status_t +axis2_libcurl_set_options( + CURL *handler, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + if (axis2_libcurl_set_auth_options(handler, env, msg_ctx) != AXIS2_SUCCESS) + { + return AXIS2_FAILURE; + } + + if (axis2_libcurl_set_proxy_options(handler, env, msg_ctx) != AXIS2_SUCCESS) + { + return AXIS2_FAILURE; + } + + if (axis2_libcurl_set_ssl_options(handler, env, msg_ctx) != AXIS2_SUCCESS) + { + return AXIS2_FAILURE; + } + + if (axis2_libcurl_set_connection_options(handler, env, msg_ctx) != AXIS2_SUCCESS) + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + + +#endif /* AXIS2_LIBCURL_ENABLED */ + diff --git a/src/core/transport/http/sender/libcurl/axis2_libcurl.h b/src/core/transport/http/sender/libcurl/axis2_libcurl.h new file mode 100644 index 0000000..f2971e5 --- /dev/null +++ b/src/core/transport/http/sender/libcurl/axis2_libcurl.h @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_LIBCURL_H +#define AXIS2_LIBCURL_H +#include <curl/curl.h> +#include <stdio.h> +#include <string.h> +#include <axis2_http_sender.h> +#include <axutil_string.h> +#include <axutil_types.h> +#include <axutil_generic_obj.h> +#include <axis2_const.h> +#include <axis2_util.h> +#include <axiom.h> + +/* typedef struct axis2_libcurl axis2_libcurl_t; */ +/* actually defined in axis2_http_sender.h as it is part of axis2/include */ + +AXIS2_EXTERN axis2_libcurl_t *AXIS2_CALL +axis2_libcurl_create( + const axutil_env_t * env); + +AXIS2_EXTERN void AXIS2_CALL +axis2_libcurl_free( + axis2_libcurl_t *data, + const axutil_env_t * env); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_libcurl_send( + axis2_libcurl_t *data, + axiom_output_t * om_output, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axiom_soap_envelope_t * out, + const axis2_char_t * str_url, + const axis2_char_t * soap_action); + +#endif /* AXIS2_LIBCURL_H */ diff --git a/src/core/transport/http/sender/libcurl/libcurl_stream.c b/src/core/transport/http/sender/libcurl/libcurl_stream.c new file mode 100644 index 0000000..0c9126d --- /dev/null +++ b/src/core/transport/http/sender/libcurl/libcurl_stream.c @@ -0,0 +1,192 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef AXIS2_LIBCURL_ENABLED + +#include "libcurl_stream.h" +#include <string.h> + +typedef struct libcurl_stream_impl +{ + axutil_stream_t stream; + axutil_stream_type_t stream_type; + axis2_char_t *buffer; + int size; + int read_len; +} +libcurl_stream_impl_t; + +#define AXIS2_INTF_TO_IMPL(stream) ((libcurl_stream_impl_t *)(stream)) + +/********************************Function headers******************************/ +axutil_stream_type_t AXIS2_CALL libcurl_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env); + +int AXIS2_CALL libcurl_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buffer, + size_t count); + +int AXIS2_CALL libcurl_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count); + +int AXIS2_CALL libcurl_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count); + +int AXIS2_CALL libcurl_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env); + +/************************* End of function headers ****************************/ + +/* + * Internal function. Not exposed to outside + */ +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_libcurl( + const axutil_env_t * env, + axis2_char_t * buffer, + unsigned int size) +{ + libcurl_stream_impl_t *stream_impl = NULL; + + AXIS2_PARAM_CHECK(env->error, buffer, NULL); + + stream_impl = + (libcurl_stream_impl_t *) AXIS2_MALLOC(env->allocator, + sizeof(libcurl_stream_impl_t)); + + if (!stream_impl) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + stream_impl->buffer = buffer; + stream_impl->size = size; + stream_impl->read_len = 0; + stream_impl->stream_type = AXIS2_STREAM_MANAGED; + + axutil_stream_set_read(&(stream_impl->stream), env, libcurl_stream_read); + axutil_stream_set_write(&(stream_impl->stream), env, libcurl_stream_write); + axutil_stream_set_skip(&(stream_impl->stream), env, libcurl_stream_skip); + + return &(stream_impl->stream); +} + +void AXIS2_CALL +libcurl_stream_free( + void * stream, + const axutil_env_t * env) +{ + libcurl_stream_impl_t *stream_impl = NULL; + + stream_impl = AXIS2_INTF_TO_IMPL(stream); + AXIS2_FREE(env->allocator, stream_impl); + + return; +} + +int AXIS2_CALL +libcurl_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count) +{ + libcurl_stream_impl_t *stream_impl = NULL; + int read = 0; + int unread = 0; + + stream_impl = AXIS2_INTF_TO_IMPL(stream); + if (stream_impl->size >= (int)count) + /* We are sure that the difference lies within the int range */ + { + if (buffer && (stream_impl->size > stream_impl->read_len)) + { + unread = (stream_impl->size - stream_impl->read_len); + if (unread > (int)count) + /* We are sure that the difference lies within the int range */ + { + memcpy(buffer, &stream_impl->buffer[stream_impl->read_len], + count); + read = (int)count; + /* We are sure that the difference lies within the int range */ + stream_impl->read_len += read; + } + else + { + memcpy(buffer, &stream_impl->buffer[stream_impl->read_len], + unread); + read = unread; + stream_impl->read_len += read; + } + } + else + read = 0; + } + else + { + if (buffer && (stream_impl->size > stream_impl->read_len)) + { + memcpy(buffer, &stream_impl->buffer[stream_impl->read_len], + stream_impl->size - stream_impl->read_len); + read = stream_impl->size - stream_impl->read_len; + stream_impl->read_len += read; + } + else + read = 0; + } + return read; +} + +int AXIS2_CALL +libcurl_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buffer, + size_t count) +{ + return (int)count; + /* We are sure that the difference lies within the int range */ +} + +int AXIS2_CALL +libcurl_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count) +{ + return 0; +} + +int AXIS2_CALL +libcurl_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + return 0; +} + +#endif /* AXIS2_LIBCURL_ENABLED */ + diff --git a/src/core/transport/http/sender/libcurl/libcurl_stream.h b/src/core/transport/http/sender/libcurl/libcurl_stream.h new file mode 100644 index 0000000..8a24fcc --- /dev/null +++ b/src/core/transport/http/sender/libcurl/libcurl_stream.h @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIBCURL_STREAM_H +#define LIBCURL_STREAM_H + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_stream.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** brief Constructor for creating apche2 stream + * @return axutil_stream (libcurl) + */ + AXIS2_EXTERN axutil_stream_t *AXIS2_CALL + axutil_stream_create_libcurl( + const axutil_env_t * env, + axis2_char_t * buffer, + unsigned int size); + + /** @} */ + + void AXIS2_CALL libcurl_stream_free( + void * stream, + const axutil_env_t * env); + + +#ifdef __cplusplus +} +#endif + +#endif /* LIBCURL_STREAM_H */ diff --git a/src/core/transport/http/sender/ssl/Makefile.am b/src/core/transport/http/sender/ssl/Makefile.am new file mode 100644 index 0000000..3e457e5 --- /dev/null +++ b/src/core/transport/http/sender/ssl/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST= ssl_stream.c ssl_stream.h ssl_utils.c ssl_utils.h + diff --git a/src/core/transport/http/sender/ssl/ssl_stream.c b/src/core/transport/http/sender/ssl/ssl_stream.c new file mode 100644 index 0000000..9360f1a --- /dev/null +++ b/src/core/transport/http/sender/ssl/ssl_stream.c @@ -0,0 +1,239 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef AXIS2_SSL_ENABLED + +#include <string.h> +#include <stdlib.h> +#include "ssl_stream.h" +#include "ssl_utils.h" + +/** + * @brief Stream struct impl + * Streaming mechanisms for SSL + */ +typedef struct ssl_stream_impl ssl_stream_impl_t; + +struct ssl_stream_impl +{ + axutil_stream_t stream; + axutil_stream_type_t stream_type; + SSL *ssl; + SSL_CTX *ctx; + axis2_socket_t socket; +}; + +#define AXIS2_INTF_TO_IMPL(stream) ((ssl_stream_impl_t *)(stream)) + +void AXIS2_CALL axis2_ssl_stream_free( + axutil_stream_t * stream, + const axutil_env_t * env); + +axutil_stream_type_t AXIS2_CALL axis2_ssl_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env); + +int AXIS2_CALL axis2_ssl_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buffer, + size_t count); + +int AXIS2_CALL axis2_ssl_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count); + +int AXIS2_CALL axis2_ssl_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count); + +int AXIS2_CALL axis2_ssl_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env); + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_ssl( + const axutil_env_t * env, + axis2_socket_t socket, + axis2_char_t * server_cert, + axis2_char_t * key_file, + axis2_char_t * ssl_pp) +{ + ssl_stream_impl_t *stream_impl = NULL; + + stream_impl = + (ssl_stream_impl_t *) AXIS2_MALLOC(env->allocator, + sizeof(ssl_stream_impl_t)); + + if (!stream_impl) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset ((void *)stream_impl, 0, sizeof (ssl_stream_impl_t)); + stream_impl->socket = socket; + stream_impl->ctx = NULL; + stream_impl->ssl = NULL; + + stream_impl->ctx = axis2_ssl_utils_initialize_ctx(env, server_cert, + key_file, ssl_pp); + if (!stream_impl->ctx) + { + axis2_ssl_stream_free((axutil_stream_t *) stream_impl, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE); + return NULL; + } + stream_impl->ssl = axis2_ssl_utils_initialize_ssl(env, stream_impl->ctx, + stream_impl->socket); + if (!stream_impl->ssl) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE); + return NULL; + } + stream_impl->stream_type = AXIS2_STREAM_MANAGED; + + axutil_stream_set_read(&(stream_impl->stream), env, axis2_ssl_stream_read); + axutil_stream_set_write(&(stream_impl->stream), env, + axis2_ssl_stream_write); + axutil_stream_set_skip(&(stream_impl->stream), env, axis2_ssl_stream_skip); + + return &(stream_impl->stream); +} + +void AXIS2_CALL +axis2_ssl_stream_free( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + ssl_stream_impl_t *stream_impl = NULL; + + stream_impl = AXIS2_INTF_TO_IMPL(stream); + axis2_ssl_utils_cleanup_ssl(env, stream_impl->ctx, stream_impl->ssl); + AXIS2_FREE(env->allocator, stream_impl); + + return; +} + +int AXIS2_CALL +axis2_ssl_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count) +{ + ssl_stream_impl_t *stream_impl = NULL; + int read = -1; + int len = -1; + + stream_impl = AXIS2_INTF_TO_IMPL(stream); + + SSL_set_mode(stream_impl->ssl, SSL_MODE_AUTO_RETRY); + + read = SSL_read(stream_impl->ssl, buffer, (int)count); + /* We are sure that the difference lies within the int range */ + switch (SSL_get_error(stream_impl->ssl, read)) + { + case SSL_ERROR_NONE: + len = read; + break; + case SSL_ERROR_ZERO_RETURN: + len = -1; + break; + case SSL_ERROR_SYSCALL: + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "SSL Error: Premature close"); + len = -1; + break; + default: + len = -1; + break; + } + return len; +} + +int AXIS2_CALL +axis2_ssl_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buf, + size_t count) +{ + ssl_stream_impl_t *stream_impl = NULL; + int write = -1; + + AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE); + stream_impl = AXIS2_INTF_TO_IMPL(stream); + write = SSL_write(stream_impl->ssl, buf, (int)count); + /* We are sure that the difference lies within the int range */ + + switch (SSL_get_error(stream_impl->ssl, write)) + { + case SSL_ERROR_NONE: + if ((int)count != write) + /* We are sure that the difference lies within the int range */ + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Incomplete SSL write!"); + break; + default: + return -1; + } + return write; +} + +int AXIS2_CALL +axis2_ssl_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count) +{ + ssl_stream_impl_t *stream_impl = NULL; + axis2_char_t *tmp_buffer = NULL; + int len = -1; + stream_impl = AXIS2_INTF_TO_IMPL(stream); + + tmp_buffer = AXIS2_MALLOC(env->allocator, count * sizeof(axis2_char_t)); + if (tmp_buffer == NULL) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return -1; + } + len = SSL_read(stream_impl->ssl, tmp_buffer, count); + AXIS2_FREE(env->allocator, tmp_buffer); + return len; + +} + +int AXIS2_CALL +axis2_ssl_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + int ret = -1; + + return ret; +} + +axutil_stream_type_t AXIS2_CALL +axis2_ssl_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + return AXIS2_INTF_TO_IMPL(stream)->stream_type; +} + +#endif + diff --git a/src/core/transport/http/sender/ssl/ssl_stream.h b/src/core/transport/http/sender/ssl/ssl_stream.h new file mode 100644 index 0000000..396da5d --- /dev/null +++ b/src/core/transport/http/sender/ssl/ssl_stream.h @@ -0,0 +1,50 @@ + +/* + * Copyright 2004,2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain count copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_SSL_STREAM_H +#define AXIS2_SSL_STREAM_H + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_stream.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <openssl/ssl.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** \brief Constructor for creating ssl stream + * @return axutil_stream (ssl) + */ + AXIS2_EXTERN axutil_stream_t *AXIS2_CALL + axutil_stream_create_ssl( + const axutil_env_t * env, + axis2_socket_t socket, + axis2_char_t * server_cert, + axis2_char_t * key_file, + axis2_char_t * ssl_pp); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_SSL_STREAM_H */ diff --git a/src/core/transport/http/sender/ssl/ssl_utils.c b/src/core/transport/http/sender/ssl/ssl_utils.c new file mode 100644 index 0000000..d565555 --- /dev/null +++ b/src/core/transport/http/sender/ssl/ssl_utils.c @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef AXIS2_SSL_ENABLED + +#include "ssl_utils.h" +#include <openssl/err.h> +BIO *bio_err = 0; + +static int +password_cb( + char *buf, + int size, + int rwflag, + void *passwd) +{ + strncpy(buf, (char *) passwd, size); + buf[size - 1] = '\0'; + return (int)(strlen(buf)); + /* We are sure that the difference lies within the int range */ +} + +AXIS2_EXTERN SSL_CTX *AXIS2_CALL +axis2_ssl_utils_initialize_ctx( + const axutil_env_t * env, + axis2_char_t * server_cert, + axis2_char_t * key_file, + axis2_char_t * ssl_pp) +{ + SSL_METHOD *meth = NULL; + SSL_CTX *ctx = NULL; + axis2_char_t *ca_file = server_cert; + + if (!ca_file) + { + AXIS2_LOG_INFO(env->log, "[ssl client] CA certificate not specified"); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_NO_CA_FILE, AXIS2_FAILURE); + return NULL; + } + + if (!bio_err) + { + /* Global system initialization */ + SSL_library_init(); + SSL_load_error_strings(); + + /* An error write context */ + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + } + + /* Create our context */ + meth = SSLv23_method(); + ctx = SSL_CTX_new(meth); + + /* Load our keys and certificates + * If we need client certificates it has to be done here + */ + if (key_file) /*can we check if the server needs client auth? */ + { + if (!ssl_pp) + { + AXIS2_LOG_INFO(env->log, + "[ssl client] No passphrase specified for \ +key file %s and server cert %s", key_file, server_cert); + } + + SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) ssl_pp); + SSL_CTX_set_default_passwd_cb(ctx, password_cb); + + if (!(SSL_CTX_use_certificate_chain_file(ctx, key_file))) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "[ssl client] Loading client certificate failed \ +, key file %s", key_file); + SSL_CTX_free(ctx); + return NULL; + } + + if (!(SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM))) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "[ssl client] Loading client key failed, key file \ +%s", key_file); + SSL_CTX_free(ctx); + return NULL; + } + } + else + { + AXIS2_LOG_INFO(env->log, + "[ssl client] Client certificate chain file" + "not specified"); + } + + /* Load the CAs we trust */ + if (!(SSL_CTX_load_verify_locations(ctx, ca_file, 0))) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "[ssl client] Loading CA certificate failed, \ +ca_file is %s", ca_file); + SSL_CTX_free(ctx); + return NULL; + } + + return ctx; +} + +AXIS2_EXTERN SSL *AXIS2_CALL +axis2_ssl_utils_initialize_ssl( + const axutil_env_t * env, + SSL_CTX * ctx, + axis2_socket_t socket) +{ + SSL *ssl = NULL; + BIO *sbio = NULL; + + AXIS2_PARAM_CHECK(env->error, ctx, NULL); + + ssl = SSL_new(ctx); + if (!ssl) + { + AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI, + "[ssl]unable to create new ssl context"); + return NULL; + } + + sbio = BIO_new_socket((int)socket, BIO_NOCLOSE); + if (!sbio) + { + AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI, + "[ssl]unable to create BIO new socket for socket %d", + (int)socket); + return NULL; + } + + SSL_set_bio(ssl, sbio, sbio); + if (SSL_connect(ssl) <= 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE); + return NULL; + } + + if (SSL_get_verify_result(ssl) != X509_V_OK) + { + char sslerror[128]; /** error buffer must be at least 120 bytes long */ + X509 *peer_cert = NULL; + X509_STORE *cert_store = NULL; + X509_NAME *peer_name = NULL; + X509_OBJECT *client_object = NULL; + X509 *client_cert = NULL; + + peer_cert = SSL_get_peer_certificate(ssl); + if (peer_cert && peer_cert->cert_info) + { + peer_name = (peer_cert->cert_info)->subject; + } + + cert_store = SSL_CTX_get_cert_store(ctx); + if (peer_name && cert_store) + { + client_object = X509_OBJECT_retrieve_by_subject(cert_store->objs, + X509_LU_X509, + peer_name); + } + if (client_object) + { + client_cert = (client_object->data).x509; + if (client_cert && + (M_ASN1_BIT_STRING_cmp(client_cert->signature, + peer_cert->signature) == 0)) + { + if (peer_cert) + { + X509_free(peer_cert); + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "[ssl client] SSL certificate verified against peer"); + return ssl; + } + } + if (peer_cert) + { + X509_free(peer_cert); + } + ERR_error_string(SSL_get_verify_result(ssl), sslerror); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "[ssl client] SSL certificate verification failed (%s)", + sslerror); + return NULL; + } + + return ssl; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_ssl_utils_cleanup_ssl( + const axutil_env_t * env, + SSL_CTX * ctx, + SSL * ssl) +{ + + if (ssl) + { + SSL_shutdown(ssl); + } + if (ctx) + { + SSL_CTX_free(ctx); + } + return AXIS2_SUCCESS; +} + +#endif + diff --git a/src/core/transport/http/sender/ssl/ssl_utils.h b/src/core/transport/http/sender/ssl/ssl_utils.h new file mode 100644 index 0000000..26dc16b --- /dev/null +++ b/src/core/transport/http/sender/ssl/ssl_utils.h @@ -0,0 +1,56 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_SSL_UTILS_H +#define AXIS2_SSL_UTILS_H + + +#include <platforms/axutil_platform_auto_sense.h> +#include <axis2_const.h> +#include <axis2_defines.h> +#include <openssl/ssl.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + AXIS2_EXTERN SSL_CTX *AXIS2_CALL + axis2_ssl_utils_initialize_ctx( + const axutil_env_t * env, + axis2_char_t * server_cert, + axis2_char_t * key_file, + axis2_char_t * ssl_pp); + + AXIS2_EXTERN SSL *AXIS2_CALL + axis2_ssl_utils_initialize_ssl( + const axutil_env_t * env, + SSL_CTX * ctx, + axis2_socket_t socket); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_ssl_utils_cleanup_ssl( + const axutil_env_t * env, + SSL_CTX * ctx, + SSL * ssl); + +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_SSL_UTILS_H */ diff --git a/src/core/transport/http/server/CGI/Makefile.am b/src/core/transport/http/server/CGI/Makefile.am new file mode 100644 index 0000000..fafb8bf --- /dev/null +++ b/src/core/transport/http/server/CGI/Makefile.am @@ -0,0 +1,31 @@ +prgbindir=$(bindir) +prgbin_PROGRAMS = axis2.cgi +SUBDIRS = +AM_CFLAGS = -g -pthread +axis2_cgi_SOURCES = axis2_cgi_main.c \ + axis2_cgi_out_transport_info.c \ + axis2_cgi_stream.c + +axis2_cgi_LDADD = $(LDFLAGS) \ + $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la \ + $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la \ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la \ + $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la \ + $(top_builddir)/src/core/description/libaxis2_description.la \ + $(top_builddir)/src/core/deployment/libaxis2_deployment.la \ + $(top_builddir)/src/core/context/libaxis2_context.la \ + $(top_builddir)/src/core/clientapi/libaxis2_clientapi.la \ + $(top_builddir)/src/core/engine/libaxis2_engine.la \ + $(top_builddir)/src/core/transport/http/sender/libaxis2_http_sender.la \ + $(top_builddir)/src/core/transport/http/receiver/libaxis2_http_receiver.la \ + -lpthread + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/description\ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/deployment\ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/http/server/CGI/axis2_cgi_main.c b/src/core/transport/http/server/CGI/axis2_cgi_main.c new file mode 100644 index 0000000..6f9a59d --- /dev/null +++ b/src/core/transport/http/server/CGI/axis2_cgi_main.c @@ -0,0 +1,280 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "axis2_cgi_out_transport_info.h" +#include "axis2_cgi_stream.h" + +#include <stdio.h> +#include <stdlib.h> +#include <axutil_error_default.h> +#include <axutil_log_default.h> +#include <axutil_thread_pool.h> +#include <axutil_types.h> +#include <axutil_version.h> +#include <axutil_file_handler.h> +#include <axutil_url.h> +#include <axutil_string.h> +#include <platforms/axutil_platform_auto_sense.h> + +#include <axis2_engine.h> +#include <axis2_conf_init.h> +#include <axis2_http_transport_utils.h> + +axis2_char_t *axis2_cgi_default_url_prefix = "/cgi-bin/axis2.cgi/"; + +/***************************** Function headers *******************************/ + +void +axis2_cgi_system_exit( + axutil_env_t * env, + int status); + +void +axis2_cgi_set_request_vars( + axis2_cgi_request_t *cgi_request); + +axis2_status_t +axis2_cgi_write_response( + const void *buffer, + unsigned int length); + +/***************************** End of function headers ************************/ + +int +main( + int argc, + char *argv[]) +{ + axutil_allocator_t *allocator = NULL; + axutil_env_t *env = NULL; + const axis2_char_t *repo_path; + axis2_conf_ctx_t *conf_ctx; + axis2_cgi_request_t *cgi_request = NULL; + int content_length = 0; + axis2_char_t *request_url = NULL; + /* axutil_stream_t *request_body_stream = NULL; */ + axutil_stream_t *out_stream = NULL; + axis2_transport_in_desc_t *in_desc = NULL; + axis2_transport_out_desc_t *out_desc = NULL; + /* axis2_msg_ctx_t *msg_ctx = NULL; */ + /* axis2_bool_t processed = AXIS2_FALSE; */ + axis2_http_transport_in_t request; + axis2_http_transport_out_t response; + /*axis2_http_header_t* http_header = NULL; */ + /*axutil_hash_t *headers = NULL; */ + /* axis2_char_t *axis2_cgi_url_prefix = NULL; */ + + if(!(repo_path = AXIS2_GETENV("AXIS2C_HOME"))) + { + fprintf(stderr, "Error: AXIS2C_HOME environment variable not set!"); + axis2_cgi_system_exit(env, -1); + } + + allocator = axutil_allocator_init(NULL); + env = axutil_env_create(allocator); + + if(axutil_file_handler_access(repo_path, AXIS2_R_OK) != AXIS2_SUCCESS) + { + fprintf(stderr, "Error reading repository: %s\nPlease check AXIS2C_HOME var", repo_path); + axis2_cgi_system_exit(env, -1); + } + + /* Set configuration */ + + conf_ctx = axis2_build_conf_ctx(env, repo_path); + if(!conf_ctx) + { + fprintf(stderr, "Error: Configuration not builded propertly\n"); + axis2_cgi_system_exit(env, -1); + } + + axis2_http_transport_utils_transport_out_init(&response, env); + axis2_http_transport_utils_transport_in_init(&request, env); + + /* Get input info */ + + cgi_request = AXIS2_MALLOC(allocator, sizeof(axis2_cgi_request_t)); + axis2_cgi_set_request_vars(cgi_request); + + request_url = (axis2_char_t *)AXIS2_MALLOC(allocator, (7 + /* "http:" */ + strlen(cgi_request->server_name) + ((strlen(cgi_request->server_port)) ? 1 : 0) + /* ":"*/ + strlen(cgi_request->server_port) + strlen(cgi_request->script_name) + strlen( + cgi_request->path_info) + ((strlen(cgi_request->path_info)) ? 1 : 0) + /* "?" */ + strlen(cgi_request->query_string)) * sizeof(axis2_char_t)); + + request_url[0] = '\0'; + + strcat(request_url, "http://"); + strcat(request_url, cgi_request->server_name); + if(strlen(cgi_request->server_port)) + strcat(request_url, ":"); + strcat(request_url, cgi_request->server_port); + strcat(request_url, cgi_request->script_name); + strcat(request_url, cgi_request->path_info); + if(strlen(cgi_request->query_string)) + strcat(request_url, "?"); + strcat(request_url, cgi_request->query_string); + + if(cgi_request->content_length) + content_length = axutil_atoi(cgi_request->content_length); + else + content_length = 0; + + /* Set streams */ + + out_stream = axutil_stream_create_basic(env); + + /* Set message contexts */ + + out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_HTTP); + in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_HTTP); + + request.msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc); + + axis2_msg_ctx_set_server_side(request.msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_transport_out_stream(request.msg_ctx, env, out_stream); + axis2_msg_ctx_set_transport_headers(request.msg_ctx, env, NULL); + + /* Set request parameters */ + + request.soap_action = cgi_request->soap_action; + request.in_stream = axutil_stream_create_cgi(env, content_length); + request.remote_ip = cgi_request->remote_addr; + request.content_length = content_length; + request.content_type = cgi_request->content_type; + request.request_uri = request_url; + request.svr_port = cgi_request->server_port; + request.accept_header = AXIS2_GETENV("HTTP_ACCEPT"); + request.accept_language_header = AXIS2_GETENV("HTTP_ACCEPT_LANGUAGE"); + request.accept_charset_header = AXIS2_GETENV("HTTP_ACCEPT_CHARSET"); + request.request_url_prefix = (AXIS2_GETENV("AXIS2C_URL_PREFIX")) ? AXIS2_GETENV( + "AXIS2C_URL_PREFIX") : axis2_cgi_default_url_prefix; + + if(axutil_strcasecmp(cgi_request->request_method, "POST") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_POST; + } + else if(axutil_strcasecmp(cgi_request->request_method, "GET") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_GET; + } + else if(axutil_strcasecmp(cgi_request->request_method, "HEAD") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_HEAD; + } + else if(axutil_strcasecmp(cgi_request->request_method, "PUT") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_PUT; + } + else if(axutil_strcasecmp(cgi_request->request_method, "DELETE") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_DELETE; + } + + request.out_transport_info = axis2_cgi_out_transport_info_create(env, cgi_request); + + /*Process request */ + fprintf(stderr, "ok\n"); + axis2_http_transport_utils_process_request(env, conf_ctx, &request, &response); + fprintf(stderr, "ok\n"); + /*Send status */ + + fprintf(stdout, "Status: %d %s \r\n", response.http_status_code, response.http_status_code_name); + + if(response.content_type) + { + fprintf(stdout, "Content-type: %s \r\n", response.content_type); + } + else if(strlen(axis2_cgi_out_transport_get_content(request.out_transport_info)) + && axis2_cgi_out_transport_get_content(request.out_transport_info)) + { + fprintf(stdout, "Content-type: %s \r\n", axis2_cgi_out_transport_get_content( + request.out_transport_info)); + } + + fprintf(stdout, "\r\n"); /* End of headers for server */ + + /* Write data body */ + if(!axis2_cgi_write_response(response.response_data, response.response_data_length)) + { + fprintf(stderr, "Error writing output data\n"); + } + + axis2_http_transport_utils_transport_in_uninit(&request, env); + axis2_http_transport_utils_transport_out_uninit(&response, env); + + return 0; +} + +axis2_status_t +axis2_cgi_write_response( + const void *buffer, + unsigned int length) +{ + if(buffer && length) + { + unsigned int completed = 0; + unsigned int written = 0; + + while(completed < length) + { + written = fwrite(buffer, sizeof(char), length - completed, stdout); + if(written < 0) + return AXIS2_FALSE; + completed += written; + } + } + return AXIS2_TRUE; +} + +void +axis2_cgi_set_request_vars( + axis2_cgi_request_t *cgi_request) +{ + cgi_request->server_name = (AXIS2_GETENV("SERVER_NAME")) ? AXIS2_GETENV("SERVER_NAME") : ""; + cgi_request->script_name = (AXIS2_GETENV("SCRIPT_NAME")) ? AXIS2_GETENV("SCRIPT_NAME") : ""; + cgi_request->path_info = (AXIS2_GETENV("PATH_INFO")) ? AXIS2_GETENV("PATH_INFO") : ""; + cgi_request->server_port = (AXIS2_GETENV("SERVER_PORT")) ? AXIS2_GETENV("SERVER_PORT") : ""; + cgi_request->server_protocol = (AXIS2_GETENV("SERVER_PROTOCOL")) ? AXIS2_GETENV( + "SERVER_PROTOCOL") : ""; + cgi_request->content_length = (AXIS2_GETENV("CONTENT_LENGTH")) ? AXIS2_GETENV("CONTENT_LENGTH") + : ""; + cgi_request->content_type = (AXIS2_GETENV("CONTENT_TYPE")) ? AXIS2_GETENV("CONTENT_TYPE") : ""; + cgi_request->request_method = (AXIS2_GETENV("REQUEST_METHOD")) ? AXIS2_GETENV("REQUEST_METHOD") + : ""; + cgi_request->remote_addr = (AXIS2_GETENV("REMOTE_ADDR")) ? AXIS2_GETENV("REMOTE_ADDR") : ""; + cgi_request->soap_action = (AXIS2_GETENV("HTTP_SOAPACTION")) ? AXIS2_GETENV("HTTP_SOAPACTION") + : NULL; + cgi_request->query_string = (AXIS2_GETENV("QUERY_STRING")) ? AXIS2_GETENV("QUERY_STRING") : ""; +} + +void +axis2_cgi_system_exit( + axutil_env_t * env, + int status) +{ + axutil_allocator_t *allocator = NULL; + + if(env) + { + allocator = env->allocator; + axutil_env_free(env); + } + exit(status); +} diff --git a/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.c b/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.c new file mode 100644 index 0000000..59e6820 --- /dev/null +++ b/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.c @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "axis2_cgi_out_transport_info.h" +#include <axutil_string.h> +#include <axis2_http_transport.h> + +/** + * @brief CIG Out transport info impl structure + * Axis2 cgi_out_transport_info_impl + */ + +typedef struct axis2_cgi_out_transport_info_s +{ + axis2_http_out_transport_info_t out_transport_info; + axis2_cgi_request_t *request; + axis2_char_t *encoding; +} axis2_cgi_out_transport_info_t; + +#define AXIS2_INTF_TO_IMPL(out_transport_info) \ + ((axis2_cgi_out_transport_info_t *)(out_transport_info)) + +void AXIS2_CALL +axis2_cgi_out_transport_info_free( + axis2_http_out_transport_info_t * info, + const axutil_env_t * env) +{ + axis2_cgi_out_transport_info_t *info_impl = NULL; + AXIS2_ENV_CHECK(env, void); + + info_impl = AXIS2_INTF_TO_IMPL(info); + + info_impl->request = NULL; /* doesn't belong here so no need to free it here */ + if(info_impl->encoding) + { + AXIS2_FREE(env->allocator, info_impl->encoding); + info_impl->encoding = NULL; + } + + AXIS2_FREE(env->allocator, info_impl); + return; +} + +void AXIS2_CALL +axis2_cgi_out_transport_info_free_void_arg( + void *transport_info, + const axutil_env_t * env) +{ + axis2_http_out_transport_info_t *transport_info_l = NULL; + + AXIS2_ENV_CHECK(env, void); + transport_info_l = (axis2_http_out_transport_info_t *)transport_info; + axis2_http_out_transport_info_free(transport_info_l, env); + return; +} + +axis2_status_t AXIS2_CALL +axis2_cgi_out_transport_info_set_content_type( + axis2_http_out_transport_info_t *info, + const axutil_env_t *env, + const axis2_char_t *content_type) +{ + axis2_cgi_out_transport_info_t *info_impl = NULL; + + axis2_char_t *temp1 = NULL; + axis2_char_t *temp2 = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE); + info_impl = AXIS2_INTF_TO_IMPL(info); + if(info_impl->encoding) + { + temp1 = axutil_stracat(env, content_type, ";charset="); + temp2 = axutil_stracat(env, temp1, info_impl->encoding); + info_impl->request->content_type = axutil_strdup(env, temp2); + AXIS2_FREE(env->allocator, temp1); + AXIS2_FREE(env->allocator, temp2); + } + else + { + info_impl->request->content_type = axutil_strdup(env, content_type); + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_cgi_out_transport_info_set_char_encoding( + axis2_http_out_transport_info_t * info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + axis2_cgi_out_transport_info_t *info_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE); + + info_impl = AXIS2_INTF_TO_IMPL(info); + + if(info_impl->encoding) + { + AXIS2_FREE(env->allocator, info_impl->encoding); + } + info_impl->encoding = axutil_strdup(env, encoding); + + return AXIS2_SUCCESS; +} + +axis2_http_out_transport_info_t *AXIS2_CALL +axis2_cgi_out_transport_info_create( + const axutil_env_t * env, + axis2_cgi_request_t * request) +{ + axis2_cgi_out_transport_info_t *info = NULL; + axis2_http_out_transport_info_t *out_transport_info = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + info = (axis2_cgi_out_transport_info_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_cgi_out_transport_info_t)); + + if(!info) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + info->request = request; + info->encoding = NULL; + + out_transport_info = &(info->out_transport_info); + + axis2_http_out_transport_info_set_char_encoding_func(out_transport_info, env, + axis2_cgi_out_transport_info_set_char_encoding); + axis2_http_out_transport_info_set_content_type_func(out_transport_info, env, + axis2_cgi_out_transport_info_set_content_type); + + return out_transport_info; +} + +axis2_char_t * +axis2_cgi_out_transport_get_content( + axis2_http_out_transport_info_t * info) +{ + axis2_cgi_out_transport_info_t *info_impl = NULL; + info_impl = AXIS2_INTF_TO_IMPL(info); + return info_impl->request->content_type; +} + diff --git a/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.h b/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.h new file mode 100644 index 0000000..bc0f526 --- /dev/null +++ b/src/core/transport/http/server/CGI/axis2_cgi_out_transport_info.h @@ -0,0 +1,62 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_CGI_OUT_TRANSPORT_INFO_H +#define AXIS2_CGI_OUT_TRANSPORT_INFO_H + +/** + * @ingroup axis2_core_transport_http + * @{ + */ + +/** + * @file axis2_cgi_out_transport_info.h + * @brief axis2 CGI Out Transport Info + */ + +#include "axis2_cgi_types.h" +#include <axis2_http_out_transport_info.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + axis2_http_out_transport_info_t *AXIS2_CALL + + axis2_cgi_out_transport_info_create( + const axutil_env_t * env, + axis2_cgi_request_t * request); + + /** + * Free http_out_transport_info passed as void pointer. This will be + * cast into appropriate type and then pass the cast object + * into the http_out_transport_info structure's free method + */ + void AXIS2_CALL + axis2_cgi_out_transport_info_free_void_arg( + void *transport_info, + const axutil_env_t * env); + + axis2_char_t *axis2_cgi_out_transport_get_content( + axis2_http_out_transport_info_t * out_transport_info); + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_SGI_OUT_TRANSPORT_INFO_H */ diff --git a/src/core/transport/http/server/CGI/axis2_cgi_stream.c b/src/core/transport/http/server/CGI/axis2_cgi_stream.c new file mode 100644 index 0000000..68ad19f --- /dev/null +++ b/src/core/transport/http/server/CGI/axis2_cgi_stream.c @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <stdlib.h> +#include "axis2_cgi_stream.h" + +/** + * @brief Stream struct impl + * Streaming mechanisms for cgi + */ + +typedef struct cgi_stream_impl +{ + axutil_stream_t stream; + axutil_stream_type_t stream_type; + unsigned int cur_pos; + unsigned int content_length; +} cgi_stream_impl_t; + +#define AXIS2_INTF_TO_IMPL(stream) ((cgi_stream_impl_t *)(stream)) + +axutil_stream_type_t AXIS2_CALL +cgi_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env); + +int AXIS2_CALL cgi_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buffer, + size_t count); + +int AXIS2_CALL cgi_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count); + +int AXIS2_CALL cgi_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count); + +int AXIS2_CALL cgi_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env); + +axutil_stream_t *AXIS2_CALL +axutil_stream_create_cgi( + const axutil_env_t * env, + unsigned int content_length) +{ + cgi_stream_impl_t *stream_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, content_length, NULL); + + stream_impl = (cgi_stream_impl_t *)AXIS2_MALLOC(env->allocator, sizeof(cgi_stream_impl_t)); + + if(!stream_impl) + { + return NULL; + } + stream_impl->cur_pos = 0; + stream_impl->content_length = content_length; + stream_impl->stream_type = AXIS2_STREAM_MANAGED; + + axutil_stream_set_read(&(stream_impl->stream), env, cgi_stream_read); + axutil_stream_set_write(&(stream_impl->stream), env, cgi_stream_write); + axutil_stream_set_skip(&(stream_impl->stream), env, cgi_stream_skip); + + return &(stream_impl->stream); +} +int AXIS2_CALL +cgi_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count) +{ + /*void *temp_buff = NULL;*/ + /*unsigned int data_to_read = 0;*/ + unsigned int read_bytes = 0; + /*axis2_bool_t ret_ok = AXIS2_TRUE;*/ + + cgi_stream_impl_t *stream_impl = NULL; + /*char *temp = NULL;*/ + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + stream_impl = (cgi_stream_impl_t *)stream; + + if(count < stream_impl->content_length) + { + read_bytes = fread(buffer, sizeof(char), count, stdin); + } + else + { + read_bytes = fread(buffer, sizeof(char), stream_impl->content_length, stdin); + } + + return read_bytes; +} + +int AXIS2_CALL +cgi_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buf, + size_t count) +{ + /* Cannot write on cgi stdin, explicitly an input stream */ + + return -1; +} + +int AXIS2_CALL +cgi_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count) +{ + cgi_stream_impl_t *stream_impl = NULL; + int skipped = -1; + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + stream_impl = AXIS2_INTF_TO_IMPL(stream); + + if(fseek(stdin, count, SEEK_CUR) == 0) + skipped = count; + return skipped; +} + +int AXIS2_CALL +cgi_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + int ret = -1; + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + + return ret; +} + +axutil_stream_type_t AXIS2_CALL +cgi_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + return AXIS2_INTF_TO_IMPL(stream)->stream_type; +} diff --git a/src/core/transport/http/server/CGI/axis2_cgi_stream.h b/src/core/transport/http/server/CGI/axis2_cgi_stream.h new file mode 100644 index 0000000..9a6af34 --- /dev/null +++ b/src/core/transport/http/server/CGI/axis2_cgi_stream.h @@ -0,0 +1,44 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CGI_STREAM_H +#define CGI_STREAM_H + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_stream.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** brief Constructor for creating CGI stream + * @return axutil_stream (CGI) + */ + axutil_stream_t *AXIS2_CALL + axutil_stream_create_cgi( + const axutil_env_t * env, + unsigned int content_length); + +#ifdef __cplusplus +} +#endif + +#endif /* CGI_STREAM_H */ diff --git a/src/core/transport/http/server/CGI/axis2_cgi_types.h b/src/core/transport/http/server/CGI/axis2_cgi_types.h new file mode 100644 index 0000000..af184a1 --- /dev/null +++ b/src/core/transport/http/server/CGI/axis2_cgi_types.h @@ -0,0 +1,34 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_const.h> + +typedef struct axis2_cgi_request +{ + axis2_char_t *server_name; + axis2_char_t *server_port; + axis2_char_t *script_name; + axis2_char_t *path_info; + axis2_char_t *server_protocol; + axis2_char_t *content_length; + axis2_char_t *content_type; + axis2_char_t *request_method; + axis2_char_t *remote_addr; + axis2_char_t *soap_action; + axis2_char_t *query_string; +} axis2_cgi_request_t; diff --git a/src/core/transport/http/server/IIS/README b/src/core/transport/http/server/IIS/README new file mode 100644 index 0000000..1a47cc4 --- /dev/null +++ b/src/core/transport/http/server/IIS/README @@ -0,0 +1,61 @@ +How to Configure IIS Module for Axis2C
+________________________________________
+
+Use the Axis2/C VC project or makefile to build the component.
+
+In this document it is assumed that the mod_axis2_IIS.dll is in the directory
+c:\axis2c\lib\mod_axis2_IIS.dll and axis2c_home is c:\axis2c
+
+Add the following key to the registry.
+
+HKEY_LOCAL_MACHINE\SOFTWARE\Apache Axis2c\IIS ISAPI Redirector
+
+Add a string value with the name axis2c_home and a value of c:\axis2c
+
+Add a string value with the name log_file and a value of c:\axis2c\logs\axis2.log
+
+Add a string value with the name log_level. The value can be one of trace, error, info, critical, debug, warning
+
+You can add a string value with the name services_url_prefix. This is optional and defaults to "/services".
+As an example, if you have "/web_services" as the prefix, then all the services hosted would have the endpoint prefix of :
+http://localhost/axis2/web_services.
+Note: don't forget the / at the begining.
+
+If you wish, you can also change the location as well by adding a string value with the name axis2_location.
+This is also optional and defaults to /axis2. If you have /myserser as the value you can access your web
+services with a url like http://localhost/myserver/services.
+Note: Don't forget the / at the beginning.
+
+Now you can do all the registry editing using the JScript file axis2_iis_regedit.js
+provided with the distribution. When you build axis2/C with the IIS module the file
+is copied to the root directory of the binary distribution. Just double click it and
+everything will be set to the defaults. The axis2c_home is taken as the current directory,
+so make sure you run the file in the Axis2/C repository location (or root of the binary distribution).
+If you want to change the values you can manually edit the the .js file or give it as command line arguments
+to the script when running the script. To run the jscript from the command line use the command
+:\cscript axis2_iis_regedit.js optional arguments.
+We recomend the manual editing as it is the easiest way to specify the values
+
+IIS 5.1 or Below
+
+Using the IIS management console, add a new virtual directory to your IIS/PWS Web site.
+The name of the virtual directory must be axis2. Its physical path should be the directory
+where you placed mod_axis2_IIS.dll (in our example it is c:\axis2c\lib). When creating this new
+virtual directory, assign execute access to it.
+
+By Using the IIS management console, add mod_axis2_IIS.dll as a filter in your IIS/PWS web site and restart the IIS admin service.
+
+
+IIS 6 & 7
+
+Using the IIS management console, add the mod_axis2_IIS.dll as a Wildcard Script Map.
+ Executable should be the complete path to the mod_axis2_IIS.dll
+ You can put any name as the name of the Wildcard Script Map
+
+Please don't add the mod_axis2_IIS.dll as a filter to IIS as in the IIS 5.1 case.
+
+Note: If the Axis2/C failed to load, verify that Axis2/C and its dependent DLLs are in the System Path (not the user path).
+
+
+
+
diff --git a/src/core/transport/http/server/IIS/axis2_iis_constants.h b/src/core/transport/http/server/IIS/axis2_iis_constants.h new file mode 100644 index 0000000..fb6929b --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_iis_constants.h @@ -0,0 +1,51 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_IIS_CONSTANTS_H +#define AXIS2_IIS_CONSTANTS_H + +#define INTERNET_MAX_PATH_LENGTH 2048 +#define INTERNET_MAX_SCHEME_LENGTH 32 /* longest protocol name length */ +#define INTERNET_MAX_URL_LENGTH (INTERNET_MAX_SCHEME_LENGTH +sizeof("://") +INTERNET_MAX_PATH_LENGTH) + +#define URI_MATCHED 1 +#define URI_UN_MATCHED 2 + +#define EXTENSION_URL "/axis2/mod_axis2_IIS.dll\? " +#define EXTENSION_URL_AXIS2 "/axis2/" +#define EXTENSION_URL_MODIIS "mod_axis2_IIS.dll\? " + + +#define MAX_SERVERNAME 128 +#define MAX_PORT_LEN 8 + +#define MAX_HTTP_VERSION_LEN 16 +#define MAX_HTTP_CONTENT_TYPE_LEN 2048 +#define MAX_CONTENT_ENCODING_LEN 16 +#define MAX_HTTP_METHOD_LEN 8 +#define MAX_TCP_PORT_LEN 8 +#define MAX_CONTENT_LEN 16 + +#define OK 200 +#define HTTP_INTERNAL_SERVER_ERROR 500 +#define HTTP_ACCEPTED 202 + +#define AXIS2_STRICMP _stricmp + +#endif /*AXIS2_IIS_CONSTANTS_H*/ + diff --git a/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.c b/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.c new file mode 100644 index 0000000..fb7693b --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.c @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "axis2_iis_out_transport_info.h" +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> + +#include "axis2_iis_constants.h" + +/** + * @brief IIS Out transport info impl structure + * Axis2 iis_out_transport_info_impl + */ + +typedef struct axis2_iis_out_transport_info_s +{ + axis2_http_out_transport_info_t out_transport_info; + axis2_char_t *encoding; + axis2_char_t content_type[MAX_HTTP_CONTENT_TYPE_LEN]; +} axis2_iis_out_transport_info_t; + +#define AXIS2_INTF_TO_IMPL(out_transport_info) \ + ((axis2_iis_out_transport_info_t *)(out_transport_info)) + +void AXIS2_CALL +axis2_iis_out_transport_info_free( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env) +{ + axis2_iis_out_transport_info_t *info = NULL; + AXIS2_ENV_CHECK(env, void); + + info = AXIS2_INTF_TO_IMPL(out_transport_info); + + if(info->encoding) + { + AXIS2_FREE(env->allocator, info->encoding); + info->encoding = NULL; + } + + AXIS2_FREE(env->allocator, info); + return; +} + +void AXIS2_CALL +axis2_iis_out_transport_info_free_void_arg( + void *transport_info, + const axutil_env_t * env) +{ + axis2_http_out_transport_info_t *transport_info_l = NULL; + + AXIS2_ENV_CHECK(env, void); + transport_info_l = (axis2_http_out_transport_info_t *)transport_info; + axis2_http_out_transport_info_free(transport_info_l, env); + return; +} + +axis2_status_t AXIS2_CALL +axis2_iis_out_transport_info_set_content_type( + axis2_http_out_transport_info_t * info, + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + axis2_iis_out_transport_info_t *info_impl = NULL; + + info_impl = AXIS2_INTF_TO_IMPL(info); + info_impl->content_type[0] = '\0'; + if(info_impl->encoding) + { + sprintf(info_impl->content_type, "%s%s%s", content_type, ";charser:", info_impl->encoding); + } + else + { + strcat(info_impl->content_type, content_type); + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_iis_out_transport_info_set_char_encoding( + axis2_http_out_transport_info_t * info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + axis2_iis_out_transport_info_t *info_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE); + + info_impl = AXIS2_INTF_TO_IMPL(info); + + if(info_impl->encoding) + { + AXIS2_FREE(env->allocator, info_impl->encoding); + } + info_impl->encoding = axutil_strdup(env, encoding); + + return AXIS2_SUCCESS; +} + +axis2_http_out_transport_info_t *AXIS2_CALL +axis2_iis_out_transport_info_create( + const axutil_env_t * env, + LPEXTENSION_CONTROL_BLOCK lpECB) +{ + axis2_iis_out_transport_info_t *info = NULL; + axis2_http_out_transport_info_t *http_out_info = NULL; + AXIS2_ENV_CHECK(env, NULL); + + info = (axis2_iis_out_transport_info_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_iis_out_transport_info_t)); + + if(!info) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + info->encoding = NULL; + + http_out_info = &(info->out_transport_info); + + axis2_http_out_transport_info_set_content_type_func(http_out_info, env, + axis2_iis_out_transport_info_set_content_type); + axis2_http_out_transport_info_set_char_encoding_func(http_out_info, env, + axis2_iis_out_transport_info_set_char_encoding); + axis2_http_out_transport_info_set_free_func(http_out_info, env, + axis2_iis_out_transport_info_free); + + return http_out_info; +} + +axis2_char_t * +axis2_iis_out_transport_get_content( + axis2_http_out_transport_info_t * info) +{ + axis2_iis_out_transport_info_t *info_impl = NULL; + info_impl = AXIS2_INTF_TO_IMPL(info); + return info_impl->content_type; +} diff --git a/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.h b/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.h new file mode 100644 index 0000000..893ffdf --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_iis_out_transport_info.h @@ -0,0 +1,61 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_IIS_OUT_TRANSPORT_INFO_H +#define AXIS2_IIS_OUT_TRANSPORT_INFO_H + +/** + * @ingroup axis2_core_transport_http + * @{ + */ + +/** + * @file axis2_iis_out_transport_info.h + * @brief axis2 IIS Out Transport Info + */ + +#include <axis2_http_out_transport_info.h> +#include <httpext.h> +#ifdef __cplusplus +extern "C" +{ +#endif + + axis2_http_out_transport_info_t *AXIS2_CALL + + axis2_iis_out_transport_info_create( + const axutil_env_t * env, + LPEXTENSION_CONTROL_BLOCK lpECB); + + /** + * Free http_out_transport_info passed as void pointer. This will be + * cast into appropriate type and then pass the cast object + * into the http_out_transport_info structure's free method + */ + void AXIS2_CALL + axis2_iis_out_transport_info_free_void_arg( + void *transport_info, + const axutil_env_t * env); + + axis2_char_t *axis2_iis_out_transport_get_content( + axis2_http_out_transport_info_t * out_transport_info); + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_IIS_OUT_TRANSPORT_INFO_H */ diff --git a/src/core/transport/http/server/IIS/axis2_iis_regedit.js b/src/core/transport/http/server/IIS/axis2_iis_regedit.js new file mode 100644 index 0000000..3889c1e --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_iis_regedit.js @@ -0,0 +1,84 @@ +var WshShell = WScript.CreateObject("WScript.Shell");
+
+/* You can change the following values to suite your requirements */
+/* Axis2/C repo location. axis2.xml, modules folder and services folder should be in this dir */
+var axis2c_home = WshShell.CurrentDirectory;
+/* Log level. Possible values are trace, error, info, critical, user, debug and warning */
+var log_level = "debug";
+/* Full path to the log file */
+var log_file = axis2c_home + "/logs/axis2.log";
+/* Services URL prefix. This is the folder where services are hosted. Optional */
+var services_url_prefix;
+/* Max log file size */
+var max_log_file_size;
+/* Axis2 location */
+var axis2_location;
+
+/* Don't change anything below */
+var axis2c_home_str = "axis2c_home";
+var log_level_str = "log_level";
+var log_file_str = "log_file";
+var services_url_prefix_str = "services_url_prefix";
+var max_log_file_size_str = "max_log_file_size";
+var axis2_location_str = "axis2_location"
+
+var reg_location = "HKLM\\Software\\Apache Axis2C\\IIS ISAPI Redirector\\"
+/* If specified get the values from the command prompt */
+var args = WScript.Arguments;
+if (args.length > 0) {
+ axis2c_home = args.Item(0);
+ if (axis2c_home) {
+ log_file = axis2c_home + "/logs/axis2.log";
+ }
+}
+if (args.length > 1) {
+ log_level = args.Item(1);
+}
+if (args.length > 2) {
+ log_file = args.Item(2);
+}
+if (args.length > 3) {
+ services_url_prefix = args.Item(3);
+}
+if (args.length > 4) {
+ max_log_file_size = args.Item(4);
+}
+if (args.length > 5) {
+ axis2_location = args.Item(5);
+}
+/* Write the axis2c_home entry. This is used by Axis2/C to find the repo location */
+WshShell.RegWrite (reg_location + axis2c_home_str, axis2c_home, "REG_SZ");
+/* Write the log_level registry entry */
+WshShell.RegWrite (reg_location + log_level_str, log_level, "REG_SZ");
+/* Write the log file name */
+WshShell.RegWrite (reg_location + log_file_str, log_file, "REG_SZ");
+/* Write the services url prefix. We write this only if specified */
+try {
+ var services_url_prefix_key = WshShell.RegRead (reg_location + services_url_prefix_str);
+ if (services_url_prefix_key) {
+ WshShell.RegDelete (reg_location + services_url_prefix_str);
+ }
+} catch (e) {}
+if (services_url_prefix) {
+ WshShell.RegWrite (reg_location + services_url_prefix_str, services_url_prefix, "REG_SZ");
+}
+/* We write max_log_file_size only if specified */
+try {
+ var max_log_file_size_key = WshShell.RegRead (reg_location + max_log_file_size_str);
+ if (max_log_file_size_key) {
+ WshShell.RegDelete (reg_location + max_log_file_size_str);
+ }
+} catch (e) {}
+if (max_log_file_size) {
+ WshShell.RegWrite (reg_location + max_log_file_size_str, max_log_file_size, "REG_SZ");
+}
+
+try{
+ var axis2_location_key = WshShell.RegRead (reg_location + axis2_location_str);
+ if (axis2_location_key) {
+ WshShell.RegDelete (reg_location + axis2_location_str);
+ }
+} catch (e) {}
+if (axis2_location) {
+ WshShell.RegWrite (reg_location + axis2_location_str, axis2_location, "REG_SZ");
+}
\ No newline at end of file diff --git a/src/core/transport/http/server/IIS/axis2_iis_stream.c b/src/core/transport/http/server/IIS/axis2_iis_stream.c new file mode 100644 index 0000000..90fc8ba --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_iis_stream.c @@ -0,0 +1,313 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <stdlib.h> +#include "axis2_iis_stream.h" +#include <httpext.h> + +/** + * @brief Stream struct impl + * Streaming mechanisms for iis web server + */ + +typedef struct iis_stream_impl +{ + axutil_stream_t stream; + axutil_stream_type_t stream_type; + LPEXTENSION_CONTROL_BLOCK lpECB; + unsigned int cur_pos; + void *cur_position; +} iis_stream_impl_t; + +#define AXIS2_INTF_TO_IMPL(stream) ((iis_stream_impl_t *)(stream)) + +axutil_stream_type_t AXIS2_CALL +iis_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env); + +int AXIS2_CALL iis_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buffer, + size_t count); + +int AXIS2_CALL iis_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count); + +int AXIS2_CALL iis_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count); + +int AXIS2_CALL iis_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env); + +axutil_stream_t *AXIS2_CALL +axutil_stream_create_iis( + const axutil_env_t * env, + LPEXTENSION_CONTROL_BLOCK lpECB) +{ + iis_stream_impl_t *stream_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, lpECB, NULL); + + stream_impl = (iis_stream_impl_t *)AXIS2_MALLOC(env->allocator, sizeof(iis_stream_impl_t)); + + if(!stream_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + stream_impl->cur_pos = 0; + stream_impl->cur_position = NULL; + stream_impl->lpECB = lpECB; + stream_impl->stream_type = AXIS2_STREAM_MANAGED; + + axutil_stream_set_read(&(stream_impl->stream), env, iis_stream_read); + axutil_stream_set_write(&(stream_impl->stream), env, iis_stream_write); + axutil_stream_set_skip(&(stream_impl->stream), env, iis_stream_skip); + + return &(stream_impl->stream); +} + +int AXIS2_CALL +iis_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count) +{ + void *temp_buff = NULL; + unsigned int data_to_read = 0; + DWORD ret_val = TRUE; + DWORD read_bytes = (DWORD)count; + iis_stream_impl_t *stream_impl = NULL; + char *temp = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + stream_impl = (iis_stream_impl_t *)stream; + + if(stream_impl->cur_pos == 0) + stream_impl->cur_position = stream_impl->lpECB->lpbData; + + /* If this is the case all the bytes are in the lpECB->lpbData buffer*/ + if(stream_impl->lpECB->cbAvailable == stream_impl->lpECB->cbTotalBytes) + { + /* Cannot read more than in the buffer.*/ + if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable) + data_to_read = (unsigned)count; + else + data_to_read = stream_impl->lpECB->cbTotalBytes - stream_impl->cur_pos; + + memcpy(buffer, stream_impl->cur_position, data_to_read); + temp = (char *)(stream_impl->cur_position); + temp += data_to_read; + stream_impl->cur_position = temp; + temp = NULL; + stream_impl->cur_pos += data_to_read; + read_bytes = data_to_read; + } + else if(stream_impl->lpECB->cbAvailable == -1) + { + ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, buffer, &read_bytes); + } + else if(stream_impl->lpECB->cbAvailable < stream_impl->lpECB->cbTotalBytes) + { + if(stream_impl->cur_pos > stream_impl->lpECB->cbAvailable) + { + ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, buffer, + &read_bytes); + } + else if(stream_impl->cur_pos + count > stream_impl->lpECB->cbAvailable + && stream_impl->cur_pos < stream_impl->lpECB->cbAvailable) + { + int read_length = 0; + if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable) + read_length = (unsigned)count; + else + read_length = stream_impl->lpECB->cbTotalBytes - stream_impl->cur_pos; + data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos; + memcpy(buffer, stream_impl->cur_position, data_to_read); + + read_bytes = stream_impl->cur_pos + read_length - stream_impl->lpECB->cbAvailable; + temp_buff = malloc(read_bytes); + + if(temp_buff == NULL) + return data_to_read; + ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff, + &read_bytes); + memcpy(((char *)buffer + data_to_read), temp_buff, read_bytes); + read_bytes += data_to_read; + temp = (char *)(stream_impl->cur_position); + temp += read_bytes; + stream_impl->cur_position = temp; + stream_impl->cur_pos += (unsigned)read_bytes; + } + else + { + memcpy(buffer, stream_impl->cur_position, count); + temp = (char *)(stream_impl->cur_position); + temp += count; + stream_impl->cur_position = temp; + temp = NULL; + stream_impl->cur_pos += (unsigned)count; + read_bytes = (int)count; + } + } + if(ret_val == TRUE) + return read_bytes; + else + return -1; +} + +int AXIS2_CALL +iis_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buf, + size_t count) +{ + DWORD ret_val = NO_ERROR; + unsigned long bytes_sent = 0; + iis_stream_impl_t *stream_impl = NULL; + axis2_char_t *buffer = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE); + stream_impl = AXIS2_INTF_TO_IMPL(stream); + buffer = (axis2_char_t *)buf; + bytes_sent = (unsigned)strlen(buffer); + + if(count <= 0) + { + return (int)count; + } + /* assume that buffer is not null terminated */ + ret_val = stream_impl->lpECB->WriteClient(stream_impl->lpECB->ConnID, buffer, &bytes_sent, + HSE_IO_SYNC); + if(ret_val == TRUE) + return (int)bytes_sent; + else + return -1; +} + +int AXIS2_CALL +iis_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count) +{ + DWORD ret_val = TRUE; + iis_stream_impl_t *stream_impl = NULL; + void *temp_buff = NULL; + int data_to_read = 0; + DWORD read_bytes = (DWORD)count; + char *temp = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + stream_impl = (iis_stream_impl_t *)stream; + + if(stream_impl->cur_pos == 0) + stream_impl->cur_position = stream_impl->lpECB->lpbData; + + if(stream_impl->lpECB->cbAvailable == stream_impl->lpECB->cbTotalBytes) + { + if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable) + data_to_read = count; + else + data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos; + + temp = (char *)(stream_impl->cur_position); + temp += data_to_read; + stream_impl->cur_position = temp; + temp = NULL; + stream_impl->cur_pos += data_to_read; + read_bytes = data_to_read; + } + else if(stream_impl->lpECB->cbAvailable == -1) + { + temp_buff = malloc(read_bytes); + ret_val + = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff, &read_bytes); + free(temp_buff); + } + else if(stream_impl->lpECB->cbAvailable < stream_impl->lpECB->cbTotalBytes) + { + if(stream_impl->cur_pos > stream_impl->lpECB->cbAvailable) + { + temp_buff = malloc(read_bytes); + ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff, + &read_bytes); + free(temp_buff); + } + else if(stream_impl->cur_pos + count > stream_impl->lpECB->cbAvailable + && stream_impl->cur_pos < stream_impl->lpECB->cbAvailable) + { + data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos; + read_bytes = stream_impl->cur_pos + count - stream_impl->lpECB->cbAvailable; + temp_buff = malloc(read_bytes); + + if(temp_buff == NULL) + return data_to_read; + + ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff, + &read_bytes); + read_bytes += data_to_read; + free(temp_buff); + } + else + { + temp = (char *)(stream_impl->cur_position); + temp += count; + stream_impl->cur_position = temp; + temp = NULL; + stream_impl->cur_pos += count; + read_bytes = count; + } + } + if(ret_val == FALSE) + { + return -1; + } + return read_bytes; +} + +int AXIS2_CALL +iis_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + int ret = -1; + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + + return ret; +} + +axutil_stream_type_t AXIS2_CALL +iis_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + return AXIS2_INTF_TO_IMPL(stream)->stream_type; +} diff --git a/src/core/transport/http/server/IIS/axis2_iis_stream.h b/src/core/transport/http/server/IIS/axis2_iis_stream.h new file mode 100644 index 0000000..091edb0 --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_iis_stream.h @@ -0,0 +1,45 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IIS_STREAM_H +#define IIS_STREAM_H + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_stream.h> +#include <httpext.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** brief Constructor for creating IIS stream + * @return axutil_stream (IIS) + */ + axutil_stream_t *AXIS2_CALL + axutil_stream_create_iis( + const axutil_env_t * env, + LPEXTENSION_CONTROL_BLOCK lpECB); + +#ifdef __cplusplus +} +#endif + +#endif /* IIS_STREAM_H */ diff --git a/src/core/transport/http/server/IIS/axis2_iis_worker.c b/src/core/transport/http/server/IIS/axis2_iis_worker.c new file mode 100644 index 0000000..51a6cc8 --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_iis_worker.c @@ -0,0 +1,607 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_transport.h> +#include <axis2_conf.h> +#include <axutil_string.h> +#include <axis2_msg_ctx.h> +#include <axis2_http_out_transport_info.h> +#include <axis2_http_transport_utils.h> +#include <axis2_op_ctx.h> +#include <axis2_engine.h> +#include <axutil_uuid_gen.h> +#include <axis2_conf_init.h> +#include <axutil_url.h> +#include <axiom_soap.h> +#include "axis2_iis_out_transport_info.h" +#include "axis2_iis_stream.h" +#include "axis2_iis_worker.h" + +/* Files from iis */ +#include <httpfilt.h> +#include <httpext.h> + +#include "axis2_iis_constants.h" + +#define READ_SIZE 2048 + +axis2_status_t AXIS2_CALL +axis2_worker_get_original_url( + char url[], + char ret_url[]); + +axis2_char_t * AXIS2_CALL +axis2_iis_worker_get_bytes( + const axutil_env_t * env, + axutil_stream_t * stream); + +axis2_status_t AXIS2_CALL +start_response( + const axutil_env_t * env, + LPEXTENSION_CONTROL_BLOCK lpECB, + int status, + const char *reason, + axutil_array_list_t *headers); + +axis2_status_t +write_response( + LPEXTENSION_CONTROL_BLOCK lpECB, + const void *b, + unsigned int l); + +axutil_hash_t * +axis2_iis_worker_read_http_headers( + const axutil_env_t * env, + LPEXTENSION_CONTROL_BLOCK lpECB); + +AXIS2_IMPORT extern axis2_char_t *axis2_request_url_prefix; + +static struct reasons +{ + axis2_char_t * status_code; + int status_len; +} reasons[] = { { "200 OK", 6 }, { "202 Accepted", 12 }, { "500 Internal Server Error", 25 } }; + +struct axis2_iis_worker +{ + axis2_conf_ctx_t * conf_ctx; +}; + +char * +status_reason( + int status); + +axis2_iis_worker_t * AXIS2_CALL +axis2_iis_worker_create( + const axutil_env_t * env, + axis2_char_t * repo_path) +{ + axis2_iis_worker_t * iis_worker = NULL; + + iis_worker = (axis2_iis_worker_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_iis_worker_t)); + if(!iis_worker) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + iis_worker->conf_ctx = axis2_build_conf_ctx(env, repo_path); + if(!iis_worker->conf_ctx) + { + axis2_iis_worker_free((axis2_iis_worker_t *)iis_worker, env); + return NULL; + } + return iis_worker; +} + +void AXIS2_CALL +axis2_iis_worker_free( + axis2_iis_worker_t * iis_worker, + const axutil_env_t * env) +{ + if(iis_worker->conf_ctx) + { + axis2_conf_ctx_free(iis_worker->conf_ctx, env); + iis_worker->conf_ctx = NULL; + } + AXIS2_FREE(env->allocator, iis_worker); + return; +} + +int AXIS2_CALL +axis2_iis_worker_process_request( + axis2_iis_worker_t * iis_worker, + const axutil_env_t * env, + LPEXTENSION_CONTROL_BLOCK lpECB) +{ + axis2_conf_ctx_t * conf_ctx = NULL; + axutil_stream_t * out_stream = NULL; + axis2_transport_out_desc_t * out_desc = NULL; + axis2_transport_in_desc_t * in_desc = NULL; + axis2_char_t soap_action[INTERNET_MAX_URL_LENGTH]; + axis2_char_t original_url[INTERNET_MAX_URL_LENGTH]; + axis2_char_t req_url[INTERNET_MAX_URL_LENGTH]; + DWORD cbSize = 0; + CHAR server_name[MAX_SERVERNAME]; + axis2_char_t port[MAX_TCP_PORT_LEN]; + axis2_char_t redirect_url[INTERNET_MAX_PATH_LENGTH]; + axis2_char_t accept_language[INTERNET_MAX_PATH_LENGTH]; + axutil_hash_t *headers = NULL; + axis2_char_t peer_ip[50]; + axis2_char_t accept_header[INTERNET_MAX_URL_LENGTH]; + axis2_char_t accept_charset[INTERNET_MAX_URL_LENGTH]; + /*axutil_property_t *peer_property = NULL;*/ + + axis2_http_header_t *content_type_header = NULL; + axis2_http_header_t *content_length_header = NULL; + + /* New Code variables */ + axis2_http_transport_in_t request; + axis2_http_transport_out_t response; + + /* initialize tranport in structure */ + axis2_http_transport_utils_transport_in_init(&request, env); + + /* initialize tranport out structure */ + axis2_http_transport_utils_transport_out_init(&response, env); + + soap_action[0] = '\0'; + + /*Check the parameters*/ + if(!lpECB) + { + AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_INVALID_NULL_PARAM); + return AXIS2_FAILURE; + } + conf_ctx = iis_worker->conf_ctx; + if(!conf_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + cbSize = INTERNET_MAX_PATH_LENGTH; + if(lpECB->GetServerVariable(lpECB->ConnID, "SERVER_NAME", server_name, &cbSize) == FALSE) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get server name from IIS."); + return AXIS2_FAILURE; + } + cbSize = MAX_TCP_PORT_LEN; + if(lpECB->GetServerVariable(lpECB->ConnID, "SERVER_PORT", port, &cbSize) == FALSE) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get server port from IIS."); + return AXIS2_FAILURE; + } + request.svr_port = port; + + cbSize = INTERNET_MAX_PATH_LENGTH; + if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_URL", redirect_url, &cbSize) == FALSE) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get server port from IIS."); + return AXIS2_FAILURE; + } + + /* We have a mapped URL only when the server version is 5 or less than that. */ + if(server_version <= 5) + { + axis2_worker_get_original_url(redirect_url, original_url); + /* create the url using the above variables */ + sprintf(req_url, "%s%s%s%s%s", "http://", server_name, ":", port, original_url); + } + else + { + sprintf(req_url, "%s%s%s%s%s", "http://", server_name, ":", port, redirect_url); + } + /* Set the request url */ + request.request_uri = req_url; + + out_stream = axutil_stream_create_basic(env); + out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(iis_worker->conf_ctx, env), + env, AXIS2_TRANSPORT_ENUM_HTTP); + in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(iis_worker->conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_HTTP); + + /* Create the in message context */ + request.msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc); + axis2_msg_ctx_set_server_side(request.msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_transport_out_stream(request.msg_ctx, env, out_stream); + + /* Get the SOAPAction Header */ + cbSize = INTERNET_MAX_URL_LENGTH; + if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_SOAPAction", soap_action, &cbSize)) + { + request.soap_action = soap_action; + } + + /* Create the in stream */ + request.in_stream = axutil_stream_create_iis(env, lpECB); + if(!request.in_stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in creating input stream."); + return AXIS2_FAILURE; + } + + /* Get the Remote Adrress */ + if(lpECB->GetServerVariable(lpECB->ConnID, "REMOTE_ADDR", peer_ip, &cbSize)) + { + request.remote_ip = peer_ip; + } + + /* Set the http headers into the message context */ + headers = axis2_iis_worker_read_http_headers(env, lpECB); + if(axis2_msg_ctx_set_transport_headers(request.msg_ctx, env, headers) == AXIS2_FAILURE) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "IIS: Error occured in setting transport headers."); + } + /* Set the content length */ + request.content_length = lpECB->cbTotalBytes; + /* Set the HTTP method */ + if(axutil_strcasecmp(lpECB->lpszMethod, "POST") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_POST; + } + else if(axutil_strcasecmp(lpECB->lpszMethod, "GET") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_GET; + } + else if(axutil_strcasecmp(lpECB->lpszMethod, "HEAD") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_HEAD; + } + else if(axutil_strcasecmp(lpECB->lpszMethod, "PUT") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_PUT; + } + else if(axutil_strcasecmp(lpECB->lpszMethod, "DELETE") == 0) + { + request.request_method = AXIS2_HTTP_METHOD_DELETE; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "IIS: Unsupported HTTP Method."); + return AXIS2_FAILURE; + } + /* Set the URL prefix. axis2_request_url_prefix is a global variable set at the init time */ + request.request_url_prefix = axis2_request_url_prefix; + /* Create the transport out info */ + request.out_transport_info = axis2_iis_out_transport_info_create(env, lpECB); + /* Set the content type */ + request.content_type = lpECB->lpszContentType; + + /* Get accept headaer */ + cbSize = INTERNET_MAX_PATH_LENGTH; + if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_Accept", accept_header, &cbSize)) + { + request.accept_header = accept_header; + } + + /* Get the accept langauge */ + cbSize = INTERNET_MAX_PATH_LENGTH; + if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_Accept-Language", accept_language, &cbSize)) + { + request.accept_language_header = accept_language; + } + + cbSize = INTERNET_MAX_PATH_LENGTH; + if(lpECB->GetServerVariable(lpECB->ConnID, "HTTP_Accept-Charset", accept_charset, &cbSize)) + { + request.accept_charset_header = accept_charset; + } + + /* Now we have set everything. We can call process method to process the request */ + if(axis2_http_transport_utils_process_request(env, conf_ctx, &request, &response) + == AXIS2_FAILURE) + { + return AXIS2_FAILURE; + } + + /* Write the response */ + if(response.response_data && response.response_data_length > 0) + { + axis2_char_t content_length_str[16] = { 0 }; + axis2_bool_t is_out_headers_created = AXIS2_FALSE; + if(!response.output_headers) + { + response.output_headers = axutil_array_list_create(env, 2); + is_out_headers_created = AXIS2_TRUE; + } + sprintf(content_length_str, "%d", response.response_data_length); + if(!response.content_type) + { + content_type_header = axis2_http_header_create(env, "Content-Type", + axis2_iis_out_transport_get_content(request.out_transport_info)); + } + else + { + content_type_header = axis2_http_header_create(env, "Content-Type", + response.content_type); + } + content_length_header = axis2_http_header_create(env, "Content-Length", content_length_str); + axutil_array_list_add(response.output_headers, env, content_length_header); + axutil_array_list_add(response.output_headers, env, content_type_header); + /* Write the headers */ + start_response(env, lpECB, response.http_status_code, response.http_status_code_name, + response.output_headers); + /* Write the response body */ + if(write_response(lpECB, response.response_data, response.response_data_length) + == AXIS2_FAILURE) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "IIS: Writing data to IIS"); + return AXIS2_FAILURE; + } + if(is_out_headers_created) + { + if(content_length_header) + { + axis2_http_header_free(content_length_header, env); + } + if(content_type_header) + { + axis2_http_header_free(content_type_header, env); + } + axutil_array_list_free(response.output_headers, env); + } + } + else + { + /* If we don't have a body we should write the HTTP headers */ + start_response(env, lpECB, response.http_status_code, response.http_status_code_name, + response.output_headers); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Response is NULL"); + } + + /* Do some cleaning */ + axis2_http_transport_utils_transport_in_uninit(&request, env); + axis2_http_transport_utils_transport_out_uninit(&response, env); + return AXIS2_SUCCESS; +} + +axis2_status_t +write_response( + LPEXTENSION_CONTROL_BLOCK lpECB, + const void *b, + unsigned int l) +{ + if(lpECB && b) + { + if(l) + { + unsigned int written = 0; + char *buf = (char *)b; + /* If couldn't write the data at onece try again until all the data is written.*/ + while(written < l) + { + DWORD try_to_write = l - written; + if(!lpECB-> WriteClient(lpECB->ConnID, buf + written, &try_to_write, 0)) + { + return AXIS2_FAILURE; + } + written += try_to_write; + } + } + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +start_response( + const axutil_env_t *env, + LPEXTENSION_CONTROL_BLOCK lpECB, + int status, + const char *reason, + axutil_array_list_t *headers) +{ + static char crlf[3] = { (char)13, (char)10, '\0' }; + unsigned int num_of_headers = 0; + + if(status < 100 || status > 1000) + { + return AXIS2_FAILURE; + } + if(lpECB) + { + size_t len_of_status; + char *status_str; + char *headers_str; + + /* + * Create the status line + */ + if(reason) + { + status_str = (char *)_alloca((6 + strlen(reason)) * sizeof(char)); + sprintf(status_str, "%d %s", status, reason); + len_of_status = strlen(status_str); + } + else + { + switch(status) + { + case 200: + status_str = reasons[0].status_code; + len_of_status = reasons[0].status_len; + break; + case 202: + status_str = reasons[1].status_code; + len_of_status = reasons[1].status_len; + break; + case 500: + status_str = reasons[2].status_code; + len_of_status = reasons[2].status_len; + break; + default: + status_str = reasons[0].status_code; + len_of_status = reasons[0].status_len; + break; + } + } + /* + * Create response headers string + */ + if(headers && (num_of_headers = axutil_array_list_size(headers, env)) > 0) + { + size_t i, len_of_headers; + axis2_http_header_t *header = NULL; + for(i = 0, len_of_headers = 0; i < num_of_headers; i++) + { + header = axutil_array_list_get(headers, env, (int)i); + len_of_headers += strlen(axis2_http_header_get_name(header, env)); + len_of_headers += strlen(axis2_http_header_get_value(header, env)); + len_of_headers += 4; /* extra for colon, space and crlf */ + } + len_of_headers += 3; /* crlf and terminating null char */ + headers_str = (char *)_alloca(len_of_headers * sizeof(char)); + headers_str[0] = '\0'; + for(i = 0; i < num_of_headers; i++) + { + header = axutil_array_list_get(headers, env, (int)i); + strcat(headers_str, axis2_http_header_get_name(header, env)); + strcat(headers_str, ": "); + strcat(headers_str, axis2_http_header_get_value(header, env)); + strcat(headers_str, "\r\n"); + } + strcat(headers_str, "\r\n"); + } + else + { + headers_str = crlf; + } + if(!lpECB-> ServerSupportFunction(lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, status_str, + (LPDWORD) & len_of_status, (LPDWORD)headers_str)) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +axis2_worker_get_original_url( + char url[], + char ret_url[]) +{ + extern axis2_char_t *axis2_location; + strcpy(ret_url, axis2_location); + strcat(ret_url, &url[25]); + return URI_MATCHED; +} + +axis2_char_t * AXIS2_CALL +axis2_iis_worker_get_bytes( + const axutil_env_t * env, + axutil_stream_t * stream) +{ + axutil_stream_t * tmp_stream = NULL; + int return_size = -1; + axis2_char_t * buffer = NULL; + axis2_bool_t loop_state = AXIS2_TRUE; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, stream, NULL); + + tmp_stream = axutil_stream_create_basic(env); + while(loop_state) + { + int read = 0; + int write = 0; + char buf[READ_SIZE]; + + read = axutil_stream_read(stream, env, buf, READ_SIZE); + if(read < 0) + { + break; + } + write = axutil_stream_write(tmp_stream, env, buf, read); + if(read < (READ_SIZE - 1)) + { + break; + } + } + return_size = axutil_stream_get_len(tmp_stream, env); + if(return_size > 0) + { + buffer = (char *)AXIS2_MALLOC(env->allocator, sizeof(char) * (return_size + 2)); + return_size = axutil_stream_read(tmp_stream, env, buffer, return_size + 1); + buffer[return_size + 1] = '\0'; + } + axutil_stream_free(tmp_stream, env); + return buffer; +} + +/** Read all HTTP headers. + */ +axutil_hash_t * +axis2_iis_worker_read_http_headers( + const axutil_env_t * env, + LPEXTENSION_CONTROL_BLOCK lpECB) +{ + const char szHTTP_[] = "HTTP_"; + char szBuffer[4096]; + DWORD dwBufferSize = sizeof szBuffer; + axutil_hash_t *headers = NULL; + axis2_http_header_t* http_header = NULL; + + BOOL bGet = lpECB->GetServerVariable(lpECB->ConnID, "ALL_HTTP", szBuffer, &dwBufferSize); + if(bGet) + { + /* Find lines, split key/data pair and write them as output */ + LPTSTR pOpts = NULL; + LPTSTR pEnd = NULL; + LPTSTR pChar = NULL; + char szTmpBuf[512]; + char szTmpName[256]; + + headers = axutil_hash_make(env); + szTmpBuf[0] = 0; + for(pChar = szBuffer; '\0' != *pChar;) + { + if(*pChar == '\r' || *pChar == '\n') + { + pChar++; + continue; + } + pOpts = strchr(pChar, ':');/* findseparator */ + if(pOpts && *pOpts) + { + pEnd = pOpts; + while(*pEnd && *pEnd != '\r' && *pEnd != '\n') + { + pEnd++; + } + *pOpts = '\0'; /* split the strings */ + *pEnd = '\0'; + if(0 == strncmp(pChar, szHTTP_, strlen(szHTTP_))) + { + pChar += strlen(szHTTP_); + } + strcpy(szTmpName, pChar); + axutil_string_replace(szTmpName, '_', '-'); + http_header = axis2_http_header_create(env, szTmpName, pOpts + 1); + axutil_hash_set(headers, axutil_strdup(env, szTmpName), AXIS2_HASH_KEY_STRING, + http_header); + pChar = pEnd + 1; + } + } + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "axis2_iis_worker_read_http_headers: no http headers"); + } + return headers; +} + diff --git a/src/core/transport/http/server/IIS/axis2_iis_worker.h b/src/core/transport/http/server/IIS/axis2_iis_worker.h new file mode 100644 index 0000000..f9b6292 --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_iis_worker.h @@ -0,0 +1,62 @@ +
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AXIS2_APACHE2_WORKER_H
+#define AXIS2_APACHE2_WORKER_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axis2_conf_ctx.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+
+#endif /*
+ */
+
+typedef struct axis2_iis_worker axis2_iis_worker_t;
+
+int server_version;
+
+int AXIS2_CALL
+ axis2_iis_worker_process_request(
+ axis2_iis_worker_t * iis_worker,
+ const axutil_env_t * env,
+ void *r);
+
+
+void AXIS2_CALL
+ axis2_iis_worker_free(
+ axis2_iis_worker_t * iis_worker,
+ const axutil_env_t * env);
+
+
+axis2_iis_worker_t * AXIS2_CALL
+ axis2_iis_worker_create(
+ const axutil_env_t * env,
+ axis2_char_t * repo_path);
+
+
+#ifdef __cplusplus
+}
+#endif /*
+ */
+
+#endif /* AXIS2_IIS_WORKER_H */
diff --git a/src/core/transport/http/server/IIS/axis2_isapi_plugin.c b/src/core/transport/http/server/IIS/axis2_isapi_plugin.c new file mode 100644 index 0000000..eccfd1c --- /dev/null +++ b/src/core/transport/http/server/IIS/axis2_isapi_plugin.c @@ -0,0 +1,476 @@ +
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <httpfilt.h>
+#include <httpext.h>
+
+#include "axis2_iis_constants.h"
+#include "axis2_iis_worker.h"
+
+/* Axis headers */ +#include <axutil_error_default.h> +#include <axutil_log_default.h> +#include <axutil_thread_pool.h> +#include <axiom_xml_reader.h> +#include <axutil_log.h>
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+
+#define AXIS2_IIS_LOG_FILE_TAG "log_file" +#define AXIS2_IIS_LOG_LEVEL_TAG "log_level" +#define AXIS2_IIS_REPO_PATH_TAG "axis2c_home" +#define AXIS2_IIS_EXTENSION_URI_TAG "extension_uri" +#define AXIS2_IIS_REDIRECT_WORD_TAG "redirect_uri" +#define AXIS2_IIS_AXIS2_LOCATION "axis2_location" +#define AXIS2_IIS_SERVICE_URL_PREFIX "services_url_prefix" + +#define AXIS2_IIS_LOG_TRACE_VERB "trace" +#define AXIS2_IIS_LOG_ERROR_VERB "error" +#define AXIS2_IIS_LOG_INFO_VERB "info" +#define AXIS2_IIS_LOG_USER_VERB "user" +#define AXIS2_IIS_LOG_CRITICAL_VERB "critical" +#define AXIS2_IIS_LOG_WARN_VERB "warning" +#define AXIS2_IIS_LOG_DEBUG_VERB "debug" + +#define MAX_FILE_PATH 256 +#define REGISTRY_LOCATION "Software\\Apache Axis2c\\IIS ISAPI Redirector" + +static int is_inited = FALSE; +static axis2_iis_worker_t *axis2_worker = NULL; +static const axutil_env_t *axutil_env = NULL; + +/* Configuration parameters */ +axis2_char_t *axis2_location = "/axis2"; +static axis2_char_t *axis2_service_url_prefix= "/services"; +static axis2_char_t repo_path[MAX_FILE_PATH]; +static axis2_char_t log_file[MAX_FILE_PATH]; +static axutil_log_levels_t log_level = AXIS2_LOG_LEVEL_CRITICAL; + +/* Path variables */ +static char szOriginalPath[_MAX_PATH + 1];
+static char szPath[_MAX_PATH + 1]; + +axis2_char_t general_error[] = "<html>\r\n"
+ "<head><title> An IIS server error occurred. </title></head>\r\n"
+ "<h1> An IIS server error occurred </h1>\r\n"
+ "<hr>\r\n"
+ "An error occurred in IIS while processing this request.</hr></html>"; + +axis2_char_t initializing_error[] = "<html>\r\n"
+ "<head><title> An IIS server error occurred. </title></head>\r\n"
+ "<h1> An IIS server error occurred </h1>\r\n"
+ "<hr>\r\n"
+ "An error occurred while initilizing Axis2/C.</hr></html>"; + + +/* + * This is a utility functipn for reading configuration data from the registery. + */ +static axis2_status_t AXIS2_CALL +read_registery_init_data(); + +/* + * Utility function for reading + */ +static axis2_status_t AXIS2_CALL get_registry_config_parameter( + HKEY hkey, + const char *tag, + char *b, + DWORD sz); + +/* + * Parse the given string and return the corresponding log_level + */ +axutil_log_levels_t AXIS2_CALL axis2_iis_parse_log_level(char level[]); +
+/*
+ * Initialize axis. This function is called in the begining of the module loading.
+ * It initializes the axis by reading values from the configuration and creating the
+ * required structures for the axis2c
+*/
+axis2_status_t AXIS2_CALL init_axis2();
+
+/*
+ * This is the function to be called after the processing
+ * is over for non Axis2 requets
+ */
+VOID
+WINAPI
+ExecUrlCompletion (
+ EXTENSION_CONTROL_BLOCK * pecb,
+ PVOID pContext,
+ DWORD cbIO,
+ DWORD dwError
+ );
+
+/*
+ * If somethign went wrong in the IIS server when
+ * we are proccessing we send this
+ */
+BOOL
+send_error(
+ EXTENSION_CONTROL_BLOCK * pecb,
+ CHAR error[]);
+
+axis2_status_t AXIS2_CALL init_axis2();
+
+BOOL
+WINAPI
+GetExtensionVersion(HSE_VERSION_INFO * pVer)
+{
+ pVer->dwExtensionVersion = MAKELONG( HSE_VERSION_MINOR,
+ HSE_VERSION_MAJOR);
+ strncpy( pVer->lpszExtensionDesc,
+ "WildCardMap Sample ISAPI Extension", HSE_MAX_EXT_DLL_NAME_LEN );
+
+ pVer->lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN-1] = '\0';
+ server_version = 5;
+ return TRUE;
+}
+
+DWORD
+WINAPI
+HttpExtensionProc(EXTENSION_CONTROL_BLOCK * pecb)
+
+{
+ HSE_EXEC_URL_INFO ExecUrlInfo;
+ DWORD cbData = INTERNET_MAX_URL_LENGTH;
+ char url[INTERNET_MAX_URL_LENGTH];
+ axis2_bool_t is_for_us = AXIS2_TRUE;
+
+ /* Get the URL */
+ if ( pecb->GetServerVariable( pecb->ConnID,
+ "URL",
+ url,
+ &cbData ) == FALSE )
+ {
+ return HSE_STATUS_ERROR;
+ }
+
+ if (!is_inited)
+ {
+ DWORD dwBufferSize = 0;
+ axis2_char_t server_software[256];
+ axis2_char_t *version = NULL;
+
+ ZeroMemory(szOriginalPath, sizeof szOriginalPath);
+ dwBufferSize = sizeof szOriginalPath;
+
+#if _WIN32_WINNT >= 0x0502
+ GetDllDirectory( dwBufferSize, szOriginalPath );
+#else
+ GetCurrentDirectory( dwBufferSize, szOriginalPath );
+#endif
+ ZeroMemory(szPath, sizeof szPath);
+ dwBufferSize = sizeof szPath;
+ /* Get the current physical paht */
+ if (pecb->GetServerVariable(pecb->ConnID, "APPL_PHYSICAL_PATH", szPath, &dwBufferSize) == FALSE)
+ {
+ send_error(pecb, initializing_error);
+ return HSE_STATUS_ERROR;
+ }
+ /* Retrieve the server version */
+ dwBufferSize = 32;
+ if (pecb->GetServerVariable(pecb->ConnID, "SERVER_SOFTWARE", server_software, &dwBufferSize) == FALSE)
+ {
+ send_error(pecb, initializing_error);
+ return HSE_STATUS_ERROR;
+ }
+ version = axutil_strchr(server_software, '/');
+ if (version)
+ {
+ server_version = atoi(version + 1);
+ }
+#if _WIN32_WINNT >= 0x0502
+ SetDllDirectory( szPath );
+#else
+ SetCurrentDirectory( szPath );
+#endif
+ /* If we haven't initialized axis2/c before initialization failed */
+ if (AXIS2_FAILURE == init_axis2())
+ {
+ send_error(pecb, initializing_error);
+ return HSE_STATUS_ERROR;
+ }
+#if _WIN32_WINNT >= 0x0502
+ SetDllDirectory( szOriginalPath );
+#else
+ SetCurrentDirectory( szOriginalPath );
+#endif
+ }
+
+ /* Check weather we have a request for Axis2/C */
+ if (server_version >= 6 && strlen(url) >= strlen(axis2_location))
+ {
+ int i = 0;
+ is_for_us = AXIS2_TRUE;
+ while (axis2_location[i] != '\0')
+ {
+ if (axis2_location[i] != (url)[i]) {
+ is_for_us = AXIS2_FALSE;
+ break;
+ }
+ i++;
+ }
+ if (url[i] != '/' && url[i] != '\0')
+ {
+ is_for_us = AXIS2_FALSE;
+ }
+ }
+
+ if (is_for_us)
+ {
+ /* Windows cannot find the correct dlls unless the path is set*/
+#if _WIN32_WINNT >= 0x0502
+ SetDllDirectory( szPath );
+#else
+ SetCurrentDirectory( szPath );
+#endif
+ pecb->dwHttpStatusCode = HTTP_INTERNAL_SERVER_ERROR;
+ /* We are sure that worker is not NULL since it is NULL init_axis2 would have failed */
+ axis2_iis_worker_process_request(axis2_worker, axutil_env, pecb);
+
+ /* Windows cannot find the correct dlls unless the dir is set
+ but we want to reset to previous dir after the load */
+#if _WIN32_WINNT >= 0x0502
+ SetDllDirectory( szOriginalPath );
+#else
+ SetCurrentDirectory( szOriginalPath );
+#endif
+ return HSE_STATUS_SUCCESS;
+ }
+ else if (server_version >= 6)
+ {
+ /* For IIS 5.1 or earlier this code is never executed. Since the URL is
+ redirected to Axis2/C by the Filter */
+
+ /* If not for Axis2/C let the request go to who ever wants it */
+ ExecUrlInfo.pszUrl = NULL; /* Use original request URL */
+ ExecUrlInfo.pszMethod = NULL; /* Use original request method */
+ ExecUrlInfo.pszChildHeaders = NULL; /* Use original request headers */
+ ExecUrlInfo.pUserInfo = NULL; /* Use original request user info */
+ ExecUrlInfo.pEntity = NULL; /* Use original request entity */
+
+ /* Provent recursion */
+ ExecUrlInfo.dwExecUrlFlags = HSE_EXEC_URL_IGNORE_CURRENT_INTERCEPTOR;
+
+ /* Associate the completion routine and the current URL with this request. */
+ if ( pecb->ServerSupportFunction( pecb->ConnID,
+ HSE_REQ_IO_COMPLETION,
+ ExecUrlCompletion,
+ NULL,
+ NULL) == FALSE )
+ {
+ return HSE_STATUS_ERROR;
+ }
+
+ /* Ok, now that everything is set up, let's call the child request */
+ if ( pecb->ServerSupportFunction( pecb->ConnID,
+ HSE_REQ_EXEC_URL,
+ &ExecUrlInfo,
+ NULL,
+ NULL ) == FALSE )
+ {
+ return HSE_STATUS_ERROR;
+ }
+ /* Return pending and let the completion clean up */
+ return HSE_STATUS_PENDING;
+ }
+ return HSE_STATUS_ERROR;
+}
+
+VOID
+WINAPI
+ExecUrlCompletion (
+ EXTENSION_CONTROL_BLOCK * pecb,
+ PVOID pContext,
+ DWORD cbIO,
+ DWORD dwError
+ )
+{
+ /* We are done so notify */
+ pecb->ServerSupportFunction(
+ pecb->ConnID,
+ HSE_REQ_DONE_WITH_SESSION,
+ NULL,
+ NULL,
+ NULL);
+}
+
+
+BOOL
+send_error(
+ EXTENSION_CONTROL_BLOCK * pecb,
+ axis2_char_t error[])
+{
+ DWORD cbData;
+ pecb->dwHttpStatusCode = 500;
+ /* Send headers and response */
+ pecb->ServerSupportFunction( pecb->ConnID,
+ HSE_REQ_SEND_RESPONSE_HEADER,
+ "500 Server Error",
+ NULL,
+ (LPDWORD)"Content-Type: text/html\r\n\r\n" );
+
+ cbData = axutil_strlen( error );
+ return pecb->WriteClient( pecb->ConnID,
+ error,
+ &cbData,
+ HSE_IO_SYNC );
+}
+
+axis2_status_t AXIS2_CALL read_registery_init_data() +{ + long rc = 0; + axis2_status_t ok = TRUE; + char tmpbuf[INTERNET_MAX_URL_LENGTH]; + HKEY hkey; + AXIS2_IMPORT extern axis2_char_t *axis2_request_url_prefix; + + rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_LOCATION, (DWORD) 0, KEY_READ, &hkey); + if (ERROR_SUCCESS != rc) + { + return AXIS2_FAILURE; + } + if (get_registry_config_parameter(hkey, AXIS2_IIS_REPO_PATH_TAG, tmpbuf, sizeof(repo_path))) + { + strcpy(repo_path, tmpbuf); + } + else + { + return AXIS2_FAILURE; + } + if (get_registry_config_parameter(hkey, AXIS2_IIS_LOG_FILE_TAG, tmpbuf, sizeof(log_file))) + { + strcpy(log_file, tmpbuf); + } + else + { + return AXIS2_FAILURE; + } + if (get_registry_config_parameter(hkey, AXIS2_IIS_LOG_LEVEL_TAG, tmpbuf, sizeof(tmpbuf))) + { + log_level = axis2_iis_parse_log_level(tmpbuf); + } + else + { + return AXIS2_FAILURE; + } + if (get_registry_config_parameter(hkey, AXIS2_IIS_SERVICE_URL_PREFIX, tmpbuf, sizeof(tmpbuf))) + { + axis2_request_url_prefix = _strdup(tmpbuf); + } + if (get_registry_config_parameter(hkey, AXIS2_IIS_AXIS2_LOCATION, tmpbuf, sizeof(tmpbuf))) + { + axis2_location = _strdup(tmpbuf); + } + RegCloseKey(hkey); + return ok; +} + +axutil_log_levels_t AXIS2_CALL +axis2_iis_parse_log_level(char level[]) +{ + if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_TRACE_VERB)) + { + return AXIS2_LOG_LEVEL_TRACE; + } + if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_DEBUG_VERB)) + { + return AXIS2_LOG_LEVEL_DEBUG; + } + if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_INFO_VERB)) + { + return AXIS2_LOG_LEVEL_INFO; + } + if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_USER_VERB)) + { + return AXIS2_LOG_LEVEL_USER; + } + if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_WARN_VERB)) + { + return AXIS2_LOG_LEVEL_WARNING; + } + if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_ERROR_VERB)) + { + return AXIS2_LOG_LEVEL_ERROR; + } + if (0 == AXIS2_STRICMP(level, AXIS2_IIS_LOG_CRITICAL_VERB)) + { + return AXIS2_LOG_LEVEL_CRITICAL; + } + return AXIS2_LOG_LEVEL_DEBUG; +} + +axis2_status_t AXIS2_CALL +get_registry_config_parameter(HKEY hkey, const char *tag, char *b, DWORD sz) +{ + DWORD type = 0; + LONG lrc; + + lrc = RegQueryValueEx(hkey, tag, (LPDWORD) 0, &type, (LPBYTE) b, &sz); + if ((ERROR_SUCCESS != lrc) || (type != REG_SZ)) + { + return FALSE; + } + b[sz] = '\0'; + return TRUE; +} + +/** + * This method initializes the axis2 engine. All the required variables are set to + * their initial values in this method. +*/ +axis2_status_t AXIS2_CALL init_axis2() +{ + /* + * These are the varibles required to initialize axis. + */ + axis2_status_t status = FALSE; + /* We need to init xml readers before we go into threaded env */ + if (!is_inited) + { + axiom_xml_reader_init(); + status = read_registery_init_data(); + if (status == AXIS2_FAILURE) + { + return AXIS2_FAILURE; + } + axutil_error_init(); + /* Initialize the environement */ + axutil_env = axutil_env_create_all(log_file, log_level); + if (!axutil_env) + { + return AXIS2_FAILURE; + } + axis2_worker = axis2_iis_worker_create(axutil_env, repo_path); + if (!axis2_worker) + { + return AXIS2_FAILURE; + } + is_inited = AXIS2_TRUE; + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} diff --git a/src/core/transport/http/server/IIS/iis_iaspi_plugin_51/axis2_isapi_51.c b/src/core/transport/http/server/IIS/iis_iaspi_plugin_51/axis2_isapi_51.c new file mode 100644 index 0000000..49cd6d9 --- /dev/null +++ b/src/core/transport/http/server/IIS/iis_iaspi_plugin_51/axis2_isapi_51.c @@ -0,0 +1,153 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <httpfilt.h>
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+
+#include "..\\axis2_iis_constants.h"
+
+#define REGISTRY_LOC "Software\\Apache Axis2c\\IIS ISAPI Redirector"
+#define AXIS2_IIS_AXIS2_LOC "axis2_location"
+static char *axis2_loc = "/axis2";
+
+static axis2_char_t redirect_word[INTERNET_MAX_URL_LENGTH] = "/axis2/mod_axis2_IIS.dll\?";
+/*
+ * Search a given uri to find weather it matches a uri for the axis2
+ * The uri format for axis2 is of the form
+ * scheme://server:port/axis2/other_parts
+ * This function search a give uri for the /axis2/. If a match
+ * is found it will replace the /axis2 part of the url with /axis2/mod_iis.dll?
+ */
+axis2_bool_t AXIS2_CALL
+get_extension_url(
+ char url[],
+ char ret_url[]);
+
+/*
+ * This function is called by the IIS server at the server
+ * initialization. So this is the ideal plcae for initializing
+ * axis2c.
+ */
+BOOL WINAPI
+GetFilterVersion(
+ PHTTP_FILTER_VERSION pVer)
+{
+ DWORD type = 0, size = 0;
+ LONG lrc = 0;
+ char tmpbuf[INTERNET_MAX_URL_LENGTH];
+ HKEY hkey;
+ ULONG http_filter_revision = HTTP_FILTER_REVISION;
+ pVer->dwFilterVersion = pVer->dwServerFilterVersion;
+ if(pVer->dwFilterVersion > http_filter_revision)
+ {
+ pVer->dwFilterVersion = http_filter_revision;
+ }
+
+ /*
+ Receive notifictions when
+ 1. Server preprocessed the headers.
+ 2. Log
+ 3. All the request coming in secure and none secure ports.
+ */
+ pVer->dwFlags = (SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_SECURE_PORT
+ | SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_AUTH_COMPLETE);
+
+ /* Give a short discription about the module.*/
+ strcpy(pVer->lpszFilterDesc, "axis2c filter");
+ /* Get the axis2 location from the registry configuration */
+ lrc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_LOC, (DWORD)0, KEY_READ, &hkey);
+ if(ERROR_SUCCESS != lrc)
+ {
+ return FALSE;
+ }
+ size = INTERNET_MAX_URL_LENGTH;
+ lrc = RegQueryValueEx(hkey, AXIS2_IIS_AXIS2_LOC, (LPDWORD)0, &type, (LPBYTE)tmpbuf, &size);
+ if((ERROR_SUCCESS == lrc) && (type == REG_SZ))
+ {
+ tmpbuf[size] = '\0';
+ axis2_loc = _strdup(tmpbuf);
+ }
+ RegCloseKey(hkey);
+ return TRUE;
+}
+
+/*
+ When a notification happens this function is called by the IIS.
+ */
+DWORD WINAPI
+HttpFilterProc(
+ PHTTP_FILTER_CONTEXT pfc,
+ DWORD notificationType,
+ LPVOID pvNotification)
+{
+ DWORD bufferLength = INTERNET_MAX_URL_LENGTH;
+ char url[INTERNET_MAX_URL_LENGTH];
+ char modified_url[INTERNET_MAX_URL_LENGTH];
+
+ if(notificationType == SF_NOTIFY_PREPROC_HEADERS)
+ {
+ pfc->GetServerVariable(pfc, "HTTP_URL", url, &bufferLength);
+ if(get_extension_url(url, modified_url))
+ {
+ ((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->SetHeader(pfc, "url", modified_url);
+ return SF_STATUS_REQ_HANDLED_NOTIFICATION;
+ }
+ }
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+}
+
+axis2_bool_t AXIS2_CALL
+get_extension_url(
+ char url[],
+ char ret_url[])
+{
+ axis2_bool_t is_for_us = AXIS2_FALSE;
+ int i = 0;
+ /* Should contain "/axis2/"*/
+ ret_url[0] = '\0';
+ if(strlen(url) >= strlen(axis2_loc))
+ {
+ is_for_us = AXIS2_TRUE;
+ while(axis2_loc[i] != '\0')
+ {
+ if(axis2_loc[i] != (url)[i])
+ {
+ is_for_us = AXIS2_FALSE;
+ break;
+ }
+ i++;
+ }
+ if(url[i] != '/' && url[i] != '\0')
+ {
+ is_for_us = AXIS2_FALSE;
+ }
+ }
+ if(is_for_us)
+ {
+ strcpy(ret_url, redirect_word);
+ strcat(ret_url, &url[i]);
+ }
+ return is_for_us;
+}
diff --git a/src/core/transport/http/server/IIS/mod_axis2.def b/src/core/transport/http/server/IIS/mod_axis2.def new file mode 100644 index 0000000..22205e7 --- /dev/null +++ b/src/core/transport/http/server/IIS/mod_axis2.def @@ -0,0 +1,7 @@ +LIBRARY "mod_axis2_IIS"
+
+EXPORTS
+ GetExtensionVersion
+ HttpExtensionProc
+ GetFilterVersion
+ HttpFilterProc
\ No newline at end of file diff --git a/src/core/transport/http/server/Makefile.am b/src/core/transport/http/server/Makefile.am new file mode 100644 index 0000000..07cf1e9 --- /dev/null +++ b/src/core/transport/http/server/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS=@APACHE2BUILD@ simple_axis2_server ${CGI_DIR} +EXTRA_DIST=IIS CGI diff --git a/src/core/transport/http/server/apache2/Makefile.am b/src/core/transport/http/server/apache2/Makefile.am new file mode 100644 index 0000000..d5f6bd8 --- /dev/null +++ b/src/core/transport/http/server/apache2/Makefile.am @@ -0,0 +1,40 @@ +lib_LTLIBRARIES = libmod_axis2.la +libmod_axis2_la_SOURCES = mod_axis2.c\ + apache2_stream.c\ + apache2_out_transport_info.c\ + apache2_worker.c + +AM_CFLAGS = -DLINUX=2 -D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE + +libmod_axis2_la_LIBADD = $(LDFLAGS) \ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la \ + $(top_builddir)/src/core/engine/libaxis2_engine.la\ + $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la\ + $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la\ + $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la\ + -lpthread + +libmod_axis2_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport/http \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/axiom/include\ + -I$(top_builddir)/util/include\ + @APACHE2INC@ \ + @APRINC@ + +EXTRA_DIST=axis2_apache2_worker.h apache2_stream.h axis2_apache2_out_transport_info.h + + + + + + + + diff --git a/src/core/transport/http/server/apache2/apache2_out_transport_info.c b/src/core/transport/http/server/apache2/apache2_out_transport_info.c new file mode 100644 index 0000000..9deaa56 --- /dev/null +++ b/src/core/transport/http/server/apache2/apache2_out_transport_info.c @@ -0,0 +1,191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "axis2_apache2_out_transport_info.h" +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> +#include <apr_strings.h> + +typedef struct axis2_apache2_out_transport_info +{ + axis2_http_out_transport_info_t out_transport_info; + request_rec *request; + axis2_char_t *encoding; +} axis2_apache2_out_transport_info_t; + +#define AXIS2_INTF_TO_IMPL(out_transport_info) \ + ((axis2_apache2_out_transport_info_t *)(out_transport_info)) + +void AXIS2_CALL +axis2_apache2_out_transport_info_free_void_arg( + void *transport_info, + const axutil_env_t * env) +{ + axis2_http_out_transport_info_t *transport_info_l = NULL; + + AXIS2_ENV_CHECK(env, void); + transport_info_l = (axis2_http_out_transport_info_t *)transport_info; + axis2_http_out_transport_info_free(transport_info_l, env); + return; +} + +axis2_status_t AXIS2_CALL +axis2_apache_out_transport_info_free( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env) +{ + axis2_apache2_out_transport_info_t *info = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + info = AXIS2_INTF_TO_IMPL(out_transport_info); + + info->request = NULL; /* request doesn't belong to info */ + if(info->encoding) + { + AXIS2_FREE(env->allocator, info->encoding); + info->encoding = NULL; + } + + AXIS2_FREE(env->allocator, info); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_apache_out_transport_info_set_content_type( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + axis2_apache2_out_transport_info_t *info = NULL; + + axis2_char_t *tmp1 = NULL; + axis2_char_t *tmp2 = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE); + info = AXIS2_INTF_TO_IMPL(out_transport_info); + + if(info->encoding) + { + + tmp1 = axutil_stracat(env, content_type, ";charset="); + tmp2 = axutil_stracat(env, tmp1, info->encoding); + info->request->content_type = apr_pstrdup(info->request->pool, tmp2); + AXIS2_FREE(env->allocator, tmp1); + AXIS2_FREE(env->allocator, tmp2); + } + else + { + info->request->content_type = apr_pstrdup(info->request->pool, content_type); + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_apache_out_transport_info_set_char_encoding( + axis2_http_out_transport_info_t * info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE); + + if(info->encoding) + { + AXIS2_FREE(env->allocator, info->encoding); + } + info->encoding = axutil_strdup(env, encoding); + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_apache_out_transport_info_set_cookie_header( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * cookie_header) +{ + axis2_apache2_out_transport_info_t *info = NULL; + + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, cookie_header, AXIS2_FAILURE); + info = AXIS2_INTF_TO_IMPL(out_transport_info); + + apr_table_set(info->request->headers_out, AXIS2_HTTP_HEADER_SET_COOKIE, cookie_header); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_apache_out_transport_info_set_session( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * session_id, + const axis2_char_t * session_value) +{ + axis2_apache2_out_transport_info_t *info = NULL; + axis2_status_t status = AXIS2_SUCCESS; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, session_id, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, session_value, AXIS2_FAILURE); + info = AXIS2_INTF_TO_IMPL(out_transport_info); + + status = env->set_session_fn(info->request, session_id, session_value); + + return status; +} + +axis2_http_out_transport_info_t *AXIS2_CALL +axis2_apache2_out_transport_info_create( + const axutil_env_t * env, + request_rec * request) +{ + axis2_apache2_out_transport_info_t *info = NULL; + axis2_http_out_transport_info_t *out_transport_info = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + info = (axis2_apache2_out_transport_info_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_apache2_out_transport_info_t)); + + if(!info) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + info->request = request; + info->encoding = NULL; + + out_transport_info = &(info->out_transport_info); + out_transport_info->encoding = NULL; + out_transport_info->response = NULL; + + axis2_http_out_transport_info_set_char_encoding_func(out_transport_info, env, + axis2_apache_out_transport_info_set_char_encoding); + axis2_http_out_transport_info_set_content_type_func(out_transport_info, env, + axis2_apache_out_transport_info_set_content_type); + axis2_http_out_transport_info_set_cookie_header_func(out_transport_info, env, + axis2_apache_out_transport_info_set_cookie_header); + axis2_http_out_transport_info_set_session_func(out_transport_info, env, + axis2_apache_out_transport_info_set_session); + + return out_transport_info; +} + + diff --git a/src/core/transport/http/server/apache2/apache2_stream.c b/src/core/transport/http/server/apache2/apache2_stream.c new file mode 100644 index 0000000..5e189a7 --- /dev/null +++ b/src/core/transport/http/server/apache2/apache2_stream.c @@ -0,0 +1,292 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <stdlib.h> +#include "apache2_stream.h" +#include <http_protocol.h> + +typedef struct apache2_stream_impl +{ + axutil_stream_t stream; + axutil_stream_type_t stream_type; + request_rec *request; +} apache2_stream_impl_t; + +#define AXIS2_INTF_TO_IMPL(stream) ((apache2_stream_impl_t *)(stream)) + +axutil_stream_type_t AXIS2_CALL +apache2_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env); + +int AXIS2_CALL apache2_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buffer, + size_t count); + +int AXIS2_CALL apache2_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count); + +static int AXIS2_CALL +apache2_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count); + +int AXIS2_CALL apache2_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env); + +static apr_size_t +apache2_ap_get_client_block( + request_rec *r, + char* buffer, + apr_size_t bufsiz); + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_apache2( + const axutil_env_t * env, + request_rec * request) +{ + apache2_stream_impl_t *stream_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, request, NULL); + + stream_impl = (apache2_stream_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(apache2_stream_impl_t)); + + if(!stream_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset(&(stream_impl->stream), 0, sizeof(axutil_stream_t)); + + stream_impl->request = request; + stream_impl->stream_type = AXIS2_STREAM_MANAGED; + + axutil_stream_set_read(&(stream_impl->stream), env, apache2_stream_read); + axutil_stream_set_write(&(stream_impl->stream), env, apache2_stream_write); + axutil_stream_set_skip(&(stream_impl->stream), env, apache2_stream_skip); + + return &(stream_impl->stream); +} + +int AXIS2_CALL +apache2_stream_read( + axutil_stream_t * stream, + const axutil_env_t * env, + void *buffer, + size_t count) +{ + apache2_stream_impl_t *stream_impl = NULL; + size_t read = 0; + size_t len = 0; + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + + stream_impl = AXIS2_INTF_TO_IMPL(stream); + + while(count - len > 0) + { + read = apache2_ap_get_client_block(stream_impl->request, (char *) buffer + len, + count - len); + if(read > 0) + { + len += read; + } + else + { + break; + } + } + + return (int)len; + /* We are sure that the difference lies within the int range */ +} + +int AXIS2_CALL +apache2_stream_write( + axutil_stream_t * stream, + const axutil_env_t * env, + const void *buf, + size_t count) +{ + apache2_stream_impl_t *stream_impl = NULL; + axis2_char_t *buffer = NULL; + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE); + stream_impl = AXIS2_INTF_TO_IMPL(stream); + buffer = (axis2_char_t *)buf; + if(count <= 0) + { + return (int)count; + /* We are sure that the difference lies within the int range */ + } + /* assume that buffer is not null terminated */ + return ap_rwrite(buffer, (int)count, stream_impl->request); + /* We are sure that the difference lies within the int range */ +} + +static int AXIS2_CALL +apache2_stream_skip( + axutil_stream_t * stream, + const axutil_env_t * env, + int count) +{ + apache2_stream_impl_t *stream_impl = NULL; + axis2_char_t *tmp_buffer = NULL; + apr_size_t len = -1; + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + stream_impl = AXIS2_INTF_TO_IMPL(stream); + + tmp_buffer = AXIS2_MALLOC(env->allocator, count * sizeof(axis2_char_t)); + if(tmp_buffer == NULL) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return -1; + } + len = apache2_ap_get_client_block(stream_impl->request, tmp_buffer, count); + AXIS2_FREE(env->allocator, tmp_buffer); + return (int)len; + +} + +int AXIS2_CALL +apache2_stream_get_char( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + int ret = -1; + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + + return ret; +} + +axutil_stream_type_t AXIS2_CALL +apache2_stream_get_type( + axutil_stream_t * stream, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + return AXIS2_INTF_TO_IMPL(stream)->stream_type; +} + +/* + * This is a re-write of get_client_block found in http_filters.c in httpd + * which does not work when dealing with compressed payloads (or any other input + * filters that could potentially return 0 bytes of filtered data and not be at + * the end of the stream). + * get_client_block is called in a loop to get the request message body. + * This is quite simple if the client includes a content-length + * (the normal case), but gets messy if the body is chunked. Note that + * r->remaining is used to maintain state across calls and that + * r->read_length is the total number of bytes given to the caller + * across all invocations. It is messy because we have to be careful not + * to read past the data provided by the client, since these reads block. + * Returns 0 on End-of-body, -1 on error or premature chunk end. + * + */ +static apr_size_t +apache2_ap_get_client_block( + request_rec *r, + char *buffer, + apr_size_t bufsiz) +{ + apr_status_t rv; + apr_bucket_brigade *bb; + int loop = 1; + apr_size_t origBufSize = bufsiz; + + if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) { + return 0; + } + + bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + if (bb == NULL) { + r->connection->keepalive = AP_CONN_CLOSE; + return -1; + } + + /* we need to loop until the input filters (if any) give us data */ + while (loop) { + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + APR_BLOCK_READ, bufsiz); + + /* We lose the failure code here. This is why ap_get_client_block should + * not be used. + */ + if (rv != APR_SUCCESS) { + /* if we actually fail here, we want to just return and + * stop trying to read data from the client. + */ + r->connection->keepalive = AP_CONN_CLOSE; + apr_brigade_destroy(bb); + return -1; + } + + /* If this fails, it means that a filter is written incorrectly and that + * it needs to learn how to properly handle APR_BLOCK_READ requests by + * returning data when requested. + */ + AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(bb)); + + /* Check to see if EOS in the brigade. + * + * If so, we have to leave a nugget for the *next* ap_get_client_block + * call to return 0. + */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { + if (r->read_chunked) { + r->remaining = -1; + } else { + r->remaining = 0; + } + } + + rv = apr_brigade_flatten(bb, buffer, &bufsiz); + if (rv != APR_SUCCESS) { + apr_brigade_destroy(bb); + return -1; + } + + /* XXX yank me? */ + r->read_length += bufsiz; + + /* it is possible that the entire bucket brigade is exhausted, but no data + * has been produced by the input filter (mod_deflate, for example).... + * in this scenario, we really need to keep looping + */ + if (bufsiz != 0 || r->remaining <= 0) { + loop = 0; + apr_brigade_destroy(bb); + } else { + if (bufsiz == 0) { + bufsiz = origBufSize; + } + } + + } + + return (long)bufsiz; +} diff --git a/src/core/transport/http/server/apache2/apache2_stream.h b/src/core/transport/http/server/apache2/apache2_stream.h new file mode 100644 index 0000000..abbea45 --- /dev/null +++ b/src/core/transport/http/server/apache2/apache2_stream.h @@ -0,0 +1,46 @@ + +/* + * Copyright 2004,2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain count copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE2_STREAM_H +#define APACHE2_STREAM_H + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_stream.h> +#include <httpd.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** \brief Constructor for creating apche2 stream + * @return axutil_stream (apache2) + */ + AXIS2_EXTERN axutil_stream_t *AXIS2_CALL + axutil_stream_create_apache2( + const axutil_env_t * env, + request_rec * req); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APACHE2_STREAM_H */ diff --git a/src/core/transport/http/server/apache2/apache2_worker.c b/src/core/transport/http/server/apache2/apache2_worker.c new file mode 100644 index 0000000..12b05b2 --- /dev/null +++ b/src/core/transport/http/server/apache2/apache2_worker.c @@ -0,0 +1,1687 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "axis2_apache2_worker.h"
+#include <axis2_http_transport.h>
+#include <axis2_conf.h>
+#include <axutil_string.h>
+#include <axis2_msg_ctx.h>
+#include <axis2_http_out_transport_info.h>
+#include <axis2_http_transport_utils.h>
+#include <axis2_http_accept_record.h>
+#include <axis2_op_ctx.h>
+#include <axis2_engine.h>
+#include <axutil_uuid_gen.h>
+#include <axis2_conf_init.h>
+#include "axis2_apache2_out_transport_info.h"
+#include <axutil_url.h>
+#include <http_core.h>
+#include <http_protocol.h>
+#include <axiom_soap.h>
+#include <axutil_class_loader.h>
+#include <axutil_string_util.h>
+#include <axiom_mime_part.h>
+#include <axiom_mtom_sending_callback.h>
+
+#define READ_SIZE 2048
+
+static axis2_status_t
+apache2_worker_send_mtom_message(
+ request_rec *request,
+ const axutil_env_t * env,
+ axutil_array_list_t *mime_parts,
+ axis2_char_t *mtom_sending_callback_name);
+
+static axis2_status_t
+apache2_worker_send_attachment_using_file(
+ const axutil_env_t * env,
+ request_rec *request,
+ FILE *fp,
+ axis2_byte_t *buffer,
+ int buffer_size);
+
+static axis2_status_t
+apache2_worker_send_attachment_using_callback(
+ const axutil_env_t * env,
+ request_rec *request,
+ axiom_mtom_sending_callback_t *callback,
+ void *handler,
+ void *user_param);
+
+static axutil_hash_t*
+axis2_apache_worker_get_headers(
+ const axutil_env_t *env,
+ request_rec *request);
+
+
+struct axis2_apache2_worker
+{
+ axis2_conf_ctx_t *conf_ctx;
+};
+
+AXIS2_EXTERN axis2_apache2_worker_t *AXIS2_CALL
+axis2_apache2_worker_create(
+ const axutil_env_t * env,
+ axis2_char_t * repo_path)
+{
+ axis2_apache2_worker_t *apache2_worker = NULL;
+ axutil_hash_t* svc_map = NULL;
+ axis2_conf_t* conf = NULL;
+ axutil_hash_index_t *hi = NULL;
+ void* svc = NULL;
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_LOG_INFO(env->log, "[Axis2] Axis2 worker created");
+ apache2_worker = (axis2_apache2_worker_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_apache2_worker_t));
+
+ if(!apache2_worker)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ apache2_worker->conf_ctx = axis2_build_conf_ctx(env, repo_path);
+
+ if(!apache2_worker->conf_ctx)
+ {
+ axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env);
+ return NULL;
+ }
+
+ /*
+ * we have to load all the services. This is because, before the fork (in linux)
+ * we should have a full code segment. Otherwise, we can't share function pointers of services
+ * between processed. In fork, the code segment will be duplicated across processes
+ */
+ conf = axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env);
+ if(!conf)
+ {
+ axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env);
+ return NULL;
+ }
+
+ svc_map = axis2_conf_get_all_svcs(conf, env);
+ if(!svc_map)
+ {
+ axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env);
+ return NULL;
+ }
+
+ for(hi = axutil_hash_first(svc_map, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ void *impl_class = NULL;
+ axis2_msg_recv_t *msg_recv = NULL;
+ axutil_hash_t *ops_hash = NULL;
+
+ axutil_hash_this(hi, NULL, NULL, &svc);
+ if(!svc)
+ continue;
+ impl_class = axis2_svc_get_impl_class(svc, env);
+ if(impl_class)
+ continue;
+ ops_hash = axis2_svc_get_all_ops(svc, env);
+ if(ops_hash)
+ {
+ axutil_hash_index_t *op_hi = NULL;
+ void *op = NULL;
+ op_hi = axutil_hash_first(ops_hash, env);
+ if(op_hi)
+ {
+ axutil_hash_this(op_hi, NULL, NULL, &op);
+ if(op)
+ {
+ msg_recv = axis2_op_get_msg_recv(op, env);
+ if(msg_recv)
+ {
+ axis2_msg_recv_set_conf_ctx(msg_recv, env, apache2_worker->conf_ctx);
+ axis2_msg_recv_load_and_init_svc(msg_recv, env, svc);
+ }
+ }
+ }
+
+ }
+ }
+
+ AXIS2_LOG_INFO(env->log, "[Axis2] Axis2 worker created");
+
+ return apache2_worker;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_apache2_worker_free(
+ axis2_apache2_worker_t * apache2_worker,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, void);
+
+ if(apache2_worker->conf_ctx)
+ {
+ axis2_conf_ctx_free(apache2_worker->conf_ctx, env);
+ apache2_worker->conf_ctx = NULL;
+ }
+
+ AXIS2_FREE(env->allocator, apache2_worker);
+
+ return;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_apache2_worker_process_request(
+ axis2_apache2_worker_t * apache2_worker,
+ const axutil_env_t * env,
+ request_rec * request)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axutil_stream_t *request_body = NULL;
+ axutil_stream_t *out_stream = NULL;
+ axis2_transport_out_desc_t *out_desc = NULL;
+ axis2_transport_in_desc_t *in_desc = NULL;
+ axis2_char_t *http_version = NULL;
+ axutil_string_t *soap_action = NULL;
+ axis2_char_t *soap_action_header_txt = NULL;
+ axis2_bool_t processed = AXIS2_FALSE;
+ int content_length = -1;
+ axis2_char_t *url_external_form = NULL;
+ axis2_char_t *body_string = NULL;
+ unsigned int body_string_len = 0;
+ int send_status = DECLINED;
+ axis2_char_t *content_type = NULL;
+ axis2_http_out_transport_info_t *apache2_out_transport_info = NULL;
+ axis2_char_t *ctx_uuid = NULL;
+ axis2_op_ctx_t *op_ctx = NULL;
+ axis2_char_t *peer_ip = NULL;
+ axutil_property_t *peer_property = NULL;
+ axutil_url_t *request_url = NULL;
+ axis2_char_t *accept_header_value = NULL;
+ axis2_char_t *accept_charset_header_value = NULL;
+ axis2_char_t *accept_language_header_value = NULL;
+ axis2_char_t *content_language_header_value = NULL;
+ axis2_bool_t do_mtom = AXIS2_FALSE;
+ axutil_array_list_t *mime_parts = NULL;
+ axutil_param_t *callback_name_param = NULL;
+ axis2_char_t *mtom_sending_callback_name = NULL;
+ axis2_char_t *cookie = NULL;
+ axis2_char_t *header_value = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_hash_t *headers = NULL;
+
+ AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, request, AXIS2_CRITICAL_FAILURE);
+
+ conf_ctx = apache2_worker->conf_ctx;
+
+ if(!conf_ctx)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE);
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ content_length = (int)request->remaining;
+ /* We are sure that the difference lies within the int range */
+ http_version = request->protocol;
+
+ request_url = axutil_url_create(env, "http", request->hostname, request->parsed_uri.port,
+ request->unparsed_uri);
+ if(request_url)
+ {
+ url_external_form = axutil_url_to_external_form(request_url, env);
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, url_external_form);
+ axutil_url_free(request_url, env);
+ request_url = NULL;
+ }
+ else
+ {
+ send_status = OK;
+ request->status = HTTP_BAD_REQUEST;
+ return send_status;
+ }
+
+ content_type = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if(!content_type)
+ {
+ content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN;
+ }
+ request->content_type = content_type;
+
+ out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env),
+ env, AXIS2_TRANSPORT_ENUM_HTTP);
+ in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env),
+ env, AXIS2_TRANSPORT_ENUM_HTTP);
+ {
+ axis2_transport_receiver_t *receiver = NULL;
+ receiver = axis2_transport_in_desc_get_recv(in_desc, env);
+ if(receiver)
+ axis2_transport_receiver_set_server_ip(receiver, env, request->connection->local_ip);
+ }
+
+ msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc);
+ axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+ cookie = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_COOKIE);
+ if(cookie)
+ {
+ char *session_str = NULL;
+ axis2_char_t *session_id = NULL;
+
+ session_id = axis2_http_transport_utils_get_session_id_from_cookie(env, cookie);
+ if(session_id)
+ session_str = env->get_session_fn((void *) request, session_id);
+ if(session_str)
+ axis2_http_transport_utils_set_session(env, msg_ctx, session_str);
+ }
+
+ if(request->read_chunked == AXIS2_TRUE && 0 == content_length)
+ {
+ content_length = -1;
+ request->chunked = 1;
+ }
+ if(!http_version)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE);
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ out_stream = axutil_stream_create_basic(env);
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Client HTTP version %s", http_version);
+
+ peer_ip = request->connection->remote_ip;
+
+ if(peer_ip)
+ {
+ peer_property = axutil_property_create(env);
+ axutil_property_set_value(peer_property, env, axutil_strdup(env, peer_ip));
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_SVR_PEER_IP_ADDR, peer_property);
+ }
+
+ axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream);
+
+ ctx_uuid = axutil_uuid_gen(env);
+ if(ctx_uuid)
+ {
+ axutil_string_t *uuid_str = axutil_string_create_assume_ownership(env, &ctx_uuid);
+ axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, uuid_str);
+ axutil_string_free(uuid_str, env);
+ }
+
+ apache2_out_transport_info = axis2_apache2_out_transport_info_create(env, request);
+ axis2_msg_ctx_set_out_transport_info(msg_ctx, env, &(apache2_out_transport_info->out_transport));
+
+ accept_header_value = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_ACCEPT);
+ if(accept_header_value)
+ {
+ axutil_array_list_t *accept_header_field_list = NULL;
+ axutil_array_list_t *accept_record_list = NULL;
+ accept_header_field_list = axutil_tokenize(env, accept_header_value, ',');
+ if(accept_header_field_list && axutil_array_list_size(accept_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_header_field_list, env, 0);
+ }
+ while(token);
+ }
+ if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0)
+ {
+ axis2_msg_ctx_set_http_accept_record_list(msg_ctx, env, accept_record_list);
+ }
+ }
+
+ accept_charset_header_value = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_ACCEPT_CHARSET);
+ if(accept_charset_header_value)
+ {
+ axutil_array_list_t *accept_charset_header_field_list = NULL;
+ axutil_array_list_t *accept_charset_record_list = NULL;
+ accept_charset_header_field_list = axutil_tokenize(env, accept_charset_header_value, ',');
+ if(accept_charset_header_field_list && axutil_array_list_size(
+ accept_charset_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_charset_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_charset_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_charset_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_charset_header_field_list,
+ env, 0);
+ }
+ while(token);
+ }
+ if(accept_charset_record_list && axutil_array_list_size(accept_charset_record_list, env)
+ > 0)
+ {
+ axis2_msg_ctx_set_http_accept_charset_record_list(msg_ctx, env,
+ accept_charset_record_list);
+ }
+ }
+
+ accept_language_header_value = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_ACCEPT_LANGUAGE);
+ if(accept_language_header_value)
+ {
+ axutil_array_list_t *accept_language_header_field_list = NULL;
+ axutil_array_list_t *accept_language_record_list = NULL;
+ accept_language_header_field_list = axutil_tokenize(env, accept_language_header_value, ',');
+ if(accept_language_header_field_list && axutil_array_list_size(
+ accept_language_header_field_list, env) > 0)
+ {
+ axis2_char_t *token = NULL;
+ accept_language_record_list = axutil_array_list_create(env, axutil_array_list_size(
+ accept_language_header_field_list, env));
+ do
+ {
+ if(token)
+ {
+ axis2_http_accept_record_t *rec = NULL;
+ rec = axis2_http_accept_record_create(env, token);
+ if(rec)
+ {
+ axutil_array_list_add(accept_language_record_list, env, rec);
+ }
+ AXIS2_FREE(env->allocator, token);
+ }
+ token = (axis2_char_t *)axutil_array_list_remove(accept_language_header_field_list,
+ env, 0);
+ }
+ while(token);
+ }
+ if(accept_language_record_list && axutil_array_list_size(accept_language_record_list, env)
+ > 0)
+ {
+ axis2_msg_ctx_set_http_accept_language_record_list(msg_ctx, env,
+ accept_language_record_list);
+ }
+ }
+
+ soap_action_header_txt = (axis2_char_t *)apr_table_get(request->headers_in,
+ AXIS2_HTTP_HEADER_SOAP_ACTION);
+
+ if(soap_action_header_txt)
+ {
+ soap_action = axutil_string_create(env, soap_action_header_txt);
+ }
+
+ headers = axis2_apache_worker_get_headers(env, request);
+ axis2_msg_ctx_set_transport_headers(msg_ctx, env, headers);
+
+ request_body = axutil_stream_create_apache2(env, request);
+ if(!request_body)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in"
+ " creating input stream.");
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ if(M_GET == request->method_number || M_DELETE == request->method_number)
+ {
+ if(M_DELETE == request->method_number)
+ {
+ processed = axis2_http_transport_utils_process_http_delete_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx,
+ axis2_http_transport_utils_get_request_params(env,
+ (axis2_char_t *)url_external_form));
+ }
+ else if(request->header_only)
+ {
+ processed = axis2_http_transport_utils_process_http_head_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx,
+ axis2_http_transport_utils_get_request_params(env,
+ (axis2_char_t *)url_external_form));
+ }
+ else
+ {
+ processed = axis2_http_transport_utils_process_http_get_request(env, msg_ctx,
+ request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx,
+ axis2_http_transport_utils_get_request_params(env,
+ (axis2_char_t *)url_external_form));
+ }
+ if(AXIS2_FALSE == processed)
+ {
+ axis2_char_t *wsdl = NULL;
+ axis2_bool_t is_services_path = AXIS2_FALSE;
+ if(M_DELETE != request->method_number)
+ {
+ axis2_char_t *temp = NULL;
+ temp = strstr(url_external_form, AXIS2_REQUEST_URL_PREFIX);
+ if(temp)
+ {
+ temp += strlen(AXIS2_REQUEST_URL_PREFIX);
+ if(*temp == '/')
+ {
+ temp++;
+ }
+ if(!*temp || *temp == '?' || *temp == '#')
+ {
+ is_services_path = AXIS2_TRUE;
+ }
+ }
+ }
+ wsdl = strstr(url_external_form, AXIS2_REQUEST_WSDL);
+ if(is_services_path)
+ {
+ body_string = axis2_http_transport_utils_get_services_html(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ }
+ else if(M_DELETE != request->method_number && wsdl)
+ {
+ body_string = axis2_http_transport_utils_get_services_static_wsdl(env, conf_ctx,
+ (axis2_char_t *)url_external_form);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
+
+ }
+ else if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND)
+ {
+ axutil_array_list_t *method_list = NULL;
+ int size = 0;
+ method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env);
+ size = axutil_array_list_size(method_list, env);
+ if(method_list && size)
+ {
+ axis2_char_t *method_list_str = NULL;
+ axis2_char_t *temp;
+ int i = 0;
+ method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29);
+ temp = method_list_str;
+ request->allowed_methods->method_mask = 0;
+ for(i = 0; i < size; i++)
+ {
+ if(i)
+ {
+ sprintf(temp, ", ");
+ temp += 2;
+ }
+ sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env,
+ i));
+ temp += strlen(temp);
+ /* Conditions below is to assist down-stream modules */
+ if(!strcasecmp(AXIS2_HTTP_PUT, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_PUT;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_POST, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_POST;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_GET, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_HEAD, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ /* Apache Can't differentiate between HEAD and GET */
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_DELETE,
+ (axis2_char_t *)axutil_array_list_get(method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_DELETE;
+ }
+ }
+ *temp = '\0';
+ apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_ALLOW,
+ method_list_str);
+ AXIS2_FREE(env->allocator, method_list_str);
+ body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx);
+ request->status = HTTP_METHOD_NOT_ALLOWED;
+ }
+ else
+ {
+ body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx);
+ request->status = HTTP_NOT_FOUND;
+ }
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_BAD_REQUEST;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_REQUEST_TIME_OUT;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_CONFLICT;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_gone(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_GONE;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_PRECONDITION_FAILED;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ }
+ else if(axis2_msg_ctx_get_status_code(msg_ctx, env)
+ == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL)
+ {
+ body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_SERVICE_UNAVAILABLE;
+ }
+ else
+ {
+ body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if(body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ }
+ }
+ else if(M_POST == request->method_number || M_PUT == request->method_number)
+ {
+ /*axis2_status_t status = AXIS2_FAILURE;*/
+ if(M_POST == request->method_number)
+ {
+ status = axis2_http_transport_utils_process_http_post_request(env, msg_ctx,
+ request_body, out_stream, content_type, content_length, soap_action,
+ (axis2_char_t *)url_external_form);
+ }
+ else
+ {
+ status = axis2_http_transport_utils_process_http_put_request(env, msg_ctx,
+ request_body, out_stream, content_type, content_length, soap_action,
+ (axis2_char_t *)url_external_form);
+ }
+ if(AXIS2_FAILURE == status && (M_PUT == request->method_number
+ || axis2_msg_ctx_get_doing_rest(msg_ctx, env)))
+ {
+ if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND)
+ {
+ axutil_array_list_t *method_list = NULL;
+ int size = 0;
+ method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env);
+ size = axutil_array_list_size(method_list, env);
+ if(method_list && size)
+ {
+ axis2_char_t *method_list_str = NULL;
+ axis2_char_t *temp;
+ int i = 0;
+ method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29);
+ temp = method_list_str;
+ request->allowed_methods->method_mask = 0;
+ for(i = 0; i < size; i++)
+ {
+ if(i)
+ {
+ sprintf(temp, ", ");
+ temp += 2;
+ }
+ sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env,
+ i));
+ temp += strlen(temp);
+ /* Conditions below is to assist down-stream modules */
+ if(!strcasecmp(AXIS2_HTTP_PUT, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_PUT;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_POST, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_POST;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_GET, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_HEAD, (axis2_char_t *)axutil_array_list_get(
+ method_list, env, i)))
+ {
+ /* Apache Can't differentiate between HEAD and GET */
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET;
+ }
+ else if(!strcasecmp(AXIS2_HTTP_DELETE,
+ (axis2_char_t *)axutil_array_list_get(method_list, env, i)))
+ {
+ request->allowed_methods->method_mask |= AP_METHOD_BIT << M_DELETE;
+ }
+ }
+ *temp = '\0';
+ apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_ALLOW,
+ method_list_str);
+ AXIS2_FREE(env->allocator, method_list_str);
+ body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx);
+ request->status = HTTP_METHOD_NOT_ALLOWED;
+ }
+ else
+ {
+ body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx);
+ request->status = HTTP_NOT_FOUND;
+ }
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ }
+ else
+ {
+ body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+ request->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if(body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ }
+ else if(status == AXIS2_FAILURE)
+ {
+ axis2_msg_ctx_t *fault_ctx = NULL;
+ axis2_char_t *fault_code = NULL;
+ axis2_engine_t *engine = axis2_engine_create(env, conf_ctx);
+ if(!engine)
+ {
+ /* Critical error, cannot proceed, Apache will send default
+ document for 500
+ */
+ return AXIS2_CRITICAL_FAILURE;
+ }
+ if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":"
+ AXIOM_SOAP11_FAULT_CODE_SENDER;
+ }
+ else
+ {
+ fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":"
+ AXIOM_SOAP12_SOAP_FAULT_VALUE_SENDER;
+ }
+ fault_ctx = axis2_engine_create_fault_msg_ctx(engine, env, msg_ctx,
+ fault_code,
+ axutil_error_get_message
+ (env->error));
+ axis2_engine_send_fault(engine, env, fault_ctx);
+ if (out_stream)
+ {
+ body_string = axutil_stream_get_buffer(out_stream, env);
+ body_string_len = axutil_stream_get_len(out_stream, env);
+ }
+
+ /* In case of a SOAP Fault, we have to set the status to 500,
+ but still return OK because the module has handled the error
+ */
+ send_status = OK;
+ request->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ else
+ {
+ body_string =
+ axis2_http_transport_utils_get_not_implemented(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ request->status = HTTP_NOT_IMPLEMENTED;
+ }
+
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+
+ if (op_ctx)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ if (out_msg_ctx)
+ {
+ content_language_header_value = axis2_msg_ctx_get_content_language(out_msg_ctx, env);
+ }
+ }
+
+ if (send_status == DECLINED)
+ {
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ if (M_POST != request->method_number ||
+ axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ do_rest = AXIS2_TRUE;
+ }
+ if ((accept_header_value || accept_charset_header_value ||
+ accept_language_header_value) && do_rest)
+ {
+ axis2_char_t *content_type_header_value = NULL;
+ axis2_char_t *temp = NULL;
+ axis2_char_t *language_header_value = NULL;
+
+ content_type_header_value = (axis2_char_t *) request->content_type;
+ language_header_value = content_language_header_value;
+ if (content_type_header_value)
+ {
+ temp = axutil_strdup(env, content_type_header_value);
+ }
+ if (temp)
+ {
+ axis2_char_t *content_type = NULL;
+ axis2_char_t *char_set = NULL;
+ axis2_char_t *temp2 = NULL;
+
+ temp2 = strchr(temp, ';');
+ if (temp2)
+ {
+ *temp2 = '\0';
+ temp2++;
+ char_set = axutil_strcasestr(temp2, AXIS2_HTTP_CHAR_SET_ENCODING);
+ }
+ if (char_set)
+ {
+ char_set = axutil_strltrim(env, char_set, " \t=");
+ }
+ if (char_set)
+ {
+ temp2 = strchr(char_set, ';');
+ }
+ if (temp2)
+ {
+ *temp2 = '\0';
+ }
+ content_type = axutil_strtrim(env, temp, NULL);
+
+ if (temp)
+ {
+ AXIS2_FREE(env->allocator, temp);
+ temp = NULL;
+ }
+ if (content_type && accept_header_value &&
+ !axutil_strcasestr(accept_header_value, content_type))
+ {
+ temp2 = strchr(content_type, '/');
+ if (temp2)
+ {
+ *temp2 = '\0';
+ temp = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * ((int)strlen(content_type) + 3));
+ if (!temp)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return AXIS2_FALSE;
+ }
+ sprintf(temp, "%s/*", content_type);
+ if (!axutil_strcasestr(accept_header_value, temp) &&
+ !strstr(accept_header_value, AXIS2_HTTP_HEADER_ACCEPT_ALL))
+ {
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ request->status = HTTP_NOT_ACCEPTABLE;
+ }
+ AXIS2_FREE(env->allocator, temp);
+ }
+ }
+ if (content_type)
+ {
+ AXIS2_FREE(env->allocator, content_type);
+ }
+ if (char_set && accept_charset_header_value &&
+ !axutil_strcasestr(accept_charset_header_value, char_set))
+ {
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ request->status = HTTP_NOT_ACCEPTABLE;
+ }
+ if (char_set)
+ {
+ AXIS2_FREE(env->allocator, char_set);
+ }
+ }
+ if (language_header_value)
+ {
+ if (accept_language_header_value &&
+ !axutil_strcasestr(accept_language_header_value, language_header_value))
+ {
+ body_string =
+ axis2_http_transport_utils_get_not_acceptable(env, conf_ctx);
+ request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML;
+
+ if (body_string)
+ {
+ body_string_len = axutil_strlen(body_string);
+ }
+ send_status = OK;
+ request->status = HTTP_NOT_ACCEPTABLE;
+ }
+ }
+ }
+ }
+
+ header_value = axis2_http_transport_utils_get_session(env, msg_ctx);
+ if(header_value)
+ {
+ axis2_http_out_transport_info_t *out_info = NULL;
+ out_info = (axis2_http_out_transport_info_t *)axis2_msg_ctx_get_out_transport_info(msg_ctx, env);
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_COOKIE_HEADER(out_info, env, header_value);
+ }
+ if (send_status == DECLINED)
+ {
+ axis2_bool_t do_rest = AXIS2_FALSE;
+ if (M_POST != request->method_number ||
+ axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ do_rest = AXIS2_TRUE;
+ }
+ if (op_ctx && axis2_op_ctx_get_response_written(op_ctx, env))
+ {
+ if (do_rest)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+ if (in_msg_ctx)
+ {
+ /* TODO: Add necessary handling */
+ }
+ if (out_msg_ctx)
+ {
+ int size = 0;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list, env);
+ }
+ while (size)
+ {
+ axis2_http_header_t *output_header = NULL;
+ size--;
+ output_header = (axis2_http_header_t *)
+ axutil_array_list_get(output_header_list, env, size);
+ apr_table_set(request->err_headers_out,
+ axis2_http_header_get_name(output_header, env),
+ axis2_http_header_get_value(output_header, env));
+ }
+ if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ request->status = HTTP_CONTINUE;
+ break;
+ case AXIS2_HTTP_RESPONSE_ACK_CODE_VAL:
+ request->status = HTTP_ACCEPTED;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ request->status = HTTP_MULTIPLE_CHOICES;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ request->status = HTTP_MOVED_PERMANENTLY;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ request->status = HTTP_SEE_OTHER;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ request->status = HTTP_NOT_MODIFIED;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ request->status = HTTP_TEMPORARY_REDIRECT;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ request->status = HTTP_BAD_REQUEST;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ request->status = HTTP_REQUEST_TIME_OUT;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ request->status = HTTP_CONFLICT;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ request->status = HTTP_GONE;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ request->status = HTTP_PRECONDITION_FAILED;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ request->status = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ request->status = HTTP_SERVICE_UNAVAILABLE;
+ break;
+ default:
+ request->status = HTTP_OK;
+ break;
+ }
+ send_status = DONE;
+ }
+ }
+ }
+ if (send_status == DECLINED)
+ {
+ send_status = OK;
+ if (out_stream)
+ {
+ body_string = axutil_stream_get_buffer(out_stream, env);
+ body_string_len = axutil_stream_get_len(out_stream, env);
+ }
+ }
+ }
+ else if (op_ctx)
+ {
+ if (do_rest)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL;
+ axis2_msg_ctx_t *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+ if (in_msg_ctx)
+ {
+ /* TODO: Add necessary handling */
+ }
+ if (out_msg_ctx)
+ {
+ int size = 0;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list, env);
+ }
+ while (size)
+ {
+ axis2_http_header_t *output_header = NULL;
+ size--;
+ output_header = (axis2_http_header_t *)
+ axutil_array_list_get(output_header_list, env, size);
+ apr_table_set(request->err_headers_out,
+ axis2_http_header_get_name(output_header, env),
+ axis2_http_header_get_value(output_header, env));
+ }
+ if (axis2_msg_ctx_get_no_content(out_msg_ctx, env))
+ {
+ if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL:
+ request->status = HTTP_RESET_CONTENT;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ request->status = HTTP_NOT_MODIFIED;
+ break;
+ default:
+ request->status = HTTP_NO_CONTENT;
+ break;
+ }
+ }
+ else
+ {
+ request->status = HTTP_NO_CONTENT;
+ }
+ send_status = DONE;
+ }
+ else if (axis2_msg_ctx_get_status_code(out_msg_ctx, env))
+ {
+ int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ request->status = HTTP_CONTINUE;
+ break;
+ case AXIS2_HTTP_RESPONSE_OK_CODE_VAL:
+ request->status = HTTP_OK;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ request->status = HTTP_MULTIPLE_CHOICES;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ request->status = HTTP_MOVED_PERMANENTLY;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ request->status = HTTP_SEE_OTHER;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ request->status = HTTP_NOT_MODIFIED;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ request->status = HTTP_TEMPORARY_REDIRECT;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ request->status = HTTP_BAD_REQUEST;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ request->status = HTTP_REQUEST_TIME_OUT;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ request->status = HTTP_CONFLICT;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ request->status = HTTP_GONE;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ request->status = HTTP_PRECONDITION_FAILED;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ request->status = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ request->status = HTTP_SERVICE_UNAVAILABLE;
+ break;
+ default:
+ request->status = HTTP_ACCEPTED;
+ break;
+ }
+ send_status = DONE;
+ }
+ }
+ }
+ if (send_status == DECLINED)
+ {
+ if (msg_ctx)
+ {
+ int size = 0;
+ int status_code;
+ axutil_array_list_t *output_header_list = NULL;
+ output_header_list = axis2_msg_ctx_get_http_output_headers(msg_ctx, env);
+ if (output_header_list)
+ {
+ size = axutil_array_list_size(output_header_list, env);
+ }
+ while (size)
+ {
+ axis2_http_header_t *output_header = NULL;
+ size--;
+ output_header = (axis2_http_header_t *)
+ axutil_array_list_get(output_header_list, env, size);
+ apr_table_set(request->err_headers_out,
+ axis2_http_header_get_name(output_header, env),
+ axis2_http_header_get_value(output_header, env));
+ }
+
+ status_code = axis2_msg_ctx_get_status_code(msg_ctx, env);
+ switch (status_code)
+ {
+ case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL:
+ request->status = HTTP_CONTINUE;
+ break;
+ case AXIS2_HTTP_RESPONSE_OK_CODE_VAL:
+ request->status = HTTP_OK;
+ break;
+ case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL:
+ request->status = HTTP_MULTIPLE_CHOICES;
+ break;
+ case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL:
+ request->status = HTTP_MOVED_PERMANENTLY;
+ break;
+ case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL:
+ request->status = HTTP_SEE_OTHER;
+ break;
+ case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL:
+ request->status = HTTP_NOT_MODIFIED;
+ break;
+ case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL:
+ request->status = HTTP_TEMPORARY_REDIRECT;
+ break;
+ case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL:
+ request->status = HTTP_BAD_REQUEST;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL:
+ request->status = HTTP_REQUEST_TIME_OUT;
+ break;
+ case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL:
+ request->status = HTTP_CONFLICT;
+ break;
+ case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL:
+ request->status = HTTP_GONE;
+ break;
+ case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL:
+ request->status = HTTP_PRECONDITION_FAILED;
+ break;
+ case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL:
+ request->status = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ break;
+ case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL:
+ request->status = HTTP_SERVICE_UNAVAILABLE;
+ break;
+ case AXIS2_HTTP_RESPONSE_FORBIDDEN_CODE_VAL:
+ request->status = HTTP_FORBIDDEN;
+ break;
+ case AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL:
+ request->status = HTTP_UNAUTHORIZED;
+ break;
+ default:
+ request->status = HTTP_ACCEPTED;
+ break;
+ }
+
+ out_stream = axis2_msg_ctx_get_transport_out_stream(msg_ctx, env);
+ if (out_stream)
+ {
+ body_string = axutil_stream_get_buffer(out_stream, env);
+ body_string_len = axutil_stream_get_len(out_stream, env);
+ }
+ send_status = DONE;
+ }
+ else
+ {
+ request->status = HTTP_ACCEPTED;
+ send_status = DONE;
+ }
+ }
+ }
+ else
+ {
+ send_status = DONE;
+ request->status = HTTP_ACCEPTED;
+ }
+ }
+
+ if (content_language_header_value)
+ {
+ apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_CONTENT_LANGUAGE,
+ content_language_header_value);
+ }
+
+ if (op_ctx)
+ {
+ axis2_msg_ctx_t *out_msg_ctx = NULL,
+ *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+ axis2_char_t *msg_id = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env);
+
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+
+ /* In mtom case we send the attachment differently */
+
+ /* status = AXIS2_FAILURE means fault scenario. We are not
+ * doing MTOM for fault cases. */
+
+ if(status != AXIS2_FAILURE)
+ {
+ do_mtom = axis2_msg_ctx_get_doing_mtom(out_msg_ctx, env);
+ if(do_mtom)
+ {
+ mime_parts = axis2_msg_ctx_get_mime_parts(out_msg_ctx, env);
+ if(!mime_parts)
+ {
+ return AXIS2_FAILURE;
+ }
+ callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env ,
+ AXIS2_MTOM_SENDING_CALLBACK);
+ if(callback_name_param)
+ {
+ mtom_sending_callback_name =
+ (axis2_char_t *) axutil_param_get_value (callback_name_param, env);
+ }
+ }
+ }
+
+ if (out_msg_ctx)
+ {
+ axis2_msg_ctx_free(out_msg_ctx, env);
+ out_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
+ }
+
+ if (in_msg_ctx)
+ {
+ msg_id =
+ axutil_strdup(env, axis2_msg_ctx_get_msg_id(in_msg_ctx, env));
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(in_msg_ctx, env);
+ axis2_msg_ctx_reset_out_transport_info(in_msg_ctx, env);
+ axis2_msg_ctx_free(in_msg_ctx, env);
+ in_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL;
+ }
+
+ if (!axis2_op_ctx_is_in_use(op_ctx, env))
+ {
+ axis2_op_ctx_destroy_mutex(op_ctx, env);
+ if (conf_ctx && msg_id)
+ {
+ axis2_conf_ctx_register_op_ctx(conf_ctx, env, msg_id, NULL);
+ AXIS2_FREE(env->allocator, msg_id);
+ }
+ axis2_op_ctx_free(op_ctx, env);
+ }
+
+ } /* Done freeing message contexts */
+
+ /* We send the message in parts when doing MTOM */
+
+ if(do_mtom)
+ {
+ axis2_status_t mtom_status = AXIS2_FAILURE;
+
+ if(!mtom_sending_callback_name)
+ {
+ /* If the callback name is not there, then we will check whether there
+ * is any mime_parts which has type callback. If we found then no point
+ * of continuing we should return a failure */
+
+ if(!mtom_sending_callback_name)
+ {
+ if(axis2_http_transport_utils_is_callback_required(
+ env, mime_parts))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Sender callback not specified");
+ return AXIS2_FAILURE;
+ }
+ }
+ }
+
+ mtom_status = apache2_worker_send_mtom_message(request, env, mime_parts,
+ mtom_sending_callback_name);
+ if(mtom_status == AXIS2_SUCCESS)
+ {
+ send_status = DONE;
+ }
+ else
+ {
+ send_status = DECLINED;
+ }
+
+ axis2_http_transport_utils_destroy_mime_parts(mime_parts, env);
+ mime_parts = NULL;
+ }
+
+ else if (body_string)
+ {
+ ap_rwrite(body_string, body_string_len, request);
+ body_string = NULL;
+ }
+
+ if (request_body)
+ {
+ axutil_stream_free(request_body, env);
+ request_body = NULL;
+ }
+
+ axutil_string_free(soap_action, env);
+
+ msg_ctx = NULL;
+ return send_status;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_apache2_worker_get_bytes(
+ const axutil_env_t * env,
+ axutil_stream_t * stream)
+{
+
+ axutil_stream_t *tmp_stream = NULL;
+ int return_size = -1;
+ axis2_char_t *buffer = NULL;
+ axis2_bool_t loop_status = AXIS2_TRUE;
+
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, stream, NULL);
+
+ tmp_stream = axutil_stream_create_basic(env);
+ while(loop_status)
+ {
+ int read = 0;
+ int write = 0;
+
+ char buf[READ_SIZE];
+ read = axutil_stream_read(stream, env, buf, READ_SIZE);
+ if(read < 0)
+ {
+ break;
+ }
+ write = axutil_stream_write(tmp_stream, env, buf, read);
+ if(read < (READ_SIZE - 1))
+ {
+ break;
+ }
+ }
+ return_size = axutil_stream_get_len(tmp_stream, env);
+
+ if(return_size > 0)
+ {
+ buffer = (char *)AXIS2_MALLOC(env->allocator, sizeof(char) * (return_size + 2));
+ return_size = axutil_stream_read(tmp_stream, env, buffer, return_size + 1);
+ buffer[return_size + 1] = '\0';
+ }
+ axutil_stream_free(tmp_stream, env);
+ return buffer;
+}
+
+static axis2_status_t
+apache2_worker_send_mtom_message(
+ request_rec *request,
+ const axutil_env_t * env,
+ axutil_array_list_t *mime_parts,
+ axis2_char_t *mtom_sending_callback_name)
+{
+ int i = 0;
+ axiom_mime_part_t *mime_part = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+ /*int written = 0;*/
+ int len = 0;
+
+ if(mime_parts)
+ {
+ for(i = 0; i < axutil_array_list_size(mime_parts, env); i++)
+ {
+ mime_part = (axiom_mime_part_t *)axutil_array_list_get(mime_parts, env, i);
+ if((mime_part->type) == AXIOM_MIME_PART_BUFFER)
+ {
+ len = 0;
+ len = ap_rwrite(mime_part->part, (int)mime_part->part_size, request);
+ ap_rflush(request);
+ if(len == -1)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ }
+ else if((mime_part->type) == AXIOM_MIME_PART_FILE)
+ {
+ FILE *f = NULL;
+ axis2_byte_t *output_buffer = NULL;
+ int output_buffer_size = 0;
+
+ f = fopen(mime_part->file_name, "rb");
+ if(!f)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error opening file %s for reading",
+ mime_part->file_name);
+ return AXIS2_FAILURE;
+ }
+ if(mime_part->part_size > AXIS2_MTOM_OUTPUT_BUFFER_SIZE)
+ {
+ output_buffer_size = AXIS2_MTOM_OUTPUT_BUFFER_SIZE;
+ }
+ else
+ {
+ output_buffer_size = (int)mime_part->part_size;
+ }
+
+ output_buffer = AXIS2_MALLOC(env->allocator, (output_buffer_size + 1)
+ * sizeof(axis2_char_t));
+
+ status = apache2_worker_send_attachment_using_file(env, request, f, output_buffer,
+ output_buffer_size);
+ if(status == AXIS2_FAILURE)
+ {
+ return status;
+ }
+ }
+ else if((mime_part->type) == AXIOM_MIME_PART_CALLBACK)
+ {
+ void *handler = NULL;
+ axiom_mtom_sending_callback_t *callback = NULL;
+
+ handler = axis2_http_transport_utils_initiate_callback(env,
+ mtom_sending_callback_name, mime_part->user_param, &callback);
+
+ if(handler)
+ {
+ status = apache2_worker_send_attachment_using_callback(env, request, callback,
+ handler, mime_part->user_param);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MTOM Sending Callback loading failed");
+ status = AXIS2_FAILURE;
+ }
+ if(callback)
+ {
+ axutil_param_t *param = NULL;
+
+ param = callback->param;
+
+ AXIOM_MTOM_SENDING_CALLBACK_FREE(callback, env);
+ callback = NULL;
+
+ if(param)
+ {
+ axutil_param_free(param, env);
+ param = NULL;
+ }
+
+ }
+
+ if(status == AXIS2_FAILURE)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ if(status == AXIS2_FAILURE)
+ {
+ break;
+ }
+ }
+ return status;
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+}
+
+static axis2_status_t
+apache2_worker_send_attachment_using_file(
+ const axutil_env_t * env,
+ request_rec *request,
+ FILE *fp,
+ axis2_byte_t *buffer,
+ int buffer_size)
+{
+
+ int count = 0;
+ int len = 0;
+ /*int written = 0;*/
+ axis2_status_t status = AXIS2_SUCCESS;
+
+ do
+ {
+ count = (int)fread(buffer, 1, buffer_size + 1, fp);
+ if(ferror(fp))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in reading file containg the attachment");
+ if(buffer)
+ {
+ AXIS2_FREE(env->allocator, buffer);
+ buffer = NULL;
+ }
+ fclose(fp);
+ return AXIS2_FAILURE;
+ }
+
+ if(count > 0)
+ {
+ len = 0;
+ len = ap_rwrite(buffer, count, request);
+ ap_rflush(request);
+ if(len == -1)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ }
+ else
+ {
+ if(buffer)
+ {
+ AXIS2_FREE(env->allocator, buffer);
+ buffer = NULL;
+ }
+ fclose(fp);
+ return AXIS2_FAILURE;
+ }
+ memset(buffer, 0, buffer_size);
+ if(status == AXIS2_FAILURE)
+ {
+ if(buffer)
+ {
+ AXIS2_FREE(env->allocator, buffer);
+ buffer = NULL;
+ }
+ fclose(fp);
+ return AXIS2_FAILURE;
+ }
+ }
+ while(!feof(fp));
+
+ fclose(fp);
+ AXIS2_FREE(env->allocator, buffer);
+ buffer = NULL;
+ return AXIS2_SUCCESS;
+}
+
+static axis2_status_t
+apache2_worker_send_attachment_using_callback(
+ const axutil_env_t * env,
+ request_rec *request,
+ axiom_mtom_sending_callback_t *callback,
+ void *handler,
+ void *user_param)
+{
+ int count = 0;
+ int len = 0;
+ axis2_status_t status = AXIS2_SUCCESS;
+ axis2_char_t *buffer = NULL;
+
+ /* Keep on loading the data in a loop until
+ * all the data is sent */
+
+ while((count = AXIOM_MTOM_SENDING_CALLBACK_LOAD_DATA(callback, env, handler, &buffer)) > 0)
+ {
+ len = 0;
+ len = ap_rwrite(buffer, count, request);
+ ap_rflush(request);
+ if(len == -1)
+ {
+ status = AXIS2_FAILURE;
+ break;
+ }
+ }
+
+ if(status == AXIS2_FAILURE)
+ {
+ AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, handler);
+ return status;
+ }
+
+ status = AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, handler);
+ return status;
+}
+
+
+static axutil_hash_t*
+axis2_apache_worker_get_headers(
+ const axutil_env_t *env,
+ request_rec *request)
+{
+ int i = 0;
+ axutil_hash_t *header_map = NULL;
+ const apr_array_header_t *tarr;
+ const apr_table_entry_t *telts;
+ axis2_http_header_t * tmp_http_header = NULL;
+
+
+ header_map = axutil_hash_make(env);
+ tarr = apr_table_elts(request->headers_in);
+ telts = (const apr_table_entry_t*)tarr->elts;
+
+ for (i = 0; i < tarr->nelts; i++)
+ {
+ axis2_char_t* tmp_key = (axis2_char_t*) telts[i].key;
+ axis2_char_t* tmp_value = (axis2_char_t*) telts[i].val;
+ tmp_http_header = axis2_http_header_create(env, tmp_key, tmp_value);
+ axutil_hash_set(header_map, tmp_key, AXIS2_HASH_KEY_STRING, tmp_http_header);
+ }
+
+ return header_map;
+
+
+}
diff --git a/src/core/transport/http/server/apache2/axis2_apache2_out_transport_info.h b/src/core/transport/http/server/apache2/axis2_apache2_out_transport_info.h new file mode 100644 index 0000000..9ab9250 --- /dev/null +++ b/src/core/transport/http/server/apache2/axis2_apache2_out_transport_info.h @@ -0,0 +1,61 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_APACHE2_OUT_TRANSPORT_INFO_H +#define AXIS2_APACHE2_OUT_TRANSPORT_INFO_H + +/** + * @ingroup axis2_core_transport_http + * @{ + */ + +/** + * @file axis2_apache2_out_transport_info.h + * @brief axis2 Apache2 Out Transport Info + */ + +#include <axis2_http_out_transport_info.h> +#include <httpd.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + AXIS2_EXTERN axis2_http_out_transport_info_t *AXIS2_CALL + + axis2_apache2_out_transport_info_create( + const axutil_env_t * env, + request_rec * r); + + /** + * Free http_out_transport_info passed as void pointer. This will be + * cast into appropriate type and then pass the cast object + * into the http_out_transport_info structure's free method + */ + AXIS2_EXTERN void AXIS2_CALL + + axis2_apache2_out_transport_info_free_void_arg( + void *transport_info, + const axutil_env_t * env); + + /** @} */ +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_APACHE2_OUT_TRANSPORT_INFO_H */ diff --git a/src/core/transport/http/server/apache2/axis2_apache2_worker.h b/src/core/transport/http/server/apache2/axis2_apache2_worker.h new file mode 100644 index 0000000..eea4033 --- /dev/null +++ b/src/core/transport/http/server/apache2/axis2_apache2_worker.h @@ -0,0 +1,78 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AXIS2_APACHE2_WORKER_H +#define AXIS2_APACHE2_WORKER_H + +/** + * @brief Apache2 Worker ops struct + * Encapsulator struct for ops of axis2_apache2_worker + */ + +/** + * @ingroup axis2_core_transport_http + * @{ + */ + +/** + * @file axis2_apache2_worker.h + * @brief axis2 Apache2 Worker + */ + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axis2_conf_ctx.h> +#include "apache2_stream.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct axis2_apache2_worker axis2_apache2_worker_t; + + AXIS2_EXTERN int AXIS2_CALL + axis2_apache2_worker_process_request( + axis2_apache2_worker_t * apache2_worker, + const axutil_env_t * env, + request_rec * r); + + AXIS2_EXTERN void AXIS2_CALL + axis2_apache2_worker_free( + axis2_apache2_worker_t * apache2_worker, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_apache2_worker_t *AXIS2_CALL + + axis2_apache2_worker_create( + const axutil_env_t * env, + axis2_char_t * repo_path); + +#define AXIS2_APACHE2_WORKER_PROCESS_REQUEST(apache2_worker, env, request) \ + axis2_apache2_worker_process_request(\ + apache2_worker, env, request) +#define AXIS2_APACHE2_WORKER_FREE(apache2_worker, env) \ + axis2_apache2_worker_free(apache2_worker, env) + + /** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_APACHE2_WORKER_H */ diff --git a/src/core/transport/http/server/apache2/mod_axis2.c b/src/core/transport/http/server/apache2/mod_axis2.c new file mode 100644 index 0000000..a9431eb --- /dev/null +++ b/src/core/transport/http/server/apache2/mod_axis2.c @@ -0,0 +1,844 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <httpd.h> +#include <http_config.h> +#include <http_log.h> +#include <http_protocol.h> +#include <ap_config.h> +#include <apr_strings.h> +#include "axis2_apache2_worker.h" +#include <axutil_error_default.h> +#include <axutil_log_default.h> +#include <axutil_thread_pool.h> +#include <axiom_xml_reader.h> +#include <axutil_version.h> +#include <apr_rmm.h> +#include <apr_shm.h> +#include <apr_dbd.h> +#include <mod_dbd.h> +#include <axis2_http_transport.h> +#include <axutil_types.h> + +/* Configuration structure populated by apache2.conf */ +typedef struct axis2_config_rec +{ + char *axutil_log_file; + char *axis2_repo_path; + axutil_log_levels_t log_level; + int max_log_file_size; + int axis2_global_pool_size; +} axis2_config_rec_t; + +axis2_apache2_worker_t *axis2_worker = NULL; +axutil_env_t *axutil_env = NULL; +apr_rmm_t* rmm = NULL; +apr_global_mutex_t *global_mutex = NULL; + +/******************************Function Headers********************************/ +static void * +axis2_create_svr( + apr_pool_t * p, + server_rec * s); + +static const char * +axis2_set_repo_path( + cmd_parms * cmd, + void *dummy, + const char *arg); + +static const char * +axis2_set_log_file( + cmd_parms * cmd, + void *dummy, + const char *arg); + +static const char * +axis2_set_max_log_file_size( + cmd_parms * cmd, + void *dummy, + const char *arg); + +static const char * +axis2_set_global_pool_size( + cmd_parms * cmd, + void * dummy, + const char *arg); + +static const char * +axis2_set_log_level( + cmd_parms * cmd, + void *dummy, + const char *arg); + +static const char * +axis2_set_svc_url_prefix( + cmd_parms * cmd, + void *dummy, + const char *arg); + +static int +axis2_handler( + request_rec * req); + +/* Shutdown Axis2 */ +apr_status_t +axis2_shutdown( + void *tmp); + +void *AXIS2_CALL axis2_module_malloc( + axutil_allocator_t * allocator, + size_t size); + +void *AXIS2_CALL axis2_module_realloc( + axutil_allocator_t * allocator, + void *ptr, + size_t size); + +void AXIS2_CALL axis2_module_free( + axutil_allocator_t * allocator, + void *ptr); + +static void +axis2_module_init( + apr_pool_t * p, + server_rec * svr_rec); + +static void +axis2_register_hooks( + apr_pool_t * p); + +char * +axis2_get_session( + void *req, + const char *id); + +axis2_status_t +axis2_set_session( + void *req, + const char *id, + const char *session); + +/***************************End of Function Headers****************************/ + +static const command_rec axis2_cmds[] = { AP_INIT_TAKE1("Axis2RepoPath", axis2_set_repo_path, NULL, + RSRC_CONF, "Axis2/C repository path"), AP_INIT_TAKE1("Axis2LogFile", axis2_set_log_file, NULL, + RSRC_CONF, "Axis2/C log file name"), AP_INIT_TAKE1("Axis2LogLevel", axis2_set_log_level, NULL, + RSRC_CONF, "Axis2/C log level"), AP_INIT_TAKE1("Axis2MaxLogFileSize", + axis2_set_max_log_file_size, NULL, RSRC_CONF, "Axis2/C maximum log file size"), + AP_INIT_TAKE1("Axis2GlobalPoolSize", axis2_set_global_pool_size, NULL, RSRC_CONF, + "Axis2/C global pool size"), AP_INIT_TAKE1("Axis2ServiceURLPrefix", + axis2_set_svc_url_prefix, NULL, RSRC_CONF, "Axis2/C service URL prifix"), + { NULL } }; + +/* Dispatch list for API hooks */ +module AP_MODULE_DECLARE_DATA axis2_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + axis2_create_svr, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + axis2_cmds, /* table of config file commands */ + axis2_register_hooks /* register hooks */ + }; + +static void * +axis2_create_svr( + apr_pool_t * p, + server_rec * s) +{ + axis2_config_rec_t *conf = apr_palloc(p, sizeof(*conf)); + conf->axutil_log_file = NULL; + conf->axis2_repo_path = NULL; + conf->log_level = AXIS2_LOG_LEVEL_DEBUG; + conf->axis2_global_pool_size = 0; + conf->max_log_file_size = 1; + return conf; +} + +static const char * +axis2_set_repo_path( + cmd_parms * cmd, + void *dummy, + const char *arg) +{ + axis2_config_rec_t *conf = NULL; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if(err != NULL) + { + return err; + } + conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module); + conf->axis2_repo_path = apr_pstrdup(cmd->pool, arg); + return NULL; +} + +static const char * +axis2_set_log_file( + cmd_parms * cmd, + void *dummy, + const char *arg) +{ + axis2_config_rec_t *conf = NULL; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if(err != NULL) + { + return err; + } + + conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module); + conf->axutil_log_file = apr_pstrdup(cmd->pool, arg); + return NULL; +} + +static const char * +axis2_set_max_log_file_size( + cmd_parms * cmd, + void *dummy, + const char *arg) +{ + axis2_config_rec_t *conf = NULL; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if(err != NULL) + { + return err; + } + + conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module); + conf->max_log_file_size = 1024 * 1024 * atoi(arg); + return NULL; +} + +static const char * +axis2_set_global_pool_size( + cmd_parms * cmd, + void *dummy, + const char *arg) +{ + axis2_config_rec_t *conf = NULL; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if(err != NULL) + { + return err; + } + + conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module); + conf->axis2_global_pool_size = 1024 * 1024 * atoi(arg); + return NULL; +} + +static const char * +axis2_set_log_level( + cmd_parms * cmd, + void *dummy, + const char *arg) +{ + char *str; + axutil_log_levels_t level = AXIS2_LOG_LEVEL_DEBUG; + axis2_config_rec_t *conf = NULL; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if(err != NULL) + { + return err; + } + + conf = (axis2_config_rec_t *)ap_get_module_config(cmd->server->module_config, &axis2_module); + + str = ap_getword_conf(cmd->pool, &arg); + if(str) + { + if(!strcasecmp(str, "crit")) + { + level = AXIS2_LOG_LEVEL_CRITICAL; + } + else if(!strcasecmp(str, "error")) + { + level = AXIS2_LOG_LEVEL_ERROR; + } + else if(!strcasecmp(str, "warn")) + { + level = AXIS2_LOG_LEVEL_WARNING; + } + else if(!strcasecmp(str, "info")) + { + level = AXIS2_LOG_LEVEL_INFO; + } + else if(!strcasecmp(str, "debug")) + { + level = AXIS2_LOG_LEVEL_DEBUG; + } + else if(!strcasecmp(str, "user")) + { + level = AXIS2_LOG_LEVEL_USER; + } + else if(!strcasecmp(str, "trace")) + { + level = AXIS2_LOG_LEVEL_TRACE; + } + } + conf->log_level = level; + return NULL; +} + +static const char * +axis2_set_svc_url_prefix( + cmd_parms * cmd, + void *dummy, + const char *arg) +{ + AXIS2_IMPORT extern axis2_char_t *axis2_request_url_prefix; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + axis2_request_url_prefix = AXIS2_REQUEST_URL_PREFIX; + if(!err) + { + axis2_char_t *prefix = apr_pstrdup(cmd->pool, arg); + if(prefix) + axis2_request_url_prefix = prefix; + } + + return NULL; +} + +/* The sample content handler */ +static int +axis2_handler( + request_rec * req) +{ + int rv = 0; + axutil_env_t *thread_env = NULL; + axutil_allocator_t *allocator = NULL; + axutil_error_t *error = NULL; + + apr_allocator_t *local_allocator = NULL; + apr_pool_t *local_pool = NULL; + + if(strcmp(req->handler, "axis2_module")) + { + return DECLINED; + } + + /* Set up the read policy from the client. */ + if((rv = ap_setup_client_block(req, REQUEST_CHUNKED_DECHUNK)) != OK) + { + return rv; + } + ap_should_client_block(req); + + apr_allocator_create(&local_allocator); + apr_pool_create_ex(&local_pool, NULL, NULL, local_allocator); + + /*thread_env = axutil_init_thread_env(axutil_env);*/ + + /*axutil_env->allocator->current_pool = (void *) req->pool; + rv = AXIS2_APACHE2_WORKER_PROCESS_REQUEST(axis2_worker, axutil_env, req);*/ + + /* create new allocator for this request */ + /*allocator = (axutil_allocator_t *) apr_palloc(req->pool, + sizeof(axutil_allocator_t));*/ + + allocator = (axutil_allocator_t *)apr_palloc(local_pool, sizeof(axutil_allocator_t)); + + if(!allocator) + { + return HTTP_INTERNAL_SERVER_ERROR; + } + allocator->malloc_fn = axis2_module_malloc; + allocator->realloc = axis2_module_realloc; + allocator->free_fn = axis2_module_free; + allocator->global_pool_ref = 0; + allocator->local_pool = (void *)local_pool; + allocator->current_pool = (void *)local_pool; + allocator->global_pool = axutil_env->allocator->global_pool; + + error = axutil_error_create(allocator); + thread_env = axutil_env_create_with_error_log_thread_pool(allocator, error, axutil_env->log, + axutil_env-> thread_pool); + thread_env->allocator = allocator; + thread_env->set_session_fn = axis2_set_session; + thread_env->get_session_fn = axis2_get_session; + + rv = AXIS2_APACHE2_WORKER_PROCESS_REQUEST(axis2_worker, thread_env, req); + if(AXIS2_CRITICAL_FAILURE == rv) + { + return HTTP_INTERNAL_SERVER_ERROR; + } + + apr_pool_destroy(local_pool); + apr_allocator_destroy(local_allocator); + + return rv; +} + +void *AXIS2_CALL +axis2_module_malloc( + axutil_allocator_t * allocator, + size_t size) +{ +#if APR_HAS_SHARED_MEMORY + if (rmm == allocator->current_pool) + { + + void* ptr = NULL; + apr_rmm_off_t offset; + apr_global_mutex_lock(global_mutex); + offset = apr_rmm_malloc(rmm, size); + if (offset) + ptr = apr_rmm_addr_get(rmm, offset); + apr_global_mutex_unlock(global_mutex); + return ptr; + } +#endif + return apr_palloc((apr_pool_t *)(allocator->current_pool), size); +} + +void *AXIS2_CALL +axis2_module_realloc( + axutil_allocator_t * allocator, + void *ptr, + size_t size) +{ +#if APR_HAS_SHARED_MEMORY + if (rmm == allocator->current_pool) + { + void* ptr = NULL; + apr_rmm_off_t offset; + apr_global_mutex_lock(global_mutex); + offset = apr_rmm_realloc(rmm, ptr, size); + if (offset) + ptr = apr_rmm_addr_get(rmm, offset); + apr_global_mutex_unlock(global_mutex); + return ptr; + } +#endif + /* can't be easily implemented */ + return NULL; +} + +void AXIS2_CALL +axis2_module_free( + axutil_allocator_t * allocator, + void *ptr) +{ +#if APR_HAS_SHARED_MEMORY + if (rmm == allocator->current_pool) + { + apr_rmm_off_t offset; + apr_global_mutex_lock(global_mutex); + offset = apr_rmm_offset_get(rmm, ptr); + apr_rmm_free(rmm, offset); + apr_global_mutex_unlock(global_mutex); + } +#endif +} + +static int +axis2_post_config( + apr_pool_t *pconf, + apr_pool_t *plog, + apr_pool_t *ptemp, + server_rec *svr_rec) +{ + apr_status_t status = APR_SUCCESS; + axutil_allocator_t *allocator = NULL; + axutil_error_t *error = NULL; + axutil_log_t *axutil_logger = NULL; + axutil_thread_pool_t *thread_pool = NULL; + void *data = NULL; + const char *userdata_key = "axis2_init"; + axis2_config_rec_t *conf = (axis2_config_rec_t *)ap_get_module_config(svr_rec->module_config, + &axis2_module); + + /* axis2_post_config() will be called twice. Don't bother + * going through all of the initialization on the first call + * because it will just be thrown away.*/ + + ap_add_version_component(pconf, AXIS2_HTTP_HEADER_SERVER_AXIS2C); + + apr_pool_userdata_get(&data, userdata_key, svr_rec->process->pool); + if(!data) + { + apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null, + svr_rec->process->pool); + return OK; + } + +#if APR_HAS_SHARED_MEMORY + if (conf->axis2_global_pool_size > 0) + { + apr_shm_t *shm; + apr_rmm_off_t offset; + + status = apr_shm_create(&shm, conf->axis2_global_pool_size, NULL, pconf); + if (status != APR_SUCCESS) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec, + "[Axis2] Error creating shared memory pool"); + exit(APEXIT_INIT); + } + + status = apr_rmm_init(&rmm, NULL, apr_shm_baseaddr_get(shm), conf->axis2_global_pool_size, + pconf); + if (status != APR_SUCCESS) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec, + "[Axis2] Error creating relocatable memory pool"); + exit(APEXIT_INIT); + } + + status = apr_global_mutex_create(&global_mutex, NULL, + APR_LOCK_DEFAULT, pconf); + if (status != APR_SUCCESS) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec, + "[Axis2] Error creating global mutex"); + exit(APEXIT_INIT); + } + + /*status = unixd_set_global_mutex_perms(global_mutex); + if (status != APR_SUCCESS) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec, + "[Axis2] Permision cannot be set to global mutex"); + exit(APEXIT_INIT); + } + */ + + offset = apr_rmm_malloc(rmm, sizeof(axutil_allocator_t)); + if (!offset) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec, + "[Axis2] Error in creating allocator in global pool"); + exit(APEXIT_INIT); + } + allocator = apr_rmm_addr_get(rmm, offset); + allocator->malloc_fn = axis2_module_malloc; + allocator->realloc = axis2_module_realloc; + allocator->free_fn = axis2_module_free; + allocator->global_pool_ref = 0; + allocator->local_pool = (void *) rmm; + allocator->current_pool = (void *) rmm; + allocator->global_pool = (void *) rmm; + + /* We need to init xml readers before we go into threaded env + */ + axiom_xml_reader_init(); + axutil_error_init(); + + error = axutil_error_create(allocator); + if (!error) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error creating mod_axis2 error structure"); + exit(APEXIT_CHILDFATAL); + } + + axutil_logger = axutil_log_create(allocator, NULL, conf->axutil_log_file); + if (!axutil_logger) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error creating mod_axis2 log structure"); + exit(APEXIT_CHILDFATAL); + } + thread_pool = axutil_thread_pool_init(allocator); + if (!thread_pool) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error initializing mod_axis2 thread pool"); + exit(APEXIT_CHILDFATAL); + } + axutil_env = axutil_env_create_with_error_log_thread_pool(allocator, error, + axutil_logger, + thread_pool); + if (!axutil_env) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error creating mod_axis2 environment"); + exit(APEXIT_CHILDFATAL); + } + if (axutil_logger) + { + axutil_logger->level = conf->log_level; + axutil_logger->size = conf->max_log_file_size; + AXIS2_LOG_INFO(axutil_env->log, "Apache Axis2/C version in use : %s", + axis2_version_string()); + AXIS2_LOG_INFO(axutil_env->log, + "Starting log with log level %d and max log file size %d", + conf->log_level, conf->max_log_file_size); + } + axutil_env->set_session_fn = axis2_set_session; + axutil_env->get_session_fn = axis2_get_session; + + axis2_worker = axis2_apache2_worker_create(axutil_env, + conf->axis2_repo_path); + if (!axis2_worker) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error creating mod_axis2 apache2 worker"); + exit(APEXIT_CHILDFATAL); + } + } + +#endif + + return OK; +} + +static void +axis2_module_init( + apr_pool_t * p, + server_rec * svr_rec) +{ + apr_pool_t *pool; + apr_status_t status; + axutil_allocator_t *allocator = NULL; + axutil_error_t *error = NULL; + axutil_log_t *axutil_logger = NULL; + axutil_thread_pool_t *thread_pool = NULL; + axis2_config_rec_t *conf = (axis2_config_rec_t*)ap_get_module_config(svr_rec->module_config, + &axis2_module); + + if(conf->axis2_global_pool_size > 0) + { + /* + If we are using shared memory, no need to init the child, as the + worker has been created in post config. + */ + return; + } + + /* We need to init xml readers before we go into threaded env + */ + axiom_xml_reader_init(); + + /* create an allocator that uses APR memory pools and lasts the + * lifetime of the httpd server child process + */ + status = apr_pool_create(&pool, p); + if(status) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, status, svr_rec, + "[Axis2] Error allocating mod_axis2 memory pool"); + exit(APEXIT_CHILDFATAL); + } + allocator = (axutil_allocator_t*)apr_palloc(pool, sizeof(axutil_allocator_t)); + if(!allocator) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_ENOMEM, svr_rec, + "[Axis2] Error allocating mod_axis2 allocator"); + exit(APEXIT_CHILDFATAL); + } + allocator->malloc_fn = axis2_module_malloc; + allocator->realloc = axis2_module_realloc; + allocator->free_fn = axis2_module_free; + allocator->global_pool_ref = 0; + allocator->local_pool = (void*)pool; + allocator->current_pool = (void*)pool; + allocator->global_pool = (void*)pool; + + if(!allocator) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error initializing mod_axis2 allocator"); + exit(APEXIT_CHILDFATAL); + } + + axutil_error_init(); + + error = axutil_error_create(allocator); + if(!error) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error creating mod_axis2 error structure"); + exit(APEXIT_CHILDFATAL); + } + axutil_logger = axutil_log_create(allocator, NULL, conf->axutil_log_file); + if(!axutil_logger) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error creating mod_axis2 log structure"); + exit(APEXIT_CHILDFATAL); + } + thread_pool = axutil_thread_pool_init(allocator); + if(!thread_pool) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error initializing mod_axis2 thread pool"); + exit(APEXIT_CHILDFATAL); + } + axutil_env = axutil_env_create_with_error_log_thread_pool(allocator, error, axutil_logger, + thread_pool); + if(!axutil_env) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error creating mod_axis2 environment"); + exit(APEXIT_CHILDFATAL); + } + if(axutil_logger) + { + + axutil_logger->level = conf->log_level; + AXIS2_LOG_INFO(axutil_env->log, "Apache Axis2/C version in use : %s", + axis2_version_string()); + AXIS2_LOG_INFO(axutil_env->log, "Starting log with log level %d", conf->log_level); + } + axutil_env->set_session_fn = axis2_set_session; + axutil_env->get_session_fn = axis2_get_session; + axis2_worker = axis2_apache2_worker_create(axutil_env, conf->axis2_repo_path); + if(!axis2_worker) + { + ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, svr_rec, + "[Axis2] Error creating mod_axis2 apache2 worker"); + exit(APEXIT_CHILDFATAL); + } + + /*ap_dbd_prepare(svr_rec, "SELECT value FROM session WHERE id = %s", "retrieve_session"); + ap_dbd_prepare(svr_rec, "INSERT INTO session VALUES(?,?)", "insert_session");*/ + + + /* If we are initialized we register a clean up as well */ + /* apr_pool_cleanup_register(p, NULL, axis2_shutdown, apr_pool_cleanup_null);*/ +} + +static void +axis2_register_hooks( + apr_pool_t * p) +{ + ap_hook_post_config(axis2_post_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_handler(axis2_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_child_init(axis2_module_init, NULL, NULL, APR_HOOK_MIDDLE); +} + +apr_status_t +axis2_shutdown( + void *tmp) +{ + if(axis2_worker) + { + axis2_apache2_worker_free(axis2_worker, axutil_env); + } + return APR_SUCCESS; +} + +char * +axis2_get_session( + void *req, + const char *id) +{ + request_rec *request = NULL; + apr_status_t rv; + const char *dbd_session = NULL; + apr_dbd_prepared_t *statement; + apr_dbd_results_t *res = NULL; + apr_dbd_row_t *row = NULL; + ap_dbd_t *dbd = NULL; + ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL; + request = (request_rec *) req; + + authn_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire); + dbd = authn_dbd_acquire_fn(request); + if (!dbd) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, + "Failed to acquire database connection to look up " + "id '%s'", id); + return NULL; + } + + statement = apr_hash_get(dbd->prepared, "retrieve_session", APR_HASH_KEY_STRING); + if (!statement) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, + "A prepared statement could not be found for " + "the key '%s'", "retrieve_session"); + return NULL; + } + if (apr_dbd_pvselect(dbd->driver, request->pool, dbd->handle, &res, statement, + 0, id, NULL) != 0) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, + "Query execution error looking up '%s' " + "in database", id); + return NULL; + } + for (rv = apr_dbd_get_row(dbd->driver, request->pool, res, &row, -1); rv != -1; + rv = apr_dbd_get_row(dbd->driver, request->pool, res, &row, -1)) + { + if (rv != 0) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, request, + "Error retrieving results while looking up '%s' " + "in database", id); + return NULL; + } + if (!dbd_session) + { + dbd_session = apr_dbd_get_entry(dbd->driver, row, 0); + } + /* we can't break out here or row won't get cleaned up */ + } + + if (!dbd_session) + { + return NULL; + } + + return (char *) dbd_session; +} + +axis2_status_t +axis2_set_session( + void *req, + const char *id, + const char *session) +{ + request_rec *request = NULL; + apr_dbd_prepared_t *statement; + int affected_rows = -1; + ap_dbd_t *dbd = NULL; + ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL; + request = (request_rec *) req; + + authn_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire); + dbd = authn_dbd_acquire_fn(request); + if (!dbd) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, + "Failed to acquire database connection to insert session for " + "id '%s'", id); + return AXIS2_FAILURE; + } + + statement = apr_hash_get(dbd->prepared, "insert_session", APR_HASH_KEY_STRING); + if (!statement) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, + "A prepared statement could not be found for " + "the key '%s'", "insert_session"); + return AXIS2_FAILURE; + } + if (apr_dbd_pvquery(dbd->driver, request->pool, dbd->handle, &affected_rows, statement, id, + session, NULL) != 0) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, request, + "Query execution error inserting session for '%s' " + "in database", id); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + + diff --git a/src/core/transport/http/server/simple_axis2_server/Makefile.am b/src/core/transport/http/server/simple_axis2_server/Makefile.am new file mode 100644 index 0000000..604851d --- /dev/null +++ b/src/core/transport/http/server/simple_axis2_server/Makefile.am @@ -0,0 +1,30 @@ +prgbindir=$(bindir) +prgbin_PROGRAMS = axis2_http_server +SUBDIRS = +AM_CFLAGS = -g -pthread +axis2_http_server_SOURCES = http_server_main.c + +axis2_http_server_LDADD = $(LDFLAGS) \ + $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la \ + $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la \ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la \ + $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la \ + $(top_builddir)/src/core/description/libaxis2_description.la \ + $(top_builddir)/src/core/deployment/libaxis2_deployment.la \ + $(top_builddir)/src/core/context/libaxis2_context.la \ + $(top_builddir)/src/core/clientapi/libaxis2_clientapi.la \ + $(top_builddir)/src/core/engine/libaxis2_engine.la \ + $(top_builddir)/src/core/transport/http/sender/libaxis2_http_sender.la \ + $(top_builddir)/src/core/transport/http/receiver/libaxis2_http_receiver.la \ + $(top_builddir)/neethi/src/libneethi.la \ + -lpthread + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/description\ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/deployment\ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/http/server/simple_axis2_server/http_server_main.c b/src/core/transport/http/server/simple_axis2_server/http_server_main.c new file mode 100644 index 0000000..cfbcda4 --- /dev/null +++ b/src/core/transport/http/server/simple_axis2_server/http_server_main.c @@ -0,0 +1,310 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_server.h> +#include <axis2_http_transport.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <stdio.h> +#include <stdlib.h> +#include <axutil_error_default.h> +#include <axutil_log_default.h> +#include <axutil_thread_pool.h> +#include <signal.h> +#include <axutil_types.h> +#include <ctype.h> +#include <axiom_xml_reader.h> +#include <axutil_version.h> +#include <axutil_file_handler.h> + +axutil_env_t *system_env = NULL; +axis2_transport_receiver_t *server = NULL; +AXIS2_IMPORT extern int axis2_http_socket_read_timeout; +AXIS2_IMPORT extern axis2_char_t *axis2_request_url_prefix; + +#define DEFAULT_REPO_PATH "../" + +/***************************** Function headers *******************************/ +axutil_env_t * +init_syetem_env( + axutil_allocator_t * allocator, + const axis2_char_t * log_file); + +void +system_exit( + axutil_env_t * env, + int status); + +void +usage( + axis2_char_t * prog_name); + +void +sig_handler( + int signal); + +/***************************** End of function headers ************************/ +axutil_env_t * +init_syetem_env( + axutil_allocator_t * allocator, + const axis2_char_t * log_file) +{ + axutil_error_t *error = axutil_error_create(allocator); + axutil_log_t *log = axutil_log_create(allocator, NULL, log_file); + /* if (!log) */ + + /* log = axutil_log_create_default (allocator); */ + axutil_thread_pool_t *thread_pool = axutil_thread_pool_init(allocator); + /* We need to init the parser in main thread before spawning child + * threads + */ + axiom_xml_reader_init(); + return axutil_env_create_with_error_log_thread_pool(allocator, error, log, thread_pool); +} + +void +system_exit( + axutil_env_t * env, + int status) +{ + axutil_allocator_t *allocator = NULL; + if(server) + { + axis2_transport_receiver_free(server, system_env); + } + if(env) + { + allocator = env->allocator; + axutil_env_free(env); + } + /*axutil_allocator_free(allocator); */ + axiom_xml_reader_cleanup(); + exit(status); +} + +int +main( + int argc, + char *argv[]) +{ + axutil_allocator_t *allocator = NULL; + axutil_env_t *env = NULL; + extern char *optarg; + extern int optopt; + int c; + unsigned int len; + int log_file_size = AXUTIL_LOG_FILE_SIZE; + unsigned int file_flag = 0; + axutil_log_levels_t log_level = AXIS2_LOG_LEVEL_DEBUG; + const axis2_char_t *log_file = "axis2.log"; + const axis2_char_t *repo_path = DEFAULT_REPO_PATH; + int port = 9090; + axis2_status_t status; + + /* Set the service URL prefix to be used. This could default to services if not + set with AXIS2_REQUEST_URL_PREFIX macro at compile time */ + axis2_request_url_prefix = AXIS2_REQUEST_URL_PREFIX; + + while((c = AXIS2_GETOPT(argc, argv, ":p:r:ht:l:s:f:")) != -1) + { + + switch(c) + { + case 'p': + port = AXIS2_ATOI(optarg); + break; + case 'r': + repo_path = optarg; + break; + case 't': + axis2_http_socket_read_timeout = AXIS2_ATOI(optarg) * 1000; + break; + case 'l': + log_level = AXIS2_ATOI(optarg); + if(log_level < AXIS2_LOG_LEVEL_CRITICAL) + log_level = AXIS2_LOG_LEVEL_CRITICAL; + if(log_level > AXIS2_LOG_LEVEL_TRACE) + log_level = AXIS2_LOG_LEVEL_TRACE; + break; + case 's': + log_file_size = 1024 * 1024 * AXIS2_ATOI(optarg); + break; + case 'f': + log_file = optarg; + break; + case 'h': + usage(argv[0]); + return 0; + case ':': + fprintf(stderr, "\nOption -%c requires an operand\n", optopt); + usage(argv[0]); + return -1; + case '?': + if(isprint(optopt)) + fprintf(stderr, "\nUnknown option `-%c'.\n", optopt); + usage(argv[0]); + return -1; + } + } + + allocator = axutil_allocator_init(NULL); + + if(!allocator) + { + system_exit(NULL, -1); + } + + env = init_syetem_env(allocator, log_file); + env->log->level = log_level; + env->log->size = log_file_size; + + axutil_error_init(); + system_env = env; + + signal(SIGINT, sig_handler); +#ifndef WIN32 + signal(SIGPIPE, sig_handler); +#endif + + AXIS2_LOG_INFO(env->log, "Starting Axis2 HTTP server...."); + AXIS2_LOG_INFO(env->log, "Apache Axis2/C version in use : %s", axis2_version_string()); + AXIS2_LOG_INFO(env->log, "Server port : %d", port); + AXIS2_LOG_INFO(env->log, "Repo location : %s", repo_path); + AXIS2_LOG_INFO(env->log, "Read Timeout : %d ms", axis2_http_socket_read_timeout); + + status = axutil_file_handler_access(repo_path, AXIS2_R_OK); + if(status == AXIS2_SUCCESS) + { + len = (unsigned int)strlen(repo_path); + /* We are sure that the difference lies within the unsigned int range */ + if((len >= 9) && !strcmp((repo_path + (len - 9)), "axis2.xml")) + { + file_flag = 1; + } + } + else + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "provided repo path %s does " + "not exist or no permissions to read, set " + "repo_path to DEFAULT_REPO_PATH", repo_path); + repo_path = DEFAULT_REPO_PATH; + } + + if(!file_flag) + server = axis2_http_server_create(env, repo_path, port); + else + server = axis2_http_server_create_with_file(env, repo_path, port); + + if(!server) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Server creation failed: Error code:" " %d :: %s", + env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error)); + system_exit(env, -1); + + } + printf("Started Simple Axis2 HTTP Server ...\n"); + if(axis2_transport_receiver_start(server, env) == AXIS2_FAILURE) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Server start failed: Error code:" " %d :: %s", + env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error)); + system_exit(env, -1); + } + return 0; +} + +void +usage( + axis2_char_t * prog_name) +{ + fprintf(stdout, "\n Usage : %s", prog_name); + fprintf(stdout, " [-p PORT]"); + fprintf(stdout, " [-t TIMEOUT]"); + fprintf(stdout, " [-r REPO_PATH]"); + fprintf(stdout, " [-l LOG_LEVEL]"); + fprintf(stdout, " [-f LOG_FILE]\n"); + fprintf(stdout, " [-s LOG_FILE_SIZE]\n"); + fprintf(stdout, " Options :\n"); + fprintf(stdout, "\t-p PORT \t port number to use, default port is 9090\n"); + fprintf(stdout, "\t-r REPO_PATH \t repository path, default is ../\n"); + fprintf(stdout, "\t-t TIMEOUT\t socket read timeout, default is 30 seconds\n"); + fprintf(stdout, "\t-l LOG_LEVEL\t log level, available log levels:" + "\n\t\t\t 0 - critical 1 - errors 2 - warnings" + "\n\t\t\t 3 - information 4 - debug 5- user 6- trace" + "\n\t\t\t Default log level is 4(debug).\n"); +#ifndef WIN32 + fprintf(stdout, "\t-f LOG_FILE\t log file, default is $AXIS2C_HOME/logs/axis2.log" + "\n\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n"); +#else + fprintf(stdout, + "\t-f LOG_FILE\t log file, default is %%AXIS2C_HOME%%\\logs\\axis2.log" + "\n\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n"); +#endif + fprintf(stdout, + "\t-s LOG_FILE_SIZE\t Maximum log file size in mega bytes, default maximum size is 1MB.\n"); + fprintf(stdout, " Help :\n\t-h \t display this help screen.\n\n"); +} + +/** + * Signal handler + */ +void +sig_handler( + int signal) +{ + + if(!system_env) + { + AXIS2_LOG_ERROR( + system_env->log, + AXIS2_LOG_SI, + "Received signal %d, unable to proceed system_env is NULL ,\ + system exit with -1", + signal); + _exit(-1); + } + + switch(signal) + { + case SIGINT: + { + /* Use of SIGINT in Windows is valid, since we have a console application + * Thus, eventhough this may a single threaded application, it does work. + */ + AXIS2_LOG_INFO(system_env->log, "Received signal SIGINT. Server " + "shutting down"); + if(server) + { + axis2_http_server_stop(server, system_env); + } + + AXIS2_LOG_INFO(system_env->log, "Shutdown complete ..."); + system_exit(system_env, 0); + } +#ifndef WIN32 + case SIGPIPE: + { + AXIS2_LOG_INFO(system_env->log, "Received signal SIGPIPE. Client " + "request serve aborted"); + return; + } +#endif + case SIGSEGV: + { + fprintf(stderr, "Received deadly signal SIGSEGV. Terminating\n"); + _exit(-1); + } + } +} diff --git a/src/core/transport/http/util/Makefile.am b/src/core/transport/http/util/Makefile.am new file mode 100644 index 0000000..eff6c0e --- /dev/null +++ b/src/core/transport/http/util/Makefile.am @@ -0,0 +1,14 @@ +NSUBDIRS = +noinst_LTLIBRARIES = libaxis2_http_util.la + +libaxis2_http_util_la_SOURCES = http_transport_utils.c + +libaxis2_http_util_la_LIBADD=$(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/axiom/src/parser/${WRAPPER_DIR}/libaxis2_parser.la\ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la + + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/http/util/http_transport_utils.c b/src/core/transport/http/util/http_transport_utils.c new file mode 100644 index 0000000..97d1510 --- /dev/null +++ b/src/core/transport/http/util/http_transport_utils.c @@ -0,0 +1,3885 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_http_transport_utils.h> +#include <string.h> +#include <ctype.h> +#include <axis2_conf.h> +#include <axis2_op.h> +#include <axutil_qname.h> +#include <axis2_http_transport.h> +#include <axiom_soap_builder.h> +#include <axis2_engine.h> +#include <axiom_soap_body.h> +#include <axutil_utils.h> +#include <axiom_namespace.h> +#include <axiom_node.h> +#include <axutil_hash.h> +#include <axiom_soap_const.h> +#include <axis2_http_header.h> +#include <axutil_property.h> +#include <axutil_utils.h> +#include <axiom_mime_parser.h> +#include <axis2_http_accept_record.h> +#include <axis2_disp.h> +#include <axis2_msg.h> +#include <axutil_string_util.h> +#include <stdlib.h> +#include <axutil_uuid_gen.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <axiom_mime_part.h> +#include <axutil_class_loader.h> + +#define AXIOM_MIME_BOUNDARY_BYTE 45 + +/** Size of the buffer to be used when reading a file */ +#ifndef AXIS2_FILE_READ_SIZE +#define AXIS2_FILE_READ_SIZE 2048 +#endif + +/** Content length value to be used in case of chunked content */ +#ifndef AXIS2_CHUNKED_CONTENT_LENGTH +#define AXIS2_CHUNKED_CONTENT_LENGTH 100000000 +#endif + +const axis2_char_t *AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING = + AXIS2_HTTP_HEADER_DEFAULT_CHAR_ENCODING; + +/***************************** Function headers *******************************/ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_process_http_post_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + const int content_length, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_process_http_put_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + const int content_length, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri); + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_process_http_get_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri, + axis2_conf_ctx_t * conf_ctx, + axutil_hash_t * request_params); + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_process_http_head_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri, + axis2_conf_ctx_t * conf_ctx, + axutil_hash_t * request_params); + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_process_http_delete_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri, + axis2_conf_ctx_t * conf_ctx, + axutil_hash_t * request_params); + +AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL +axis2_http_transport_utils_select_builder_for_mime( + const axutil_env_t * env, + axis2_char_t * request_uri, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axis2_char_t * content_type); + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_is_optimized( + const axutil_env_t * env, + axiom_element_t * om_element); + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_do_write_mtom( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_strdecode( + const axutil_env_t * env, + axis2_char_t * dest, + axis2_char_t * src); + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_transport_utils_hexit( + axis2_char_t c); + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_services_html( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx); + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_services_static_wsdl( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_char_t * request_url); + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axis2_http_transport_utils_get_charset_enc( + const axutil_env_t * env, + const axis2_char_t * content_type); + +int AXIS2_CALL +axis2_http_transport_utils_on_data_request( + char *buffer, + int size, + void *ctx); + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axis2_http_transport_utils_create_soap_msg( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + const axis2_char_t * soap_ns_uri); + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_value_from_content_type( + const axutil_env_t * env, + const axis2_char_t * content_type, + const axis2_char_t * key); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_dispatch_and_verify( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axis2_http_transport_utils_handle_media_type_url_encoded( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_hash_t * param_map, + axis2_char_t * method); + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_transport_utils_session_map_free_void_arg( + void *sm_void, + const axutil_env_t *env); + +static axis2_status_t +axis2_http_transport_utils_send_attachment_using_file( + const axutil_env_t * env, + axutil_http_chunked_stream_t *chunked_stream, + FILE *fp, + axis2_byte_t *buffer, + int buffer_size); + +static axis2_status_t +axis2_http_transport_utils_send_attachment_using_callback( + const axutil_env_t * env, + axutil_http_chunked_stream_t *chunked_stream, + axiom_mtom_sending_callback_t *callback, + void *handler, + void *user_param); + +static axis2_char_t * +axis2_http_transport_utils_copy_key( + const axutil_env_t *env, + axis2_char_t *); + +static axis2_char_t * +axis2_http_transport_utils_copy_value( + const axutil_env_t *env, + axis2_char_t *pair); + +static void +axis2_http_transport_utils_parse_session_str( + const axutil_env_t *env, + axis2_char_t *str, + axutil_hash_t *ht); +/***************************** End of function headers ************************/ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_transport_out_init( + axis2_http_transport_out_t *response, + const axutil_env_t *env) +{ + response->http_status_code_name = NULL; + response->http_status_code = 0; + response->msg_ctx = NULL; + response->response_data = NULL; + response->content_type = NULL; + response->response_data_length = 0; + response->content_language = NULL; + response->output_headers = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_transport_out_uninit( + axis2_http_transport_out_t *response, + const axutil_env_t *env) +{ + if(response->msg_ctx) + { + axis2_msg_ctx_free(response->msg_ctx, env); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_transport_in_init( + axis2_http_transport_in_t *request, + const axutil_env_t *env) +{ + request->content_type = NULL; + request->content_length = 0; + request->msg_ctx = NULL; + request->soap_action = NULL; + request->request_uri = NULL; + request->in_stream = NULL; + request->remote_ip = NULL; + request->svr_port = NULL; + request->transfer_encoding = NULL; + request->accept_header = NULL; + request->accept_language_header = NULL; + request->accept_charset_header = NULL; + request->request_method = 0; + request->out_transport_info = NULL; + request->request_url_prefix = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_transport_in_uninit( + axis2_http_transport_in_t *request, + const axutil_env_t *env) +{ + if(request->msg_ctx) + { + axis2_msg_ctx_reset_out_transport_info(request->msg_ctx, env); + axis2_msg_ctx_free(request->msg_ctx, env); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_process_http_post_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + const int content_length, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_soap_builder_t *soap_builder = NULL; + axiom_stax_builder_t *om_builder = NULL; + axis2_bool_t is_soap11 = AXIS2_FALSE; + axiom_xml_reader_t *xml_reader = NULL; + axutil_string_t *char_set_str = NULL; + + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_callback_info_t *callback_ctx = NULL; + axis2_callback_info_t *mime_cb_ctx = NULL; + axutil_hash_t *headers = NULL; + axis2_engine_t *engine = NULL; + axiom_soap_body_t *soap_body = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_hash_t *binary_data_map = NULL; + axis2_char_t *soap_body_str = NULL; + axutil_stream_t *stream = NULL; + axis2_bool_t do_rest = AXIS2_FALSE; + axis2_bool_t run_as_get = AXIS2_FALSE; + axis2_char_t *soap_action = NULL; + unsigned int soap_action_len = 0; + axutil_property_t *http_error_property = NULL; + axiom_mime_parser_t *mime_parser = NULL; + axis2_bool_t is_svc_callback = AXIS2_FALSE; + axutil_property_t *is_client_property = NULL; + axis2_bool_t is_application_client_side = AXIS2_FALSE; + axis2_char_t *mime_boundary = NULL; + axis2_bool_t check_for_fault = AXIS2_FALSE; + axis2_bool_t has_fault = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FAILURE); + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + + callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t)); + /* Note: the memory created above is freed in xml reader free function + as this is passed on to the reader */ + callback_ctx->in_stream = in_stream; + callback_ctx->env = env; + callback_ctx->content_length = content_length; + callback_ctx->unread_len = content_length; + callback_ctx->chunked_stream = NULL; + + soap_action = (axis2_char_t *)axutil_string_get_buffer(soap_action_header, env); + soap_action_len = axutil_string_get_length(soap_action_header, env); + + if(soap_action && (soap_action_len > 0)) + { + /* remove leading and trailing " s */ + if(AXIS2_DOUBLE_QUOTE == soap_action[0]) + { + memmove(soap_action, soap_action + sizeof(char), soap_action_len - 1 + sizeof(char)); + } + if(AXIS2_DOUBLE_QUOTE == soap_action[soap_action_len - 2]) + { + soap_action[soap_action_len - 2] = AXIS2_ESC_NULL; + } + } + else + { + /** soap action is null, check whether soap action is in content_type header */ + soap_action = axis2_http_transport_utils_get_value_from_content_type(env, content_type, + AXIS2_ACTION); + } + + headers = axis2_msg_ctx_get_transport_headers(msg_ctx, env); + if(headers) + { + axis2_http_header_t *encoding_header = NULL; + encoding_header = (axis2_http_header_t *)axutil_hash_get(headers, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING, AXIS2_HASH_KEY_STRING); + + if(encoding_header) + { + axis2_char_t *encoding_value = NULL; + encoding_value = axis2_http_header_get_value(encoding_header, env); + if(encoding_value && 0 == axutil_strcasecmp(encoding_value, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)) + { + callback_ctx->chunked_stream = axutil_http_chunked_stream_create(env, in_stream); + + if(!callback_ctx->chunked_stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occurred in" + " creating in chunked stream."); + return AXIS2_FAILURE; + } + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "HTTP" + " stream chunked"); + } + } + } + else + { + /* Encoding header is not available */ + /* check content encoding from msg ctx property */ + axis2_char_t *value = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env); + + if(value && axutil_strstr(value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)) + { + /* In case Transfer encoding is set to message context, some streams strip chunking meta + data, so chunked streams should not be created */ + + callback_ctx->content_length = -1; + callback_ctx->unread_len = -1; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[chunked ] setting length to -1"); + } + } + + /* when the message contains does not contain pure XML we can't send it + * directly to the parser, First we need to separate the SOAP part from + * the attachment */ + + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED)) + { + /* get mime boundary */ + mime_boundary = axis2_http_transport_utils_get_value_from_content_type(env, + content_type, AXIS2_HTTP_HEADER_CONTENT_TYPE_MIME_BOUNDARY); + + if(mime_boundary) + { + /*axiom_mime_parser_t *mime_parser = NULL;*/ + int soap_body_len = 0; + axutil_param_t *buffer_size_param = NULL; + axutil_param_t *max_buffers_param = NULL; + axutil_param_t *attachment_dir_param = NULL; + axutil_param_t *callback_name_param = NULL; + axutil_param_t *enable_service_callback_param = NULL; + axis2_char_t *value_size = NULL; + axis2_char_t *value_num = NULL; + axis2_char_t *value_dir = NULL; + axis2_char_t *value_callback = NULL; + axis2_char_t *value_enable_service_callback = NULL; + int size = 0; + int num = 0; + + mime_parser = axiom_mime_parser_create(env); + /* This is the size of the buffer we keep inside mime_parser + * when parsing. */ + + enable_service_callback_param = axis2_msg_ctx_get_parameter(msg_ctx, env, + AXIS2_ENABLE_MTOM_SERVICE_CALLBACK); + if(enable_service_callback_param) + { + value_enable_service_callback = (axis2_char_t *)axutil_param_get_value( + enable_service_callback_param, env); + if(value_enable_service_callback) + { + if(!axutil_strcmp(value_enable_service_callback, AXIS2_VALUE_TRUE)) + { + is_svc_callback = AXIS2_TRUE; + } + } + } + + buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE); + if(buffer_size_param) + { + value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env); + if(value_size) + { + size = atoi(value_size); + axiom_mime_parser_set_buffer_size(mime_parser, env, size); + } + } + + /* We create an array of buffers in order to conatin SOAP data inside + * mime_parser. This is the number of sucj buffers */ + max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS); + if(max_buffers_param) + { + value_num = (axis2_char_t *)axutil_param_get_value(max_buffers_param, env); + if(value_num) + { + num = atoi(value_num); + axiom_mime_parser_set_max_buffers(mime_parser, env, num); + } + } + /* If this paramter is there mime_parser will cached the attachment + * using to the directory for large attachments. */ + + callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env, + AXIS2_MTOM_CACHING_CALLBACK); + if(callback_name_param) + { + value_callback = (axis2_char_t *)axutil_param_get_value(callback_name_param, env); + if(value_callback) + { + axiom_mime_parser_set_caching_callback_name(mime_parser, env, value_callback); + } + } + + attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR); + + if(attachment_dir_param) + { + value_dir = (axis2_char_t *)axutil_param_get_value(attachment_dir_param, env); + if(value_dir) + { + axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir); + } + } + + axiom_mime_parser_set_mime_boundary(mime_parser, env, mime_boundary); + + if(axiom_mime_parser_parse_for_soap(mime_parser, env, + axis2_http_transport_utils_on_data_request, (void *)callback_ctx, mime_boundary) + == AXIS2_FAILURE) + { + return AXIS2_FAILURE; + } + + if(!is_svc_callback) + { + binary_data_map = axiom_mime_parser_parse_for_attachments(mime_parser, env, + axis2_http_transport_utils_on_data_request, (void *)callback_ctx, + mime_boundary, NULL); + if(!binary_data_map) + { + return AXIS2_FAILURE; + } + } + soap_body_len = (int)axiom_mime_parser_get_soap_body_len(mime_parser, env); + soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env); + + if(!is_svc_callback) + { + if(callback_ctx->chunked_stream) + { + axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env); + callback_ctx->chunked_stream = NULL; + } + } + else + { + mime_cb_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t)); + if(mime_cb_ctx) + { + mime_cb_ctx->in_stream = callback_ctx->in_stream; + mime_cb_ctx->env = callback_ctx->env; + mime_cb_ctx->content_length = callback_ctx->content_length; + mime_cb_ctx->unread_len = callback_ctx->unread_len; + mime_cb_ctx->chunked_stream = callback_ctx->chunked_stream; + } + } + + stream = axutil_stream_create_basic(env); + if(stream) + { + axutil_stream_write(stream, env, soap_body_str, soap_body_len); + callback_ctx->in_stream = stream; + callback_ctx->chunked_stream = NULL; + callback_ctx->content_length = soap_body_len; + callback_ctx->unread_len = soap_body_len; + } + /*axiom_mime_parser_free(mime_parser, env); + mime_parser = NULL;*/ + + /*AXIS2_FREE(env->allocator, mime_boundary);*/ + } + /*AXIS2_FREE(env->allocator, mime_boundary);*/ + } + + if(soap_action_header) + { + axis2_msg_ctx_set_soap_action(msg_ctx, env, soap_action_header); + + } + else if(soap_action) + { + axutil_string_t *soap_action_str = NULL; + soap_action_str = axutil_string_create(env, soap_action); + axis2_msg_ctx_set_soap_action(msg_ctx, env, soap_action_str); + axutil_string_free(soap_action_str, env); + } + axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri)); + + axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); + + char_set_str = axis2_http_transport_utils_get_charset_enc(env, content_type); + xml_reader = axiom_xml_reader_create_for_io(env, axis2_http_transport_utils_on_data_request, + NULL, (void *)callback_ctx, axutil_string_get_buffer(char_set_str, env)); + + if(!xml_reader) + { + return AXIS2_FAILURE; + } + + axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str); + + om_builder = axiom_stax_builder_create(env, xml_reader); + if(!om_builder) + { + axiom_xml_reader_free(xml_reader, env); + xml_reader = NULL; + return AXIS2_FAILURE; + } + + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP)) + { + is_soap11 = AXIS2_FALSE; + soap_builder = axiom_soap_builder_create(env, om_builder, + AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI); + if(!soap_builder) + { + /* We should not be freeing om_builder here as it is done by + axiom_soap_builder_create in case of error - Samisa */ + om_builder = NULL; + xml_reader = NULL; + axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11); + return AXIS2_FAILURE; + } + + soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + if(!soap_envelope) + { + axiom_stax_builder_free(om_builder, env); + om_builder = NULL; + xml_reader = NULL; + axiom_soap_builder_free(soap_builder, env); + soap_builder = NULL; + axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11); + return AXIS2_FAILURE; + } + } + else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML)) + { + is_soap11 = AXIS2_TRUE; + if(soap_action_header) + { + soap_builder = axiom_soap_builder_create(env, om_builder, + AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI); + if(!soap_builder) + { + /* We should not be freeing om_builder here as it is done by + axiom_soap_builder_create in case of error - Samisa */ + om_builder = NULL; + xml_reader = NULL; + axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11); + return AXIS2_FAILURE; + } + soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + if(!soap_envelope) + { + axiom_soap_builder_free(soap_builder, env); + om_builder = NULL; + xml_reader = NULL; + soap_builder = NULL; + axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11); + return AXIS2_FAILURE; + } + } + else + { + /* REST support */ + do_rest = AXIS2_TRUE; + } + } + + else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_X_WWW_FORM_URLENCODED)) + { + /* REST support */ + do_rest = AXIS2_TRUE; + run_as_get = AXIS2_TRUE; + } + else + { + http_error_property = axutil_property_create(env); + axutil_property_set_value(http_error_property, env, AXIS2_HTTP_UNSUPPORTED_MEDIA_TYPE); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_TRANSPORT_ERROR, http_error_property); + } + + if(soap_builder) + { + if(mime_parser) + { + axiom_soap_builder_set_mime_parser(soap_builder, env, mime_parser); + if(mime_cb_ctx) + { + axiom_soap_builder_set_callback_ctx(soap_builder, env, mime_cb_ctx); + axiom_soap_builder_set_callback_function(soap_builder, env, + axis2_http_transport_utils_on_data_request); + } + else if(is_svc_callback) + { + return AXIS2_FAILURE; + } + } + } + + if(do_rest) + { + /* REST support */ + axutil_param_t *rest_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ENABLE_REST); + if(rest_param && 0 == axutil_strcmp(AXIS2_VALUE_TRUE, axutil_param_get_value(rest_param, + env))) + { + axiom_soap_body_t *def_body = NULL; + axiom_document_t *om_doc = NULL; + axiom_node_t *root_node = NULL; + if(!run_as_get) + { + soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11); + def_body = axiom_soap_envelope_get_body(soap_envelope, env); + om_doc = axiom_stax_builder_get_document(om_builder, env); + root_node = axiom_document_build_all(om_doc, env); + axiom_soap_body_add_child(def_body, env, root_node); + } + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_POST); + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + } + else + { + return AXIS2_FAILURE; + } + if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx)) + { + return AXIS2_FAILURE; + } + } + + if(run_as_get) + { + axis2_char_t *buffer = NULL; + axis2_char_t *new_url = NULL; + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (content_length + 1)); + if(!buffer) + { + return AXIS2_FAILURE; + } + axis2_http_transport_utils_on_data_request(buffer, content_length, (void *)callback_ctx); + + new_url = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * ((int)(strlen(request_uri) + + strlen(buffer)) + 2)); + if(!new_url) + { + return AXIS2_FAILURE; + } + sprintf(new_url, "%s?%s", request_uri, buffer); + AXIS2_FREE(env->allocator, buffer); + + soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx, + axis2_http_transport_utils_get_request_params(env, new_url), AXIS2_HTTP_POST); + } + + if(binary_data_map) + { + axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map); + } + + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + + engine = axis2_engine_create(env, conf_ctx); + + if(!soap_envelope) + return AXIS2_FAILURE; + + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + + if(!soap_body) + return AXIS2_FAILURE; + + if(!is_svc_callback) + { + is_client_property = axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE); + if(is_client_property) + { + axis2_char_t *prop_value = NULL; + prop_value = axutil_property_get_value(is_client_property, env); + if(prop_value && !axutil_strcmp(prop_value , AXIS2_VALUE_TRUE)) + { + is_application_client_side = AXIS2_TRUE; + } + } + if(mime_boundary || is_application_client_side) + { + check_for_fault = AXIS2_TRUE; + } + if(check_for_fault) + { + has_fault = axiom_soap_body_has_fault(soap_body, env); + } + if(has_fault) + { + status = axis2_engine_receive_fault(engine, env, msg_ctx); + } + else + { + status = axis2_engine_receive(engine, env, msg_ctx); + } + } + else + { + status = axis2_engine_receive(engine, env, msg_ctx); + } + + if(!axis2_msg_ctx_get_soap_envelope(msg_ctx, env) && AXIS2_FALSE == is_soap11) + { + axiom_soap_envelope_t *def_envelope = axiom_soap_envelope_create_default_soap_envelope(env, + AXIOM_SOAP12); + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, def_envelope); + } + + if(engine) + { + axis2_engine_free(engine, env); + } + + if(soap_body_str) + { + AXIS2_FREE(env->allocator, soap_body_str); + } + + if(stream) + { + axutil_stream_free(stream, env); + } + + if(char_set_str) + { + axutil_string_free(char_set_str, env); + } + if(!soap_builder && om_builder) + { + axiom_stax_builder_free_self(om_builder, env); + om_builder = NULL; + } + if(!axutil_string_get_buffer(soap_action_header, env) && soap_action) + { + AXIS2_FREE(env->allocator, soap_action); + soap_action = NULL; + } + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_process_http_put_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + const int content_length, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_soap_builder_t *soap_builder = NULL; + axiom_stax_builder_t *om_builder = NULL; + axis2_bool_t is_soap11 = AXIS2_FALSE; + axiom_xml_reader_t *xml_reader = NULL; + axutil_string_t *char_set_str = NULL; + + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_callback_info_t *callback_ctx; + axutil_hash_t *headers = NULL; + axis2_engine_t *engine = NULL; + axiom_soap_body_t *soap_body = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_hash_t *binary_data_map = NULL; + axis2_char_t *soap_body_str = NULL; + axutil_stream_t *stream = NULL; + axis2_bool_t do_rest = AXIS2_FALSE; + axis2_bool_t run_as_get = AXIS2_FALSE; + axutil_property_t *http_error_property = NULL; + axutil_property_t *is_client_property = NULL; + axis2_bool_t is_application_client_side = AXIS2_FALSE; + axis2_char_t *mime_boundary = NULL; + axis2_bool_t check_for_fault = AXIS2_FALSE; + axis2_bool_t has_fault = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FAILURE); + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + + callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t)); + /* Note: the memory created above is freed in xml reader free function + as this is passed on to the reader */ + callback_ctx->in_stream = in_stream; + callback_ctx->env = env; + callback_ctx->content_length = content_length; + callback_ctx->unread_len = content_length; + callback_ctx->chunked_stream = NULL; + + headers = axis2_msg_ctx_get_transport_headers(msg_ctx, env); + if(headers) + { + axis2_http_header_t *encoding_header = NULL; + encoding_header = (axis2_http_header_t *)axutil_hash_get(headers, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING, AXIS2_HASH_KEY_STRING); + + if(encoding_header) + { + axis2_char_t *encoding_value = NULL; + encoding_value = axis2_http_header_get_value(encoding_header, env); + if(encoding_value && 0 == axutil_strcasecmp(encoding_value, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)) + { + callback_ctx->chunked_stream = axutil_http_chunked_stream_create(env, in_stream); + if(!callback_ctx->chunked_stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in" + " creating in chunked stream."); + return AXIS2_FAILURE; + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "HTTP" + " stream chunked"); + } + } + } + else + { + /* check content encoding from msg ctx property */ + axis2_char_t *value = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env); + + if(value && axutil_strstr(value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)) + { + /* this is an UGLY hack to get some of the transports working + e.g. PHP transport where it strips the chunking info in case of chunking + and also gives out a content lenght of 0. + We need to fix the transport design to fix sutuations like this. + */ + callback_ctx->content_length = AXIS2_CHUNKED_CONTENT_LENGTH; + callback_ctx->unread_len = callback_ctx->content_length; + } + } + + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED)) + { + /* get mime boundry */ + mime_boundary = axis2_http_transport_utils_get_value_from_content_type(env, + content_type, AXIS2_HTTP_HEADER_CONTENT_TYPE_MIME_BOUNDARY); + + if(mime_boundary) + { + axiom_mime_parser_t *mime_parser = NULL; + int soap_body_len = 0; + axutil_param_t *buffer_size_param = NULL; + axutil_param_t *max_buffers_param = NULL; + axutil_param_t *attachment_dir_param = NULL; + axutil_param_t *callback_name_param = NULL; + axis2_char_t *value_size = NULL; + axis2_char_t *value_num = NULL; + axis2_char_t *value_dir = NULL; + axis2_char_t *value_callback = NULL; + int size = 0; + int num = 0; + + mime_parser = axiom_mime_parser_create(env); + + buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE); + if(buffer_size_param) + { + value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env); + if(value_size) + { + size = atoi(value_size); + axiom_mime_parser_set_buffer_size(mime_parser, env, size); + } + } + + max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS); + if(max_buffers_param) + { + value_num = (axis2_char_t *)axutil_param_get_value(max_buffers_param, env); + if(value_num) + { + num = atoi(value_num); + axiom_mime_parser_set_max_buffers(mime_parser, env, num); + } + } + + callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env, + AXIS2_MTOM_CACHING_CALLBACK); + if(callback_name_param) + { + value_callback = (axis2_char_t *)axutil_param_get_value(callback_name_param, env); + if(value_callback) + { + axiom_mime_parser_set_caching_callback_name(mime_parser, env, value_callback); + } + } + + attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR); + + if(attachment_dir_param) + { + value_dir = (axis2_char_t *)axutil_param_get_value(attachment_dir_param, env); + if(value_dir) + { + axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir); + } + } + + if(mime_parser) + { + /*binary_data_map = + axiom_mime_parser_parse(mime_parser, env, + axis2_http_transport_utils_on_data_request, + (void *) callback_ctx, + mime_boundary);*/ + if(!binary_data_map) + { + return AXIS2_FAILURE; + } + soap_body_len = (int)axiom_mime_parser_get_soap_body_len(mime_parser, env); + soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env); + } + + stream = axutil_stream_create_basic(env); + if(stream) + { + axutil_stream_write(stream, env, soap_body_str, soap_body_len); + callback_ctx->in_stream = stream; + callback_ctx->chunked_stream = NULL; + callback_ctx->content_length = soap_body_len; + callback_ctx->unread_len = soap_body_len; + } + axiom_mime_parser_free(mime_parser, env); + mime_parser = NULL; + } + /*AXIS2_FREE(env->allocator, mime_boundary);*/ + } + + axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri)); + + axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); + + char_set_str = axis2_http_transport_utils_get_charset_enc(env, content_type); + xml_reader = axiom_xml_reader_create_for_io(env, axis2_http_transport_utils_on_data_request, + NULL, (void *)callback_ctx, axutil_string_get_buffer(char_set_str, env)); + + if(!xml_reader) + { + return AXIS2_FAILURE; + } + + axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str); + + om_builder = axiom_stax_builder_create(env, xml_reader); + if(!om_builder) + { + axiom_xml_reader_free(xml_reader, env); + xml_reader = NULL; + return AXIS2_FAILURE; + } + + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP)) + { + is_soap11 = AXIS2_FALSE; + soap_builder = axiom_soap_builder_create(env, om_builder, + AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI); + if(!soap_builder) + { + /* We should not be freeing om_builder here as it is done by + axiom_soap_builder_create in case of error - Samisa */ + om_builder = NULL; + xml_reader = NULL; + axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11); + return AXIS2_FAILURE; + } + + soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + if(!soap_envelope) + { + axiom_stax_builder_free(om_builder, env); + om_builder = NULL; + xml_reader = NULL; + axiom_soap_builder_free(soap_builder, env); + soap_builder = NULL; + axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11); + return AXIS2_FAILURE; + } + } + else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML)) + { + do_rest = AXIS2_TRUE; + if(soap_action_header) + { + return AXIS2_FAILURE; + } + else + { + /* REST support */ + do_rest = AXIS2_TRUE; + } + } + else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_X_WWW_FORM_URLENCODED)) + { + /* REST support */ + do_rest = AXIS2_TRUE; + run_as_get = AXIS2_TRUE; + } + else + { + http_error_property = axutil_property_create(env); + axutil_property_set_value(http_error_property, env, AXIS2_HTTP_UNSUPPORTED_MEDIA_TYPE); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_TRANSPORT_ERROR, http_error_property); + } + + if(do_rest) + { + /* REST support */ + axutil_param_t *rest_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ENABLE_REST); + if(rest_param && 0 == axutil_strcmp(AXIS2_VALUE_TRUE, axutil_param_get_value(rest_param, + env))) + { + axiom_soap_body_t *def_body = NULL; + axiom_document_t *om_doc = NULL; + axiom_node_t *root_node = NULL; + if(!run_as_get) + { + soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11); + def_body = axiom_soap_envelope_get_body(soap_envelope, env); + om_doc = axiom_stax_builder_get_document(om_builder, env); + root_node = axiom_document_build_all(om_doc, env); + axiom_soap_body_add_child(def_body, env, root_node); + } + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_PUT); + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + } + else + { + return AXIS2_FAILURE; + } + if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx)) + { + return AXIS2_FAILURE; + } + } + + if(run_as_get) + { + axis2_char_t *buffer = NULL; + axis2_char_t *new_url = NULL; + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (content_length + 1)); + if(!buffer) + { + return AXIS2_FAILURE; + } + axis2_http_transport_utils_on_data_request(buffer, content_length, (void *)callback_ctx); + + new_url = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * ((int)(strlen(request_uri) + + strlen(buffer)) + 2)); + if(!new_url) + { + return AXIS2_FAILURE; + } + sprintf(new_url, "%s?%s", request_uri, buffer); + AXIS2_FREE(env->allocator, buffer); + + soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx, + axis2_http_transport_utils_get_request_params(env, new_url), AXIS2_HTTP_POST); + } + + if(binary_data_map) + { + axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map); + } + + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + + engine = axis2_engine_create(env, conf_ctx); + + if(!soap_envelope) + return AXIS2_FAILURE; + + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + + if(!soap_body) + return AXIS2_FAILURE; + + is_client_property = axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE); + if(is_client_property) + { + axis2_char_t *prop_value = NULL; + prop_value = axutil_property_get_value(is_client_property, env); + if(prop_value && !axutil_strcmp(prop_value , AXIS2_VALUE_TRUE)) + { + is_application_client_side = AXIS2_TRUE; + } + } + if(mime_boundary || is_application_client_side) + { + check_for_fault = AXIS2_TRUE; + } + if(check_for_fault) + { + has_fault = axiom_soap_body_has_fault(soap_body, env); + } + if(has_fault) + { + status = axis2_engine_receive_fault(engine, env, msg_ctx); + } + else + { + status = axis2_engine_receive(engine, env, msg_ctx); + } + if(mime_boundary) + { + AXIS2_FREE(env->allocator, mime_boundary); + } + if(!axis2_msg_ctx_get_soap_envelope(msg_ctx, env) && AXIS2_FALSE == is_soap11) + { + axiom_soap_envelope_t *def_envelope = axiom_soap_envelope_create_default_soap_envelope(env, + AXIOM_SOAP12); + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, def_envelope); + } + + if(engine) + { + axis2_engine_free(engine, env); + } + + if(soap_body_str) + { + AXIS2_FREE(env->allocator, soap_body_str); + } + + if(stream) + { + axutil_stream_free(stream, env); + } + + if(char_set_str) + { + axutil_string_free(char_set_str, env); + } + if(!soap_builder && om_builder) + { + axiom_stax_builder_free_self(om_builder, env); + om_builder = NULL; + } + return status; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_process_http_head_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri, + axis2_conf_ctx_t * conf_ctx, + axutil_hash_t * request_params) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axis2_engine_t *engine = NULL; + axis2_bool_t do_rest = AXIS2_TRUE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE); + + AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FALSE); + + axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri)); + axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML)) + { + if(soap_action_header) + { + do_rest = AXIS2_FALSE; + } + } + else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP)) + { + do_rest = AXIS2_FALSE; + } + + if(do_rest) + { + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_HEAD); + } + else + { + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE); + } + if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx)) + { + return AXIS2_FALSE; + } + + soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx, + request_params, AXIS2_HTTP_HEAD); + if(!soap_envelope) + { + return AXIS2_FALSE; + } + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + engine = axis2_engine_create(env, conf_ctx); + axis2_engine_receive(engine, env, msg_ctx); + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_process_http_get_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri, + axis2_conf_ctx_t * conf_ctx, + axutil_hash_t * request_params) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axis2_engine_t *engine = NULL; + axis2_bool_t do_rest = AXIS2_TRUE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FALSE); + + axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri)); + axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); + if(content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML)) + { + if(soap_action_header) + { + do_rest = AXIS2_FALSE; + } + } + else if(content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP)) + { + do_rest = AXIS2_FALSE; + } + + if(do_rest) + { + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_GET); + } + else + { + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE); + } + + if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx)) + { + return AXIS2_FALSE; + } + soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx, + request_params, AXIS2_HTTP_GET); + if(!soap_envelope) + { + return AXIS2_FALSE; + } + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + + engine = axis2_engine_create(env, conf_ctx); + axis2_engine_receive(engine, env, msg_ctx); + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_process_http_delete_request( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_stream_t * in_stream, + axutil_stream_t * out_stream, + const axis2_char_t * content_type, + axutil_string_t * soap_action_header, + const axis2_char_t * request_uri, + axis2_conf_ctx_t * conf_ctx, + axutil_hash_t * request_params) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axis2_engine_t *engine = NULL; + axis2_bool_t do_rest = AXIS2_TRUE; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FALSE); + + axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri)); + axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML)) + { + if(soap_action_header) + { + do_rest = AXIS2_FALSE; + } + } + else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP)) + { + do_rest = AXIS2_FALSE; + } + + if(do_rest) + { + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_DELETE); + } + else + { + axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE); + } + + soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx, + request_params, AXIS2_HTTP_DELETE); + if(!soap_envelope) + { + return AXIS2_FALSE; + } + + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + + if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx)) + { + return AXIS2_FALSE; + } + engine = axis2_engine_create(env, conf_ctx); + axis2_engine_receive(engine, env, msg_ctx); + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_do_write_mtom( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + return (axis2_msg_ctx_get_doing_mtom(msg_ctx, env)); +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axis2_http_transport_utils_get_request_params( + const axutil_env_t * env, + axis2_char_t * request_uri) +{ + + axis2_char_t *query_str = NULL; + axis2_char_t *tmp = strchr(request_uri, AXIS2_Q_MARK); + axis2_char_t *tmp2 = NULL; + axis2_char_t *tmp_name = NULL; + axis2_char_t *tmp_value = NULL; + axutil_hash_t *ret = NULL; + + AXIS2_PARAM_CHECK(env->error, request_uri, NULL); + + if(!tmp || AXIS2_ESC_NULL == *(tmp + 1)) + { + return NULL; + } + query_str = axutil_strdup(env, tmp + 1); + + for(tmp2 = tmp = query_str; *tmp != AXIS2_ESC_NULL; ++tmp) + { + if(AXIS2_EQ == *tmp) + { + *tmp = AXIS2_ESC_NULL; + tmp_name = axutil_strdup(env, tmp2); + axis2_http_transport_utils_strdecode(env, tmp_name, tmp_name); + tmp2 = tmp + 1; + } + if(AXIS2_AND == *tmp) + { + *tmp = AXIS2_ESC_NULL; + tmp_value = axutil_strdup(env, tmp2); + axis2_http_transport_utils_strdecode(env, tmp_value, tmp_value); + tmp2 = tmp + 1; + } + if(tmp_name && NULL != tmp_value) + { + if(!ret) + { + ret = axutil_hash_make(env); + } + axutil_hash_set(ret, tmp_name, AXIS2_HASH_KEY_STRING, tmp_value); + tmp_name = NULL; + tmp_value = NULL; + } + } + if(tmp_name && AXIS2_ESC_NULL != *tmp2) + { + if(!ret) + { + ret = axutil_hash_make(env); + } + tmp_value = axutil_strdup(env, tmp2); + axis2_http_transport_utils_strdecode(env, tmp_value, tmp_value); + axutil_hash_set(ret, tmp_name, AXIS2_HASH_KEY_STRING, tmp_value); + } + + return ret; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_strdecode( + const axutil_env_t * env, + axis2_char_t * dest, + axis2_char_t * src) +{ + AXIS2_PARAM_CHECK(env->error, dest, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, src, AXIS2_FAILURE); + + for(; *src != AXIS2_ESC_NULL; ++dest, ++src) + { + if(src[0] == AXIS2_PERCENT && isxdigit((int)src[1]) && isxdigit((int)src[2])) + { + *dest = (axis2_char_t)(axis2_http_transport_utils_hexit(src[1]) * 16 + + axis2_http_transport_utils_hexit(src[2])); + /* We are sure that the conversion is valid */ + src += 2; + } + else + { + *dest = *src; + } + } + *dest = AXIS2_ESC_NULL; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_transport_utils_hexit( + axis2_char_t c) +{ + if(c >= '0' && c <= '9') + { + return c - '0'; + } + if(c >= 'a' && c <= 'f') + { + return c - 'a' + 10; + } + if(c >= 'A' && c <= 'F') + { + return c - 'A' + 10; + } + return 0; /* shouldn't happen, we're guarded by isxdigit() */ +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_not_found( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_NOT_FOUND; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_not_implemented( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_NOT_IMPLEMENTED; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_internal_server_error( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_INTERNAL_SERVER_ERROR; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_method_not_allowed( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_METHOD_NOT_ALLOWED; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_not_acceptable( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_NOT_ACCEPTABLE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_bad_request( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_BAD_REQUEST; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_request_timeout( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_REQUEST_TIMEOUT; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_conflict( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_CONFLICT; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_gone( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_GONE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_precondition_failed( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_PRECONDITION_FAILED; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_request_entity_too_large( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_TOO_LARGE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_service_unavailable( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + return AXIS2_HTTP_SERVICE_UNAVILABLE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_services_html( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + axutil_hash_t *services_map = NULL; + axutil_hash_t *errorneous_svc_map = NULL; + axis2_char_t *ret = NULL; + axis2_char_t *tmp2 = (axis2_char_t *)"<h2>Deployed Services</h2>"; + axutil_hash_index_t *hi = NULL; + axis2_bool_t svcs_exists = AXIS2_FALSE; + axis2_conf_t *conf = NULL; + AXIS2_PARAM_CHECK(env->error, conf_ctx, NULL); + + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + services_map = axis2_conf_get_all_svcs(conf, env); + errorneous_svc_map = axis2_conf_get_all_faulty_svcs(conf, env); + if(services_map && 0 != axutil_hash_count(services_map)) + { + void *service = NULL; + axis2_char_t *sname = NULL; + axutil_hash_t *ops = NULL; + svcs_exists = AXIS2_TRUE; + + for(hi = axutil_hash_first(services_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &service); + sname = axutil_qname_get_localpart(axis2_svc_get_qname(((axis2_svc_t *)service), env), + env); + ret = axutil_stracat(env, tmp2, "<h3><u>"); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, sname); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "</u></h3>"); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "<p>"); + tmp2 = ret; + + /** + *setting services description */ + ret = axutil_stracat(env, tmp2, axis2_svc_get_svc_desc((axis2_svc_t *)service, env)); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "</p>"); + tmp2 = ret; + ops = axis2_svc_get_all_ops(((axis2_svc_t *)service), env); + if(ops && 0 != axutil_hash_count(ops)) + { + axutil_hash_index_t *hi2 = NULL; + void *op = NULL; + axis2_char_t *oname = NULL; + + ret = axutil_stracat(env, tmp2, "<i>Available Operations</i> <ul>"); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + for(hi2 = axutil_hash_first(ops, env); hi2; hi2 = axutil_hash_next(env, hi2)) + { + axutil_hash_this(hi2, NULL, NULL, &op); + oname = axutil_qname_get_localpart(axis2_op_get_qname(((axis2_op_t *)op), env), + env); + ret = axutil_stracat(env, tmp2, "<li>"); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + + ret = axutil_stracat(env, tmp2, oname); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "</li>"); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + } + ret = axutil_stracat(env, tmp2, "</ul>"); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + } + else + { + ret = axutil_stracat(env, tmp2, "No operations Available"); + tmp2 = ret; + } + } + } + + if(errorneous_svc_map && 0 != axutil_hash_count(errorneous_svc_map)) + { + void *fsname = NULL; + svcs_exists = AXIS2_TRUE; + ret = axutil_stracat(env, tmp2, + "<hr><h2><font color=\"red\">Faulty \ + Services</font></h2>"); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + + for(hi = axutil_hash_first(errorneous_svc_map, env); hi; axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, (const void **)&fsname, NULL, NULL); + ret = axutil_stracat(env, tmp2, "<h3><font color=\"red\">"); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, (axis2_char_t *)fsname); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "</font></h3>"); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + } + } + if(AXIS2_FALSE == svcs_exists) + { + ret = axutil_strdup(env, "<h2>There are no services deployed</h2>"); + } + ret = axutil_stracat(env, "<html><head><title>Axis2C :: Services</title></head>" + "<body><font face=\"courier\">", tmp2); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "</font></body></html>\r\n"); + + return ret; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_services_static_wsdl( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_char_t * request_url) +{ + axis2_char_t *wsdl_string = NULL; + axis2_char_t *wsdl_path = NULL; + axis2_char_t **url_tok = NULL; + unsigned int len = 0; + axis2_char_t *svc_name = NULL; + axis2_conf_t *conf = NULL; + axutil_hash_t *services_map = NULL; + axutil_hash_index_t *hi = NULL; + + AXIS2_PARAM_CHECK(env->error, conf_ctx, NULL); + AXIS2_PARAM_CHECK(env->error, request_url, NULL); + + url_tok = axutil_parse_request_url_for_svc_and_op(env, request_url); + if(url_tok[0]) + { + len = (int)strlen(url_tok[0]); + /* We are sure that the difference lies within the int range */ + url_tok[0][len - 5] = 0; + svc_name = url_tok[0]; + } + + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + services_map = axis2_conf_get_all_svcs(conf, env); + + if(services_map && 0 != axutil_hash_count(services_map)) + { + void *service = NULL; + axis2_char_t *sname = NULL; + + for(hi = axutil_hash_first(services_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &service); + sname = axutil_qname_get_localpart(axis2_svc_get_qname(((axis2_svc_t *)service), env), + env); + if(!axutil_strcmp(svc_name, sname)) + { + wsdl_path = (axis2_char_t *)axutil_strdup(env, axis2_svc_get_svc_wsdl_path( + (axis2_svc_t *)service, env)); + if(!wsdl_path) + { + wsdl_path = axutil_strcat(env, axis2_svc_get_svc_folder_path( + (axis2_svc_t *)service, env), AXIS2_PATH_SEP_STR, svc_name, ".wsdl", NULL); + } + break; + } + + } + } + + if(wsdl_path) + { + FILE *wsdl_file = NULL; + axis2_char_t *content = NULL; + int c; + int size = AXIS2_FILE_READ_SIZE; + axis2_char_t *tmp; + int i = 0; + + content = (axis2_char_t *)AXIS2_MALLOC(env->allocator, size); + wsdl_file = fopen(wsdl_path, "r"); + if(wsdl_file) + { + c = fgetc(wsdl_file); + while(c != EOF) + { + if(i >= size) + { + size = size * 3; + tmp = (axis2_char_t *)AXIS2_MALLOC(env->allocator, size); + memcpy(tmp, content, i); + AXIS2_FREE(env->allocator, content); + content = tmp; + } + content[i++] = (axis2_char_t)c; + c = fgetc(wsdl_file); + } + content[i] = AXIS2_ESC_NULL; + wsdl_string = (axis2_char_t *)content; + fclose(wsdl_file); + } + + AXIS2_FREE(env->allocator, wsdl_path); + } + else + { + wsdl_string = axutil_strdup(env, "Unable to retrieve wsdl for this service"); + } + + return wsdl_string; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axis2_http_transport_utils_get_charset_enc( + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + axis2_char_t *tmp = NULL; + axis2_char_t *tmp_content_type = NULL; + axis2_char_t *tmp2 = NULL; + axutil_string_t *str = NULL; + + AXIS2_PARAM_CHECK(env->error, content_type, NULL); + + tmp_content_type = (axis2_char_t *)content_type; + if(!tmp_content_type) + { + return axutil_string_create_const(env, + (axis2_char_t **)&AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING); + } + + tmp = strstr(tmp_content_type, AXIS2_HTTP_CHAR_SET_ENCODING); + + if(tmp) + { + tmp = strchr(tmp, AXIS2_EQ); + if(tmp) + { + tmp2 = strchr(tmp, AXIS2_SEMI_COLON); + if(!tmp2) + { + tmp2 = tmp + strlen(tmp); + } + } + + if(tmp2) + { + if('\'' == *(tmp2 - sizeof(axis2_char_t)) || '\"' == *(tmp2 - sizeof(axis2_char_t))) + { + tmp2 -= sizeof(axis2_char_t); + } + *tmp2 = AXIS2_ESC_NULL; + } + } + + if(tmp) + { + /* Following formats are acceptable + * charset="UTF-8" + * charser='UTF-8' + * charset=UTF-8 + * But for our requirements charset we get should be UTF-8 + */ + if(AXIS2_ESC_SINGLE_QUOTE == *(tmp + sizeof(axis2_char_t)) || AXIS2_ESC_DOUBLE_QUOTE + == *(tmp + sizeof(axis2_char_t))) + { + tmp += 2 * sizeof(axis2_char_t); + } + else + { + tmp += sizeof(axis2_char_t); + } + } + + if(tmp) + { + str = axutil_string_create(env, tmp); + } + else + { + str = axutil_string_create_const(env, + (axis2_char_t **)&AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING); + } + return str; +} + +int AXIS2_CALL +axis2_http_transport_utils_on_data_request( + char *buffer, + int size, + void *ctx) +{ + const axutil_env_t *env = NULL; + int len = -1; + axis2_callback_info_t *cb_ctx = (axis2_callback_info_t *)ctx; + + if(!buffer || !ctx) + { + return 0; + } + env = ((axis2_callback_info_t *)ctx)->env; + if(cb_ctx->unread_len <= 0 && -1 != cb_ctx->content_length) + { + return 0; + } + if(cb_ctx->chunked_stream) + { + --size; + /* reserve space to insert trailing null */ + len = axutil_http_chunked_stream_read(cb_ctx->chunked_stream, env, buffer, size); + if(len >= 0) + { + buffer[len] = AXIS2_ESC_NULL; + } + } + else + { + axutil_stream_t *in_stream = NULL; + in_stream = (axutil_stream_t *)((axis2_callback_info_t *)ctx)->in_stream; + --size; /* reserve space to insert trailing null */ + len = axutil_stream_read(in_stream, env, buffer, size); + if(len > 0) + { + buffer[len] = AXIS2_ESC_NULL; + ((axis2_callback_info_t *)ctx)->unread_len -= len; + } + else if(len == 0) + { + ((axis2_callback_info_t *)ctx)->unread_len = 0; + } + } + return len; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axis2_http_transport_utils_create_soap_msg( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + const axis2_char_t * soap_ns_uri) +{ + axis2_op_ctx_t *op_ctx = NULL; + const axis2_char_t *char_set_enc = NULL; + axis2_char_t *content_type = NULL; + axutil_stream_t *in_stream = NULL; + axis2_callback_info_t *callback_ctx = NULL; + axis2_char_t *trans_enc = NULL; + int *content_length = NULL; + axutil_property_t *property = NULL; + axutil_hash_t *binary_data_map = NULL; + axiom_soap_envelope_t *soap_envelope = NULL; + axutil_stream_t *stream = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + AXIS2_PARAM_CHECK(env->error, soap_ns_uri, NULL); + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_IN); + if(property) + { + in_stream = axutil_property_get_value(property, env); + property = NULL; + } + callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t)); + /* Note: the memory created above is freed in xml reader free function + as this is passed on to the reader */ + if(!callback_ctx) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + callback_ctx->in_stream = in_stream; + callback_ctx->env = env; + callback_ctx->content_length = -1; + callback_ctx->unread_len = -1; + callback_ctx->chunked_stream = NULL; + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH); + if(property) + { + content_length = axutil_property_get_value(property, env); + property = NULL; + } + + if(content_length) + { + callback_ctx->content_length = *content_length; + callback_ctx->unread_len = *content_length; + } + + if(!in_stream) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_IN_STREAM_IN_MSG_CTX, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, callback_ctx); + return NULL; + } + + trans_enc = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env); + + if(trans_enc && 0 == axutil_strcmp(trans_enc, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)) + { + callback_ctx->chunked_stream = axutil_http_chunked_stream_create(env, in_stream); + if(!callback_ctx->chunked_stream) + { + return NULL; + } + } + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + axis2_ctx_t *ctx = axis2_op_ctx_get_base(op_ctx, env); + if(ctx) + { + property = axis2_ctx_get_property(ctx, env, AXIS2_CHARACTER_SET_ENCODING); + if(property) + { + char_set_enc = axutil_property_get_value(property, env); + property = NULL; + } + property = axis2_ctx_get_property(ctx, env, MTOM_RECIVED_CONTENT_TYPE); + if(property) + { + content_type = axutil_property_get_value(property, env); + property = NULL; + } + + } + } + + if(!char_set_enc) + { + char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING; + } + if(content_type) + { + axis2_char_t *mime_boundary = NULL; + axis2_msg_ctx_set_doing_mtom(msg_ctx, env, AXIS2_TRUE); + /* get mime boundry */ + mime_boundary = axis2_http_transport_utils_get_value_from_content_type(env, content_type, + AXIS2_HTTP_HEADER_CONTENT_TYPE_MIME_BOUNDARY); + + if(mime_boundary) + { + axiom_mime_parser_t *mime_parser = NULL; + int soap_body_len = 0; + axis2_char_t *soap_body_str = NULL; + axutil_param_t *buffer_size_param = NULL; + axutil_param_t *max_buffers_param = NULL; + axutil_param_t *attachment_dir_param = NULL; + axutil_param_t *callback_name_param = NULL; + axis2_char_t *value_size = NULL; + axis2_char_t *value_num = NULL; + axis2_char_t *value_dir = NULL; + axis2_char_t *value_callback = NULL; + int size = 0; + int num = 0; + + mime_parser = axiom_mime_parser_create(env); + + /* Following are the parameters in the axis2.xml regarding MTOM */ + + buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE); + if(buffer_size_param) + { + value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env); + + if(value_size) + { + size = atoi(value_size); + axiom_mime_parser_set_buffer_size(mime_parser, env, size); + } + } + + max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS); + if(max_buffers_param) + { + value_num = (axis2_char_t *)axutil_param_get_value(max_buffers_param, env); + if(value_num) + { + num = atoi(value_num); + axiom_mime_parser_set_max_buffers(mime_parser, env, num); + } + } + + callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env, + AXIS2_MTOM_CACHING_CALLBACK); + if(callback_name_param) + { + value_callback = (axis2_char_t *)axutil_param_get_value(callback_name_param, env); + if(value_callback) + { + axiom_mime_parser_set_caching_callback_name(mime_parser, env, value_callback); + } + } + + attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR); + if(attachment_dir_param) + { + value_dir = (axis2_char_t *)axutil_param_get_value(attachment_dir_param, env); + if(value_dir) + { + axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir); + } + } + + if(mime_parser) + { + if(axiom_mime_parser_parse_for_soap(mime_parser, env, + axis2_http_transport_utils_on_data_request, (void *)callback_ctx, mime_boundary) + == AXIS2_FAILURE) + { + return NULL; + } + + binary_data_map = axiom_mime_parser_parse_for_attachments(mime_parser, env, + axis2_http_transport_utils_on_data_request, (void *)callback_ctx, + mime_boundary, NULL); + if(!binary_data_map) + { + return NULL; + } + + if(!binary_data_map) + { + return NULL; + } + + soap_body_len = (int)axiom_mime_parser_get_soap_body_len(mime_parser, env); + soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env); + } + + if(callback_ctx->chunked_stream) + { + axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env); + callback_ctx->chunked_stream = NULL; + } + + stream = axutil_stream_create_basic(env); + if(stream) + { + axutil_stream_write(stream, env, soap_body_str, soap_body_len); + callback_ctx->in_stream = stream; + callback_ctx->chunked_stream = NULL; + callback_ctx->content_length = soap_body_len; + callback_ctx->unread_len = soap_body_len; + } + + axiom_mime_parser_free(mime_parser, env); + mime_parser = NULL; + if(mime_boundary) + { + AXIS2_FREE(env->allocator, mime_boundary); + } + + if(soap_body_str) + { + AXIS2_FREE(env->allocator, soap_body_str); + } + } + } + + if(AXIS2_TRUE != axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + { + axiom_xml_reader_t *xml_reader = NULL; + axiom_stax_builder_t *om_builder = NULL; + axiom_soap_builder_t *soap_builder = NULL; + + xml_reader = axiom_xml_reader_create_for_io(env, + axis2_http_transport_utils_on_data_request, NULL, (void *)callback_ctx, char_set_enc); + if(!xml_reader) + { + return NULL; + } + om_builder = axiom_stax_builder_create(env, xml_reader); + if(!om_builder) + { + axiom_xml_reader_free(xml_reader, env); + xml_reader = NULL; + return NULL; + } + soap_builder = axiom_soap_builder_create(env, om_builder, soap_ns_uri); + if(!soap_builder) + { + /* We should not be freeing om_builder here as it is done by + axiom_soap_builder_create in case of error - Samisa */ + om_builder = NULL; + xml_reader = NULL; + return NULL; + } + + soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + + if(binary_data_map) + { + axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map); + } + + if(soap_envelope) + { + /* hack to get around MTOM problem */ + axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + + if(soap_body) + { + axiom_soap_body_has_fault(soap_body, env); + } + } + if(stream) + { + axutil_stream_free(stream, env); + callback_ctx->in_stream = NULL; + } + if(callback_ctx->chunked_stream) + { + axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env); + callback_ctx->chunked_stream = NULL; + } + + } + else + { + /* REST processing */ + axiom_xml_reader_t *xml_reader = NULL; + axiom_stax_builder_t *om_builder = NULL; + axiom_soap_body_t *def_body = NULL; + axiom_document_t *om_doc = NULL; + axiom_node_t *root_node = NULL; + + xml_reader = axiom_xml_reader_create_for_io(env, + axis2_http_transport_utils_on_data_request, NULL, (void *)callback_ctx, char_set_enc); + if(!xml_reader) + { + return NULL; + } + om_builder = axiom_stax_builder_create(env, xml_reader); + if(!om_builder) + { + axiom_xml_reader_free(xml_reader, env); + xml_reader = NULL; + return NULL; + } + soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11); + def_body = axiom_soap_envelope_get_body(soap_envelope, env); + om_doc = axiom_stax_builder_get_document(om_builder, env); + root_node = axiom_document_build_all(om_doc, env); + axiom_soap_body_add_child(def_body, env, root_node); + axiom_stax_builder_free_self(om_builder, env); + } + + return soap_envelope; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_value_from_content_type( + const axutil_env_t * env, + const axis2_char_t * content_type, + const axis2_char_t * key) +{ + axis2_char_t *tmp = NULL; + axis2_char_t *tmp_content_type = NULL; + axis2_char_t *tmp2 = NULL; + + AXIS2_PARAM_CHECK(env->error, content_type, NULL); + AXIS2_PARAM_CHECK(env->error, key, NULL); + + tmp_content_type = axutil_strdup(env, content_type); + if(!tmp_content_type) + { + return NULL; + } + tmp = strstr(tmp_content_type, key); + if(!tmp) + { + AXIS2_FREE(env->allocator, tmp_content_type); + return NULL; + } + + tmp = strchr(tmp, AXIS2_EQ); + tmp2 = strchr(tmp, AXIS2_SEMI_COLON); + + if(tmp2) + { + *tmp2 = AXIS2_ESC_NULL; + } + if(!tmp) + { + AXIS2_FREE(env->allocator, tmp_content_type); + return NULL; + } + + tmp2 = axutil_strdup(env, tmp + 1); + + AXIS2_FREE(env->allocator, tmp_content_type); + if(*tmp2 == AXIS2_DOUBLE_QUOTE) + { + tmp = tmp2; + tmp2 = axutil_strdup(env, tmp + 1); + tmp2[strlen(tmp2) - 1] = AXIS2_ESC_NULL; + if(tmp) + { + AXIS2_FREE(env->allocator, tmp); + tmp = NULL; + } + + } + /* handle XOP */ + if(*tmp2 == AXIS2_B_SLASH && *(tmp2 + 1) == '\"') + { + tmp = tmp2; + tmp2 = axutil_strdup(env, tmp + 2); + tmp2[strlen(tmp2) - 3] = AXIS2_ESC_NULL; + if(tmp) + { + AXIS2_FREE(env->allocator, tmp); + tmp = NULL; + } + } + return tmp2; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axis2_http_transport_utils_handle_media_type_url_encoded( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axutil_hash_t * param_map, + axis2_char_t * method) +{ + axiom_soap_envelope_t *soap_env = NULL; + axiom_soap_body_t *soap_body = NULL; + axiom_element_t *body_child = NULL; + axiom_node_t *body_child_node = NULL; + axiom_node_t *body_element_node = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL); + AXIS2_PARAM_CHECK(env->error, method, NULL); + + soap_env = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + + if(!soap_env) + { + soap_env = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11); + } + soap_body = axiom_soap_envelope_get_body(soap_env, env); + if(!soap_body) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL, AXIS2_FAILURE); + return NULL; + } + + body_element_node = axiom_soap_body_get_base_node(soap_body, env); + + if(body_element_node) + { + body_child_node = axiom_node_get_first_child(body_element_node, env); + } + + if(!body_child_node) + { + if(!axis2_msg_ctx_get_op(msg_ctx, env)) + { + return NULL; + } + body_child = axiom_element_create_with_qname(env, NULL, axis2_op_get_qname( + axis2_msg_ctx_get_op(msg_ctx, env), env), &body_child_node); + axiom_soap_body_add_child(soap_body, env, body_child_node); + } + if(param_map) + { + axutil_hash_index_t *hi = NULL; + for(hi = axutil_hash_first(param_map, env); hi; hi = axutil_hash_next(env, hi)) + { + void *name = NULL; + void *value = NULL; + axiom_node_t *node = NULL; + axiom_element_t *element = NULL; + + axutil_hash_this(hi, (const void **)&name, NULL, (void **)&value); + element = axiom_element_create(env, NULL, (axis2_char_t *)name, NULL, &node); + axiom_element_set_text(element, env, (axis2_char_t *)value, node); + axiom_node_add_child(body_child_node, env, node); + } + } + return soap_env; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_dispatch_and_verify( + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_disp_t *rest_disp = NULL; + axis2_handler_t *handler = NULL; + + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + if(axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + { + rest_disp = axis2_rest_disp_create(env); + handler = axis2_disp_get_base(rest_disp, env); + axis2_handler_invoke(handler, env, msg_ctx); + + if(!axis2_msg_ctx_get_svc(msg_ctx, env) || !axis2_msg_ctx_get_op(msg_ctx, env)) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SVC_OR_OP_NOT_FOUND, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_http_transport_utils_process_accept_headers( + const axutil_env_t *env, + axis2_char_t *accept_value) +{ + axutil_array_list_t *accept_field_list = NULL; + axutil_array_list_t *accept_record_list = NULL; + accept_field_list = axutil_tokenize(env, accept_value, ','); + if(accept_field_list && axutil_array_list_size(accept_field_list, env) > 0) + { + axis2_char_t *token = NULL; + accept_record_list = axutil_array_list_create(env, axutil_array_list_size( + accept_field_list, env)); + do + { + if(token) + { + axis2_http_accept_record_t *rec = NULL; + rec = axis2_http_accept_record_create(env, token); + if(rec) + { + axutil_array_list_add(accept_field_list, env, rec); + } + AXIS2_FREE(env->allocator, token); + } + token = (axis2_char_t *)axutil_array_list_remove(accept_field_list, env, 0); + } + while(token); + } + if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0) + { + return accept_record_list; + } + return NULL; +} + +int +axis2_http_transport_utils_check_status_code( + int status_code) +{ + int status = AXIS2_HTTP_RESPONSE_OK_CODE_VAL; + switch(status_code) + { + case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_ACK_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_GONE_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL: + status = AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL; + break; + } + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_process_request( + const axutil_env_t *env, + axis2_conf_ctx_t *conf_ctx, + axis2_http_transport_in_t *request, + axis2_http_transport_out_t *response) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_msg_ctx_t *msg_ctx = NULL; + axutil_stream_t *out_stream = NULL; + axutil_string_t *soap_action = NULL; + axis2_bool_t processed = AXIS2_FALSE; + axis2_char_t *body_string = NULL; + axis2_char_t *ctx_uuid = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_char_t *peer_ip = NULL; + axutil_property_t *peer_property = NULL; + axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t **msg_ctx_map = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + AXIS2_PARAM_CHECK(env->error, request, AXIS2_CRITICAL_FAILURE); + AXIS2_PARAM_CHECK(env->error, request->request_uri, AXIS2_FALSE); + + if(!conf_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE); + return AXIS2_CRITICAL_FAILURE; + } + + if(!request->content_type) + { + request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN; + } + + /** creating the out stream */ + out_stream = axutil_stream_create_basic(env); + + if(request->transfer_encoding) + axis2_msg_ctx_set_transfer_encoding(request->msg_ctx, env, request->transfer_encoding); + + axis2_msg_ctx_set_server_side(request->msg_ctx, env, AXIS2_TRUE); + msg_ctx = request->msg_ctx; + peer_ip = request->remote_ip; + + if(peer_ip) + { + peer_property = axutil_property_create(env); + axutil_property_set_value(peer_property, env, axutil_strdup(env, peer_ip)); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_SVR_PEER_IP_ADDR, peer_property); + } + + axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream); + + ctx_uuid = axutil_uuid_gen(env); + if(ctx_uuid) + { + axutil_string_t *uuid_str = axutil_string_create_assume_ownership(env, &ctx_uuid); + axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, uuid_str); + axutil_string_free(uuid_str, env); + } + + axis2_msg_ctx_set_out_transport_info(msg_ctx, env, + &(request->out_transport_info->out_transport)); + + if(request->accept_header) + { + axutil_array_list_t *accept_record_list = NULL; + accept_record_list = axis2_http_transport_utils_process_accept_headers(env, + request->accept_header); + if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0) + { + axis2_msg_ctx_set_http_accept_record_list(msg_ctx, env, accept_record_list); + } + } + if(request->accept_charset_header) + { + axutil_array_list_t *accept_charset_record_list = NULL; + accept_charset_record_list = axis2_http_transport_utils_process_accept_headers(env, + request->accept_charset_header); + if(accept_charset_record_list) + { + axis2_msg_ctx_set_http_accept_charset_record_list(msg_ctx, env, + accept_charset_record_list); + } + } + if(request->accept_language_header) + { + axutil_array_list_t *accept_language_record_list = NULL; + accept_language_record_list = axis2_http_transport_utils_process_accept_headers(env, + request->accept_language_header); + if(accept_language_record_list) + { + axis2_msg_ctx_set_http_accept_language_record_list(msg_ctx, env, + accept_language_record_list); + } + } + + if(request->soap_action) + { + soap_action = axutil_string_create(env, request->soap_action); + } + + if(request->request_method == AXIS2_HTTP_METHOD_GET || request->request_method + == AXIS2_HTTP_METHOD_DELETE || request->request_method == AXIS2_HTTP_METHOD_HEAD) + { + + if(request->request_method == AXIS2_HTTP_METHOD_DELETE) + { + processed = axis2_http_transport_utils_process_http_delete_request(env, + request->msg_ctx, request->in_stream, out_stream, request->content_type, + soap_action, request->request_uri, conf_ctx, + axis2_http_transport_utils_get_request_params(env, request->request_uri)); + } + else if(request->request_method == AXIS2_HTTP_METHOD_HEAD) + { + processed = axis2_http_transport_utils_process_http_head_request(env, request->msg_ctx, + request->in_stream, out_stream, request->content_type, soap_action, + request->request_uri, conf_ctx, axis2_http_transport_utils_get_request_params(env, + request->request_uri)); + } + else if(request->request_method == AXIS2_HTTP_METHOD_GET) + { + processed = axis2_http_transport_utils_process_http_get_request(env, request->msg_ctx, + request->in_stream, out_stream, request->content_type, soap_action, + request->request_uri, conf_ctx, axis2_http_transport_utils_get_request_params(env, + request->request_uri)); + } + if(AXIS2_FALSE == processed) + { + axis2_bool_t is_services_path = AXIS2_FALSE; + int msg_ctx_status_code = axis2_msg_ctx_get_status_code(msg_ctx, env); + if(request->request_method != AXIS2_HTTP_METHOD_DELETE && request->request_url_prefix) + { + axis2_char_t *temp = NULL; + temp = strstr(request->request_uri, request->request_url_prefix); + if(temp) + { + temp += strlen(request->request_url_prefix); + if(*temp == '/') + { + temp++; + } + if(!*temp || *temp == '?' || *temp == '#') + { + is_services_path = AXIS2_TRUE; + } + } + } + if(is_services_path) + { + body_string = axis2_http_transport_utils_get_services_html(env, conf_ctx); + response->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; + response->http_status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_OK_CODE_NAME; + } + else if(AXIS2_HTTP_METHOD_DELETE != request->request_method) + { + axis2_char_t *wsdl = NULL; + wsdl = strstr(request->request_uri, AXIS2_REQUEST_WSDL); + if(wsdl) + { + body_string = axis2_http_transport_utils_get_services_static_wsdl(env, + conf_ctx, request->request_uri); + request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML; + response->http_status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_OK_CODE_NAME; + } + } + else if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND) + { + axutil_array_list_t *method_list = NULL; + int size = 0; + method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env); + size = axutil_array_list_size(method_list, env); + + if(method_list && size) + { + /** 405 */ + body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx); + + response->http_status_code = AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL; + response->http_status_code_name + = AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME; + } + else + { + /** 404 */ + body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME; + } + } + else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL) + { + /* 400, Bad Request */ + body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME; + + } + else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL) + { + /* 408, Request Timeout */ + body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME; + } + else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL) + { + /* 409, Conflict Types */ + body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME; + } + else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL) + { + /* 410, Gone. Resource no longer available */ + body_string = axis2_http_transport_utils_get_gone(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_GONE_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_GONE_CODE_NAME; + + } + else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL) + { + /*410, Precondition for the url failed */ + body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME; + + } + else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL) + { + /* 413, Request entity too large */ + body_string + = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL; + response->http_status_code_name + = AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME; + } + else if(msg_ctx_status_code == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL) + { + /* 513, Service Unavailable */ + body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME; + } + else + { + /* 500, Internal Server Error */ + body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL; + response->http_status_code_name + = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME; + } + + if(body_string) + { + response->response_data = body_string; + response->response_data_length = axutil_strlen(body_string); + } + status = AXIS2_SUCCESS; + } + } + else if(AXIS2_HTTP_METHOD_POST == request->request_method || AXIS2_HTTP_METHOD_PUT + == request->request_method) + { + if(AXIS2_HTTP_METHOD_POST == request->request_method) + { + processed = axis2_http_transport_utils_process_http_post_request(env, request->msg_ctx, + request->in_stream, out_stream, request->content_type, request->content_length, + soap_action, request->request_uri); + } + else + { + processed = axis2_http_transport_utils_process_http_put_request(env, request->msg_ctx, + request->in_stream, out_stream, request->content_type, request->content_length, + soap_action, request->request_uri); + } + if(AXIS2_FAILURE == processed && (AXIS2_HTTP_METHOD_PUT == request->request_method + || axis2_msg_ctx_get_doing_rest(msg_ctx, env))) + { + + if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND) + { + axutil_array_list_t *method_list = NULL; + int size = 0; + method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env); + size = axutil_array_list_size(method_list, env); + if(method_list && size) + { + /** 405 */ + body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL; + response->http_status_code_name + = AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME; + } + else + { + /** 404 */ + body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME; + } + request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; + } + else + { + /* 500, Internal Server Error */ + body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx); + response->http_status_code = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL; + response->http_status_code_name + = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME; + + } + + if(body_string) + { + response->response_data = body_string; + response->response_data_length = axutil_strlen(body_string); + } + status = AXIS2_SUCCESS; + } + else if(processed == AXIS2_FAILURE) + { + axis2_msg_ctx_t *fault_ctx = NULL; + axis2_char_t *fault_code = NULL; + axis2_engine_t *engine = axis2_engine_create(env, conf_ctx); + if(!engine) + { + /* Critical error, cannot proceed, send defaults document for 500 */ + return AXIS2_CRITICAL_FAILURE; + } + if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" + AXIOM_SOAP11_FAULT_CODE_SENDER; + } + else + { + fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" + AXIOM_SOAP12_SOAP_FAULT_VALUE_SENDER; + } + fault_ctx = axis2_engine_create_fault_msg_ctx(engine, env, request->msg_ctx, + fault_code, axutil_error_get_message(env->error)); + + axis2_engine_send_fault(engine, env, fault_ctx); + if (out_stream) + { + response->response_data = axutil_stream_get_buffer(out_stream, env); + response->response_data_length = axutil_stream_get_len (out_stream, env); + } + /* In case of a SOAP Fault, we have to set the status to 500, but still return */ + status = AXIS2_SUCCESS; + response->http_status_code = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME; + } + } + else + { + response->response_data = axis2_http_transport_utils_get_not_implemented(env, conf_ctx); + request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; + + if (response->response_data) + { + response->response_data_length = axutil_strlen(response->response_data); + } + response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_NAME; + status = AXIS2_SUCCESS; + } + + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + + if (op_ctx) + { + msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); + out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; + response->msg_ctx = out_msg_ctx; + } + + if (status == AXIS2_FAILURE) + { + axis2_bool_t do_rest = AXIS2_FALSE; + if (AXIS2_HTTP_METHOD_POST != request->request_method || + axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + { + do_rest = AXIS2_TRUE; + } + if ((request->accept_header || request->accept_charset_header || + request->accept_language_header) && do_rest) + { + axis2_char_t *content_type_header_value = NULL; + axis2_char_t *temp = NULL; + axis2_char_t *language_header_value = NULL; + + content_type_header_value = (axis2_char_t *) request->content_type; + language_header_value = axis2_msg_ctx_get_content_language(out_msg_ctx,env); + if (content_type_header_value) + { + temp = axutil_strdup(env, content_type_header_value); + } + if (temp) + { + axis2_char_t *content_type = NULL; + axis2_char_t *char_set = NULL; + axis2_char_t *temp2 = NULL; + + temp2 = strchr(temp, ';'); + if (temp2) + { + *temp2 = '\0'; + temp2++; + char_set = axutil_strcasestr(temp2, AXIS2_HTTP_CHAR_SET_ENCODING); + } + if (char_set) + { + char_set = axutil_strltrim(env, char_set, " \t="); + } + if (char_set) + { + temp2 = strchr(char_set, ';'); + } + if (temp2) + { + *temp2 = '\0'; + } + content_type = axutil_strtrim(env, temp, NULL); + + if (temp) + { + AXIS2_FREE(env->allocator, temp); + temp = NULL; + } + if (content_type && request->accept_header && + !axutil_strcasestr(request->accept_header, content_type)) + { + temp2 = strchr(content_type, '/'); + if (temp2) + { + *temp2 = '\0'; + temp = AXIS2_MALLOC(env->allocator, + sizeof(axis2_char_t) * ((int)strlen(content_type) + 3)); + if (!temp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FALSE; + } + sprintf(temp, "%s/*", content_type); + if (!axutil_strcasestr(request->accept_header, temp) && + !strstr(request->accept_header, AXIS2_HTTP_HEADER_ACCEPT_ALL)) + { + response->response_data = + axis2_http_transport_utils_get_not_acceptable(env, conf_ctx); + response->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; + if (response->response_data) + { + response->response_data_length = axutil_strlen(response->response_data); + } + response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_NAME; + status = AXIS2_TRUE; + } + AXIS2_FREE(env->allocator, temp); + } + } + if (content_type) + { + AXIS2_FREE(env->allocator, content_type); + } + if (char_set && request->accept_charset_header && + !axutil_strcasestr(request->accept_charset_header , char_set)) + { + response->response_data = + axis2_http_transport_utils_get_not_acceptable(env, conf_ctx); + response->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; + + if (response->response_data) + { + response->response_data_length= axutil_strlen(response->response_data); + } + status = AXIS2_SUCCESS; + response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME; + } + if (char_set) + { + AXIS2_FREE(env->allocator, char_set); + } + } + if (language_header_value) + { + if (request->accept_language_header && + !axutil_strcasestr(request->accept_language_header , language_header_value)) + { + response->response_data = + axis2_http_transport_utils_get_not_acceptable(env, conf_ctx); + response->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; + if (response->response_data) + { + response->response_data_length = axutil_strlen(response->response_data); + } + response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME; + } + } + } + } + if (status == AXIS2_FAILURE) + { + axis2_bool_t do_rest = AXIS2_FALSE; + if (AXIS2_HTTP_METHOD_POST != request->request_method || + axis2_msg_ctx_get_doing_rest(msg_ctx, env)) + { + do_rest = AXIS2_TRUE; + } + if (op_ctx && axis2_op_ctx_get_response_written(op_ctx, env)) + { + if (do_rest) + { + if (out_msg_ctx) + { + int size = 0; + axutil_array_list_t *output_header_list = NULL; + output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env); + if (output_header_list) + { + size = axutil_array_list_size(output_header_list, env); + response->output_headers = output_header_list; + } + + if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) + { + int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); + response->http_status_code = + axis2_http_transport_utils_check_status_code(status_code); + status = AXIS2_SUCCESS; + } + } + } + if (status == AXIS2_FAILURE) + { + status = AXIS2_SUCCESS; + if (out_stream) + { + response->response_data = axutil_stream_get_buffer(out_stream, env); + response->response_data_length = axutil_stream_get_len(out_stream, env); + response->http_status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_OK_CODE_NAME; + } + } + } + else if (op_ctx) + { + if (do_rest) + { + if (out_msg_ctx) + { + int size = 0; + axutil_array_list_t *output_header_list = NULL; + output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env); + if (output_header_list) + { + size = axutil_array_list_size(output_header_list, env); + response->output_headers = output_header_list; + } + if (axis2_msg_ctx_get_no_content(out_msg_ctx, env)) + { + if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) + { + int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); + switch (status_code) + { + case AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL: + response->http_status_code = AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL; + break; + case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: + response->http_status_code = AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL; + break; + default: + response->http_status_code = AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL; + break; + } + } + else + { + response->http_status_code = AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL; + } + status = AXIS2_SUCCESS; + } + else if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) + { + int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); + response->http_status_code = + axis2_http_transport_utils_check_status_code(status_code); + status = AXIS2_SUCCESS; + } + } + } + if (status == AXIS2_FAILURE) + { + response->http_status_code = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_ACK_CODE_NAME; + status = AXIS2_SUCCESS; + } + } + else + { + status = AXIS2_SUCCESS; + response->http_status_code = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL; + response->http_status_code_name = AXIS2_HTTP_RESPONSE_ACK_CODE_NAME; + } + } + axutil_string_free(soap_action, env); + msg_ctx = NULL; + + return status; +} + +/* This method takes an array_list as the input. It has items some + may be buffers and some may be files. This will send these part + one by one to the wire using the chunked stream.*/ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_transport_utils_send_mtom_message( + axutil_http_chunked_stream_t * chunked_stream, + const axutil_env_t * env, + axutil_array_list_t *mime_parts, + axis2_char_t *sending_callback_name) +{ + int i = 0; + axis2_status_t status = AXIS2_SUCCESS; + + for(i = 0; i < axutil_array_list_size(mime_parts, env); i++) + { + axiom_mime_part_t *mime_part = NULL; + mime_part = (axiom_mime_part_t *)axutil_array_list_get(mime_parts, env, i); + + /* If it is a buffer just write it to the wire. This includes mime_bounadaries, + * mime_headers and SOAP */ + if(mime_part->type == AXIOM_MIME_PART_BUFFER) + { + size_t written = 0; + while(written < mime_part->part_size) + { + int len = 0; + len = axutil_http_chunked_stream_write(chunked_stream, env, + mime_part->part + written, mime_part->part_size - written); + if(len == -1) + { + status = AXIS2_FAILURE; + break; + } + else + { + written += len; + } + } + } + + /* If it is a file we load a very little portion to memory and send it as chunked , + * we keep on doing this until we find the end of the file */ + else if(mime_part->type == AXIOM_MIME_PART_FILE) + { + FILE *f = NULL; + axis2_byte_t *output_buffer = NULL; + int output_buffer_size = 0; + + f = fopen(mime_part->file_name, "rb"); + if(!f) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error opening file %s for reading", + mime_part->file_name); + return AXIS2_FAILURE; + } + + /* If the part_size is less than the defined buffer size then + * from the first write to the wire we can send the file */ + if(mime_part->part_size > AXIS2_MTOM_OUTPUT_BUFFER_SIZE) + { + output_buffer_size = AXIS2_MTOM_OUTPUT_BUFFER_SIZE; + } + else + { + output_buffer_size = (int)mime_part->part_size; + } + + output_buffer = AXIS2_MALLOC(env->allocator, output_buffer_size * sizeof(axis2_char_t)); + + /*This is the method responsible for writing to the wire */ + status = axis2_http_transport_utils_send_attachment_using_file(env, chunked_stream, + f, output_buffer, output_buffer_size); + AXIS2_FREE(env->allocator, output_buffer); + fclose(f); + } + + /* if the callback is given, send data using callback */ + else if((mime_part->type) == AXIOM_MIME_PART_CALLBACK) + { + void *handler = NULL; + axiom_mtom_sending_callback_t *callback = NULL; + + handler = axis2_http_transport_utils_initiate_callback(env, sending_callback_name, + mime_part->user_param, &callback); + if(handler) + { + status = axis2_http_transport_utils_send_attachment_using_callback(env, + chunked_stream, callback, handler, mime_part->user_param); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MTOM Sending Callback loading failed"); + status = AXIS2_FAILURE; + } + + if(callback) + { + axutil_param_t *param = NULL; + param = callback->param; + AXIOM_MTOM_SENDING_CALLBACK_FREE(callback, env); + if(param) + { + axutil_param_free(param, env); + } + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unknown mime_part."); + status = AXIS2_FAILURE; + } + + if(status != AXIS2_SUCCESS) + { + break; + } + } + + if(status == AXIS2_SUCCESS) + { + /* send the end of chunk */ + status = axutil_http_chunked_stream_write_last_chunk(chunked_stream, env); + } + + return status; +} + +static axis2_status_t +axis2_http_transport_utils_send_attachment_using_file( + const axutil_env_t * env, + axutil_http_chunked_stream_t *chunked_stream, + FILE *fp, + axis2_byte_t *buffer, + int buffer_size) +{ + /*We do not load the whole file to memory. Just load a buffer_size portion + *and send it. Keep on doing this until the end of file */ + do + { + int written = 0; + int count = (int)fread(buffer, 1, buffer_size, fp); + if(ferror(fp) || (count < 0)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in reading file containing the attachment"); + return AXIS2_FAILURE; + } + + /* count == 0 is a valid case. If the file size is multiple of buffer_size, then last read + * will have count == 0 + */ + + /*Writing the part we loaded to memory to the wire*/ + while(written < count) + { + int len = axutil_http_chunked_stream_write(chunked_stream, env, + buffer + written, count - written); + if(len == -1) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "error in writing file to stream"); + return AXIS2_FAILURE; + } + + written += len; + } + } + while(!feof(fp)); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_transport_utils_destroy_mime_parts( + axutil_array_list_t *mime_parts, + const axutil_env_t *env) +{ + if (mime_parts) + { + int i = 0; + for (i = 0; i < axutil_array_list_size(mime_parts, env); i++) + { + axiom_mime_part_t *mime_part = NULL; + mime_part = (axiom_mime_part_t *) + axutil_array_list_get(mime_parts, env, i); + if (mime_part) + { + axiom_mime_part_free(mime_part, env); + } + } + axutil_array_list_free(mime_parts, env); + } +} + +AXIS2_EXTERN void *AXIS2_CALL +axis2_http_transport_utils_initiate_callback( + const axutil_env_t *env, + axis2_char_t *callback_name, + void *user_param, + axiom_mtom_sending_callback_t **callback) +{ + axutil_dll_desc_t *dll_desc = NULL; + axutil_param_t *impl_info_param = NULL; + void *ptr = NULL; + + if(!callback_name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "invalid callback name given"); + return NULL; + } + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Trying to load module = %s", callback_name); + + dll_desc = axutil_dll_desc_create(env); + axutil_dll_desc_set_name(dll_desc, env, callback_name); + impl_info_param = axutil_param_create(env, NULL, dll_desc); + axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg); + axutil_class_loader_init(env); + ptr = axutil_class_loader_create_dll(env, impl_info_param); + if (!ptr) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to load the module %s.", callback_name); + return NULL; + } + + *callback = (axiom_mtom_sending_callback_t *)ptr; + (*callback)->param = impl_info_param; + + return AXIOM_MTOM_SENDING_CALLBACK_INIT_HANDLER(*callback, env, user_param); +} + +static axis2_status_t +axis2_http_transport_utils_send_attachment_using_callback( + const axutil_env_t * env, + axutil_http_chunked_stream_t *chunked_stream, + axiom_mtom_sending_callback_t *callback, + void *handler, + void *user_param) +{ + int count = 0; + axis2_status_t status = AXIS2_SUCCESS; + axis2_char_t *buffer = NULL; + + /* Keep on loading the data in a loop until all the data is sent */ + while((count = AXIOM_MTOM_SENDING_CALLBACK_LOAD_DATA(callback, env, handler, &buffer)) > 0) + { + int written = 0; + while(written < count) + { + int len = 0; + len = axutil_http_chunked_stream_write(chunked_stream, env, + buffer + written, count - written); + if(len == -1) + { + status = AXIS2_FAILURE; + break; + } + + written += len; + } + } + + status = AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, handler) && status; + return status; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_transport_utils_is_callback_required( + const axutil_env_t *env, + axutil_array_list_t *mime_parts) +{ + int size = 0; + int i = 0; + axis2_bool_t is_required = AXIS2_FALSE; + + size = axutil_array_list_size(mime_parts, env); + for(i = 0; i < size; i++) + { + axiom_mime_part_t *mime_part = NULL; + mime_part = (axiom_mime_part_t *)axutil_array_list_get(mime_parts, env, i); + if(mime_part) + { + if(mime_part->type == AXIOM_MIME_PART_CALLBACK) + { + is_required = AXIS2_TRUE; + break; + } + } + } + + return is_required; +} + +static void +axis2_http_transport_utils_parse_session_str(const axutil_env_t *env, axis2_char_t *str, + axutil_hash_t *ht) +{ + while (*str) + { + axis2_char_t *next = axutil_strstr(str, ";"); + if (next) + { + axis2_char_t *key = NULL; + axis2_char_t *val = NULL; + + + /* Get key and value pairs */ + key = axis2_http_transport_utils_copy_key(env, str); + val = axis2_http_transport_utils_copy_value(env, str); + axutil_hash_set(ht, key, AXIS2_HASH_KEY_STRING, val); + + /* find next token */ + str = next + 1; + } + + } +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_session( + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx) +{ + axutil_hash_index_t *hi = NULL; + void *val = NULL; + const void *key = NULL; + axutil_hash_t *ht = NULL; + axis2_char_t *session_id = NULL; + axis2_char_t *time_str = NULL; + axis2_char_t *header_value = NULL; + axutil_date_time_t *expire_time = NULL; + axis2_char_t session_value[256]; + axis2_http_out_transport_info_t *out_info = NULL; + axis2_status_t status = AXIS2_SUCCESS; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_utils_get_session"); + ht = axis2_msg_ctx_get_property_value(msg_ctx, env, AXIS2_TRANSPORT_SESSION_TABLE); + if(!ht) + { + axis2_op_ctx_t *op_ctx = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); + if(op_ctx) + { + in_msg_ctx = axis2_op_ctx_get_msg_ctx(op_ctx, env, AXIS2_WSDL_MESSAGE_LABEL_IN); + if(in_msg_ctx) + { + ht = axis2_msg_ctx_get_property_value(in_msg_ctx, env, + AXIS2_TRANSPORT_SESSION_TABLE); + } + } + if(!ht) + { + return NULL; + } + } + session_id = axutil_hash_get(ht, "id", AXIS2_HASH_KEY_STRING); + if(!session_id) + { + /* Generate session and set it in session table */ + session_id = axutil_uuid_gen(env); + axutil_hash_set(ht, axutil_strdup(env, "id"), AXIS2_HASH_KEY_STRING, axutil_strdup(env, + session_id)); + + /* Generate expire time and set it in session table */ + expire_time = axutil_date_time_create_with_offset(env, AXIS2_TRANSPORT_SESSION_EXPIRE_DURATION); + time_str = axutil_strdup(env, axutil_date_time_serialize_date_time(expire_time, env)); + axutil_date_time_free(expire_time, env); + axutil_hash_set(ht, axutil_strdup(env, "expires"), AXIS2_HASH_KEY_STRING, time_str); + + sprintf(session_value, "%s", ""); + + for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_char_t *name = NULL; + axis2_char_t *value = NULL; + int len = -1; + + axutil_hash_this(hi, &key, NULL, &val); + name = (axis2_char_t *) key; + value = (axis2_char_t *) val; + if(name) + { + len = axutil_strlen(session_value); + sprintf(session_value + len, "%s=", name); + AXIS2_FREE(env->allocator, name); + } + if(value) + { + len = axutil_strlen(session_value); + sprintf(session_value + len, "%s;", value); + AXIS2_FREE(env->allocator, value); + } + } + + out_info = (axis2_http_out_transport_info_t *)axis2_msg_ctx_get_out_transport_info( + msg_ctx, env); + if(!out_info) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_OUT_TRNSPORT_INFO_NULL, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, header_value); + return NULL; + } + status = AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_SESSION(out_info, env, session_id, session_value); + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Inserting session value failed for session id %s", session_id); + return NULL; + } + } + else + { + time_str = axutil_hash_get(ht, "expires", AXIS2_HASH_KEY_STRING); + } + header_value = AXIS2_MALLOC(env->allocator, 256 * sizeof(axis2_char_t)); + sprintf(header_value, "ID=%s; expires=%s;", session_id, time_str); + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_utils_get_session"); + return header_value; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_transport_utils_set_session( + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx, + axis2_char_t *session_str) +{ + axutil_date_time_t *expire_time = NULL; + axutil_date_time_t *current_time = NULL; + axutil_date_time_comp_result_t result; + axis2_char_t *time_str = NULL; + axutil_hash_t *ht = NULL; + axutil_property_t *property = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_tranpsport_utils_set_session"); + + /* Check whether session has expired. If so set error and return */ + ht = axutil_hash_make(env); + axis2_http_transport_utils_parse_session_str(env, session_str, ht); + time_str = (axis2_char_t *) axutil_hash_get(ht, "time", AXIS2_HASH_KEY_STRING); + expire_time = axutil_date_time_create(env); + axutil_date_time_deserialize_date_time(expire_time, env, time_str); + current_time = axutil_date_time_create(env); + result = axutil_date_time_compare(current_time, env, expire_time); + axutil_date_time_free(current_time, env); + axutil_date_time_free(expire_time, env); + if(result == AXIS2_DATE_TIME_COMP_RES_EXPIRED) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + const void *key = NULL; + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Session time out"); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SESSION_TIMEOUT, AXIS2_FAILURE); + for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_char_t *name = NULL; + axis2_char_t *value = NULL; + + axutil_hash_this(hi, &key, NULL, &val); + name = (axis2_char_t *) key; + if(name) + { + AXIS2_FREE(env->allocator, name); + } + value = (axis2_char_t *) val; + if(value) + { + AXIS2_FREE(env->allocator, value); + } + } + axutil_hash_free(ht, env); + } + + property = axutil_property_create_with_args(env, 0, AXIS2_TRUE, 0, ht); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_SESSION_TABLE, property); + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_tranpsport_utils_set_session"); +} + +/** + * After receiving Set-Cookie header store it + */ +AXIS2_EXTERN void AXIS2_CALL +axis2_http_transport_utils_store_cookie( + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx, + axis2_char_t *cookie) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axutil_property_t *property = NULL; + axutil_hash_t *session_map = NULL; + axis2_endpoint_ref_t *endpoint = NULL; + const axis2_char_t *address = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_utils_store_cookie"); + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_TRANSPORT_SESSION_MAP); + if(property) + { + session_map = axutil_property_get_value(property, env); + } + if(!session_map) + { + if(!cookie) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "No session map found and no cookie set. So return"); + return; + } + session_map = axutil_hash_make(env); + if(session_map) + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 1, + axis2_http_transport_utils_session_map_free_void_arg, session_map); + axis2_conf_ctx_set_property(conf_ctx, env, AXIS2_TRANSPORT_SESSION_MAP, property); + } + else + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return; + } + } + endpoint = axis2_msg_ctx_get_to(msg_ctx, env); + if(endpoint) + { + address = axis2_endpoint_ref_get_address(endpoint, env); + if(address) + { + axutil_url_t *url = NULL; + + url = axutil_url_parse_string(env, address); + if(url) + { + axis2_char_t *server = NULL; + server = axutil_url_get_server(url, env); + if(server) + { + if(cookie) + { + axutil_hash_set(session_map, axutil_strdup(env, server), AXIS2_HASH_KEY_STRING, + axutil_strdup(env, cookie)); + } + else /* We remove any cookie set for this endpoint */ + { + cookie = axutil_hash_get(session_map, server, AXIS2_HASH_KEY_STRING); + if(cookie) + { + AXIS2_FREE(env->allocator, cookie); + } + axutil_hash_set(session_map, axutil_strdup(env, server), AXIS2_HASH_KEY_STRING, NULL); + } + } + axutil_url_free(url, env); + } + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_utils_store_cookie"); +} + +/* Read from cookie store before sending */ +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_read_from_cookie_store( + const axutil_env_t *env, + axis2_msg_ctx_t *msg_ctx) +{ + axutil_property_t *property = NULL; + axutil_hash_t *session_map = NULL; + axis2_endpoint_ref_t *endpoint = NULL; + const axis2_char_t *address = NULL; + axis2_char_t *cookie = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_utils_read_from_cookie_store"); + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_TRANSPORT_SESSION_MAP); + if(property) + { + session_map = axutil_property_get_value(property, env); + } + if(!session_map) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "No session map stored"); + return NULL; + } + endpoint = axis2_msg_ctx_get_to(msg_ctx, env); + if(endpoint) + { + address = axis2_endpoint_ref_get_address(endpoint, env); + if(address) + { + axutil_url_t *url = NULL; + url = axutil_url_parse_string(env, address); + if(url) + { + axis2_char_t *server = NULL; + server = axutil_url_get_server(url, env); + if(server) + { + cookie = axutil_hash_get(session_map, server, AXIS2_HASH_KEY_STRING); + } + axutil_url_free(url, env); + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "cookie:%s", cookie); + } + } + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_utils_read_from_cookie_store"); + return cookie; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_transport_utils_get_session_id_from_cookie( + const axutil_env_t *env, + axis2_char_t *cookie) +{ + axis2_char_t *next = NULL; + axis2_char_t *session_id = NULL; + + next = axutil_strstr(cookie, ";"); + if (next) + { + session_id = axis2_http_transport_utils_copy_value(env, cookie); + } + + return session_id; +} + +static axis2_char_t * +axis2_http_transport_utils_copy_key( + const axutil_env_t *env, + axis2_char_t *pair) +{ + axis2_char_t *p = axutil_strchr(pair, '='); + axis2_char_t *ret = NULL; + + if (p) + { + axis2_char_t c; + size_t len = p - pair; + c = pair[len]; + pair[len] = '\0'; + ret = axutil_strdup(env, pair); + pair[len] = c; + } + + return ret; +} + +static axis2_char_t * +axis2_http_transport_utils_copy_value( + const axutil_env_t *env, + axis2_char_t *pair) +{ + axis2_char_t *ret = NULL; + size_t len; + axis2_char_t c; + + pair = axutil_strchr(pair, '='); + if (pair) + { + pair++; + len = axutil_strchr(pair, ';') - pair; + c = pair[len]; + pair[len] = '\0'; + ret = axutil_strdup(env, pair); + pair[len] = c; + } + + return ret; +} + + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_transport_utils_session_map_free_void_arg( + void *sm_void, + const axutil_env_t *env) +{ + void *val = NULL; + const void *key = NULL; + axutil_hash_index_t *hi = NULL; + axutil_hash_t *ht = (axutil_hash_t *)sm_void; + + for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_char_t *name = NULL; + axis2_char_t *value = NULL; + + axutil_hash_this(hi, &key, NULL, &val); + name = (axis2_char_t *) key; + if(name) + { + AXIS2_FREE(env->allocator, name); + } + value = (axis2_char_t *) val; + if(value) + { + AXIS2_FREE(env->allocator, value); + } + } + axutil_hash_free(ht, env); +} + + diff --git a/src/core/transport/tcp/Makefile.am b/src/core/transport/tcp/Makefile.am new file mode 100644 index 0000000..79f45b7 --- /dev/null +++ b/src/core/transport/tcp/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = sender receiver server +EXTRA_DIST=axis2_simple_tcp_svr_conn.h axis2_tcp_svr_thread.h axis2_tcp_transport_sender.h axis2_tcp_server.h axis2_tcp_transport.h axis2_tcp_worker.h + diff --git a/src/core/transport/tcp/axis2_simple_tcp_svr_conn.h b/src/core/transport/tcp/axis2_simple_tcp_svr_conn.h new file mode 100644 index 0000000..c0d3b89 --- /dev/null +++ b/src/core/transport/tcp/axis2_simple_tcp_svr_conn.h @@ -0,0 +1,155 @@ + +/* + * 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 + * + * tcp://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_SIMPLE_HTTP_SVR_CONN_H +#define AXIS2_SIMPLE_HTTP_SVR_CONN_H + +/** + * @ingroup axis2_core_transport_tcp + * @{ + */ + +/** + * @file axis2_simple_tcp_svr_conn.h + * @brief Axis2 simple tcp server connection + */ + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axutil_stream.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct axis2_simple_tcp_svr_conn axis2_simple_tcp_svr_conn_t; + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_simple_tcp_svr_conn_close( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env); + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_simple_tcp_svr_conn_is_open( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env); + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + */ + + AXIS2_EXTERN axutil_stream_t *AXIS2_CALL + + axis2_simple_tcp_svr_conn_get_stream( + const axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env); + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + + axis2_simple_tcp_svr_conn_read_request( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env); + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + * @param timeout timeout + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_simple_tcp_svr_conn_set_rcv_timeout( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env, + int timeout); + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + * @param timeout timeout + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axis2_simple_tcp_svr_conn_set_snd_timeout( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env, + int timeout); + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + + axis2_simple_tcp_svr_conn_get_svr_ip( + const axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env); + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + + axis2_simple_tcp_svr_conn_get_peer_ip( + const axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env); + + /** + * @param svr_conn pointer to server connection struct + * @param env pointer to environment struct + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_simple_tcp_svr_conn_free( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env); + + /** + * creates axis2_simple_tcp_svr_conn struct + * @param env pointer to environment struct + * @param sockfd sockfd + */ + AXIS2_EXTERN axis2_simple_tcp_svr_conn_t *AXIS2_CALL + + axis2_simple_tcp_svr_conn_create( + const axutil_env_t * env, + int sockfd); + +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_SIMPLE_HTTP_SVR_CONN_H */ diff --git a/src/core/transport/tcp/axis2_tcp_server.h b/src/core/transport/tcp/axis2_tcp_server.h new file mode 100644 index 0000000..e4557a1 --- /dev/null +++ b/src/core/transport/tcp/axis2_tcp_server.h @@ -0,0 +1,60 @@ + +/* +* 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_TCP_SERVER_H +#define AXIS2_TCP_SERVER_H + +/** + * @defgroup axis2_tcp_server tcp server + * @ingroup axis2_core_trans_tcp + * @{ + */ + +/** + * @file axis2_tcp_server.h + * @brief axis2 TCP Server implementation + */ + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axis2_conf_ctx.h> +#include <axis2_transport_receiver.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL + axis2_tcp_server_create( + const axutil_env_t * env, + const axis2_char_t * repo, + const int port); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_tcp_server_stop( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + + /** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_TCP_SERVER_H */ diff --git a/src/core/transport/tcp/axis2_tcp_svr_thread.h b/src/core/transport/tcp/axis2_tcp_svr_thread.h new file mode 100644 index 0000000..aa22ea1 --- /dev/null +++ b/src/core/transport/tcp/axis2_tcp_svr_thread.h @@ -0,0 +1,117 @@ + +/* + * 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_TCP_SVR_THREAD_H +#define AXIS2_TCP_SVR_THREAD_H + +/** + * @defgroup axis2_tcp_svr_thread tcp server thread + * @ingroup axis2_core_trans_tcp + * @{ + */ + +/** + * @file axis2_tcp_svr_thread.h + * @brief axis2 TCP server listning thread implementation + */ + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axis2_tcp_worker.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** Type name for struct axist_tcp_svr_thread */ + typedef struct axis2_tcp_svr_thread axis2_tcp_svr_thread_t; + + /** + * @param svr_thread pointer to server thread + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_tcp_svr_thread_run( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env); + + /** + * @param svr_thread pointer to server thread + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_tcp_svr_thread_destroy( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env); + + /** + * @param svr_thread pointer to server thread + * @param env pointer to environment struct + */ + AXIS2_EXTERN int AXIS2_CALL + axis2_tcp_svr_thread_get_local_port( + const axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env); + + /** + * @param svr_thread pointer to server thread + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_tcp_svr_thread_is_running( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env); + + /** + * @param svr_thread pointer to server thread + * @param env pointer to environment struct + * @param worker pointer to worker + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_tcp_svr_thread_set_worker( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env, + axis2_tcp_worker_t * worker); + + /** + * @param svr_thread pointer to server thread + * @param env pointer to environment struct + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_tcp_svr_thread_free( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env); + + /** + * @param env pointer to environment struct + * @param port + */ + AXIS2_EXTERN axis2_tcp_svr_thread_t *AXIS2_CALL + + axis2_tcp_svr_thread_create( + const axutil_env_t * env, + int port); + + /** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_TCP_SVR_THREAD_H */ diff --git a/src/core/transport/tcp/axis2_tcp_transport.h b/src/core/transport/tcp/axis2_tcp_transport.h new file mode 100644 index 0000000..9c8c7db --- /dev/null +++ b/src/core/transport/tcp/axis2_tcp_transport.h @@ -0,0 +1,89 @@ + +/* +* Copyright 2004,2005 The Apache Software Foundation. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain count copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef AXIS2_TCP_TRANSPORT_H +#define AXIS2_TCP_TRANSPORT_H + +#include <axis2_const.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** @defgroup axis2_core_trans_tcp tcp transport + * @ingroup axis2_transport + * Description. + * @{ + */ + + /** + * @defgroup axis2_core_transport_tcp core tcp transport + * @ingroup axis2_core_trans_tcp + * @{ + */ + + /** + * @brief TCP protocol and message context constants. + * + */ +#define AXIS2_TCP_OUT_TRANSPORT_INFO "TCPOutTransportInfo" + + /** + * PROTOCOL_VERSION + */ +#define AXIS2_TCP_PROTOCOL_VERSION "PROTOCOL" + + /** + * SOCKET + */ +#define AXIS2_SOCKET "SOCKET" + + /** + * HEADER_HOST + */ +#define AXIS2_TCP_HOST "Host" + + /** + * SO_TIMEOUT + */ +#define AXIS2_TCP_SO_TIMEOUT "SO_TIMEOUT" + + /** + * CONNECTION_TIMEOUT + */ +#define AXIS2_TCP_CONNECTION_TIMEOUT "CONNECTION_TIMEOUT" + + /** + * DEFAULT_SO_TIMEOUT + */ +#define AXIS2_TCP_DEFAULT_SO_TIMEOUT 60000 + + /** + * DEFAULT_CONNECTION_TIMEOUT + */ +#define AXIS2_TCP_DEFAULT_CONNECTION_TIMEOUT 60000 + + /** + * Field TRANSPORT_TCP + */ +#define AXIS2_TRANSPORT_TCP "tcp" + +#ifdef __cplusplus +} +#endif +#endif /* AXIS2_TCP_TRANSPORT_H */ diff --git a/src/core/transport/tcp/axis2_tcp_transport_sender.h b/src/core/transport/tcp/axis2_tcp_transport_sender.h new file mode 100644 index 0000000..9d706e5 --- /dev/null +++ b/src/core/transport/tcp/axis2_tcp_transport_sender.h @@ -0,0 +1,59 @@ + +/* + * 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_TCP_TRANSPORT_SENDER_H +#define AXIS2_TCP_TRANSPORT_SENDER_H + +/** + * @defgroup axis2_tcp_transport_sender tcp transport sender + * @ingroup axis2_core_trans_tcp + * @{ + */ + +/** + * @file axis2_tcp_transport_sender.h + * @brief axis2 TCP Transport Sender (Handler) implementation + */ + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axis2_msg_ctx.h> +#include <axis2_conf_ctx.h> +#include <axis2_transport_out_desc.h> +#include <axis2_transport_sender.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @param env pointer to environment struct + */ + AXIS2_EXTERN axis2_transport_sender_t *AXIS2_CALL + + axis2_tcp_transport_sender_create( + const axutil_env_t * env); + + /** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_TCP_TRANSPORT_SENDER_H */ diff --git a/src/core/transport/tcp/axis2_tcp_worker.h b/src/core/transport/tcp/axis2_tcp_worker.h new file mode 100644 index 0000000..dcd74fc --- /dev/null +++ b/src/core/transport/tcp/axis2_tcp_worker.h @@ -0,0 +1,95 @@ + +/* + * 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 + * + * tcp://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_TCP_WORKER_H +#define AXIS2_TCP_WORKER_H + +/** + * @defgroup axis2_tcp_worker tcp worker + * @ingroup axis2_core_trans_tcp + * @{ + */ + +/** + * @file axis2_tcp_worker.h + * @brief axis2 TCP Worker + */ + +#include <axis2_const.h> +#include <axis2_defines.h> +#include <axutil_env.h> +#include <axis2_simple_tcp_svr_conn.h> +#include <axis2_conf_ctx.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** Type name for struct axis2_tcp_worker */ + typedef struct axis2_tcp_worker axis2_tcp_worker_t; + + /** + * @param tcp_worker pointer to tcp worker + * @param env pointer to environment struct + * @param svr_conn pointer to svr conn + * @param simple_request pointer to simple request + */ + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_tcp_worker_process_request( + axis2_tcp_worker_t * tcp_worker, + const axutil_env_t * env, + axis2_simple_tcp_svr_conn_t * svr_conn, + axis2_char_t * simple_request); + + /** + * @param tcp_worker pointer to tcp worker + * @param env pointer to environment struct + * @param port + * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_tcp_worker_set_svr_port( + axis2_tcp_worker_t * tcp_worker, + const axutil_env_t * env, + int port); + + /** + * @param tcp_worker pointer to tcp worker + * @param env pointer to environment strut + * @return void + */ + AXIS2_EXTERN void AXIS2_CALL + axis2_tcp_worker_free( + axis2_tcp_worker_t * tcp_worker, + const axutil_env_t * env); + + /** + * @param env pointer to environment struct + * @param conf_ctx pointer to configuration context + */ + AXIS2_EXTERN axis2_tcp_worker_t *AXIS2_CALL + axis2_tcp_worker_create( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* AXIS2_TCP_WORKER_H */ diff --git a/src/core/transport/tcp/receiver/Makefile.am b/src/core/transport/tcp/receiver/Makefile.am new file mode 100644 index 0000000..e3543dc --- /dev/null +++ b/src/core/transport/tcp/receiver/Makefile.am @@ -0,0 +1,23 @@ +lib_LTLIBRARIES = libaxis2_tcp_receiver.la +libaxis2_tcp_receiver_la_LIBADD=$(top_builddir)/util/src/libaxutil.la\ + $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la + + +libaxis2_tcp_receiver_la_SOURCES = tcp_svr_thread.c \ + tcp_worker.c \ + simple_tcp_svr_conn.c \ + tcp_receiver.c + + +libaxis2_tcp_receiver_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport\ + -I$(top_builddir)/src/core/transport/tcp \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/tcp/receiver/simple_tcp_svr_conn.c b/src/core/transport/tcp/receiver/simple_tcp_svr_conn.c new file mode 100644 index 0000000..a5fd9a9 --- /dev/null +++ b/src/core/transport/tcp/receiver/simple_tcp_svr_conn.c @@ -0,0 +1,181 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_simple_tcp_svr_conn.h> +#include <axis2_tcp_transport.h> +#include <axutil_string.h> +#include <axutil_network_handler.h> +#include <platforms/axutil_platform_auto_sense.h> + +struct axis2_simple_tcp_svr_conn +{ + int socket; + axutil_stream_t *stream; + axis2_char_t *buffer; +}; + +AXIS2_EXTERN axis2_simple_tcp_svr_conn_t *AXIS2_CALL +axis2_simple_tcp_svr_conn_create( + const axutil_env_t * env, + int sockfd) +{ + axis2_simple_tcp_svr_conn_t *svr_conn = NULL; + AXIS2_ENV_CHECK(env, NULL); + svr_conn = (axis2_simple_tcp_svr_conn_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_simple_tcp_svr_conn_t)); + + if(!svr_conn) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + svr_conn->socket = sockfd; + svr_conn->stream = NULL; + svr_conn->buffer = NULL; + + if(-1 != svr_conn->socket) + { + svr_conn->stream = axutil_stream_create_socket(env, svr_conn->socket); + if(!svr_conn->stream) + { + axis2_simple_tcp_svr_conn_free((axis2_simple_tcp_svr_conn_t *)svr_conn, env); + return NULL; + } + } + return svr_conn; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_simple_tcp_svr_conn_free( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + axis2_simple_tcp_svr_conn_close(svr_conn, env); + + AXIS2_FREE(env->allocator, svr_conn); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_tcp_svr_conn_close( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + axutil_stream_free(svr_conn->stream, env); + if(-1 != svr_conn->socket) + { + axutil_network_handler_close_socket(env, svr_conn->socket); + svr_conn->socket = -1; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_simple_tcp_svr_conn_is_open( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(-1 != svr_conn->socket) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axis2_simple_tcp_svr_conn_get_stream( + const axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return svr_conn->stream; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_simple_tcp_svr_conn_read_request( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + int size = 32000; + axis2_char_t str_line[32000]; + axis2_char_t tmp_buf[32000]; + int read = -1; + + AXIS2_ENV_CHECK(env, NULL); + + memset(str_line, 0, size); + while((read = axutil_stream_peek_socket(svr_conn->stream, env, tmp_buf, size - 1)) > 0) + { + tmp_buf[read] = '\0'; + if(read > 0) + { + read = axutil_stream_read(svr_conn->stream, env, tmp_buf, size - 1); + if(read > 0) + { + tmp_buf[read] = '\0'; + strcat(str_line, tmp_buf); + break; + } + else + { + break; + } + } + } + if(str_line > 0) + { + svr_conn->buffer = str_line; + } + return svr_conn->buffer; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_tcp_svr_conn_set_rcv_timeout( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env, + int timeout) +{ + return axutil_network_handler_set_sock_option(env, svr_conn->socket, SO_RCVTIMEO, timeout); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_tcp_svr_conn_set_snd_timeout( + axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env, + int timeout) +{ + return axutil_network_handler_set_sock_option(env, svr_conn->socket, SO_SNDTIMEO, timeout); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_simple_tcp_svr_conn_get_svr_ip( + const axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return axutil_network_handler_get_svr_ip(env, svr_conn->socket); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_simple_tcp_svr_conn_get_peer_ip( + const axis2_simple_tcp_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return axutil_network_handler_get_peer_ip(env, svr_conn->socket); +} diff --git a/src/core/transport/tcp/receiver/tcp_receiver.c b/src/core/transport/tcp/receiver/tcp_receiver.c new file mode 100644 index 0000000..0451217 --- /dev/null +++ b/src/core/transport/tcp/receiver/tcp_receiver.c @@ -0,0 +1,400 @@ +/* + * 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_tcp_transport.h> +#include <axis2_tcp_svr_thread.h> +#include <axis2_tcp_server.h> +#include <axis2_transport_in_desc.h> +#include <axutil_param_container.h> +#include <axutil_url.h> +#include <axis2_conf_init.h> +#include <stdlib.h> + +/** + * @brief TCP Client struct impl + * Axis2 TCP Client impl + */ + +typedef struct axis2_tcp_server_impl +{ + axis2_transport_receiver_t tcp_server; + axis2_tcp_svr_thread_t *svr_thread; + int port; + axis2_char_t *svr_ip; + axis2_conf_ctx_t *conf_ctx; + axis2_conf_ctx_t *conf_ctx_private; + axis2_conf_t *conf; + axis2_bool_t is_application_client_side; +} axis2_tcp_server_impl_t; + +#define AXIS2_INTF_TO_IMPL(tcp_server) \ + ((axis2_tcp_server_impl_t *)(tcp_server)) + +/***************************** Function headers *******************************/ + +axis2_status_t AXIS2_CALL +axis2_tcp_server_init( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_transport_in_desc_t * in_desc); + +axis2_status_t AXIS2_CALL +axis2_tcp_server_start( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_tcp_server_stop( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +axis2_conf_ctx_t *AXIS2_CALL axis2_tcp_server_get_conf_ctx( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +axis2_endpoint_ref_t *AXIS2_CALL axis2_tcp_server_get_reply_to_epr( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + const axis2_char_t * svc_name); + + +axis2_endpoint_ref_t *AXIS2_CALL axis2_tcp_server_get_epr_for_service( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + const axis2_char_t * svc_name); + + +axis2_bool_t AXIS2_CALL +axis2_tcp_server_is_running( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +static void AXIS2_CALL +axis2_tcp_server_set_is_application_client_side( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + axis2_bool_t is_application_client_side); + +void AXIS2_CALL axis2_tcp_server_free( + axis2_transport_receiver_t * server, + const axutil_env_t * env); + +static axis2_char_t* AXIS2_CALL +axis2_tcp_server_get_server_ip( +axis2_transport_receiver_t *server, +const axutil_env_t *env); + +static void AXIS2_CALL +axis2_tcp_server_set_server_ip( +axis2_transport_receiver_t *transport_receiver, +const axutil_env_t *env, + axis2_char_t *serverip); + +static const axis2_transport_receiver_ops_t tcp_transport_receiver_ops_var = { + axis2_tcp_server_init, + axis2_tcp_server_start, + axis2_tcp_server_get_reply_to_epr, + axis2_tcp_server_get_epr_for_service, + axis2_tcp_server_get_server_ip, + axis2_tcp_server_set_server_ip, + axis2_tcp_server_get_conf_ctx, + axis2_tcp_server_is_running, + axis2_tcp_server_set_is_application_client_side, + axis2_tcp_server_stop, + axis2_tcp_server_free }; + +AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL +axis2_tcp_server_create( + const axutil_env_t * env, + const axis2_char_t * repo, + const int port) +{ + axis2_tcp_server_impl_t *server_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + + server_impl = (axis2_tcp_server_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_tcp_server_impl_t)); + + if(!server_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + server_impl->svr_thread = NULL; + server_impl->conf_ctx = NULL; + server_impl->conf_ctx_private = NULL; + server_impl->port = port; + server_impl->svr_ip = NULL; + server_impl->tcp_server.ops = &tcp_transport_receiver_ops_var; + + if(repo) + { + + /** + * We first create a private conf ctx which is owned by this server + * we only free this private conf context. We should never free the + * server_impl->conf_ctx because it may own to any other object which + * may lead to double free + */ + server_impl->conf_ctx_private = axis2_build_conf_ctx(env, repo); + if(!server_impl->conf_ctx_private) + { + axis2_tcp_server_free((axis2_transport_receiver_t *)server_impl, env); + return NULL; + } + server_impl->conf_ctx = server_impl->conf_ctx_private; + } + return &(server_impl->tcp_server); +} + +void AXIS2_CALL +axis2_tcp_server_free( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + axis2_tcp_server_impl_t *server_impl = NULL; + AXIS2_ENV_CHECK(env, void); + server_impl = AXIS2_INTF_TO_IMPL(server); + if(server_impl->svr_thread) + { + axis2_tcp_svr_thread_destroy(server_impl->svr_thread, env); + axis2_tcp_svr_thread_free(server_impl->svr_thread, env); + server_impl->svr_thread = NULL; + } + + if(server_impl->conf_ctx_private) + { + axis2_conf_ctx_free(server_impl->conf_ctx_private, env); + server_impl->conf_ctx_private = NULL; + } + + /** + * Do not free this. It may own to some other object + */ + server_impl->conf_ctx = NULL; + AXIS2_FREE(env->allocator, server_impl); + return; +} + +static void AXIS2_CALL +axis2_tcp_server_set_is_application_client_side( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + axis2_bool_t is_application_client_side) +{ + axis2_tcp_server_impl_t *server_impl = NULL; + server_impl = AXIS2_INTF_TO_IMPL(server); + server_impl->is_application_client_side = is_application_client_side; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_server_init( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_transport_in_desc_t * in_desc) +{ + axis2_tcp_server_impl_t *server_impl = NULL; + axis2_char_t *port_str = NULL; + axutil_param_t *param = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + server_impl = AXIS2_INTF_TO_IMPL(server); + + server_impl->conf_ctx = conf_ctx; + param = (axutil_param_t *)axutil_param_container_get_param( + axis2_transport_in_desc_param_container(in_desc, env), env, "port"); + if(param) + { + port_str = axutil_param_get_value(param, env); + } + if(port_str) + { + server_impl->port = atoi(port_str); + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_server_start( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + + axis2_tcp_server_impl_t *server_impl = NULL; + axis2_tcp_worker_t *worker = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + server_impl = AXIS2_INTF_TO_IMPL(server); + server_impl->svr_thread = axis2_tcp_svr_thread_create(env, server_impl->port); + if(!server_impl->svr_thread) + { + return AXIS2_FAILURE; + } + worker = axis2_tcp_worker_create(env, server_impl->conf_ctx); + axis2_tcp_worker_set_svr_port(worker, env, server_impl->port); + if(!worker) + { + axis2_tcp_svr_thread_free(server_impl->svr_thread, env); + return AXIS2_FAILURE; + } + AXIS2_LOG_INFO(env->log, "Starting TCP server thread"); + axis2_tcp_svr_thread_set_worker(server_impl->svr_thread, env, worker); + axis2_tcp_svr_thread_run(server_impl->svr_thread, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_tcp_server_stop( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + AXIS2_LOG_INFO(env->log, "Terminating TCP server thread"); + if(AXIS2_INTF_TO_IMPL(server)->svr_thread) + { + axis2_tcp_svr_thread_destroy(AXIS2_INTF_TO_IMPL(server)->svr_thread, env); + } + AXIS2_LOG_INFO(env->log, "Successfully terminated TCP server" " thread"); + return AXIS2_SUCCESS; +} + +axis2_conf_ctx_t *AXIS2_CALL +axis2_tcp_server_get_conf_ctx( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return AXIS2_INTF_TO_IMPL(server)->conf_ctx; +} + +axis2_endpoint_ref_t *AXIS2_CALL +axis2_tcp_server_get_reply_to_epr( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + axis2_endpoint_ref_t *epr = NULL; + const axis2_char_t *host_address = NULL; + axis2_char_t *svc_path = NULL; + axutil_url_t *url = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, svc_name, NULL); + + host_address = "127.0.0.1"; /* TODO : get from axis2.xml */ + svc_path = axutil_stracat(env, "/axis2/services/", svc_name); + url = axutil_url_create(env, "tcp", host_address, AXIS2_INTF_TO_IMPL(server)->port, svc_path); + AXIS2_FREE(env->allocator, svc_path); + if(!url) + { + return NULL; + } + epr = axis2_endpoint_ref_create(env, axutil_url_to_external_form(url, env)); + axutil_url_free(url, env); + return epr; +} + +axis2_endpoint_ref_t *AXIS2_CALL +axis2_tcp_server_get_epr_for_service( + axis2_transport_receiver_t * server, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + axis2_endpoint_ref_t *epr = NULL; + const axis2_char_t *host_address = NULL; + axis2_char_t *svc_path = NULL; + axutil_url_t *url = NULL; + + AXIS2_PARAM_CHECK(env->error, svc_name, NULL); + host_address = "127.0.0.1"; /* TODO : get from axis2.xml */ + svc_path = axutil_stracat(env, "/axis2/services/", svc_name); + + url = axutil_url_create(env, "tcp", host_address, AXIS2_INTF_TO_IMPL(server)->port, svc_path); + AXIS2_FREE(env->allocator, svc_path); + if(!url) + { + return NULL; + } + epr = axis2_endpoint_ref_create(env, axutil_url_to_external_form(url, env)); + axutil_url_free(url, env); + return epr; +} + +axis2_bool_t AXIS2_CALL +axis2_tcp_server_is_running( + axis2_transport_receiver_t * server, + const axutil_env_t * env) +{ + axis2_tcp_server_impl_t *server_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + server_impl = AXIS2_INTF_TO_IMPL(server); + if(!server_impl->svr_thread) + { + return AXIS2_FALSE; + } + return axis2_tcp_svr_thread_is_running(server_impl->svr_thread, env); +} + +static axis2_char_t* AXIS2_CALL +axis2_tcp_server_get_server_ip( +axis2_transport_receiver_t *server, +const axutil_env_t *env) +{ + return AXIS2_INTF_TO_IMPL(server)->svr_ip; +} + +static void AXIS2_CALL +axis2_tcp_server_set_server_ip( +axis2_transport_receiver_t *server, +const axutil_env_t *env, + axis2_char_t *serverip) +{ + AXIS2_INTF_TO_IMPL(server)->svr_ip = serverip; +} + + +/** + * Following block distinguish the exposed part of the dll. + */ +AXIS2_EXPORT int +axis2_get_instance( + struct axis2_transport_receiver **inst, + const axutil_env_t * env) +{ + *inst = axis2_tcp_server_create(env, NULL, -1); + if(!(*inst)) + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT int +axis2_remove_instance( + axis2_transport_receiver_t * inst, + const axutil_env_t * env) +{ + if(inst) + { + axis2_transport_receiver_free(inst, env); + } + return AXIS2_SUCCESS; +} diff --git a/src/core/transport/tcp/receiver/tcp_svr_thread.c b/src/core/transport/tcp/receiver/tcp_svr_thread.c new file mode 100644 index 0000000..5543394 --- /dev/null +++ b/src/core/transport/tcp/receiver/tcp_svr_thread.c @@ -0,0 +1,297 @@ +/* + * 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 + * + * tcp://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <platforms/axutil_platform_auto_sense.h> +#include <axis2_tcp_svr_thread.h> +#include <axis2_simple_tcp_svr_conn.h> +#include <axis2_tcp_server.h> +#include <axis2_tcp_transport.h> +#include <axutil_string.h> +#include <axutil_network_handler.h> +#include <axis2_simple_tcp_svr_conn.h> +#include <axutil_url.h> +#include <axutil_error_default.h> +#include <axiom_xml_reader.h> +#include <signal.h> + +AXIS2_EXPORT int axis2_tcp_socket_read_timeout = AXIS2_TCP_DEFAULT_SO_TIMEOUT; + +struct axis2_tcp_svr_thread +{ + int listen_socket; + axis2_bool_t stopped; + axis2_tcp_worker_t *worker; + int port; +}; + +typedef struct axis2_tcp_svr_thd_args +{ + axutil_env_t *env; + axis2_socket_t socket; + axis2_tcp_worker_t *worker; + axutil_thread_t *thread; +} axis2_tcp_svr_thd_args_t; + +AXIS2_EXTERN const axutil_env_t *AXIS2_CALL init_thread_env( + const axutil_env_t ** system_env); + +void *AXIS2_THREAD_FUNC axis2_svr_thread_worker_func( + axutil_thread_t * thd, + void *data); + +axis2_tcp_svr_thread_t *AXIS2_CALL +axis2_tcp_svr_thread_create( + const axutil_env_t * env, + int port) +{ + axis2_tcp_svr_thread_t *svr_thread = NULL; + AXIS2_ENV_CHECK(env, NULL); + + svr_thread = (axis2_tcp_svr_thread_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_tcp_svr_thread_t)); + + if(!svr_thread) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + svr_thread->worker = NULL; + svr_thread->stopped = AXIS2_FALSE; + svr_thread->port = port; + svr_thread->listen_socket = (int)axutil_network_handler_create_server_socket(env, + svr_thread->port); + if(-1 == svr_thread->listen_socket) + { + axis2_tcp_svr_thread_free((axis2_tcp_svr_thread_t *)svr_thread, env); + return NULL; + } + + return svr_thread; +} + +void AXIS2_CALL +axis2_tcp_svr_thread_free( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(svr_thread->worker) + { + axis2_tcp_worker_free(svr_thread->worker, env); + svr_thread->worker = NULL; + } + if(-1 != svr_thread->listen_socket) + { + axutil_network_handler_close_socket(env, svr_thread->listen_socket); + svr_thread->listen_socket = -1; + } + svr_thread->stopped = AXIS2_TRUE; + + AXIS2_FREE(env->allocator, svr_thread); + return; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_svr_thread_run( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + while(AXIS2_FALSE == svr_thread->stopped) + { + int socket = -1; + axis2_tcp_svr_thd_args_t *arg_list = NULL; +#ifdef AXIS2_SVR_MULTI_THREADED + axutil_thread_t *worker_thread = NULL; +#endif + + socket = (int)axutil_network_handler_svr_socket_accept(env, svr_thread-> listen_socket); + if(!svr_thread->worker) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "Worker not ready yet." + " Cannot serve the request"); + axutil_network_handler_close_socket(env, socket); + continue; + } + arg_list = AXIS2_MALLOC(env->allocator, sizeof(axis2_tcp_svr_thd_args_t)); + if(!arg_list) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Memory allocation error in the svr thread loop"); + continue; + } + arg_list->env = (axutil_env_t *)env; + arg_list->socket = socket; + arg_list->worker = svr_thread->worker; +#ifdef AXIS2_SVR_MULTI_THREADED + worker_thread = axutil_thread_pool_get_thread(env->thread_pool, + axis2_svr_thread_worker_func, + (void *) arg_list); + if (!worker_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Thread creation failed" + "server thread loop"); + continue; + } + axutil_thread_pool_thread_detach(env->thread_pool, worker_thread); +#else + axis2_svr_thread_worker_func(NULL, (void *)arg_list); +#endif + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_svr_thread_destroy( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); + + if(AXIS2_TRUE == svr_thread->stopped) + { + return AXIS2_SUCCESS; + } + svr_thread->stopped = AXIS2_TRUE; + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Terminating TCP server " + "thread."); + if(svr_thread->listen_socket) + { + axutil_network_handler_close_socket(env, svr_thread->listen_socket); + svr_thread->listen_socket = -1; + } + return AXIS2_SUCCESS; +} + +int AXIS2_CALL +axis2_tcp_svr_thread_get_local_port( + const axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + return svr_thread->port; +} + +axis2_bool_t AXIS2_CALL +axis2_tcp_svr_thread_is_running( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env) +{ + return svr_thread->port; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_svr_thread_set_worker( + axis2_tcp_svr_thread_t * svr_thread, + const axutil_env_t * env, + axis2_tcp_worker_t * worker) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, worker, AXIS2_FAILURE); + svr_thread->worker = worker; + return AXIS2_SUCCESS; +} + +/** + * Thread worker function. + */ +void *AXIS2_THREAD_FUNC +axis2_svr_thread_worker_func( + axutil_thread_t * thd, + void *data) +{ + struct AXIS2_PLATFORM_TIMEB t1, t2; + axis2_simple_tcp_svr_conn_t *svr_conn = NULL; + axis2_char_t *request = NULL; + int millisecs = 0; + double secs = 0; + axis2_tcp_worker_t *tmp = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_env_t *env = NULL; + axis2_socket_t socket; + axutil_env_t *thread_env = NULL; + axis2_tcp_svr_thd_args_t *arg_list = NULL; + +#ifndef WIN32 +#ifdef AXIS2_SVR_MULTI_THREADED + signal(SIGPIPE, SIG_IGN); +#endif +#endif + + arg_list = (axis2_tcp_svr_thd_args_t *)data; + if(!arg_list) + { + return NULL; + } + AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t1); + env = arg_list->env; + thread_env = axutil_init_thread_env(env); + socket = arg_list->socket; + svr_conn = axis2_simple_tcp_svr_conn_create(thread_env, (int)socket); + axis2_simple_tcp_svr_conn_set_rcv_timeout(svr_conn, thread_env, axis2_tcp_socket_read_timeout); + request = axis2_simple_tcp_svr_conn_read_request(svr_conn, thread_env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "tcp request %s", request); + tmp = arg_list->worker; + status = axis2_tcp_worker_process_request(tmp, thread_env, svr_conn, request); + axis2_simple_tcp_svr_conn_free(svr_conn, thread_env); + + AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t2); + millisecs = t2.millitm - t1.millitm; + secs = difftime(t2.time, t1.time); + if(millisecs < 0) + { + millisecs += 1000; + secs--; + } + secs += millisecs / 1000.0; + + if(status == AXIS2_SUCCESS) + { +#if defined(WIN32) + AXIS2_LOG_INFO(thread_env->log, "Request served successfully"); +#else + AXIS2_LOG_INFO(thread_env->log, "Request served in %.3f seconds", secs); +#endif + } + else + { +#if defined(WIN32) + AXIS2_LOG_WARNING(thread_env->log, AXIS2_LOG_SI, + "Error occured in processing request "); +#else + AXIS2_LOG_WARNING(thread_env->log, AXIS2_LOG_SI, + "Error occured in processing request (%.3f seconds)", secs); +#endif + } + + AXIS2_FREE(thread_env->allocator, arg_list); + + if(thread_env) + { + /* There is a persistant problem: Uncomment this after fix + * the issue */ + /* axutil_free_thread_env(thread_env); */ + thread_env = NULL; + } +#ifdef AXIS2_SVR_MULTI_THREADED + axutil_thread_pool_exit_thread(env->thread_pool, thd); +#endif + + return NULL; +} diff --git a/src/core/transport/tcp/receiver/tcp_worker.c b/src/core/transport/tcp/receiver/tcp_worker.c new file mode 100644 index 0000000..217519d --- /dev/null +++ b/src/core/transport/tcp/receiver/tcp_worker.c @@ -0,0 +1,180 @@ +/* + * 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 + * + * tcp://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_tcp_worker.h> +#include <axutil_string.h> +#include <axis2_tcp_transport.h> +#include <axis2_conf.h> +#include <axutil_string.h> +#include <axutil_stream.h> +#include <axis2_msg_ctx.h> +#include <axis2_op_ctx.h> +#include <axis2_engine.h> +#include <axutil_uuid_gen.h> +#include <axutil_url.h> +#include <axutil_property.h> +#include <string.h> +#include <axiom_soap.h> +#include <axiom.h> +#include <axis2_simple_tcp_svr_conn.h> + +struct axis2_tcp_worker +{ + axis2_conf_ctx_t *conf_ctx; + int svr_port; +}; + +AXIS2_EXTERN axis2_tcp_worker_t *AXIS2_CALL +axis2_tcp_worker_create( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_tcp_worker_t *tcp_worker = NULL; + AXIS2_ENV_CHECK(env, NULL); + tcp_worker = (axis2_tcp_worker_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_tcp_worker_t)); + + if(!tcp_worker) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + tcp_worker->conf_ctx = conf_ctx; + tcp_worker->svr_port = 9090; /* default - must set later */ + + return tcp_worker; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_tcp_worker_free( + axis2_tcp_worker_t * tcp_worker, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + tcp_worker->conf_ctx = NULL; + + AXIS2_FREE(env->allocator, tcp_worker); + + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_tcp_worker_process_request( + axis2_tcp_worker_t * tcp_worker, + const axutil_env_t * env, + axis2_simple_tcp_svr_conn_t * svr_conn, + axis2_char_t * simple_request) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_transport_out_desc_t *out_desc = NULL; + axis2_transport_in_desc_t *in_desc = NULL; + axis2_msg_ctx_t *msg_ctx = NULL; + axiom_xml_reader_t *reader = NULL; + axiom_stax_builder_t *builder = NULL; + axiom_soap_builder_t *soap_builder = NULL; + axiom_soap_envelope_t *soap_envelope = NULL; + axis2_engine_t *engine = NULL; + axis2_status_t status = AXIS2_FALSE; + axutil_stream_t *svr_stream = NULL; + axis2_char_t *buffer = NULL; + int len = 0; + int write = -1; + axutil_stream_t *out_stream = NULL; + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "start:axis2_tcp_worker_process_request"); + + out_stream = axutil_stream_create_basic(env); + reader = axiom_xml_reader_create_for_memory(env, simple_request, axutil_strlen(simple_request), + NULL, AXIS2_XML_PARSER_TYPE_BUFFER); + if(!reader) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to create XML reader"); + return AXIS2_FAILURE; + } + + builder = axiom_stax_builder_create(env, reader); + if(!builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to create Stax builder"); + return AXIS2_FAILURE; + } + + soap_builder + = axiom_soap_builder_create(env, builder, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI); + + if(!soap_builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to create SOAP builder"); + return AXIS2_FAILURE; + } + + conf_ctx = tcp_worker->conf_ctx; + + if(!conf_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "conf ctx not available"); + return AXIS2_FAILURE; + } + + out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_TCP); + if(!out_desc) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport out not set"); + return AXIS2_FAILURE; + } + + in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_TCP); + + msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc); + axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); + axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream); + + soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + + engine = axis2_engine_create(env, conf_ctx); + status = axis2_engine_receive(engine, env, msg_ctx); + + svr_stream = axis2_simple_tcp_svr_conn_get_stream(svr_conn, env); + buffer = out_stream->buffer; + len = out_stream->len; + buffer[len] = 0; + if(svr_stream && buffer) + { + write = axutil_stream_write(svr_stream, env, buffer, len + 1); + if(write < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "stream write failed"); + return AXIS2_FAILURE; + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "stream wrote:%s", buffer); + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "end:axis2_tcp_worker_process_request"); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_tcp_worker_set_svr_port( + axis2_tcp_worker_t * worker, + const axutil_env_t * env, + int port) +{ + worker->svr_port = port; + return AXIS2_SUCCESS; +} diff --git a/src/core/transport/tcp/sender/Makefile.am b/src/core/transport/tcp/sender/Makefile.am new file mode 100644 index 0000000..1e35b3d --- /dev/null +++ b/src/core/transport/tcp/sender/Makefile.am @@ -0,0 +1,26 @@ +lib_LTLIBRARIES = libaxis2_tcp_sender.la + +libaxis2_tcp_sender_la_SOURCES = tcp_transport_sender.c + +libaxis2_tcp_sender_la_LIBADD = $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la\ + $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la\ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la\ + $(top_builddir)/util/src/libaxutil.la\ + $(LIBCURL_LIBS)\ + $(SSL_LIBS) + + +libaxis2_tcp_sender_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport\ + -I$(top_builddir)/src/core/transport/tcp \ + -I$(top_builddir)/src/core/transport/tcp/sender/libcurl \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I.. \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/tcp/sender/tcp_transport_sender.c b/src/core/transport/tcp/sender/tcp_transport_sender.c new file mode 100644 index 0000000..62f34d3 --- /dev/null +++ b/src/core/transport/tcp/sender/tcp_transport_sender.c @@ -0,0 +1,477 @@ +/* + * 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 + * + * tcp://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_tcp_transport_sender.h> +#include <axutil_string.h> +#include <axis2_endpoint_ref.h> +#include <axis2_addr.h> +#include <axiom_xml_writer.h> +#include <axiom_output.h> +#include <axis2_tcp_transport.h> +#include <axiom_soap_body.h> +#include <axiom_soap.h> +#include <axutil_generic_obj.h> +#include <axutil_types.h> +#include <axutil_url.h> +#include <axutil_network_handler.h> + +#define RES_BUFF 50 + +/** + * TCP Transport Sender struct impl + * Axis2 TCP Transport Sender impl + */ + +typedef struct axis2_tcp_transport_sender_impl +{ + axis2_transport_sender_t transport_sender; + int connection_timeout; + int so_timeout; +} axis2_tcp_transport_sender_impl_t; + +#define AXIS2_INTF_TO_IMPL(transport_sender) \ + ((axis2_tcp_transport_sender_impl_t *) \ + (transport_sender)) + +/***************************** Function headers *******************************/ +axis2_status_t AXIS2_CALL +axis2_tcp_transport_sender_invoke( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +axis2_status_t AXIS2_CALL +axis2_tcp_transport_sender_clean_up( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx); + +axis2_status_t AXIS2_CALL +axis2_tcp_transport_sender_init( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_transport_out_desc_t * out_desc); + +axis2_status_t AXIS2_CALL +axis2_tcp_transport_sender_write_message( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_endpoint_ref_t * epr, + axiom_soap_envelope_t * out, + axiom_output_t * om_output); + +void AXIS2_CALL axis2_tcp_transport_sender_free( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env); + +static const axis2_transport_sender_ops_t tcp_transport_sender_ops_var = { + axis2_tcp_transport_sender_init, axis2_tcp_transport_sender_invoke, + axis2_tcp_transport_sender_clean_up, axis2_tcp_transport_sender_free }; + +axis2_transport_sender_t *AXIS2_CALL +axis2_tcp_transport_sender_create( + const axutil_env_t * env) +{ + axis2_tcp_transport_sender_impl_t *transport_sender_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + + transport_sender_impl = (axis2_tcp_transport_sender_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_tcp_transport_sender_impl_t)); + + if(!transport_sender_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + transport_sender_impl->connection_timeout = AXIS2_TCP_DEFAULT_CONNECTION_TIMEOUT; + transport_sender_impl->so_timeout = AXIS2_TCP_DEFAULT_SO_TIMEOUT; + transport_sender_impl->transport_sender.ops = &tcp_transport_sender_ops_var; + return &(transport_sender_impl->transport_sender); +} + +void AXIS2_CALL +axis2_tcp_transport_sender_free( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env) +{ + axis2_tcp_transport_sender_impl_t *transport_sender_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + transport_sender_impl = AXIS2_INTF_TO_IMPL(transport_sender); + AXIS2_FREE(env->allocator, transport_sender_impl); + return; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_transport_sender_invoke( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + axis2_op_t *op = NULL; + const axis2_char_t *mep_uri = NULL; + axis2_bool_t is_server = AXIS2_TRUE; + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axiom_output_t *om_output = NULL; + axis2_char_t *buffer = NULL; + axutil_stream_t *out_stream = NULL; + int buffer_size = 0; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_out_desc_t *trans_desc = NULL; + axutil_param_t *write_xml_declaration_param = NULL; + axutil_hash_t *transport_attrs = NULL; + axis2_bool_t write_xml_declaration = AXIS2_FALSE; + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "start:tcp transport sender invoke"); + + op = axis2_msg_ctx_get_op(msg_ctx, env); + mep_uri = axis2_op_get_msg_exchange_pattern(op, env); + + is_server = axis2_msg_ctx_get_server_side(msg_ctx, env); + + soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[tcp]Failed to create XML writer"); + return AXIS2_FAILURE; + } + + om_output = axiom_output_create(env, xml_writer); + if(!om_output) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[tcp]Failed to create OM output"); + axiom_xml_writer_free(xml_writer, env); + xml_writer = NULL; + return AXIS2_FAILURE; + } + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + } + if(conf) + { + trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_TCP); + } + if(trans_desc) + { + write_xml_declaration_param = axutil_param_container_get_param( + axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_XML_DECLARATION); + } + if(write_xml_declaration_param) + { + transport_attrs = axutil_param_get_attributes(write_xml_declaration_param, env); + if(transport_attrs) + { + axutil_generic_obj_t *obj = NULL; + axiom_attribute_t *write_xml_declaration_attr = NULL; + axis2_char_t *write_xml_declaration_attr_value = NULL; + + obj + = axutil_hash_get(transport_attrs, AXIS2_ADD_XML_DECLARATION, AXIS2_HASH_KEY_STRING); + if(obj) + { + write_xml_declaration_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, + env); + } + if(write_xml_declaration_attr) + { + write_xml_declaration_attr_value = axiom_attribute_get_value( + write_xml_declaration_attr, env); + } + if(write_xml_declaration_attr_value && 0 == axutil_strcasecmp( + write_xml_declaration_attr_value, AXIS2_VALUE_TRUE)) + { + write_xml_declaration = AXIS2_TRUE; + } + } + } + + if(write_xml_declaration) + { + axiom_output_write_xml_version_encoding(om_output, env); + } + + axiom_soap_envelope_serialize(soap_envelope, env, om_output, AXIS2_FALSE); + + buffer = (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env); + if(!buffer) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[tcp]Failed to serialize the SOAP envelope"); + return AXIS2_FAILURE; + } + buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env); + buffer[buffer_size] = 0; + if(is_server) + { + out_stream = axis2_msg_ctx_get_transport_out_stream(msg_ctx, env); + axutil_stream_write(out_stream, env, buffer, buffer_size); + } + else + { + axis2_endpoint_ref_t *to = NULL; + axutil_url_t *to_url = NULL; + const axis2_char_t *to_str = NULL; + const axis2_char_t *host = NULL; + int port = 0; + int socket = -1; + axutil_stream_t *stream; + int write = -1; + int read = -1; + axis2_char_t buff[1]; + axis2_char_t *res_buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, RES_BUFF); + int res_size = 0; + int size = 0; + axiom_xml_reader_t *reader = NULL; + axiom_stax_builder_t *builder = NULL; + axiom_soap_builder_t *soap_builder = NULL; + axiom_soap_envelope_t *soap_envelope = NULL; + + to = axis2_msg_ctx_get_to(msg_ctx, env); + + if(!to) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "To epr not presant"); + return AXIS2_FAILURE; + } + + to_str = axis2_endpoint_ref_get_address(to, env); + if(!to_str) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to convert epr to string"); + return AXIS2_FAILURE; + } + + to_url = axutil_url_parse_string(env, to_str); + + if(!to_url) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to parser string to url"); + return AXIS2_FAILURE; + } + + host = axutil_url_get_host(to_url, env); + if(!host) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "retrieving host failed"); + return AXIS2_FAILURE; + } + + port = axutil_url_get_port(to_url, env); + if(!port) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "retrieving port failed"); + return AXIS2_FAILURE; + } + socket = (int)axutil_network_handler_open_socket(env, (char *)host, port); + if(!socket) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "socket creation failed"); + return AXIS2_FAILURE; + } + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "open socket for host:%s port:%d", host, port); + + stream = axutil_stream_create_socket(env, socket); + if(!stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "stream creation failed"); + return AXIS2_FAILURE; + } + + write = axutil_stream_write(stream, env, buffer, buffer_size); + if(write < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "stream write error"); + return AXIS2_FAILURE; + } + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "stream wrote soap msg: %s", buffer); + write = axutil_stream_write(stream, env, "\r\n\r\n", 4); + size = RES_BUFF; + while((read = axutil_stream_read(stream, env, &buff, 1)) > 0) + { + if(res_size >= size) + { + axis2_char_t *tmp_buff = NULL; + size <<= 2; + tmp_buff = AXIS2_MALLOC(env->allocator, size); + memcpy(tmp_buff, res_buffer, res_size); + AXIS2_FREE(env->allocator, res_buffer); + res_buffer = tmp_buff; + } + memcpy(res_buffer + res_size, buff, 1); + res_size++; + } + + axutil_network_handler_close_socket(env, stream->socket); + axutil_stream_close(stream, env); + axutil_stream_free(stream, env); + + AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "%s", res_buffer); + + reader = axiom_xml_reader_create_for_memory(env, res_buffer, (res_size - 1), NULL, + AXIS2_XML_PARSER_TYPE_BUFFER); + + if(!reader) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to create XML reader"); + return AXIS2_FAILURE; + } + + builder = axiom_stax_builder_create(env, reader); + if(!builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to create Stax builder"); + return AXIS2_FAILURE; + } + + soap_builder = axiom_soap_builder_create(env, builder, + AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI); + if(!soap_builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to create SOAP builder"); + return AXIS2_FAILURE; + } + soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + + if(!soap_envelope) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to create SOAP envelope"); + return AXIS2_FAILURE; + } + + axis2_msg_ctx_set_response_soap_envelope(msg_ctx, env, soap_envelope); + + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "end:tcp transport sender invoke"); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_transport_sender_clean_up( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + /* + * Clean up is not used. If the tcp sender needs + * to be cleaned up it should be done here. + */ + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_transport_sender_init( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx, + axis2_transport_out_desc_t * out_desc) +{ + axis2_char_t *temp = NULL; + axutil_param_t *temp_param = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, out_desc, AXIS2_FAILURE); + + temp_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container( + out_desc, env), env, AXIS2_TCP_SO_TIMEOUT); + if(temp_param) + { + temp = axutil_param_get_value(temp_param, env); + } + if(temp) + { + AXIS2_INTF_TO_IMPL(transport_sender)->so_timeout = AXIS2_ATOI(temp); + } + temp = (axis2_char_t *)axutil_param_container_get_param( + axis2_transport_out_desc_param_container(out_desc, env), env, AXIS2_TCP_CONNECTION_TIMEOUT); + if(temp_param) + { + temp = axutil_param_get_value(temp_param, env); + } + if(temp) + { + AXIS2_INTF_TO_IMPL(transport_sender)->connection_timeout = AXIS2_ATOI(temp); + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_tcp_transport_sender_write_message( + axis2_transport_sender_t * transport_sender, + const axutil_env_t * env, + axis2_msg_ctx_t * msg_ctx, + axis2_endpoint_ref_t * epr, + axiom_soap_envelope_t * out, + axiom_output_t * om_output) +{ + + return AXIS2_TRUE; +} + +/** + * Following block distinguish the exposed part of the dll. + */ + +/* When building for static deployment, give the get and remove methods + * unique names. This avoids having the linker fail with duplicate symbol + * errors. + */ + +AXIS2_EXPORT int +#ifndef AXIS2_STATIC_DEPLOY +axis2_get_instance( +#else + axis2_tcp_transport_sender_get_instance( +#endif + struct axis2_transport_sender **inst, + const axutil_env_t * env) +{ + *inst = axis2_tcp_transport_sender_create(env); + if(!(*inst)) + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT int +#ifndef AXIS2_STATIC_DEPLOY +axis2_remove_instance( +#else + axis2_tcp_transport_sender_remove_instance( +#endif + axis2_transport_sender_t * inst, + const axutil_env_t * env) +{ + if(inst) + { + AXIS2_TRANSPORT_SENDER_FREE(inst, env); + } + return AXIS2_SUCCESS; +} diff --git a/src/core/transport/tcp/server/Makefile.am b/src/core/transport/tcp/server/Makefile.am new file mode 100644 index 0000000..5d7b263 --- /dev/null +++ b/src/core/transport/tcp/server/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=simple_tcp_server diff --git a/src/core/transport/tcp/server/simple_tcp_server/Makefile.am b/src/core/transport/tcp/server/simple_tcp_server/Makefile.am new file mode 100644 index 0000000..1dafbad --- /dev/null +++ b/src/core/transport/tcp/server/simple_tcp_server/Makefile.am @@ -0,0 +1,30 @@ +prgbindir=$(bindir) +prgbin_PROGRAMS = axis2_tcp_server +SUBDIRS = +AM_CFLAGS = -g -pthread +axis2_tcp_server_SOURCES = tcp_server_main.c + +axis2_tcp_server_LDADD = $(LDFLAGS) \ + $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la \ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la \ + $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la \ + $(top_builddir)/src/core/description/libaxis2_description.la \ + $(top_builddir)/src/core/deployment/libaxis2_deployment.la \ + $(top_builddir)/src/core/context/libaxis2_context.la \ + $(top_builddir)/src/core/clientapi/libaxis2_clientapi.la \ + $(top_builddir)/src/core/engine/libaxis2_engine.la \ + $(top_builddir)/src/core/transport/tcp/sender/libaxis2_tcp_sender.la \ + $(top_builddir)/src/core/transport/tcp/receiver/libaxis2_tcp_receiver.la \ + $(top_builddir)/neethi/src/libneethi.la \ + -lpthread + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/description\ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/deployment\ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/util/include \ + -I../.. \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/tcp/server/simple_tcp_server/tcp_server_main.c b/src/core/transport/tcp/server/simple_tcp_server/tcp_server_main.c new file mode 100644 index 0000000..dc2dbf9 --- /dev/null +++ b/src/core/transport/tcp/server/simple_tcp_server/tcp_server_main.c @@ -0,0 +1,262 @@ +/* + * 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 + * + * tcp://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_tcp_server.h> +#include <axis2_tcp_transport.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <stdio.h> +#include <stdlib.h> +#include <axutil_error_default.h> +#include <axutil_log_default.h> +#include <axutil_thread_pool.h> +#include <signal.h> +#include <axutil_types.h> +#include <ctype.h> +#include <axiom_xml_reader.h> + +#ifndef AXIS2_TCP_SERVER_LOG_FILE_NAME +#define AXIS2_TCP_SERVER_LOG_FILE_NAME "axis2_tcp_server.log" +#endif + +#ifndef AXIS2_TCP_SERVER_PORT +#define AXIS2_TCP_SERVER_PORT 9091 +#endif + +#ifndef AXIS2_TCP_SERVER_REPO_PATH +#define AXIS2_TCP_SERVER_REPO_PATH "../" +#endif + +axutil_env_t *system_env = NULL; +axis2_transport_receiver_t *server = NULL; +int axis2_tcp_socket_read_timeout = 60000; + +/***************************** Function headers *******************************/ +axutil_env_t * +init_syetem_env( + axutil_allocator_t * allocator, + const axis2_char_t * log_file); + +void +system_exit( + axutil_env_t * env, + int status); + +void +usage( + axis2_char_t * prog_name); + +void +sig_handler( + int signal); + +/***************************** End of function headers ************************/ +axutil_env_t * +init_syetem_env( + axutil_allocator_t * allocator, + const axis2_char_t * log_file) +{ + axutil_error_t *error = axutil_error_create(allocator); + axutil_log_t *log = axutil_log_create(allocator, NULL, log_file); + axutil_thread_pool_t *thread_pool = axutil_thread_pool_init(allocator); + /* We need to init the parser in main thread before spawning child + * threads + */ + axiom_xml_reader_init(); + return axutil_env_create_with_error_log_thread_pool(allocator, error, log, thread_pool); +} + +void +system_exit( + axutil_env_t * env, + int status) +{ + axutil_allocator_t *allocator = NULL; + if(server) + { + axis2_transport_receiver_free(server, system_env); + } + if(env) + { + allocator = env->allocator; + axutil_env_free(env); + } + axiom_xml_reader_cleanup(); + exit(status); +} + +int +main( + int argc, + char *argv[]) +{ + axutil_allocator_t *allocator = NULL; + axutil_env_t *env = NULL; + extern char *optarg; + extern int optopt; + int c; + int log_file_size = AXUTIL_LOG_FILE_SIZE; + axutil_log_levels_t log_level = AXIS2_LOG_LEVEL_DEBUG; + const axis2_char_t *log_file = AXIS2_TCP_SERVER_LOG_FILE_NAME; + int port = AXIS2_TCP_SERVER_PORT; + const axis2_char_t *repo_path = AXIS2_TCP_SERVER_REPO_PATH; + + while((c = AXIS2_GETOPT(argc, argv, ":p:r:ht:l:s:f:")) != -1) + { + + switch(c) + { + case 'p': + port = AXIS2_ATOI(optarg); + break; + case 'r': + repo_path = optarg; + break; + case 't': + axis2_tcp_socket_read_timeout = AXIS2_ATOI(optarg) * 1000; + break; + case 'l': + log_level = AXIS2_ATOI(optarg); + if(log_level < AXIS2_LOG_LEVEL_CRITICAL) + log_level = AXIS2_LOG_LEVEL_CRITICAL; + if(log_level > AXIS2_LOG_LEVEL_TRACE) + log_level = AXIS2_LOG_LEVEL_TRACE; + break; + case 's': + log_file_size = 1024 * 1024 * AXIS2_ATOI(optarg); + break; + case 'f': + log_file = optarg; + break; + case 'h': + usage(argv[0]); + return 0; + case ':': + fprintf(stderr, "\nOption -%c requires an operand\n", optopt); + usage(argv[0]); + return -1; + case '?': + if(isprint(optopt)) + fprintf(stderr, "\nUnknown option `-%c'.\n", optopt); + usage(argv[0]); + return -1; + } + } + + allocator = axutil_allocator_init(NULL); + if(!allocator) + { + system_exit(NULL, -1); + } + env = init_syetem_env(allocator, log_file); + env->log->level = log_level; + env->log->size = log_file_size; + axutil_error_init(); + system_env = env; + +#ifndef WIN32 + signal(SIGINT, sig_handler); + signal(SIGPIPE, sig_handler); +#endif + + AXIS2_LOG_INFO(env->log, "Starting Axis2 TCP server...."); + AXIS2_LOG_INFO(env->log, "Server port : %d", port); + AXIS2_LOG_INFO(env->log, "Repo location : %s", repo_path); + AXIS2_LOG_INFO(env->log, "Read Timeout : %d ms", axis2_tcp_socket_read_timeout); + + server = axis2_tcp_server_create(env, repo_path, port); + if(!server) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Server creation failed: Error code:" " %d :: %s", + env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error)); + system_exit(env, -1); + + } + printf("Started Simple Axis2 TCP Server ...\n"); + if(axis2_transport_receiver_start(server, env) == AXIS2_FAILURE) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Server start failed: Error code:" " %d :: %s", + env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error)); + system_exit(env, -1); + } + return 0; +} + +void +usage( + axis2_char_t * prog_name) +{ + fprintf(stdout, "\n Usage : %s", prog_name); + fprintf(stdout, " [-p PORT]"); + fprintf(stdout, " [-t TIMEOUT]"); + fprintf(stdout, " [-r REPO_PATH]"); + fprintf(stdout, " [-l LOG_LEVEL]"); + fprintf(stdout, " [-f LOG_FILE]\n"); + fprintf(stdout, " [-s LOG_FILE_SIZE]\n"); + fprintf(stdout, " Options :\n"); + fprintf(stdout, "\t-p PORT \t port number to use, default port is %d\n", AXIS2_TCP_SERVER_PORT); + fprintf(stdout, "\t-r REPO_PATH \t repository path, default is ../\n"); + fprintf(stdout, "\t-t TIMEOUT\t socket read timeout, default is 30 seconds\n"); + fprintf(stdout, "\t-l LOG_LEVEL\t log level, available log levels:" + "\n\t\t\t 0 - critical 1 - errors 2 - warnings" + "\n\t\t\t 3 - information 4 - debug 5- user 6 - trace" + "\n\t\t\t Default log level is 4(debug).\n"); +#ifndef WIN32 + fprintf(stdout, "\t-f LOG_FILE\t log file, default is $AXIS2C_HOME/logs/axis2.log" + "\n\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n"); +#else + fprintf(stdout, + "\t-f LOG_FILE\t log file, default is %%AXIS2C_HOME%%\\logs\\axis2.log" + "\n\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n"); +#endif + fprintf(stdout, + "\t-s LOG_FILE_SIZE\t Maximum log file size in mega bytes, default maximum size is 1MB.\n"); + fprintf(stdout, " Help :\n\t-h \t display this help screen.\n\n"); +} + +/** + * Signal handler + */ +#ifndef WIN32 + +void +sig_handler( + int signal) +{ + switch(signal) + { + case SIGINT: + { + AXIS2_LOG_INFO(system_env->log, "Received signal SIGINT. Server " + "shutting down"); + axis2_tcp_server_stop(server, system_env); + AXIS2_LOG_INFO(system_env->log, "Shutdown complete ..."); + system_exit(system_env, 0); + } + case SIGPIPE: + { + AXIS2_LOG_INFO(system_env->log, "Received signal SIGPIPE. Client " + "request serve aborted"); + return; + } + case SIGSEGV: + { + fprintf(stderr, "Received deadly signal SIGSEGV. Terminating\n"); + _exit(-1); + } + } +} +#endif diff --git a/src/core/transport/transport_receiver.c b/src/core/transport/transport_receiver.c new file mode 100644 index 0000000..009d24b --- /dev/null +++ b/src/core/transport/transport_receiver.c @@ -0,0 +1,114 @@ +/* + * 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_transport_receiver.h> + +AXIS2_EXTERN void AXIS2_CALL +axis2_transport_receiver_free( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env) +{ + (transport_receiver->ops)->free(transport_receiver, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_transport_receiver_init( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env, + struct axis2_conf_ctx *conf_ctx, + struct axis2_transport_in_desc *transport_in) +{ + return (transport_receiver->ops)->init(transport_receiver, env, conf_ctx, transport_in); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_transport_receiver_start( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env) +{ + return (transport_receiver->ops)->start(transport_receiver, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_transport_receiver_stop( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env) +{ + return (transport_receiver->ops)->stop(transport_receiver, env); +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_transport_receiver_get_reply_to_epr( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + return (transport_receiver->ops)->get_reply_to_epr(transport_receiver, env, svc_name); +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_transport_receiver_get_epr_for_service( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env, + const axis2_char_t * svc_name) +{ + return (transport_receiver->ops)->get_epr_for_service(transport_receiver, env, svc_name); +} + +AXIS2_EXTERN axis2_char_t* AXIS2_CALL +axis2_transport_receiver_get_server_ip( +axis2_transport_receiver_t *transport_receiver, +const axutil_env_t *env) +{ + return (transport_receiver->ops)->get_server_ip(transport_receiver, env); +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_transport_receiver_set_server_ip( +axis2_transport_receiver_t *transport_receiver, +const axutil_env_t *env, + axis2_char_t *serverip) +{ + (transport_receiver->ops)->set_server_ip(transport_receiver, env, serverip); +} + + +AXIS2_EXTERN struct axis2_conf_ctx *AXIS2_CALL +axis2_transport_receiver_get_conf_ctx( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env) +{ + return (transport_receiver)->ops->get_conf_ctx(transport_receiver, env); +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_transport_receiver_is_running( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env) +{ + return (transport_receiver)->ops->is_running(transport_receiver, env); +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_transport_receiver_set_is_application_client_side( + axis2_transport_receiver_t * transport_receiver, + const axutil_env_t * env, + axis2_bool_t is_application_client_side) +{ + (transport_receiver)->ops->set_is_application_client_side(transport_receiver, env, + is_application_client_side); +} diff --git a/src/core/util/Makefile.am b/src/core/util/Makefile.am new file mode 100644 index 0000000..e5609a2 --- /dev/null +++ b/src/core/util/Makefile.am @@ -0,0 +1,9 @@ +noinst_LTLIBRARIES = libaxis2_core_utils.la +#noinst_HEADERS = axis2_core_utils.h + +libaxis2_core_utils_la_SOURCES = core_utils.c + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/util/core_utils.c b/src/core/util/core_utils.c new file mode 100644 index 0000000..5ae9f31 --- /dev/null +++ b/src/core/util/core_utils.c @@ -0,0 +1,1635 @@ +/* + * 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_core_utils.h> +#include <axutil_string.h> +#include <axis2_conf.h> +#include <axis2_relates_to.h> +#include <axis2_addr.h> +#include <axis2_http_transport.h> +#include <axutil_uuid_gen.h> +#include <axutil_property.h> +#include <axis2_conf_ctx.h> + + +/* internal structure to keep the rest map in a multi level hash */ +typedef struct +{ + /* the structure will keep as many as following fields */ + + /* if the mapped value is directly the operation */ + axis2_op_t *op_desc; + + /* if the mapped value is a constant, this keeps a hash map of + possible constants => corrosponding map_internal structure */ + axutil_hash_t *consts_map; + + /* if the mapped value is a param, this keeps a hash map of + possible param_values => corrosponding_map_internal structre */ + axutil_hash_t *params_map; + +} axutil_core_utils_map_internal_t; + +/* some functions to use internally in handling rest map */ +/* infer op from the live url */ +axis2_op_t * +axis2_core_utils_infer_op_from_parent_rest_map( + const axutil_env_t *env, + axutil_hash_t *rest_map, + axis2_char_t *live_url, + axutil_array_list_t *param_keys, + axutil_array_list_t *param_values); + +/* build the restmap recursively - internal function*/ +axis2_status_t AXIS2_CALL +axis2_core_utils_internal_build_rest_map_recursively( + const axutil_env_t * env, + axis2_char_t * url, + axutil_core_utils_map_internal_t *mapping_struct, + axis2_op_t *op_desc); + +/* infer op from the live url recursively */ +axis2_op_t *AXIS2_CALL +axis2_core_utils_internal_infer_op_from_rest_map_recursively( + const axutil_env_t *env, + const axutil_core_utils_map_internal_t *parent_mapping_struct, + axis2_char_t *live_url, + axutil_array_list_t *param_keys, + axutil_array_list_t *param_values); + +/* match a pattern with a url component */ +axis2_status_t +axis2_core_utils_match_url_component_with_pattern( + const axutil_env_t *env, + axis2_char_t *pattern, + axis2_char_t *url_component, + axutil_array_list_t *param_keys, + axutil_array_list_t *param_values); + +AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL +axis2_core_utils_create_out_msg_ctx( + const axutil_env_t * env, + axis2_msg_ctx_t * in_msg_ctx) +{ + axis2_ctx_t *ctx = NULL; + axis2_msg_ctx_t *new_msg_ctx = NULL; + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_transport_in_desc_t *transport_in = NULL; + axis2_transport_out_desc_t *transport_out = NULL; + axis2_msg_info_headers_t *old_msg_info_headers = NULL; + axis2_msg_info_headers_t *msg_info_headers = NULL; + axis2_endpoint_ref_t *reply_to = NULL; + axis2_endpoint_ref_t *fault_to = NULL; + axis2_endpoint_ref_t *to = NULL; + const axis2_char_t *msg_id = NULL; + axis2_relates_to_t *relates_to = NULL; + const axis2_char_t *action = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_svc_ctx_t *svc_ctx = NULL; + axis2_bool_t doing_rest = AXIS2_FALSE; + axis2_bool_t doing_mtom = AXIS2_FALSE; + axis2_bool_t server_side = AXIS2_FALSE; + axis2_svc_grp_ctx_t *svc_grp_ctx = NULL; + axis2_char_t *msg_uuid = NULL; + axutil_stream_t *out_stream = NULL; + axutil_param_t *expose_headers_param = NULL; + axis2_bool_t expose_headers = AXIS2_FALSE; + + AXIS2_PARAM_CHECK(env->error, in_msg_ctx, NULL); + + conf_ctx = axis2_msg_ctx_get_conf_ctx(in_msg_ctx, env); + transport_in = axis2_msg_ctx_get_transport_in_desc(in_msg_ctx, env); + transport_out = axis2_msg_ctx_get_transport_out_desc(in_msg_ctx, env); + + new_msg_ctx = axis2_msg_ctx_create(env, conf_ctx, transport_in, transport_out); + if(!new_msg_ctx) + { + return NULL; + } + + if(transport_in) + { + expose_headers_param = axutil_param_container_get_param( + axis2_transport_in_desc_param_container(transport_in, env), env, AXIS2_EXPOSE_HEADERS); + } + if(expose_headers_param) + { + axis2_char_t *expose_headers_value = NULL; + expose_headers_value = axutil_param_get_value(expose_headers_param, env); + if(expose_headers_value && 0 == axutil_strcasecmp(expose_headers_value, AXIS2_VALUE_TRUE)) + { + expose_headers = AXIS2_TRUE; + } + } + if(expose_headers) + { + axis2_msg_ctx_set_transport_headers(new_msg_ctx, env, + axis2_msg_ctx_extract_transport_headers(in_msg_ctx, env)); + } + axis2_msg_ctx_set_http_accept_record_list(new_msg_ctx, env, + axis2_msg_ctx_extract_http_accept_record_list(in_msg_ctx, env)); + axis2_msg_ctx_set_http_accept_charset_record_list(new_msg_ctx, env, + axis2_msg_ctx_extract_http_accept_charset_record_list(in_msg_ctx, env)); + axis2_msg_ctx_set_http_accept_language_record_list(new_msg_ctx, env, + axis2_msg_ctx_extract_http_accept_language_record_list(in_msg_ctx, env)); + + old_msg_info_headers = axis2_msg_ctx_get_msg_info_headers(in_msg_ctx, env); + if(!old_msg_info_headers) + { + return NULL; + } + msg_info_headers = axis2_msg_ctx_get_msg_info_headers(new_msg_ctx, env); + if(!msg_info_headers) + { + /* if there is no msg info header in ew msg ctx, then create one */ + msg_info_headers = axis2_msg_info_headers_create(env, NULL, NULL); + if(!msg_info_headers) + return NULL; + axis2_msg_ctx_set_msg_info_headers(new_msg_ctx, env, msg_info_headers); + } + + msg_uuid = axutil_uuid_gen(env); + axis2_msg_info_headers_set_message_id(msg_info_headers, env, msg_uuid); + if(msg_uuid) + { + AXIS2_FREE(env->allocator, msg_uuid); + msg_uuid = NULL; + } + reply_to = axis2_msg_info_headers_get_reply_to(old_msg_info_headers, env); + axis2_msg_info_headers_set_to(msg_info_headers, env, reply_to); + + fault_to = axis2_msg_info_headers_get_fault_to(old_msg_info_headers, env); + axis2_msg_info_headers_set_fault_to(msg_info_headers, env, fault_to); + + to = axis2_msg_info_headers_get_to(old_msg_info_headers, env); + axis2_msg_info_headers_set_from(msg_info_headers, env, to); + + msg_id = axis2_msg_info_headers_get_message_id(old_msg_info_headers, env); + + /* we can create with default Relates to namespace. + Actual namespace based on addressing version will be created in addressing out handler */ + relates_to = axis2_relates_to_create(env, msg_id, + AXIS2_WSA_RELATES_TO_RELATIONSHIP_TYPE_DEFAULT_VALUE); + axis2_msg_info_headers_set_relates_to(msg_info_headers, env, relates_to); + + action = axis2_msg_info_headers_get_action(old_msg_info_headers, env); + axis2_msg_info_headers_set_action(msg_info_headers, env, action); + + op_ctx = axis2_msg_ctx_get_op_ctx(in_msg_ctx, env); + axis2_msg_ctx_set_op_ctx(new_msg_ctx, env, op_ctx); + + svc_ctx = axis2_msg_ctx_get_svc_ctx(in_msg_ctx, env); + axis2_msg_ctx_set_svc_ctx(new_msg_ctx, env, svc_ctx); + + ctx = axis2_msg_ctx_get_base(in_msg_ctx, env); + if(ctx) + { + axis2_ctx_t *new_ctx = axis2_msg_ctx_get_base(new_msg_ctx, env); + if(new_ctx) + { + axis2_ctx_set_property_map(new_ctx, env, axis2_ctx_get_property_map(ctx, env)); + } + } + + out_stream = axis2_msg_ctx_get_transport_out_stream(in_msg_ctx, env); + axis2_msg_ctx_set_transport_out_stream(new_msg_ctx, env, out_stream); + axis2_msg_ctx_set_out_transport_info(new_msg_ctx, env, axis2_msg_ctx_get_out_transport_info( + in_msg_ctx, env)); + + /* Setting the character set encoding */ + doing_rest = axis2_msg_ctx_get_doing_rest(in_msg_ctx, env); + axis2_msg_ctx_set_doing_rest(new_msg_ctx, env, doing_rest); + + doing_mtom = axis2_msg_ctx_get_doing_mtom(in_msg_ctx, env); + axis2_msg_ctx_set_doing_mtom(new_msg_ctx, env, doing_mtom); + + server_side = axis2_msg_ctx_get_server_side(in_msg_ctx, env); + axis2_msg_ctx_set_server_side(new_msg_ctx, env, server_side); + + svc_grp_ctx = axis2_msg_ctx_get_svc_grp_ctx(in_msg_ctx, env); + axis2_msg_ctx_set_svc_grp_ctx(new_msg_ctx, env, svc_grp_ctx); + + axis2_msg_ctx_set_is_soap_11(new_msg_ctx, env, axis2_msg_ctx_get_is_soap_11(in_msg_ctx, env)); + axis2_msg_ctx_set_keep_alive(new_msg_ctx, env, axis2_msg_ctx_is_keep_alive(in_msg_ctx, env)); + + axis2_msg_ctx_set_charset_encoding(new_msg_ctx, env, axis2_msg_ctx_get_charset_encoding( + in_msg_ctx, env)); + + return new_msg_ctx; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_core_utils_reset_out_msg_ctx( + const axutil_env_t * env, + axis2_msg_ctx_t * out_msg_ctx) +{ + axis2_msg_info_headers_t *msg_info_headers = NULL; + if(!out_msg_ctx) + return; + + msg_info_headers = axis2_msg_ctx_get_msg_info_headers(out_msg_ctx, env); + if(msg_info_headers) + { + axis2_msg_info_headers_set_to(msg_info_headers, env, NULL); + axis2_msg_info_headers_set_fault_to(msg_info_headers, env, NULL); + axis2_msg_info_headers_set_from(msg_info_headers, env, NULL); + axis2_msg_info_headers_set_reply_to(msg_info_headers, env, NULL); + } + + axis2_msg_ctx_set_op_ctx(out_msg_ctx, env, NULL); + axis2_msg_ctx_set_svc_ctx(out_msg_ctx, env, NULL); + axis2_msg_ctx_reset_transport_out_stream(out_msg_ctx, env); + axis2_msg_ctx_reset_out_transport_info(out_msg_ctx, env); + axis2_msg_ctx_set_svc_grp_ctx(out_msg_ctx, env, NULL); + + return; +} + +AXIS2_EXTERN axutil_qname_t *AXIS2_CALL +axis2_core_utils_get_module_qname( + const axutil_env_t * env, + const axis2_char_t * name, + const axis2_char_t * version) +{ + axutil_qname_t *ret_qname = NULL; + AXIS2_PARAM_CHECK(env->error, name, NULL); + + if(version && 0 != axutil_strlen(version)) + { + axis2_char_t *mod_name1 = NULL; + axis2_char_t *mod_name = NULL; + mod_name1 = axutil_stracat(env, name, "-"); + if(!mod_name1) + { + return NULL; + } + mod_name = axutil_stracat(env, mod_name1, version); + if(!mod_name) + { + AXIS2_FREE(env->allocator, mod_name1); + mod_name1 = NULL; + return NULL; + } + ret_qname = axutil_qname_create(env, mod_name, NULL, NULL); + AXIS2_FREE(env->allocator, mod_name); + AXIS2_FREE(env->allocator, mod_name1); + return ret_qname; + } + ret_qname = axutil_qname_create(env, name, NULL, NULL); + return ret_qname; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_core_utils_calculate_default_module_version( + const axutil_env_t * env, + axutil_hash_t * modules_map, + axis2_conf_t * axis_conf) +{ + axutil_hash_t *default_modules = NULL; + axutil_hash_index_t *hi = NULL; + void *val = NULL; + + AXIS2_PARAM_CHECK(env->error, modules_map, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, axis_conf, AXIS2_FAILURE); + + default_modules = axutil_hash_make(env); + if(!default_modules) + { + return AXIS2_FAILURE; + } + for(hi = axutil_hash_first(modules_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axis2_module_desc_t *mod_desc = NULL; + + axutil_hash_this(hi, NULL, NULL, &val); + mod_desc = (axis2_module_desc_t *)val; + if(mod_desc) + { + const axutil_qname_t *module_qname = NULL; + module_qname = axis2_module_desc_get_qname(mod_desc, env); + if(module_qname) + { + axis2_char_t *mod_name_with_ver = NULL; + mod_name_with_ver = axutil_qname_get_localpart(module_qname, env); + if(mod_name_with_ver) + { + axis2_char_t *module_name_str = NULL; + axis2_char_t *module_ver_str = NULL; + axis2_char_t *current_def_ver = NULL; + + module_name_str = axis2_core_utils_get_module_name(env, mod_name_with_ver); + if(!module_name_str) + { + return AXIS2_FAILURE; + } + module_ver_str = axis2_core_utils_get_module_version(env, mod_name_with_ver); + current_def_ver = axutil_hash_get(default_modules, module_name_str, + AXIS2_HASH_KEY_STRING); + if(current_def_ver) + { + if(module_ver_str && AXIS2_TRUE == axis2_core_utils_is_latest_mod_ver(env, + module_ver_str, current_def_ver)) + { + axutil_hash_set(default_modules, module_name_str, + AXIS2_HASH_KEY_STRING, module_ver_str); + } + else + { + if(module_name_str) + { + AXIS2_FREE(env->allocator, module_name_str); + } + if(module_ver_str) + { + AXIS2_FREE(env->allocator, module_ver_str); + } + } + } + else + { + axutil_hash_set(default_modules, module_name_str, AXIS2_HASH_KEY_STRING, + module_ver_str); + } + + if(module_name_str) + { + AXIS2_FREE(env->allocator, module_name_str); + } + } + } + } + val = NULL; + } + + hi = NULL; + val = NULL; + for(hi = axutil_hash_first(default_modules, env); hi; hi = axutil_hash_next(env, hi)) + { + void *key_string = NULL; + axutil_hash_this(hi, (const void **)&key_string, NULL, &val); + if(key_string && NULL != val) + { + axis2_conf_add_default_module_version(axis_conf, env, (axis2_char_t *)key_string, + (axis2_char_t *)val); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Added default module" + " version : %s for module : %s", (axis2_char_t *)val, (axis2_char_t *)key_string); + } + } + + if(default_modules) + { + axutil_hash_free(default_modules, env); + default_modules = NULL; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_core_utils_get_module_name( + const axutil_env_t * env, + axis2_char_t * module_name) +{ + axis2_char_t version_seperator = '-'; + axis2_char_t *name = NULL; + axis2_char_t *version_sep_loc = NULL; + + AXIS2_PARAM_CHECK(env->error, module_name, NULL); + + name = axutil_strdup(env, module_name); + if(!name) + { + return NULL; + } + version_sep_loc = axutil_rindex(name, version_seperator); + if(version_sep_loc) + { + *version_sep_loc = '\0'; + } + return name; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_core_utils_get_module_version( + const axutil_env_t * env, + axis2_char_t * module_name) +{ + axis2_char_t version_seperator = '-'; + axis2_char_t *version_sep_loc = NULL; + + AXIS2_PARAM_CHECK(env->error, module_name, NULL); + + version_sep_loc = axutil_rindex(module_name, version_seperator); + if(version_sep_loc) + { + return axutil_strdup(env, version_sep_loc + sizeof(axis2_char_t)); + } + return NULL; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_core_utils_is_latest_mod_ver( + const axutil_env_t * env, + axis2_char_t * module_ver, + axis2_char_t * current_def_ver) +{ + double cur_ver = 0.0; + double mod_ver = 0.0; + AXIS2_PARAM_CHECK(env->error, module_ver, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, current_def_ver, AXIS2_FALSE); + cur_ver = atof(current_def_ver); + mod_ver = atof(module_ver); + if(mod_ver > cur_ver) + { + return AXIS2_TRUE; + } + return AXIS2_FAILURE; +} + +/* build the rest map - external function */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_core_utils_prepare_rest_mapping( + const axutil_env_t * env, + axis2_char_t * url, + axutil_hash_t *rest_map, + axis2_op_t *op_desc) +{ + + axis2_char_t *first_delimitter = NULL; + axis2_char_t *next_level_url = NULL; + axis2_char_t *mapping_key = NULL; + axutil_core_utils_map_internal_t *mapping_struct = NULL; + axis2_status_t status = AXIS2_SUCCESS; + axis2_char_t *bracket_start = NULL; + + first_delimitter = axutil_strchr(url, '/'); + + if(first_delimitter) + { + /* if there is another recursive level, + this will get the url of that level */ + next_level_url = first_delimitter + 1; + *first_delimitter = '\0'; + } + + if((bracket_start = axutil_strchr(url, '{'))) + { + /* we support multiple param per url component, + but we validate only one param */ + if(axutil_strchr(bracket_start, '}')) + { + /* this is validated */ + } + + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid URL Format, no closing bracket in declaring parameters"); + return AXIS2_FAILURE; + } + } + + /* only constants are allowed in this level, so here url become the mapping_key */ + mapping_key = url; + + if(*mapping_key == '\0') /* empty mapping key */ + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid URL Format: empty mapping key"); + return AXIS2_FAILURE; + } + + /* retrieve or create the mapping structure for the key*/ + mapping_struct = axutil_hash_get(rest_map, mapping_key, AXIS2_HASH_KEY_STRING); + if(!mapping_struct) + { + mapping_struct = (axutil_core_utils_map_internal_t*)AXIS2_MALLOC(env->allocator, + sizeof(axutil_core_utils_map_internal_t)); + if(!mapping_struct) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + return AXIS2_FAILURE; + + } + memset(mapping_struct, 0, sizeof(axutil_core_utils_map_internal_t)); + + mapping_key = axutil_strdup(env, mapping_key); + axutil_hash_set(rest_map, mapping_key, AXIS2_HASH_KEY_STRING, mapping_struct); + } + + if(!next_level_url) + { + /* if no next level url, put the op_desc in right this level */ + if(mapping_struct->op_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DUPLICATE_URL_REST_MAPPING, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Duplicate URL Mapping found"); + return AXIS2_FAILURE; + } + mapping_struct->op_desc = op_desc; + } + else + { + /* we have to build the map_internal structure recursively */ + status = axis2_core_utils_internal_build_rest_map_recursively(env, next_level_url, + mapping_struct, op_desc); + } + + return status; + +} + +/* build the restmap recursively - internal function*/ +axis2_status_t AXIS2_CALL +axis2_core_utils_internal_build_rest_map_recursively( + const axutil_env_t * env, + axis2_char_t * url, + axutil_core_utils_map_internal_t *parent_mapping_struct, + axis2_op_t *op_desc) +{ + + /* Here url is expected to be in the form + {student}/marks/{subject} or + marks/{subject} + */ + + axis2_char_t *first_delimitter = NULL; + axis2_char_t *next_level_url = NULL; + axis2_char_t *mapping_key = NULL; + axutil_core_utils_map_internal_t *mapping_struct = NULL; + axutil_hash_t *cur_level_rest_map = NULL; + axis2_status_t status = AXIS2_SUCCESS; + axis2_char_t *bracket_start = NULL; + + axis2_bool_t is_key_a_param = AXIS2_FALSE; + + first_delimitter = axutil_strchr(url, '/'); + + if(first_delimitter) + { + /* if there is another recurisive level, + this will get the url of that level */ + next_level_url = first_delimitter + 1; + *first_delimitter = '\0'; + } + + if((bracket_start = axutil_strchr(url, '{'))) + { + /* we support multiple param per url component, + but we validate only one param */ + if(axutil_strchr(bracket_start, '}')) + { + is_key_a_param = AXIS2_TRUE; + } + + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid URL Format, no closing bracket in declaring parameters"); + return AXIS2_FAILURE; + } + } + + /* here the url become the mapping_key */ + mapping_key = url; + + if(*mapping_key == '\0') /* empty mappng key */ + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid URL Format: empty mapping key"); + return AXIS2_FAILURE; + } + + if(is_key_a_param) + { + /* set the rest map as the params_map */ + if(parent_mapping_struct->params_map == NULL) + { + parent_mapping_struct->params_map = axutil_hash_make(env); + if(!parent_mapping_struct->params_map) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + return AXIS2_FAILURE; + } + } + cur_level_rest_map = parent_mapping_struct->params_map; + } + else + { + /* set the rest map as the consts_map */ + if(parent_mapping_struct->consts_map == NULL) + { + parent_mapping_struct->consts_map = axutil_hash_make(env); + if(!parent_mapping_struct->consts_map) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + return AXIS2_FAILURE; + } + } + cur_level_rest_map = parent_mapping_struct->consts_map; + } + + /* retrieve or create the maping structure for the key*/ + mapping_struct = axutil_hash_get(cur_level_rest_map, mapping_key, AXIS2_HASH_KEY_STRING); + if(!mapping_struct) + { + mapping_struct = (axutil_core_utils_map_internal_t*)AXIS2_MALLOC(env->allocator, + sizeof(axutil_core_utils_map_internal_t)); + if(!mapping_struct) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + return AXIS2_FAILURE; + + } + memset(mapping_struct, 0, sizeof(axutil_core_utils_map_internal_t)); + + mapping_key = axutil_strdup(env, mapping_key); + axutil_hash_set(cur_level_rest_map, mapping_key, AXIS2_HASH_KEY_STRING, mapping_struct); + } + + if(!next_level_url) + { + /* if no next level url, put the op_desc in right this level */ + if(mapping_struct->op_desc) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_DUPLICATE_URL_REST_MAPPING, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Duplicate URL Mapping found"); + return AXIS2_FAILURE; + } + mapping_struct->op_desc = op_desc; + } + else + { + /* we have to build the map_internal structure recursively */ + status = axis2_core_utils_internal_build_rest_map_recursively(env, next_level_url, + mapping_struct, op_desc); + } + + return status; +} + +/* free the rest map recursively */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_core_utils_free_rest_map( + const axutil_env_t *env, + axutil_hash_t *rest_map) +{ + + axutil_hash_index_t *hi = NULL; + const void *key = NULL; + void *val = NULL; + axis2_status_t status = AXIS2_SUCCESS; + + for(hi = axutil_hash_first(rest_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, &key, NULL, &val); + + if(val) + { + axutil_core_utils_map_internal_t *mapping_struct = NULL; + mapping_struct = (axutil_core_utils_map_internal_t*)val; + + /* freeing the consts_map and params_map */ + if(mapping_struct->consts_map) + { + axis2_core_utils_free_rest_map(env, mapping_struct->consts_map); + } + + if(mapping_struct->params_map) + { + axis2_core_utils_free_rest_map(env, mapping_struct->params_map); + } + AXIS2_FREE(env->allocator, mapping_struct); + } + + if(key) + { + AXIS2_FREE(env->allocator, (axis2_char_t *)key); + key = NULL; + } + } + axutil_hash_free(rest_map, env); + return status; +} + +AXIS2_EXTERN axis2_op_t *AXIS2_CALL +axis2_core_utils_get_rest_op_with_method_and_location( + axis2_svc_t *svc, + const axutil_env_t *env, + const axis2_char_t *method, + const axis2_char_t *location, + axutil_array_list_t *param_keys, + axutil_array_list_t *param_values) +{ + axis2_char_t *addition_params_str = NULL; + axis2_char_t *adjusted_local_url = NULL; + + axis2_char_t *live_mapping_url = NULL; + axis2_char_t *local_url = NULL; + + axis2_op_t *op = NULL; + + int key_len = 0; + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Checking for operation using " + "REST HTTP Location fragment : %s", location); + + /* we are creating a dup of the location */ + local_url = (axis2_char_t*)axutil_strdup(env, location); + if(!local_url) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create the live rest mapping url"); + return NULL; + } + + /* checking the existence of the addition parameters + after the question mark '?' */ + addition_params_str = strchr(local_url, '?'); + if(addition_params_str) + { + *addition_params_str = '\0'; + addition_params_str++; + } + + /* if the first character is '/' ignore that */ + if(*local_url == '/') + { + adjusted_local_url = local_url + 1; + } + else + { + adjusted_local_url = local_url; + } + + /* now create the mapping url */ + key_len = axutil_strlen(method) + axutil_strlen(adjusted_local_url) + 2; + + live_mapping_url + = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * key_len)); + + if(!live_mapping_url) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create the live rest mapping url"); + AXIS2_FREE(env->allocator, local_url); + return NULL; + } + + sprintf(live_mapping_url, "%s:%s", method, adjusted_local_url); + + op = axis2_core_utils_infer_op_from_parent_rest_map(env, axis2_svc_get_rest_map(svc, env), + live_mapping_url, param_keys, param_values); + + if(op) + { + axis2_char_t *params_str; + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "Operation found using target endpoint uri fragment"); + + /* here we are going to extract out the additional parameters + * put after '?' mark */ + params_str = addition_params_str; + while(params_str && *params_str != '\0') + { + axis2_char_t *next_params_str = NULL; + axis2_char_t *key_value_seperator = NULL; + + axis2_char_t *key = NULL; + axis2_char_t *value = NULL; + + /* we take one parameter pair to the params_str */ + next_params_str = strchr(params_str, '&'); + if(next_params_str) + { + *next_params_str = '\0'; + } + + key_value_seperator = strchr(params_str, '='); + if(key_value_seperator) + { + /* devide the key value pair */ + *key_value_seperator = '\0'; + key = params_str; + value = key_value_seperator + 1; + } + else + { + /* there is no '=' symbol, that mean only the key exist */ + key = params_str; + } + if(key) + { + key = axutil_strdup(env, key); + axutil_array_list_add(param_keys, env, key); + } + if(value) + { + value = axutil_strdup(env, value); + axutil_array_list_add(param_values, env, value); + } + + if(next_params_str) + { + /* if there was an '&' character then */ + params_str = next_params_str + 1; + } + else + { + params_str = NULL; /* just to end the loop */ + } + } + } + + if(live_mapping_url) + { + AXIS2_FREE(env->allocator, live_mapping_url); + } + if(local_url) + { + AXIS2_FREE(env->allocator, local_url); + } + return op; +} + +/* infer op from the live url */ +axis2_op_t * +axis2_core_utils_infer_op_from_parent_rest_map( + const axutil_env_t *env, + axutil_hash_t *rest_map, + axis2_char_t *live_url, + axutil_array_list_t *param_keys, + axutil_array_list_t *param_values) +{ + axis2_char_t *first_delimitter = NULL; + axis2_char_t *next_level_url = NULL; + axis2_char_t *url_component = NULL; + + axis2_op_t *op_desc = NULL; + axutil_core_utils_map_internal_t *mapping_struct = NULL; + + first_delimitter = axutil_strchr(live_url, '/'); + + if(first_delimitter) + { + /* if there is another recursive level, + this will get the url of that level */ + next_level_url = first_delimitter + 1; + *first_delimitter = '\0'; + } + + /* so live url is the url_component */ + url_component = live_url; + + /* check it in the hash map */ + mapping_struct = (axutil_core_utils_map_internal_t*)axutil_hash_get(rest_map, url_component, + AXIS2_HASH_KEY_STRING); + + if(mapping_struct) + { + if(!next_level_url) + { + /* if no level exists, find it here */ + op_desc = mapping_struct->op_desc; + } + else + { + + op_desc = axis2_core_utils_internal_infer_op_from_rest_map_recursively(env, + mapping_struct, next_level_url, param_keys, param_values); + } + } + if(!op_desc) + { + /* if the url is not mapped to the given constant url + * we have to match it with the url pattern */ + + axutil_hash_index_t *hi = NULL; + const void *key = NULL; + void *val = NULL; + axis2_status_t matched_status = AXIS2_FAILURE; + + for(hi = axutil_hash_first(rest_map, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, &key, NULL, &val); + + if(key == url_component) + { + continue; /* skip the already checked key */ + } + if(key && val) + { + axis2_char_t *hash_key = (axis2_char_t*)key; + axis2_char_t *dup_url_component = NULL; + axis2_char_t *dup_pattern = NULL; + + /* temporary param keys and values for each entry */ + axutil_array_list_t *tmp_param_keys = NULL; + axutil_array_list_t *tmp_param_values = NULL; + + tmp_param_keys = axutil_array_list_create(env, 10); + if(!tmp_param_keys) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + + return NULL; + } + tmp_param_values = axutil_array_list_create(env, 10); + if(!tmp_param_values) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + axutil_array_list_free(tmp_param_keys, env); + return NULL; + } + + dup_url_component = axutil_strdup(env, url_component); + if(!dup_url_component) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + axutil_array_list_free(tmp_param_keys, env); + axutil_array_list_free(tmp_param_values, env); + return NULL; + } + dup_pattern = axutil_strdup(env, hash_key); + if(!dup_pattern) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + axutil_array_list_free(tmp_param_keys, env); + axutil_array_list_free(tmp_param_values, env); + AXIS2_FREE(env->allocator, dup_url_component); + return NULL; + } + + matched_status = axis2_core_utils_match_url_component_with_pattern(env, + dup_pattern, dup_url_component, tmp_param_keys, tmp_param_values); + + AXIS2_FREE(env->allocator, dup_url_component); + AXIS2_FREE(env->allocator, dup_pattern); + + if(matched_status == AXIS2_SUCCESS && val) + { + mapping_struct = (axutil_core_utils_map_internal_t*)val; + + if(!next_level_url) + { + op_desc = mapping_struct->op_desc; + } + else + { + + op_desc = axis2_core_utils_internal_infer_op_from_rest_map_recursively(env, + mapping_struct, next_level_url, tmp_param_keys, tmp_param_values); + } + if(op_desc) + { + /* we are done, the url is matched with a pattern */ + /* but before leaving should merge the param arrays */ + + int i = 0; + void *param_key = NULL; + void *param_value = NULL; + + for(i = 0; i < axutil_array_list_size(tmp_param_keys, env); i++) + { + /* size(tmp_param_keys) == size(tmp_param_values) */ + param_key = axutil_array_list_get(tmp_param_keys, env, i); + param_value = axutil_array_list_get(tmp_param_values, env, i); + + /* add it to original array */ + axutil_array_list_add(param_keys, env, param_key); + axutil_array_list_add(param_values, env, param_value); + + } + /* since of is found, no more searches needed */ + break; + } + } + /* freeing the temporary arrays */ + axutil_array_list_free(tmp_param_keys, env); + axutil_array_list_free(tmp_param_values, env); + } + } + } + + if(!op_desc) + { + /* no more to look up */ + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "REST maping structure is NULL for the accessed URL"); + return NULL; + } + + return op_desc; +} + +/* infer op from the live url recursively */ +axis2_op_t *AXIS2_CALL +axis2_core_utils_internal_infer_op_from_rest_map_recursively( + const axutil_env_t *env, + const axutil_core_utils_map_internal_t *parent_mapping_struct, + axis2_char_t *live_url, + axutil_array_list_t *param_keys, + axutil_array_list_t *param_values) +{ + + axis2_char_t *first_delimitter = NULL; + axis2_char_t *next_level_url = NULL; + axis2_char_t *url_component = NULL; + + axis2_op_t *op_desc = NULL; + axutil_core_utils_map_internal_t *child_mapping_struct = NULL; + + axutil_hash_index_t *hi = NULL; + const void *key = NULL; + void *val = NULL; + + first_delimitter = axutil_strchr(live_url, '/'); + + if(first_delimitter) + { + /* if there is another recurisive level, + this will get the url of that level */ + next_level_url = first_delimitter + 1; + *first_delimitter = '\0'; + } + + /* so live url is the url_component */ + url_component = live_url; + + /* first check the url component in the constants array list */ + if(parent_mapping_struct->consts_map) + { + child_mapping_struct = axutil_hash_get(parent_mapping_struct->consts_map, url_component, + AXIS2_HASH_KEY_STRING); + } + + /* if the url component exists in the consts_map, go through it inside */ + + if(child_mapping_struct) + { + if(!next_level_url) + { + /* there is no another level, so the op should be here */ + + op_desc = child_mapping_struct->op_desc; + + if(!op_desc) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "The operation descriptor not found constant given in the url"); + } + /* rather than returning NULL we continue to search params_map */ + + } + else + { + + op_desc = axis2_core_utils_internal_infer_op_from_rest_map_recursively(env, + child_mapping_struct, next_level_url, param_keys, param_values); + } + } + + if(op_desc) + { + /* if the op for the accessed url found, no further searching is needed */ + return op_desc; + } + + /* if it is not found in the consts_map we have to assume it is in a params_map */ + + if(!parent_mapping_struct->params_map) + { + /* wrong operation, abort to continue to let calling function to check other operations */ + if(first_delimitter) + { + /* restore the delimmiters */ + *first_delimitter = '/'; + } + return NULL; + } + + for(hi = axutil_hash_first(parent_mapping_struct->params_map, env); hi; hi = axutil_hash_next( + env, hi)) + { + axutil_hash_this(hi, &key, NULL, &val); + + if(key && val) + { + int i = 0; + axis2_char_t *hash_key = (axis2_char_t*)key; + axis2_status_t matched_status = AXIS2_SUCCESS; + axis2_char_t *dup_url_component = NULL; + axis2_char_t *dup_pattern = NULL; + + /* temporary param keys and values for each entry */ + axutil_array_list_t *tmp_param_keys; + axutil_array_list_t *tmp_param_values; + + tmp_param_keys = axutil_array_list_create(env, 10); + if(!tmp_param_keys) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + + return NULL; + } + tmp_param_values = axutil_array_list_create(env, 10); + if(!tmp_param_values) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + axutil_array_list_free(tmp_param_keys, env); + return NULL; + } + + dup_url_component = axutil_strdup(env, url_component); + if(!dup_url_component) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + axutil_array_list_free(tmp_param_keys, env); + axutil_array_list_free(tmp_param_values, env); + return NULL; + } + dup_pattern = axutil_strdup(env, hash_key); + if(!dup_pattern) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + axutil_array_list_free(tmp_param_keys, env); + axutil_array_list_free(tmp_param_values, env); + AXIS2_FREE(env->allocator, dup_url_component); + return NULL; + } + + matched_status = axis2_core_utils_match_url_component_with_pattern(env, dup_pattern, + dup_url_component, tmp_param_keys, tmp_param_values); + + AXIS2_FREE(env->allocator, dup_url_component); + AXIS2_FREE(env->allocator, dup_pattern); + + if(matched_status == AXIS2_SUCCESS) + { + child_mapping_struct = (axutil_core_utils_map_internal_t*)val; + + if(!next_level_url) + { + /* there is no another level, so the op should be here */ + op_desc = child_mapping_struct->op_desc; + + } + else + { + + /* if there is next level, we should check that level too */ + op_desc = axis2_core_utils_internal_infer_op_from_rest_map_recursively(env, + child_mapping_struct, next_level_url, tmp_param_keys, tmp_param_values); + } + + if(op_desc) + { + /* the operation is found */ + /* but before leaving should merge the param arrays */ + + int i = 0; + void *param_key = NULL; + void *param_value = NULL; + for(i = 0; i < axutil_array_list_size(tmp_param_keys, env); i++) + { + /* size(tmp_param_keys) == size(tmp_param_values) */ + param_key = axutil_array_list_get(tmp_param_keys, env, i); + param_value = axutil_array_list_get(tmp_param_values, env, i); + + /* add it to original array */ + axutil_array_list_add(param_keys, env, param_key); + axutil_array_list_add(param_values, env, param_value); + + } + + /* freeing the temporary arrays */ + axutil_array_list_free(tmp_param_keys, env); + axutil_array_list_free(tmp_param_values, env); + /* since of is found, no more searches needed */ + break; + } + } + + /* if we come here => op is not yet found */ + /* just freeing the temp key and value arrays */ + for(i = 0; i < axutil_array_list_size(tmp_param_keys, env); i++) + { + void *value = axutil_array_list_get(tmp_param_keys, env, i); + if(value) + { + AXIS2_FREE(env->allocator, value); + } + } + for(i = 0; i < axutil_array_list_size(tmp_param_values, env); i++) + { + void *value = axutil_array_list_get(tmp_param_values, env, i); + if(value) + { + AXIS2_FREE(env->allocator, value); + } + } + axutil_array_list_free(tmp_param_keys, env); + axutil_array_list_free(tmp_param_values, env); + } + } + + if(!op_desc) + { + /* this is not an error, since the calling function + may find another opertion match with the url */ + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "The operation descriptor not found for the accessed URL"); + + if(first_delimitter) + { + /* restore the delimmiters */ + *first_delimitter = '/'; + } + } + return op_desc; +} + +/* match a pattern with a url component */ +axis2_status_t +axis2_core_utils_match_url_component_with_pattern( + const axutil_env_t *env, + axis2_char_t *pattern, + axis2_char_t *url_component, + axutil_array_list_t *param_keys, + axutil_array_list_t *param_values) +{ + axutil_array_list_t *const_components = NULL; + axis2_char_t *c = NULL; + axis2_char_t *url_c = NULL; + axis2_char_t *pattern_c = NULL; + axis2_char_t *const_part = NULL; + axis2_char_t *param_part = NULL; + axis2_char_t *param_value = NULL; + axis2_status_t status = AXIS2_SUCCESS; + /* here the state can have following values + 0 - inside a constant + 1 - inside a param + */ + int loop_state = 0; + int i = 0; + int pattern_ending_with_param = 0; + + /* the constant that undergoing matching */ + int matching_constant_index = 0; + axis2_char_t *matching_constant = NULL; + + /* dividing the pattern to consts */ + const_components = axutil_array_list_create(env, 10); + if(!const_components) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + } + /* check whether the pattern ending with a param */ + if(*(pattern + axutil_strlen(pattern) - 1) == '}') + { + pattern_ending_with_param = 1; + } + + const_part = pattern; + /* a parse to fil the const array and key array */ + for(c = pattern; c && *c != '\0'; c++) + { + if(loop_state == 0) + { + /* inside a constant */ + if(*c == '{') + { + if(const_part == c) + { + /* no const part */ + } + else + { + /* add the constant */ + *c = '\0'; + const_part = axutil_strdup(env, const_part); + if(!const_part) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + + status = AXIS2_FAILURE; + break; + + } + axutil_array_list_add(const_components, env, const_part); + + } + param_part = c + 1; /* start the param */ + loop_state = 1; /* moving to the param from next iteration */ + } + else if(*c == '}') + { + /* invalid state */ + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing the url for %s", + url_component); + + status = AXIS2_FAILURE; + break; + } + } + else + { + /* inside a param */ + if(*c == '}') + { + if(*(c + 1) == '{') /* you can not have two params without a constant in between */ + { + /* invalid state */ + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR( + env->log, + AXIS2_LOG_SI, + "Error in parsing the url for %s, Please put constant between 2 parameters", + url_component); + + status = AXIS2_FAILURE; + break; + } + if(param_part == c) + { + /* no param part */ + } + else + { + /* add the param */ + *c = '\0'; + param_part = axutil_strdup(env, param_part); + + if(param_part == NULL) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + status = AXIS2_FAILURE; + break; + } + axutil_array_list_add(param_keys, env, param_part); + + const_part = c + 1; /* start the const */ + } + loop_state = 0; /* moving to the const from next iteration */ + } + else if(*c == '{') + { + /* invalid state */ + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing the url for %s", + url_component); + + status = AXIS2_FAILURE; + break; + + } + } + } + /* loop should stop in state 0 */ + if(loop_state != 0) + { + status = AXIS2_FAILURE; + } + + if(const_part != c) + { + /* add the tailing const */ + const_part = axutil_strdup(env, const_part); + if(!const_part) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + status = AXIS2_FAILURE; + } + axutil_array_list_add(const_components, env, const_part); + } + + if(axutil_array_list_size(const_components, env) == 0 && status == AXIS2_SUCCESS) + { + /* no constants mean, the url componenent itself is the value */ + url_component = axutil_strdup(env, url_component); + if(url_component) + { + axutil_array_list_add(param_values, env, url_component); + + /* free the empty const array */ + + axutil_array_list_free(const_components, env); + return AXIS2_SUCCESS; + } + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + status = AXIS2_FAILURE; + + } + + if(status == AXIS2_FAILURE) + { + /* invalid state */ + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing the url for %s", url_component); + + /* free the const array */ + for(i = 0; i < axutil_array_list_size(const_components, env); i++) + { + void *value; + value = axutil_array_list_get(const_components, env, i); + + AXIS2_FREE(env->allocator, value); + } + + axutil_array_list_free(const_components, env); + + return status; + } + + /* we are tracking the loop_state here too - this is useful only to track start*/ + /* we are using the param_value part to track the matching param value */ + if(*pattern != '{') + { + /* starting_with_constant */ + loop_state = 0; + param_value = NULL; + } + else + { + /* starting_with_param */ + loop_state = 1; + param_value = url_component; + + } + + matching_constant_index = 0; + matching_constant = axutil_array_list_get(const_components, env, 0); + + /* now parse the url component */ + for(url_c = url_component; *url_c != '\0' && status == AXIS2_SUCCESS && matching_constant + != NULL; url_c++) + { + axis2_char_t *tmp_url_c = url_c; + pattern_c = matching_constant; + + while(*tmp_url_c == *pattern_c && *tmp_url_c != '\0' && *pattern_c != '\0') + { + tmp_url_c++; + pattern_c++; + } + + if(*pattern_c == '\0') + { + /* we finised matching the constant pattern successfuly*/ + if(loop_state == 0) + { + /* loop_state => we expected there is a constant */ + } + else + { + /* we expected a param, but the constant is found => + url_c should mark the end of the param */ + if(param_value == NULL) + { + /* unexpected invalid state */ + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_URL_FORMAT, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing the url for %s", + url_component); + status = AXIS2_FAILURE; + } + *url_c = '\0'; + param_value = axutil_strdup(env, param_value); + + if(param_value == NULL) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + status = AXIS2_FAILURE; + break; + } + axutil_array_list_add(param_values, env, param_value); + + } + /* next the param part is starting */ + param_value = tmp_url_c; + + loop_state = 1; /* the end of the constant expects, start of a variable */ + + /* so we found one constant, go for the other */ + matching_constant_index++; + matching_constant = axutil_array_list_get(const_components, env, + matching_constant_index); + + tmp_url_c--; + /* increment the url_c to tmp_url_c */ + url_c = tmp_url_c; + } + else + { + /* pattern not matched */ + if(loop_state == 0) + { + /* we are expected this to be a constant, but it has not happend + * mean: the pattern match failed + */ + status = AXIS2_FAILURE; + break; + } + } + + } + + if(matching_constant_index != axutil_array_list_size(const_components, env)) + { + status = AXIS2_FAILURE; + } + + if(pattern_ending_with_param) + { + if(param_value) + { + param_value = axutil_strdup(env, param_value); + + if(param_value == NULL) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create internal rest mapping structure"); + status = AXIS2_FAILURE; + } + else + { + axutil_array_list_add(param_values, env, param_value); + } + } + } + else if(*url_c != '\0') + { + /* here the pattern ending is a constant (not a param), and matches all are already made + * but some url part left => this is a not mach */ + status = AXIS2_FAILURE; + } + + /* finally freeing the const array */ + for(i = 0; i < axutil_array_list_size(const_components, env); i++) + { + void *value; + value = axutil_array_list_get(const_components, env, i); + + AXIS2_FREE(env->allocator, value); + } + axutil_array_list_free(const_components, env); + + return status; +} |