summaryrefslogtreecommitdiffstats
path: root/src/core/transport/http/sender
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/transport/http/sender')
-rw-r--r--src/core/transport/http/sender/Makefile.am51
-rw-r--r--src/core/transport/http/sender/http_client.c965
-rw-r--r--src/core/transport/http/sender/http_sender.c3332
-rw-r--r--src/core/transport/http/sender/http_transport_sender.c859
-rw-r--r--src/core/transport/http/sender/libcurl/Makefile.am2
-rw-r--r--src/core/transport/http/sender/libcurl/axis2_libcurl.c1169
-rw-r--r--src/core/transport/http/sender/libcurl/axis2_libcurl.h53
-rw-r--r--src/core/transport/http/sender/libcurl/libcurl_stream.c192
-rw-r--r--src/core/transport/http/sender/libcurl/libcurl_stream.h51
-rw-r--r--src/core/transport/http/sender/ssl/Makefile.am2
-rw-r--r--src/core/transport/http/sender/ssl/ssl_stream.c239
-rw-r--r--src/core/transport/http/sender/ssl/ssl_stream.h50
-rw-r--r--src/core/transport/http/sender/ssl/ssl_utils.c227
-rw-r--r--src/core/transport/http/sender/ssl/ssl_utils.h56
14 files changed, 7248 insertions, 0 deletions
diff --git a/src/core/transport/http/sender/Makefile.am b/src/core/transport/http/sender/Makefile.am
new file mode 100644
index 0000000..399ed39
--- /dev/null
+++ b/src/core/transport/http/sender/Makefile.am
@@ -0,0 +1,51 @@
+SUBDIRS=ssl libcurl
+lib_LTLIBRARIES = libaxis2_http_sender.la
+
+
+
+if AXIS2_LIBCURL_ENABLED
+LIBCURL_SOURCES=libcurl/axis2_libcurl.c\
+ libcurl/libcurl_stream.c
+LIBCURL_LIBS=-lssl -lcrypto -lcurl -ldl -lz
+else
+LIBCURL_SOURCES=
+LIBCURL_LIBS=
+endif
+
+
+if AXIS2_SSL_ENABLED
+SSL_SOURCES = ssl/ssl_stream.c\
+ ssl/ssl_utils.c
+SSL_LIBS = -lssl -lcrypto
+else
+SSL_SOURCES=
+SSL_LIBS=
+endif
+
+libaxis2_http_sender_la_SOURCES = http_transport_sender.c \
+ http_sender.c \
+ http_client.c \
+ $(SSL_SOURCES) \
+ $(LIBCURL_SOURCES)
+
+libaxis2_http_sender_la_LIBADD = $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la\
+ $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la\
+ $(top_builddir)/axiom/src/om/libaxis2_axiom.la\
+ $(top_builddir)/util/src/libaxutil.la\
+ $(LIBCURL_LIBS)\
+ $(SSL_LIBS)
+
+
+libaxis2_http_sender_la_LDFLAGS = -version-info $(VERSION_NO)
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/transport\
+ -I$(top_builddir)/src/core/transport/http \
+ -I$(top_builddir)/src/core/transport/http/sender/libcurl \
+ -I$(top_builddir)/src/core/description \
+ -I$(top_builddir)/src/core/context \
+ -I$(top_builddir)/src/core/phaseresolver \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/axiom/include
diff --git a/src/core/transport/http/sender/http_client.c b/src/core/transport/http/sender/http_client.c
new file mode 100644
index 0000000..80e7ee3
--- /dev/null
+++ b/src/core/transport/http/sender/http_client.c
@@ -0,0 +1,965 @@
+/*
+ * 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
+
+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_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;
+ }
+ }
+ 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
+ {
+ 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;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_http_client_recieve_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[512];
+ axis2_char_t tmp_buf[3];
+ axis2_char_t str_header[512];
+ 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, 512);
+ 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';
+ 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, 512);
+ 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';
+ 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, 512);
+ 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[512];
+ 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 open 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, 512);
+ while((read = axutil_stream_read(tmp_stream, env, tmp_buf, 1)) > 0)
+ {
+ tmp_buf[read] = '\0';
+ 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);
+ axutil_stream_free(tmp_stream, env);
+ return AXIS2_FAILURE;
+ }
+ /* We need to empty the stream before we return
+ */
+ memset(str_status_line, 0, 512);
+ while(AXIS2_FALSE == end_of_response)
+ {
+ while((read = axutil_stream_read(tmp_stream, env, tmp_buf, 1)) > 0)
+ {
+ tmp_buf[read] = '\0';
+ strcat(str_status_line, tmp_buf);
+ if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF))
+ {
+ end_of_line = AXIS2_TRUE;
+ break;
+ }
+ }
+ if(AXIS2_TRUE == end_of_line)
+ {
+ if(0 == axutil_strcmp(str_status_line, AXIS2_HTTP_CRLF))
+ {
+ end_of_response = AXIS2_TRUE;
+ }
+ }
+ }
+ AXIS2_FREE(env->allocator, connect_string);
+ 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;
+}
diff --git a/src/core/transport/http/sender/http_sender.c b/src/core/transport/http/sender/http_sender.c
new file mode 100644
index 0000000..56f11e0
--- /dev/null
+++ b/src/core/transport/http/sender/http_sender.c
@@ -0,0 +1,3332 @@
+/*
+ * 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_sender.h>
+#include <axutil_string.h>
+#include <axis2_http_transport.h>
+#include <axis2_http_transport_utils.h>
+#include <string.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 <axutil_uuid_gen.h>
+#include <axutil_digest_calc.h>
+#include <axis2_const.h>
+#include <axis2_util.h>
+#include <axiom_soap.h>
+#include <axutil_version.h>
+
+#ifdef AXIS2_LIBCURL_ENABLED
+#include "libcurl/axis2_libcurl.h"
+#else
+#define CLIENT_NONCE_LENGTH 8
+#endif
+
+struct axis2_http_sender
+{
+ axis2_char_t *http_version;
+ axis2_bool_t chunked;
+ int so_timeout;
+ axiom_output_t *om_output;
+ axis2_http_client_t *client;
+ axis2_bool_t is_soap;
+ axis2_bool_t keep_alive;
+};
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static void
+axis2_http_sender_add_header_list(
+ axis2_http_simple_request_t * request,
+ const axutil_env_t * env,
+ axutil_array_list_t * array_list);
+
+static axis2_status_t
+axis2_http_sender_configure_proxy(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+static axis2_status_t
+axis2_http_sender_configure_server_cert(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+static axis2_status_t
+axis2_http_sender_configure_key_file(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+static axis2_status_t
+axis2_http_sender_configure_http_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_set_http_auth_type(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_set_proxy_auth_type(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_configure_http_basic_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_basic_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request);
+
+static axis2_status_t
+axis2_http_sender_configure_http_digest_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_data);
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_digest_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_data);
+
+
+
+#endif
+
+static axutil_hash_t *
+axis2_http_sender_connection_map_create(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx);
+
+static void
+axis2_http_sender_connection_map_remove(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_http_client_t *http_client);
+
+static void
+axis2_http_sender_connection_map_add(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_http_client_t *http_client);
+
+static axis2_http_client_t *
+axis2_http_sender_connection_map_get(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx);
+
+static void AXIS2_CALL
+axis2_http_sender_connection_map_free(
+ void *cm_void,
+ const axutil_env_t *env);
+
+AXIS2_EXTERN axis2_http_sender_t *AXIS2_CALL
+axis2_http_sender_create(
+ const axutil_env_t * env)
+{
+ axis2_http_sender_t *sender = NULL;
+
+ sender = (axis2_http_sender_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_sender_t));
+
+ if(!sender)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ memset(sender, 0, sizeof(axis2_http_sender_t));
+ sender->http_version = (axis2_char_t *)AXIS2_HTTP_HEADER_PROTOCOL_11;
+ sender->so_timeout = AXIS2_HTTP_DEFAULT_SO_TIMEOUT;
+ /* unlike the java impl we don't have a default om output
+ * it should be explicitly set and it's a MUST
+ */
+ sender->om_output = NULL;
+ sender->chunked = AXIS2_FALSE;
+ sender->client = NULL;
+ sender->keep_alive = AXIS2_TRUE;
+
+ return sender;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_sender_free(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env)
+{
+ if(sender->http_version)
+ {
+ AXIS2_FREE(env->allocator, sender->http_version);
+ }
+
+ /* Do not free this here since it will be required in later processing
+ * of the response soap message
+ */
+ sender->client = NULL;
+ AXIS2_FREE(env->allocator, sender);
+ return;
+}
+
+#ifndef AXIS2_LIBCURL_ENABLED
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_send(
+ axis2_http_sender_t * sender,
+ 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)
+{
+ axis2_http_simple_request_t *request = NULL;
+ axis2_http_request_line_t *request_line = NULL;
+
+ /* url is to hold url given in str_url */
+ axutil_url_t *url = NULL;
+ axiom_xml_writer_t *xml_writer = NULL;
+ axis2_char_t *buffer = NULL;
+ unsigned int buffer_size = 0;
+ const axis2_char_t *char_set_enc = NULL;
+ axutil_string_t *char_set_enc_str = NULL;
+ int status_code = -1;
+ axis2_http_simple_response_t *response = NULL;
+ axis2_char_t *content_type = NULL;
+ axis2_bool_t content_type_deepl_copy = AXIS2_TRUE;
+ axis2_byte_t *output_stream = NULL;
+ int output_stream_size = 0;
+ axis2_bool_t doing_mtom = AXIS2_FALSE;
+ axutil_property_t *dump_property = NULL;
+ axutil_param_t *ssl_pp_param = NULL;
+ /* ssl passphrase */
+ axis2_char_t *ssl_pp = NULL;
+ axutil_property_t *ssl_pp_property = NULL;
+ axutil_property_t *test_auth_property = NULL;
+ axis2_char_t *test_auth_property_value = NULL;
+ axis2_bool_t test_proxy_auth = AXIS2_FALSE;
+ axis2_bool_t test_http_auth = AXIS2_FALSE;
+
+ /* http proxy authentication */
+ axutil_property_t *proxy_auth_property = NULL;
+ axis2_char_t *proxy_auth_property_value = NULL;
+ axis2_bool_t force_proxy_auth = AXIS2_FALSE;
+ axis2_bool_t force_proxy_auth_with_head = AXIS2_FALSE;
+ axutil_property_t *http_auth_property = NULL;
+ axis2_char_t *http_auth_property_value = NULL;
+ axis2_bool_t force_http_auth = AXIS2_FALSE;
+ axis2_bool_t force_http_auth_with_head = AXIS2_FALSE;
+ axutil_property_t *content_type_property = NULL;
+ axutil_hash_t *content_type_hash = NULL;
+ axis2_char_t *content_type_value = NULL;
+ axutil_property_t *method = NULL;
+ axis2_char_t *method_value = NULL;
+
+ /* handling REST requests */
+ axis2_bool_t send_via_get = AXIS2_FALSE;
+ axis2_bool_t send_via_head = AXIS2_FALSE;
+ axis2_bool_t send_via_delete = AXIS2_FALSE;
+ axis2_bool_t send_via_put = AXIS2_FALSE;
+ axiom_node_t *data_out = NULL;
+ axiom_node_t *body_node = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axis2_bool_t is_soap = AXIS2_TRUE;
+ axis2_bool_t add_keepalive_header = AXIS2_FALSE;
+
+ /* http header property to get HTTP headers from msg_ctx and give
+ * it to http_sender */
+ axutil_property_t *http_property = NULL;
+ axutil_array_list_t *array_list;
+ axis2_bool_t http_auth_header_added = AXIS2_FALSE;
+ 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 = NULL;/* Property for holding http client */
+ /*axis2_char_t *header_value = NULL;*/
+ axis2_char_t *cookie_str = NULL;
+ axutil_hash_t *connection_map = NULL;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_sender_send");
+ soap_body = axiom_soap_envelope_get_body(out, env);
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, out, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, str_url, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, soap_action, AXIS2_FAILURE);
+
+ if(AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ is_soap = AXIS2_FALSE;
+ }
+ else
+ {
+ is_soap = AXIS2_TRUE;
+ }
+
+ url = axutil_url_parse_string(env, str_url);
+
+ if(!is_soap)
+ {
+ if(soap_body)
+ {
+ body_node = axiom_soap_body_get_base_node(soap_body, env);
+ }
+ if(body_node)
+ {
+ 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;
+ }
+ }
+
+ if(!url)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "url is null for string %s", str_url);
+ return AXIS2_FAILURE;
+ }
+
+ /*if(sender->client)
+ {
+ axis2_http_client_free(sender->client, env);
+ sender->client = NULL;
+ }*/
+
+ /* This property may be set by the application client. This get the priority over the keep alive
+ * parameter set in the axix2.xml
+ */
+ property = (axutil_property_t *) axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE);
+ if(property)
+ {
+ axis2_char_t *keep_alive_value = NULL;
+
+ keep_alive_value = axutil_property_get_value(property, env);
+ if(!axutil_strcmp(keep_alive_value, AXIS2_VALUE_FALSE))
+ {
+ sender->keep_alive = AXIS2_FALSE;
+ }
+ }
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ }
+
+ /* Because keep alive is not still supported at callback receiver we check
+ * for client side
+ */
+ if(sender->keep_alive && !axis2_msg_ctx_get_server_side(msg_ctx, env))
+ {
+ axutil_property_t *connection_map_property = NULL;
+
+ connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_HTTP_CONNECTION_MAP);
+ if(!connection_map_property)
+ {
+ connection_map = axis2_http_sender_connection_map_create(env, msg_ctx);
+ if(!connection_map)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ connection_map = axutil_property_get_value(connection_map_property, env);
+ if(connection_map)
+ {
+ sender->client = axis2_http_sender_connection_map_get(connection_map, env, msg_ctx);
+ }
+ }
+ if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_10))
+ {
+ add_keepalive_header = AXIS2_TRUE;
+ }
+ } /* End if sender->keep_alive */
+ if(!sender->client)
+ {
+ sender->client = axis2_http_client_create(env, url);
+ }
+ if(!sender->client)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "sender->client creation failed for url %s", url);
+ return AXIS2_FAILURE;
+ }
+ /* configure proxy settings if we have set so
+ */
+
+ axis2_http_sender_configure_proxy(sender, env, msg_ctx);
+
+ if(conf)
+ {
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+
+ if(trans_desc)
+ {
+ /* get xml declaration details from axis2.xml */
+ 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)
+ {
+ /* accessing attributes of the HTTP transport's , xml
+ * declaration element from axis2.xml*/
+
+ 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(sender->om_output, env);
+ }
+
+ if(!send_via_get && !send_via_head && !send_via_delete)
+ {
+ /* processing POST and PUT methods */
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "msg_ctx_id:%s", axis2_msg_ctx_get_msg_id(msg_ctx,
+ env));
+
+ doing_mtom = axis2_msg_ctx_get_doing_mtom(msg_ctx, env);
+
+ if(!sender->om_output)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_OM_OUTPUT, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", AXIS2_ERROR_GET_MESSAGE(env->error));
+ return AXIS2_FAILURE;
+ }
+
+ xml_writer = axiom_output_get_xml_writer(sender->om_output, env);
+
+ char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env);
+
+ if(!char_set_enc_str)
+ {
+ /* if there is no character encoding details available
+ * use default one.
+ * #define AXIS2_DEFAULT_CHAR_SET_ENCODING "UTF-8"
+ */
+ 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)
+ {
+ /* HTTP POST case */
+ /* dump property use to dump message without sending */
+ dump_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_DUMP_INPUT_MSG_TRUE);
+ if(dump_property)
+ {
+ axis2_char_t *dump_true = axutil_property_get_value(dump_property, env);
+ if(0 == axutil_strcmp(dump_true, AXIS2_VALUE_TRUE))
+ {
+ axis2_http_client_set_dump_input_msg(sender->client, env, AXIS2_TRUE);
+ }
+ }
+
+ axiom_output_set_do_optimize(sender->om_output, env, doing_mtom);
+ axiom_soap_envelope_serialize(out, env, sender->om_output, AXIS2_FALSE);
+ }
+ 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
+ {
+ if(!data_out)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "body node payload is NULL");
+ return AXIS2_FAILURE;
+ }
+ axiom_node_serialize(data_out, env, sender->om_output);
+ }
+
+ if(doing_mtom)
+ {
+ axutil_param_t *callback_name_param = NULL;
+ axis2_status_t mtom_status = AXIS2_FAILURE;
+ axutil_array_list_t *mime_parts = NULL;
+ axis2_char_t *mtom_sending_callback_name = NULL;
+
+ /* Getting the sender callback name paramter if it is
+ * specified in the configuration file */
+
+ callback_name_param = axis2_msg_ctx_get_parameter(msg_ctx, env,
+ AXIS2_MTOM_SENDING_CALLBACK);
+ if(callback_name_param)
+ {
+ mtom_sending_callback_name = (axis2_char_t *)axutil_param_get_value(
+ callback_name_param, env);
+ if(mtom_sending_callback_name)
+ {
+ axis2_http_client_set_mtom_sending_callback_name(sender->client, env,
+ mtom_sending_callback_name);
+ }
+ }
+
+ /* Here we put all the attachment related stuff in a array_list
+ After this method we have the message in parts */
+
+ mtom_status = axiom_output_flush(sender->om_output, env);
+ if(mtom_status == AXIS2_FAILURE)
+ {
+ return mtom_status;
+ }
+ /* HTTP client should distinguish an MTOM invocation because the way
+ of sending the message in MTOM case is different */
+ axis2_http_client_set_doing_mtom(sender->client, env, doing_mtom);
+
+ /* HTTP client will keep this mime_parts, which it will send in chunks at
+ th end */
+ mime_parts = axiom_output_get_mime_parts(sender->om_output, env);
+ if(mime_parts)
+ {
+ axis2_http_client_set_mime_parts(sender->client, env, mime_parts);
+ }
+ }
+ else
+ {
+ buffer = axiom_xml_writer_get_xml(xml_writer, env);
+ }
+
+ if(!(buffer || doing_mtom))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "NULL xml returned from xml writer");
+ return AXIS2_FAILURE;
+ }
+
+ if(!send_via_put)
+ {
+ /* HTTP POST */
+ axis2_char_t *path_with_query = NULL;
+
+ path_with_query = axutil_strcat(env, axutil_url_get_path(url, env),
+ axutil_url_get_query(url, env), NULL);
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_POST, path_with_query,
+ sender->http_version);
+ AXIS2_FREE(env->allocator, path_with_query);
+ }
+ else
+ {
+ /* HTTP PUT */
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_PUT, axutil_url_get_path(
+ url, env), sender->http_version);
+ }
+ }
+ else
+ {
+ /* Processing HTTP GET, HEAD and DELETE */
+
+ axis2_char_t *request_params = NULL;
+ axis2_char_t *path = NULL;
+
+ request_params = axis2_http_sender_get_param_string(sender, env, msg_ctx);
+
+ if(request_params)
+ {
+ /* substituting AXIS2_Q_MARK for "?" */
+ path = axutil_strcat(env, axutil_url_get_path(url, env), AXIS2_Q_MARK_STR,
+ request_params, NULL);
+ AXIS2_FREE(env->allocator, request_params);
+ request_params = NULL;
+ }
+ else
+ {
+ path = axutil_strdup(env, axutil_url_get_path(url, env));
+ }
+
+ if(send_via_get)
+ {
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_GET, path,
+ sender->http_version);
+ }
+ else if(send_via_head)
+ {
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD, path,
+ sender->http_version);
+ }
+ else if(send_via_delete)
+ {
+ request_line = axis2_http_request_line_create(env, AXIS2_HTTP_DELETE, path,
+ sender->http_version);
+ }
+
+ if(path)
+ {
+ AXIS2_FREE(env->allocator, path);
+ path = NULL;
+ }
+ }
+
+ request = axis2_http_simple_request_create(env, request_line, NULL, 0, NULL);
+ if(add_keepalive_header)
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONNECTION,
+ AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE);
+ }
+ /**
+ * If there is a session related stuff handle it
+ */
+ /*header_value = axis2_http_transport_utils_get_session(env, msg_ctx);
+ if(header_value)
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SET_COOKIE, header_value);
+ }*/
+
+ /**
+ * In the client side sender if a cookie is sent by server add it to the http header
+ */
+ cookie_str = axis2_http_transport_utils_read_from_cookie_store(env, msg_ctx);
+ if(cookie_str)
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_COOKIE, cookie_str);
+ }
+
+ /* User-Agent:Axis2/C header */
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_USER_AGENT, AXIS2_USER_AGENT);
+
+ http_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_HEADER_PROPERTY);
+ if(http_property)
+ {
+ array_list = (axutil_array_list_t *)axutil_property_get_value(http_property, env);
+ axis2_http_sender_add_header_list(request, env, array_list);
+ }
+
+ if(!send_via_get && !send_via_head && !send_via_put && !send_via_delete && 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);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SOAP_ACTION,
+ tmp_soap_action);
+ AXIS2_FREE(env->allocator, tmp_soap_action);
+ }
+ else
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_SOAP_ACTION,
+ (const axis2_char_t *)soap_action);
+ }
+ }
+ else if(AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Adding of SOAP Action Failed for REST request");
+
+ return AXIS2_FAILURE;
+ }
+
+ if(!send_via_get && !send_via_head && !send_via_delete)
+ {
+ /* processing PUT and POST */
+ buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env);
+
+ if(AXIS2_FALSE == sender->chunked)
+ {
+ axis2_char_t tmp_buf[10];
+ if(!buffer)
+ {
+ buffer_size = output_stream_size;
+ }
+
+ if(buffer_size)
+ {
+ sprintf(tmp_buf, "%d", buffer_size);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONTENT_LENGTH,
+ tmp_buf);
+ }
+ }
+ else
+ {
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_TRANSFER_ENCODING,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED);
+ }
+
+ if(!send_via_put && is_soap)
+ {
+ /* HTTP POST */
+ if(doing_mtom)
+ {
+ content_type = (axis2_char_t *)axiom_output_get_content_type(sender-> om_output,
+ env);
+ if(AXIS2_TRUE != axis2_msg_ctx_get_is_soap_11(msg_ctx, env) && 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
+ {
+ content_type_deepl_copy = AXIS2_FALSE;
+ }
+ }
+ else if(AXIS2_TRUE == axis2_msg_ctx_get_is_soap_11(msg_ctx, env))
+ {
+ /* SOAP 1.1 without MTOM */
+ 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
+ {
+ /* SOAP 1.2 without MTOM */
+ 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_ESC_DOUBLE_QUOTE_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
+ {
+ 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;
+ }
+
+ content_type_deepl_copy = AXIS2_FALSE;
+ }
+
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_CONTENT_TYPE,
+ content_type);
+
+ if(content_type_deepl_copy && content_type)
+ {
+ AXIS2_FREE(env->allocator, content_type);
+ content_type = NULL;
+ }
+ /* Finished Processing PUT and POST */
+ }
+
+ if(0 == axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_11))
+ {
+ /* HTTP 1.1 */
+ axis2_char_t *header = NULL;
+ int host_len = 0;
+ host_len = axutil_strlen(axutil_url_get_host(url, env));
+ header = AXIS2_MALLOC(env->allocator, host_len + 10 * sizeof(axis2_char_t));
+ sprintf(header, "%s:%d", axutil_url_get_host(url, env), axutil_url_get_port(url, env));
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_HOST, header);
+ AXIS2_FREE(env->allocator, header);
+ header = NULL;
+ }
+
+ /* If this is a normal invocation the buffer has the full SOAP message
+ which needs to be send. In the MTOM case instead of this buffer
+ it has the mime_parts array_list */
+
+ if(!doing_mtom)
+ {
+ axis2_http_simple_request_set_body_string(request, env, buffer, buffer_size);
+ }
+
+ /* HTTPS request processing */
+ axis2_http_sender_configure_server_cert(sender, env, msg_ctx);
+
+ axis2_http_sender_configure_key_file(sender, env, msg_ctx);
+
+ axis2_http_sender_get_timeout_values(sender, env, msg_ctx);
+ axis2_http_client_set_timeout(sender->client, env, sender->so_timeout);
+
+ ssl_pp_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_PASSPHRASE);
+
+ if(ssl_pp_property)
+ {
+ ssl_pp = (axis2_char_t *)axutil_property_get_value(ssl_pp_property, env);
+ }
+ else
+ {
+ ssl_pp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_PASSPHRASE);
+
+ if(ssl_pp_param)
+ {
+ ssl_pp = axutil_param_get_value(ssl_pp_param, env);
+ }
+ }
+
+ test_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_TEST_PROXY_AUTH);
+ if(test_auth_property)
+ {
+ test_auth_property_value = (axis2_char_t *)axutil_property_get_value(test_auth_property,
+ env);
+ }
+
+ if(test_auth_property_value && 0 == axutil_strcmp(test_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ test_proxy_auth = AXIS2_TRUE;
+ }
+
+ test_auth_property = NULL;
+ test_auth_property_value = NULL;
+
+ test_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_TEST_HTTP_AUTH);
+ if(test_auth_property)
+ {
+ test_auth_property_value = (axis2_char_t *)axutil_property_get_value(test_auth_property,
+ env);
+ }
+
+ if(test_auth_property_value && 0 == axutil_strcmp(test_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ test_http_auth = AXIS2_TRUE;
+ }
+
+ if(!test_proxy_auth)
+ {
+ proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_FORCE_PROXY_AUTH);
+ }
+ if(proxy_auth_property)
+ {
+ proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property,
+ env);
+ }
+
+ if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ force_proxy_auth = AXIS2_TRUE;
+ }
+
+ proxy_auth_property = NULL;
+ proxy_auth_property_value = NULL;
+
+ if(force_proxy_auth)
+ {
+ proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_PROXY_AUTH_TYPE);
+ }
+
+ if(proxy_auth_property)
+ {
+ proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property,
+ env);
+ }
+
+ if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value,
+ AXIS2_PROXY_AUTH_TYPE_DIGEST))
+ {
+ force_proxy_auth = AXIS2_FALSE;
+ force_proxy_auth_with_head = AXIS2_TRUE;
+ }
+
+ if(!test_http_auth)
+ {
+ http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_FORCE_HTTP_AUTH);
+ }
+
+ if(http_auth_property)
+ {
+ http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property,
+ env);
+ }
+
+ if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ force_http_auth = AXIS2_TRUE;
+ }
+
+ http_auth_property = NULL;
+ http_auth_property_value = NULL;
+
+ if(force_http_auth)
+ {
+ http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_HTTP_AUTH_TYPE);
+ }
+
+ if(http_auth_property)
+ {
+ http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property,
+ env);
+ }
+
+ if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value,
+ AXIS2_HTTP_AUTH_TYPE_DIGEST))
+ {
+ force_http_auth = AXIS2_FALSE;
+ force_http_auth_with_head = AXIS2_TRUE;
+ }
+
+ axis2_msg_ctx_set_auth_type(msg_ctx, env, NULL);
+
+ if(force_proxy_auth || force_proxy_auth_with_head)
+ {
+ status_code = AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL;
+ }
+ else
+ {
+ /* NOT forcing proxy authentication */
+ if(force_http_auth)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP Authentication header");
+ }
+ http_auth_header_added = AXIS2_TRUE;
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+
+ else if(force_http_auth_with_head)
+ {
+ axis2_http_request_line_t *head_request_line = NULL;
+ axis2_http_request_line_t *temp = NULL;
+
+ temp = axis2_http_simple_request_get_request_line(request, env);
+ head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD,
+ axis2_http_request_line_get_uri(temp, env),
+ axis2_http_request_line_get_http_version(temp, env));
+ axis2_http_simple_request_set_request_line(request, env, head_request_line);
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ axis2_http_simple_request_set_request_line(request, env, temp);
+ axis2_http_request_line_free(head_request_line, env);
+
+ if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP Authentication\
+ header");
+ }
+ http_auth_header_added = AXIS2_TRUE;
+ }
+
+ if(status_code != AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL)
+ {
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+
+ if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+ http_auth_header_added = AXIS2_FALSE;
+ force_http_auth_with_head = AXIS2_FALSE;
+ }
+ }
+ }
+ else
+ {
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+ }
+
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code
+ && !test_proxy_auth)
+ {
+ if(force_proxy_auth_with_head)
+ {
+ axis2_http_request_line_t *head_request_line = NULL;
+ axis2_http_request_line_t *temp = NULL;
+
+ temp = axis2_http_simple_request_get_request_line(request, env);
+ head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD,
+ axis2_http_request_line_get_uri(temp, env),
+ axis2_http_request_line_get_http_version(temp, env));
+ axis2_http_simple_request_set_request_line(request, env, head_request_line);
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ axis2_http_simple_request_set_request_line(request, env, temp);
+ axis2_http_request_line_free(head_request_line, env);
+
+ if(status_code == AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_proxy_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting Proxy Authentication\
+ header");
+ }
+
+ if((force_http_auth_with_head || force_http_auth) && !http_auth_header_added)
+ {
+ status_code = AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL;
+ }
+ else
+ {
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+ }
+ else if(status_code != AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+
+ /* Proxies have no idea about HTTP Methods therefore, if
+ * it fails no need to re-check */
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE);
+ }
+ }
+ else
+ {
+
+ /* not forcing proxy auth with head */
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_proxy_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting Proxy Authentication \
+header");
+ }
+
+ if((force_http_auth_with_head || force_http_auth) && !http_auth_header_added)
+ {
+ status_code = AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL;
+ }
+ else
+ {
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE);
+ }
+ }
+ }
+ }
+ else if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE);
+ axis2_http_sender_set_proxy_auth_type(sender, env, msg_ctx, request);
+ }
+
+ if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code && !test_http_auth)
+ {
+ if(!http_auth_header_added)
+ {
+ if(force_proxy_auth_with_head)
+ {
+ axis2_http_request_line_t *head_request_line = NULL;
+ axis2_http_request_line_t *temp = NULL;
+
+ temp = axis2_http_simple_request_get_request_line(request, env);
+ head_request_line = axis2_http_request_line_create(env, AXIS2_HTTP_HEAD,
+ axis2_http_request_line_get_uri(temp, env),
+ axis2_http_request_line_get_http_version(temp, env));
+ axis2_http_simple_request_set_request_line(request, env, head_request_line);
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ axis2_http_simple_request_set_request_line(request, env, temp);
+ axis2_http_request_line_free(head_request_line, env);
+
+ if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx,
+ request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP Authentication \
+header");
+ }
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ if(status_code == AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL)
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx,
+ request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP \
+Authentication header");
+ }
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+
+ }
+ }
+ else
+ {
+ axis2_status_t auth_status;
+ auth_status = axis2_http_sender_configure_http_auth(sender, env, msg_ctx, request);
+
+ if(auth_status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in setting HTTP Authentication \
+header");
+ }
+
+ status_code = axis2_http_client_send(sender->client, env, request, ssl_pp);
+
+ status_code = axis2_http_client_recieve_header(sender->client, env);
+ }
+
+ if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE);
+ }
+
+ if(AXIS2_HTTP_RESPONSE_PROXY_AUTHENTICATION_REQUIRED_CODE_VAL == status_code)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Proxy Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_FALSE);
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP Authentication failed");
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE);
+ }
+ }
+ else if(AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL == status_code)
+ {
+ axis2_msg_ctx_set_auth_failed(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_required_auth_is_http(msg_ctx, env, AXIS2_TRUE);
+ axis2_http_sender_set_http_auth_type(sender, env, msg_ctx, request);
+ }
+
+ axis2_http_simple_request_free(request, env);
+ request = NULL;
+
+ if(output_stream)
+ {
+ AXIS2_FREE(env->allocator, output_stream);
+ output_stream = NULL;
+ }
+
+ if(status_code < 0)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "status_code < 0");
+ return AXIS2_FAILURE;
+ }
+
+ axis2_msg_ctx_set_status_code(msg_ctx, env, status_code);
+
+ /* Start processing response */
+ response = axis2_http_client_get_response(sender->client, env);
+ if(!is_soap)
+ {
+ return axis2_http_sender_process_response(sender, env, msg_ctx, response);
+ }
+ else if(AXIS2_HTTP_RESPONSE_OK_CODE_VAL == status_code || AXIS2_HTTP_RESPONSE_ACK_CODE_VAL
+ == status_code)
+ {
+ return axis2_http_sender_process_response(sender, env, msg_ctx, response);
+ }
+ else if(AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL == status_code)
+ {
+ axis2_http_header_t *tmp_header = NULL;
+ axis2_char_t *tmp_header_val = NULL;
+ axis2_op_t *op = NULL;
+
+ op = axis2_msg_ctx_get_op(msg_ctx, env);
+ if(op)
+ {
+ const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ /* handle one way case */
+
+ if(!axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "mep is AXIS2_MEP_URI_OUT_ONLY");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ /* set an error to indicate error code status */
+ tmp_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_CONTENT_TYPE);
+ if(tmp_header)
+ {
+ tmp_header_val = axis2_http_header_get_value(tmp_header, env);
+ }
+
+ if(tmp_header_val && (axutil_strstr(tmp_header_val, AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP)
+ || axutil_strstr(tmp_header_val, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML)))
+ {
+ return axis2_http_sender_process_response(sender, env, msg_ctx, response);
+ }
+ }
+
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_sender_send");
+ return AXIS2_FAILURE;
+}
+#endif
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_set_chunked(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_bool_t chunked)
+{
+ sender->chunked = chunked;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_set_om_output(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axiom_output_t * om_output)
+{
+ sender->om_output = om_output;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_get_header_info(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_response_t * response)
+{
+ axutil_array_list_t *headers = NULL;
+ axis2_char_t *charset = NULL;
+ int i = 0;
+ axis2_bool_t response_chunked = AXIS2_FALSE;
+ int *content_length = NULL;
+ axutil_property_t *property = NULL;
+ axis2_char_t *content_type = NULL;
+ int status_code = 0;
+ axis2_bool_t set_cookie_header_present = AXIS2_FALSE;
+ axis2_bool_t connection_header_present = AXIS2_FALSE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, sender, AXIS2_FAILURE);
+
+ headers = axis2_http_simple_response_get_headers(response, env);
+ if(headers == NULL)
+ {
+ return AXIS2_SUCCESS;
+ }
+
+ for(i = 0; i < axutil_array_list_size(headers, env); i++)
+ {
+ axis2_http_header_t *header = axutil_array_list_get(headers, env, i);
+ axis2_char_t *name = axis2_http_header_get_name((axis2_http_header_t *)header, env);
+ if(name)
+ {
+ if(0 == axutil_strcasecmp(name, AXIS2_HTTP_HEADER_TRANSFER_ENCODING) && 0
+ == axutil_strcasecmp(axis2_http_header_get_value(header, env),
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ axis2_char_t *transfer_encoding = NULL;
+ transfer_encoding = axutil_strdup(env, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED);
+ response_chunked = AXIS2_TRUE;
+ axis2_msg_ctx_set_transfer_encoding(msg_ctx, env, transfer_encoding);
+
+ }
+ if(0 != axutil_strcasecmp(name, AXIS2_HTTP_HEADER_CONTENT_TYPE))
+ {
+ axis2_char_t *tmp_charset = NULL;
+ axis2_char_t *content_type = axis2_http_header_get_value(header, env);
+ tmp_charset = strstr(content_type, AXIS2_HTTP_CHAR_SET_ENCODING);
+ if(charset)
+ {
+ charset = axutil_strdup(env, tmp_charset);
+ break;
+ }
+ }
+ if(!axutil_strcasecmp(name, AXIS2_HTTP_HEADER_SET_COOKIE))
+ {
+ axis2_char_t *cookie_str = axis2_http_header_get_value(header, env);
+ if(cookie_str)
+ {
+ axis2_http_transport_utils_store_cookie(env, msg_ctx, cookie_str);
+ }
+ set_cookie_header_present = AXIS2_TRUE;
+ }
+
+ if(!axutil_strcasecmp(name, AXIS2_HTTP_HEADER_CONNECTION))
+ {
+ axis2_char_t *connection_header_value = NULL;
+ axutil_property_t *connection_map_property = NULL;
+ axutil_hash_t *connection_map = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ connection_header_present = AXIS2_TRUE;
+ connection_header_value = axis2_http_header_get_value(header, env);
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_HTTP_CONNECTION_MAP);
+
+ if(connection_map_property)
+ {
+ connection_map = axutil_property_get_value(connection_map_property, env);
+ }
+ /**
+ * In HTTP1.1 if connection header has value close then drop the connection
+ */
+ if(connection_header_value && !axutil_strcasecmp(connection_header_value, "close"))
+ {
+ if(connection_map)
+ {
+ axis2_http_sender_connection_map_remove(connection_map, env,
+ msg_ctx, sender->client);
+ }
+ }
+ else if(connection_header_value && !axutil_strcasecmp(connection_header_value,
+ "Keep-Alive"))
+ {
+ if(connection_map)
+ {
+ axis2_http_sender_connection_map_add(connection_map, env,
+ msg_ctx, sender->client);
+ }
+ }
+ } /* End if name is connection */
+ } /* End if name of the header present */
+ }
+ if(!set_cookie_header_present) /* We need to remove any cookie set previously for this endpoint */
+ {
+ axis2_http_transport_utils_store_cookie(env, msg_ctx, NULL);
+ }
+ if(!connection_header_present) /* No connection header present */
+ {
+ /** In HTTP1.0 if there is no keep alive header sent back from server we drop the
+ * connection
+ */
+ axutil_property_t *connection_map_property = NULL;
+ axutil_hash_t *connection_map = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+
+ connection_map_property = axis2_conf_ctx_get_property(conf_ctx, env,
+ AXIS2_HTTP_CONNECTION_MAP);
+ if(connection_map_property)
+ {
+ connection_map = axutil_property_get_value(connection_map_property, env);
+ } /* End if connectin_map_property */
+ if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_10))
+ {
+ if(connection_map)
+ {
+ axis2_http_sender_connection_map_remove(connection_map, env, msg_ctx,
+ sender->client);
+ }
+ } /* End if http version 1.0 */
+ else if(!axutil_strcasecmp(sender->http_version, AXIS2_HTTP_HEADER_PROTOCOL_11))
+ {
+ /**
+ * If keep alive enabled we store the http client for reuse.
+ */
+ if(connection_map)
+ {
+ axis2_http_sender_connection_map_add(connection_map, env, msg_ctx,
+ sender->client);
+ }
+ } /* End if http version 1.1 */
+ } /* End if !connection_header_present */
+
+ content_type = (axis2_char_t *)axis2_http_simple_response_get_content_type(response, 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);
+ }
+ }
+
+ if(charset)
+ {
+ axis2_ctx_t *axis_ctx = axis2_op_ctx_get_base(axis2_msg_ctx_get_op_ctx(msg_ctx, env), env);
+ if(axis_ctx)
+ {
+ property = axutil_property_create(env);
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value(property, env, charset);
+ axis2_ctx_set_property(axis_ctx, env, AXIS2_CHARACTER_SET_ENCODING, property);
+ }
+ }
+
+ if(AXIS2_FALSE == response_chunked)
+ {
+ int tmp_len = 0;
+ content_length = AXIS2_MALLOC(env->allocator, sizeof(int));
+ if(!content_length)
+ {
+ return AXIS2_FAILURE;
+ }
+ tmp_len = axis2_http_simple_response_get_content_length(response, env);
+ memcpy(content_length, &tmp_len, sizeof(int));
+ property = axutil_property_create(env);
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value(property, env, content_length);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, property);
+ }
+
+ status_code = axis2_http_simple_response_get_status_code(response, env);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_process_response(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_response_t * response)
+{
+ axutil_stream_t *in_stream = NULL;
+ axutil_property_t *property = NULL;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_sender_process_response");
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE);
+
+ in_stream = axis2_http_simple_response_get_body(response, env);
+ if(!in_stream)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_STREAM_IN_RESPONSE_BODY, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+
+ axis2_http_sender_get_header_info(sender, env, msg_ctx, response);
+ axis2_msg_ctx_set_http_output_headers(msg_ctx, env, axis2_http_simple_response_extract_headers(
+ response, env));
+ property = axutil_property_create(env);
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_free_func(property, env, axutil_stream_free_void_arg);
+ axutil_property_set_value(property, env, in_stream);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property);
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_sender_process_response");
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_get_timeout_values(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_char_t *so_str = NULL;
+ axis2_char_t *connection_str = NULL;
+ axutil_param_t *tmp_param = NULL;
+ axutil_property_t *property = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, sender, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ /* 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)
+ {
+ sender->so_timeout = AXIS2_ATOI(value);
+ return AXIS2_SUCCESS;
+ }
+ }
+
+ tmp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_HTTP_SO_TIMEOUT);
+
+ if(tmp_param)
+ {
+ so_str = (axis2_char_t *)axutil_param_get_value(tmp_param, env);
+ if(so_str)
+ {
+ sender->so_timeout = AXIS2_ATOI(so_str);
+ return AXIS2_SUCCESS;
+ }
+ }
+
+ tmp_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_HTTP_CONNECTION_TIMEOUT);
+ if(tmp_param)
+ {
+ connection_str = (axis2_char_t *)axutil_param_get_value(tmp_param, env);
+ if(connection_str)
+ {
+ sender->so_timeout = AXIS2_ATOI(connection_str);
+ return AXIS2_SUCCESS;
+ }
+ }
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_http_sender_set_http_version(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_char_t * version)
+{
+ sender->http_version = axutil_strdup(env, version);
+ if(!sender->http_version)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static void
+axis2_http_sender_add_header_list(
+ axis2_http_simple_request_t * request,
+ const axutil_env_t * env,
+ axutil_array_list_t * array_list)
+{
+ int ii = 0;
+ int kk = 0;
+ axis2_http_header_t *http_header = NULL;
+ ii = axutil_array_list_size(array_list, env);
+ for(; kk < ii; kk++)
+ {
+ http_header = (axis2_http_header_t *)axutil_array_list_get(array_list, env, kk);
+ axis2_http_simple_request_add_header(request, env, http_header);
+ }
+}
+
+static axis2_status_t
+axis2_http_sender_configure_proxy(
+ axis2_http_sender_t * sender,
+ 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;
+ axis2_char_t *proxy_host = NULL;
+ axis2_char_t *proxy_port = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ if(!conf_ctx)
+ {
+ return AXIS2_FAILURE;
+ }
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(!conf)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ if(!trans_desc)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ 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 *host_attr = NULL;
+ axiom_attribute_t *port_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING);
+ if(!obj)
+ {
+ return AXIS2_FAILURE;
+ }
+ host_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ if(!host_attr)
+ {
+ return AXIS2_FAILURE;
+ }
+ proxy_host = axiom_attribute_get_value(host_attr, env);
+ if(!proxy_host)
+ {
+ return AXIS2_FAILURE;
+ }
+ /* Now we get the port */
+ obj = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING);
+ port_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ if(!port_attr)
+ {
+ return AXIS2_FAILURE;
+ }
+ proxy_port = axiom_attribute_get_value(port_attr, env);
+ if(!proxy_port)
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ }
+ if(proxy_port && proxy_host)
+ {
+ axis2_http_client_set_proxy(sender->client, env, proxy_host, AXIS2_ATOI(proxy_port));
+ }
+ return AXIS2_SUCCESS;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_server_cert(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axutil_property_t *server_cert_property = NULL;
+ axutil_param_t *server_cert_param = NULL;
+ axis2_char_t *server_cert = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ server_cert_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_SERVER_CERT);
+ if(server_cert_property)
+ {
+ server_cert = (axis2_char_t *)axutil_property_get_value(server_cert_property, env);
+ }
+ else
+ {
+ server_cert_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_SERVER_CERT);
+ if(server_cert_param)
+ {
+ server_cert = (axis2_char_t *)axutil_param_get_value(server_cert_param, env);
+ }
+ }
+
+ if(server_cert)
+ {
+ status = axis2_http_client_set_server_cert(sender->client, env, server_cert);
+ }
+
+ return status;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_key_file(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axutil_property_t *key_file_property = NULL;
+ axutil_param_t *key_file_param = NULL;
+ axis2_char_t *key_file = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ key_file_property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_SSL_KEY_FILE);
+ if(key_file_property)
+ {
+ key_file = (axis2_char_t *)axutil_property_get_value(key_file_property, env);
+ }
+ else
+ {
+ key_file_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_SSL_KEY_FILE);
+ if(key_file_param)
+ {
+ key_file = (axis2_char_t *)axutil_param_get_value(key_file_param, env);
+ }
+ }
+
+ if(key_file)
+ {
+ status = axis2_http_client_set_key_file(sender->client, env, key_file);
+ }
+
+ return status;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_http_basic_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axutil_property_t *http_auth_un = NULL;
+ axutil_property_t *http_auth_pw = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+
+ http_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME);
+ http_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD);
+ if(http_auth_un && http_auth_pw)
+ {
+ uname = (axis2_char_t *)axutil_property_get_value(http_auth_un, env);
+ passwd = (axis2_char_t *)axutil_property_get_value(http_auth_pw, env);
+ }
+ if(!uname || !passwd)
+ {
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *http_auth_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+
+ 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)
+ {
+ http_auth_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_HTTP_AUTHENTICATION);
+ if(http_auth_param)
+ {
+ transport_attrs = axutil_param_get_attributes(http_auth_param, env);
+ if(transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_USERNAME,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(username_attr)
+ {
+ uname = axiom_attribute_get_value(username_attr, env);
+ }
+ obj = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_PASSWORD,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(password_attr)
+ {
+ passwd = axiom_attribute_get_value(password_attr, env);
+ }
+ }
+ }
+ }
+ }
+ if(uname && passwd)
+ {
+ int elen;
+ int plen = axutil_strlen(uname) + axutil_strlen(passwd) + 1;
+ axis2_char_t *to_encode = (axis2_char_t *)(AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * plen + 1));
+ axis2_char_t *encoded = NULL;
+ axis2_char_t *auth_str = NULL;
+ sprintf(to_encode, "%s:%s", uname, passwd);
+ elen = axutil_base64_encode_len(plen);
+ encoded = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * elen));
+ auth_str
+ = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 6)));
+ axutil_base64_encode(encoded, to_encode, plen);
+ sprintf(auth_str, "%s %s", AXIS2_HTTP_AUTH_TYPE_BASIC, encoded);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_AUTHORIZATION, auth_str);
+
+ AXIS2_FREE(env->allocator, to_encode);
+ to_encode = NULL;
+ AXIS2_FREE(env->allocator, encoded);
+ encoded = NULL;
+ AXIS2_FREE(env->allocator, auth_str);
+ auth_str = NULL;
+
+ return AXIS2_SUCCESS;
+ }
+
+ return AXIS2_FAILURE;
+
+}
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_basic_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axutil_property_t *proxy_auth_un = NULL;
+ axutil_property_t *proxy_auth_pw = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+
+ proxy_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME);
+ proxy_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD);
+
+ if(proxy_auth_un && proxy_auth_pw)
+ {
+ uname = (axis2_char_t *)axutil_property_get_value(proxy_auth_un, env);
+ passwd = (axis2_char_t *)axutil_property_get_value(proxy_auth_pw, env);
+ }
+ if(!uname || !passwd)
+ {
+ 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;
+
+ 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 *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(username_attr)
+ {
+ uname = axiom_attribute_get_value(username_attr, env);
+ }
+ obj = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(password_attr)
+ {
+ passwd = axiom_attribute_get_value(password_attr, env);
+ }
+ }
+ }
+ }
+ }
+ if(uname && passwd)
+ {
+ int elen;
+ int plen = axutil_strlen(uname) + axutil_strlen(passwd) + 1;
+ axis2_char_t *to_encode = (axis2_char_t *)(AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * plen + 1));
+ axis2_char_t *encoded = NULL;
+ axis2_char_t *auth_str = NULL;
+ sprintf(to_encode, "%s:%s", uname, passwd);
+ elen = axutil_base64_encode_len(plen);
+ encoded = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * elen));
+ auth_str
+ = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 6)));
+ axutil_base64_encode(encoded, to_encode, plen);
+ sprintf(auth_str, "%s %s", AXIS2_PROXY_AUTH_TYPE_BASIC, encoded);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_PROXY_AUTHORIZATION,
+ auth_str);
+
+ AXIS2_FREE(env->allocator, to_encode);
+ to_encode = NULL;
+ AXIS2_FREE(env->allocator, encoded);
+ encoded = NULL;
+ AXIS2_FREE(env->allocator, auth_str);
+ auth_str = NULL;
+
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_http_digest_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_data)
+{
+ axutil_property_t *http_auth_un = NULL;
+ axutil_property_t *http_auth_pw = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+
+ if(!header_data || !*header_data)
+ return AXIS2_FAILURE;
+
+ http_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_UNAME);
+ http_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HTTP_AUTH_PASSWD);
+ if(http_auth_un && http_auth_pw)
+ {
+ uname = (axis2_char_t *)axutil_property_get_value(http_auth_un, env);
+ passwd = (axis2_char_t *)axutil_property_get_value(http_auth_pw, env);
+ }
+ if(!uname || !passwd)
+ {
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axutil_param_t *http_auth_param = NULL;
+ axutil_hash_t *transport_attrs = NULL;
+
+ 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)
+ {
+ http_auth_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(trans_desc, env), env,
+ AXIS2_HTTP_AUTHENTICATION);
+ if(http_auth_param)
+ {
+ transport_attrs = axutil_param_get_attributes(http_auth_param, env);
+ if(transport_attrs)
+ {
+ axutil_generic_obj_t *obj = NULL;
+ axiom_attribute_t *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_USERNAME,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(username_attr)
+ {
+ uname = axiom_attribute_get_value(username_attr, env);
+ }
+ obj = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_AUTHENTICATION_PASSWORD,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(password_attr)
+ {
+ passwd = axiom_attribute_get_value(password_attr, env);
+ }
+ }
+ }
+ }
+ }
+ if(uname && passwd)
+ {
+ int elen = 0; /* length of header content */
+ int print_const = 5; /* constant accounts for printing the
+ quoatation marks, comma, and space */
+ int response_length = 32;
+ axis2_char_t *temp = NULL;
+ axis2_char_t *alloc_temp = NULL;
+ axis2_char_t *algo = AXIS2_HTTP_AUTHORIZATION_REQUEST_ALGORITHM_MD5;
+ axis2_char_t *realm = NULL;
+ axis2_char_t *qop = NULL;
+ axis2_char_t *nonce = NULL;
+ axis2_char_t *opaque = NULL;
+ axis2_char_t *cnonce = NULL;
+ axis2_char_t *nc = NULL;
+ axutil_digest_hash_hex_t h_a1;
+ axutil_digest_hash_hex_t h_a2;
+ axutil_digest_hash_hex_t response;
+ axis2_char_t *auth_str = NULL;
+ axutil_property_t *method = NULL;
+ axis2_char_t *method_value = NULL;
+ axis2_char_t *url = NULL;
+
+ url = axis2_http_request_line_get_uri(axis2_http_simple_request_get_request_line(request,
+ env), env);
+
+ if(!url)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI)
+ + axutil_strlen(url);
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME)
+ + axutil_strlen(uname);
+
+ 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);
+ }
+ else
+ {
+ method_value = AXIS2_HTTP_POST;
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM);
+ if(temp)
+ {
+ realm = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(realm)
+ {
+ realm++;
+ temp = axutil_strchr(realm, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - realm + 1)));
+ strncpy(alloc_temp, realm, (temp - realm));
+ if(alloc_temp)
+ alloc_temp[temp - realm] = AXIS2_ESC_NULL;
+ realm = alloc_temp;
+ alloc_temp = NULL;
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM)
+ + axutil_strlen(realm);
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP);
+ if(temp)
+ {
+ qop = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(qop)
+ {
+ qop++;
+ temp = axutil_strchr(qop, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - qop + 1)));
+ strncpy(alloc_temp, qop, (temp - qop));
+ if(alloc_temp)
+ alloc_temp[temp - qop] = AXIS2_ESC_NULL;
+ qop = alloc_temp;
+ alloc_temp = NULL;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE);
+ if(temp)
+ {
+ nonce = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(nonce)
+ {
+ nonce++;
+ temp = axutil_strchr(nonce, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - nonce + 1)));
+ strncpy(alloc_temp, nonce, (temp - nonce));
+ if(alloc_temp)
+ alloc_temp[temp - nonce] = AXIS2_ESC_NULL;
+ nonce = alloc_temp;
+ alloc_temp = NULL;
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE)
+ + axutil_strlen(nonce);
+ }
+ else
+ {
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE);
+ if(temp)
+ {
+ opaque = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(opaque)
+ {
+ opaque++;
+ temp = axutil_strchr(opaque, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - opaque + 1)));
+ strncpy(alloc_temp, opaque, (temp - opaque));
+ if(alloc_temp)
+ alloc_temp[temp - opaque] = AXIS2_ESC_NULL;
+ opaque = alloc_temp;
+ alloc_temp = NULL;
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE)
+ + axutil_strlen(opaque);
+ }
+ else
+ {
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ if(nonce)
+ AXIS2_FREE(env->allocator, nonce);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ if(qop)
+ {
+ nc = AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE;
+ temp = qop;
+ if(!axutil_strstr(temp, AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH))
+ {
+ return AXIS2_FAILURE;
+ }
+ AXIS2_FREE(env->allocator, qop);
+ qop = AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH;
+ temp = axutil_uuid_gen(env);
+ cnonce = temp;
+ temp += CLIENT_NONCE_LENGTH;
+ if(temp)
+ *temp = AXIS2_ESC_NULL;
+ elen += 11 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + CLIENT_NONCE_LENGTH
+ + axutil_strlen(qop);
+ }
+
+ axutil_digest_calc_get_h_a1(env, algo, uname, realm, passwd, cnonce, nonce, h_a1);
+ axutil_digest_calc_get_response(env, h_a1, nonce, nc, cnonce, qop, method_value, url, h_a2,
+ response);
+
+ elen += 4 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE) + axutil_strlen(
+ AXIS2_HTTP_AUTH_TYPE_DIGEST) + response_length;
+
+ auth_str
+ = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 1)));
+ temp = auth_str;
+ sprintf(temp, "%s %s=\"%s\", ", AXIS2_HTTP_AUTH_TYPE_DIGEST,
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME, uname);
+ temp += ((int)strlen(AXIS2_HTTP_AUTH_TYPE_DIGEST) + (int)strlen(
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME) + (int)strlen(uname) + 6);
+ if(realm)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM, realm);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM) + (int)strlen(realm)
+ + 5);
+ }
+ if(nonce)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE, nonce);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE) + (int)strlen(nonce)
+ + 5);
+ }
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI, url);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI) + (int)strlen(url) + 5);
+ if(qop)
+ {
+ sprintf(temp, "%s=%s, %s=%s, %s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP,
+ qop, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT, nc,
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE, cnonce);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + (int)strlen(qop)
+ + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT) + (int)strlen(nc)
+ + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE) + (int)strlen(
+ cnonce) + 11);
+ }
+ if(opaque)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE, opaque);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE) + (int)strlen(
+ opaque) + 5);
+ }
+ sprintf(temp, "%s=\"%s\"", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE, response);
+
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_AUTHORIZATION, auth_str);
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ if(nonce)
+ AXIS2_FREE(env->allocator, nonce);
+ if(cnonce)
+ AXIS2_FREE(env->allocator, cnonce);
+ if(opaque)
+ AXIS2_FREE(env->allocator, opaque);
+ if(auth_str)
+ AXIS2_FREE(env->allocator, auth_str);
+ auth_str = NULL;
+
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_digest_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_data)
+{
+ axutil_property_t *proxy_auth_un = NULL;
+ axutil_property_t *proxy_auth_pw = NULL;
+ axis2_char_t *uname = NULL;
+ axis2_char_t *passwd = NULL;
+
+ if(!header_data || !*header_data)
+ return AXIS2_FAILURE;
+
+ proxy_auth_un = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_UNAME);
+ proxy_auth_pw = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_PROXY_AUTH_PASSWD);
+
+ if(proxy_auth_un && proxy_auth_pw)
+ {
+ uname = (axis2_char_t *)axutil_property_get_value(proxy_auth_un, env);
+ passwd = (axis2_char_t *)axutil_property_get_value(proxy_auth_pw, env);
+ }
+ if(!uname || !passwd)
+ {
+ 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;
+
+ 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 *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_USERNAME,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ username_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(username_attr)
+ {
+ uname = axiom_attribute_get_value(username_attr, env);
+ }
+
+ obj = NULL;
+ obj = axutil_hash_get(transport_attrs, AXIS2_HTTP_PROXY_PASSWORD,
+ AXIS2_HASH_KEY_STRING);
+ if(obj)
+ {
+ password_attr = (axiom_attribute_t *)axutil_generic_obj_get_value(obj, env);
+ }
+ if(password_attr)
+ {
+ passwd = axiom_attribute_get_value(password_attr, env);
+ }
+ }
+ }
+ }
+ }
+ if(uname && passwd)
+ {
+ int elen = 0; /* length of header content */
+ int print_const = 5; /* constant accounts for printing the
+ quoatation marks, comma, and space */
+ int response_length = 32;
+ axis2_char_t *temp = NULL;
+ axis2_char_t *alloc_temp = NULL;
+ axis2_char_t *algo = AXIS2_HTTP_AUTHORIZATION_REQUEST_ALGORITHM_MD5;
+ axis2_char_t *realm = NULL;
+ axis2_char_t *qop = NULL;
+ axis2_char_t *nonce = NULL;
+ axis2_char_t *opaque = NULL;
+ axis2_char_t *cnonce = NULL;
+ axis2_char_t *nc = NULL;
+ axutil_digest_hash_hex_t h_a1;
+ axutil_digest_hash_hex_t h_a2;
+ axutil_digest_hash_hex_t response;
+ axis2_char_t *auth_str = NULL;
+ axutil_property_t *method = NULL;
+ axis2_char_t *method_value = NULL;
+ axis2_char_t *url = NULL;
+
+ url = axis2_http_request_line_get_uri(axis2_http_simple_request_get_request_line(request,
+ env), env);
+
+ if(!url)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI)
+ + axutil_strlen(url);
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME)
+ + axutil_strlen(uname);
+
+ 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);
+ }
+ else
+ {
+ method_value = AXIS2_HTTP_POST;
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM);
+ if(temp)
+ {
+ realm = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(realm)
+ {
+ realm++;
+ temp = axutil_strchr(realm, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - realm + 1)));
+ strncpy(alloc_temp, realm, (temp - realm));
+ if(alloc_temp)
+ alloc_temp[temp - realm] = AXIS2_ESC_NULL;
+ realm = alloc_temp;
+ alloc_temp = NULL;
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM)
+ + axutil_strlen(realm);
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP);
+ if(temp)
+ {
+ qop = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(qop)
+ {
+ qop++;
+ temp = axutil_strchr(qop, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - qop + 1)));
+ strncpy(alloc_temp, qop, (temp - qop));
+ if(alloc_temp)
+ alloc_temp[temp - qop] = AXIS2_ESC_NULL;
+ qop = alloc_temp;
+ alloc_temp = NULL;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE);
+ if(temp)
+ {
+ nonce = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(nonce)
+ {
+ nonce++;
+ temp = axutil_strchr(nonce, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - nonce + 1)));
+ strncpy(alloc_temp, nonce, (temp - nonce));
+ if(alloc_temp)
+ alloc_temp[temp - nonce] = AXIS2_ESC_NULL;
+ nonce = alloc_temp;
+ alloc_temp = NULL;
+
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE)
+ + axutil_strlen(nonce);
+ }
+ else
+ {
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ temp = axutil_strstr(header_data, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE);
+ if(temp)
+ {
+ opaque = axutil_strchr(temp, AXIS2_ESC_DOUBLE_QUOTE);
+ if(opaque)
+ {
+ opaque++;
+ temp = axutil_strchr(opaque, AXIS2_ESC_DOUBLE_QUOTE);
+ alloc_temp = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
+ * (temp - opaque + 1)));
+ strncpy(alloc_temp, opaque, (temp - opaque));
+ if(alloc_temp)
+ alloc_temp[temp - opaque] = AXIS2_ESC_NULL;
+ opaque = alloc_temp;
+ alloc_temp = NULL;
+ elen += print_const + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE)
+ + axutil_strlen(opaque);
+ }
+ else
+ {
+ if(realm)
+ AXIS2_FREE(env->allocator, realm);
+ if(nonce)
+ AXIS2_FREE(env->allocator, nonce);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ if(qop)
+ {
+ nc = AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE;
+ temp = qop;
+ if(!axutil_strstr(temp, AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH))
+ {
+ return AXIS2_FAILURE;
+ }
+ AXIS2_FREE(env->allocator, qop);
+ qop = AXIS2_HTTP_AUTHORIZATION_REQUEST_QOP_OPTION_AUTH;
+ temp = axutil_uuid_gen(env);
+ cnonce = temp;
+ temp += CLIENT_NONCE_LENGTH;
+ if(temp)
+ *temp = AXIS2_ESC_NULL;
+ elen += 11 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_DEFAULT_CLIENT_NONCE)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE)
+ + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + CLIENT_NONCE_LENGTH
+ + axutil_strlen(qop);
+ }
+
+ axutil_digest_calc_get_h_a1(env, algo, uname, realm, passwd, cnonce, nonce, h_a1);
+ axutil_digest_calc_get_response(env, h_a1, nonce, nc, cnonce, qop, method_value, url, h_a2,
+ response);
+
+ elen += 4 + axutil_strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE) + axutil_strlen(
+ AXIS2_PROXY_AUTH_TYPE_DIGEST) + response_length;
+
+ auth_str
+ = (axis2_char_t *)(AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (elen + 1)));
+ temp = auth_str;
+ sprintf(temp, "%s %s=\"%s\", ", AXIS2_PROXY_AUTH_TYPE_DIGEST,
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME, uname);
+ temp += ((int)strlen(AXIS2_HTTP_AUTH_TYPE_DIGEST) + (int)strlen(
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_USERNAME) + (int)strlen(uname) + 6);
+ if(realm)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM, realm);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_REALM) + (int)strlen(realm)
+ + 5);
+ }
+ if(nonce)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE, nonce);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE) + (int)strlen(nonce)
+ + 5);
+ }
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI, url);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_URI) + (int)strlen(url) + 5);
+ if(qop)
+ {
+ sprintf(temp, "%s=%s, %s=%s, %s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP,
+ qop, AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT, nc,
+ AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE, cnonce);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_QOP) + (int)strlen(qop)
+ + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_NONCE_COUNT) + (int)strlen(nc)
+ + (int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_CLIENT_NONCE) + (int)strlen(
+ cnonce) + 11);
+ }
+ if(opaque)
+ {
+ sprintf(temp, "%s=\"%s\", ", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE, opaque);
+ temp += ((int)strlen(AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_OPAQUE) + (int)strlen(
+ opaque) + 5);
+ }
+ sprintf(temp, "%s=\"%s\"", AXIS2_HTTP_AUTHORIZATION_REQUEST_PARAM_RESPONSE, response);
+ axis2_http_sender_util_add_header(env, request, AXIS2_HTTP_HEADER_PROXY_AUTHORIZATION,
+ auth_str);
+ if(realm)
+ {
+ AXIS2_FREE(env->allocator, realm);
+ }
+
+ if(nonce)
+ {
+ AXIS2_FREE(env->allocator, nonce);
+ }
+
+ if(cnonce)
+ {
+ AXIS2_FREE(env->allocator, cnonce);
+ }
+
+ if(opaque)
+ {
+ AXIS2_FREE(env->allocator, opaque);
+ }
+
+ if(auth_str)
+ {
+ AXIS2_FREE(env->allocator, auth_str);
+ }
+
+ auth_str = NULL;
+
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_configure_http_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axis2_char_t *auth_type = NULL;
+ axis2_status_t status = AXIS2_FALSE;
+ axutil_property_t *http_auth_property = NULL;
+ axis2_char_t *http_auth_property_value = NULL;
+ axis2_bool_t force_http_auth = AXIS2_FALSE;
+ axutil_property_t *http_auth_type_property = NULL;
+ axis2_char_t *http_auth_type_property_value = NULL;
+ axis2_char_t *auth_type_end = NULL;
+
+ http_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_FORCE_HTTP_AUTH);
+ if(http_auth_property)
+ {
+ http_auth_property_value = (axis2_char_t *)axutil_property_get_value(http_auth_property,
+ env);
+ }
+
+ if(http_auth_property_value && 0 == axutil_strcmp(http_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ force_http_auth = AXIS2_TRUE;
+ }
+
+ if(force_http_auth)
+ {
+ http_auth_type_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_HTTP_AUTH_TYPE);
+ if(http_auth_type_property)
+ {
+ http_auth_type_property_value = (axis2_char_t *)axutil_property_get_value(
+ http_auth_type_property, env);
+ }
+
+ if(http_auth_type_property_value)
+ {
+ auth_type = http_auth_type_property_value;
+ }
+ }
+ if(!force_http_auth || axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0)
+ {
+ axis2_http_header_t *auth_header = NULL;
+ axis2_http_simple_response_t *response = NULL;
+
+ response = axis2_http_client_get_response(sender->client, env);
+
+ if(response)
+ {
+ auth_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_WWW_AUTHENTICATE);
+ }
+
+ if(auth_header)
+ {
+ auth_type = axis2_http_header_get_value(auth_header, env);
+ }
+
+ if(auth_type)
+ {
+ auth_type_end = axutil_strchr(auth_type, ' ');
+ *auth_type_end = AXIS2_ESC_NULL;
+ auth_type_end++;
+ /*Read the realm and the rest stuff now from auth_type_end */
+ }
+ if(force_http_auth && axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) != 0)
+ {
+ auth_type = NULL;
+ }
+ }
+ if(auth_type)
+ {
+ if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0)
+ {
+ status = axis2_http_sender_configure_http_basic_auth(sender, env, msg_ctx, request);
+ }
+ else if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0)
+ {
+ status = axis2_http_sender_configure_http_digest_auth(sender, env, msg_ctx, request,
+ auth_type_end);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not"
+ "supported", auth_type);
+ }
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ }
+
+ return status;
+}
+
+static axis2_status_t
+axis2_http_sender_configure_proxy_auth(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axis2_char_t *auth_type = NULL;
+ axis2_status_t status = AXIS2_FALSE;
+ axutil_property_t *proxy_auth_property = NULL;
+ axis2_char_t *proxy_auth_property_value = NULL;
+ axis2_bool_t force_proxy_auth = AXIS2_FALSE;
+ axutil_property_t *proxy_auth_type_property = NULL;
+ axis2_char_t *proxy_auth_type_property_value = NULL;
+ axis2_char_t *auth_type_end = NULL;
+
+ proxy_auth_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_FORCE_PROXY_AUTH);
+ if(proxy_auth_property)
+ {
+ proxy_auth_property_value = (axis2_char_t *)axutil_property_get_value(proxy_auth_property,
+ env);
+ }
+
+ if(proxy_auth_property_value && 0 == axutil_strcmp(proxy_auth_property_value, AXIS2_VALUE_TRUE))
+ {
+ force_proxy_auth = AXIS2_TRUE;
+ }
+
+ if(force_proxy_auth)
+ {
+ proxy_auth_type_property = (axutil_property_t *)axis2_msg_ctx_get_property(msg_ctx, env,
+ AXIS2_PROXY_AUTH_TYPE);
+ if(proxy_auth_type_property)
+ {
+ proxy_auth_type_property_value = (axis2_char_t *)axutil_property_get_value(
+ proxy_auth_type_property, env);
+ }
+
+ if(proxy_auth_type_property_value)
+ {
+ auth_type = proxy_auth_type_property_value;
+ }
+ }
+ else
+ {
+ axis2_http_header_t *auth_header = NULL;
+ axis2_http_simple_response_t *response = NULL;
+
+ response = axis2_http_client_get_response(sender->client, env);
+
+ if(response)
+ {
+ auth_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_PROXY_AUTHENTICATE);
+ }
+
+ if(auth_header)
+ {
+ auth_type = axis2_http_header_get_value(auth_header, env);
+ }
+
+ if(auth_type)
+ {
+ auth_type_end = axutil_strchr(auth_type, ' ');
+ *auth_type_end = AXIS2_ESC_NULL;
+ auth_type_end++;
+ /*Read the realm and the rest stuff now from auth_type_end */
+ }
+ }
+ if(auth_type)
+ {
+ if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0)
+ {
+ status = axis2_http_sender_configure_proxy_basic_auth(sender, env, msg_ctx, request);
+ }
+ else if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0)
+ {
+ status = axis2_http_sender_configure_proxy_digest_auth(sender, env, msg_ctx, request,
+ auth_type_end);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type);
+ }
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ }
+
+ return status;
+}
+#endif
+
+#ifndef AXIS2_LIBCURL_ENABLED
+static axis2_status_t
+axis2_http_sender_set_http_auth_type(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axis2_char_t *auth_type = NULL;
+ axis2_status_t status = AXIS2_FALSE;
+ axis2_char_t *auth_type_end = NULL;
+ axis2_http_header_t *auth_header = NULL;
+ axis2_http_simple_response_t *response = NULL;
+
+ response = axis2_http_client_get_response(sender->client, env);
+
+ if(response)
+ {
+ auth_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_WWW_AUTHENTICATE);
+ }
+
+ if(auth_header)
+ {
+ auth_type = axis2_http_header_get_value(auth_header, env);
+ }
+
+ if(auth_type)
+ {
+ auth_type_end = axutil_strchr(auth_type, ' ');
+ *auth_type_end = AXIS2_ESC_NULL;
+ auth_type_end++;
+ /*Read the realm and the rest stuff now from auth_type_end */
+ }
+
+ if(auth_type)
+ {
+ if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0)
+ {
+ status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE_BASIC);
+ }
+ else if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0)
+ {
+ status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_HTTP_AUTH_TYPE_DIGEST);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type);
+ }
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ }
+ return status;
+}
+
+static axis2_status_t
+axis2_http_sender_set_proxy_auth_type(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_http_simple_request_t * request)
+{
+ axis2_char_t *auth_type = NULL;
+ axis2_status_t status = AXIS2_FALSE;
+ axis2_char_t *auth_type_end = NULL;
+ axis2_http_header_t *auth_header = NULL;
+ axis2_http_simple_response_t *response = NULL;
+
+ response = axis2_http_client_get_response(sender->client, env);
+
+ if(response)
+ {
+ auth_header = axis2_http_simple_response_get_first_header(response, env,
+ AXIS2_HTTP_HEADER_PROXY_AUTHENTICATE);
+ }
+
+ if(auth_header)
+ {
+ auth_type = axis2_http_header_get_value(auth_header, env);
+ }
+
+ if(auth_type)
+ {
+ auth_type_end = axutil_strchr(auth_type, ' ');
+ *auth_type_end = AXIS2_ESC_NULL;
+ auth_type_end++;
+ /*Read the realm and the rest stuff now from auth_type_end */
+ }
+
+ if(auth_type)
+ {
+ if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0)
+ {
+ status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_PROXY_AUTH_TYPE_BASIC);
+ }
+ else if(axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0)
+ {
+ status = axis2_msg_ctx_set_auth_type(msg_ctx, env, AXIS2_PROXY_AUTH_TYPE_DIGEST);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Authtype %s is not supported", auth_type);
+ }
+ }
+ else
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ }
+ return status;
+}
+#endif
+
+#ifdef AXIS2_LIBCURL_ENABLED
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_libcurl_http_send (axis2_libcurl_t * curl,
+ axis2_http_sender_t * sender,
+ 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)
+{
+ return axis2_libcurl_send (curl, sender->om_output,
+ env, msg_ctx, out, str_url, soap_action);
+}
+#endif
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_http_sender_get_param_string(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axiom_soap_envelope_t *soap_env = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axiom_node_t *body_node = NULL;
+ axiom_node_t *data_node = NULL;
+ axiom_element_t *data_element = NULL;
+ axiom_child_element_iterator_t *iterator = NULL;
+ axutil_array_list_t *param_list = NULL;
+ axis2_char_t *param_string = NULL;
+ int i = 0;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, NULL);
+
+ soap_env = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
+ if(!soap_env)
+ {
+ return NULL;
+ }
+ soap_body = axiom_soap_envelope_get_body(soap_env, env);
+ body_node = axiom_soap_body_get_base_node(soap_body, env);
+ if(!body_node)
+ {
+ /* This could be the situation where service client does not provide
+ * a xml payload and instead add url parameters to the endpoint url
+ */
+ return NULL;
+ }
+ data_node = axiom_node_get_first_child(body_node, env);
+ if(!data_node)
+ {
+ return NULL;
+ }
+
+ param_list = axutil_array_list_create(env, AXIS2_ARRAY_LIST_DEFAULT_CAPACITY);
+
+ data_element = axiom_node_get_data_element(data_node, env);
+
+ iterator = axiom_element_get_child_elements(data_element, env, data_node);
+
+ if(iterator)
+ {
+ while(AXIS2_TRUE == AXIOM_CHILD_ELEMENT_ITERATOR_HAS_NEXT(iterator, env))
+ {
+ axiom_node_t *node = NULL;
+ axiom_element_t *element = NULL;
+ axis2_char_t *name = NULL;
+ axis2_char_t *value = NULL;
+ axis2_char_t *encoded_value = NULL;
+
+ node = AXIOM_CHILD_ELEMENT_ITERATOR_NEXT(iterator, env);
+ element = axiom_node_get_data_element(node, env);
+ name = axiom_element_get_localname(element, env);
+ value = axiom_element_get_text(element, env, node);
+ if(value)
+ {
+ encoded_value = (axis2_char_t *)AXIS2_MALLOC(env->allocator, strlen(value));
+ memset(encoded_value, 0, strlen(value));
+ encoded_value = axutil_url_encode(env, encoded_value, value, (int)strlen(value));
+ /* We are sure that the difference lies within the int range */
+
+ axutil_array_list_add(param_list, env, axutil_strcat(env, name, "=", encoded_value,
+ NULL));
+ AXIS2_FREE(env->allocator, encoded_value);
+ encoded_value = NULL;
+ }
+ }
+ }
+ for(i = 0; i < axutil_array_list_size(param_list, env); i++)
+ {
+ axis2_char_t *tmp_string = NULL;
+ axis2_char_t *pair = NULL;
+
+ pair = axutil_array_list_get(param_list, env, i);
+ if(i == 0)
+ {
+ tmp_string = axutil_stracat(env, param_string, pair);
+ }
+ else
+ {
+ tmp_string = axutil_strcat(env, param_string, AXIS2_AND_SIGN, pair, NULL);
+ }
+
+ if(param_string)
+ {
+ AXIS2_FREE(env->allocator, param_string);
+ param_string = NULL;
+ }
+ AXIS2_FREE(env->allocator, pair);
+ param_string = tmp_string;
+ }
+ axutil_array_list_free(param_list, env);
+ return param_string;
+}
+
+void AXIS2_CALL
+axis2_http_sender_util_add_header(
+ const axutil_env_t * env,
+ axis2_http_simple_request_t * request,
+ axis2_char_t * header_name,
+ const axis2_char_t * header_value)
+{
+ axis2_http_header_t *http_header;
+ http_header = axis2_http_header_create(env, header_name, header_value);
+ axis2_http_simple_request_add_header(request, env, http_header);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_http_sender_set_keep_alive(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env,
+ axis2_bool_t keep_alive)
+{
+ sender->keep_alive = keep_alive;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_http_sender_get_keep_alive(
+ axis2_http_sender_t * sender,
+ const axutil_env_t * env)
+{
+ return sender->keep_alive;
+}
+
+static axutil_hash_t *
+axis2_http_sender_connection_map_create(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx)
+{
+ axutil_hash_t *connection_map = NULL;
+ connection_map = axutil_hash_make(env);
+ if(!connection_map)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ }
+ else
+ {
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axutil_property_t *connection_map_property = NULL;
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ connection_map_property = axutil_property_create_with_args(env, AXIS2_SCOPE_SESSION,
+ AXIS2_TRUE, axis2_http_sender_connection_map_free, connection_map);
+ axis2_conf_ctx_set_property(conf_ctx, env, AXIS2_HTTP_CONNECTION_MAP,
+ connection_map_property);
+ }
+ return connection_map;
+}
+
+static void
+axis2_http_sender_connection_map_remove(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_http_client_t *http_client)
+{
+ axutil_property_t *property = NULL;
+ axis2_endpoint_ref_t *endpoint = NULL;
+ /**
+ * Put the http client into message context with own value true so that it will be freed
+ * after response processed
+ */
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE,
+ axis2_http_client_free_void_arg, http_client);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_CLIENT, property);
+ endpoint = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(endpoint)
+ {
+ const axis2_char_t *address = NULL;
+ address = axis2_endpoint_ref_get_address(endpoint, env);
+ if(address)
+ {
+ axutil_url_t *url = NULL;
+ url = axutil_url_parse_string(env, address);
+ if(url)
+ {
+ axis2_char_t *server = axutil_url_get_server(url, env);
+ if(server)
+ {
+ axutil_hash_set(connection_map, server, AXIS2_HASH_KEY_STRING, NULL);
+ }
+ axutil_url_free(url, env);
+ }
+ }
+ }
+}
+
+static void
+axis2_http_sender_connection_map_add(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_http_client_t *http_client)
+{
+ axutil_property_t *property = NULL;
+ axis2_endpoint_ref_t *endpoint = NULL;
+ /**
+ * Put the http client into message context. Is this neccessary?
+ */
+ property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE,
+ axis2_http_client_free_void_arg, http_client);
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_CLIENT, property);
+ endpoint = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(endpoint)
+ {
+ const axis2_char_t *address = NULL;
+ address = axis2_endpoint_ref_get_address(endpoint, env);
+ if(address)
+ {
+ axutil_url_t *url = NULL;
+ url = axutil_url_parse_string(env, address);
+ if(url)
+ {
+ axis2_char_t *server = axutil_url_get_server(url, env);
+ if(server)
+ {
+ axutil_hash_set(connection_map, axutil_strdup(env, server),
+ AXIS2_HASH_KEY_STRING, http_client);
+ }
+ axutil_url_free(url, env);
+ }
+ }
+ }
+}
+
+static axis2_http_client_t *
+axis2_http_sender_connection_map_get(
+ axutil_hash_t *connection_map,
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx)
+{
+ axis2_http_client_t *http_client = NULL;
+ axis2_endpoint_ref_t *endpoint = NULL;
+ endpoint = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(endpoint)
+ {
+ const axis2_char_t *address = NULL;
+ address = axis2_endpoint_ref_get_address(endpoint, env);
+ if(address)
+ {
+ axutil_url_t *url = NULL;
+ url = axutil_url_parse_string(env, address);
+ if(url)
+ {
+ axis2_char_t *server = axutil_url_get_server(url, env);
+ if(server)
+ {
+ http_client = axutil_hash_get(connection_map, server, AXIS2_HASH_KEY_STRING);
+ }
+ axutil_url_free(url, env);
+ }
+ }
+ }
+ return http_client;
+}
+
+static void AXIS2_CALL
+axis2_http_sender_connection_map_free(
+ void *cm_void,
+ const axutil_env_t *env)
+{
+ void *val = NULL;
+ const void *key = NULL;
+ axutil_hash_index_t *hi = NULL;
+ axutil_hash_t *ht = (axutil_hash_t *)cm_void;
+
+ for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ axis2_char_t *name = NULL;
+ axis2_http_client_t *value = NULL;
+
+ axutil_hash_this(hi, &key, NULL, &val);
+ name = (axis2_char_t *) key;
+ if(name)
+ {
+ AXIS2_FREE(env->allocator, name);
+ }
+ value = (axis2_http_client_t *) val;
+ if(value)
+ {
+ axis2_http_client_free(value, env);
+ }
+ }
+ axutil_hash_free(ht, env);
+}
+
diff --git a/src/core/transport/http/sender/http_transport_sender.c b/src/core/transport/http/sender/http_transport_sender.c
new file mode 100644
index 0000000..3ef55b0
--- /dev/null
+++ b/src/core/transport/http/sender/http_transport_sender.c
@@ -0,0 +1,859 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <axis2_http_transport_sender.h>
+#include <axutil_string.h>
+#include <axis2_endpoint_ref.h>
+#include <axis2_addr.h>
+#include <axiom_xml_writer.h>
+#include <axiom_output.h>
+#include <axis2_http_transport_utils.h>
+#include <axutil_generic_obj.h>
+#include <axis2_http_out_transport_info.h>
+#include <axis2_http_transport.h>
+#include <axis2_http_sender.h>
+#include <axiom_soap_body.h>
+#include <axutil_types.h>
+#include <axiom_soap_fault_detail.h>
+#include <axis2_msg_ctx.h>
+
+#ifdef AXIS2_LIBCURL_ENABLED
+#include "libcurl/axis2_libcurl.h"
+#endif
+
+/**
+ * HTTP Transport Sender struct impl
+ * Axis2 HTTP Transport Sender impl
+ */
+
+typedef struct axis2_http_transport_sender_impl
+{
+ axis2_transport_sender_t transport_sender;
+ axis2_char_t *http_version;
+ axis2_bool_t chunked;
+ int connection_timeout;
+ int so_timeout;
+ axis2_bool_t keep_alive;
+#ifdef AXIS2_LIBCURL_ENABLED
+ axis2_libcurl_t *libcurl;
+#endif
+} axis2_http_transport_sender_impl_t;
+
+#define AXIS2_WS_RM_ANONYMOUS_URL "http://docs.oasis-open.org/ws-rx/wsmc/200702/anonymous?id="
+#define AXIS2_INTF_TO_IMPL(transport_sender) \
+ ((axis2_http_transport_sender_impl_t *)\
+ (transport_sender))
+
+/***************************** Function headers *******************************/
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_invoke(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_clean_up(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_init(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_transport_out_desc_t * out_desc);
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_write_message(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_endpoint_ref_t * epr,
+ axiom_soap_envelope_t * out,
+ axiom_output_t * om_output);
+
+void AXIS2_CALL axis2_http_transport_sender_free(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env);
+
+static const axis2_transport_sender_ops_t http_transport_sender_ops_var = {
+ axis2_http_transport_sender_init, axis2_http_transport_sender_invoke,
+ axis2_http_transport_sender_clean_up, axis2_http_transport_sender_free };
+
+axis2_transport_sender_t *AXIS2_CALL
+axis2_http_transport_sender_create(
+ const axutil_env_t * env)
+{
+ axis2_http_transport_sender_impl_t *transport_sender_impl = NULL;
+
+ transport_sender_impl = (axis2_http_transport_sender_impl_t *)AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_http_transport_sender_impl_t));
+
+ if(!transport_sender_impl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset((void *)transport_sender_impl, 0, sizeof(axis2_http_transport_sender_impl_t));
+
+ transport_sender_impl->http_version = axutil_strdup(env, AXIS2_HTTP_HEADER_PROTOCOL_11);
+ transport_sender_impl->chunked = AXIS2_TRUE;
+ transport_sender_impl->connection_timeout = AXIS2_HTTP_DEFAULT_CONNECTION_TIMEOUT;
+ transport_sender_impl->so_timeout = AXIS2_HTTP_DEFAULT_SO_TIMEOUT;
+ transport_sender_impl->keep_alive = AXIS2_TRUE;
+ transport_sender_impl->transport_sender.ops = &http_transport_sender_ops_var;
+
+#ifdef AXIS2_LIBCURL_ENABLED
+ transport_sender_impl->libcurl = axis2_libcurl_create(env);
+ if (!transport_sender_impl->libcurl)
+ {
+ AXIS2_FREE(env->allocator, transport_sender_impl);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+#endif
+
+ return &(transport_sender_impl->transport_sender);
+}
+
+void AXIS2_CALL
+axis2_http_transport_sender_free(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env)
+{
+
+ axis2_http_transport_sender_impl_t *transport_sender_impl = NULL;
+ if(!transport_sender)
+ {
+ return;
+ }
+
+ transport_sender_impl = AXIS2_INTF_TO_IMPL(transport_sender);
+
+ if(transport_sender_impl->http_version)
+ {
+ AXIS2_FREE(env->allocator, transport_sender_impl->http_version);
+ transport_sender_impl->http_version = NULL;
+ }
+
+#ifdef AXIS2_LIBCURL_ENABLED
+ if (transport_sender_impl->libcurl)
+ {
+ axis2_libcurl_free(transport_sender_impl->libcurl, env);
+ }
+#endif
+
+ AXIS2_FREE(env->allocator, transport_sender_impl);
+ return;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_invoke(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ const axis2_char_t *char_set_enc = NULL;
+ axutil_string_t *char_set_enc_str = NULL;
+ axis2_endpoint_ref_t *epr = NULL;
+ axis2_char_t *transport_url = NULL;
+ axiom_xml_writer_t *xml_writer = NULL;
+ axiom_output_t *om_output = NULL;
+ axis2_char_t *buffer = NULL;
+ axiom_soap_envelope_t *soap_data_out = NULL;
+ axis2_bool_t do_mtom;
+ axutil_property_t *property = NULL;
+ axiom_node_t *data_out = NULL;
+ int buffer_size = 0;
+ axis2_status_t status = AXIS2_SUCCESS;
+ 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;
+ axis2_bool_t fault = AXIS2_FALSE;
+
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_http_transport_sender_invoke");
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ char_set_enc_str = axis2_msg_ctx_get_charset_encoding(msg_ctx, env);
+ if(char_set_enc_str)
+ {
+ char_set_enc = axutil_string_get_buffer(char_set_enc_str, env);
+ }
+
+ if(!char_set_enc)
+ {
+ axis2_op_ctx_t *op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+ if(op_ctx)
+ {
+ axis2_ctx_t *ctx = axis2_op_ctx_get_base(op_ctx, env);
+ if(ctx)
+ {
+ property = axis2_ctx_get_property(ctx, env, AXIS2_CHARACTER_SET_ENCODING);
+ if(property)
+ {
+ char_set_enc = axutil_property_get_value(property, env);
+ property = NULL;
+ }
+ }
+ }
+ }
+
+ /**
+ * If we still can't find the char set enc we will
+ * use default
+ */
+ if(!char_set_enc)
+ {
+ char_set_enc = AXIS2_DEFAULT_CHAR_SET_ENCODING;
+ }
+
+ do_mtom = axis2_http_transport_utils_do_write_mtom(env, msg_ctx);
+
+ transport_url = axis2_msg_ctx_get_transport_url(msg_ctx, env);
+ if(transport_url)
+ {
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "transport_url:%s", transport_url);
+ epr = axis2_endpoint_ref_create(env, transport_url);
+ }
+ else
+ {
+ /* when transport url is not available in msg_ctx */
+ axis2_endpoint_ref_t *ctx_epr = axis2_msg_ctx_get_to(msg_ctx, env);
+ if(ctx_epr)
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "ctx_epr:%s", axis2_endpoint_ref_get_address(
+ ctx_epr, env));
+
+ if(ctx_epr && axutil_strcmp(AXIS2_WSA_ANONYMOUS_URL_SUBMISSION,
+ axis2_endpoint_ref_get_address(ctx_epr, env)) && axutil_strcmp(AXIS2_WSA_ANONYMOUS_URL,
+ axis2_endpoint_ref_get_address(ctx_epr, env)) && !(axutil_strstr(
+ axis2_endpoint_ref_get_address(ctx_epr, env), AXIS2_WS_RM_ANONYMOUS_URL)))
+ {
+ epr = ctx_epr;
+ }
+ }
+
+ soap_data_out = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
+ if(!soap_data_out)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_SOAP_ENVELOPE_IN_MSG_CTX, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", AXIS2_ERROR_GET_MESSAGE(env->error));
+ return AXIS2_SUCCESS;
+ }
+
+ xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
+ AXIS2_XML_PARSER_TYPE_BUFFER);
+ if(!xml_writer)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Could not create xml_writer for \
+AXIS2_XML_PARSER_TYPE_BUFFER");
+ return AXIS2_FAILURE;
+ }
+
+ om_output = axiom_output_create(env, xml_writer);
+ if(!om_output)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Could not create om_output for xml writer of \
+AXIS2_XML_PARSER_TYPE_BUFFER");
+ axiom_xml_writer_free(xml_writer, env);
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ /* setting SOAP version for OM_OUTPUT. */
+ axiom_output_set_soap11(om_output, env, axis2_msg_ctx_get_is_soap_11(msg_ctx, env));
+
+ /* This is the case where normal client send the requet using a http_client*/
+
+ if(epr)
+ {
+ if(axutil_strcmp(AXIS2_WSA_NONE_URL_SUBMISSION, axis2_endpoint_ref_get_address(epr, env))
+ == 0 || axutil_strcmp(AXIS2_WSA_NONE_URL, axis2_endpoint_ref_get_address(epr, env))
+ == 0)
+ {
+ epr = NULL;
+ }
+ else
+ {
+ status = axis2_http_transport_sender_write_message(transport_sender, env, msg_ctx, epr,
+ soap_data_out, om_output);
+ }
+ }
+
+ /* If no endpoint reference could be derived from the the message context. It could well be the
+ * single channel two way scenario in the application server side send.
+ */
+ if(!epr)
+ {
+ axutil_stream_t *out_stream = axis2_msg_ctx_get_transport_out_stream(msg_ctx, env);
+
+ if(AXIS2_TRUE == axis2_msg_ctx_get_server_side(msg_ctx, env))
+ {
+ axis2_http_out_transport_info_t *out_info = NULL;
+ axis2_bool_t is_soap11 = AXIS2_FALSE;
+ axis2_op_ctx_t *op_ctx = NULL;
+ /*axis2_char_t *header_value = NULL;*/
+
+ out_info = (axis2_http_out_transport_info_t *)axis2_msg_ctx_get_out_transport_info(
+ msg_ctx, env);
+
+ if(!out_info)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_OUT_TRNSPORT_INFO_NULL, AXIS2_FAILURE);
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+ /*header_value = axis2_http_transport_utils_get_session(env, msg_ctx);
+ if(header_value)
+ {
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_COOKIE_HEADER(out_info, env, header_value);
+ }*/
+
+ is_soap11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env);
+
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CHAR_ENCODING(out_info, env, char_set_enc);
+ if(AXIS2_TRUE == is_soap11)
+ {
+ /* SOAP1.1 */
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env,
+ AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML);
+ }
+ else
+ {
+ /* SOAP1.2 */
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env,
+ AXIS2_HTTP_HEADER_ACCEPT_APPL_SOAP);
+ }
+
+ 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)
+ {
+ /* get access to HTTP transport for sending */
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ }
+
+ if(trans_desc)
+ {
+
+ /* accessing parameter in axis2.xml which set to have
+ * an ability to send xml versoin processing
+ * instruction <?xml version = "1.0"?> */
+ 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)
+ {
+ /* Accessing attribute values */
+ 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(AXIS2_TRUE == axis2_msg_ctx_get_doing_rest(msg_ctx, env))
+ {
+ axiom_node_t *body_node = NULL;
+ /* axis2_bool_t fault = AXIS2_FALSE;*/
+ axiom_soap_fault_t *soap_fault;
+ axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_data_out, env);
+ axiom_soap_fault_detail_t *soap_fault_detial;
+
+ if(!soap_body)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL,
+ AXIS2_FAILURE);
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ fault = axiom_soap_body_has_fault(soap_body, env);
+
+ if(fault == AXIS2_TRUE)
+ {
+ soap_fault = axiom_soap_body_get_fault(soap_body, env);
+
+ if(!soap_fault)
+ {
+
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Rest fault has occur, error described below");
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ return AXIS2_FAILURE;
+ }
+
+ soap_fault_detial = axiom_soap_fault_get_detail(soap_fault, env);
+
+ if(!soap_fault_detial)
+ {
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "Returning failure to obtain soap_fault_detail from soap_fault");
+ return AXIS2_FAILURE;
+ }
+
+ body_node = axiom_soap_fault_detail_get_base_node(soap_fault_detial, env);
+ if(!body_node)
+ {
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "failure to get base node from soap_fault_detail.");
+ return AXIS2_FAILURE;
+ }
+
+ }
+ else
+ {
+
+ body_node = axiom_soap_body_get_base_node(soap_body, env);
+ if(!body_node)
+ {
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "failure to get base node from soap_body.");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ data_out = axiom_node_get_first_element(body_node, env);
+
+ if(!data_out || axiom_node_get_node_type(data_out, env) != AXIOM_ELEMENT)
+ {
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "unable to get first element from soap_body, base node.");
+ return AXIS2_FAILURE;
+ }
+
+ axiom_node_serialize(data_out, env, om_output);
+ buffer = (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env);
+ buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env);
+ axutil_stream_write(out_stream, env, buffer, buffer_size);
+ /* Finish Rest Processing */
+
+ }
+ else
+ {
+ axiom_soap_body_t *body = NULL;
+
+ body = axiom_soap_envelope_get_body(soap_data_out, env);
+ fault = axiom_soap_body_has_fault(body, env);
+
+ /* SOAP Processing */
+ axiom_output_set_do_optimize(om_output, env, do_mtom);
+ axiom_soap_envelope_serialize(soap_data_out, env, om_output, AXIS2_FALSE);
+ if(do_mtom && !fault)
+ {
+ axis2_status_t mtom_status = AXIS2_FAILURE;
+ axis2_char_t *content_type = NULL;
+ axutil_array_list_t *mime_parts = NULL;
+
+ /*Create the attachment related data and put them to an
+ *array_list */
+ mtom_status = axiom_output_flush(om_output, env);
+ if(mtom_status == AXIS2_SUCCESS)
+ {
+ mime_parts = axiom_output_get_mime_parts(om_output, env);
+ if(!mime_parts)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Unable to create the mime_part list from om_output");
+ return AXIS2_FAILURE;
+ }
+ else
+ {
+ axis2_msg_ctx_set_mime_parts(msg_ctx, env, mime_parts);
+ }
+ }
+ /*om_out put has the details of content_type */
+ content_type = (axis2_char_t *)axiom_output_get_content_type(om_output, env);
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(out_info, env, content_type);
+ }
+ else
+ {
+ buffer = (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env);
+ buffer_size = axiom_xml_writer_get_xml_size(xml_writer, env);
+
+ /* This is where it actually fill the buffer in out_stream. In application server
+ * side this is the out_stream passed to the in message context from http_worker
+ * function and then copied to the out message context.
+ */
+ axutil_stream_write(out_stream, env, buffer, buffer_size);
+ }
+ }
+
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+ axis2_op_ctx_set_response_written(op_ctx, env, AXIS2_TRUE);
+ }
+ }
+
+ axiom_output_free(om_output, env);
+ om_output = NULL;
+ xml_writer = NULL;
+
+ if(transport_url)
+ {
+ if(epr)
+ {
+ axis2_endpoint_ref_free(epr, env);
+ epr = NULL;
+ }
+ }
+ AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_http_transport_sender_invoke");
+ return status;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_clean_up(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE);
+ /*
+ * Clean up is not used. If the http sender needs
+ * to be cleaned up it should be done here.
+ */
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_init(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_transport_out_desc_t * out_desc)
+{
+ axutil_param_t *version_param = NULL;
+ axis2_char_t *version = NULL;
+ axis2_char_t *temp = NULL;
+ axutil_param_t *temp_param = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, out_desc, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE);
+
+ /* Getting HTTP version from axis2.xml */
+ version_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container(
+ out_desc, env), env, AXIS2_HTTP_PROTOCOL_VERSION);
+
+ if(version_param)
+ {
+ version = axutil_param_get_value(version_param, env);
+ }
+
+ if(version)
+ {
+ /* handling HTTP 1.1 */
+ if(0 == axutil_strcmp(version, AXIS2_HTTP_HEADER_PROTOCOL_11))
+ {
+ axis2_char_t *encoding = NULL;
+ axutil_param_t *encoding_param = NULL;
+ if(AXIS2_INTF_TO_IMPL(transport_sender)->http_version)
+ {
+ AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(transport_sender)->http_version);
+ }
+
+ AXIS2_INTF_TO_IMPL(transport_sender)->http_version = axutil_strdup(env, version);
+ AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive = AXIS2_TRUE;
+ encoding_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(out_desc, env), env,
+ AXIS2_HTTP_HEADER_TRANSFER_ENCODING);
+
+ if(encoding_param)
+ {
+ encoding = axutil_param_get_value(encoding_param, env);
+ }
+
+ if(encoding && 0
+ == axutil_strcmp(encoding, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_TRUE;
+ }
+ else
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_FALSE;
+ }
+
+ }
+ else if(0 == axutil_strcmp(version, AXIS2_HTTP_HEADER_PROTOCOL_10))
+ {
+ axutil_param_t *keepalive_param = NULL;
+
+ /* Handling HTTP 1.0 */
+ if(AXIS2_INTF_TO_IMPL(transport_sender)->http_version)
+ {
+ AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(transport_sender)->http_version);
+ }
+ AXIS2_INTF_TO_IMPL(transport_sender)->http_version = axutil_strdup(env, version);
+ AXIS2_INTF_TO_IMPL(transport_sender)->chunked = AXIS2_FALSE;
+ keepalive_param = axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(out_desc, env), env,
+ AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE);
+ if(keepalive_param)
+ {
+ axis2_char_t *keepalive_value = NULL;
+ keepalive_value = axutil_param_get_value(keepalive_param, env);
+ if(!axutil_strcmp(keepalive_value, AXIS2_VALUE_FALSE))
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive = AXIS2_FALSE;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* HTTP version is not available in axis2.xml */
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+
+ /* Getting HTTP_SO_TIMEOUT value from axis2.xml */
+ temp_param = axutil_param_container_get_param(axis2_transport_out_desc_param_container(
+ out_desc, env), env, AXIS2_HTTP_SO_TIMEOUT);
+
+ if(temp_param)
+ {
+ temp = axutil_param_get_value(temp_param, env);
+ }
+
+ if(temp)
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->so_timeout = AXIS2_ATOI(temp);
+ }
+
+ /* Getting HTTP_CONNECTION_TIMEOUT from axis2.xml */
+ temp
+ = (axis2_char_t *)axutil_param_container_get_param(
+ axis2_transport_out_desc_param_container(out_desc, env), env,
+ AXIS2_HTTP_CONNECTION_TIMEOUT);
+ if(temp_param)
+ {
+ temp = axutil_param_get_value(temp_param, env);
+ }
+
+ /* set axis2.xml connection timeout value to http_sender */
+ if(temp)
+ {
+ AXIS2_INTF_TO_IMPL(transport_sender)->connection_timeout = AXIS2_ATOI(temp);
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_http_transport_sender_write_message(
+ axis2_transport_sender_t * transport_sender,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ axis2_endpoint_ref_t * epr,
+ axiom_soap_envelope_t * out,
+ axiom_output_t * om_output)
+{
+ const axis2_char_t *soap_action = NULL;
+ const axis2_char_t *url = NULL;
+ axis2_http_sender_t *sender = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ const axis2_char_t *soap_ns_uri = NULL;
+ axiom_soap_envelope_t *response_envelope = NULL;
+ axis2_op_t *op = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, epr, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, transport_sender, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, out, AXIS2_FAILURE);
+
+ /* epr is already passed NULL checking */
+ url = axis2_endpoint_ref_get_address(epr, env);
+
+ soap_action = axutil_string_get_buffer(axis2_msg_ctx_get_soap_action(msg_ctx, env), env);
+
+ if(!soap_action)
+ {
+ soap_action = "";
+ }
+
+ sender = axis2_http_sender_create(env);
+
+ if(!sender)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "http sender creation failed");
+ return AXIS2_FAILURE;
+ }
+ axis2_http_sender_set_keep_alive(sender, env, AXIS2_INTF_TO_IMPL(transport_sender)->keep_alive);
+
+ /* For the MTOM case we should on chunking. And for chunking to work the
+ * protocol should be http 1.1*/
+
+ if(axis2_msg_ctx_get_doing_mtom(msg_ctx, env))
+ {
+ AXIS2_HTTP_SENDER_SET_CHUNKED(sender, env, AXIS2_TRUE);
+ AXIS2_HTTP_SENDER_SET_HTTP_VERSION(sender, env, AXIS2_HTTP_HEADER_PROTOCOL_11);
+ }
+ else
+ {
+ AXIS2_HTTP_SENDER_SET_CHUNKED(sender, env, AXIS2_INTF_TO_IMPL(transport_sender)->chunked);
+ AXIS2_HTTP_SENDER_SET_HTTP_VERSION(sender, env,
+ AXIS2_INTF_TO_IMPL(transport_sender)->http_version);
+ }
+ AXIS2_HTTP_SENDER_SET_OM_OUTPUT(sender, env, om_output);
+
+#ifdef AXIS2_LIBCURL_ENABLED
+ AXIS2_LOG_DEBUG (env->log, AXIS2_LOG_SI, "using axis2 libcurl http sender.");
+ status =
+ axis2_libcurl_http_send(AXIS2_INTF_TO_IMPL(transport_sender)->libcurl,
+ sender, env, msg_ctx, out, url, soap_action);
+#else
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "using axis2 native http sender.");
+ status = AXIS2_HTTP_SENDER_SEND(sender, env, msg_ctx, out, url, soap_action);
+#endif
+
+ AXIS2_HTTP_SENDER_FREE(sender, env);
+ sender = NULL;
+
+ /* if the send was not successful, do not process any response */
+ if(status != AXIS2_SUCCESS)
+ return status;
+
+ op = axis2_msg_ctx_get_op(msg_ctx, env);
+ if(op)
+ {
+ /* handle one way case */
+ const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env);
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "OP name axutil_qname_get_localpart = %s", mep);
+ if(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY) == 0 || axutil_strcmp(mep,
+ AXIS2_MEP_URI_ROBUST_OUT_ONLY) == 0 || axutil_strcmp(mep, AXIS2_MEP_URI_IN_ONLY) == 0)
+ {
+ return status;
+ }
+ else
+ {
+ /* AXIS2_MEP_URI_IN_OUT case , we have a response this
+ * time */
+ soap_ns_uri
+ = axis2_msg_ctx_get_is_soap_11(msg_ctx, env) ? AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI
+ : AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
+ response_envelope = axis2_http_transport_utils_create_soap_msg(env, msg_ctx,
+ soap_ns_uri);
+ if(response_envelope)
+ {
+ axis2_msg_ctx_set_response_soap_envelope(msg_ctx, env, response_envelope);
+ }
+ }
+ }
+
+ return status;
+}
+
+/**
+ * Following block distinguish the exposed part of the dll.
+ */
+
+/* When building for static deployment, give the get and remove methods
+ * unique names. This avoids having the linker fail with duplicate symbol
+ * errors.
+ */
+
+AXIS2_EXPORT int
+#ifndef AXIS2_STATIC_DEPLOY
+axis2_get_instance(
+#else
+ axis2_http_transport_sender_get_instance(
+#endif
+ struct axis2_transport_sender **inst,
+ const axutil_env_t * env)
+{
+ *inst = axis2_http_transport_sender_create(env);
+ if(!(*inst))
+ {
+ return AXIS2_FAILURE;
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXPORT int
+#ifndef AXIS2_STATIC_DEPLOY
+axis2_remove_instance(
+#else
+ axis2_http_transport_sender_remove_instance(
+#endif
+ axis2_transport_sender_t * inst,
+ const axutil_env_t * env)
+{
+ if(inst)
+ {
+ AXIS2_TRANSPORT_SENDER_FREE(inst, env);
+ }
+ return AXIS2_SUCCESS;
+}
+
diff --git a/src/core/transport/http/sender/libcurl/Makefile.am b/src/core/transport/http/sender/libcurl/Makefile.am
new file mode 100644
index 0000000..90e5ce6
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST= axis2_libcurl.h axis2_libcurl.c libcurl_stream.h libcurl_stream.c
+
diff --git a/src/core/transport/http/sender/libcurl/axis2_libcurl.c b/src/core/transport/http/sender/libcurl/axis2_libcurl.c
new file mode 100644
index 0000000..834e69b
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/axis2_libcurl.c
@@ -0,0 +1,1169 @@
+/*
+ * 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;
+ {
+ 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 */
+
diff --git a/src/core/transport/http/sender/libcurl/axis2_libcurl.h b/src/core/transport/http/sender/libcurl/axis2_libcurl.h
new file mode 100644
index 0000000..f2971e5
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/axis2_libcurl.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef AXIS2_LIBCURL_H
+#define AXIS2_LIBCURL_H
+#include <curl/curl.h>
+#include <stdio.h>
+#include <string.h>
+#include <axis2_http_sender.h>
+#include <axutil_string.h>
+#include <axutil_types.h>
+#include <axutil_generic_obj.h>
+#include <axis2_const.h>
+#include <axis2_util.h>
+#include <axiom.h>
+
+/* typedef struct axis2_libcurl axis2_libcurl_t; */
+/* actually defined in axis2_http_sender.h as it is part of axis2/include */
+
+AXIS2_EXTERN axis2_libcurl_t *AXIS2_CALL
+axis2_libcurl_create(
+ const axutil_env_t * env);
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_libcurl_free(
+ axis2_libcurl_t *data,
+ const axutil_env_t * env);
+
+AXIS2_EXTERN 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);
+
+#endif /* AXIS2_LIBCURL_H */
diff --git a/src/core/transport/http/sender/libcurl/libcurl_stream.c b/src/core/transport/http/sender/libcurl/libcurl_stream.c
new file mode 100644
index 0000000..0c9126d
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/libcurl_stream.c
@@ -0,0 +1,192 @@
+/*
+ * 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 "libcurl_stream.h"
+#include <string.h>
+
+typedef struct libcurl_stream_impl
+{
+ axutil_stream_t stream;
+ axutil_stream_type_t stream_type;
+ axis2_char_t *buffer;
+ int size;
+ int read_len;
+}
+libcurl_stream_impl_t;
+
+#define AXIS2_INTF_TO_IMPL(stream) ((libcurl_stream_impl_t *)(stream))
+
+/********************************Function headers******************************/
+axutil_stream_type_t AXIS2_CALL libcurl_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+int AXIS2_CALL libcurl_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count);
+
+int AXIS2_CALL libcurl_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count);
+
+int AXIS2_CALL libcurl_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count);
+
+int AXIS2_CALL libcurl_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+/************************* End of function headers ****************************/
+
+/*
+ * Internal function. Not exposed to outside
+ */
+AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+axutil_stream_create_libcurl(
+ const axutil_env_t * env,
+ axis2_char_t * buffer,
+ unsigned int size)
+{
+ libcurl_stream_impl_t *stream_impl = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, buffer, NULL);
+
+ stream_impl =
+ (libcurl_stream_impl_t *) AXIS2_MALLOC(env->allocator,
+ sizeof(libcurl_stream_impl_t));
+
+ if (!stream_impl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ stream_impl->buffer = buffer;
+ stream_impl->size = size;
+ stream_impl->read_len = 0;
+ stream_impl->stream_type = AXIS2_STREAM_MANAGED;
+
+ axutil_stream_set_read(&(stream_impl->stream), env, libcurl_stream_read);
+ axutil_stream_set_write(&(stream_impl->stream), env, libcurl_stream_write);
+ axutil_stream_set_skip(&(stream_impl->stream), env, libcurl_stream_skip);
+
+ return &(stream_impl->stream);
+}
+
+void AXIS2_CALL
+libcurl_stream_free(
+ void * stream,
+ const axutil_env_t * env)
+{
+ libcurl_stream_impl_t *stream_impl = NULL;
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ AXIS2_FREE(env->allocator, stream_impl);
+
+ return;
+}
+
+int AXIS2_CALL
+libcurl_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count)
+{
+ libcurl_stream_impl_t *stream_impl = NULL;
+ int read = 0;
+ int unread = 0;
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ if (stream_impl->size >= (int)count)
+ /* We are sure that the difference lies within the int range */
+ {
+ if (buffer && (stream_impl->size > stream_impl->read_len))
+ {
+ unread = (stream_impl->size - stream_impl->read_len);
+ if (unread > (int)count)
+ /* We are sure that the difference lies within the int range */
+ {
+ memcpy(buffer, &stream_impl->buffer[stream_impl->read_len],
+ count);
+ read = (int)count;
+ /* We are sure that the difference lies within the int range */
+ stream_impl->read_len += read;
+ }
+ else
+ {
+ memcpy(buffer, &stream_impl->buffer[stream_impl->read_len],
+ unread);
+ read = unread;
+ stream_impl->read_len += read;
+ }
+ }
+ else
+ read = 0;
+ }
+ else
+ {
+ if (buffer && (stream_impl->size > stream_impl->read_len))
+ {
+ memcpy(buffer, &stream_impl->buffer[stream_impl->read_len],
+ stream_impl->size - stream_impl->read_len);
+ read = stream_impl->size - stream_impl->read_len;
+ stream_impl->read_len += read;
+ }
+ else
+ read = 0;
+ }
+ return read;
+}
+
+int AXIS2_CALL
+libcurl_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count)
+{
+ return (int)count;
+ /* We are sure that the difference lies within the int range */
+}
+
+int AXIS2_CALL
+libcurl_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count)
+{
+ return 0;
+}
+
+int AXIS2_CALL
+libcurl_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ return 0;
+}
+
+#endif /* AXIS2_LIBCURL_ENABLED */
+
diff --git a/src/core/transport/http/sender/libcurl/libcurl_stream.h b/src/core/transport/http/sender/libcurl/libcurl_stream.h
new file mode 100644
index 0000000..8a24fcc
--- /dev/null
+++ b/src/core/transport/http/sender/libcurl/libcurl_stream.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#ifndef LIBCURL_STREAM_H
+#define LIBCURL_STREAM_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /** brief Constructor for creating apche2 stream
+ * @return axutil_stream (libcurl)
+ */
+ AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+ axutil_stream_create_libcurl(
+ const axutil_env_t * env,
+ axis2_char_t * buffer,
+ unsigned int size);
+
+ /** @} */
+
+ void AXIS2_CALL libcurl_stream_free(
+ void * stream,
+ const axutil_env_t * env);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBCURL_STREAM_H */
diff --git a/src/core/transport/http/sender/ssl/Makefile.am b/src/core/transport/http/sender/ssl/Makefile.am
new file mode 100644
index 0000000..3e457e5
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST= ssl_stream.c ssl_stream.h ssl_utils.c ssl_utils.h
+
diff --git a/src/core/transport/http/sender/ssl/ssl_stream.c b/src/core/transport/http/sender/ssl/ssl_stream.c
new file mode 100644
index 0000000..9360f1a
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/ssl_stream.c
@@ -0,0 +1,239 @@
+/*
+ * 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_SSL_ENABLED
+
+#include <string.h>
+#include <stdlib.h>
+#include "ssl_stream.h"
+#include "ssl_utils.h"
+
+/**
+ * @brief Stream struct impl
+ * Streaming mechanisms for SSL
+ */
+typedef struct ssl_stream_impl ssl_stream_impl_t;
+
+struct ssl_stream_impl
+{
+ axutil_stream_t stream;
+ axutil_stream_type_t stream_type;
+ SSL *ssl;
+ SSL_CTX *ctx;
+ axis2_socket_t socket;
+};
+
+#define AXIS2_INTF_TO_IMPL(stream) ((ssl_stream_impl_t *)(stream))
+
+void AXIS2_CALL axis2_ssl_stream_free(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+axutil_stream_type_t AXIS2_CALL axis2_ssl_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+int AXIS2_CALL axis2_ssl_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buffer,
+ size_t count);
+
+int AXIS2_CALL axis2_ssl_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count);
+
+int AXIS2_CALL axis2_ssl_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count);
+
+int AXIS2_CALL axis2_ssl_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env);
+
+AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+axutil_stream_create_ssl(
+ const axutil_env_t * env,
+ axis2_socket_t socket,
+ axis2_char_t * server_cert,
+ axis2_char_t * key_file,
+ axis2_char_t * ssl_pp)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+
+ stream_impl =
+ (ssl_stream_impl_t *) AXIS2_MALLOC(env->allocator,
+ sizeof(ssl_stream_impl_t));
+
+ if (!stream_impl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+ memset ((void *)stream_impl, 0, sizeof (ssl_stream_impl_t));
+ stream_impl->socket = socket;
+ stream_impl->ctx = NULL;
+ stream_impl->ssl = NULL;
+
+ stream_impl->ctx = axis2_ssl_utils_initialize_ctx(env, server_cert,
+ key_file, ssl_pp);
+ if (!stream_impl->ctx)
+ {
+ axis2_ssl_stream_free((axutil_stream_t *) stream_impl, env);
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ stream_impl->ssl = axis2_ssl_utils_initialize_ssl(env, stream_impl->ctx,
+ stream_impl->socket);
+ if (!stream_impl->ssl)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE);
+ return NULL;
+ }
+ stream_impl->stream_type = AXIS2_STREAM_MANAGED;
+
+ axutil_stream_set_read(&(stream_impl->stream), env, axis2_ssl_stream_read);
+ axutil_stream_set_write(&(stream_impl->stream), env,
+ axis2_ssl_stream_write);
+ axutil_stream_set_skip(&(stream_impl->stream), env, axis2_ssl_stream_skip);
+
+ return &(stream_impl->stream);
+}
+
+void AXIS2_CALL
+axis2_ssl_stream_free(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ axis2_ssl_utils_cleanup_ssl(env, stream_impl->ctx, stream_impl->ssl);
+ AXIS2_FREE(env->allocator, stream_impl);
+
+ return;
+}
+
+int AXIS2_CALL
+axis2_ssl_stream_read(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ void *buffer,
+ size_t count)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+ int read = -1;
+ int len = -1;
+
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+
+ SSL_set_mode(stream_impl->ssl, SSL_MODE_AUTO_RETRY);
+
+ read = SSL_read(stream_impl->ssl, buffer, (int)count);
+ /* We are sure that the difference lies within the int range */
+ switch (SSL_get_error(stream_impl->ssl, read))
+ {
+ case SSL_ERROR_NONE:
+ len = read;
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ len = -1;
+ break;
+ case SSL_ERROR_SYSCALL:
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "SSL Error: Premature close");
+ len = -1;
+ break;
+ default:
+ len = -1;
+ break;
+ }
+ return len;
+}
+
+int AXIS2_CALL
+axis2_ssl_stream_write(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ const void *buf,
+ size_t count)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+ int write = -1;
+
+ AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE);
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+ write = SSL_write(stream_impl->ssl, buf, (int)count);
+ /* We are sure that the difference lies within the int range */
+
+ switch (SSL_get_error(stream_impl->ssl, write))
+ {
+ case SSL_ERROR_NONE:
+ if ((int)count != write)
+ /* We are sure that the difference lies within the int range */
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Incomplete SSL write!");
+ break;
+ default:
+ return -1;
+ }
+ return write;
+}
+
+int AXIS2_CALL
+axis2_ssl_stream_skip(
+ axutil_stream_t * stream,
+ const axutil_env_t * env,
+ int count)
+{
+ ssl_stream_impl_t *stream_impl = NULL;
+ axis2_char_t *tmp_buffer = NULL;
+ int len = -1;
+ stream_impl = AXIS2_INTF_TO_IMPL(stream);
+
+ tmp_buffer = AXIS2_MALLOC(env->allocator, count * sizeof(axis2_char_t));
+ if (tmp_buffer == NULL)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return -1;
+ }
+ len = SSL_read(stream_impl->ssl, tmp_buffer, count);
+ AXIS2_FREE(env->allocator, tmp_buffer);
+ return len;
+
+}
+
+int AXIS2_CALL
+axis2_ssl_stream_get_char(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ int ret = -1;
+
+ return ret;
+}
+
+axutil_stream_type_t AXIS2_CALL
+axis2_ssl_stream_get_type(
+ axutil_stream_t * stream,
+ const axutil_env_t * env)
+{
+ return AXIS2_INTF_TO_IMPL(stream)->stream_type;
+}
+
+#endif
+
diff --git a/src/core/transport/http/sender/ssl/ssl_stream.h b/src/core/transport/http/sender/ssl/ssl_stream.h
new file mode 100644
index 0000000..396da5d
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/ssl_stream.h
@@ -0,0 +1,50 @@
+
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain count 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.
+ */
+
+#ifndef AXIS2_SSL_STREAM_H
+#define AXIS2_SSL_STREAM_H
+
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <axutil_env.h>
+#include <axutil_stream.h>
+#include <platforms/axutil_platform_auto_sense.h>
+#include <openssl/ssl.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /** \brief Constructor for creating ssl stream
+ * @return axutil_stream (ssl)
+ */
+ AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
+ axutil_stream_create_ssl(
+ const axutil_env_t * env,
+ axis2_socket_t socket,
+ axis2_char_t * server_cert,
+ axis2_char_t * key_file,
+ axis2_char_t * ssl_pp);
+
+ /** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AXIS2_SSL_STREAM_H */
diff --git a/src/core/transport/http/sender/ssl/ssl_utils.c b/src/core/transport/http/sender/ssl/ssl_utils.c
new file mode 100644
index 0000000..d565555
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/ssl_utils.c
@@ -0,0 +1,227 @@
+/*
+ * 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_SSL_ENABLED
+
+#include "ssl_utils.h"
+#include <openssl/err.h>
+BIO *bio_err = 0;
+
+static int
+password_cb(
+ char *buf,
+ int size,
+ int rwflag,
+ void *passwd)
+{
+ strncpy(buf, (char *) passwd, size);
+ buf[size - 1] = '\0';
+ return (int)(strlen(buf));
+ /* We are sure that the difference lies within the int range */
+}
+
+AXIS2_EXTERN SSL_CTX *AXIS2_CALL
+axis2_ssl_utils_initialize_ctx(
+ const axutil_env_t * env,
+ axis2_char_t * server_cert,
+ axis2_char_t * key_file,
+ axis2_char_t * ssl_pp)
+{
+ SSL_METHOD *meth = NULL;
+ SSL_CTX *ctx = NULL;
+ axis2_char_t *ca_file = server_cert;
+
+ if (!ca_file)
+ {
+ AXIS2_LOG_INFO(env->log, "[ssl client] CA certificate not specified");
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_NO_CA_FILE, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ if (!bio_err)
+ {
+ /* Global system initialization */
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ /* An error write context */
+ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+ }
+
+ /* Create our context */
+ meth = SSLv23_method();
+ ctx = SSL_CTX_new(meth);
+
+ /* Load our keys and certificates
+ * If we need client certificates it has to be done here
+ */
+ if (key_file) /*can we check if the server needs client auth? */
+ {
+ if (!ssl_pp)
+ {
+ AXIS2_LOG_INFO(env->log,
+ "[ssl client] No passphrase specified for \
+key file %s and server cert %s", key_file, server_cert);
+ }
+
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) ssl_pp);
+ SSL_CTX_set_default_passwd_cb(ctx, password_cb);
+
+ if (!(SSL_CTX_use_certificate_chain_file(ctx, key_file)))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[ssl client] Loading client certificate failed \
+, key file %s", key_file);
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+
+ if (!(SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM)))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[ssl client] Loading client key failed, key file \
+%s", key_file);
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ }
+ else
+ {
+ AXIS2_LOG_INFO(env->log,
+ "[ssl client] Client certificate chain file"
+ "not specified");
+ }
+
+ /* Load the CAs we trust */
+ if (!(SSL_CTX_load_verify_locations(ctx, ca_file, 0)))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[ssl client] Loading CA certificate failed, \
+ca_file is %s", ca_file);
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+AXIS2_EXTERN SSL *AXIS2_CALL
+axis2_ssl_utils_initialize_ssl(
+ const axutil_env_t * env,
+ SSL_CTX * ctx,
+ axis2_socket_t socket)
+{
+ SSL *ssl = NULL;
+ BIO *sbio = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, ctx, NULL);
+
+ ssl = SSL_new(ctx);
+ if (!ssl)
+ {
+ AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI,
+ "[ssl]unable to create new ssl context");
+ return NULL;
+ }
+
+ sbio = BIO_new_socket((int)socket, BIO_NOCLOSE);
+ if (!sbio)
+ {
+ AXIS2_LOG_ERROR (env->log, AXIS2_LOG_SI,
+ "[ssl]unable to create BIO new socket for socket %d",
+ (int)socket);
+ return NULL;
+ }
+
+ SSL_set_bio(ssl, sbio, sbio);
+ if (SSL_connect(ssl) <= 0)
+ {
+ AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ if (SSL_get_verify_result(ssl) != X509_V_OK)
+ {
+ char sslerror[128]; /** error buffer must be at least 120 bytes long */
+ X509 *peer_cert = NULL;
+ X509_STORE *cert_store = NULL;
+ X509_NAME *peer_name = NULL;
+ X509_OBJECT *client_object = NULL;
+ X509 *client_cert = NULL;
+
+ peer_cert = SSL_get_peer_certificate(ssl);
+ if (peer_cert && peer_cert->cert_info)
+ {
+ peer_name = (peer_cert->cert_info)->subject;
+ }
+
+ cert_store = SSL_CTX_get_cert_store(ctx);
+ if (peer_name && cert_store)
+ {
+ client_object = X509_OBJECT_retrieve_by_subject(cert_store->objs,
+ X509_LU_X509,
+ peer_name);
+ }
+ if (client_object)
+ {
+ client_cert = (client_object->data).x509;
+ if (client_cert &&
+ (M_ASN1_BIT_STRING_cmp(client_cert->signature,
+ peer_cert->signature) == 0))
+ {
+ if (peer_cert)
+ {
+ X509_free(peer_cert);
+ }
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "[ssl client] SSL certificate verified against peer");
+ return ssl;
+ }
+ }
+ if (peer_cert)
+ {
+ X509_free(peer_cert);
+ }
+ ERR_error_string(SSL_get_verify_result(ssl), sslerror);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[ssl client] SSL certificate verification failed (%s)",
+ sslerror);
+ return NULL;
+ }
+
+ return ssl;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_ssl_utils_cleanup_ssl(
+ const axutil_env_t * env,
+ SSL_CTX * ctx,
+ SSL * ssl)
+{
+
+ if (ssl)
+ {
+ SSL_shutdown(ssl);
+ }
+ if (ctx)
+ {
+ SSL_CTX_free(ctx);
+ }
+ return AXIS2_SUCCESS;
+}
+
+#endif
+
diff --git a/src/core/transport/http/sender/ssl/ssl_utils.h b/src/core/transport/http/sender/ssl/ssl_utils.h
new file mode 100644
index 0000000..26dc16b
--- /dev/null
+++ b/src/core/transport/http/sender/ssl/ssl_utils.h
@@ -0,0 +1,56 @@
+
+/*
+ * 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.
+ */
+
+#ifndef AXIS2_SSL_UTILS_H
+#define AXIS2_SSL_UTILS_H
+
+
+#include <platforms/axutil_platform_auto_sense.h>
+#include <axis2_const.h>
+#include <axis2_defines.h>
+#include <openssl/ssl.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ AXIS2_EXTERN SSL_CTX *AXIS2_CALL
+ axis2_ssl_utils_initialize_ctx(
+ const axutil_env_t * env,
+ axis2_char_t * server_cert,
+ axis2_char_t * key_file,
+ axis2_char_t * ssl_pp);
+
+ AXIS2_EXTERN SSL *AXIS2_CALL
+ axis2_ssl_utils_initialize_ssl(
+ const axutil_env_t * env,
+ SSL_CTX * ctx,
+ axis2_socket_t socket);
+
+ AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axis2_ssl_utils_cleanup_ssl(
+ const axutil_env_t * env,
+ SSL_CTX * ctx,
+ SSL * ssl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AXIS2_SSL_UTILS_H */