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

#include "axis2_libcurl.h"
#include <axiom_soap.h>
#include <axutil_string.h>
#include <axis2_http_transport.h>
#include <axiom_output.h>
#include <axis2_op_ctx.h>
#include <axis2_ctx.h>
#include <axis2_conf_ctx.h>
#include <axis2_http_client.h>
#include <axiom_xml_writer.h>
#include <axutil_property.h>
#include <axutil_param.h>
#include <axutil_types.h>
#include <axutil_generic_obj.h>
#include <axis2_const.h>
#include <axis2_util.h>
#include <stdlib.h>
#include <axis2_http_sender.h>
#include <axis2_http_transport.h>
#include "libcurl_stream.h"

static int ref = 0;

struct axis2_libcurl
{
    axis2_char_t *memory;
    axutil_array_list_t *alist;
    unsigned int size;
    const axutil_env_t *env;
    char errorbuffer[CURL_ERROR_SIZE];
    CURL *handler;
    axis2_bool_t cookies;
};

static size_t
axis2_libcurl_write_memory_callback(
    void *ptr,
    size_t size,
    size_t nmemb,
    void *data);

static size_t
axis2_libcurl_header_callback(
    void *ptr,
    size_t size,
    size_t nmemb,
    void *data);

static axis2_char_t *
axis2_libcurl_get_content_type(
    axis2_libcurl_t *curl,
    const axutil_env_t * env);

static int
axis2_libcurl_get_content_length(
    axis2_libcurl_t *curl,
    const axutil_env_t * env);

static axis2_http_header_t *
axis2_libcurl_get_first_header(
    axis2_libcurl_t *curl,
    const axutil_env_t * env,
    const axis2_char_t * str);

static void
axis2_libcurl_free_headers(
    axis2_libcurl_t *curl,
    const axutil_env_t * env);

static axis2_status_t
axis2_libcurl_set_options(
    CURL *handler,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx);

