/*
 * 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_client.h>
#include <axis2_http_transport.h>
#include <axutil_stream.h>
#include <axutil_string.h>
#include <axutil_network_handler.h>
#include <axis2_http_request_line.h>
#include <axis2_http_header.h>
#include <axis2_http_status_line.h>
#include <axutil_http_chunked_stream.h>
#include <platforms/axutil_platform_auto_sense.h>
#include <axiom_mime_part.h>
#include <axis2_http_transport_utils.h>

#ifdef AXIS2_SSL_ENABLED
#include "ssl/ssl_stream.h"
#endif

#define AXIS2_HTTP_HEADER_LENGTH 4096
#define AXIS2_HTTP_STATUS_LINE_LENGTH 512

struct axis2_http_client
{
    int sockfd;
    axutil_stream_t *data_stream;
    axutil_url_t *url;
    axis2_http_simple_response_t *response;
    axis2_bool_t request_sent;
    int timeout;
    axis2_bool_t proxy_enabled;
    axis2_char_t *proxy_host;
    int proxy_port;
    axis2_char_t *proxy_host_port;
    axis2_bool_t dump_input_msg;
    axis2_char_t *server_cert;
    axis2_char_t *key_file;
    axis2_char_t *req_body;
    int req_body_size;

    /* These are for mtom case */
    axutil_array_list_t *mime_parts;
    axis2_bool_t doing_mtom;
    axis2_char_t *mtom_sending_callback_name;
};

