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

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

#define AXIOM_MIME_BOUNDARY_BYTE 45

/** Size of the buffer to be used when reading a file */
#ifndef AXIS2_FILE_READ_SIZE
#define AXIS2_FILE_READ_SIZE 2048
#endif

/** Content length value to be used in case of chunked content  */
#ifndef AXIS2_CHUNKED_CONTENT_LENGTH
#define AXIS2_CHUNKED_CONTENT_LENGTH 100000000
#endif

const axis2_char_t *AXIS2_TRANS_UTIL_DEFAULT_CHAR_ENCODING =
    AXIS2_HTTP_HEADER_DEFAULT_CHAR_ENCODING;

/***************************** Function headers *******************************/

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_process_http_post_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    const int content_length,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri);

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_process_http_put_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    const int content_length,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri);

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_transport_utils_process_http_get_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri,
    axis2_conf_ctx_t * conf_ctx,
    axutil_hash_t * request_params);

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_transport_utils_process_http_head_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri,
    axis2_conf_ctx_t * conf_ctx,
    axutil_hash_t * request_params);

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_transport_utils_process_http_delete_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri,
    axis2_conf_ctx_t * conf_ctx,
    axutil_hash_t * request_params);

AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL
axis2_http_transport_utils_select_builder_for_mime(
    const axutil_env_t * env,
    axis2_char_t * request_uri,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axis2_char_t * content_type);

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_transport_utils_is_optimized(
    const axutil_env_t * env,
    axiom_element_t * om_element);

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_transport_utils_do_write_mtom(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx);

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_strdecode(
    const axutil_env_t * env,
    axis2_char_t * dest,
    axis2_char_t * src);

AXIS2_EXTERN int AXIS2_CALL
axis2_http_transport_utils_hexit(
    axis2_char_t c);

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_services_html(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx);

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_services_static_wsdl(
    const axutil_env_t * env,
    axis2_conf_ctx_t * conf_ctx,
    axis2_char_t * request_url);

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axis2_http_transport_utils_get_charset_enc(
    const axutil_env_t * env,
    const axis2_char_t * content_type);

int AXIS2_CALL
axis2_http_transport_utils_on_data_request(
    char *buffer,
    int size,
    void *ctx);

AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
axis2_http_transport_utils_create_soap_msg(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    const axis2_char_t * soap_ns_uri);

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_value_from_content_type(
    const axutil_env_t * env,
    const axis2_char_t * content_type,
    const axis2_char_t * key);

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_dispatch_and_verify(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx);

AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
axis2_http_transport_utils_handle_media_type_url_encoded(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_hash_t * param_map,
    axis2_char_t * method);

AXIS2_EXTERN void AXIS2_CALL
axis2_http_transport_utils_session_map_free_void_arg(
    void *sm_void,
    const axutil_env_t *env);

static axis2_status_t
axis2_http_transport_utils_send_attachment_using_file(
    const axutil_env_t * env,
    axutil_http_chunked_stream_t *chunked_stream,
    FILE *fp,
    axis2_byte_t *buffer,
    int buffer_size);

static axis2_status_t
axis2_http_transport_utils_send_attachment_using_callback(
    const axutil_env_t * env,
    axutil_http_chunked_stream_t *chunked_stream,
    axiom_mtom_sending_callback_t *callback,
    void *handler,
    void *user_param);

static axis2_char_t *
axis2_http_transport_utils_copy_key(
        const axutil_env_t *env, 
        axis2_char_t *);
    
static axis2_char_t *
axis2_http_transport_utils_copy_value(
        const axutil_env_t *env, 
        axis2_char_t *pair);

static void 
axis2_http_transport_utils_parse_session_str(
        const axutil_env_t *env, 
        axis2_char_t *str, 
        axutil_hash_t *ht);