axis2_status_t AXIS2_CALL
axis2_libcurl_send(
    axis2_libcurl_t *data,
    axiom_output_t * om_output,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    axiom_soap_envelope_t * out,
    const axis2_char_t * str_url,
    const axis2_char_t * soap_action)
{
    struct curl_slist *headers = NULL;
    axiom_soap_body_t *soap_body;
    axis2_bool_t is_soap = AXIS2_TRUE;
    axis2_bool_t send_via_get = AXIS2_FALSE;
    axis2_bool_t send_via_head = AXIS2_FALSE;
    axis2_bool_t send_via_put = AXIS2_FALSE;
    axis2_bool_t send_via_delete = AXIS2_FALSE;
    axis2_bool_t doing_mtom = AXIS2_FALSE;
    axiom_node_t *body_node = NULL;
    axiom_node_t *data_out = NULL;
    axutil_property_t *method = NULL;
    axis2_char_t *method_value = NULL;
    axiom_xml_writer_t *xml_writer = NULL;
    axis2_char_t *buffer = NULL;
    unsigned int buffer_size = 0;
    int content_length = -1;
    axis2_char_t *content_type = NULL;
    /*axis2_char_t *content_len = AXIS2_HTTP_HEADER_CONTENT_LENGTH_; */
    const axis2_char_t *char_set_enc = NULL;
    axis2_char_t *content = AXIS2_HTTP_HEADER_CONTENT_TYPE_;
    axis2_char_t *soap_action_header = AXIS2_HTTP_HEADER_SOAP_ACTION_;
    axutil_stream_t *in_stream;
    axutil_property_t *trans_in_property;
    axutil_string_t *char_set_enc_str;
    axis2_byte_t *output_stream = NULL;
    int output_stream_size = 0;
    CURL *handler;
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_conf_t *conf = NULL;
    axis2_transport_out_desc_t *trans_desc = NULL;
    axutil_param_t *write_xml_declaration_param = NULL;
    axutil_hash_t *transport_attrs = NULL;
    axis2_bool_t write_xml_declaration = AXIS2_FALSE;
    axutil_property_t *property;
    int *response_length = NULL;
    axis2_http_status_line_t *status_line = NULL;
    axis2_char_t *status_line_str = NULL;
    axis2_char_t *tmp_strcat = NULL;
    int status_code = 0;

    AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, data->handler, AXIS2_FAILURE);

    handler = data->handler;
    curl_easy_reset(handler);
    curl_easy_setopt(handler, CURLOPT_ERRORBUFFER, data->errorbuffer);
    headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_USER_AGENT_AXIS2C);
    headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_ACCEPT_);
    headers = curl_slist_append(headers, AXIS2_HTTP_HEADER_EXPECT_);

    if(AXIS2_FAILURE == axis2_libcurl_set_options(handler, env, msg_ctx))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[axis2libcurl]Setting options in Libcurl failed");
        return AXIS2_FAILURE;
    }

    if (AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env))
    {
        is_soap = AXIS2_FALSE;
    }
    else
    {
        is_soap = AXIS2_TRUE;
    }

    if (!is_soap)
    {
        soap_body = axiom_soap_envelope_get_body(out, env);
        if (!soap_body)
        {
            AXIS2_HANDLE_ERROR(env,
                AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL,
                AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }

        body_node = axiom_soap_body_get_base_node(soap_body, env);
        if (!body_node)
        {
            AXIS2_HANDLE_ERROR(env,
                AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL,
                AXIS2_FAILURE);

            return AXIS2_FAILURE;
        }
        data_out = axiom_node_get_first_element(body_node, env);

        method = (axutil_property_t *) axis2_msg_ctx_get_property(msg_ctx, env,
            AXIS2_HTTP_METHOD);

        if (method)
        {
            method_value =
            (axis2_char_t *) axutil_property_get_value(method, env);
        }

        /* The default is POST */
        if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_GET))
        {
            send_via_get = AXIS2_TRUE;
        }
        else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_HEAD))
        {
            send_via_head = AXIS2_TRUE;
        }
        else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_PUT))
        {
            send_via_put = AXIS2_TRUE;
        }
        else if (method_value && 0 == axutil_strcmp(method_value, AXIS2_HTTP_DELETE))
        {
            send_via_delete = AXIS2_TRUE;
        }
    }

    conf_ctx = axis2_msg_ctx_get_conf_ctx (msg_ctx, env);
    if (conf_ctx)
    {
        conf = axis2_conf_ctx_get_conf (conf_ctx, env);
    }

    if (conf)
    {
        trans_desc = axis2_conf_get_transport_out (conf,
            env, AXIS2_TRANSPORT_ENUM_HTTP);
    }

    if (trans_desc)
    {
        write_xml_declaration_param =
        axutil_param_container_get_param
        (axis2_transport_out_desc_param_container (trans_desc, env), env,
            AXIS2_XML_DECLARATION);
    }

    if (write_xml_declaration_param)
    {
        transport_attrs =
        axutil_param_get_attributes (write_xml_declaration_param, env);
        if (transport_attrs)
        {
            axutil_generic_obj_t *obj = NULL;
            axiom_attribute_t *write_xml_declaration_attr = NULL;
            axis2_char_t *write_xml_declaration_attr_value = NULL;

            obj = axutil_hash_get (transport_attrs, AXIS2_ADD_XML_DECLARATION,
                AXIS2_HASH_KEY_STRING);
            if (obj)
            {
                write_xml_declaration_attr = (axiom_attribute_t *)
                axutil_generic_obj_get_value (obj,
                    env);
            }
            if (write_xml_declaration_attr)
            {
                write_xml_declaration_attr_value =
                axiom_attribute_get_value (write_xml_declaration_attr, env);
            }
            if (write_xml_declaration_attr_value &&
                0 == axutil_strcasecmp (write_xml_declaration_attr_value,
                    AXIS2_VALUE_TRUE))
            {
                write_xml_declaration = AXIS2_TRUE;
            }
        }
    }

    if (write_xml_declaration)
    {
        axiom_output_write_xml_version_encoding (om_output, env);
    }

    if (!send_via_get && !send_via_head && !send_via_delete)
    {
        xml_writer = axiom_output_get_xml_writer(om_output, env);

        char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env);

        if (!char_set_enc_str)
        {
            char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING;
        }
        else
        {
            char_set_enc = axutil_string_get_buffer(char_set_enc_str, env);
        }

        if (!send_via_put && is_soap)
        {
            doing_mtom = axis2_msg_ctx_get_doing_mtom(msg_ctx, env);

            axiom_output_set_do_optimize(om_output, env, doing_mtom);
            axiom_soap_envelope_serialize(out, env, om_output, AXIS2_FALSE);
            if (AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
            {
                if (AXIS2_ESC_DOUBLE_QUOTE != *soap_action)
                {
                    axis2_char_t *tmp_soap_action = NULL;
                    tmp_soap_action =
                    AXIS2_MALLOC(env->allocator,
                        (axutil_strlen(soap_action) +
                            5) * sizeof(axis2_char_t));
                    sprintf(tmp_soap_action, "\"%s\"", soap_action);
                    tmp_strcat = axutil_stracat(env, soap_action_header,tmp_soap_action);
                    headers = curl_slist_append(headers, tmp_strcat);
                    AXIS2_FREE(env->allocator, tmp_strcat);
                    AXIS2_FREE(env->allocator, tmp_soap_action);
                }
                else
                {
                    tmp_strcat = axutil_stracat(env, soap_action_header, soap_action);
                    headers = curl_slist_append(headers, tmp_strcat );
                    AXIS2_FREE(env->allocator, tmp_strcat);
                }
            }

            if (doing_mtom)
            {
                /*axiom_output_flush(om_output, env, &output_stream,
                 &output_stream_size);*/
                axiom_output_flush(om_output, env);
                content_type =
                (axis2_char_t *) axiom_output_get_content_type(om_output,
                    env);
                if (AXIS2_TRUE != axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
                {
                    if (axutil_strcmp(soap_action, ""))
                    {
                        /* handle SOAP action for SOAP 1.2 case */
                        axis2_char_t *temp_content_type = NULL;
                        temp_content_type = axutil_stracat (env,
                            content_type,
                            AXIS2_CONTENT_TYPE_ACTION);
                        content_type = temp_content_type;
                        temp_content_type = axutil_stracat (env,
                            content_type,
                            soap_action);
                        AXIS2_FREE (env->allocator, content_type);
                        content_type = temp_content_type;
                        temp_content_type =
                        axutil_stracat (env, content_type,
                            AXIS2_ESC_DOUBLE_QUOTE_STR);
                        AXIS2_FREE (env->allocator, content_type);
                        content_type = temp_content_type;
                    }
                }
            }
            else if (AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
            {
                axis2_char_t *temp_content_type = NULL;
                content_type =
                (axis2_char_t *) AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
                content_type = axutil_stracat(env, content_type,
                    AXIS2_CONTENT_TYPE_CHARSET);
                temp_content_type =
                axutil_stracat(env, content_type, char_set_enc);
                AXIS2_FREE(env->allocator, content_type);
                content_type = temp_content_type;
            }
            else
            {
                axis2_char_t *temp_content_type = NULL;
                content_type =
                (axis2_char_t *) AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP;
                content_type = axutil_stracat(env, content_type,
                    AXIS2_CONTENT_TYPE_CHARSET);
                temp_content_type =
                axutil_stracat(env, content_type, char_set_enc);
                AXIS2_FREE(env->allocator, content_type);
                content_type = temp_content_type;
                if (axutil_strcmp(soap_action, ""))
                {
                    temp_content_type =
                    axutil_stracat(env, content_type,
                        AXIS2_CONTENT_TYPE_ACTION);
                    AXIS2_FREE(env->allocator, content_type);
                    content_type = temp_content_type;
                    temp_content_type =
                    axutil_stracat(env, content_type, soap_action);
                    AXIS2_FREE(env->allocator, content_type);
                    content_type = temp_content_type;
                }
                temp_content_type = axutil_stracat(env, content_type,
                    AXIS2_SEMI_COLON_STR);
                AXIS2_FREE(env->allocator, content_type);
                content_type = temp_content_type;
            }
        }
        else if (is_soap)
        {
            AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI, "Attempt to send SOAP"
                "message using HTTP PUT failed");
            return AXIS2_FAILURE;
        }
        else
        {
            axutil_property_t *content_type_property = NULL;
            axutil_hash_t *content_type_hash = NULL;
            axis2_char_t *content_type_value = NULL;

            axiom_node_serialize(data_out, env, om_output);
            content_type_property =
            (axutil_property_t *)
            axis2_msg_ctx_get_property(msg_ctx, env,
                AXIS2_USER_DEFINED_HTTP_HEADER_CONTENT_TYPE);

            if (content_type_property)
            {
                content_type_hash =
                (axutil_hash_t *)
                axutil_property_get_value(content_type_property, env);

                if (content_type_hash)
                {
                    content_type_value =
                    (char *) axutil_hash_get(content_type_hash,
                        AXIS2_HTTP_HEADER_CONTENT_TYPE,
                        AXIS2_HASH_KEY_STRING);
                }
            }

            if (content_type_value)
            {
                content_type = content_type_value;
            }
            else
            {
                content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML;
            }

        }

        buffer = axiom_xml_writer_get_xml(xml_writer, env);
        if (!doing_mtom)
        {
            buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env);
        }
        else
        buffer_size = output_stream_size;
        {
            /*
             * Curl calculates the content-length automatically.
             * This commented section is not only unnecessary,
             * it interferes with authentication.
             *
             * NTLM, for example, will send an empty request
             * first (no body) to get the auth challenge
             * before resending with actual content.
             */
            /*char tmp_buf[10];
            sprintf(tmp_buf, "%d", buffer_size);
            tmp_strcat = axutil_stracat(env, content_len, tmp_buf);
            headers = curl_slist_append(headers, tmp_strcat);
            AXIS2_FREE(env->allocator, tmp_strcat);
            tmp_strcat = NULL;*/

            tmp_strcat = axutil_stracat(env, content, content_type);
            headers = curl_slist_append(headers, tmp_strcat);
            AXIS2_FREE(env->allocator, tmp_strcat);
            tmp_strcat = NULL;
        }

        if (!doing_mtom)
        {
            curl_easy_setopt(handler, CURLOPT_POSTFIELDSIZE, buffer_size);
            curl_easy_setopt(handler, CURLOPT_POSTFIELDS, buffer);
        }
        else
        {
            curl_easy_setopt(handler, CURLOPT_POSTFIELDSIZE,
                output_stream_size);
            curl_easy_setopt(handler, CURLOPT_POSTFIELDS, output_stream);
        }

        if (send_via_put)
        {
            curl_easy_setopt(handler, CURLOPT_CUSTOMREQUEST, AXIS2_HTTP_PUT);
        }
        curl_easy_setopt(handler, CURLOPT_URL, str_url);
    }
    else
    {
        axis2_char_t *request_param;
        axis2_char_t *url_encode;
        request_param =
        (axis2_char_t *) axis2_http_sender_get_param_string(NULL, env,
            msg_ctx);
        url_encode = axutil_strcat(env, str_url, AXIS2_Q_MARK_STR,
            request_param, NULL);
        if (send_via_get)
        {
            curl_easy_setopt(handler, CURLOPT_HTTPGET, 1);
        }
        else if (send_via_head)
        {
            curl_easy_setopt(handler, CURLOPT_NOBODY, 1);
        }
        else if (send_via_delete)
        {
            curl_easy_setopt(handler, CURLOPT_CUSTOMREQUEST, AXIS2_HTTP_DELETE);
        }
        curl_easy_setopt(handler, CURLOPT_URL, url_encode);
    }

    {
        axis2_bool_t manage_session;
        manage_session = axis2_msg_ctx_get_manage_session(msg_ctx, env);
        if (manage_session == AXIS2_TRUE)
        {
            if (data->cookies == AXIS2_FALSE)
            {
                /* Ensure cookies enabled to manage session */
                /* Pass empty cookie string to enable cookies */
                curl_easy_setopt(handler, CURLOPT_COOKIEFILE, " ");
                data->cookies = AXIS2_TRUE;
            }
        }
        else if (data->cookies == AXIS2_TRUE)
        {
            /* Pass special string ALL to reset cookies if any have been enabled. */
            /* If cookies have ever been enabled, we reset every time as long as 
             manage_session is false, as there is no clear curl option to
             turn off the cookie engine once enabled. */
            curl_easy_setopt(handler, CURLOPT_COOKIELIST, AXIS2_ALL);
        }
    }

    curl_easy_setopt(handler, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(handler, CURLOPT_WRITEFUNCTION,
        axis2_libcurl_write_memory_callback);
    curl_easy_setopt(handler, CURLOPT_WRITEDATA, data);

    curl_easy_setopt (handler, CURLOPT_HEADERFUNCTION, axis2_libcurl_header_callback);

    curl_easy_setopt (handler, CURLOPT_WRITEHEADER, data);

    /* Free response data from previous request */
    if( data->size )
    {
        if (data->memory)
        {
            AXIS2_FREE(data->env->allocator, data->memory);
        }
        data->size = 0;
    }

    if (curl_easy_perform(handler))
    {
        AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI, "%s", &data->errorbuffer);
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR,
            AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    in_stream = axutil_stream_create_libcurl(env, data->memory, data->size);
    trans_in_property = axutil_property_create(env);
    axutil_property_set_scope(trans_in_property, env, AXIS2_SCOPE_REQUEST);
    axutil_property_set_free_func(trans_in_property, env,
        libcurl_stream_free);
    axutil_property_set_value(trans_in_property, env, in_stream);
    axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN,
        trans_in_property);

    if (axutil_array_list_size(data->alist, env) > 0)
    {
        status_line_str = axutil_array_list_get(data->alist, env, 0);
        if (status_line_str)
        {
            status_line = axis2_http_status_line_create(env, status_line_str);
        }
    }

    if (status_line)
    {
        status_code = axis2_http_status_line_get_status_code(status_line, env);
    }

    axis2_msg_ctx_set_status_code (msg_ctx, env, status_code);
    AXIS2_FREE(data->env->allocator, content_type);
    content_type = axis2_libcurl_get_content_type(data, env);

    if (content_type)
    {
        if (strstr (content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED)
            && strstr (content_type, AXIS2_HTTP_HEADER_ACCEPT_XOP_XML))
        {
            axis2_ctx_t *axis_ctx =
            axis2_op_ctx_get_base (axis2_msg_ctx_get_op_ctx (msg_ctx, env),
                env);
            property = axutil_property_create (env);
            axutil_property_set_scope (property, env, AXIS2_SCOPE_REQUEST);
            axutil_property_set_value (property,
                env, axutil_strdup (env, content_type));
            axis2_ctx_set_property (axis_ctx,
                env, MTOM_RECIVED_CONTENT_TYPE, property);
        }
    }

    content_length = axis2_libcurl_get_content_length(data, env);
    if (content_length >= 0)
    {
        response_length = AXIS2_MALLOC (env->allocator, sizeof (int));
        memcpy (response_length, &content_length, sizeof (int));
        property = axutil_property_create (env);
        axutil_property_set_scope (property, env, AXIS2_SCOPE_REQUEST);
        axutil_property_set_value (property, env, response_length);
        axis2_msg_ctx_set_property (msg_ctx, env,
            AXIS2_HTTP_HEADER_CONTENT_LENGTH, property);
    }

    curl_slist_free_all (headers);
    /* release the read http headers. */
    /* (commenting out the call below is a clever way to force a premature EOF 
     condition in subsequent messages, as they will be read using the content-length
     of the first message.) */
    axis2_libcurl_free_headers(data, env);
    AXIS2_FREE(data->env->allocator, content_type);
    axis2_http_status_line_free( status_line, env);

    return AXIS2_SUCCESS;
}

