| /* |
| * 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_apache2_worker.h" |
| #include <axis2_http_transport.h> |
| #include <axis2_conf.h> |
| #include <axutil_string.h> |
| #include <axis2_msg_ctx.h> |
| #include <axis2_http_out_transport_info.h> |
| #include <axis2_http_transport_utils.h> |
| #include <axis2_http_accept_record.h> |
| #include <axis2_op_ctx.h> |
| #include <axis2_engine.h> |
| #include <axutil_uuid_gen.h> |
| #include <axis2_conf_init.h> |
| #include "axis2_apache2_out_transport_info.h" |
| #include <axutil_url.h> |
| #include <http_core.h> |
| #include <http_protocol.h> |
| #include <axiom_soap.h> |
| #include <axutil_class_loader.h> |
| #include <axutil_string_util.h> |
| #include <axiom_mime_part.h> |
| #include <axiom_mtom_sending_callback.h> |
| |
| #define READ_SIZE 2048 |
| |
| static axis2_status_t |
| apache2_worker_send_mtom_message( |
| request_rec *request, |
| const axutil_env_t * env, |
| axutil_array_list_t *mime_parts, |
| axis2_char_t *mtom_sending_callback_name); |
| |
| static axis2_status_t |
| apache2_worker_send_attachment_using_file( |
| const axutil_env_t * env, |
| request_rec *request, |
| FILE *fp, |
| axis2_byte_t *buffer, |
| int buffer_size); |
| |
| static axis2_status_t |
| apache2_worker_send_attachment_using_callback( |
| const axutil_env_t * env, |
| request_rec *request, |
| axiom_mtom_sending_callback_t *callback, |
| void *handler, |
| void *user_param); |
| |
| static axutil_hash_t* |
| axis2_apache_worker_get_headers( |
| const axutil_env_t *env, |
| request_rec *request); |
| |
| |
| struct axis2_apache2_worker |
| { |
| axis2_conf_ctx_t *conf_ctx; |
| }; |
| |
| AXIS2_EXTERN axis2_apache2_worker_t *AXIS2_CALL |
| axis2_apache2_worker_create( |
| const axutil_env_t * env, |
| axis2_char_t * repo_path) |
| { |
| axis2_apache2_worker_t *apache2_worker = NULL; |
| axutil_hash_t* svc_map = NULL; |
| axis2_conf_t* conf = NULL; |
| axutil_hash_index_t *hi = NULL; |
| void* svc = NULL; |
| AXIS2_ENV_CHECK(env, NULL); |
| AXIS2_LOG_INFO(env->log, "[Axis2] Axis2 worker created"); |
| apache2_worker = (axis2_apache2_worker_t *)AXIS2_MALLOC(env->allocator, |
| sizeof(axis2_apache2_worker_t)); |
| |
| if(!apache2_worker) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); |
| return NULL; |
| } |
| apache2_worker->conf_ctx = axis2_build_conf_ctx(env, repo_path); |
| |
| if(!apache2_worker->conf_ctx) |
| { |
| axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env); |
| return NULL; |
| } |
| |
| /* |
| * we have to load all the services. This is because, before the fork (in linux) |
| * we should have a full code segment. Otherwise, we can't share function pointers of services |
| * between processed. In fork, the code segment will be duplicated across processes |
| */ |
| conf = axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env); |
| if(!conf) |
| { |
| axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env); |
| return NULL; |
| } |
| |
| svc_map = axis2_conf_get_all_svcs(conf, env); |
| if(!svc_map) |
| { |
| axis2_apache2_worker_free((axis2_apache2_worker_t *)apache2_worker, env); |
| return NULL; |
| } |
| |
| for(hi = axutil_hash_first(svc_map, env); hi; hi = axutil_hash_next(env, hi)) |
| { |
| void *impl_class = NULL; |
| axis2_msg_recv_t *msg_recv = NULL; |
| axutil_hash_t *ops_hash = NULL; |
| |
| axutil_hash_this(hi, NULL, NULL, &svc); |
| if(!svc) |
| continue; |
| impl_class = axis2_svc_get_impl_class(svc, env); |
| if(impl_class) |
| continue; |
| ops_hash = axis2_svc_get_all_ops(svc, env); |
| if(ops_hash) |
| { |
| axutil_hash_index_t *op_hi = NULL; |
| void *op = NULL; |
| op_hi = axutil_hash_first(ops_hash, env); |
| if(op_hi) |
| { |
| axutil_hash_this(op_hi, NULL, NULL, &op); |
| if(op) |
| { |
| msg_recv = axis2_op_get_msg_recv(op, env); |
| if(msg_recv) |
| { |
| axis2_msg_recv_set_conf_ctx(msg_recv, env, apache2_worker->conf_ctx); |
| axis2_msg_recv_load_and_init_svc(msg_recv, env, svc); |
| } |
| } |
| } |
| |
| } |
| } |
| |
| AXIS2_LOG_INFO(env->log, "[Axis2] Axis2 worker created"); |
| |
| return apache2_worker; |
| } |
| |
| AXIS2_EXTERN void AXIS2_CALL |
| axis2_apache2_worker_free( |
| axis2_apache2_worker_t * apache2_worker, |
| const axutil_env_t * env) |
| { |
| AXIS2_ENV_CHECK(env, void); |
| |
| if(apache2_worker->conf_ctx) |
| { |
| axis2_conf_ctx_free(apache2_worker->conf_ctx, env); |
| apache2_worker->conf_ctx = NULL; |
| } |
| |
| AXIS2_FREE(env->allocator, apache2_worker); |
| |
| return; |
| } |
| |
| AXIS2_EXTERN int AXIS2_CALL |
| axis2_apache2_worker_process_request( |
| axis2_apache2_worker_t * apache2_worker, |
| const axutil_env_t * env, |
| request_rec * request) |
| { |
| axis2_conf_ctx_t *conf_ctx = NULL; |
| axis2_msg_ctx_t *msg_ctx = NULL; |
| axutil_stream_t *request_body = NULL; |
| axutil_stream_t *out_stream = NULL; |
| axis2_transport_out_desc_t *out_desc = NULL; |
| axis2_transport_in_desc_t *in_desc = NULL; |
| axis2_char_t *http_version = NULL; |
| axutil_string_t *soap_action = NULL; |
| axis2_char_t *soap_action_header_txt = NULL; |
| axis2_bool_t processed = AXIS2_FALSE; |
| int content_length = -1; |
| axis2_char_t *url_external_form = NULL; |
| axis2_char_t *body_string = NULL; |
| unsigned int body_string_len = 0; |
| int send_status = DECLINED; |
| axis2_char_t *content_type = NULL; |
| axis2_http_out_transport_info_t *apache2_out_transport_info = NULL; |
| axis2_char_t *ctx_uuid = NULL; |
| axis2_op_ctx_t *op_ctx = NULL; |
| axis2_char_t *peer_ip = NULL; |
| axutil_property_t *peer_property = NULL; |
| axutil_url_t *request_url = NULL; |
| axis2_char_t *accept_header_value = NULL; |
| axis2_char_t *accept_charset_header_value = NULL; |
| axis2_char_t *accept_language_header_value = NULL; |
| axis2_char_t *content_language_header_value = NULL; |
| axis2_bool_t do_mtom = AXIS2_FALSE; |
| axutil_array_list_t *mime_parts = NULL; |
| axutil_param_t *callback_name_param = NULL; |
| axis2_char_t *mtom_sending_callback_name = NULL; |
| axis2_char_t *cookie = NULL; |
| axis2_char_t *header_value = NULL; |
| axis2_status_t status = AXIS2_FAILURE; |
| axutil_hash_t *headers = NULL; |
| |
| AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE); |
| AXIS2_PARAM_CHECK(env->error, request, AXIS2_CRITICAL_FAILURE); |
| |
| conf_ctx = apache2_worker->conf_ctx; |
| |
| if(!conf_ctx) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE); |
| return AXIS2_CRITICAL_FAILURE; |
| } |
| content_length = (int)request->remaining; |
| /* We are sure that the difference lies within the int range */ |
| http_version = request->protocol; |
| |
| request_url = axutil_url_create(env, "http", request->hostname, request->parsed_uri.port, |
| request->unparsed_uri); |
| if(request_url) |
| { |
| url_external_form = axutil_url_to_external_form(request_url, env); |
| AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, url_external_form); |
| axutil_url_free(request_url, env); |
| request_url = NULL; |
| } |
| else |
| { |
| send_status = OK; |
| request->status = HTTP_BAD_REQUEST; |
| return send_status; |
| } |
| |
| content_type = (axis2_char_t *)apr_table_get(request->headers_in, |
| AXIS2_HTTP_HEADER_CONTENT_TYPE); |
| if(!content_type) |
| { |
| content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN; |
| } |
| request->content_type = content_type; |
| |
| out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env), |
| env, AXIS2_TRANSPORT_ENUM_HTTP); |
| in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(apache2_worker->conf_ctx, env), |
| env, AXIS2_TRANSPORT_ENUM_HTTP); |
| { |
| axis2_transport_receiver_t *receiver = NULL; |
| receiver = axis2_transport_in_desc_get_recv(in_desc, env); |
| if(receiver) |
| axis2_transport_receiver_set_server_ip(receiver, env, request->connection->local_ip); |
| } |
| |
| msg_ctx = axis2_msg_ctx_create(env, conf_ctx, in_desc, out_desc); |
| axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); |
| |
| cookie = (axis2_char_t *)apr_table_get(request->headers_in, |
| AXIS2_HTTP_HEADER_COOKIE); |
| if(cookie) |
| { |
| char *session_str = NULL; |
| axis2_char_t *session_id = NULL; |
| |
| session_id = axis2_http_transport_utils_get_session_id_from_cookie(env, cookie); |
| if(session_id) |
| session_str = env->get_session_fn((void *) request, session_id); |
| if(session_str) |
| axis2_http_transport_utils_set_session(env, msg_ctx, session_str); |
| } |
| |
| if(request->read_chunked == AXIS2_TRUE && 0 == content_length) |
| { |
| content_length = -1; |
| request->chunked = 1; |
| } |
| if(!http_version) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE); |
| return AXIS2_CRITICAL_FAILURE; |
| } |
| out_stream = axutil_stream_create_basic(env); |
| AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Client HTTP version %s", http_version); |
| |
| #if (AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER >= 4) |
| peer_ip = request->connection->client_ip; |
| #else |
| peer_ip = request->connection->remote_ip; |
| #endif |
| |
| if(peer_ip) |
| { |
| peer_property = axutil_property_create(env); |
| axutil_property_set_value(peer_property, env, axutil_strdup(env, peer_ip)); |
| axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_SVR_PEER_IP_ADDR, peer_property); |
| } |
| |
| axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream); |
| |
| ctx_uuid = axutil_uuid_gen(env); |
| if(ctx_uuid) |
| { |
| axutil_string_t *uuid_str = axutil_string_create_assume_ownership(env, &ctx_uuid); |
| axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, uuid_str); |
| axutil_string_free(uuid_str, env); |
| } |
| |
| apache2_out_transport_info = axis2_apache2_out_transport_info_create(env, request); |
| axis2_msg_ctx_set_out_transport_info(msg_ctx, env, &(apache2_out_transport_info->out_transport)); |
| |
| accept_header_value = (axis2_char_t *)apr_table_get(request->headers_in, |
| AXIS2_HTTP_HEADER_ACCEPT); |
| if(accept_header_value) |
| { |
| axutil_array_list_t *accept_header_field_list = NULL; |
| axutil_array_list_t *accept_record_list = NULL; |
| accept_header_field_list = axutil_tokenize(env, accept_header_value, ','); |
| if(accept_header_field_list && axutil_array_list_size(accept_header_field_list, env) > 0) |
| { |
| axis2_char_t *token = NULL; |
| accept_record_list = axutil_array_list_create(env, axutil_array_list_size( |
| accept_header_field_list, env)); |
| do |
| { |
| if(token) |
| { |
| axis2_http_accept_record_t *rec = NULL; |
| rec = axis2_http_accept_record_create(env, token); |
| if(rec) |
| { |
| axutil_array_list_add(accept_record_list, env, rec); |
| } |
| AXIS2_FREE(env->allocator, token); |
| } |
| token = (axis2_char_t *)axutil_array_list_remove(accept_header_field_list, env, 0); |
| } |
| while(token); |
| } |
| if(accept_record_list && axutil_array_list_size(accept_record_list, env) > 0) |
| { |
| axis2_msg_ctx_set_http_accept_record_list(msg_ctx, env, accept_record_list); |
| } |
| } |
| |
| accept_charset_header_value = (axis2_char_t *)apr_table_get(request->headers_in, |
| AXIS2_HTTP_HEADER_ACCEPT_CHARSET); |
| if(accept_charset_header_value) |
| { |
| axutil_array_list_t *accept_charset_header_field_list = NULL; |
| axutil_array_list_t *accept_charset_record_list = NULL; |
| accept_charset_header_field_list = axutil_tokenize(env, accept_charset_header_value, ','); |
| if(accept_charset_header_field_list && axutil_array_list_size( |
| accept_charset_header_field_list, env) > 0) |
| { |
| axis2_char_t *token = NULL; |
| accept_charset_record_list = axutil_array_list_create(env, axutil_array_list_size( |
| accept_charset_header_field_list, env)); |
| do |
| { |
| if(token) |
| { |
| axis2_http_accept_record_t *rec = NULL; |
| rec = axis2_http_accept_record_create(env, token); |
| if(rec) |
| { |
| axutil_array_list_add(accept_charset_record_list, env, rec); |
| } |
| AXIS2_FREE(env->allocator, token); |
| } |
| token = (axis2_char_t *)axutil_array_list_remove(accept_charset_header_field_list, |
| env, 0); |
| } |
| while(token); |
| } |
| if(accept_charset_record_list && axutil_array_list_size(accept_charset_record_list, env) |
| > 0) |
| { |
| axis2_msg_ctx_set_http_accept_charset_record_list(msg_ctx, env, |
| accept_charset_record_list); |
| } |
| } |
| |
| accept_language_header_value = (axis2_char_t *)apr_table_get(request->headers_in, |
| AXIS2_HTTP_HEADER_ACCEPT_LANGUAGE); |
| if(accept_language_header_value) |
| { |
| axutil_array_list_t *accept_language_header_field_list = NULL; |
| axutil_array_list_t *accept_language_record_list = NULL; |
| accept_language_header_field_list = axutil_tokenize(env, accept_language_header_value, ','); |
| if(accept_language_header_field_list && axutil_array_list_size( |
| accept_language_header_field_list, env) > 0) |
| { |
| axis2_char_t *token = NULL; |
| accept_language_record_list = axutil_array_list_create(env, axutil_array_list_size( |
| accept_language_header_field_list, env)); |
| do |
| { |
| if(token) |
| { |
| axis2_http_accept_record_t *rec = NULL; |
| rec = axis2_http_accept_record_create(env, token); |
| if(rec) |
| { |
| axutil_array_list_add(accept_language_record_list, env, rec); |
| } |
| AXIS2_FREE(env->allocator, token); |
| } |
| token = (axis2_char_t *)axutil_array_list_remove(accept_language_header_field_list, |
| env, 0); |
| } |
| while(token); |
| } |
| if(accept_language_record_list && axutil_array_list_size(accept_language_record_list, env) |
| > 0) |
| { |
| axis2_msg_ctx_set_http_accept_language_record_list(msg_ctx, env, |
| accept_language_record_list); |
| } |
| } |
| |
| soap_action_header_txt = (axis2_char_t *)apr_table_get(request->headers_in, |
| AXIS2_HTTP_HEADER_SOAP_ACTION); |
| |
| if(soap_action_header_txt) |
| { |
| soap_action = axutil_string_create(env, soap_action_header_txt); |
| } |
| |
| headers = axis2_apache_worker_get_headers(env, request); |
| axis2_msg_ctx_set_transport_headers(msg_ctx, env, headers); |
| if(headers)
|
| { |
| /** Transfer encoding property set in message context is used to check whether to |
| create a chunked stream or not in transport_utils_process_request. For apache stream, |
| using chunked stream will fail. */ |
| axis2_http_header_t *encoding_header = NULL;
|
| encoding_header = (axis2_http_header_t *)axutil_hash_get(headers,
|
| AXIS2_HTTP_HEADER_TRANSFER_ENCODING, AXIS2_HASH_KEY_STRING);
|
|
|
| if(encoding_header)
|
| { |
| axis2_msg_ctx_set_transfer_encoding(msg_ctx, env, axutil_strdup(env, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED)); |
| } |
| } |
| request_body = axutil_stream_create_apache2(env, request); |
| if(!request_body) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in" |
| " creating input stream."); |
| return AXIS2_CRITICAL_FAILURE; |
| } |
| if(M_GET == request->method_number || M_DELETE == request->method_number) |
| { |
| if(M_DELETE == request->method_number) |
| { |
| processed = axis2_http_transport_utils_process_http_delete_request(env, msg_ctx, |
| request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx, |
| axis2_http_transport_utils_get_request_params(env, |
| (axis2_char_t *)url_external_form)); |
| } |
| else if(request->header_only) |
| { |
| processed = axis2_http_transport_utils_process_http_head_request(env, msg_ctx, |
| request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx, |
| axis2_http_transport_utils_get_request_params(env, |
| (axis2_char_t *)url_external_form)); |
| } |
| else |
| { |
| processed = axis2_http_transport_utils_process_http_get_request(env, msg_ctx, |
| request_body, out_stream, content_type, soap_action, url_external_form, conf_ctx, |
| axis2_http_transport_utils_get_request_params(env, |
| (axis2_char_t *)url_external_form)); |
| } |
| if(AXIS2_FALSE == processed) |
| { |
| axis2_char_t *wsdl = NULL; |
| axis2_bool_t is_services_path = AXIS2_FALSE; |
| if(M_DELETE != request->method_number) |
| { |
| axis2_char_t *temp = NULL; |
| temp = strstr(url_external_form, AXIS2_REQUEST_URL_PREFIX); |
| if(temp) |
| { |
| temp += strlen(AXIS2_REQUEST_URL_PREFIX); |
| if(*temp == '/') |
| { |
| temp++; |
| } |
| if(!*temp || *temp == '?' || *temp == '#') |
| { |
| is_services_path = AXIS2_TRUE; |
| } |
| } |
| } |
| wsdl = strstr(url_external_form, AXIS2_REQUEST_WSDL); |
| if(is_services_path) |
| { |
| body_string = axis2_http_transport_utils_get_services_html(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| } |
| else if(M_DELETE != request->method_number && wsdl) |
| { |
| body_string = axis2_http_transport_utils_get_services_static_wsdl(env, conf_ctx, |
| (axis2_char_t *)url_external_form); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML; |
| |
| } |
| else if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND) |
| { |
| axutil_array_list_t *method_list = NULL; |
| int size = 0; |
| method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env); |
| size = axutil_array_list_size(method_list, env); |
| if(method_list && size) |
| { |
| axis2_char_t *method_list_str = NULL; |
| axis2_char_t *temp; |
| int i = 0; |
| method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29); |
| temp = method_list_str; |
| request->allowed_methods->method_mask = 0; |
| for(i = 0; i < size; i++) |
| { |
| if(i) |
| { |
| sprintf(temp, ", "); |
| temp += 2; |
| } |
| sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env, |
| i)); |
| temp += strlen(temp); |
| /* Conditions below is to assist down-stream modules */ |
| if(!axutil_strcasecmp(AXIS2_HTTP_PUT, (axis2_char_t *)axutil_array_list_get( |
| method_list, env, i))) |
| { |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_PUT; |
| } |
| else if(!axutil_strcasecmp(AXIS2_HTTP_POST, (axis2_char_t *)axutil_array_list_get( |
| method_list, env, i))) |
| { |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_POST; |
| } |
| else if(!axutil_strcasecmp(AXIS2_HTTP_GET, (axis2_char_t *)axutil_array_list_get( |
| method_list, env, i))) |
| { |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET; |
| } |
| else if(!axutil_strcasecmp(AXIS2_HTTP_HEAD, (axis2_char_t *)axutil_array_list_get( |
| method_list, env, i))) |
| { |
| /* Apache Can't differentiate between HEAD and GET */ |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET; |
| } |
| else if(!axutil_strcasecmp(AXIS2_HTTP_DELETE, |
| (axis2_char_t *)axutil_array_list_get(method_list, env, i))) |
| { |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_DELETE; |
| } |
| } |
| *temp = '\0'; |
| apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_ALLOW, |
| method_list_str); |
| AXIS2_FREE(env->allocator, method_list_str); |
| body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx); |
| request->status = HTTP_METHOD_NOT_ALLOWED; |
| } |
| else |
| { |
| body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx); |
| request->status = HTTP_NOT_FOUND; |
| } |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| } |
| else if(axis2_msg_ctx_get_status_code(msg_ctx, env) |
| == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL) |
| { |
| body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_BAD_REQUEST; |
| } |
| else if(axis2_msg_ctx_get_status_code(msg_ctx, env) |
| == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL) |
| { |
| body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_REQUEST_TIME_OUT; |
| } |
| else if(axis2_msg_ctx_get_status_code(msg_ctx, env) |
| == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL) |
| { |
| body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_CONFLICT; |
| } |
| else if(axis2_msg_ctx_get_status_code(msg_ctx, env) |
| == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL) |
| { |
| body_string = axis2_http_transport_utils_get_gone(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_GONE; |
| } |
| else if(axis2_msg_ctx_get_status_code(msg_ctx, env) |
| == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL) |
| { |
| body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_PRECONDITION_FAILED; |
| } |
| else if(axis2_msg_ctx_get_status_code(msg_ctx, env) |
| == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL) |
| { |
| body_string = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_REQUEST_ENTITY_TOO_LARGE; |
| } |
| else if(axis2_msg_ctx_get_status_code(msg_ctx, env) |
| == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL) |
| { |
| body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_SERVICE_UNAVAILABLE; |
| } |
| else |
| { |
| body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_INTERNAL_SERVER_ERROR; |
| } |
| |
| if(body_string) |
| { |
| body_string_len = axutil_strlen(body_string); |
| } |
| send_status = OK; |
| } |
| } |
| else if(M_POST == request->method_number || M_PUT == request->method_number) |
| { |
| /*axis2_status_t status = AXIS2_FAILURE;*/ |
| if(M_POST == request->method_number) |
| { |
| status = axis2_http_transport_utils_process_http_post_request(env, msg_ctx, |
| request_body, out_stream, content_type, content_length, soap_action, |
| (axis2_char_t *)url_external_form); |
| } |
| else |
| { |
| status = axis2_http_transport_utils_process_http_put_request(env, msg_ctx, |
| request_body, out_stream, content_type, content_length, soap_action, |
| (axis2_char_t *)url_external_form); |
| } |
| if(AXIS2_FAILURE == status && (M_PUT == request->method_number |
| || axis2_msg_ctx_get_doing_rest(msg_ctx, env))) |
| { |
| if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND) |
| { |
| axutil_array_list_t *method_list = NULL; |
| int size = 0; |
| method_list = axis2_msg_ctx_get_supported_rest_http_methods(msg_ctx, env); |
| size = axutil_array_list_size(method_list, env); |
| if(method_list && size) |
| { |
| axis2_char_t *method_list_str = NULL; |
| axis2_char_t *temp; |
| int i = 0; |
| method_list_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 29); |
| temp = method_list_str; |
| request->allowed_methods->method_mask = 0; |
| for(i = 0; i < size; i++) |
| { |
| if(i) |
| { |
| sprintf(temp, ", "); |
| temp += 2; |
| } |
| sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env, |
| i)); |
| temp += strlen(temp); |
| /* Conditions below is to assist down-stream modules */ |
| if(!axutil_strcasecmp(AXIS2_HTTP_PUT, (axis2_char_t *)axutil_array_list_get( |
| method_list, env, i))) |
| { |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_PUT; |
| } |
| else if(!axutil_strcasecmp(AXIS2_HTTP_POST, (axis2_char_t *)axutil_array_list_get( |
| method_list, env, i))) |
| { |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_POST; |
| } |
| else if(!axutil_strcasecmp(AXIS2_HTTP_GET, (axis2_char_t *)axutil_array_list_get( |
| method_list, env, i))) |
| { |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET; |
| } |
| else if(!axutil_strcasecmp(AXIS2_HTTP_HEAD, (axis2_char_t *)axutil_array_list_get( |
| method_list, env, i))) |
| { |
| /* Apache Can't differentiate between HEAD and GET */ |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_GET; |
| } |
| else if(!axutil_strcasecmp(AXIS2_HTTP_DELETE, |
| (axis2_char_t *)axutil_array_list_get(method_list, env, i))) |
| { |
| request->allowed_methods->method_mask |= AP_METHOD_BIT << M_DELETE; |
| } |
| } |
| *temp = '\0'; |
| apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_ALLOW, |
| method_list_str); |
| AXIS2_FREE(env->allocator, method_list_str); |
| body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx); |
| request->status = HTTP_METHOD_NOT_ALLOWED; |
| } |
| else |
| { |
| body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx); |
| request->status = HTTP_NOT_FOUND; |
| } |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| } |
| else |
| { |
| body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| request->status = HTTP_INTERNAL_SERVER_ERROR; |
| } |
| |
| if(body_string) |
| { |
| body_string_len = axutil_strlen(body_string); |
| } |
| send_status = OK; |
| } |
| else if(status == AXIS2_FAILURE) |
| { |
| axis2_msg_ctx_t *fault_ctx = NULL; |
| axis2_char_t *fault_code = NULL; |
| axis2_engine_t *engine = axis2_engine_create(env, conf_ctx); |
| if(!engine) |
| { |
| /* Critical error, cannot proceed, Apache will send default |
| document for 500 |
| */ |
| return AXIS2_CRITICAL_FAILURE; |
| } |
| if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) |
| { |
| fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" |
| AXIOM_SOAP11_FAULT_CODE_SENDER; |
| } |
| else |
| { |
| fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX ":" |
| AXIOM_SOAP12_SOAP_FAULT_VALUE_SENDER; |
| } |
| fault_ctx = axis2_engine_create_fault_msg_ctx(engine, env, msg_ctx, |
| fault_code, |
| axutil_error_get_message |
| (env->error)); |
| axis2_engine_send_fault(engine, env, fault_ctx); |
| if (out_stream) |
| { |
| body_string = axutil_stream_get_buffer(out_stream, env); |
| body_string_len = axutil_stream_get_len(out_stream, env); |
| } |
| |
| /* In case of a SOAP Fault, we have to set the status to 500, |
| but still return OK because the module has handled the error |
| */ |
| send_status = OK; |
| request->status = HTTP_INTERNAL_SERVER_ERROR; |
| } |
| } |
| else |
| { |
| body_string = |
| axis2_http_transport_utils_get_not_implemented(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| |
| if (body_string) |
| { |
| body_string_len = axutil_strlen(body_string); |
| } |
| send_status = OK; |
| request->status = HTTP_NOT_IMPLEMENTED; |
| } |
| |
| op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); |
| |
| if (op_ctx) |
| { |
| axis2_msg_ctx_t *out_msg_ctx = NULL; |
| axis2_msg_ctx_t **msg_ctx_map = NULL; |
| |
| msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); |
| out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; |
| if (out_msg_ctx) |
| { |
| content_language_header_value = axis2_msg_ctx_get_content_language(out_msg_ctx, env); |
| } |
| } |
| |
| if (send_status == DECLINED) |
| { |
| axis2_bool_t do_rest = AXIS2_FALSE; |
| if (M_POST != request->method_number || |
| axis2_msg_ctx_get_doing_rest(msg_ctx, env)) |
| { |
| do_rest = AXIS2_TRUE; |
| } |
| if ((accept_header_value || accept_charset_header_value || |
| accept_language_header_value) && do_rest) |
| { |
| axis2_char_t *content_type_header_value = NULL; |
| axis2_char_t *temp = NULL; |
| axis2_char_t *language_header_value = NULL; |
| |
| content_type_header_value = (axis2_char_t *) request->content_type; |
| language_header_value = content_language_header_value; |
| if (content_type_header_value) |
| { |
| temp = axutil_strdup(env, content_type_header_value); |
| } |
| if (temp) |
| { |
| axis2_char_t *content_type = NULL; |
| axis2_char_t *char_set = NULL; |
| axis2_char_t *temp2 = NULL; |
| |
| temp2 = strchr(temp, ';'); |
| if (temp2) |
| { |
| *temp2 = '\0'; |
| temp2++; |
| char_set = axutil_strcasestr(temp2, AXIS2_HTTP_CHAR_SET_ENCODING); |
| } |
| if (char_set) |
| { |
| char_set = axutil_strltrim(env, char_set, " \t="); |
| } |
| if (char_set) |
| { |
| temp2 = strchr(char_set, ';'); |
| } |
| if (temp2) |
| { |
| *temp2 = '\0'; |
| } |
| content_type = axutil_strtrim(env, temp, NULL); |
| |
| if (temp) |
| { |
| AXIS2_FREE(env->allocator, temp); |
| temp = NULL; |
| } |
| if (content_type && accept_header_value && |
| !axutil_strcasestr(accept_header_value, content_type)) |
| { |
| temp2 = strchr(content_type, '/'); |
| if (temp2) |
| { |
| *temp2 = '\0'; |
| temp = AXIS2_MALLOC(env->allocator, |
| sizeof(axis2_char_t) * ((int)strlen(content_type) + 3)); |
| if (!temp) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); |
| return AXIS2_FALSE; |
| } |
| sprintf(temp, "%s/*", content_type); |
| if (!axutil_strcasestr(accept_header_value, temp) && |
| !strstr(accept_header_value, AXIS2_HTTP_HEADER_ACCEPT_ALL)) |
| { |
| body_string = |
| axis2_http_transport_utils_get_not_acceptable(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| |
| if (body_string) |
| { |
| body_string_len = axutil_strlen(body_string); |
| } |
| send_status = OK; |
| request->status = HTTP_NOT_ACCEPTABLE; |
| } |
| AXIS2_FREE(env->allocator, temp); |
| } |
| } |
| if (content_type) |
| { |
| AXIS2_FREE(env->allocator, content_type); |
| } |
| if (char_set && accept_charset_header_value && |
| !axutil_strcasestr(accept_charset_header_value, char_set)) |
| { |
| body_string = |
| axis2_http_transport_utils_get_not_acceptable(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| |
| if (body_string) |
| { |
| body_string_len = axutil_strlen(body_string); |
| } |
| send_status = OK; |
| request->status = HTTP_NOT_ACCEPTABLE; |
| } |
| if (char_set) |
| { |
| AXIS2_FREE(env->allocator, char_set); |
| } |
| } |
| if (language_header_value) |
| { |
| if (accept_language_header_value && |
| !axutil_strcasestr(accept_language_header_value, language_header_value)) |
| { |
| body_string = |
| axis2_http_transport_utils_get_not_acceptable(env, conf_ctx); |
| request->content_type = AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML; |
| |
| if (body_string) |
| { |
| body_string_len = axutil_strlen(body_string); |
| } |
| send_status = OK; |
| request->status = HTTP_NOT_ACCEPTABLE; |
| } |
| } |
| } |
| } |
| |
| header_value = axis2_http_transport_utils_get_session(env, msg_ctx); |
| if(header_value) |
| { |
| axis2_http_out_transport_info_t *out_info = NULL; |
| out_info = (axis2_http_out_transport_info_t *)axis2_msg_ctx_get_out_transport_info(msg_ctx, env); |
| AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_COOKIE_HEADER(out_info, env, header_value); |
| } |
| if (send_status == DECLINED) |
| { |
| axis2_bool_t do_rest = AXIS2_FALSE; |
| if (M_POST != request->method_number || |
| axis2_msg_ctx_get_doing_rest(msg_ctx, env)) |
| { |
| do_rest = AXIS2_TRUE; |
| } |
| if (op_ctx && axis2_op_ctx_get_response_written(op_ctx, env)) |
| { |
| if (do_rest) |
| { |
| axis2_msg_ctx_t *out_msg_ctx = NULL; |
| axis2_msg_ctx_t *in_msg_ctx = NULL; |
| axis2_msg_ctx_t **msg_ctx_map = NULL; |
| |
| msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); |
| out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; |
| in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN]; |
| if (in_msg_ctx) |
| { |
| /* TODO: Add necessary handling */ |
| } |
| if (out_msg_ctx) |
| { |
| int size = 0; |
| axutil_array_list_t *output_header_list = NULL; |
| output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env); |
| if (output_header_list) |
| { |
| size = axutil_array_list_size(output_header_list, env); |
| } |
| while (size) |
| { |
| axis2_http_header_t *output_header = NULL; |
| size--; |
| output_header = (axis2_http_header_t *) |
| axutil_array_list_get(output_header_list, env, size); |
| apr_table_set(request->err_headers_out, |
| axis2_http_header_get_name(output_header, env), |
| axis2_http_header_get_value(output_header, env)); |
| } |
| if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) |
| { |
| int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); |
| switch (status_code) |
| { |
| case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL: |
| request->status = HTTP_CONTINUE; |
| break; |
| case AXIS2_HTTP_RESPONSE_ACK_CODE_VAL: |
| request->status = HTTP_ACCEPTED; |
| break; |
| case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL: |
| request->status = HTTP_MULTIPLE_CHOICES; |
| break; |
| case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL: |
| request->status = HTTP_MOVED_PERMANENTLY; |
| break; |
| case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL: |
| request->status = HTTP_SEE_OTHER; |
| break; |
| case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: |
| request->status = HTTP_NOT_MODIFIED; |
| break; |
| case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL: |
| request->status = HTTP_TEMPORARY_REDIRECT; |
| break; |
| case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL: |
| request->status = HTTP_BAD_REQUEST; |
| break; |
| case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL: |
| request->status = HTTP_REQUEST_TIME_OUT; |
| break; |
| case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL: |
| request->status = HTTP_CONFLICT; |
| break; |
| case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL: |
| request->status = HTTP_GONE; |
| break; |
| case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL: |
| request->status = HTTP_PRECONDITION_FAILED; |
| break; |
| case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL: |
| request->status = HTTP_REQUEST_ENTITY_TOO_LARGE; |
| break; |
| case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL: |
| request->status = HTTP_SERVICE_UNAVAILABLE; |
| break; |
| default: |
| request->status = HTTP_OK; |
| break; |
| } |
| send_status = DONE; |
| } |
| } |
| } |
| if (send_status == DECLINED) |
| { |
| send_status = OK; |
| if (out_stream) |
| { |
| body_string = axutil_stream_get_buffer(out_stream, env); |
| body_string_len = axutil_stream_get_len(out_stream, env); |
| } |
| } |
| } |
| else if (op_ctx) |
| { |
| if (do_rest) |
| { |
| axis2_msg_ctx_t *out_msg_ctx = NULL; |
| axis2_msg_ctx_t *in_msg_ctx = NULL; |
| axis2_msg_ctx_t **msg_ctx_map = NULL; |
| |
| msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); |
| out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; |
| in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN]; |
| if (in_msg_ctx) |
| { |
| /* TODO: Add necessary handling */ |
| } |
| if (out_msg_ctx) |
| { |
| int size = 0; |
| axutil_array_list_t *output_header_list = NULL; |
| output_header_list = axis2_msg_ctx_get_http_output_headers(out_msg_ctx, env); |
| if (output_header_list) |
| { |
| size = axutil_array_list_size(output_header_list, env); |
| } |
| while (size) |
| { |
| axis2_http_header_t *output_header = NULL; |
| size--; |
| output_header = (axis2_http_header_t *) |
| axutil_array_list_get(output_header_list, env, size); |
| apr_table_set(request->err_headers_out, |
| axis2_http_header_get_name(output_header, env), |
| axis2_http_header_get_value(output_header, env)); |
| } |
| if (axis2_msg_ctx_get_no_content(out_msg_ctx, env)) |
| { |
| if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) |
| { |
| int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); |
| switch (status_code) |
| { |
| case AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL: |
| request->status = HTTP_RESET_CONTENT; |
| break; |
| case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: |
| request->status = HTTP_NOT_MODIFIED; |
| break; |
| default: |
| request->status = HTTP_NO_CONTENT; |
| break; |
| } |
| } |
| else |
| { |
| request->status = HTTP_NO_CONTENT; |
| } |
| send_status = DONE; |
| } |
| else if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) |
| { |
| int status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); |
| switch (status_code) |
| { |
| case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL: |
| request->status = HTTP_CONTINUE; |
| break; |
| case AXIS2_HTTP_RESPONSE_OK_CODE_VAL: |
| request->status = HTTP_OK; |
| break; |
| case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL: |
| request->status = HTTP_MULTIPLE_CHOICES; |
| break; |
| case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL: |
| request->status = HTTP_MOVED_PERMANENTLY; |
| break; |
| case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL: |
| request->status = HTTP_SEE_OTHER; |
| break; |
| case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: |
| request->status = HTTP_NOT_MODIFIED; |
| break; |
| case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL: |
| request->status = HTTP_TEMPORARY_REDIRECT; |
| break; |
| case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL: |
| request->status = HTTP_BAD_REQUEST; |
| break; |
| case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL: |
| request->status = HTTP_REQUEST_TIME_OUT; |
| break; |
| case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL: |
| request->status = HTTP_CONFLICT; |
| break; |
| case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL: |
| request->status = HTTP_GONE; |
| break; |
| case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL: |
| request->status = HTTP_PRECONDITION_FAILED; |
| break; |
| case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL: |
| request->status = HTTP_REQUEST_ENTITY_TOO_LARGE; |
| break; |
| case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL: |
| request->status = HTTP_SERVICE_UNAVAILABLE; |
| break; |
| default: |
| request->status = HTTP_ACCEPTED; |
| break; |
| } |
| send_status = DONE; |
| } |
| } |
| } |
| if (send_status == DECLINED) |
| { |
| if (msg_ctx) |
| { |
| int size = 0; |
| int status_code; |
| axutil_array_list_t *output_header_list = NULL; |
| output_header_list = axis2_msg_ctx_get_http_output_headers(msg_ctx, env); |
| if (output_header_list) |
| { |
| size = axutil_array_list_size(output_header_list, env); |
| } |
| while (size) |
| { |
| axis2_http_header_t *output_header = NULL; |
| size--; |
| output_header = (axis2_http_header_t *) |
| axutil_array_list_get(output_header_list, env, size); |
| apr_table_set(request->err_headers_out, |
| axis2_http_header_get_name(output_header, env), |
| axis2_http_header_get_value(output_header, env)); |
| } |
| |
| status_code = axis2_msg_ctx_get_status_code(msg_ctx, env); |
| switch (status_code) |
| { |
| case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL: |
| request->status = HTTP_CONTINUE; |
| break; |
| case AXIS2_HTTP_RESPONSE_OK_CODE_VAL: |
| request->status = HTTP_OK; |
| break; |
| case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL: |
| request->status = HTTP_MULTIPLE_CHOICES; |
| break; |
| case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL: |
| request->status = HTTP_MOVED_PERMANENTLY; |
| break; |
| case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL: |
| request->status = HTTP_SEE_OTHER; |
| break; |
| case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: |
| request->status = HTTP_NOT_MODIFIED; |
| break; |
| case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL: |
| request->status = HTTP_TEMPORARY_REDIRECT; |
| break; |
| case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL: |
| request->status = HTTP_BAD_REQUEST; |
| break; |
| case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL: |
| request->status = HTTP_REQUEST_TIME_OUT; |
| break; |
| case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL: |
| request->status = HTTP_CONFLICT; |
| break; |
| case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL: |
| request->status = HTTP_GONE; |
| break; |
| case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL: |
| request->status = HTTP_PRECONDITION_FAILED; |
| break; |
| case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL: |
| request->status = HTTP_REQUEST_ENTITY_TOO_LARGE; |
| break; |
| case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL: |
| request->status = HTTP_SERVICE_UNAVAILABLE; |
| break; |
| case AXIS2_HTTP_RESPONSE_FORBIDDEN_CODE_VAL: |
| request->status = HTTP_FORBIDDEN; |
| break; |
| case AXIS2_HTTP_RESPONSE_HTTP_UNAUTHORIZED_CODE_VAL: |
| request->status = HTTP_UNAUTHORIZED; |
| break; |
| default: |
| request->status = HTTP_ACCEPTED; |
| break; |
| } |
| |
| out_stream = axis2_msg_ctx_get_transport_out_stream(msg_ctx, env); |
| if (out_stream) |
| { |
| body_string = axutil_stream_get_buffer(out_stream, env); |
| body_string_len = axutil_stream_get_len(out_stream, env); |
| } |
| send_status = DONE; |
| } |
| else |
| { |
| request->status = HTTP_ACCEPTED; |
| send_status = DONE; |
| } |
| } |
| } |
| else |
| { |
| send_status = DONE; |
| request->status = HTTP_ACCEPTED; |
| } |
| } |
| |
| if (content_language_header_value) |
| { |
| apr_table_set(request->err_headers_out, AXIS2_HTTP_HEADER_CONTENT_LANGUAGE, |
| content_language_header_value); |
| } |
| |
| if (op_ctx) |
| { |
| axis2_msg_ctx_t *out_msg_ctx = NULL, |
| *in_msg_ctx = NULL; |
| axis2_msg_ctx_t **msg_ctx_map = NULL; |
| axis2_char_t *msg_id = NULL; |
| axis2_conf_ctx_t *conf_ctx = NULL; |
| msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_ctx, env); |
| |
| out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT]; |
| in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN]; |
| |
| /* In mtom case we send the attachment differently */ |
| |
| /* status = AXIS2_FAILURE means fault scenario. We are not |
| * doing MTOM for fault cases. */ |
| |
| if(status != AXIS2_FAILURE) |
| { |
| do_mtom = axis2_msg_ctx_get_doing_mtom(out_msg_ctx, env); |
| if(do_mtom) |
| { |
| mime_parts = axis2_msg_ctx_get_mime_parts(out_msg_ctx, env); |
| if(!mime_parts) |
| { |
| return AXIS2_FAILURE; |
| } |
| 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 (out_msg_ctx) |
| { |
| axis2_msg_ctx_free(out_msg_ctx, env); |
| out_msg_ctx = NULL; |
| msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL; |
| } |
| |
| if (in_msg_ctx) |
| { |
| msg_id = |
| axutil_strdup(env, axis2_msg_ctx_get_msg_id(in_msg_ctx, env)); |
| conf_ctx = axis2_msg_ctx_get_conf_ctx(in_msg_ctx, env); |
| axis2_msg_ctx_reset_out_transport_info(in_msg_ctx, env); |
| axis2_msg_ctx_free(in_msg_ctx, env); |
| in_msg_ctx = NULL; |
| msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL; |
| } |
| |
| if (!axis2_op_ctx_is_in_use(op_ctx, env)) |
| { |
| axis2_op_ctx_destroy_mutex(op_ctx, env); |
| if (conf_ctx && msg_id) |
| { |
| axis2_conf_ctx_register_op_ctx(conf_ctx, env, msg_id, NULL); |
| AXIS2_FREE(env->allocator, msg_id); |
| } |
| axis2_op_ctx_free(op_ctx, env); |
| } |
| |
| } /* Done freeing message contexts */ |
| |
| /* We send the message in parts when doing MTOM */ |
| |
| if(do_mtom) |
| { |
| axis2_status_t mtom_status = AXIS2_FAILURE; |
| |
| if(!mtom_sending_callback_name) |
| { |
| /* 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(!mtom_sending_callback_name) |
| { |
| if(axis2_http_transport_utils_is_callback_required( |
| env, mime_parts)) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Sender callback not specified"); |
| return AXIS2_FAILURE; |
| } |
| } |
| } |
| |
| mtom_status = apache2_worker_send_mtom_message(request, env, mime_parts, |
| mtom_sending_callback_name); |
| if(mtom_status == AXIS2_SUCCESS) |
| { |
| send_status = DONE; |
| } |
| else |
| { |
| send_status = DECLINED; |
| } |
| |
| axis2_http_transport_utils_destroy_mime_parts(mime_parts, env); |
| mime_parts = NULL; |
| } |
| |
| else if (body_string) |
| { |
| ap_rwrite(body_string, body_string_len, request); |
| body_string = NULL; |
| } |
| |
| if (request_body) |
| { |
| axutil_stream_free(request_body, env); |
| request_body = NULL; |
| } |
| |
| axutil_string_free(soap_action, env); |
| |
| msg_ctx = NULL; |
| return send_status; |
| } |
| |
| AXIS2_EXTERN axis2_char_t *AXIS2_CALL |
| axis2_apache2_worker_get_bytes( |
| const axutil_env_t * env, |
| axutil_stream_t * stream) |
| { |
| |
| axutil_stream_t *tmp_stream = NULL; |
| int return_size = -1; |
| axis2_char_t *buffer = NULL; |
| axis2_bool_t loop_status = AXIS2_TRUE; |
| |
| AXIS2_ENV_CHECK(env, NULL); |
| AXIS2_PARAM_CHECK(env->error, stream, NULL); |
| |
| tmp_stream = axutil_stream_create_basic(env); |
| while(loop_status) |
| { |
| int read = 0; |
| int write = 0; |
| |
| char buf[READ_SIZE]; |
| read = axutil_stream_read(stream, env, buf, READ_SIZE); |
| if(read < 0) |
| { |
| break; |
| } |
| write = axutil_stream_write(tmp_stream, env, buf, read); |
| if(read < (READ_SIZE - 1)) |
| { |
| break; |
| } |
| } |
| return_size = axutil_stream_get_len(tmp_stream, env); |
| |
| if(return_size > 0) |
| { |
| buffer = (char *)AXIS2_MALLOC(env->allocator, sizeof(char) * (return_size + 2)); |
| return_size = axutil_stream_read(tmp_stream, env, buffer, return_size + 1); |
| buffer[return_size + 1] = '\0'; |
| } |
| axutil_stream_free(tmp_stream, env); |
| return buffer; |
| } |
| |
| static axis2_status_t |
| apache2_worker_send_mtom_message( |
| request_rec *request, |
| const axutil_env_t * env, |
| axutil_array_list_t *mime_parts, |
| axis2_char_t *mtom_sending_callback_name) |
| { |
| int i = 0; |
| axiom_mime_part_t *mime_part = NULL; |
| axis2_status_t status = AXIS2_SUCCESS; |
| /*int written = 0;*/ |
| int len = 0; |
| |
| if(mime_parts) |
| { |
| for(i = 0; i < axutil_array_list_size(mime_parts, env); i++) |
| { |
| mime_part = (axiom_mime_part_t *)axutil_array_list_get(mime_parts, env, i); |
| if((mime_part->type) == AXIOM_MIME_PART_BUFFER) |
| { |
| len = 0; |
| len = ap_rwrite(mime_part->part, (int)mime_part->part_size, request); |
| ap_rflush(request); |
| if(len == -1) |
| { |
| status = AXIS2_FAILURE; |
| break; |
| } |
| } |
| else if((mime_part->type) == AXIOM_MIME_PART_FILE) |
| { |
| FILE *f = NULL; |
| axis2_byte_t *output_buffer = NULL; |
| int output_buffer_size = 0; |
| |
| f = fopen(mime_part->file_name, "rb"); |
| if(!f) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error opening file %s for reading", |
| mime_part->file_name); |
| return AXIS2_FAILURE; |
| } |
| if(mime_part->part_size > AXIS2_MTOM_OUTPUT_BUFFER_SIZE) |
| { |
| output_buffer_size = AXIS2_MTOM_OUTPUT_BUFFER_SIZE; |
| } |
| else |
| { |
| output_buffer_size = (int)mime_part->part_size; |
| } |
| |
| output_buffer = AXIS2_MALLOC(env->allocator, (output_buffer_size + 1) |
| * sizeof(axis2_char_t)); |
| |
| status = apache2_worker_send_attachment_using_file(env, request, f, output_buffer, |
| output_buffer_size); |
| if(status == AXIS2_FAILURE) |
| { |
| return status; |
| } |
| } |
| else if((mime_part->type) == AXIOM_MIME_PART_CALLBACK) |
| { |
| void *handler = NULL; |
| axiom_mtom_sending_callback_t *callback = NULL; |
| |
| handler = axis2_http_transport_utils_initiate_callback(env, |
| mtom_sending_callback_name, mime_part->user_param, &callback); |
| |
| if(handler) |
| { |
| status = apache2_worker_send_attachment_using_callback(env, request, callback, |
| handler, mime_part->user_param); |
| } |
| else |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MTOM Sending Callback loading failed"); |
| status = AXIS2_FAILURE; |
| } |
| if(callback) |
| { |
| axutil_param_t *param = NULL; |
| |
| param = callback->param; |
| |
| AXIOM_MTOM_SENDING_CALLBACK_FREE(callback, env); |
| callback = NULL; |
| |
| if(param) |
| { |
| axutil_param_free(param, env); |
| param = NULL; |
| } |
| |
| } |
| |
| if(status == AXIS2_FAILURE) |
| { |
| return status; |
| } |
| } |
| else |
| { |
| return AXIS2_FAILURE; |
| } |
| if(status == AXIS2_FAILURE) |
| { |
| break; |
| } |
| } |
| return status; |
| } |
| else |
| { |
| return AXIS2_FAILURE; |
| } |
| } |
| |
| static axis2_status_t |
| apache2_worker_send_attachment_using_file( |
| const axutil_env_t * env, |
| request_rec *request, |
| FILE *fp, |
| axis2_byte_t *buffer, |
| int buffer_size) |
| { |
| |
| int count = 0; |
| int len = 0; |
| /*int written = 0;*/ |
| axis2_status_t status = AXIS2_SUCCESS; |
| |
| do |
| { |
| count = (int)fread(buffer, 1, buffer_size + 1, fp); |
| if(ferror(fp)) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in reading file containg the attachment"); |
| if(buffer) |
| { |
| AXIS2_FREE(env->allocator, buffer); |
| buffer = NULL; |
| } |
| fclose(fp); |
| return AXIS2_FAILURE; |
| } |
| |
| if(count > 0) |
| { |
| len = 0; |
| len = ap_rwrite(buffer, count, request); |
| ap_rflush(request); |
| if(len == -1) |
| { |
| status = AXIS2_FAILURE; |
| break; |
| } |
| } |
| else |
| { |
| if(buffer) |
| { |
| AXIS2_FREE(env->allocator, buffer); |
| buffer = NULL; |
| } |
| fclose(fp); |
| return AXIS2_FAILURE; |
| } |
| memset(buffer, 0, buffer_size); |
| if(status == AXIS2_FAILURE) |
| { |
| if(buffer) |
| { |
| AXIS2_FREE(env->allocator, buffer); |
| buffer = NULL; |
| } |
| fclose(fp); |
| return AXIS2_FAILURE; |
| } |
| } |
| while(!feof(fp)); |
| |
| fclose(fp); |
| AXIS2_FREE(env->allocator, buffer); |
| buffer = NULL; |
| return AXIS2_SUCCESS; |
| } |
| |
| static axis2_status_t |
| apache2_worker_send_attachment_using_callback( |
| const axutil_env_t * env, |
| request_rec *request, |
| axiom_mtom_sending_callback_t *callback, |
| void *handler, |
| void *user_param) |
| { |
| int count = 0; |
| int len = 0; |
| axis2_status_t status = AXIS2_SUCCESS; |
| axis2_char_t *buffer = NULL; |
| |
| /* Keep on loading the data in a loop until |
| * all the data is sent */ |
| |
| while((count = AXIOM_MTOM_SENDING_CALLBACK_LOAD_DATA(callback, env, handler, &buffer)) > 0) |
| { |
| len = 0; |
| len = ap_rwrite(buffer, count, request); |
| ap_rflush(request); |
| if(len == -1) |
| { |
| status = AXIS2_FAILURE; |
| break; |
| } |
| } |
| |
| if(status == AXIS2_FAILURE) |
| { |
| AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, handler); |
| return status; |
| } |
| |
| status = AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, handler); |
| return status; |
| } |
| |
| |
| static axutil_hash_t* |
| axis2_apache_worker_get_headers( |
| const axutil_env_t *env, |
| request_rec *request) |
| { |
| int i = 0; |
| axutil_hash_t *header_map = NULL; |
| const apr_array_header_t *tarr; |
| const apr_table_entry_t *telts; |
| axis2_http_header_t * tmp_http_header = NULL; |
| |
| |
| header_map = axutil_hash_make(env); |
| tarr = apr_table_elts(request->headers_in); |
| telts = (const apr_table_entry_t*)tarr->elts; |
| |
| for (i = 0; i < tarr->nelts; i++) |
| { |
| axis2_char_t* tmp_key = (axis2_char_t*) telts[i].key; |
| axis2_char_t* tmp_value = (axis2_char_t*) telts[i].val; |
| tmp_http_header = axis2_http_header_create(env, tmp_key, tmp_value); |
| axutil_hash_set(header_map, tmp_key, AXIS2_HASH_KEY_STRING, tmp_http_header); |
| } |
| |
| return header_map; |
| |
| |
| } |