/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <axis2_http_transport_utils.h>
#include <string.h>
#include <ctype.h>
#include <axis2_conf.h>
#include <axis2_op.h>
#include <axutil_qname.h>
#include <axis2_http_transport.h>
#include <axiom_soap_builder.h>
#include <axis2_engine.h>
#include <axiom_soap_body.h>
#include <axutil_utils.h>
#include <axiom_namespace.h>
#include <axiom_node.h>
#include <axutil_hash.h>
#include <axiom_soap_const.h>
#include <axis2_http_header.h>
#include <axutil_property.h>
#include <axutil_utils.h>
#include <axiom_mime_parser.h>
#include <axis2_http_accept_record.h>
#include <axis2_disp.h>
#include <axis2_msg.h>
#include <axutil_string_util.h>
#include <stdlib.h>
#include <axutil_uuid_gen.h>
#include <platforms/axutil_platform_auto_sense.h>
#include <axiom_mime_part.h>
#include <axutil_class_loader.h>

#ifdef AXIS2_JSON_ENABLED
#include <axis2_json_reader.h>
#endif

#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_char_t *encoding_header_value = NULL;

    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);
    
	encoding_header_value = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env);

    if(encoding_header_value && axutil_strstr(encoding_header_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");
    }else 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
    {
        
        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);

    axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str);

#ifdef AXIS2_JSON_ENABLED
    if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
    {
        axis2_json_reader_t* json_reader = NULL;
        axiom_soap_body_t* soap_body = NULL;
        axiom_node_t* root_node = NULL;

        json_reader = axis2_json_reader_create_for_stream(env, in_stream);
        if (!json_reader)
        {
            axis2_json_reader_free(json_reader, env);
            return AXIS2_FAILURE;
        }

        status = axis2_json_reader_read(json_reader, env);
        if (status != AXIS2_SUCCESS)
        {
            axis2_json_reader_free(json_reader, env);
            return status;
        }

        root_node = axis2_json_reader_get_root_node(json_reader, env);
        if (!root_node)
        {
            axis2_json_reader_free(json_reader, env);
            return AXIS2_FAILURE;
        }

        axis2_json_reader_free(json_reader, env);

        soap_envelope =
                axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
        soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
        axiom_soap_body_add_child(soap_body, env, root_node);
        axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
        axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
        axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_POST);
    }
    else
    {
#endif
    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;
    }

    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;
            }
        }
    }
#ifdef AXIS2_JSON_ENABLED
    }
#endif

    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);
                if (!om_doc)
                    return AXIS2_FAILURE;
                root_node = axiom_document_get_root_element(om_doc, env);
                if (!root_node)
                    return AXIS2_FAILURE;
                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);

#ifdef AXIS2_JSON_ENABLED
    if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
    {
        axis2_json_reader_t* json_reader = NULL;
        axiom_soap_body_t* soap_body = NULL;
        axiom_node_t* root_node = NULL;

        json_reader = axis2_json_reader_create_for_stream(env, in_stream);
        if (!json_reader)
        {
            axis2_json_reader_free(json_reader, env);
            return AXIS2_FAILURE;
        }

        status = axis2_json_reader_read(json_reader, env);
        if (status != AXIS2_SUCCESS)
        {
            axis2_json_reader_free(json_reader, env);
            return status;
        }

        root_node = axis2_json_reader_get_root_node(json_reader, env);
        if (!root_node)
        {
            axis2_json_reader_free(json_reader, env);
            return AXIS2_FAILURE;
        }

        axis2_json_reader_free(json_reader, env);

        soap_envelope =
                axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
        soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
        axiom_soap_body_add_child(soap_body, env, root_node);
        axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
        axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
        axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_PUT);
    }
    else
    {
#endif

    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);
                if (!om_doc)
                    return AXIS2_FAILURE;
                root_node = axiom_document_get_root_element(om_doc, env);
                if (!root_node)
                    return AXIS2_FAILURE;
                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;
        }
    }
#ifdef AXIS2_JSON_ENABLED
    }
#endif

    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);

#ifdef AXIS2_JSON_ENABLED
    if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
    {
        axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
    }
    else
#endif
    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);

#ifdef AXIS2_JSON_ENABLED
    if (content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
    {
        axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
    }
    else
#endif
    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);