static size_t
axis2_libcurl_write_memory_callback(
    void *ptr,
    size_t size,
    size_t nmemb,
    void *data)
{
    size_t realsize = size * nmemb;
    axis2_libcurl_t *curl = (axis2_libcurl_t *) data;
    axis2_char_t *buffer =
    (axis2_char_t *) AXIS2_MALLOC(curl->env->allocator,
        curl->size + realsize + 1);
    if (buffer)
    {
        if (curl->size)
        {
            memcpy(&(buffer[0]), curl->memory, curl->size);
            AXIS2_FREE(curl->env->allocator, curl->memory);
        }

        memcpy(&(buffer[curl->size]), ptr, realsize);
        curl->size += (int)realsize;
        /* We are sure that the difference lies within the int range */
        buffer[curl->size] = 0;
        curl->memory = buffer;
    }
    return realsize;
}

static size_t
axis2_libcurl_header_callback(
    void *ptr,
    size_t size,
    size_t nmemb,
    void *data)
{
    axis2_char_t *memory;
    size_t realsize = size * nmemb;
    axis2_libcurl_t *curl = (axis2_libcurl_t *) data;
    memory = (axis2_char_t *)AXIS2_MALLOC(curl->env->allocator, realsize + 1);
    if (memory)
    {
        memcpy(&(memory[0]), ptr, realsize);
        memory[realsize] = 0;
        axutil_array_list_add(curl->alist, curl->env, memory);
    }
    return realsize;
}

