/* | |
* 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 <signal.h> | |
#include <axiom.h> | |
#include <axiom_soap.h> | |
#include <axis2_engine.h> | |
#include <axiom_mime_parser.h> | |
#include <axutil_http_chunked_stream.h> | |
#include <axis2_amqp_defines.h> | |
#include <axis2_amqp_util.h> | |
#include <axis2_amqp_request_processor.h> | |
void* AXIS2_THREAD_FUNC | |
axis2_amqp_request_processor_thread_function( | |
axutil_thread_t* thread, | |
void* request_data) | |
{ | |
axis2_status_t status = AXIS2_FAILURE; | |
axutil_env_t* env = NULL; | |
axutil_env_t* thread_env = NULL; | |
axis2_amqp_request_processor_resource_pack_t* request_resource_pack = NULL; | |
#ifndef WIN32 | |
#ifdef AXIS2_SVR_MULTI_THREADED | |
signal(SIGPIPE, SIG_IGN); | |
#endif | |
#endif | |
request_resource_pack = (axis2_amqp_request_processor_resource_pack_t*)request_data; | |
env = request_resource_pack->env; | |
thread_env = axutil_init_thread_env(env); | |
/* Process Request */ | |
status = axis2_amqp_process_request(thread_env, request_resource_pack); | |
if (status == AXIS2_SUCCESS) | |
{ | |
AXIS2_LOG_INFO(thread_env->log, "Request Processed Successfully"); | |
} | |
else | |
{ | |
AXIS2_LOG_WARNING(thread_env->log, AXIS2_LOG_SI, "Error while Processing Request"); | |
} | |
AXIS2_FREE(thread_env->allocator, request_resource_pack->request_content); | |
AXIS2_FREE(thread_env->allocator, request_resource_pack->reply_to); | |
AXIS2_FREE(thread_env->allocator, request_resource_pack->content_type); | |
AXIS2_FREE(thread_env->allocator, request_resource_pack->soap_action); | |
AXIS2_FREE(thread_env->allocator, request_resource_pack); | |
if (thread_env) | |
{ | |
thread_env = NULL; | |
} | |
#ifdef AXIS2_SVR_MULTI_THREADED | |
axutil_thread_pool_exit_thread(env->thread_pool, thread); | |
#endif | |
return NULL; | |
} | |
axis2_status_t | |
axis2_amqp_process_request( | |
const axutil_env_t* env, | |
axis2_amqp_request_processor_resource_pack_t* request_resource_pack) | |
{ | |
axiom_xml_reader_t* xml_reader = NULL; | |
axiom_stax_builder_t* stax_builder = NULL; | |
axiom_soap_builder_t* soap_builder = NULL; | |
axis2_transport_out_desc_t* out_desc = NULL; | |
axis2_transport_in_desc_t* in_desc = NULL; | |
axis2_msg_ctx_t* msg_ctx = NULL; | |
axiom_soap_envelope_t* soap_envelope = NULL; | |
axis2_engine_t* engine = NULL; | |
const axis2_char_t* soap_ns_uri = NULL; | |
axis2_bool_t is_soap_11 = AXIS2_FALSE; | |
axis2_char_t *soap_body_str = NULL; | |
int soap_body_len = 0; | |
axis2_bool_t is_mtom = AXIS2_FALSE; | |
axis2_status_t status = AXIS2_FAILURE; | |
axutil_hash_t *binary_data_map = NULL; | |
axiom_soap_body_t *soap_body = NULL; | |
axutil_property_t* reply_to_property = NULL; | |
/* Create msg_ctx */ | |
if (!request_resource_pack->conf_ctx) | |
{ | |
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Conf Context not Available"); | |
return AXIS2_FAILURE; | |
} | |
out_desc = axis2_conf_get_transport_out( | |
axis2_conf_ctx_get_conf(request_resource_pack->conf_ctx, env), | |
env, AXIS2_TRANSPORT_ENUM_AMQP); | |
if (!out_desc) | |
{ | |
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport Out Descriptor not Found"); | |
return AXIS2_FAILURE; | |
} | |
in_desc = axis2_conf_get_transport_in( | |
axis2_conf_ctx_get_conf(request_resource_pack->conf_ctx, env), | |
env, AXIS2_TRANSPORT_ENUM_AMQP); | |
if (!in_desc) | |
{ | |
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport In Descriptor not Found"); | |
return AXIS2_FAILURE; | |
} | |
/* Create msg_ctx */ | |
msg_ctx = axis2_msg_ctx_create(env, request_resource_pack->conf_ctx, in_desc, out_desc); | |
axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); | |
/* Handle MTOM */ | |
if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_MULTIPART_RELATED)) | |
{ | |
axis2_char_t* mime_boundary = | |
axis2_amqp_util_get_value_from_content_type(env, | |
request_resource_pack->content_type, | |
AXIS2_AMQP_HEADER_CONTENT_TYPE_MIME_BOUNDARY); | |
if (mime_boundary) | |
{ | |
axiom_mime_parser_t *mime_parser = NULL; | |
int soap_body_len = 0; | |
axutil_param_t *buffer_size_param = NULL; | |
axutil_param_t *max_buffers_param = NULL; | |
axutil_param_t *attachment_dir_param = NULL; | |
axis2_char_t *value_size = NULL; | |
axis2_char_t *value_num = NULL; | |
axis2_char_t *value_dir = NULL; | |
int size = 0; | |
int num = 0; | |
mime_parser = axiom_mime_parser_create(env); | |
buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE); | |
if (buffer_size_param) | |
{ | |
value_size = (axis2_char_t*)axutil_param_get_value(buffer_size_param, env); | |
if (value_size) | |
{ | |
size = atoi(value_size); | |
axiom_mime_parser_set_buffer_size(mime_parser, env, size); | |
} | |
} | |
max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS); | |
if (max_buffers_param) | |
{ | |
value_num = (axis2_char_t*)axutil_param_get_value(max_buffers_param, env); | |
if (value_num) | |
{ | |
num = atoi(value_num); | |
axiom_mime_parser_set_max_buffers(mime_parser, env, num); | |
} | |
} | |
/* If this paramter is there mime_parser will cached the attachment | |
* using to the directory for large attachments. */ | |
attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR); | |
if (attachment_dir_param) | |
{ | |
value_dir = (axis2_char_t*)axutil_param_get_value(attachment_dir_param, env); | |
if (value_dir) | |
{ | |
axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir); | |
} | |
} | |
if (mime_parser) | |
{ | |
axis2_callback_info_t *callback_ctx = NULL; | |
axutil_stream_t *stream = NULL; | |
callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t)); | |
stream = axutil_stream_create_basic(env); | |
if (stream) | |
{ | |
axutil_stream_write(stream, env, request_resource_pack->request_content, | |
request_resource_pack->content_length); | |
callback_ctx->env = env; | |
callback_ctx->in_stream = stream; | |
callback_ctx->content_length = request_resource_pack->content_length; | |
callback_ctx->unread_len = request_resource_pack->content_length; | |
callback_ctx->chunked_stream = NULL; | |
} | |
binary_data_map = | |
axiom_mime_parser_parse(mime_parser, env, | |
axis2_amqp_util_on_data_request, | |
(void*)callback_ctx, | |
mime_boundary); | |
if (!binary_data_map) | |
{ | |
return AXIS2_FAILURE; | |
} | |
soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env); | |
soap_body_len = axiom_mime_parser_get_soap_body_len(mime_parser, env); | |
axutil_stream_free(stream, env); | |
AXIS2_FREE(env->allocator, callback_ctx); | |
axiom_mime_parser_free(mime_parser, env); | |
} | |
AXIS2_FREE(env->allocator, mime_boundary); | |
} | |
is_mtom = AXIS2_TRUE; | |
} | |
else | |
{ | |
soap_body_str = request_resource_pack->request_content; | |
soap_body_len = request_resource_pack->content_length; | |
} | |
soap_body_len = axutil_strlen(soap_body_str); | |
xml_reader = axiom_xml_reader_create_for_memory(env, soap_body_str, soap_body_len, | |
NULL, AXIS2_XML_PARSER_TYPE_BUFFER); | |
if (!xml_reader) | |
{ | |
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create XML Reader"); | |
return AXIS2_FAILURE; | |
} | |
stax_builder = axiom_stax_builder_create(env, xml_reader); | |
if (!stax_builder) | |
{ | |
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create StAX Builder"); | |
return AXIS2_FAILURE; | |
} | |
soap_ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; | |
if (request_resource_pack->content_type) | |
{ | |
if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML)) | |
{ | |
is_soap_11 = AXIS2_TRUE; | |
soap_ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; | |
} | |
/*if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_APPL_SOAP)) | |
{ | |
is_soap_11 = AXIS2_FALSE; | |
soap_ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; | |
} | |
else if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML)) | |
{ | |
is_soap_11 = AXIS2_TRUE; | |
soap_ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; | |
}*/ | |
} | |
soap_builder = axiom_soap_builder_create(env, stax_builder, soap_ns_uri); | |
if (!soap_builder) | |
{ | |
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create SOAP Builder"); | |
return AXIS2_FAILURE; | |
} | |
if (binary_data_map) | |
{ | |
axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map); | |
} | |
soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); | |
axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); | |
soap_body = axiom_soap_envelope_get_body(soap_envelope, env); | |
if (!soap_body) | |
{ | |
return AXIS2_FAILURE; | |
} | |
/* SOAPAction */ | |
if (request_resource_pack->soap_action) | |
{ | |
axis2_msg_ctx_set_soap_action(msg_ctx, env, | |
axutil_string_create(env, request_resource_pack->soap_action)); | |
} | |
/* SOAP version */ | |
axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap_11); | |
/* Set ReplyTo in the msg_ctx as a property. This is used by the server when | |
* 1. WS-A is not in use | |
* 2. ReplyTo is an anonymous EPR - Sandesha2/Dual-channel */ | |
reply_to_property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, 0, 0, | |
(void*)request_resource_pack->reply_to); | |
axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO, | |
reply_to_property); | |
engine = axis2_engine_create(env, request_resource_pack->conf_ctx); | |
if (AXIS2_TRUE == axiom_soap_body_has_fault(soap_body, env)) | |
{ | |
status = axis2_engine_receive_fault(engine, env, msg_ctx); | |
} | |
else | |
{ | |
status = axis2_engine_receive(engine, env, msg_ctx); | |
} | |
if (engine) | |
{ | |
axis2_engine_free(engine, env); | |
} | |
if (soap_body_str && is_mtom) | |
{ | |
AXIS2_FREE(env->allocator, soap_body_str); | |
} | |
return status; | |
} |