/***************************** End of function headers ************************/

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_transport_out_init(
    axis2_http_transport_out_t *response,
    const axutil_env_t *env)
{
    response->http_status_code_name = NULL;
    response->http_status_code = 0;
    response->msg_ctx = NULL;
    response->response_data = NULL;
    response->content_type = NULL;
    response->response_data_length = 0;
    response->content_language = NULL;
    response->output_headers = NULL;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_transport_out_uninit(
    axis2_http_transport_out_t *response,
    const axutil_env_t *env)
{
    if(response->msg_ctx)
    {
        axis2_msg_ctx_free(response->msg_ctx, env);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_transport_in_init(
    axis2_http_transport_in_t *request,
    const axutil_env_t *env)
{
    request->content_type = NULL;
    request->content_length = 0;
    request->msg_ctx = NULL;
    request->soap_action = NULL;
    request->request_uri = NULL;
    request->in_stream = NULL;
    request->remote_ip = NULL;
    request->svr_port = NULL;
    request->transfer_encoding = NULL;
    request->accept_header = NULL;
    request->accept_language_header = NULL;
    request->accept_charset_header = NULL;
    request->request_method = 0;
    request->out_transport_info = NULL;
    request->request_url_prefix = NULL;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_transport_in_uninit(
    axis2_http_transport_in_t *request,
    const axutil_env_t *env)
{
    if(request->msg_ctx)
    {
        axis2_msg_ctx_reset_out_transport_info(request->msg_ctx, env);
        axis2_msg_ctx_free(request->msg_ctx, env);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_process_http_post_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    const int content_length,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri)
{
    axiom_soap_envelope_t *soap_envelope = NULL;
    axiom_soap_builder_t *soap_builder = NULL;
    axiom_stax_builder_t *om_builder = NULL;
    axis2_bool_t is_soap11 = AXIS2_FALSE;
    axiom_xml_reader_t *xml_reader = NULL;
    axutil_string_t *char_set_str = NULL;

    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_callback_info_t *callback_ctx = NULL;
    axis2_callback_info_t *mime_cb_ctx = NULL;
    axutil_hash_t *headers = NULL;
    axis2_engine_t *engine = NULL;
    axiom_soap_body_t *soap_body = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    axutil_hash_t *binary_data_map = NULL;
    axis2_char_t *soap_body_str = NULL;
    axutil_stream_t *stream = NULL;
    axis2_bool_t do_rest = AXIS2_FALSE;
    axis2_bool_t run_as_get = AXIS2_FALSE;
    axis2_char_t *soap_action = NULL;
    unsigned int soap_action_len = 0;
    axutil_property_t *http_error_property = NULL;
    axiom_mime_parser_t *mime_parser = NULL;
    axis2_bool_t is_svc_callback = AXIS2_FALSE;
    axutil_property_t *is_client_property = NULL;
    axis2_bool_t is_application_client_side = AXIS2_FALSE;
    axis2_char_t *mime_boundary = NULL;
    axis2_bool_t check_for_fault = AXIS2_FALSE;
    axis2_bool_t has_fault = AXIS2_FALSE;
	axis2_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);
    xml_reader = axiom_xml_reader_create_for_io(env, axis2_http_transport_utils_on_data_request,
        NULL, (void *)callback_ctx, axutil_string_get_buffer(char_set_str, env));

    if(!xml_reader)
    {
        return AXIS2_FAILURE;
    }

    axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str);

    om_builder = axiom_stax_builder_create(env, xml_reader);
    if(!om_builder)
    {
        axiom_xml_reader_free(xml_reader, env);
        xml_reader = NULL;
        return AXIS2_FAILURE;
    }

    if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
    {
        is_soap11 = AXIS2_FALSE;
        soap_builder = axiom_soap_builder_create(env, om_builder,
            AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI);
        if(!soap_builder)
        {
            /* We should not be freeing om_builder here as it is done by
             axiom_soap_builder_create in case of error - Samisa */
            om_builder = NULL;
            xml_reader = NULL;
            axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
            return AXIS2_FAILURE;
        }

        soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
        if(!soap_envelope)
        {
            axiom_stax_builder_free(om_builder, env);
            om_builder = NULL;
            xml_reader = NULL;
            axiom_soap_builder_free(soap_builder, env);
            soap_builder = NULL;
            axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
            return AXIS2_FAILURE;
        }
    }
    else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
    {
        is_soap11 = AXIS2_TRUE;
        if(soap_action_header)
        {
            soap_builder = axiom_soap_builder_create(env, om_builder,
                AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI);
            if(!soap_builder)
            {
                /* We should not be freeing om_builder here as it is done by
                 axiom_soap_builder_create in case of error - Samisa */
                om_builder = NULL;
                xml_reader = NULL;
                axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
                return AXIS2_FAILURE;
            }
            soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
            if(!soap_envelope)
            {
                axiom_soap_builder_free(soap_builder, env);
                om_builder = NULL;
                xml_reader = NULL;
                soap_builder = NULL;
                axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
                return AXIS2_FAILURE;
            }
        }
        else
        {
            /* REST support */
            do_rest = AXIS2_TRUE;
        }
    }

    else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_X_WWW_FORM_URLENCODED))
    {
        /* REST support */
        do_rest = AXIS2_TRUE;
        run_as_get = AXIS2_TRUE;
    }
    else
    {
        http_error_property = axutil_property_create(env);
        axutil_property_set_value(http_error_property, env, AXIS2_HTTP_UNSUPPORTED_MEDIA_TYPE);
        axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_TRANSPORT_ERROR, http_error_property);
    }

    if(soap_builder)
    {
        if(mime_parser)
        {
            axiom_soap_builder_set_mime_parser(soap_builder, env, mime_parser);
            if(mime_cb_ctx)
            {
                axiom_soap_builder_set_callback_ctx(soap_builder, env, mime_cb_ctx);
                axiom_soap_builder_set_callback_function(soap_builder, env,
                    axis2_http_transport_utils_on_data_request);
            }
            else if(is_svc_callback)
            {
                return AXIS2_FAILURE;
            }
        }
    }

    if(do_rest)
    {
        /* REST support */
        axutil_param_t *rest_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ENABLE_REST);
        if(rest_param && 0 == axutil_strcmp(AXIS2_VALUE_TRUE, axutil_param_get_value(rest_param,
            env)))
        {
            axiom_soap_body_t *def_body = NULL;
            axiom_document_t *om_doc = NULL;
            axiom_node_t *root_node = NULL;
            if(!run_as_get)
            {
                soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
                def_body = axiom_soap_envelope_get_body(soap_envelope, env);
                om_doc = axiom_stax_builder_get_document(om_builder, env);
				root_node = axiom_document_get_root_element(om_doc, env);
                root_node = axiom_document_build_all(om_doc, env);
                axiom_soap_body_add_child(def_body, env, root_node);
            }
            axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
            axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_POST);
            axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
        }
        else
        {
            return AXIS2_FAILURE;
        }
        if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
        {
            return AXIS2_FAILURE;
        }
    }

    if(run_as_get)
    {
        axis2_char_t *buffer = NULL;
        axis2_char_t *new_url = NULL;
        buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (content_length + 1));
        if(!buffer)
        {
            return AXIS2_FAILURE;
        }
        axis2_http_transport_utils_on_data_request(buffer, content_length, (void *)callback_ctx);

        new_url = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * ((int)(strlen(request_uri)
            + strlen(buffer)) + 2));
        if(!new_url)
        {
            return AXIS2_FAILURE;
        }
        sprintf(new_url, "%s?%s", request_uri, buffer);
        AXIS2_FREE(env->allocator, buffer);

        soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
            axis2_http_transport_utils_get_request_params(env, new_url), AXIS2_HTTP_POST);
    }

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

    axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);

    engine = axis2_engine_create(env, conf_ctx);

    if(!soap_envelope)
        return AXIS2_FAILURE;

    soap_body = axiom_soap_envelope_get_body(soap_envelope, env);

    if(!soap_body)
        return AXIS2_FAILURE;

    if(!is_svc_callback)
    {
        is_client_property = axis2_msg_ctx_get_property(msg_ctx, env, 
                AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE);
        if(is_client_property)
        {
            axis2_char_t *prop_value = NULL;
            prop_value = axutil_property_get_value(is_client_property, env);
            if(prop_value && !axutil_strcmp(prop_value , AXIS2_VALUE_TRUE))
            {
                is_application_client_side = AXIS2_TRUE;
            }
        }
        if(mime_boundary || is_application_client_side)
        {
            check_for_fault = AXIS2_TRUE;
        }
        if(check_for_fault)
        {
            has_fault = axiom_soap_body_has_fault(soap_body, env);
        }
        if(has_fault)
        {
            status = axis2_engine_receive_fault(engine, env, msg_ctx);
        }
        else
        {
            status = axis2_engine_receive(engine, env, msg_ctx);
        }
    }
    else
    {
        status = axis2_engine_receive(engine, env, msg_ctx);
    }

    if(!axis2_msg_ctx_get_soap_envelope(msg_ctx, env) && AXIS2_FALSE == is_soap11)
    {
        axiom_soap_envelope_t *def_envelope = axiom_soap_envelope_create_default_soap_envelope(env,
            AXIOM_SOAP12);
        axis2_msg_ctx_set_soap_envelope(msg_ctx, env, def_envelope);
    }

    if(engine)
    {
        axis2_engine_free(engine, env);
    }

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

    if(stream)
    {
        axutil_stream_free(stream, env);
    }

    if(char_set_str)
    {
        axutil_string_free(char_set_str, env);
    }
    if(!soap_builder && om_builder)
    {
        axiom_stax_builder_free_self(om_builder, env);
        om_builder = NULL;
    }
    if(!axutil_string_get_buffer(soap_action_header, env) && soap_action)
    {
        AXIS2_FREE(env->allocator, soap_action);
        soap_action = NULL;
    }
    return status;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_process_http_put_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    const int content_length,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri)
{
    axiom_soap_envelope_t *soap_envelope = NULL;
    axiom_soap_builder_t *soap_builder = NULL;
    axiom_stax_builder_t *om_builder = NULL;
    axis2_bool_t is_soap11 = AXIS2_FALSE;
    axiom_xml_reader_t *xml_reader = NULL;
    axutil_string_t *char_set_str = NULL;

    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_callback_info_t *callback_ctx;
    axutil_hash_t *headers = NULL;
    axis2_engine_t *engine = NULL;
    axiom_soap_body_t *soap_body = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    axutil_hash_t *binary_data_map = NULL;
    axis2_char_t *soap_body_str = NULL;
    axutil_stream_t *stream = NULL;
    axis2_bool_t do_rest = AXIS2_FALSE;
    axis2_bool_t run_as_get = AXIS2_FALSE;
    axutil_property_t *http_error_property = NULL;
    axutil_property_t *is_client_property = NULL;
    axis2_bool_t is_application_client_side = AXIS2_FALSE;
    axis2_char_t *mime_boundary = NULL;
    axis2_bool_t check_for_fault = AXIS2_FALSE;
    axis2_bool_t has_fault = AXIS2_FALSE;

    AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FAILURE);

    conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);

    callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t));
    /* Note: the memory created above is freed in xml reader free function
     as this is passed on to the reader */
    callback_ctx->in_stream = in_stream;
    callback_ctx->env = env;
    callback_ctx->content_length = content_length;
    callback_ctx->unread_len = content_length;
    callback_ctx->chunked_stream = NULL;

    headers = axis2_msg_ctx_get_transport_headers(msg_ctx, env);
    if(headers)
    {
        axis2_http_header_t *encoding_header = NULL;
        encoding_header = (axis2_http_header_t *)axutil_hash_get(headers,
            AXIS2_HTTP_HEADER_TRANSFER_ENCODING, AXIS2_HASH_KEY_STRING);

        if(encoding_header)
        {
            axis2_char_t *encoding_value = NULL;
            encoding_value = axis2_http_header_get_value(encoding_header, env);
            if(encoding_value && 0 == axutil_strcasecmp(encoding_value,
                AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
            {
                callback_ctx->chunked_stream = axutil_http_chunked_stream_create(env, in_stream);
                if(!callback_ctx->chunked_stream)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in"
                        " creating in chunked stream.");
                    return AXIS2_FAILURE;
                }
                AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "HTTP"
                    " stream chunked");
            }
        }
    }
    else
    {
        /* check content encoding from msg ctx property */
        axis2_char_t *value = axis2_msg_ctx_get_transfer_encoding(msg_ctx, env);

        if(value && axutil_strstr(value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
        {
            /* this is an UGLY hack to get some of the transports working 
             e.g. PHP transport where it strips the chunking info in case of chunking
             and also gives out a content lenght of 0.
             We need to fix the transport design to fix sutuations like this.
             */
            callback_ctx->content_length = AXIS2_CHUNKED_CONTENT_LENGTH;
            callback_ctx->unread_len = callback_ctx->content_length;
        }
    }

    if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED))
    {
        /* get mime boundry */
        mime_boundary = axis2_http_transport_utils_get_value_from_content_type(env,
            content_type, AXIS2_HTTP_HEADER_CONTENT_TYPE_MIME_BOUNDARY);

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

            mime_parser = axiom_mime_parser_create(env);

            buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE);
            if(buffer_size_param)
            {
                value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env);
                if(value_size)
                {
                    size = atoi(value_size);
                    axiom_mime_parser_set_buffer_size(mime_parser, env, size);
                }
            }

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

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

            attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR);

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

            if(mime_parser)
            {
                /*binary_data_map = 
                 axiom_mime_parser_parse(mime_parser, env,
                 axis2_http_transport_utils_on_data_request,
                 (void *) callback_ctx,
                 mime_boundary);*/
                if(!binary_data_map)
                {
                    return AXIS2_FAILURE;
                }
                soap_body_len = (int)axiom_mime_parser_get_soap_body_len(mime_parser, env);
                soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env);
            }

            stream = axutil_stream_create_basic(env);
            if(stream)
            {
                axutil_stream_write(stream, env, soap_body_str, soap_body_len);
                callback_ctx->in_stream = stream;
                callback_ctx->chunked_stream = NULL;
                callback_ctx->content_length = soap_body_len;
                callback_ctx->unread_len = soap_body_len;
            }
            axiom_mime_parser_free(mime_parser, env);
            mime_parser = NULL;
        }
        /*AXIS2_FREE(env->allocator, mime_boundary);*/
    }

    axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));

    axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);

    char_set_str = axis2_http_transport_utils_get_charset_enc(env, content_type);
    xml_reader = axiom_xml_reader_create_for_io(env, axis2_http_transport_utils_on_data_request,
        NULL, (void *)callback_ctx, axutil_string_get_buffer(char_set_str, env));

    if(!xml_reader)
    {
        return AXIS2_FAILURE;
    }

    axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str);

    om_builder = axiom_stax_builder_create(env, xml_reader);
    if(!om_builder)
    {
        axiom_xml_reader_free(xml_reader, env);
        xml_reader = NULL;
        return AXIS2_FAILURE;
    }

    if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
    {
        is_soap11 = AXIS2_FALSE;
        soap_builder = axiom_soap_builder_create(env, om_builder,
            AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI);
        if(!soap_builder)
        {
            /* We should not be freeing om_builder here as it is done by
             axiom_soap_builder_create in case of error - Samisa */
            om_builder = NULL;
            xml_reader = NULL;
            axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
            return AXIS2_FAILURE;
        }

        soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
        if(!soap_envelope)
        {
            axiom_stax_builder_free(om_builder, env);
            om_builder = NULL;
            xml_reader = NULL;
            axiom_soap_builder_free(soap_builder, env);
            soap_builder = NULL;
            axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap11);
            return AXIS2_FAILURE;
        }
    }
    else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
    {
        do_rest = AXIS2_TRUE;
        if(soap_action_header)
        {
            return AXIS2_FAILURE;
        }
        else
        {
            /* REST support */
            do_rest = AXIS2_TRUE;
        }
    }
    else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_X_WWW_FORM_URLENCODED))
    {
        /* REST support */
        do_rest = AXIS2_TRUE;
        run_as_get = AXIS2_TRUE;
    }
    else
    {
        http_error_property = axutil_property_create(env);
        axutil_property_set_value(http_error_property, env, AXIS2_HTTP_UNSUPPORTED_MEDIA_TYPE);
        axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_TRANSPORT_ERROR, http_error_property);
    }

    if(do_rest)
    {
        /* REST support */
        axutil_param_t *rest_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ENABLE_REST);
        if(rest_param && 0 == axutil_strcmp(AXIS2_VALUE_TRUE, axutil_param_get_value(rest_param,
            env)))
        {
            axiom_soap_body_t *def_body = NULL;
            axiom_document_t *om_doc = NULL;
            axiom_node_t *root_node = NULL;
            if(!run_as_get)
            {
                soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
                def_body = axiom_soap_envelope_get_body(soap_envelope, env);
                om_doc = axiom_stax_builder_get_document(om_builder, env);
				root_node = axiom_document_get_root_element(om_doc, env);
                root_node = axiom_document_build_all(om_doc, env);
                axiom_soap_body_add_child(def_body, env, root_node);
            }
            axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
            axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_PUT);
            axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
        }
        else
        {
            return AXIS2_FAILURE;
        }
        if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
        {
            return AXIS2_FAILURE;
        }
    }

    if(run_as_get)
    {
        axis2_char_t *buffer = NULL;
        axis2_char_t *new_url = NULL;
        buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (content_length + 1));
        if(!buffer)
        {
            return AXIS2_FAILURE;
        }
        axis2_http_transport_utils_on_data_request(buffer, content_length, (void *)callback_ctx);

        new_url = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * ((int)(strlen(request_uri)
            + strlen(buffer)) + 2));
        if(!new_url)
        {
            return AXIS2_FAILURE;
        }
        sprintf(new_url, "%s?%s", request_uri, buffer);
        AXIS2_FREE(env->allocator, buffer);

        soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
            axis2_http_transport_utils_get_request_params(env, new_url), AXIS2_HTTP_POST);
    }

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

    axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);

    engine = axis2_engine_create(env, conf_ctx);

    if(!soap_envelope)
        return AXIS2_FAILURE;

    soap_body = axiom_soap_envelope_get_body(soap_envelope, env);

    if(!soap_body)
        return AXIS2_FAILURE;

    is_client_property = axis2_msg_ctx_get_property(msg_ctx, env, 
            AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE);
    if(is_client_property)
    {
        axis2_char_t *prop_value = NULL;
        prop_value = axutil_property_get_value(is_client_property, env);
        if(prop_value && !axutil_strcmp(prop_value , AXIS2_VALUE_TRUE))
        {
            is_application_client_side = AXIS2_TRUE;
        }
    }
    if(mime_boundary || is_application_client_side)
    {
        check_for_fault = AXIS2_TRUE;
    }
    if(check_for_fault)
    {
        has_fault = axiom_soap_body_has_fault(soap_body, env);
    }
    if(has_fault)
    {
        status = axis2_engine_receive_fault(engine, env, msg_ctx);
    }
    else
    {
        status = axis2_engine_receive(engine, env, msg_ctx);
    }
    if(mime_boundary)
    {
        AXIS2_FREE(env->allocator, mime_boundary);
    }
    if(!axis2_msg_ctx_get_soap_envelope(msg_ctx, env) && AXIS2_FALSE == is_soap11)
    {
        axiom_soap_envelope_t *def_envelope = axiom_soap_envelope_create_default_soap_envelope(env,
            AXIOM_SOAP12);
        axis2_msg_ctx_set_soap_envelope(msg_ctx, env, def_envelope);
    }

    if(engine)
    {
        axis2_engine_free(engine, env);
    }

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

    if(stream)
    {
        axutil_stream_free(stream, env);
    }

    if(char_set_str)
    {
        axutil_string_free(char_set_str, env);
    }
    if(!soap_builder && om_builder)
    {
        axiom_stax_builder_free_self(om_builder, env);
        om_builder = NULL;
    }
    return status;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_transport_utils_process_http_head_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri,
    axis2_conf_ctx_t * conf_ctx,
    axutil_hash_t * request_params)
{
    axiom_soap_envelope_t *soap_envelope = NULL;
    axis2_engine_t *engine = NULL;
    axis2_bool_t do_rest = AXIS2_TRUE;

    AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE);

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

    axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
    axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
    if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
    {
        if(soap_action_header)
        {
            do_rest = AXIS2_FALSE;
        }
    }
    else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
    {
        do_rest = AXIS2_FALSE;
    }

    if(do_rest)
    {
        axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
        axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_HEAD);
    }
    else
    {
        axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE);
    }
    if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
    {
        return AXIS2_FALSE;
    }

    soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
        request_params, AXIS2_HTTP_HEAD);
    if(!soap_envelope)
    {
        return AXIS2_FALSE;
    }
    axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);
    engine = axis2_engine_create(env, conf_ctx);
    axis2_engine_receive(engine, env, msg_ctx);
    return AXIS2_TRUE;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_transport_utils_process_http_get_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri,
    axis2_conf_ctx_t * conf_ctx,
    axutil_hash_t * request_params)
{
    axiom_soap_envelope_t *soap_envelope = NULL;
    axis2_engine_t *engine = NULL;
    axis2_bool_t do_rest = AXIS2_TRUE;

    AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FALSE);

    axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
    axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
    if(content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
    {
        if(soap_action_header)
        {
            do_rest = AXIS2_FALSE;
        }
    }
    else if(content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
    {
        do_rest = AXIS2_FALSE;
    }

    if(do_rest)
    {
        axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
        axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_GET);
    }
    else
    {
        axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE);
    }

    if(AXIS2_SUCCESS != axis2_http_transport_utils_dispatch_and_verify(env, msg_ctx))
    {
        return AXIS2_FALSE;
    }
    soap_envelope = axis2_http_transport_utils_handle_media_type_url_encoded(env, msg_ctx,
        request_params, AXIS2_HTTP_GET);
    if(!soap_envelope)
    {
        return AXIS2_FALSE;
    }
    axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);

    engine = axis2_engine_create(env, conf_ctx);
    axis2_engine_receive(engine, env, msg_ctx);
    return AXIS2_TRUE;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_transport_utils_process_http_delete_request(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_stream_t * in_stream,
    axutil_stream_t * out_stream,
    const axis2_char_t * content_type,
    axutil_string_t * soap_action_header,
    const axis2_char_t * request_uri,
    axis2_conf_ctx_t * conf_ctx,
    axutil_hash_t * request_params)
{
    axiom_soap_envelope_t *soap_envelope = NULL;
    axis2_engine_t *engine = NULL;
    axis2_bool_t do_rest = AXIS2_TRUE;

    AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, in_stream, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, out_stream, AXIS2_FALSE);
    AXIS2_PARAM_CHECK(env->error, request_uri, AXIS2_FALSE);

    axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
    axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
    if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
    {
        if(soap_action_header)
        {
            do_rest = AXIS2_FALSE;
        }
    }
    else if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP))
    {
        do_rest = AXIS2_FALSE;
    }

    if(do_rest)
    {
        axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
        axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_DELETE);
    }
    else
    {
        axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_FALSE);
    }

    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);
		root_node = axiom_document_get_root_element(om_doc, env);
		root_node = axiom_document_build_all(om_doc, env);
        axiom_soap_body_add_child(def_body, env, root_node);
        axiom_stax_builder_free_self(om_builder, env);
    }

    return soap_envelope;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_transport_utils_get_value_from_content_type(
    const axutil_env_t * env,
    const axis2_char_t * content_type,
    const axis2_char_t * key)
{
    axis2_char_t *tmp = NULL;
    axis2_char_t *tmp_content_type = NULL;
    axis2_char_t *tmp2 = NULL;

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

    tmp_content_type = axutil_strdup(env, content_type);
    if(!tmp_content_type)
    {
        return NULL;
    }
    tmp = strstr(tmp_content_type, key);
    if(!tmp)
    {
        AXIS2_FREE(env->allocator, tmp_content_type);
        return NULL;
    }

    tmp = strchr(tmp, AXIS2_EQ);
    tmp2 = strchr(tmp, AXIS2_SEMI_COLON);

    if(tmp2)
    {
        *tmp2 = AXIS2_ESC_NULL;
    }
    if(!tmp)
    {
        AXIS2_FREE(env->allocator, tmp_content_type);
        return NULL;
    }

    tmp2 = axutil_strdup(env, tmp + 1);

    AXIS2_FREE(env->allocator, tmp_content_type);
    if(*tmp2 == AXIS2_DOUBLE_QUOTE)
    {
        tmp = tmp2;
        tmp2 = axutil_strdup(env, tmp + 1);
        tmp2[strlen(tmp2) - 1] = AXIS2_ESC_NULL;
        if(tmp)
        {
            AXIS2_FREE(env->allocator, tmp);
            tmp = NULL;
        }

    }
    /* handle XOP */
    if(*tmp2 == AXIS2_B_SLASH && *(tmp2 + 1) == '\"')
    {
        tmp = tmp2;
        tmp2 = axutil_strdup(env, tmp + 2);
        tmp2[strlen(tmp2) - 3] = AXIS2_ESC_NULL;
        if(tmp)
        {
            AXIS2_FREE(env->allocator, tmp);
            tmp = NULL;
        }
    }
    return tmp2;
}

AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
axis2_http_transport_utils_handle_media_type_url_encoded(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axutil_hash_t * param_map,
    axis2_char_t * method)
{
    axiom_soap_envelope_t *soap_env = NULL;
    axiom_soap_body_t *soap_body = NULL;
    axiom_element_t *body_child = NULL;
    axiom_node_t *body_child_node = NULL;
    axiom_node_t *body_element_node = NULL;

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

    soap_env = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);

    if(!soap_env)
    {
        soap_env = axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
    }
    soap_body = axiom_soap_envelope_get_body(soap_env, env);
    if(!soap_body)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL, AXIS2_FAILURE);
        return NULL;
    }

    body_element_node = axiom_soap_body_get_base_node(soap_body, env);

    if(body_element_node)
    {
        body_child_node = axiom_node_get_first_child(body_element_node, env);
    }

    if(!body_child_node)
    {
        if(!axis2_msg_ctx_get_op(msg_ctx, env))
        {
            return NULL;
        }
        body_child = axiom_element_create_with_qname(env, NULL, axis2_op_get_qname(
            axis2_msg_ctx_get_op(msg_ctx, env), env), &body_child_node);
        axiom_soap_body_add_child(soap_body, env, body_child_node);
    }
    if(param_map)
    {
        axutil_hash_index_t *hi = NULL;
        for(hi = axutil_hash_first(param_map, env); hi; hi = axutil_hash_next(env, hi))
        {
            void *name = NULL;
            void *value = NULL;
            axiom_node_t *node = NULL;
            axiom_element_t *element = NULL;

            axutil_hash_this(hi, (const void **)&name, NULL, (void **)&value);
            element = axiom_element_create(env, NULL, (axis2_char_t *)name, NULL, &node);
            axiom_element_set_text(element, env, (axis2_char_t *)value, node);
            axiom_node_add_child(body_child_node, env, node);
        }
    }
    return soap_env;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_transport_utils_dispatch_and_verify(
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axis2_disp_t *rest_disp = NULL;
    axis2_handler_t *handler = NULL;

    AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);

    if(axis2_msg_ctx_get_doing_rest(msg_ctx, env))
    {
		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);
}