axis2_libcurl_t * AXIS2_CALL
axis2_libcurl_create(
    const axutil_env_t * env)
{
    axis2_libcurl_t *curl = NULL;
    CURLcode code;

    if (!ref)
    {
        /* curl_global_init is not thread-safe so it would be better
         to do this, as well as the test and increment of ref, under
         mutex if one is available, or as part of an
         axis2_initialize() if a global initialize is created.
         Otherwise the client application should perform the the
         curl_global_init itself in a thread-safe fashion.
         */
        code = curl_global_init(CURL_GLOBAL_ALL);
        if (code)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "libcurl curl_global_init failed, error: %d", code);
            return NULL;
        }
        ref++;
    }

    curl =
    (axis2_libcurl_t *) AXIS2_MALLOC(env->allocator,
        sizeof(axis2_libcurl_t));
    if (curl)
    {
        curl->memory = 0;
        curl->size = 0;
        curl->alist = axutil_array_list_create(env, 15);
        curl->env = env;
        curl->handler = curl_easy_init();
        curl->cookies = AXIS2_FALSE;
        if ((!curl->alist) || (!curl->handler))
        {
            axis2_libcurl_free(curl, env);
            curl = 0;
        }
    }
    return curl;
}

void AXIS2_CALL
axis2_libcurl_free(
    axis2_libcurl_t *curl,
    const axutil_env_t * env)
{
    if (!curl)
    {
        return;
    }

    if (curl->handler)
    {
        curl_easy_cleanup (curl->handler);
    }
    if (curl->alist)
    {
        axis2_libcurl_free_headers(curl, env);
        axutil_array_list_free(curl->alist, env);
        curl->alist = NULL;
    }
    if (curl->memory)
    {
        AXIS2_FREE(env->allocator, curl->memory);
    }

    AXIS2_FREE(env->allocator, curl);
}