AXIS2_EXTERN axis2_http_client_t *AXIS2_CALL
axis2_http_client_create(
    const axutil_env_t * env,
    axutil_url_t * url)
{
    axis2_http_client_t *http_client = NULL;

    http_client = (axis2_http_client_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_client_t));

    if(!http_client)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    memset(http_client, 0, sizeof(axis2_http_client_t));

    http_client->url = url;
    http_client->data_stream = NULL;
    http_client->sockfd = -1;
    http_client->response = NULL;
    http_client->request_sent = AXIS2_FALSE;

    /* default timeout is 60000 milliseconds */
    http_client->timeout = AXIS2_HTTP_DEFAULT_CONNECTION_TIMEOUT;
    http_client->proxy_enabled = AXIS2_FALSE;
    http_client->proxy_port = 0;
    http_client->proxy_host = NULL;
    http_client->proxy_host_port = NULL;
    http_client->dump_input_msg = AXIS2_FALSE;
    http_client->server_cert = NULL;
    http_client->key_file = NULL;
    http_client->req_body = NULL;
    http_client->req_body_size = 0;
    http_client->mime_parts = NULL;
    http_client->doing_mtom = AXIS2_FALSE;
    http_client->mtom_sending_callback_name = NULL;

    return http_client;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_http_client_free(
    axis2_http_client_t * http_client,
    const axutil_env_t * env)
{
    if(http_client->proxy_host)
    {
        AXIS2_FREE(env->allocator, http_client->proxy_host);
    }
    if(http_client->proxy_host_port)
    {
        AXIS2_FREE(env->allocator, http_client->proxy_host_port);
    }
    if(http_client->url)
    {
        axutil_url_free(http_client->url, env);
    }
    if(http_client->response)
    {
        axis2_http_simple_response_free(http_client->response, env);
    }
    if(-1 != http_client->sockfd)
    {
        axutil_stream_free(http_client->data_stream, env);
        http_client->data_stream = NULL;
		axutil_network_handler_close_socket(env, http_client->sockfd);
        http_client->sockfd = -1;
    }

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

    /* There is no other appropriate place to free the mime_part list when a 
     * particular client send requests. */

    if(http_client->mime_parts)
    {
        int i = 0;
        for(i = 0; i < axutil_array_list_size(http_client->mime_parts, env); i++)
        {
            axiom_mime_part_t *mime_part = NULL;
            mime_part = (axiom_mime_part_t *)axutil_array_list_get(http_client->mime_parts, env, i);
            if(mime_part)
            {
                axiom_mime_part_free(mime_part, env);
            }
        }
        axutil_array_list_free(http_client->mime_parts, env);
    }

    AXIS2_FREE(env->allocator, http_client);
    return;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_http_client_free_void_arg(
    void *client,
    const axutil_env_t * env)
{
    axis2_http_client_t *client_l = NULL;

    client_l = (axis2_http_client_t *)client;
    axis2_http_client_free(client_l, env);
    return;
}

/* This is the main method which writes to the socket in the case of a client 
 * sends an http_request. Previously this method does not distinguish between a 
 * mtom request and non mtom request. Because what finally it had was the 
 * complete buffer with the request. But now MTOM invocations are done 
 * differently in order to support large attachments so this method should 
 * distinguish those invocations */

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_send(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axis2_http_simple_request_t * request,
    axis2_char_t * ssl_pp)
{
    char *wire_format = NULL;
    axutil_array_list_t *headers = NULL;
    char *str_header = NULL;
    char *str_request_line = NULL;
    int written = 0;
    axis2_status_t status = AXIS2_FAILURE;
    axis2_bool_t chunking_enabled = AXIS2_FALSE;
    axis2_char_t *host = NULL;
    unsigned int port = 0;

    /* In the MTOM case request body is not set. Instead mime_parts
     array_list is there */

    /*if(client->req_body)
    {
        AXIS2_FREE(env->allocator, client->req_body);
        client->req_body = NULL;
    }*/
    if(!client->req_body && !(client->doing_mtom))
    {
        client->req_body_size = axis2_http_simple_request_get_body_bytes(request, env,
            &client->req_body);
    }

    if(client->dump_input_msg == AXIS2_TRUE)
    {
        return AXIS2_SUCCESS;
    }

    if(!client->url)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_URL, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Request url not set");
        return AXIS2_FAILURE;
    }

    host = axutil_url_get_host(client->url, env);
    port = axutil_url_get_port(client->url, env);

    if(client->proxy_enabled)
    {
        if(!client->proxy_host || client->proxy_port <= 0)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy port or Host not set");
            return AXIS2_FAILURE;
        }

        if(client->sockfd < 0)
        {
            client->sockfd = (int)axutil_network_handler_open_socket(env, client->proxy_host,
                client->proxy_port);
        }
    }
    else
    {
        /*Proxy is not enabled*/

        if(client->sockfd < 0)
        {
            client->sockfd = (int)axutil_network_handler_open_socket(env, host, port);
        }
    }

    if(client->sockfd < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Socket Creation failed.");
        return AXIS2_FAILURE;
    }

    if(client->timeout > 0)
    {
        /*Set the receiving time out*/
        axutil_network_handler_set_sock_option(env, client->sockfd, SO_RCVTIMEO, client->timeout);
        /*Set the sending time out*/

        axutil_network_handler_set_sock_option(env, client->sockfd, SO_SNDTIMEO, client->timeout);
    }

    if(0 == axutil_strcasecmp(axutil_url_get_protocol(client->url, env), AXIS2_TRANSPORT_URL_HTTPS))
    {
#ifdef AXIS2_SSL_ENABLED
        if (client->proxy_enabled)
        {
            if (AXIS2_SUCCESS != axis2_http_client_connect_ssl_host(client, env, host, port))
            {
                axutil_network_handler_close_socket(env, client->sockfd);
                client->sockfd = -1;
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTPS connection creation failed");
                return AXIS2_FAILURE;
            }
        }
		if(!client->data_stream)
			client->data_stream =
			axutil_stream_create_ssl(env, client->sockfd, axis2_http_client_get_server_cert(client,
                env), axis2_http_client_get_key_file(client, env), ssl_pp);
#else
        axutil_network_handler_close_socket(env, client->sockfd);
        client->sockfd = -1;
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_TRANSPORT_PROTOCOL, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Invalid Transport Protocol, HTTPS transport not enabled.");

        return AXIS2_FAILURE;
#endif
    }
    else
    {
        if(!client->data_stream)
            client->data_stream = axutil_stream_create_socket(env, client->sockfd);
    }

    if(!client->data_stream)
    {
        axutil_network_handler_close_socket(env, client->sockfd);
        client->sockfd = -1;
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Data stream creation failed for Host %s and %d port", host, port);

        return AXIS2_FAILURE;
    }

    /*Accessing HTTP headers*/

    headers = axis2_http_simple_request_get_headers(request, env);
    if(headers)
    {
        int header_count = axutil_array_list_size(headers, env);
        int i = 0;
        char *str_header2 = NULL;
        for(i = 0; i < header_count; i++)
        {
            axis2_char_t *header_ext_form = NULL;
            axis2_http_header_t *tmp_header = (axis2_http_header_t *)axutil_array_list_get(headers,
                env, i);

            if(!tmp_header)
            {
                /* This continue is added as a safey mechanism,
                 * However I see a problem with this logic, AFAIC
                 * see there can't be null headers in the headers
                 * array list, because number of headers in "headers"
                 * array list count with axutil_array_list_size,
                 * therefore this check and continue might not have a
                 * real effect.*/

                continue;
            }

            /* check whether we have transfer encoding and then see whether the
             * value is "chunked" */
            if(!axutil_strcmp(axis2_http_header_get_name(tmp_header, env),
                AXIS2_HTTP_HEADER_TRANSFER_ENCODING) && !axutil_strcmp(axis2_http_header_get_value(
                tmp_header, env), AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
            {
                chunking_enabled = AXIS2_TRUE;
            }

            header_ext_form = axis2_http_header_to_external_form(tmp_header, env);

            /* str_header2 is to hold intermediate value of str_header */
            str_header2 = axutil_stracat(env, str_header, header_ext_form);
            if(str_header)
            {
                AXIS2_FREE(env->allocator, str_header);
                str_header = NULL;
            }
            if(header_ext_form)
            {
                AXIS2_FREE(env->allocator, header_ext_form);
                header_ext_form = NULL;
            }

            /* str_header has all HTTP headers to send. */
            str_header = str_header2;
        }
    }

    if(AXIS2_FALSE == client->proxy_enabled)
    {
        str_request_line = axis2_http_request_line_to_string(
            axis2_http_simple_request_get_request_line(request, env), env);
    }
    else
    {
        /* proxy enabled case */

        /* we need the request line in the format
         * POST http://host:port/path HTTP/1.x if we have enabled proxies
         */
        axis2_char_t *host_port_str = NULL;
        axis2_char_t *host = axutil_url_get_host(client->url, env);
        axis2_http_request_line_t *request_line = axis2_http_simple_request_get_request_line(
            request, env);
        axis2_char_t *path = axis2_http_request_line_get_uri(request_line, env);

        host_port_str = AXIS2_MALLOC(env->allocator, axutil_strlen(host) + axutil_strlen(path) + 20
            * sizeof(axis2_char_t));

        if(!host_port_str)
        {
            axutil_network_handler_close_socket(env, client->sockfd);
            client->sockfd = -1;
            AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Memory allocation failed for host %s and %s path", host, path);

            return AXIS2_FAILURE;
        }

        sprintf(host_port_str, "http://%s:%d%s", host, axutil_url_get_port(client->url, env), path);
        str_request_line = AXIS2_MALLOC(env->allocator, axutil_strlen(host_port_str) + 20
            * sizeof(axis2_char_t));

        if(!str_request_line)
        {
            axutil_network_handler_close_socket(env, client->sockfd);
            client->sockfd = -1;
            AXIS2_FREE(env->allocator, host_port_str);
            AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "memory allocation failed for host %s and %s path", host, path);

            return AXIS2_FAILURE;
        }

        sprintf(str_request_line, "%s %s %s\r\n", axis2_http_request_line_get_method(request_line,
            env), host_port_str, axis2_http_request_line_get_http_version(request_line, env));

        AXIS2_FREE(env->allocator, host_port_str);
        host_port_str = NULL;

    }

    /* Here first we send the http header part */

    wire_format = axutil_stracat(env, str_request_line, str_header);
    AXIS2_FREE(env->allocator, str_header);
    str_header = NULL;
    AXIS2_FREE(env->allocator, str_request_line);
    str_request_line = NULL;
    written
        = axutil_stream_write(client->data_stream, env, wire_format, axutil_strlen(wire_format));
    AXIS2_FREE(env->allocator, wire_format);
    wire_format = NULL;

    /* Then we write the two new line charaters before the http body*/

    written = axutil_stream_write(client->data_stream, env, AXIS2_HTTP_CRLF, 2);

    /* When sending MTOM it is bit different. We keep the attachment + other
     mime headers in an array_list and send them one by one */

    if(client->doing_mtom)
    {
        /*axis2_status_t status = AXIS2_SUCCESS; */
        axutil_http_chunked_stream_t *chunked_stream = NULL;

        /* If the callback name is not there, then we will check whether there 
         * is any mime_parts which has type callback. If we found then no point 
         * of continuing we should return a failure */

        if(!(client->mtom_sending_callback_name))
        {
            if(axis2_http_transport_utils_is_callback_required(env, client->mime_parts))
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Sender callback not specified");
                return AXIS2_FAILURE;
            }
        }

        /* For MTOM we automatically enabled chunking */
        chunked_stream = axutil_http_chunked_stream_create(env, client->data_stream);

        /* This method will write the Attachment + data to the wire */

        status = axis2_http_transport_utils_send_mtom_message(chunked_stream, env,
            client->mime_parts, client->mtom_sending_callback_name);

        axutil_http_chunked_stream_free(chunked_stream, env);
        chunked_stream = NULL;

    }
    /* Non MTOM case */
    else if(client->req_body_size > 0 && client->req_body)
    {
        int len = 0;
        written = 0;

        /* Keep on writing data in a loop until we finised 
         with all the data in the buffer */

        if(!chunking_enabled)
        {
            status = AXIS2_SUCCESS;
            while(written < client->req_body_size)
            {
                len = 0;
                len = axutil_stream_write(client->data_stream, env, client->req_body + written,
                    client->req_body_size - written);
                if(-1 == len)
                {
                    status = AXIS2_FAILURE;
                    break;
                }
                else
                {
                    written += len;
                }
            }
        }
        else
        {
            /* Not MTOM but chunking is enabled */
            axutil_http_chunked_stream_t *chunked_stream = NULL;
            chunked_stream = axutil_http_chunked_stream_create(env, client->data_stream);
            status = AXIS2_SUCCESS;
            if(!chunked_stream)
            {
                axutil_network_handler_close_socket(env, client->sockfd);
                client->sockfd = -1;
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Creatoin of chunked stream failed");
                return AXIS2_FAILURE;
            }

            while(written < client->req_body_size)
            {
                written = axutil_http_chunked_stream_write(chunked_stream, env, client->req_body,
                    client->req_body_size);

                if(-1 == written)
                {
                    status = AXIS2_FAILURE;
                    break;
                }
            }

            if(AXIS2_SUCCESS == status)
            {
                /* Writing the trailing null charactor */
                axutil_http_chunked_stream_write_last_chunk(chunked_stream, env);
            }

            axutil_http_chunked_stream_free(chunked_stream, env);
        }
    }

    client->request_sent = AXIS2_TRUE;
    return status;
}

