blob: c4b954ce080e360a721f9adf858a273720d928ee [file] [log] [blame]
/*
* 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
#ifdef AXIS2_JSON_ENABLED
#include <axis2_json_writer.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;
}
#ifdef AXIS2_JSON_ENABLED
if (AXIS2_TRUE == axis2_msg_ctx_get_doing_json(msg_ctx, env))
{
axis2_json_writer_t* json_writer;
axiom_node_t *body_node = NULL;
axiom_soap_body_t* soap_body =
axiom_soap_envelope_get_body(soap_data_out, env);
axutil_stream_t* out_stream =
axis2_msg_ctx_get_transport_out_stream(msg_ctx, env);
if (!soap_body)
{
AXIS2_ERROR_SET(env->error,
AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL,
AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s",
AXIS2_ERROR_GET_MESSAGE(env->error));
return AXIS2_FAILURE;
}
body_node = axiom_soap_body_get_base_node(soap_body, env);
if (!body_node)
{
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)
{
return AXIS2_FAILURE;
}
json_writer = axis2_json_writer_create(env);
if (!json_writer)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"Failed to create JSON writer");
return AXIS2_FAILURE;
}
axis2_json_writer_write(json_writer, data_out, env);
buffer = (axis2_char_t*)axis2_json_writer_get_json_string(
json_writer, env, &buffer_size);
if (!buffer)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"Failed to get resulting JSON string");
return AXIS2_FAILURE;
}
if (AXIS2_TRUE == axis2_msg_ctx_get_server_side(msg_ctx, env))
{
axis2_op_ctx_t *op_ctx = NULL;
axis2_http_out_transport_info_t* 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);
return AXIS2_FAILURE;
}
AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CHAR_ENCODING(
out_info, env, char_set_enc);
AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(
out_info, env, AXIS2_HTTP_HEADER_ACCEPT_JSON);
op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
axis2_op_ctx_set_response_written(op_ctx, env, AXIS2_TRUE);
}
axutil_stream_write(out_stream, env, buffer, buffer_size);
axis2_json_writer_free(json_writer, env);
return AXIS2_SUCCESS;
}
#endif
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
/* if the send was not successful, do not process any response */
if(status != AXIS2_SUCCESS)
{
AXIS2_HTTP_SENDER_FREE(sender, env);
sender = NULL;
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)
{
AXIS2_HTTP_SENDER_FREE(sender, env);
sender = NULL;
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);
}
}
}
AXIS2_HTTP_SENDER_FREE(sender, env);
sender = NULL;
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;
}