#ifdef AXIS2_JSON_ENABLED
    if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
    {
        axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
    }
    else
#endif
    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);
    }

    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_DELETE);
    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_do_write_mtom(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);

    return (axis2_msg_ctx_get_doing_mtom(msg_ctx, env));
}

AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axis2_http_transport_utils_get_request_params(
    const axutil_env_t * env,
    axis2_char_t * request_uri)
{

    axis2_char_t *query_str = NULL;
    axis2_char_t *tmp = strchr(request_uri, AXIS2_Q_MARK);
    axis2_char_t *tmp2 = NULL;
    axis2_char_t *tmp_name = NULL;
    axis2_char_t *tmp_value = NULL;
    axutil_hash_t *ret = NULL;

    AXIS2_PARAM_CHECK(env->error, request_uri, NULL);

    if(!tmp || AXIS2_ESC_NULL == *(tmp + 1))
    {
        return NULL;
    }
    query_str = axutil_strdup(env, tmp + 1);

    for(tmp2 = tmp = query_str; *tmp != AXIS2_ESC_NULL; ++tmp)
    {
        if(AXIS2_EQ == *tmp)
        {
            *tmp = AXIS2_ESC_NULL;
            tmp_name = axutil_strdup(env, tmp2);
            axis2_http_transport_utils_strdecode(env, tmp_name, tmp_name);
            tmp2 = tmp + 1;
        }
        if(AXIS2_AND == *tmp)
        {
            *tmp = AXIS2_ESC_NULL;
            tmp_value = axutil_strdup(env, tmp2);
            axis2_http_transport_utils_strdecode(env, tmp_value, tmp_value);
            tmp2 = tmp + 1;
        }
        if(tmp_name && NULL != tmp_value)
        {
            if(!ret)
            {
                ret = axutil_hash_make(env);
            }
            axutil_hash_set(ret, tmp_name, AXIS2_HASH_KEY_STRING, tmp_value);
            tmp_name = NULL;
            tmp_value = NULL;
        }
    }
    if(tmp_name && AXIS2_ESC_NULL != *tmp2)
    {
        if(!ret)
        {
            ret = axutil_hash_make(env);
        }
        tmp_value = axutil_strdup(env, tmp2);
        axis2_http_transport_utils_strdecode(env, tmp_value, tmp_value);
        axutil_hash_set(ret, tmp_name, AXIS2_HASH_KEY_STRING, tmp_value);
    }

    return ret;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_strdecode(
    const axutil_env_t * env,
    axis2_char_t * dest,
    axis2_char_t * src)
{
    AXIS2_PARAM_CHECK(env->error, dest, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, src, AXIS2_FAILURE);

    for(; *src != AXIS2_ESC_NULL; ++dest, ++src)
    {
        if(src[0] == AXIS2_PERCENT && isxdigit((int)src[1]) && isxdigit((int)src[2]))
        {
            *dest = (axis2_char_t)(axis2_http_transport_utils_hexit(src[1]) * 16
                + axis2_http_transport_utils_hexit(src[2]));
            /* We are sure that the conversion is valid */
            src += 2;
        }
        else
        {
            *dest = *src;
        }
    }
    *dest = AXIS2_ESC_NULL;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axis2_http_transport_utils_hexit(
    axis2_char_t c)
{
    if(c >= '0' && c <= '9')
    {
        return c - '0';
    }
    if(c >= 'a' && c <= 'f')
    {
        return c - 'a' + 10;
    }
    if(c >= 'A' && c <= 'F')
    {
        return c - 'A' + 10;
    }
    return 0; /* shouldn't happen, we're guarded by isxdigit() */
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_not_found(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_NOT_FOUND;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_not_implemented(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_NOT_IMPLEMENTED;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_internal_server_error(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_INTERNAL_SERVER_ERROR;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_method_not_allowed(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_METHOD_NOT_ALLOWED;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_not_acceptable(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_NOT_ACCEPTABLE;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_bad_request(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_BAD_REQUEST;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_request_timeout(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_REQUEST_TIMEOUT;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_conflict(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_CONFLICT;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_gone(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_GONE;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_precondition_failed(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_PRECONDITION_FAILED;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_request_entity_too_large(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_TOO_LARGE;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_service_unavailable(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    return AXIS2_HTTP_SERVICE_UNAVILABLE;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_services_html(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx)
{
    axutil_hash_t *services_map = NULL;
    axutil_hash_t *errorneous_svc_map = NULL;
    axis2_char_t *ret = NULL;
    axis2_char_t *tmp2 = (axis2_char_t *)"<h2>Deployed Services</h2>";
    axutil_hash_index_t *hi = NULL;
    axis2_bool_t svcs_exists = AXIS2_FALSE;
    axis2_conf_t *conf = NULL;
    AXIS2_PARAM_CHECK(env->error, conf_ctx, NULL);

    conf = axis2_conf_ctx_get_conf(conf_ctx, env);
    services_map = axis2_conf_get_all_svcs(conf, env);
    errorneous_svc_map = axis2_conf_get_all_faulty_svcs(conf, env);
    if(services_map && 0 != axutil_hash_count(services_map))
    {
        void *service = NULL;
        axis2_char_t *sname = NULL;
        axutil_hash_t *ops = NULL;
        svcs_exists = AXIS2_TRUE;

        for(hi = axutil_hash_first(services_map, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, NULL, NULL, &service);
            sname = axutil_qname_get_localpart(axis2_svc_get_qname(((axis2_svc_t *)service), env),
                env);
            ret = axutil_stracat(env, tmp2, "<h3><u>");
            tmp2 = ret;
            ret = axutil_stracat(env, tmp2, sname);
            AXIS2_FREE(env->allocator, tmp2);
            tmp2 = ret;
            ret = axutil_stracat(env, tmp2, "</u></h3>");
            tmp2 = ret;
            ret = axutil_stracat(env, tmp2, "<p>");
            tmp2 = ret;

            /**
             *setting services description */
            ret = axutil_stracat(env, tmp2, axis2_svc_get_svc_desc((axis2_svc_t *)service, env));
            tmp2 = ret;
            ret = axutil_stracat(env, tmp2, "</p>");
            tmp2 = ret;
            ops = axis2_svc_get_all_ops(((axis2_svc_t *)service), env);
            if(ops && 0 != axutil_hash_count(ops))
            {
                axutil_hash_index_t *hi2 = NULL;
                void *op = NULL;
                axis2_char_t *oname = NULL;

                ret = axutil_stracat(env, tmp2, "<i>Available Operations</i> <ul>");
                AXIS2_FREE(env->allocator, tmp2);
                tmp2 = ret;
                for(hi2 = axutil_hash_first(ops, env); hi2; hi2 = axutil_hash_next(env, hi2))
                {
                    axutil_hash_this(hi2, NULL, NULL, &op);
                    oname = axutil_qname_get_localpart(axis2_op_get_qname(((axis2_op_t *)op), env),
                        env);
                    ret = axutil_stracat(env, tmp2, "<li>");
                    AXIS2_FREE(env->allocator, tmp2);
                    tmp2 = ret;

                    ret = axutil_stracat(env, tmp2, oname);
                    AXIS2_FREE(env->allocator, tmp2);
                    tmp2 = ret;
                    ret = axutil_stracat(env, tmp2, "</li>");
                    AXIS2_FREE(env->allocator, tmp2);
                    tmp2 = ret;
                }
                ret = axutil_stracat(env, tmp2, "</ul>");
                AXIS2_FREE(env->allocator, tmp2);
                tmp2 = ret;
            }
            else
            {
                ret = axutil_stracat(env, tmp2, "No operations Available");
                tmp2 = ret;
            }
        }
    }

    if(errorneous_svc_map && 0 != axutil_hash_count(errorneous_svc_map))
    {
        void *fsname = NULL;
        svcs_exists = AXIS2_TRUE;
        ret = axutil_stracat(env, tmp2,
            "<hr><h2><font color=\"red\">Faulty \
        Services</font></h2>");
        AXIS2_FREE(env->allocator, tmp2);
        tmp2 = ret;

        for(hi = axutil_hash_first(errorneous_svc_map, env); hi; axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, (const void **)&fsname, NULL, NULL);
            ret = axutil_stracat(env, tmp2, "<h3><font color=\"red\">");
            AXIS2_FREE(env->allocator, tmp2);
            tmp2 = ret;
            ret = axutil_stracat(env, tmp2, (axis2_char_t *)fsname);
            AXIS2_FREE(env->allocator, tmp2);
            tmp2 = ret;
            ret = axutil_stracat(env, tmp2, "</font></h3>");
            AXIS2_FREE(env->allocator, tmp2);
            tmp2 = ret;
        }
    }
    if(AXIS2_FALSE == svcs_exists)
    {
        ret = axutil_strdup(env, "<h2>There are no services deployed</h2>");
    }
    ret = axutil_stracat(env, "<html><head><title>Axis2C :: Services</title></head>"
        "<body><font face=\"courier\">", tmp2);
    tmp2 = ret;
    ret = axutil_stracat(env, tmp2, "</font></body></html>\r\n");

    return ret;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_services_static_wsdl(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx,
    axis2_char_t * request_url)
{
    axis2_char_t *wsdl_string = NULL;
    axis2_char_t *wsdl_path = NULL;
    axis2_char_t **url_tok = NULL;
    unsigned int len = 0;
    axis2_char_t *svc_name = NULL;
    axis2_conf_t *conf = NULL;
    axutil_hash_t *services_map = NULL;
    axutil_hash_index_t *hi = NULL;

    AXIS2_PARAM_CHECK(env->error, conf_ctx, NULL);
    AXIS2_PARAM_CHECK(env->error, request_url, NULL);

    url_tok = axutil_parse_request_url_for_svc_and_op(env, request_url);
    if(url_tok[0])
    {
        len = (int)strlen(url_tok[0]);
        /* We are sure that the difference lies within the int range */
        url_tok[0][len - 5] = 0;
        svc_name = url_tok[0];
    }

    conf = axis2_conf_ctx_get_conf(conf_ctx, env);
    services_map = axis2_conf_get_all_svcs(conf, env);

    if(services_map && 0 != axutil_hash_count(services_map))
    {
        void *service = NULL;
        axis2_char_t *sname = NULL;

        for(hi = axutil_hash_first(services_map, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, NULL, NULL, &service);
            sname = axutil_qname_get_localpart(axis2_svc_get_qname(((axis2_svc_t *)service), env),
                env);
            if(!axutil_strcmp(svc_name, sname))
            {
                wsdl_path = (axis2_char_t *)axutil_strdup(env, axis2_svc_get_svc_wsdl_path(
                    (axis2_svc_t *)service, env));
                if(!wsdl_path)
                {
                    wsdl_path = axutil_strcat(env, axis2_svc_get_svc_folder_path(
                        (axis2_svc_t *)service, env), AXIS2_PATH_SEP_STR, svc_name, ".wsdl", NULL);
                }
                break;
            }

        }
    }

    if(wsdl_path)
    {
        FILE *wsdl_file = NULL;
        axis2_char_t *content = NULL;
        int c;
        int size = AXIS2_FILE_READ_SIZE;
        axis2_char_t *tmp;
        int i = 0;

        content = (axis2_char_t *)AXIS2_MALLOC(env->allocator, size);
        wsdl_file = fopen(wsdl_path, "r");
        if(wsdl_file)
        {
            c = fgetc(wsdl_file);
            while(c != EOF)
            {
                if(i >= size)
                {
                    size = size * 3;
                    tmp = (axis2_char_t *)AXIS2_MALLOC(env->allocator, size);
                    memcpy(tmp, content, i);
                    AXIS2_FREE(env->allocator, content);
                    content = tmp;
                }
                content[i++] = (axis2_char_t)c;
                c = fgetc(wsdl_file);
            }
            content[i] = AXIS2_ESC_NULL;
            wsdl_string = (axis2_char_t *)content;
			fclose(wsdl_file);
        }
		
        AXIS2_FREE(env->allocator, wsdl_path);
    }
    else
    {
        wsdl_string = axutil_strdup(env, "Unable to retrieve wsdl for this service");
    }

    return wsdl_string;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axis2_http_transport_utils_get_charset_enc(
    const axutil_env_t * env,
    const axis2_char_t * content_type)
{
    axis2_char_t *tmp = NULL;
    axis2_char_t *tmp_content_type = NULL;
    axis2_char_t *tmp2 = NULL;
    axutil_string_t *str = NULL;

    AXIS2_PARAM_CHECK(env->error, content_type, NULL);

    tmp_content_type = (axis2_char_t *)content_type;
    if(!tmp_content_type)
    {
        return axutil_string_create_const(env,
            (axis2_char_t **)&AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING);
    }

    tmp = strstr(tmp_content_type, AXIS2_HTTP_CHAR_SET_ENCODING);

    if(tmp)
    {
        tmp = strchr(tmp, AXIS2_EQ);
        if(tmp)
        {
            tmp2 = strchr(tmp, AXIS2_SEMI_COLON);
            if(!tmp2)
            {
                tmp2 = tmp + strlen(tmp);
            }
        }

        if(tmp2)
        {
            if('\'' == *(tmp2 - sizeof(axis2_char_t)) || '\"' == *(tmp2 - sizeof(axis2_char_t)))
            {
                tmp2 -= sizeof(axis2_char_t);
            }
            *tmp2 = AXIS2_ESC_NULL;
        }
    }

    if(tmp)
    {
        /* Following formats are acceptable
         * charset="UTF-8"
         * charser='UTF-8'
         * charset=UTF-8
         * But for our requirements charset we get should be UTF-8
         */
        if(AXIS2_ESC_SINGLE_QUOTE == *(tmp + sizeof(axis2_char_t)) || AXIS2_ESC_DOUBLE_QUOTE
            == *(tmp + sizeof(axis2_char_t)))
        {
            tmp += 2 * sizeof(axis2_char_t);
        }
        else
        {
            tmp += sizeof(axis2_char_t);
        }
    }

    if(tmp)
    {
        str = axutil_string_create(env, tmp);
    }
    else
    {
        str = axutil_string_create_const(env,
            (axis2_char_t **)&AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING);
    }
    return str;
}

int AXIS2_CALL
axis2_http_transport_utils_on_data_request(
    char *buffer,
    int size,
    void *ctx)
{
    const axutil_env_t *env = NULL;
    int len = -1;
    axis2_callback_info_t *cb_ctx = (axis2_callback_info_t *)ctx;

    if(!buffer || !ctx)
    {
        return 0;
    }
    env = ((axis2_callback_info_t *)ctx)->env;
    if(cb_ctx->unread_len <= 0 && -1 != cb_ctx->content_length)
    {
        return 0;
    }
    if(cb_ctx->chunked_stream)
    {
        --size;
        /* reserve space to insert trailing null */
        len = axutil_http_chunked_stream_read(cb_ctx->chunked_stream, env, buffer, size);
        if(len >= 0)
        {
            buffer[len] = AXIS2_ESC_NULL;
        }
    }
    else
    {
        axutil_stream_t *in_stream = NULL;
        in_stream = (axutil_stream_t *)((axis2_callback_info_t *)ctx)->in_stream;
        --size; /* reserve space to insert trailing null */
        len = axutil_stream_read(in_stream, env, buffer, size);
        if(len > 0)
        {
            buffer[len] = AXIS2_ESC_NULL;
            ((axis2_callback_info_t *)ctx)->unread_len -= len;
        }
        else if(len == 0)
        {
            ((axis2_callback_info_t *)ctx)->unread_len = 0;
        }
    }
    return len;
}

AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
axis2_http_transport_utils_create_soap_msg(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    const axis2_char_t * soap_ns_uri)
{
    axis2_op_ctx_t *op_ctx = NULL;
    const axis2_char_t *char_set_enc = NULL;
    axis2_char_t *content_type = NULL;
    axutil_stream_t *in_stream = NULL;
    axis2_callback_info_t *callback_ctx = NULL;
    axis2_char_t *trans_enc = NULL;
    int *content_length = NULL;
    axutil_property_t *property = NULL;
    axutil_hash_t *binary_data_map = NULL;
    axiom_soap_envelope_t *soap_envelope = NULL;
    axutil_stream_t *stream = NULL;

    AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL);
    AXIS2_PARAM_CHECK(env->error, soap_ns_uri, NULL);

    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_IN);
    if(property)
    {
        in_stream = axutil_property_get_value(property, env);
        property = NULL;
    }
    callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t));
    /* Note: the memory created above is freed in xml reader free function
     as this is passed on to the reader */
    if(!callback_ctx)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    callback_ctx->in_stream = in_stream;
    callback_ctx->env = env;
    callback_ctx->content_length = -1;
    callback_ctx->unread_len = -1;
    callback_ctx->chunked_stream = NULL;

    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH);
    if(property)
    {
        content_length = axutil_property_get_value(property, env);
        property = NULL;
    }

    if(content_length)
    {
        callback_ctx->content_length = *content_length;
        callback_ctx->unread_len = *content_length;
    }

    if(!in_stream)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_IN_STREAM_IN_MSG_CTX, AXIS2_FAILURE);
        AXIS2_FREE(env->allocator, callback_ctx);
        return NULL;
    }

    trans_enc = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env);

    if(trans_enc && 0 == axutil_strcmp(trans_enc, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
    {
        callback_ctx->chunked_stream = axutil_http_chunked_stream_create(env, in_stream);
        if(!callback_ctx->chunked_stream)
        {
            return NULL;
        }
    }

    op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
    if(op_ctx)
    {
        axis2_ctx_t *ctx = axis2_op_ctx_get_base(op_ctx, env);
        if(ctx)
        {
            property = axis2_ctx_get_property(ctx, env, AXIS2_CHARACTER_SET_ENCODING);
            if(property)
            {
                char_set_enc = axutil_property_get_value(property, env);
                property = NULL;
            }
            property = axis2_ctx_get_property(ctx, env, MTOM_RECIVED_CONTENT_TYPE);
            if(property)
            {
                content_type = axutil_property_get_value(property, env);
                property = NULL;
            }

        }
    }

    if(!char_set_enc)
    {
        char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING;
    }
    if(content_type)
    {
        axis2_char_t *mime_boundary = NULL;
        axis2_msg_ctx_set_doing_mtom(msg_ctx, env, AXIS2_TRUE);
        /* get mime boundry */
        mime_boundary = axis2_http_transport_utils_get_value_from_content_type(env, content_type,
            AXIS2_HTTP_HEADER_CONTENT_TYPE_MIME_BOUNDARY);

        if(mime_boundary)
        {
            axiom_mime_parser_t *mime_parser = NULL;
            int soap_body_len = 0;
            axis2_char_t *soap_body_str = NULL;
            axutil_param_t *buffer_size_param = NULL;
            axutil_param_t *max_buffers_param = NULL;
            axutil_param_t *attachment_dir_param = NULL;
            axutil_param_t *callback_name_param = NULL;
            axis2_char_t *value_size = NULL;
            axis2_char_t *value_num = NULL;
            axis2_char_t *value_dir = NULL;
            axis2_char_t *value_callback = NULL;
            int size = 0;
            int num = 0;

            mime_parser = axiom_mime_parser_create(env);

            /* Following are the parameters in the axis2.xml regarding MTOM */

            buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE);
            if(buffer_size_param)
            {
                value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env);

                if(value_size)
                {
                    size = atoi(value_size);
                    axiom_mime_parser_set_buffer_size(mime_parser, env, size);
                }
            }

            max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS);
            if(max_buffers_param)
            {
                value_num = (axis2_char_t *)axutil_param_get_value(max_buffers_param, env);
                if(value_num)
                {
                    num = atoi(value_num);
                    axiom_mime_parser_set_max_buffers(mime_parser, env, num);
                }
            }

            callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env,
                AXIS2_MTOM_CACHING_CALLBACK);
            if(callback_name_param)
            {
                value_callback = (axis2_char_t *)axutil_param_get_value(callback_name_param, env);
                if(value_callback)
                {
                    axiom_mime_parser_set_caching_callback_name(mime_parser, env, value_callback);
                }
            }

            attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR);
            if(attachment_dir_param)
            {
                value_dir = (axis2_char_t *)axutil_param_get_value(attachment_dir_param, env);
                if(value_dir)
                {
                    axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
                }
            }

            if(mime_parser)
            {
                if(axiom_mime_parser_parse_for_soap(mime_parser, env,
                    axis2_http_transport_utils_on_data_request, (void *)callback_ctx, mime_boundary)
                    == AXIS2_FAILURE)
                {
                    return NULL;
                }

                binary_data_map = axiom_mime_parser_parse_for_attachments(mime_parser, env,
                    axis2_http_transport_utils_on_data_request, (void *)callback_ctx,
                    mime_boundary, NULL);
                if(!binary_data_map)
                {
                    return NULL;
                }

                if(!binary_data_map)
                {
                    return NULL;
                }

                soap_body_len = (int)axiom_mime_parser_get_soap_body_len(mime_parser, env);
                soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env);
            }

            if(callback_ctx->chunked_stream)
            {
                axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env);
                callback_ctx->chunked_stream = NULL;
            }

            stream = axutil_stream_create_basic(env);
            if(stream)
            {
                axutil_stream_write(stream, env, soap_body_str, soap_body_len);
                callback_ctx->in_stream = stream;
                callback_ctx->chunked_stream = NULL;
                callback_ctx->content_length = soap_body_len;
                callback_ctx->unread_len = soap_body_len;
            }

            axiom_mime_parser_free(mime_parser, env);
            mime_parser = NULL;
            if(mime_boundary)
            {
                AXIS2_FREE(env->allocator, mime_boundary);
            }

            if(soap_body_str)
            {
                AXIS2_FREE(env->allocator, soap_body_str);
            }
        }
    }

    if(AXIS2_TRUE != axis2_msg_ctx_get_doing_rest(msg_ctx, env))
    {
        axiom_xml_reader_t *xml_reader = NULL;
        axiom_stax_builder_t *om_builder = NULL;
        axiom_soap_builder_t *soap_builder = NULL;

        xml_reader = axiom_xml_reader_create_for_io(env,
            axis2_http_transport_utils_on_data_request, NULL, (void *)callback_ctx, char_set_enc);
        if(!xml_reader)
        {
            return NULL;
        }
        om_builder = axiom_stax_builder_create(env, xml_reader);
        if(!om_builder)
        {
            axiom_xml_reader_free(xml_reader, env);
            xml_reader = NULL;
            return NULL;
        }
        soap_builder = axiom_soap_builder_create(env, om_builder, soap_ns_uri);
        if(!soap_builder)
        {
            /* We should not be freeing om_builder here as it is done by
             axiom_soap_builder_create in case of error - Samisa */
            om_builder = NULL;
            xml_reader = NULL;
            return NULL;
        }

        soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);

        if(binary_data_map)
        {
            axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map);
        }


        if(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);
        if (!om_doc)
            return AXIS2_FAILURE;
        root_node = axiom_document_get_root_element(om_doc, env);
        if (!root_node)
            return AXIS2_FAILURE;
        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);

        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;
        }

    }

    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))
    {
		axis2_handler_desc_t *desc;
        rest_disp = axis2_rest_disp_create(env);
        handler = axis2_disp_get_base(rest_disp, env);
        axis2_handler_invoke(handler, env, msg_ctx);
		axis2_disp_free(rest_disp, env);
		desc = axis2_handler_get_handler_desc(handler, env);
		if(desc)
		{
			axis2_handler_desc_free(desc, env);
		}

        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_record_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);
                    response->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);
        }
        else if((mime_part->type) == AXIOM_MIME_PART_HANDLER) 
        {
            void *handler_data = NULL;
            axiom_mtom_sending_callback_t *callback = NULL;

            status = mime_part->read_handler_create(&callback, env);

            if(callback)
            {
                handler_data = AXIOM_MTOM_SENDING_CALLBACK_INIT_HANDLER(callback, env,
                    mime_part->user_param);

                if (handler_data)
                {
                    status = axis2_http_transport_utils_send_attachment_using_callback(env,
                        chunked_stream, callback, handler_data, mime_part->user_param);
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MTOM Sending Handler loading failed");
                    status = AXIS2_FAILURE;
                }

                mime_part->read_handler_remove(callback, env);
            }

            if(status == AXIS2_FAILURE)
            {
                return status;
            }
        }
        /* 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", "");

        /* Note that in addition to storing the values in the session table into a string, we also 
         * free the session table entries in the following loop,  because we are going to store them 
         * into the session database.
         */
        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;
        }
        /* Store the session in the session database */
        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
    {
        /* This means session is already created in a previous request.*/
        time_str = axutil_hash_get(ht, "expires", AXIS2_HASH_KEY_STRING);
        /* Free the session hash table entries, because session entries are already in the
         * session database.
         */
        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;
            value = (axis2_char_t *) val;
            if(name)
            {
                AXIS2_FREE(env->allocator, name);
            }
            if(value)
            {
                AXIS2_FREE(env->allocator, value);
            }
        }
    }
    header_value = AXIS2_MALLOC(env->allocator, 256 * sizeof(axis2_char_t));
    sprintf(header_value, "ID=%s; expires=%s;", session_id, time_str);

    /* Free the session hash table here */
    axutil_hash_free(ht, env);
    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);
    }
    /* session hash table does not belong to property.*/
    property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE, 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);
}


