/*
 * 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 = axutil_strdup(env,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 */

