From 0425aadc78680e53000fd0108b540d6eca048516 Mon Sep 17 00:00:00 2001 From: gmcdonald Date: Sat, 13 Feb 2010 01:32:03 +0000 Subject: Moving axis svn, part of TLP move INFRA-2441 git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68 --- src/core/transport/http/util/Makefile.am | 14 + .../transport/http/util/http_transport_utils.c | 3885 ++++++++++++++++++++ 2 files changed, 3899 insertions(+) create mode 100644 src/core/transport/http/util/Makefile.am create mode 100644 src/core/transport/http/util/http_transport_utils.c (limited to 'src/core/transport/http/util') 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 *)"

Deployed Services

"; + 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, "

"); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, sname); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "

"); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "

"); + 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, "

"); + 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, "Available Operations
    "); + 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, "
  • "); + 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, "
  • "); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + } + ret = axutil_stracat(env, tmp2, "
"); + 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, + "

Faulty \ + Services

"); + 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, "

"); + 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, "

"); + AXIS2_FREE(env->allocator, tmp2); + tmp2 = ret; + } + } + if(AXIS2_FALSE == svcs_exists) + { + ret = axutil_strdup(env, "

There are no services deployed

"); + } + ret = axutil_stracat(env, "Axis2C :: Services" + "", tmp2); + tmp2 = ret; + ret = axutil_stracat(env, tmp2, "\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); +} + + -- cgit v1.1-32-gdbae