static void
axis2_libcurl_free_headers(
    axis2_libcurl_t *curl,
    const axutil_env_t * env)
{
    int count = 0;
    axutil_array_list_t *header_group = curl->alist;
    if (header_group)
    {
        while ((count = axutil_array_list_size(header_group, env)) > 0)
        {
            axis2_char_t *header = axutil_array_list_remove(header_group, env, count-1);
            AXIS2_FREE(env->allocator, header);
        }
    }
}

static axis2_http_header_t *
axis2_libcurl_get_first_header(
    axis2_libcurl_t *curl,
    const axutil_env_t * env,
    const axis2_char_t * str)
{
    axis2_http_header_t *tmp_header = NULL;
    axis2_char_t *tmp_header_str = NULL;
    axis2_char_t *tmp_name = NULL;
    int i = 0;
    int count = 0;
    axutil_array_list_t *header_group = NULL;

    AXIS2_PARAM_CHECK(env->error, curl, NULL);
    AXIS2_PARAM_CHECK(env->error, str, NULL);

    header_group = curl->alist;
    if (!header_group)
    {
        return NULL;
    }

    if (0 == axutil_array_list_size(header_group, env))
    {
        return NULL;
    }

    count = axutil_array_list_size(header_group, env);

    for (i = 0; i < count; i++)
    {
        tmp_header_str = (axis2_char_t *) axutil_array_list_get(header_group,
            env, i);
        if(!tmp_header_str)
        {
            continue;
        }
        tmp_header = (axis2_http_header_t *) axis2_http_header_create_by_str(env, tmp_header_str);
        if(!tmp_header)
        {
            continue;
        }

        tmp_name = axis2_http_header_get_name(tmp_header, env);
        if (0 == axutil_strcasecmp(str, tmp_name))
        {
            return tmp_header;
        }
        else
        {
            axis2_http_header_free( tmp_header, env );
        }

    }
    return NULL;
}

