| /* |
| * 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; |
| } |
| |