blob: a748a8f0f5d9394dab7c8d181d6139936d0e0103 [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 <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;
}