static int
axis2_libcurl_get_content_length(
    axis2_libcurl_t *curl,
    const axutil_env_t * env)
{
    axis2_http_header_t *tmp_header;
    int rtn_value = -1;

    tmp_header = axis2_libcurl_get_first_header
    (curl, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH);
    if (tmp_header)
    {
        rtn_value = AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env));
        axis2_http_header_free( tmp_header, env );
    }
    return rtn_value;
}

static axis2_char_t *
axis2_libcurl_get_content_type(
    axis2_libcurl_t *curl,
    const axutil_env_t * env)
{
    axis2_http_header_t *tmp_header;
    axis2_char_t *rtn_value = NULL;

    tmp_header = axis2_libcurl_get_first_header
    (curl, env, AXIS2_HTTP_HEADER_CONTENT_TYPE);
    if (tmp_header)
    {
        rtn_value = axutil_strdup (env, axis2_http_header_get_value(tmp_header, env) );
        axis2_http_header_free( tmp_header, env );
    }
    else
    {
        rtn_value = axutil_strdup (env, AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN);
    }

    return rtn_value;
}

/**
 * axis2_libcurl_set_auth_options maps authentication AXIS2/C options to
 * libcURL options.
 *
 * CURLOPT_USERPWD - char * user:password for authentication
 * CURLOPT_HTTPAUTH - long bitmask which authentication methods to use
 */