/* Following is deprecated and should be removed after 1.8 - spelling of API is not correct */
AXIS2_EXTERN int AXIS2_CALL
axis2_http_client_recieve_header(
    axis2_http_client_t * client,
    const axutil_env_t * env)
{
    return axis2_http_client_receive_header(client, env);
}

AXIS2_EXTERN int AXIS2_CALL
axis2_http_client_receive_header(
    axis2_http_client_t * client,
    const axutil_env_t * env)
{
    int status_code = -1;
    axis2_http_status_line_t *status_line = NULL;
    axis2_char_t str_status_line[AXIS2_HTTP_STATUS_LINE_LENGTH];
    axis2_char_t tmp_buf[3];
    axis2_char_t str_header[AXIS2_HTTP_HEADER_LENGTH];
    int read = 0;
    int http_status = 0;
    axis2_bool_t end_of_line = AXIS2_FALSE;
    axis2_bool_t end_of_headers = AXIS2_FALSE;

    if(-1 == client->sockfd || !client->data_stream || AXIS2_FALSE == client->request_sent)
    {
        axis2_char_t *host;
        unsigned int port;
        host = axutil_url_get_host(client->url, env);
        port = axutil_url_get_port(client->url, env);

        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Client data stream null or socket error for host %s and %d port", host, port);
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_REQUEST_NOT_SENT, AXIS2_FAILURE);
        return -1;
    }

    /* read the status line */
    do
    {
        memset(str_status_line, 0, AXIS2_HTTP_STATUS_LINE_LENGTH);
        unsigned int str_status_line_length = 0;
        while((read = axutil_stream_read(client->data_stream, env, tmp_buf, 1)) > 0)
        {
            /* "read" variable is number of characters read by stream */
            tmp_buf[read] = '\0';
            str_status_line_length += read;
            if (str_status_line_length + 1 > AXIS2_HTTP_STATUS_LINE_LENGTH)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "reached maximum status line length %i",
                        AXIS2_HTTP_STATUS_LINE_LENGTH);
                end_of_line = AXIS2_TRUE;
                break;
            }
            strcat(str_status_line, tmp_buf);
            if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF))
            {
                end_of_line = AXIS2_TRUE;
                break;
            }
        }

        if(read < 0)
        {
            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "http client , response timed out");
            AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE);
            return -1;
        }
        else if(read == 0)
        {
            AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_SERVER_SHUTDOWN, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response error, Server Shutdown");
            return 0;
        }

        status_line = axis2_http_status_line_create(env, str_status_line);
        if(!status_line)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "axis2_http_status_line_create failed for \
str_status_line %s", str_status_line);
            AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
            http_status = 0;
            continue;

        }
        http_status = axis2_http_status_line_get_status_code(status_line, env);

    }
    while(AXIS2_HTTP_RESPONSE_OK_CODE_VAL > http_status);

    if(client->response)
        axis2_http_simple_response_free(client->response, env);
    client->response = axis2_http_simple_response_create_default(env);
    axis2_http_simple_response_set_status_line(client->response, env,
        axis2_http_status_line_get_http_version(status_line, env),
        axis2_http_status_line_get_status_code(status_line, env),
        axis2_http_status_line_get_reason_phrase(status_line, env));

    /* now read the headers */
    memset(str_header, 0, AXIS2_HTTP_HEADER_LENGTH);
    unsigned int str_header_length = 0;
    end_of_line = AXIS2_FALSE;
    while(AXIS2_FALSE == end_of_headers)
    {
        while((read = axutil_stream_read(client->data_stream, env, tmp_buf, 1)) > 0)
        {
            tmp_buf[read] = '\0';
            str_header_length += read;
            if (str_header_length + 1 > AXIS2_HTTP_HEADER_LENGTH)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "reached maximum header line length %i",
                        AXIS2_HTTP_HEADER_LENGTH);
                end_of_line = AXIS2_TRUE;
                break;
            }
            strcat(str_header, tmp_buf);
            if(0 != strstr(str_header, AXIS2_HTTP_CRLF))
            {
                end_of_line = AXIS2_TRUE;
                break;
            }
        }
        if(AXIS2_TRUE == end_of_line)
        {
            if(0 == axutil_strcmp(str_header, AXIS2_HTTP_CRLF))
            {
                end_of_headers = AXIS2_TRUE;
            }
            else
            {
                axis2_http_header_t *tmp_header = axis2_http_header_create_by_str(env, str_header);
                memset(str_header, 0, AXIS2_HTTP_HEADER_LENGTH);
                if(tmp_header)
                {
                    axis2_http_simple_response_set_header(client->response, env, tmp_header);
                }
            }
        }
        end_of_line = AXIS2_FALSE;
    }
    axis2_http_simple_response_set_body_stream(client->response, env, client->data_stream);
    if(status_line)
    {
        status_code = axis2_http_status_line_get_status_code(status_line, env);
        axis2_http_status_line_free(status_line, env);
        status_line = NULL;
    }

    if(AXIS2_FALSE == axis2_http_simple_response_contains_header(client->response, env,
        AXIS2_HTTP_HEADER_CONTENT_TYPE) && 202 != status_code
        && axis2_http_simple_response_get_content_length(client->response, env) > 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_CONTENT_TYPE_MISSING, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response does not contain Content-Type");
        return -1;
    }
    return status_code;
}

AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL
axis2_http_client_get_response(
    const axis2_http_client_t * client,
    const axutil_env_t * env)
{
    return client->response;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_url(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axutil_url_t * url)
{
    AXIS2_PARAM_CHECK(env->error, url, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);

    if(client->url)
    {
        axutil_url_free(client->url, env);
        client->url = NULL;
    }
    client->url = url;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axutil_url_t *AXIS2_CALL
axis2_http_client_get_url(
    const axis2_http_client_t * client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, client, NULL);
    return client->url;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_timeout(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    int timeout_ms)
{
    AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
    client->timeout = timeout_ms;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axis2_http_client_get_timeout(
    const axis2_http_client_t * client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
    return client->timeout;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_proxy(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axis2_char_t * proxy_host,
    int proxy_port)
{
    AXIS2_PARAM_CHECK(env->error, proxy_host, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);

    if(proxy_port <= 0)
    {
        return AXIS2_FAILURE;
    }

    client->proxy_port = proxy_port;
    if(client->proxy_host)
    {
        AXIS2_FREE(env->allocator, client->proxy_host);
        client->proxy_host = NULL;
    }

    if(client->proxy_host_port)
    {
        AXIS2_FREE(env->allocator, client->proxy_host_port);
        client->proxy_host_port = NULL;
    }

    client->proxy_host = axutil_strdup(env, proxy_host);
    if(!client->proxy_host)
    {
        return AXIS2_FAILURE;
    }

    client->proxy_host_port = AXIS2_MALLOC(env->allocator, axutil_strlen(proxy_host) + 10
        * sizeof(axis2_char_t));

    sprintf(client->proxy_host_port, "%s:%d", proxy_host, proxy_port);
    client->proxy_enabled = AXIS2_TRUE;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_client_get_proxy(
    const axis2_http_client_t * client,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK(env->error, client, NULL);
    return client->proxy_host_port;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_connect_ssl_host(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axis2_char_t * host,
    int port)
{
    axutil_stream_t *tmp_stream = NULL;
    axis2_char_t *connect_string = NULL;
    axis2_char_t str_status_line[AXIS2_HTTP_STATUS_LINE_LENGTH];
    axis2_char_t str_header[AXIS2_HTTP_HEADER_LENGTH];
    axis2_char_t tmp_buf[3];
    int read = 0;
    axis2_bool_t end_of_line = AXIS2_FALSE;
    axis2_bool_t end_of_response = AXIS2_FALSE;
    axis2_http_status_line_t *status_line = NULL;

    AXIS2_PARAM_CHECK(env->error, host, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, client->url, AXIS2_FAILURE);
    /* This host and port will use for give undersandable log messages
     * */

    if(port <= 0)
    {
        return AXIS2_FAILURE;
    }

    tmp_stream = axutil_stream_create_socket(env, client->sockfd);
    if(!tmp_stream)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "Unable to create socket for SSL host %s and %d port", host, port);
        return AXIS2_FAILURE;
    }

    connect_string = AXIS2_MALLOC(env->allocator, axutil_strlen(host) * sizeof(axis2_char_t) + 30
        * sizeof(axis2_char_t));
    sprintf(connect_string, "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
    axutil_stream_write(tmp_stream, env, connect_string, axutil_strlen(connect_string)
        * sizeof(axis2_char_t));

    memset(str_status_line, 0, AXIS2_HTTP_STATUS_LINE_LENGTH);
    unsigned int str_status_line_length = 0;
    end_of_line = AXIS2_FALSE;
    while((read = axutil_stream_read(tmp_stream, env, tmp_buf, 1)) > 0)
    {
        tmp_buf[read] = '\0';
        str_status_line_length += read;
        if (str_status_line_length + 1 > AXIS2_HTTP_STATUS_LINE_LENGTH)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "reached maximum status line length %i",
                    AXIS2_HTTP_STATUS_LINE_LENGTH);
            end_of_line = AXIS2_TRUE;
            break;
        }
        strcat(str_status_line, tmp_buf);
        if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF))
        {
            end_of_line = AXIS2_TRUE;
            break;
        }
    }
    if(read < 0)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE);
        AXIS2_FREE(env->allocator, connect_string);
        axutil_stream_free(tmp_stream, env);
        return AXIS2_FAILURE;
    }
    status_line = axis2_http_status_line_create(env, str_status_line);
    if(!status_line)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE);
        AXIS2_FREE(env->allocator, connect_string);
        axutil_stream_free(tmp_stream, env);
        return AXIS2_FAILURE;
    }
    if(200 != axis2_http_status_line_get_status_code(status_line, env))
    {
        AXIS2_FREE(env->allocator, connect_string);
        axis2_http_status_line_free(status_line, env);
        axutil_stream_free(tmp_stream, env);
        return AXIS2_FAILURE;
    }
    /* We need to empty the stream before we return
     */
    memset(str_header, 0, AXIS2_HTTP_HEADER_LENGTH);
    unsigned int str_header_length = 0;
    while(AXIS2_FALSE == end_of_response)
    {
        while((read = axutil_stream_read(tmp_stream, env, tmp_buf, 1)) > 0)
        {
            tmp_buf[read] = '\0';
            str_header_length += read;
            if (str_header_length + 1 > AXIS2_HTTP_HEADER_LENGTH)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "reached maximum header line length %i",
                        AXIS2_HTTP_HEADER_LENGTH);
                end_of_line = AXIS2_TRUE;
                break;
            }
            strcat(str_header, tmp_buf);
            if(0 != strstr(str_header, AXIS2_HTTP_CRLF))
            {
                end_of_line = AXIS2_TRUE;
                break;
            }
        }
        if(AXIS2_TRUE == end_of_line)
        {
            if(0 == axutil_strcmp(str_header, AXIS2_HTTP_CRLF))
            {
                end_of_response = AXIS2_TRUE;
            }
            else
            {
                end_of_line == AXIS2_FALSE;
                memset(str_header, 0, AXIS2_HTTP_HEADER_LENGTH);
            }

        }
    }
    AXIS2_FREE(env->allocator, connect_string);
    axis2_http_status_line_free(status_line, env);
    axutil_stream_free(tmp_stream, env);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_dump_input_msg(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axis2_bool_t dump_input_msg)
{
    client->dump_input_msg = dump_input_msg;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_server_cert(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axis2_char_t * server_cert)
{
    AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, server_cert, AXIS2_FAILURE);
    client->server_cert = server_cert;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_client_get_server_cert(
    const axis2_http_client_t * client,
    const axutil_env_t * env)
{
    return client->server_cert;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_key_file(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axis2_char_t * key_file)
{
    AXIS2_PARAM_CHECK(env->error, client, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, key_file, AXIS2_FAILURE);
    client->key_file = key_file;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_http_client_get_key_file(
    const axis2_http_client_t * client,
    const axutil_env_t * env)
{
    return client->key_file;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_mime_parts(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axutil_array_list_t *mime_parts)
{
    client->mime_parts = mime_parts;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
axis2_http_client_get_mime_parts(
    const axis2_http_client_t * client,
    const axutil_env_t * env)
{
    return client->mime_parts;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_doing_mtom(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axis2_bool_t doing_mtom)
{
    client->doing_mtom = doing_mtom;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_http_client_get_doing_mtom(
    const axis2_http_client_t * client,
    const axutil_env_t * env)
{
    return client->doing_mtom;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_set_mtom_sending_callback_name(
    axis2_http_client_t * client,
    const axutil_env_t * env,
    axis2_char_t *callback_name)
{
    client->mtom_sending_callback_name = callback_name;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_consume_stream(
    axis2_http_client_t * client,
    const axutil_env_t * env)
{
    /*axutil_stream_close(client->data_stream, env);*/
    axis2_char_t tmp_buffer[512];
    int read;
    
    while((read = axutil_stream_read(client->data_stream, env, tmp_buffer, 511)) == 511)
    {
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_http_client_reset(
    axis2_http_client_t * client,
    const axutil_env_t * env)
{
    if(client->req_body)
    {
        AXIS2_FREE(env->allocator, client->req_body);
        client->req_body = NULL;
    }
    return AXIS2_SUCCESS;
}