static axis2_status_t
axis2_libcurl_set_auth_options(
    CURL *handler,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axutil_property_t *property = NULL;
    axis2_char_t *uname = NULL;
    axis2_char_t *passwd = NULL;
    axis2_char_t *auth_type = NULL;

    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME);
    if (property)
    {
        uname = (axis2_char_t *) axutil_property_get_value(property, env);
    }
    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD);
    if (property)
    {
        passwd = (axis2_char_t *) axutil_property_get_value(property, env);
    }
    if (uname && passwd)
    {
        axis2_char_t buffer[256];
        strncpy(buffer, uname, 256);
        strncat(buffer, ":", 256);
        strncat(buffer, passwd, 256);
        curl_easy_setopt(handler, CURLOPT_USERPWD, buffer);
    }

    property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE);

    if (property)
    {
        auth_type = (axis2_char_t *) axutil_property_get_value(property, env);
    }

    if (auth_type && 0 == axutil_strcmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC))
    {
        curl_easy_setopt(handler, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    }
    else
    {
        /* Uses anonymous connection.*/
    }

    return AXIS2_SUCCESS;
}

/**
 * axis2_libcurl_set_proxy_options maps proxy AXIS2/C options to
 * libcURL options.
 *
 * CURLOPT_PROXY - char * proxy hostname
 * CURLOPT_PROXYPORT - long proxy listen port
 * CURLOPT_PROXYUSERPWD - char * user:password to authenticate to proxy
 *
 * TODO:
 * CURLOPT_PROXYTYPE - long enum type of proxy (HTTP, SOCKS)
 * CURLOPT_PROXYAUTH - long bitmask which authentication methods to use for proxy
 */
static axis2_status_t
axis2_libcurl_set_proxy_options(
    CURL *handler,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_conf_t *conf = NULL;
    axis2_transport_out_desc_t *trans_desc = NULL;
    axutil_param_t *proxy_param = NULL;
    axutil_hash_t *transport_attrs = NULL;
    axutil_property_t *property = NULL;
    axis2_char_t *uname = NULL;
    axis2_char_t *passwd = NULL;
    axis2_char_t *proxy_host = NULL;
    axis2_char_t *proxy_port = NULL;

    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME);
    if (property)
    {
        uname = (axis2_char_t *) axutil_property_get_value(property, env);
    }
    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD);
    if (property)
    {
        passwd = (axis2_char_t *) axutil_property_get_value(property, env);
    }

    conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
    if (conf_ctx)
    {
        conf = axis2_conf_ctx_get_conf(conf_ctx, env);
        if (conf)
        {
            trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
        }
    }
    if (trans_desc)
    {
        proxy_param = axutil_param_container_get_param(
            axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_HTTP_PROXY_API);
        if (!proxy_param)
        {
            proxy_param = axutil_param_container_get_param(
                axis2_transport_out_desc_param_container(trans_desc, env), env, AXIS2_HTTP_PROXY);
        }
        if (proxy_param)
        {
            transport_attrs = axutil_param_get_attributes(proxy_param, env);
        }
    }

    if (transport_attrs)
    {
        axutil_generic_obj_t *obj = NULL;
        axiom_attribute_t *attr = NULL;

        if (!uname || !passwd)
        {
            obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME, AXIS2_HASH_KEY_STRING);
            if (obj)
            {
                attr = (axiom_attribute_t *) axutil_generic_obj_get_value(obj, env);
            }
            if (attr)
            {
                uname = axiom_attribute_get_value(attr, env);
            }

            attr = NULL;
            obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD, AXIS2_HASH_KEY_STRING);
            if (obj)
            {
                attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
            }
            if (attr)
            {
                passwd = axiom_attribute_get_value(attr, env);
            }
        }

        obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING);
        if (obj)
        {
            attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
        }
        if (attr)
        {
            proxy_host = axiom_attribute_get_value(attr, env);
        }
        if (proxy_host)
        {
            curl_easy_setopt(handler, CURLOPT_PROXY, proxy_host);
        }

        attr = NULL;
        obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING);
        if (obj)
        {
            attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
        }
        if (attr)
        {
            proxy_port = axiom_attribute_get_value(attr, env);
        }
        if (proxy_port)
        {
            curl_easy_setopt(handler, CURLOPT_PROXYPORT, AXIS2_ATOI(proxy_port));
        }
    }
    if (uname && passwd)
    {
        axis2_char_t buffer[256];
        strncpy(buffer, uname, 256);
        strncat(buffer, ":", 256);
        strncat(buffer, passwd, 256);
        curl_easy_setopt(handler, CURLOPT_PROXYUSERPWD, buffer);
    }

    return AXIS2_SUCCESS;
}

/**
 * axis2_libcurl_set_ssl_options maps SSL AXIS2/C options to
 * libcURL options.
 *
 * CURLOPT_SSL_VERIFYHOST - long enum whether to verify the server identity
 * CURLOPT_SSL_VERIFYPEER - long boolean whether to verify the server certificate
 */
static axis2_status_t
axis2_libcurl_set_ssl_options(
    CURL *handler,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axutil_property_t *property = NULL;
    axis2_char_t *verify_peer = NULL;
    axis2_char_t *verify_host = NULL;

    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_VERIFY_PEER);
    if (property)
    {
        verify_peer = (axis2_char_t *)axutil_property_get_value(property, env);
    }
    if (verify_peer)
    {
        if (0 == axutil_strcasecmp(verify_peer, AXIS2_VALUE_TRUE))
        {
            curl_easy_setopt(handler, CURLOPT_SSL_VERIFYPEER, 1);
        }
        else
        {
            curl_easy_setopt(handler, CURLOPT_SSL_VERIFYPEER, 0);
        }
    }

    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_VERIFY_HOST);
    if (property)
    {
        verify_host = (axis2_char_t *)axutil_property_get_value(property, env);
    }
    if (verify_host)
    {
        curl_easy_setopt(handler, CURLOPT_SSL_VERIFYHOST, AXIS2_ATOI(verify_host));
    }

    return AXIS2_SUCCESS;
}

/**
 * axis2_libcurl_set_connection_options maps connection AXIS2/C options to
 * libcURL options.
 * CURLOPT_CONNECTTIMEOUT_MS - long connection timeout in milliseconds
 * CURLOPT_TIMEOUT_MS - long transfer timeout in milliseconds
 */
static axis2_status_t
axis2_libcurl_set_connection_options(
    CURL *handler,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axutil_property_t *property = NULL;
    long long_property_value = 0;

    /* check if timeout has been set by user using options
     * with axis2_options_set_timeout_in_milli_seconds
     */
    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_CONNECTION_TIMEOUT);
    if (property)
    {
        axis2_char_t *value = axutil_property_get_value(property, env);
        if (value)
        {
            long_property_value = AXIS2_ATOI(value);
            curl_easy_setopt(handler, CURLOPT_CONNECTTIMEOUT_MS, long_property_value);
        }
    }

    property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_SO_TIMEOUT);
    if (property)
    {
        axis2_char_t *value = axutil_property_get_value(property, env);
        if (value)
        {
            long_property_value = AXIS2_ATOI(value);
            curl_easy_setopt(handler, CURLOPT_TIMEOUT_MS, long_property_value);
        }
    }

    return AXIS2_SUCCESS;
}

/**
 * axis2_libcurl_set_options maps the AXIS2/C options to libcURL options.
 */
static axis2_status_t
axis2_libcurl_set_options(
    CURL *handler,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    if (axis2_libcurl_set_auth_options(handler, env, msg_ctx) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    if (axis2_libcurl_set_proxy_options(handler, env, msg_ctx) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    if (axis2_libcurl_set_ssl_options(handler, env, msg_ctx) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    if (axis2_libcurl_set_connection_options(handler, env, msg_ctx) != AXIS2_SUCCESS)
    {
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}


#endif                          /* AXIS2_LIBCURL_ENABLED */

