diff options
author | gmcdonald | 2010-02-13 01:32:03 +0000 |
---|---|---|
committer | gmcdonald | 2010-02-13 01:32:03 +0000 |
commit | 0425aadc78680e53000fd0108b540d6eca048516 (patch) | |
tree | 8ec7ab8e015d454c5ec586dfc91e05a2dce1cfc0 /src/core/transport/http/common | |
download | axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.gz axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.bz2 |
Moving axis svn, part of TLP move INFRA-2441
git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/core/transport/http/common')
-rw-r--r-- | src/core/transport/http/common/Makefile.am | 29 | ||||
-rw-r--r-- | src/core/transport/http/common/http_accept_record.c | 165 | ||||
-rw-r--r-- | src/core/transport/http/common/http_header.c | 168 | ||||
-rw-r--r-- | src/core/transport/http/common/http_out_transport_info.c | 353 | ||||
-rw-r--r-- | src/core/transport/http/common/http_request_line.c | 227 | ||||
-rw-r--r-- | src/core/transport/http/common/http_response_writer.c | 176 | ||||
-rw-r--r-- | src/core/transport/http/common/http_simple_request.c | 433 | ||||
-rw-r--r-- | src/core/transport/http/common/http_simple_response.c | 615 | ||||
-rw-r--r-- | src/core/transport/http/common/http_status_line.c | 267 | ||||
-rw-r--r-- | src/core/transport/http/common/http_worker.c | 2064 | ||||
-rw-r--r-- | src/core/transport/http/common/simple_http_svr_conn.c | 504 |
11 files changed, 5001 insertions, 0 deletions
diff --git a/src/core/transport/http/common/Makefile.am b/src/core/transport/http/common/Makefile.am new file mode 100644 index 0000000..8aaa2c6 --- /dev/null +++ b/src/core/transport/http/common/Makefile.am @@ -0,0 +1,29 @@ +lib_LTLIBRARIES = libaxis2_http_common.la + +libaxis2_http_common_la_LIBADD=$(top_builddir)/util/src/libaxutil.la\ + $(top_builddir)/src/core/transport/http/util/libaxis2_http_util.la + +libaxis2_http_common_la_SOURCES = http_header.c\ + http_out_transport_info.c\ + http_request_line.c\ + http_simple_request.c\ + http_simple_response.c\ + http_status_line.c\ + http_accept_record.c\ + http_response_writer.c\ + simple_http_svr_conn.c\ + http_worker.c + + +libaxis2_http_common_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport\ + -I$(top_builddir)/src/core/transport/http \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/http/common/http_accept_record.c b/src/core/transport/http/common/http_accept_record.c new file mode 100644 index 0000000..25f15b1 --- /dev/null +++ b/src/core/transport/http/common/http_accept_record.c @@ -0,0 +1,165 @@ +/* + * 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_accept_record.h> +#include <axutil_string.h> +#include <axutil_types.h> +#include <stdio.h> +#include <stdlib.h> +#include <axis2_http_transport.h> + +struct axis2_http_accept_record +{ + axis2_char_t *name; + float quality; + int level; + axis2_char_t *record; +}; + +AXIS2_EXTERN axis2_http_accept_record_t *AXIS2_CALL +axis2_http_accept_record_create( + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_char_t *tmp_accept_record = NULL; + axis2_char_t *tmp = NULL; + axis2_http_accept_record_t *accept_record = NULL; + float quality = 1.0; + int level = -1; + axis2_char_t *name = NULL; + + AXIS2_PARAM_CHECK(env->error, str, NULL); + + tmp_accept_record = (axis2_char_t *)axutil_strdup(env, str); + if(!tmp_accept_record) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to strdup string %s", str); + return NULL; + } + + accept_record = (axis2_http_accept_record_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_accept_record_t)); + + if(!accept_record) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)accept_record, 0, sizeof(axis2_http_accept_record_t)); + accept_record->record = axutil_strtrim(env, tmp_accept_record, AXIS2_SPACE_COMMA); + + tmp = strchr(tmp_accept_record, AXIS2_Q); + if(tmp) + { + *tmp = AXIS2_ESC_NULL; + tmp++; + tmp = axutil_strtrim(env, tmp, AXIS2_EQ_N_SEMICOLON); + if(tmp) + { + sscanf(tmp, "%f", &quality); + AXIS2_FREE(env->allocator, tmp); + } + } + + tmp = strstr(tmp_accept_record, AXIS2_LEVEL); + if(tmp) + { + *tmp = AXIS2_ESC_NULL; + tmp++; + tmp = axutil_strtrim(env, tmp, AXIS2_EQ_N_SEMICOLON); + if(tmp) + { + sscanf(tmp, "%d", &level); + AXIS2_FREE(env->allocator, tmp); + } + } + + tmp = axutil_strtrim(env, tmp_accept_record, AXIS2_SPACE_SEMICOLON); + if(tmp) + { + name = tmp; + } + + if(!name || quality > 1.0 || quality < 0.0) + { + axis2_http_accept_record_free(accept_record, env); + return NULL; + } + + accept_record->name = name; + accept_record->quality = quality; + accept_record->level = level; + + AXIS2_FREE(env->allocator, tmp_accept_record); + return accept_record; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_accept_record_free( + axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + + if(!accept_record) + { + return; + } + + if(accept_record->name) + { + AXIS2_FREE(env->allocator, accept_record->name); + } + if(accept_record->record) + { + AXIS2_FREE(env->allocator, accept_record->record); + } + AXIS2_FREE(env->allocator, accept_record); + return; +} + +AXIS2_EXTERN float AXIS2_CALL +axis2_http_accept_record_get_quality_factor( + const axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + return accept_record->quality; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_accept_record_get_name( + const axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + return accept_record->name; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_accept_record_get_level( + const axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + return accept_record->level; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_accept_record_to_string( + axis2_http_accept_record_t * accept_record, + const axutil_env_t * env) +{ + return accept_record->record; +} diff --git a/src/core/transport/http/common/http_header.c b/src/core/transport/http/common/http_header.c new file mode 100644 index 0000000..3ea2ffc --- /dev/null +++ b/src/core/transport/http/common/http_header.c @@ -0,0 +1,168 @@ +/* + * 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_header.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <stdio.h> +#include <string.h> + +struct axis2_http_header +{ + axis2_char_t *name; + axis2_char_t *value; +}; + +AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL +axis2_http_header_create( + const axutil_env_t * env, + const axis2_char_t * name, + const axis2_char_t * value) +{ + axis2_http_header_t *http_header = NULL; + http_header = (axis2_http_header_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_header_t)); + if(!http_header) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)http_header, 0, sizeof(axis2_http_header_t)); + http_header->name = (axis2_char_t *)axutil_strdup(env, name); + http_header->value = (axis2_char_t *)axutil_strdup(env, value); + + return http_header; +} + +/** + * Creates http header object from a string having format "header_name: header_value" + * (e.g. "SOAPAction: urn:hello") + * @param env pointer to environment struct + * @param str pointer to str + */ +AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL +axis2_http_header_create_by_str( + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_char_t *tmp_str = NULL; + axis2_char_t *ch = NULL; + axis2_char_t *ch2 = NULL; + axis2_http_header_t *ret = NULL; + int tmp_str_len = 0; + AXIS2_PARAM_CHECK(env->error, str, NULL); + + /* + tmp_str = axutil_strdup(env, str); + if(!tmp_str) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to strdup string, %s", str); + return NULL; + } + */ + /* + * strdup is removed to increase the performance. This method is called from + * axis2_simple_http_svr_conn_read_request and axis2_http_client_recieve_header and both of them + * passes a temporary string. hence we can modify the contents without doing a strdup. + * Above code is commented after 1.6.0 . If no issue is found until 1.8.0, above can be removed + */ + tmp_str = (axis2_char_t *)str; + + /* remove trailing \r\n */ + tmp_str_len = axutil_strlen(tmp_str); + if((tmp_str_len >= 2) && (AXIS2_RETURN == tmp_str[tmp_str_len - 2])) + { + tmp_str[tmp_str_len - 2] = AXIS2_ESC_NULL; + } + + /* get http header */ + ch = strchr((const char *)tmp_str, AXIS2_COLON); + if(!ch) + { + /*AXIS2_FREE(env->allocator, tmp_str);*/ + return NULL; + } + *ch = AXIS2_ESC_NULL; + + /* get http header value */ + ch2 = ++ch; + + /* skip spaces */ + while(AXIS2_SPACE == *ch2) + { + ++ch2; + } + + ret = axis2_http_header_create(env, tmp_str, ch2); + /*AXIS2_FREE(env->allocator, tmp_str);*/ + return ret; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_header_free( + axis2_http_header_t * http_header, + const axutil_env_t * env) +{ + + if(!http_header) + { + return; + } + + if(http_header->name) + { + AXIS2_FREE(env->allocator, http_header->name); + } + if(http_header->value) + { + AXIS2_FREE(env->allocator, http_header->value); + } + + AXIS2_FREE(env->allocator, http_header); + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_header_to_external_form( + axis2_http_header_t * http_header, + const axutil_env_t * env) +{ + axis2_ssize_t len = 0; + axis2_char_t *external_form = NULL; + + AXIS2_PARAM_CHECK(env->error, http_header, NULL); + + len = axutil_strlen(http_header->name) + axutil_strlen(http_header->value) + 8; + external_form = (axis2_char_t *)AXIS2_MALLOC(env->allocator, len); + sprintf(external_form, "%s: %s%s", http_header->name, http_header->value, AXIS2_HTTP_CRLF); + return external_form; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_header_get_name( + const axis2_http_header_t * http_header, + const axutil_env_t * env) +{ + return http_header->name; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_header_get_value( + const axis2_http_header_t * http_header, + const axutil_env_t * env) +{ + return http_header->value; +} diff --git a/src/core/transport/http/common/http_out_transport_info.c b/src/core/transport/http/common/http_out_transport_info.c new file mode 100644 index 0000000..b70ee6c --- /dev/null +++ b/src/core/transport/http/common/http_out_transport_info.c @@ -0,0 +1,353 @@ +/* + * 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_out_transport_info.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> + +#define AXIS2_INTF_TO_IMPL(out_transport_info) \ + ((axis2_http_out_transport_info_t *) \ + (out_transport_info)) + +axis2_status_t AXIS2_CALL +axis2_out_transport_info_impl_set_content_type( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + return axis2_http_out_transport_info_set_content_type(http_transport_info, env, content_type); +} + +axis2_status_t AXIS2_CALL +axis2_out_transport_info_impl_set_char_encoding( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + return axis2_http_out_transport_info_set_char_encoding(http_transport_info, env, encoding); +} + +axis2_status_t AXIS2_CALL +axis2_out_transport_info_impl_set_cookie_header( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * set_cookie) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + return axis2_http_out_transport_info_set_cookie_header(http_transport_info, env, set_cookie); +} + +axis2_status_t AXIS2_CALL +axis2_out_transport_info_impl_set_session( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + const axis2_char_t * session_id, + const axis2_char_t * session_value) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + return axis2_http_out_transport_info_set_session(http_transport_info, env, session_id, + session_value); +} + +void AXIS2_CALL +axis2_out_transport_info_impl_free( + axis2_out_transport_info_t * out_transport_info, + const axutil_env_t * env) +{ + axis2_http_out_transport_info_t *http_transport_info = NULL; + http_transport_info = AXIS2_INTF_TO_IMPL(out_transport_info); + axis2_http_out_transport_info_free(http_transport_info, env); + return; +} + +static const axis2_out_transport_info_ops_t ops_var = { + axis2_out_transport_info_impl_set_content_type, + axis2_out_transport_info_impl_set_char_encoding, + axis2_out_transport_info_impl_set_cookie_header, + axis2_out_transport_info_impl_set_session, + axis2_out_transport_info_impl_free }; + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_impl_set_content_type( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + axis2_char_t *tmp1 = NULL; + axis2_char_t *tmp2 = NULL; + + AXIS2_PARAM_CHECK(env->error, content_type, AXIS2_FAILURE); + if(http_out_transport_info->encoding) + { + axis2_char_t *charset_pos = axutil_strcasestr(content_type, AXIS2_CHARSET); + if(!charset_pos) + { + /* if "charset" not found in content_type string */ + tmp1 = axutil_stracat(env, content_type, AXIS2_CONTENT_TYPE_CHARSET); + tmp2 = axutil_stracat(env, tmp1, http_out_transport_info->encoding); + axis2_http_simple_response_set_header(http_out_transport_info-> response, env, + axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, tmp2)); + AXIS2_FREE(env->allocator, tmp1); + AXIS2_FREE(env->allocator, tmp2); + } + else + { + /* "charset" is found in content_type string */ + axis2_http_simple_response_set_header(http_out_transport_info-> response, env, + axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, content_type)); + } + } + else + { + /* no http_out_transport_info->encoding */ + if(http_out_transport_info->response) + { + axis2_http_simple_response_set_header(http_out_transport_info-> response, env, + axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, content_type)); + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_impl_set_char_encoding( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE); + if(http_out_transport_info->encoding) + { + AXIS2_FREE(env->allocator, http_out_transport_info->encoding); + } + http_out_transport_info->encoding = axutil_strdup(env, encoding); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_impl_set_cookie_header( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * set_cookie) +{ + AXIS2_PARAM_CHECK(env->error, set_cookie, AXIS2_FAILURE); + if(http_out_transport_info->response) + { + axis2_http_simple_response_set_header(http_out_transport_info-> response, env, + axis2_http_header_create(env, AXIS2_HTTP_HEADER_SET_COOKIE, set_cookie)); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_impl_set_session( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * session_id, + const axis2_char_t * session_value) +{ + AXIS2_PARAM_CHECK(env->error, session_id, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, session_value, AXIS2_FAILURE); + if(http_out_transport_info->server) + { + env->set_session_fn((void *) http_out_transport_info->server, session_id, session_value); + } + return AXIS2_SUCCESS; +} +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_impl_free( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env) +{ + + if(!http_out_transport_info) + { + return; + } + + if(http_out_transport_info->response) + { + axis2_http_simple_response_free(http_out_transport_info->response, env); + } + if(http_out_transport_info->encoding) + { + AXIS2_FREE(env->allocator, http_out_transport_info->encoding); + } + AXIS2_FREE(env->allocator, http_out_transport_info); + return; +} + +AXIS2_EXTERN axis2_http_out_transport_info_t *AXIS2_CALL +axis2_http_out_transport_info_create( + const axutil_env_t * env, + axis2_http_simple_response_t * response) +{ + axis2_http_out_transport_info_t *http_out_transport_info = NULL; + + http_out_transport_info = (axis2_http_out_transport_info_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_out_transport_info_t)); + + if(!http_out_transport_info) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)http_out_transport_info, 0, sizeof(axis2_http_out_transport_info_t)); + http_out_transport_info->out_transport.ops = &ops_var; + http_out_transport_info->response = response; + http_out_transport_info->encoding = NULL; + http_out_transport_info->set_char_encoding = NULL; + http_out_transport_info->set_content_type = NULL; + http_out_transport_info->set_cookie_header = NULL; + http_out_transport_info->set_session = NULL; + http_out_transport_info->free_function = NULL; + + http_out_transport_info->set_char_encoding + = axis2_http_out_transport_info_impl_set_char_encoding; + http_out_transport_info->set_content_type = axis2_http_out_transport_info_impl_set_content_type; + http_out_transport_info->set_cookie_header = axis2_http_out_transport_info_impl_set_cookie_header; + http_out_transport_info->set_session = axis2_http_out_transport_info_impl_set_session; + http_out_transport_info->free_function = axis2_http_out_transport_info_impl_free; + + return http_out_transport_info; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_free( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env) +{ + http_out_transport_info->free_function(http_out_transport_info, env); + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_free_void_arg( + void *transport_info, + const axutil_env_t * env) +{ + axis2_http_out_transport_info_t *transport_info_l = NULL; + + transport_info_l = AXIS2_INTF_TO_IMPL(transport_info); + axis2_http_out_transport_info_free(transport_info_l, env); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_set_content_type( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * content_type) +{ + return http_out_transport_info->set_content_type(http_out_transport_info, env, content_type); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_set_char_encoding( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * encoding) +{ + return http_out_transport_info->set_char_encoding(http_out_transport_info, env, encoding); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_set_cookie_header( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * set_cookie) +{ + return http_out_transport_info->set_cookie_header(http_out_transport_info, env, set_cookie); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_out_transport_info_set_session( + axis2_http_out_transport_info_t * http_out_transport_info, + const axutil_env_t * env, + const axis2_char_t * session_id, + const axis2_char_t * session_value) +{ + return http_out_transport_info->set_session(http_out_transport_info, env, session_id, + session_value); +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_char_encoding_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + axis2_status_t(AXIS2_CALL * set_char_encoding) + (axis2_http_out_transport_info_t *, + const axutil_env_t *, + const axis2_char_t *)) +{ + out_transport_info->set_char_encoding = set_char_encoding; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_content_type_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + axis2_status_t(AXIS2_CALL * + set_content_type) (axis2_http_out_transport_info_t *, + const axutil_env_t *, + const axis2_char_t *)) +{ + out_transport_info->set_content_type = set_content_type; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_cookie_header_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + axis2_status_t(AXIS2_CALL * + set_cookie_header) (axis2_http_out_transport_info_t *, + const axutil_env_t *, + const axis2_char_t *)) +{ + out_transport_info->set_cookie_header = set_cookie_header; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_session_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + axis2_status_t(AXIS2_CALL * + set_session) (axis2_http_out_transport_info_t *, + const axutil_env_t *, + const axis2_char_t *, + const axis2_char_t *)) +{ + out_transport_info->set_session = set_session; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_out_transport_info_set_free_func( + axis2_http_out_transport_info_t * out_transport_info, + const axutil_env_t * env, + void (AXIS2_CALL * free_function) (axis2_http_out_transport_info_t *, + const axutil_env_t *)) +{ + out_transport_info->free_function = free_function; +} + diff --git a/src/core/transport/http/common/http_request_line.c b/src/core/transport/http/common/http_request_line.c new file mode 100644 index 0000000..f12cbba --- /dev/null +++ b/src/core/transport/http/common/http_request_line.c @@ -0,0 +1,227 @@ +/* + * 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_request_line.h> +#include <axutil_string.h> +#include <string.h> +#include <axis2_http_transport.h> +#include <stdio.h> + +struct axis2_http_request_line +{ + axis2_char_t *http_version; + axis2_char_t *method; + axis2_char_t *uri; +}; + +AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL +axis2_http_request_line_create( + const axutil_env_t * env, + const axis2_char_t * method, + const axis2_char_t * uri, + const axis2_char_t * http_version) +{ + axis2_http_request_line_t *request_line = NULL; + + AXIS2_PARAM_CHECK(env->error, method, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); + AXIS2_PARAM_CHECK(env->error, http_version, NULL); + + request_line = (axis2_http_request_line_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_request_line_t)); + + if(!request_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)request_line, 0, sizeof(axis2_http_request_line_t)); + request_line->method = (axis2_char_t *)axutil_strdup(env, method); + request_line->uri = (axis2_char_t *)axutil_strdup(env, uri); + request_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version); + + return request_line; +} + +void AXIS2_CALL +axis2_http_request_line_free( + axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + + if(!request_line) + { + return; + } + + if(request_line->method) + { + AXIS2_FREE(env->allocator, request_line->method); + } + if(request_line->uri) + { + AXIS2_FREE(env->allocator, request_line->uri); + } + if(request_line->http_version) + { + AXIS2_FREE(env->allocator, request_line->http_version); + } + + AXIS2_FREE(env->allocator, request_line); + return; +} + +/** + * Parses a line "<http method> <uri location> <http version>CRLF" and creates http_request_line + * object. E.g "POST /axis2/services/echo HTTP/1.1\r\n" + * @param env pointer to environment struct + * @param str pointer to the line to be parsed + * @return created object if success. NULL otherwise + */ +AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL +axis2_http_request_line_parse_line( + const axutil_env_t * env, + const axis2_char_t * str) +{ + /*axis2_char_t *req_line = NULL;*/ + axis2_char_t *method = NULL; + axis2_char_t *uri = NULL; + axis2_char_t *http_version = NULL; + axis2_http_request_line_t *ret = NULL; + axis2_char_t *tmp = NULL; + int i = 0; + + if(!str) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid parameter is given to parse"); + return NULL; + } + + tmp = axutil_strstr(str, AXIS2_HTTP_CRLF); + if(!tmp) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + + i = (int)(tmp - str); /* We are sure that the difference lies within the int range */ + + /* + req_line = AXIS2_MALLOC(env->allocator, i * sizeof(axis2_char_t) + 1); + if(!req_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memcpy(req_line, str, i * sizeof(axis2_char_t)); + req_line[i] = AXIS2_ESC_NULL; + tmp = req_line; + */ + /* we don't need to do a malloc and memcpy, because this method is only used by + * axis2_simple_http_svr_conn_read_request and it passes a temporary string. So, we can just + * set it as req_line and set the escape characters. this is done after 1.6.0 and if no issues + * found until 1.8.0, above code comment can be removed after 1.8.0 + */ + + tmp = (axis2_char_t *)str; + tmp[i] = AXIS2_ESC_NULL; + + /* find http method */ + method = tmp; + tmp = strchr(tmp, AXIS2_SPACE); + if(!tmp) + { + /*AXIS2_FREE(env->allocator, req_line);*/ + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + *tmp++ = AXIS2_ESC_NULL; + + /* find URI */ + uri = tmp; + tmp = strrchr(tmp, AXIS2_SPACE); + if(!tmp) + { + /*AXIS2_FREE(env->allocator, req_line);*/ + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + *tmp++ = AXIS2_ESC_NULL; + + /* find HTTP version */ + http_version = tmp; + ret = axis2_http_request_line_create(env, method, uri, http_version); + /*AXIS2_FREE(env->allocator, req_line);*/ + + return ret; +} + +axis2_char_t *AXIS2_CALL +axis2_http_request_line_get_method( + const axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + return request_line->method; +} + +axis2_char_t *AXIS2_CALL +axis2_http_request_line_get_http_version( + const axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + return request_line->http_version; +} + +axis2_char_t *AXIS2_CALL +axis2_http_request_line_get_uri( + const axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + return request_line->uri; +} + +axis2_char_t *AXIS2_CALL +axis2_http_request_line_to_string( + axis2_http_request_line_t * request_line, + const axutil_env_t * env) +{ + int alloc_len = 0; + axis2_char_t *ret = NULL; + + alloc_len = axutil_strlen(request_line->method) + axutil_strlen(request_line->uri) + + axutil_strlen(request_line->http_version) + 6; + /* 5 = 2 * spaces + '/' +CR + LF + '\0' */ + + ret = AXIS2_MALLOC(env->allocator, alloc_len * sizeof(axis2_char_t)); + if(!ret) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(request_line->uri[0] != AXIS2_F_SLASH) + { + sprintf(ret, "%s /%s %s%s", request_line->method, request_line->uri, + request_line->http_version, AXIS2_HTTP_CRLF); + } + else + { + sprintf(ret, "%s %s %s%s", request_line->method, request_line->uri, + request_line->http_version, AXIS2_HTTP_CRLF); + } + return ret; +} diff --git a/src/core/transport/http/common/http_response_writer.c b/src/core/transport/http/common/http_response_writer.c new file mode 100644 index 0000000..eec2422 --- /dev/null +++ b/src/core/transport/http/common/http_response_writer.c @@ -0,0 +1,176 @@ +/* + * 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_response_writer.h> +#include <axutil_array_list.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> + +struct axis2_http_response_writer +{ + axutil_stream_t *stream; + axis2_char_t *encoding; +}; + +AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL +axis2_http_response_writer_create( + const axutil_env_t * env, + axutil_stream_t * stream) +{ + return axis2_http_response_writer_create_with_encoding(env, stream, + AXIS2_HTTP_DEFAULT_CONTENT_CHARSET); +} + +AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL +axis2_http_response_writer_create_with_encoding( + const axutil_env_t * env, + axutil_stream_t * stream, + const axis2_char_t * encoding) +{ + axis2_http_response_writer_t *response_writer = NULL; + response_writer = (axis2_http_response_writer_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_response_writer_t)); + if(!response_writer) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + response_writer->stream = stream; + response_writer->encoding = (axis2_char_t *)axutil_strdup(env, encoding); + return response_writer; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_response_writer_free( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, response_writer->encoding); + AXIS2_FREE(env->allocator, response_writer); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_response_writer_get_encoding( + const axis2_http_response_writer_t * response_writer, + const axutil_env_t * env) +{ + return response_writer->encoding; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_write_char( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + char c) +{ + int write = -1; + if(!response_writer->stream) + { + return AXIS2_FAILURE; + } + + write = axutil_stream_write(response_writer->stream, env, &c, 1); + if(write < 0) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_write_buf( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + char *buf, + int offset, + axis2_ssize_t len) +{ + int write = -1; + + AXIS2_PARAM_CHECK(env->error, response_writer, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE); + + if(!response_writer->stream) + { + return AXIS2_FAILURE; + } + write = axutil_stream_write(response_writer->stream, env, buf, len); + if(write < 0) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_print_str( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + const char *str) +{ + int write = -1; + int len = -1; + + len = axutil_strlen(str); + if(!response_writer->stream) + { + return AXIS2_FAILURE; + } + write = axutil_stream_write(response_writer->stream, env, str, len); + + if(write < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "failed to write to stream string %s of length %d", str, len); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_print_int( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + int i) +{ + axis2_char_t int_str[10]; + sprintf(int_str, "%10d", i); + return axis2_http_response_writer_print_str(response_writer, env, int_str); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_println_str( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env, + const char *str) +{ + if(AXIS2_SUCCESS == axis2_http_response_writer_print_str(response_writer, env, str)) + { + return axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_response_writer_println( + axis2_http_response_writer_t * response_writer, + const axutil_env_t * env) +{ + return axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF); +} diff --git a/src/core/transport/http/common/http_simple_request.c b/src/core/transport/http/common/http_simple_request.c new file mode 100644 index 0000000..9e10ce1 --- /dev/null +++ b/src/core/transport/http/common/http_simple_request.c @@ -0,0 +1,433 @@ +/* + * 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_simple_request.h> +#include <axutil_array_list.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> +#include <string.h> +#include <axutil_types.h> + +struct axis2_http_simple_request +{ + axis2_http_request_line_t *request_line; + axutil_array_list_t *header_group; + axutil_stream_t *stream; + axis2_bool_t owns_stream; +}; + +AXIS2_EXTERN axis2_http_simple_request_t *AXIS2_CALL +axis2_http_simple_request_create( + const axutil_env_t * env, + axis2_http_request_line_t * request_line, + axis2_http_header_t ** http_headers, + axis2_ssize_t http_hdr_count, + axutil_stream_t * content) +{ + axis2_http_simple_request_t *simple_request = NULL; + simple_request = (axis2_http_simple_request_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_simple_request_t)); + if(!simple_request) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)simple_request, 0, sizeof(axis2_http_simple_request_t)); + simple_request->request_line = request_line; + simple_request->stream = content; + + if(!(simple_request->stream)) + { + simple_request->stream = axutil_stream_create_basic(env); + if(!simple_request->stream) + { + axis2_http_simple_request_free(simple_request, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + simple_request->owns_stream = AXIS2_TRUE; + } + + if((http_hdr_count > 0) && http_headers) + { + int i = 0; + simple_request->header_group = axutil_array_list_create(env, http_hdr_count); + + for(i = 0; i < (int)http_hdr_count; i++) + /* We are sure that the difference lies within the int range */ + { + axutil_array_list_add(simple_request->header_group, env, (void *)http_headers[i]); + } + } + + return simple_request; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_simple_request_free( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + /* free the stream only if we own it. Otherwise shouldn't free the stream + * since it belongs to the socket + */ + if(simple_request->owns_stream) + { + axutil_stream_free(simple_request->stream, env); + } + + if(simple_request->request_line) + { + axis2_http_request_line_free(simple_request->request_line, env); + } + + if(simple_request->header_group) + { + int i = 0; + axis2_http_header_t *tmp = NULL; + for(i = 0; i < axutil_array_list_size(simple_request->header_group, env); i++) + { + tmp = (axis2_http_header_t*)axutil_array_list_get(simple_request->header_group, env, i); + axis2_http_header_free(tmp, env); + } + axutil_array_list_free(simple_request->header_group, env); + } + AXIS2_FREE(env->allocator, simple_request); +} + +AXIS2_EXTERN axis2_http_request_line_t *AXIS2_CALL +axis2_http_simple_request_get_request_line( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + return simple_request->request_line; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_simple_request_set_request_line( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + axis2_http_request_line_t * request_line) +{ + AXIS2_PARAM_CHECK(env->error, request_line, AXIS2_FAILURE); + simple_request->request_line = request_line; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_simple_request_contains_header( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + const axis2_char_t * name) +{ + int i = 0; + axis2_char_t *header_name = NULL; + int count = 0; + + AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); + + if(!simple_request->header_group) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "http simple request \ +does not contain headers, unable to find: %s header", name); + return AXIS2_FALSE; + } + + count = axutil_array_list_size(simple_request->header_group, env); + + if(0 == count) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "http simple request \ +contains zero headers, unable to find: %s header", name); + return AXIS2_FALSE; + } + + for(i = 0; i < count; i++) + { + header_name = axis2_http_header_get_name((axis2_http_header_t *)axutil_array_list_get( + simple_request->header_group, env, i), env); + if(0 == axutil_strcasecmp(name, header_name)) + { + return AXIS2_TRUE; + } + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_http_simple_request_get_headers( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + return simple_request->header_group; +} + +AXIS2_EXTERN axis2_http_header_t *AXIS2_CALL +axis2_http_simple_request_get_first_header( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axutil_array_list_t *header_group = NULL; + int i = 0; + int count = 0; + + AXIS2_PARAM_CHECK(env->error, str, NULL); + + header_group = simple_request->header_group; + if(!simple_request->header_group) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "http simple request does not contain any headers; unable to find: %s header", str); + return NULL; + } + + if(0 == axutil_array_list_size(header_group, env)) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, + "http simple request contain zero headers, unable to find: %s header", str); + return NULL; + } + + count = axutil_array_list_size(header_group, env); + for(i = 0; i < count; i++) + { + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(str, tmp_name)) + { + return tmp_header; + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_simple_request_remove_headers( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + int i = 0; + int count = 0; + axutil_array_list_t *header_group = NULL; + + AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE); + + header_group = simple_request->header_group; + + if(!header_group) + { + /* Even though we couldn't complete the op, we are sure that the + * requred header is no more in the request. So we can proceed without a + * problem. + */ + return AXIS2_SUCCESS; + } + + count = axutil_array_list_size(header_group, env); + + for(i = 0; i < count; i++) + { + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(str, tmp_name)) + { + axis2_http_header_free(tmp_header, env); + axutil_array_list_remove(header_group, env, i); + break; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_simple_request_add_header( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + axis2_http_header_t * header) +{ + AXIS2_PARAM_CHECK(env->error, header, AXIS2_FAILURE); + + if(!simple_request->header_group) + { + simple_request->header_group = axutil_array_list_create(env, 1); + } + return axutil_array_list_add(simple_request->header_group, env, header); +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_http_simple_request_get_content_type( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + + tmp_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + return axis2_http_header_get_value(tmp_header, env); + } + + return AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axis2_http_simple_request_get_charset( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + + tmp_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + axis2_char_t *value = axis2_http_header_get_value(tmp_header, env); + axis2_char_t *charset = (axis2_char_t *)strstr((char *)value, + (char *)AXIS2_HTTP_CHAR_SET_ENCODING); + if(charset) + { + charset = strchr((char *)charset, AXIS2_EQ); + return charset; + } + } + + return AXIS2_HTTP_DEFAULT_CONTENT_CHARSET; +} + +AXIS2_EXTERN axis2_ssize_t AXIS2_CALL +axis2_http_simple_request_get_content_length( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + int error_return = -1; + + tmp_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH); + if(tmp_header) + { + return AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env)); + } + return error_return; +} + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axis2_http_simple_request_get_body( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env) +{ + return simple_request->stream; +} + +AXIS2_EXTERN axis2_ssize_t AXIS2_CALL +axis2_http_simple_request_get_body_bytes( + const axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + char **buf) +{ + axutil_stream_t *body = NULL; + char *tmp_buf = NULL; + char *tmp_buf2 = NULL; + char *tmp_buf3 = NULL; + int length = 0; + int read_len = 0; + + body = simple_request->stream; + if(!body) + { + *buf = (char *)AXIS2_MALLOC(env->allocator, 1); + *buf[0] = '\0'; + return 0; + } + + length = axis2_http_simple_request_get_content_length(simple_request, env); + if(length > 0) + { + *buf = (char *)AXIS2_MALLOC(env->allocator, length + 1); + read_len = axutil_stream_read(body, env, *buf, length + 1); + return read_len; + } + + tmp_buf2 = AXIS2_MALLOC(env->allocator, 128 * sizeof(char)); + while(axutil_stream_read(body, env, tmp_buf2, 128) > 0) + { + tmp_buf3 = axutil_stracat(env, tmp_buf, tmp_buf2); + if(tmp_buf) + { + AXIS2_FREE(env->allocator, tmp_buf); + tmp_buf = NULL; + } + tmp_buf = tmp_buf3; + + } + + if(tmp_buf2) + { + AXIS2_FREE(env->allocator, tmp_buf2); + tmp_buf2 = NULL; + } + + if(tmp_buf) + { + *buf = tmp_buf; + return axutil_strlen(tmp_buf); + } + + *buf = (char *)AXIS2_MALLOC(env->allocator, 1); + *buf[0] = AXIS2_ESC_NULL; + return 0; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_simple_request_set_body_string( + axis2_http_simple_request_t * simple_request, + const axutil_env_t * env, + void *str, + unsigned int str_len) +{ + axutil_stream_t *body_stream = NULL; + + AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE); + + body_stream = simple_request->stream; + if(!body_stream) + { + body_stream = axutil_stream_create_basic(env); + if(!body_stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "unable to create stream\ +for stream %s of %d length", (axis2_char_t *)str, str_len); + return AXIS2_FAILURE; + } + simple_request->stream = body_stream; + simple_request->owns_stream = AXIS2_TRUE; + } + + axutil_stream_write(body_stream, env, str, str_len); + return AXIS2_SUCCESS; +} diff --git a/src/core/transport/http/common/http_simple_response.c b/src/core/transport/http/common/http_simple_response.c new file mode 100644 index 0000000..74acb80 --- /dev/null +++ b/src/core/transport/http/common/http_simple_response.c @@ -0,0 +1,615 @@ +/* + * 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_simple_response.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> +#include <stdio.h> +#include <string.h> +#include <axutil_types.h> +#include <axiom_mime_part.h> + +#define AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE 2048 + +struct axis2_http_simple_response +{ + axis2_http_status_line_t *status_line; + axutil_array_list_t *header_group; + axutil_stream_t *stream; + axutil_array_list_t *mime_parts; + axis2_char_t *mtom_sending_callback_name; +}; + +AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL +axis2_http_simple_response_create( + const axutil_env_t * env, + axis2_http_status_line_t * status_line, + const axis2_http_header_t ** http_headers, + const axis2_ssize_t http_hdr_count, + axutil_stream_t * content) +{ + axis2_http_simple_response_t *ret = NULL; + ret = axis2_http_simple_response_create_default(env); + if(!ret) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 http simple response creation failed"); + return NULL; + } + + ret->status_line = status_line; + if(http_hdr_count > 0 && http_headers) + { + int i = 0; + ret->header_group = axutil_array_list_create(env, http_hdr_count); + + for(i = 0; i < (int)http_hdr_count; i++) + /* We are sure that the difference lies within the int range */ + { + axutil_array_list_add(ret->header_group, env, (void *)http_headers[i]); + } + } + ret->stream = content; + return ret; +} + +AXIS2_EXTERN axis2_http_simple_response_t *AXIS2_CALL +axis2_http_simple_response_create_default( + const axutil_env_t * env) +{ + axis2_http_simple_response_t *simple_response = NULL; + simple_response = (axis2_http_simple_response_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_simple_response_t)); + if(!simple_response) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + memset((void *)simple_response, 0, sizeof(axis2_http_simple_response_t)); + return simple_response; +} + +void AXIS2_CALL +axis2_http_simple_response_free( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + if(simple_response->status_line) + { + axis2_http_status_line_free(simple_response->status_line, env); + } + + if(simple_response->header_group) + { + int i = 0; + for(i = 0; i < axutil_array_list_size(simple_response->header_group, env); i++) + { + void *tmp = NULL; + tmp = axutil_array_list_get(simple_response-> header_group, env, i); + if(tmp) + { + axis2_http_header_free((axis2_http_header_t *)tmp, env); + } + } + axutil_array_list_free(simple_response->header_group, env); + } + + if(simple_response->mime_parts) + { + int i = 0; + for(i = 0; i < axutil_array_list_size(simple_response->mime_parts, env); i++) + { + void *mime_part = NULL; + mime_part = axutil_array_list_get(simple_response->mime_parts, env, i); + if(mime_part) + { + axiom_mime_part_free((axiom_mime_part_t *)mime_part, env); + } + } + axutil_array_list_free(simple_response->mime_parts, env); + } + + /* Stream is not freed. Assumption : stream doesn't belong to the response */ + + AXIS2_FREE(env->allocator, simple_response); +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_status_line( + struct axis2_http_simple_response * simple_response, + const axutil_env_t * env, + const axis2_char_t * http_ver, + const int status_code, + const axis2_char_t * phrase) +{ + if(!http_ver || !phrase || !status_code) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "invalid parameter given"); + return AXIS2_FAILURE; + } + + if(simple_response->status_line) + { + axis2_http_status_line_free(simple_response->status_line, env); + } + + simple_response->status_line = axis2_http_status_line_create_with_values( + env, http_ver, status_code, phrase); + if(!simple_response->status_line) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "http status line creation failed for string %s %3d %s", http_ver, status_code, phrase); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_phrase( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + return NULL; + } + + return axis2_http_status_line_get_reason_phrase(simple_response-> status_line, env); +} + +int AXIS2_CALL +axis2_http_simple_response_get_status_code( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + return -1; + } + return axis2_http_status_line_get_status_code(simple_response->status_line, env); +} + +axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_http_version( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + + return NULL; + } + return axis2_http_status_line_get_http_version(simple_response->status_line, env); +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_http_version( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_char_t *http_version) +{ + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + + return AXIS2_FAILURE; + } + axis2_http_status_line_set_http_version(simple_response->status_line, env, http_version); + return AXIS2_SUCCESS; +} + +axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_status_line( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + + if(!(simple_response->status_line)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "axis2 simple response , status line is not available"); + + return NULL; + } + return axis2_http_status_line_to_string(simple_response->status_line, env); +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_http_simple_response_get_headers( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + return simple_response->header_group; +} + +axutil_array_list_t *AXIS2_CALL +axis2_http_simple_response_extract_headers( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + axutil_array_list_t *temp = NULL; + temp = simple_response->header_group; + if(temp) + { + simple_response->header_group = NULL; + } + return temp; +} + +axis2_http_header_t *AXIS2_CALL +axis2_http_simple_response_get_first_header( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + int i = 0; + int count = 0; + axutil_array_list_t *header_group = NULL; + + AXIS2_PARAM_CHECK(env->error, str, NULL); + + header_group = simple_response->header_group; + if(!simple_response->header_group) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 simple response , headers not available"); + return NULL; + } + + if(0 == axutil_array_list_size(header_group, env)) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "axis2 simple response , contains zero headers"); + + return NULL; + } + + count = axutil_array_list_size(header_group, env); + + for(i = 0; i < count; i++) + { + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(str, tmp_name)) + { + return tmp_header; + } + } + return NULL; + +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_remove_headers( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + const axis2_char_t * str) +{ + axutil_array_list_t *header_group = NULL; + int i = 0; + int count = 0; + + AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE); + + header_group = simple_response->header_group; + if(!header_group) + { + /* Even though we couldn't complete the op, we are sure that the + * required header is no more in the request. So we can proceed without a + * problem. + */ + return AXIS2_SUCCESS; + } + + count = axutil_array_list_size(header_group, env); + for(i = 0; i < count; i++) + { + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(str, tmp_name)) + { + axis2_http_header_free(tmp_header, env); + axutil_array_list_remove(header_group, env, i); + break; + } + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_header( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_http_header_t * header) +{ + int i = 0; + int count = 0; + axutil_array_list_t *header_group = NULL; + + AXIS2_PARAM_CHECK(env->error, header, AXIS2_FAILURE); + + if(!simple_response->header_group) + { + simple_response->header_group = axutil_array_list_create(env, 10); + axutil_array_list_add(simple_response->header_group, env, header); + return AXIS2_SUCCESS; + } + + /* If a header with the same name exists search and remove the old header */ + header_group = simple_response->header_group; + count = axutil_array_list_size(header_group, env); + for(i = 0; i < count; i++) + { + axis2_http_header_t *tmp_header = NULL; + axis2_char_t *tmp_name = NULL; + tmp_header = (axis2_http_header_t *)axutil_array_list_get(header_group, env, i); + tmp_name = axis2_http_header_get_name(tmp_header, env); + if(0 == axutil_strcasecmp(axis2_http_header_get_name(header, env), tmp_name)) + { + axis2_http_header_free(tmp_header, env); + axutil_array_list_set(header_group, env, i, header); + return AXIS2_SUCCESS; + } + } + + /* if header is not found, then we have to add it */ + axutil_array_list_add(header_group, env, header); + return AXIS2_SUCCESS; +} + +const axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_charset( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + + tmp_header = axis2_http_simple_response_get_first_header(simple_response, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + axis2_char_t *value = axis2_http_header_get_value(tmp_header, env); + axis2_char_t *charset = (axis2_char_t *)strstr((char *)value, + (char *)AXIS2_HTTP_CHAR_SET_ENCODING); + if(charset) + { + charset = strchr((char *)charset, AXIS2_EQ); + return charset; + } + } + + return AXIS2_HTTP_DEFAULT_CONTENT_CHARSET; +} + +axis2_ssize_t AXIS2_CALL +axis2_http_simple_response_get_content_length( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + int error_return = -1; + + tmp_header = axis2_http_simple_response_get_first_header(simple_response, env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH); + if(tmp_header) + { + return AXIS2_ATOI(axis2_http_header_get_value(tmp_header, env)); + } + return error_return; +} + +const axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_content_type( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + axis2_http_header_t *tmp_header = NULL; + + tmp_header = axis2_http_simple_response_get_first_header(simple_response, env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + if(tmp_header) + { + return axis2_http_header_get_value(tmp_header, env); + } + + return AXIS2_HTTP_HEADER_ACCEPT_TEXT_PLAIN; +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_body_string( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_char_t * str) +{ + axutil_stream_t *body_stream = NULL; + + AXIS2_PARAM_CHECK(env->error, str, AXIS2_FAILURE); + + body_stream = simple_response->stream; + if(!body_stream) + { + body_stream = axutil_stream_create_basic(env); + if(!body_stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "unable to create basic stream for string %s", + str); + return AXIS2_FAILURE; + } + simple_response->stream = body_stream; + } + axutil_stream_write(body_stream, env, str, axutil_strlen(str)); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_http_simple_response_set_body_stream( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axutil_stream_t * stream) +{ + /* + * We don't free the stream + * Problem in freeing is most of the time the stream doesn't belong + * to the http_simple_response + */ + simple_response->stream = stream; + return AXIS2_SUCCESS; +} + +axutil_stream_t *AXIS2_CALL +axis2_http_simple_response_get_body( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + return simple_response->stream; +} + +axis2_ssize_t AXIS2_CALL +axis2_http_simple_response_get_body_bytes( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_char_t ** buffer) +{ + axutil_stream_t *tmp_stream = NULL; + axis2_bool_t loop_state = AXIS2_TRUE; + int return_size = -1; + + if(!simple_response->stream) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_BODY, AXIS2_FAILURE); + return return_size; + } + tmp_stream = axutil_stream_create_basic(env); + while(loop_state) + { + int read = 0; + int write = 0; + char buf[AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE]; + + read = axutil_stream_read(simple_response->stream, env, buf, + AXIS2_HTTP_SIMPLE_RESPONSE_READ_SIZE); + if(read < 0) + { + break; + } + write = axutil_stream_write(tmp_stream, env, buf, read); + if(read < (AXIS2_HTTP_SIMPLE_RESPONSE_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 + 1)); + + if(!buffer) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return -1; + } + + return_size = axutil_stream_read(tmp_stream, env, *buffer, return_size + 1); + } + axutil_stream_free(tmp_stream, env); + return return_size; +} + +axis2_bool_t AXIS2_CALL +axis2_http_simple_response_contains_header( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + const axis2_char_t * name) +{ + axis2_char_t *header_name = NULL; + int count = 0; + int i = 0; + + AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); + if(!simple_response->header_group) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2 simple response , headers not available"); + return AXIS2_FALSE; + } + + count = axutil_array_list_size(simple_response->header_group, env); + if(0 == count) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "axis2 simple response , contains zero headers"); + return AXIS2_FALSE; + } + + for(i = 0; i < count; i++) + { + axis2_http_header_t *header = (axis2_http_header_t *)axutil_array_list_get( + simple_response->header_group, env, i); + header_name = axis2_http_header_get_name(header, env); + if(0 == axutil_strcasecmp(name, header_name)) + { + return AXIS2_TRUE; + } + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axis2_http_simple_response_get_mime_parts( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + + return simple_response->mime_parts; + +} + +void AXIS2_EXTERN AXIS2_CALL +axis2_http_simple_response_set_mime_parts( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axutil_array_list_t *mime_parts) +{ + + simple_response->mime_parts = mime_parts; + +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_simple_response_get_mtom_sending_callback_name( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env) +{ + return simple_response->mtom_sending_callback_name; +} + +void AXIS2_EXTERN AXIS2_CALL +axis2_http_simple_response_set_mtom_sending_callback_name( + axis2_http_simple_response_t * simple_response, + const axutil_env_t * env, + axis2_char_t *mtom_sending_callback_name) +{ + simple_response->mtom_sending_callback_name = + mtom_sending_callback_name; +} diff --git a/src/core/transport/http/common/http_status_line.c b/src/core/transport/http/common/http_status_line.c new file mode 100644 index 0000000..fdf0fea --- /dev/null +++ b/src/core/transport/http/common/http_status_line.c @@ -0,0 +1,267 @@ +/* + * 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_status_line.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <string.h> +#include <stdio.h> +#include <axutil_types.h> + +struct axis2_http_status_line +{ + axis2_char_t *line; + axis2_char_t *http_version; + axis2_char_t *status_code; + axis2_char_t *reason_phrase; +}; + +AXIS2_EXTERN axis2_http_status_line_t *AXIS2_CALL +axis2_http_status_line_create( + const axutil_env_t * env, + const axis2_char_t * str) +{ + axis2_char_t *tmp_status_line = NULL; + axis2_char_t *reason_phrase = NULL; + axis2_char_t *status_code = NULL; + axis2_char_t *http_version = NULL; + int i = 0; + axis2_char_t *tmp = NULL; + axis2_http_status_line_t *status_line = NULL; + + status_line = (axis2_http_status_line_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_status_line_t)); + + if(!status_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)status_line, 0, sizeof(axis2_http_status_line_t)); + status_line->line = (axis2_char_t *)axutil_strdup(env, str); + + /* extract status code, phrase and version from given string */ + tmp = strstr(str, AXIS2_HTTP_CRLF); + if(!tmp) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + + i = (int)(tmp - str); /* We are sure that the difference lies within the int range */ + + tmp_status_line = AXIS2_MALLOC(env->allocator, i * sizeof(axis2_char_t) + 1); + if(!tmp_status_line) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memcpy(tmp_status_line, str, i * sizeof(axis2_char_t)); + tmp_status_line[i] = AXIS2_ESC_NULL; + tmp = tmp_status_line; + + /* get HTTP version */ + http_version = tmp; + tmp = strchr(tmp, AXIS2_SPACE); + if(!tmp) + { + AXIS2_FREE(env->allocator, tmp_status_line); + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + *tmp++ = AXIS2_ESC_NULL; + + /* get status code */ + status_code = tmp; + tmp = strchr(tmp, AXIS2_SPACE); + if(!tmp) + { + AXIS2_FREE(env->allocator, tmp_status_line); + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + *tmp++ = AXIS2_ESC_NULL; + + /* get reason phrase */ + reason_phrase = tmp; + + /* populate values */ + status_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version); + status_line->status_code = (axis2_char_t *)axutil_strdup(env, status_code); + status_line->reason_phrase = (axis2_char_t *)axutil_strdup(env, reason_phrase); + AXIS2_FREE(env->allocator, tmp_status_line); + + if(!status_line->http_version || !status_line->reason_phrase || !status_line->status_code) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return status_line; +} + +AXIS2_EXTERN axis2_http_status_line_t *AXIS2_CALL +axis2_http_status_line_create_with_values( + const axutil_env_t * env, + const axis2_char_t * http_ver, + const int status_code, + const axis2_char_t * phrase) +{ + axis2_http_status_line_t *status_line = NULL; + status_line = (axis2_http_status_line_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_http_status_line_t)); + if(!status_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + memset((void *)status_line, 0, sizeof(axis2_http_status_line_t)); + + status_line->status_code = AXIS2_MALLOC(env->allocator, 6 * sizeof(axis2_char_t *)); + if(!status_line->status_code) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axis2_http_status_line_free(status_line, env); + return NULL; + } + sprintf(status_line->status_code, "%3d", status_code); + + status_line->http_version = axutil_strdup(env, http_ver); + status_line->reason_phrase = axutil_strdup(env, phrase); + if(!status_line->http_version || !status_line->reason_phrase) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + status_line->line = axutil_strcat(env, http_ver, " ", status_line->status_code, " ", phrase, + AXIS2_HTTP_CRLF, NULL); + if(!status_line->line) + { + axis2_http_status_line_free(status_line, env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + return status_line; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_status_line_free( + axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + + if(!status_line) + { + return; + } + + if(status_line->line) + { + AXIS2_FREE(env->allocator, status_line->line); + } + if(status_line->http_version) + { + AXIS2_FREE(env->allocator, status_line->http_version); + } + if(status_line->status_code) + { + AXIS2_FREE(env->allocator, status_line->status_code); + } + if(status_line->reason_phrase) + { + AXIS2_FREE(env->allocator, status_line->reason_phrase); + } + + AXIS2_FREE(env->allocator, status_line); + return; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_http_status_line_get_status_code( + const axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + if(status_line->status_code) + { + return AXIS2_ATOI(status_line->status_code); + } + else + { + return AXIS2_CRITICAL_FAILURE; + } + +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_status_line_get_http_version( + const axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + return status_line->http_version; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_status_line_set_http_version( + axis2_http_status_line_t * status_line, + const axutil_env_t * env, + axis2_char_t *http_version) +{ + if(status_line->http_version) + { + AXIS2_FREE(env->allocator, status_line->http_version); + status_line->http_version = NULL; + } + + status_line->http_version = (axis2_char_t *)axutil_strdup(env, http_version); + +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_status_line_get_reason_phrase( + const axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + return status_line->reason_phrase; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_status_line_starts_with_http( + axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + if(0 == axutil_strncasecmp(status_line->line, AXIS2_HTTP, 4)) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_http_status_line_to_string( + axis2_http_status_line_t * status_line, + const axutil_env_t * env) +{ + return status_line->line; +} diff --git a/src/core/transport/http/common/http_worker.c b/src/core/transport/http/common/http_worker.c new file mode 100644 index 0000000..26ccce3 --- /dev/null +++ b/src/core/transport/http/common/http_worker.c @@ -0,0 +1,2064 @@ +/* + * 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_worker.h> +#include <axutil_string.h> +#include <axis2_http_transport.h> +#include <axis2_conf.h> +#include <axutil_string.h> +#include <axis2_msg_ctx.h> +#include <axis2_http_request_line.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 <axutil_url.h> +#include <axutil_property.h> +#include <axiom_soap.h> +#include <string.h> +#include <axutil_string_util.h> +#include <stdio.h> +#include <stdlib.h> +#include <platforms/axutil_platform_auto_sense.h> + +struct axis2_http_worker +{ + axis2_conf_ctx_t *conf_ctx; + int svr_port; + axis2_bool_t is_application_client_side; +}; + +static axis2_status_t +axis2_http_worker_set_response_headers( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_simple_http_svr_conn_t * svr_conn, + axis2_http_simple_request_t * simple_request, + axis2_http_simple_response_t * simple_response, + axis2_ssize_t content_length); + +static axutil_hash_t * +axis2_http_worker_get_headers( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_http_simple_request_t * request); + +static axis2_http_simple_response_t * +axis2_http_worker_create_simple_response( + axis2_http_worker_t *http_worker, + const axutil_env_t *env); + +AXIS2_EXTERN axis2_http_worker_t *AXIS2_CALL +axis2_http_worker_create( + const axutil_env_t * env, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_http_worker_t *http_worker = NULL; + + http_worker = (axis2_http_worker_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_http_worker_t)); + + if(!http_worker) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + http_worker->conf_ctx = conf_ctx; + http_worker->svr_port = 9090; /* default - must set later */ + http_worker->is_application_client_side = AXIS2_FALSE; /* default is creating for application + server side */ + + return http_worker; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_worker_free( + axis2_http_worker_t * http_worker, + const axutil_env_t * env) +{ + http_worker->conf_ctx = NULL; + AXIS2_FREE(env->allocator, http_worker); + return; +} + +/* Each in-coming request is passed into this function for process. Basically http method to deliver + * is deduced here and call appropriate http processing function. + * eg. transport_utils_process_http_post_request() function. Once this function call done it will go + * through engine inflow phases and finally hit the message receiver for the operation. + */ +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_http_worker_process_request( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_simple_http_svr_conn_t * svr_conn, + axis2_http_simple_request_t * simple_request) +{ + axis2_conf_ctx_t *conf_ctx = NULL; + axis2_msg_ctx_t *msg_ctx = NULL; + axutil_stream_t *request_body = NULL; + + /* Creating out_stream as basic stream */ + axutil_stream_t *out_stream = axutil_stream_create_basic(env); + axis2_http_simple_response_t *response = NULL; + + /* Transport in and out descriptions */ + axis2_transport_out_desc_t *out_desc = NULL; + axis2_transport_in_desc_t *in_desc = NULL; + + axis2_char_t *http_version = NULL; + axis2_char_t *soap_action = NULL; + axutil_string_t *soap_action_str = NULL; + axis2_bool_t processed = AXIS2_FALSE; + axis2_status_t status = AXIS2_FAILURE; + int content_length = -1; + axis2_http_header_t *encoding_header = NULL; + axis2_char_t *encoding_header_value = NULL; + axis2_op_ctx_t *op_ctx = NULL; + axis2_char_t *svr_ip = NULL; + axis2_char_t *peer_ip = NULL; + axutil_url_t *request_url = NULL; + axis2_http_out_transport_info_t *http_out_transport_info = NULL; + axutil_hash_t *headers = NULL; + axis2_char_t *url_external_form = NULL; + axis2_char_t *svc_grp_uuid = NULL; + axis2_char_t *path = NULL; + axutil_property_t *peer_property = NULL; + + /* REST processing variables */ + axis2_bool_t is_get = AXIS2_FALSE; + axis2_bool_t is_head = AXIS2_FALSE; + axis2_bool_t is_put = AXIS2_FALSE; + axis2_bool_t is_delete = AXIS2_FALSE; + axis2_bool_t request_handled = AXIS2_FALSE; + + /* HTTP and Proxy authentication */ + axis2_char_t *cookie_header_value = NULL; + /*axis2_char_t *set_cookie_header_value = NULL; + axis2_http_header_t *set_cookie_header = NULL; + axis2_http_header_t *connection_header = NULL;*/ + axis2_http_header_t *cookie_header = NULL; + axis2_char_t *accept_header_value = NULL; + axis2_http_header_t *accept_header = NULL; + axis2_char_t *accept_charset_header_value = NULL; + axis2_http_header_t *accept_charset_header = NULL; + axis2_char_t *accept_language_header_value = NULL; + axis2_http_header_t *accept_language_header = NULL; + + axis2_char_t *http_method = NULL; + axis2_http_request_line_t *request_line = NULL; + + axutil_hash_t *request_params = NULL; + axis2_char_t *request_uri = NULL; + axis2_char_t *url_ext_form = NULL; + const axis2_char_t *content_type = NULL; + + axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t *in_msg_ctx = NULL; + axis2_msg_ctx_t **msg_ctx_map = NULL; + + AXIS2_PARAM_CHECK(env->error, svr_conn, AXIS2_FALSE); + AXIS2_PARAM_CHECK(env->error, simple_request, AXIS2_FALSE); + + conf_ctx = http_worker->conf_ctx; + if(!conf_ctx) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_CONFIGURATION_CONTEXT, AXIS2_FAILURE); + return AXIS2_FALSE; + } + + content_length = axis2_http_simple_request_get_content_length(simple_request, env); + request_line = axis2_http_simple_request_get_request_line(simple_request, env); + http_method = axis2_http_request_line_get_method(request_line, env); + + http_version = axis2_http_request_line_get_http_version(request_line, env); + if(!http_version) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NULL_HTTP_VERSION, AXIS2_FAILURE); + return AXIS2_FALSE; + } + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Client HTTP version %s", http_version); + + encoding_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING); + if(encoding_header) + { + encoding_header_value = axis2_http_header_get_value(encoding_header, env); + } + + response = axis2_http_worker_create_simple_response(http_worker, env); + if(!response) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot create http simple response"); + return AXIS2_FALSE; + } + + /* if length is not given and it is not chunked, then return error to client */ + if((content_length < 0) && encoding_header_value + && (0 != axutil_strcmp(encoding_header_value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))) + { + if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_POST) + || 0 == axutil_strcasecmp(http_method, AXIS2_HTTP_PUT)) + { + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_LENGTH_REQUIRED_CODE_VAL, + AXIS2_HTTP_RESPONSE_LENGTH_REQUIRED_CODE_NAME); + + status = axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + axis2_http_simple_response_free(response, env); + return status; + } + } + + request_body = axis2_http_simple_request_get_body(simple_request, env); + + out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_HTTP); + in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(conf_ctx, env), env, + AXIS2_TRANSPORT_ENUM_HTTP); + + 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_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_COOKIE); + if(cookie_header) + { + char *session_str = NULL; + axis2_char_t *session_id = NULL; + + cookie_header_value = axis2_http_header_get_value(cookie_header, env); + session_id = axis2_http_transport_utils_get_session_id_from_cookie(env, + cookie_header_value); + if(session_id) + session_str = env->get_session_fn((void *) conf_ctx, session_id); + if(session_str) + axis2_http_transport_utils_set_session(env, msg_ctx, session_str); + } + + /*connection_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONNECTION); + if(connection_header) + { + axutil_property_t *connection_header_property = NULL; + axis2_char_t *connection_header_value = NULL; + connection_header_value = axis2_http_header_get_value(connection_header, env); + connection_header_property = axutil_property_create_with_args(env, + AXIS2_SCOPE_REQUEST, 0, 0, connection_header_value); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_HTTP_HEADER_CONNECTION, + connection_header_property); + }*/ + + /* Server and Peer IP's */ + svr_ip = axis2_simple_http_svr_conn_get_svr_ip(svr_conn, env); + peer_ip = axis2_simple_http_svr_conn_get_peer_ip(svr_conn, env); + + 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); + } + + path = axis2_http_request_line_get_uri(request_line, env); + + request_url = axutil_url_create(env, AXIS2_HTTP_PROTOCOL, svr_ip, http_worker->svr_port, path); + if(request_url) + { + url_external_form = axutil_url_to_external_form(request_url, env); + } + + if(!url_external_form) + { + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL, AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME); + status = axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + axis2_http_simple_response_free(response, env); + response = NULL; + return status; + } + + accept_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_ACCEPT); + if(accept_header) + { + accept_header_value = axis2_http_header_get_value(accept_header, env); + } + 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, AXIS2_COMMA); + 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 = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_ACCEPT_CHARSET); + if(accept_charset_header) + { + accept_charset_header_value = axis2_http_header_get_value(accept_charset_header, env); + } + 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, + AXIS2_COMMA); + 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 = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_ACCEPT_LANGUAGE); + if(accept_language_header) + { + accept_language_header_value = axis2_http_header_get_value(accept_language_header, env); + } + + 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, + AXIS2_COMMA); + 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); + } + } + + /* Here out_stream is set into the in message context. out_stream is copied from in message context + * into the out message context later in core_utils_create_out_msg_ctx() function. The buffer in + * out_stream is finally filled with the soap envelope in http_transport_sender_invoke() function. + * To avoid double freeing of out_stream we reset the out message context at the end of engine + * receive function. + */ + axis2_msg_ctx_set_transport_out_stream(msg_ctx, env, out_stream); + + headers = axis2_http_worker_get_headers(http_worker, env, simple_request); + axis2_msg_ctx_set_transport_headers(msg_ctx, env, headers); + + svc_grp_uuid = axutil_uuid_gen(env); + if(svc_grp_uuid) + { + axutil_string_t *svc_grp_uuid_str = axutil_string_create_assume_ownership(env, + &svc_grp_uuid); + axis2_msg_ctx_set_svc_grp_ctx_id(msg_ctx, env, svc_grp_uuid_str); + axutil_string_free(svc_grp_uuid_str, env); + } + + http_out_transport_info = axis2_http_out_transport_info_create(env, response); + axis2_msg_ctx_set_out_transport_info(msg_ctx, env, &(http_out_transport_info->out_transport)); + + if(axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_SOAP_ACTION)) + { + soap_action = axis2_http_header_get_value(axis2_http_simple_request_get_first_header( + simple_request, env, AXIS2_HTTP_HEADER_SOAP_ACTION), env); + soap_action_str = axutil_string_create(env, soap_action); + } + + if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_GET)) + { + is_get = AXIS2_TRUE; + } + else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_HEAD)) + { + is_head = AXIS2_TRUE; + } + else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_DELETE)) + { + is_delete = AXIS2_TRUE; + } + else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_PUT)) + { + is_put = AXIS2_TRUE; + } + + request_uri = axis2_http_request_line_get_uri(request_line, env); + request_params = axis2_http_transport_utils_get_request_params(env, request_uri); + url_ext_form = axutil_url_to_external_form(request_url, env); + + content_type = axis2_http_simple_request_get_content_type(simple_request, env); + + if(is_get || is_head || is_delete) + { + + if(is_get) + { + /* HTTP GET */ + processed = axis2_http_transport_utils_process_http_get_request(env, msg_ctx, + request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx, + request_params); + } + else if(is_delete) + { + /* HTTP DELETE */ + processed = axis2_http_transport_utils_process_http_delete_request(env, msg_ctx, + request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx, + request_params); + } + else if(is_head) + { + /* HTTP HEAD */ + processed = axis2_http_transport_utils_process_http_head_request(env, msg_ctx, + request_body, out_stream, content_type, soap_action_str, url_ext_form, conf_ctx, + request_params); + } + + if(AXIS2_FALSE == processed) + { + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_char_t *wsdl = NULL; + axis2_bool_t is_services_path = AXIS2_FALSE; + + if(!is_delete) + { + axis2_char_t *temp = NULL; + /* check whether request url have "/services" */ + temp = strstr(axutil_url_get_path(request_url, env), AXIS2_REQUEST_URL_PREFIX); + if(temp) + { + temp += strlen(AXIS2_REQUEST_URL_PREFIX); + if(*temp == AXIS2_F_SLASH) + { + temp++; + } + if(!*temp || *temp == AXIS2_Q_MARK || *temp == AXIS2_H_MARK) + { + is_services_path = AXIS2_TRUE; + } + } + + } + + /* processing request for WSDL via "?wsdl" */ + wsdl = strstr(url_external_form, AXIS2_REQUEST_WSDL); + if(is_services_path) + { + /* request for service */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_OK_CODE_VAL, AXIS2_HTTP_RESPONSE_OK_CODE_NAME); + body_string = axis2_http_transport_utils_get_services_html(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(!is_delete && wsdl) + { + /* Request is not for delete and ask for wsdl */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_OK_CODE_VAL, AXIS2_HTTP_RESPONSE_OK_CODE_NAME); + body_string = axis2_http_transport_utils_get_services_static_wsdl(env, conf_ctx, + url_external_form); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_APPLICATION_XML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(env->error->error_number == AXIS2_ERROR_SVC_OR_OP_NOT_FOUND) + { + + /* Processing SVC or Operation Not found case */ + 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_http_header_t *allow_header = NULL; + 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); + + if(!method_list_str) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FALSE); + } + + temp = method_list_str; + for(i = 0; i < size; i++) + { + if(i) + { + sprintf(temp, AXIS2_COMMA_SPACE_STR); + temp += 2; + } + sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env, + i)); + temp += strlen(temp); + } + *temp = AXIS2_ESC_NULL; + + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL, + AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME); + + body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx); + allow_header = axis2_http_header_create(env, AXIS2_HTTP_HEADER_ALLOW, + method_list_str); + axis2_http_simple_response_set_header(response, env, allow_header); + AXIS2_FREE(env->allocator, method_list_str); + } + else + { + /* 404 Not Found */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME); + + body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx); + } + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL) + { + /* 400 Bad Request */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME); + + body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL) + { + + /* 408 , Request Time Out */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL, + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME); + + body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL) + { + /* 409, Conflict */ + + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL, AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME); + + body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL) + { + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_GONE_CODE_VAL, AXIS2_HTTP_RESPONSE_GONE_CODE_NAME); + + body_string = axis2_http_transport_utils_get_gone(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL) + { + /* 412 Precondition failed */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL, + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME); + + body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL) + { + /* 413 entity too large */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL, + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME); + + body_string + = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL) + { + /* 503, Service Unavailable*/ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME); + + body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else + { + /* 500 Internal Server Error */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME); + + body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + + if(body_string) + { + axis2_char_t str_len[10]; + if(!is_head) + { + axis2_http_simple_response_set_body_string(response, env, body_string); + } + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, simple_request, + response, 0); + + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + } + } + else if(0 == axutil_strcasecmp(http_method, AXIS2_HTTP_POST) || is_put) + { + if(is_put) + { + axutil_property_t *property = NULL; + if(http_worker->is_application_client_side) + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE, 0, + AXIS2_VALUE_TRUE); + } + else + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE, + 0, AXIS2_VALUE_FALSE); + } + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE, + property); + status = axis2_http_transport_utils_process_http_put_request(env, msg_ctx, + request_body, out_stream, content_type, content_length, soap_action_str, + url_ext_form); + + } + else + { + axutil_property_t *property = NULL; + if(http_worker->is_application_client_side) + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_TRUE, 0, + AXIS2_VALUE_TRUE); + } + else + { + property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, AXIS2_FALSE, + 0, AXIS2_VALUE_FALSE); + } + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANPORT_IS_APPLICATION_CLIENT_SIDE, + property); + status = axis2_http_transport_utils_process_http_post_request(env, msg_ctx, + request_body, out_stream, content_type, content_length, soap_action_str, + url_ext_form); + + } + if(url_ext_form) + AXIS2_FREE(env->allocator, url_ext_form); + if(AXIS2_FAILURE == status && (is_put || axis2_msg_ctx_get_doing_rest(msg_ctx, env))) + { + /* Failure Occur while processing REST */ + + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + 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_http_header_t *allow_header = NULL; + 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); + if(!method_list_str) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FALSE); + } + + temp = method_list_str; + for(i = 0; i < size; i++) + { + if(i) + { + sprintf(temp, AXIS2_COMMA_SPACE_STR); + temp += 2; + } + sprintf(temp, "%s", (axis2_char_t *)axutil_array_list_get(method_list, env, + i)); + temp += strlen(temp); + } + *temp = AXIS2_ESC_NULL; + + /* 405 Method Not Allowed */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_VAL, + AXIS2_HTTP_RESPONSE_METHOD_NOT_ALLOWED_CODE_NAME); + + body_string = axis2_http_transport_utils_get_method_not_allowed(env, conf_ctx); + allow_header = axis2_http_header_create(env, AXIS2_HTTP_HEADER_ALLOW, + method_list_str); + axis2_http_simple_response_set_header(response, env, allow_header); + AXIS2_FREE(env->allocator, method_list_str); + } + else + { + /* 404 Not Found */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_FOUND_CODE_NAME); + + body_string = axis2_http_transport_utils_get_not_found(env, conf_ctx); + } + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL) + { + /* 400, Bad Request */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL, + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME); + + body_string = axis2_http_transport_utils_get_bad_request(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL) + { + /* 408, Request Timeout */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL, + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME); + + body_string = axis2_http_transport_utils_get_request_timeout(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL) + { + /* 409, Conflict Types */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL, AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME); + + body_string = axis2_http_transport_utils_get_conflict(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_GONE_CODE_VAL) + { + /* 410, Gone. Resource no longer available */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_GONE_CODE_VAL, AXIS2_HTTP_RESPONSE_GONE_CODE_NAME); + + body_string = axis2_http_transport_utils_get_gone(env, conf_ctx); + + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL) + { + /*410, Precondition for the url failed */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL, + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME); + + body_string = axis2_http_transport_utils_get_precondition_failed(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL) + { + /* 413, Request entity too large */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL, + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME); + + body_string + = axis2_http_transport_utils_get_request_entity_too_large(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + } + else if(axis2_msg_ctx_get_status_code(msg_ctx, env) + == AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL) + { + /* 513, Service Unavailable */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME); + + body_string = axis2_http_transport_utils_get_service_unavailable(env, conf_ctx); + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + else + { + /* 500, Internal Server Error */ + axis2_http_simple_response_set_status_line(response, env, http_version, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_VAL, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR_CODE_NAME); + + body_string = axis2_http_transport_utils_get_internal_server_error(env, conf_ctx); + + cont_type = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + } + + if(body_string) + { + axis2_char_t str_len[10]; + if(!is_head) + { + axis2_http_simple_response_set_body_string(response, env, body_string); + } + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, AXIS2_HTTP_HEADER_CONTENT_LENGTH, str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, simple_request, + response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + } + else if(status == AXIS2_FAILURE) + { + axis2_msg_ctx_t *fault_ctx = NULL; + axis2_engine_t *engine = axis2_engine_create(env, conf_ctx); + axis2_http_request_line_t *req_line = NULL; + axis2_http_status_line_t *tmp_stat_line = NULL; + axis2_char_t status_line_str[100]; + axutil_property_t *http_error_property = NULL; + axis2_char_t *http_error_value = NULL; + axis2_char_t *fault_code = NULL; + int status_code = 0; + axis2_char_t *reason_phrase = NULL; + int stream_len = 0; + + if(!engine) + { + return AXIS2_FALSE; + } + + http_error_property = axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_HTTP_TRANSPORT_ERROR); + + if(http_error_property) + http_error_value = (axis2_char_t *)axutil_property_get_value(http_error_property, + env); + + if(axis2_msg_ctx_get_is_soap_11(msg_ctx, env)) + { + fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX AXIS2_COLON_STR + AXIOM_SOAP11_FAULT_CODE_SENDER; + } + else + { + fault_code = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX AXIS2_COLON_STR + 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)); + req_line = + axis2_http_simple_request_get_request_line(simple_request, env); + if (req_line) + { + if (!http_error_value) + { + sprintf(status_line_str, "%s %s\r\n", + http_version, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR); + } + else + { + sprintf(status_line_str, "%s %s", + http_version, + http_error_value); + } + } + else + { + sprintf(status_line_str, "%s %s\r\n", + AXIS2_HTTP_HEADER_PROTOCOL_11, + AXIS2_HTTP_RESPONSE_INTERNAL_SERVER_ERROR); + } + + tmp_stat_line = axis2_http_status_line_create(env, status_line_str); + + if (!http_error_value) + { + axis2_engine_send_fault(engine, env, fault_ctx); + } + + status_code = axis2_http_status_line_get_status_code(tmp_stat_line, env); + reason_phrase = axis2_http_status_line_get_reason_phrase(tmp_stat_line, env); + + axis2_http_simple_response_set_status_line(response, env, + http_version, + status_code, + reason_phrase); + + axis2_http_simple_response_set_body_stream(response, env, + out_stream); + + stream_len = axutil_stream_get_len (out_stream, env); + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, + stream_len); + + status = axis2_simple_http_svr_conn_write_response(svr_conn, env, + response); + request_handled = AXIS2_TRUE; + if(tmp_stat_line) + { + axis2_http_status_line_free(tmp_stat_line, env); + tmp_stat_line = NULL; + } + } + } + else + { + /* Other case than, PUT, DELETE, HEAD, GET and POST */ + /* 501, Request method is not implemented */ + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_http_simple_response_set_status_line( + response, env, + http_version, + AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_IMPLEMENTED_CODE_NAME); + + body_string = + axis2_http_transport_utils_get_not_implemented(env, + conf_ctx); + cont_type = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + axis2_http_simple_response_set_header(response, env, cont_type); + + if (body_string) + { + axis2_char_t str_len[10]; + axis2_http_simple_response_set_body_string(response, env, + body_string); + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, + str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + } + + 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;*/ + axis2_char_t *language_str = 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) + { + language_str = axis2_msg_ctx_get_content_language(out_msg_ctx, env); + } + + if (language_str && *language_str && !request_handled) + { + axis2_http_header_t *language = NULL; + language = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LANGUAGE, + language_str); + axis2_http_simple_response_set_header(response, env, language); + } + } + + if (!request_handled) + { + axis2_bool_t do_rest = AXIS2_FALSE; + axis2_bool_t response_written = AXIS2_FALSE; + if (is_get || is_head || is_put || is_delete || + 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_http_header_t *content_type_header = NULL; + axis2_char_t *temp = NULL; + axis2_char_t *language_header_value = NULL; + axis2_http_header_t *language_header = NULL; + content_type_header = axis2_http_simple_response_get_first_header( + response, + env, + AXIS2_HTTP_HEADER_CONTENT_TYPE); + + language_header = axis2_http_simple_response_get_first_header( + response, + env, + AXIS2_HTTP_HEADER_CONTENT_LANGUAGE); + + if (content_type_header) + { + content_type_header_value = axis2_http_header_get_value(content_type_header, + env); + } + + if (content_type_header_value) + { + temp = axutil_strdup(env, content_type_header_value); + } + + if (language_header) + { + language_header_value = axis2_http_header_get_value(language_header, + env); + } + + if (temp) + { + axis2_char_t *content_type = NULL; + axis2_char_t *char_set = NULL; + axis2_char_t *temp2 = NULL; + + temp2 = strchr(temp, AXIS2_SEMI_COLON); + if (temp2) + { + *temp2 = AXIS2_ESC_NULL; + temp2++; + char_set = axutil_strcasestr(temp2, AXIS2_HTTP_CHAR_SET_ENCODING); + } + + if (char_set) + { + char_set = axutil_strltrim(env, char_set, AXIS2_SPACE_TAB_EQ); + } + + 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, AXIS2_F_SLASH); + if (temp2) + { + *temp2 = AXIS2_ESC_NULL; + temp = AXIS2_MALLOC(env->allocator, + sizeof(axis2_char_t) * + ((int)strlen(content_type) + 3)); + if (!temp) + { + AXIS2_HANDLE_ERROR(env, 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)) + { + /* 406, Not Acceptable */ + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME); + + body_string = + axis2_http_transport_utils_get_not_acceptable(env, + conf_ctx); + cont_type = + axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + if (body_string) + { + axis2_char_t str_len[10]; + axis2_http_simple_response_set_body_string(response, env, + body_string); + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = + axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, + str_len); + + axis2_http_simple_response_set_header(response, + env, + cont_len); + } + + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + response_written = AXIS2_TRUE; + } + AXIS2_FREE(env->allocator, temp); + } + } + + if (content_type) + { + AXIS2_FREE(env->allocator, content_type); + } + + if (char_set) + { + temp2 = strchr(char_set, AXIS2_EQ); + } + + if (temp2) + { + ++temp2; + } + + if (char_set && accept_charset_header_value && + !axutil_strcasestr(accept_charset_header_value, char_set) && + !axutil_strcasestr(accept_charset_header_value, temp2)) + { + /* 406, Not Acceptable */ + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME); + body_string = + axis2_http_transport_utils_get_not_acceptable(env, + conf_ctx); + cont_type = + axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + if (body_string) + { + axis2_char_t str_len[10]; + axis2_http_simple_response_set_body_string(response, env, + body_string); + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, + str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + response_written = AXIS2_TRUE; + } + 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)) + { + /* 406, Not acceptable */ + axis2_http_header_t *cont_len = NULL; + axis2_http_header_t *cont_type = NULL; + axis2_char_t *body_string = NULL; + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_VAL, + AXIS2_HTTP_RESPONSE_NOT_ACCEPTABLE_CODE_NAME); + + body_string = + axis2_http_transport_utils_get_not_acceptable(env, + conf_ctx); + cont_type = + axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_TYPE, + AXIS2_HTTP_HEADER_ACCEPT_TEXT_HTML); + + axis2_http_simple_response_set_header(response, env, cont_type); + axis2_http_simple_response_remove_headers( + response, + env, + AXIS2_HTTP_HEADER_CONTENT_LANGUAGE); + + if (body_string) + { + axis2_char_t str_len[10]; + axis2_http_simple_response_set_body_string(response, env, + body_string); + sprintf(str_len, "%d", axutil_strlen(body_string)); + cont_len = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, + str_len); + axis2_http_simple_response_set_header(response, env, cont_len); + } + + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, 0); + axis2_simple_http_svr_conn_write_response(svr_conn, env, response); + request_handled = AXIS2_TRUE; + status = AXIS2_TRUE; + response_written = AXIS2_TRUE; + } + } + } + + if (!response_written) + { + /* If in there is a soap message is to to be sent in the back channel then we go inside this + * block. Somewhere in the receiveing end axis2_op_ctx_set_response_written() function has + * been called by this time to indicate to append the message into the http back channel. + */ + 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 neccessary 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 *simple_header = NULL; + size--; + simple_header = (axis2_http_header_t *) + axutil_array_list_get(output_header_list, + env, size); + axis2_http_simple_response_set_header(response, + env, + simple_header); + } + + if (axis2_msg_ctx_get_status_code(out_msg_ctx, env)) + { + int status_code = 0; + axis2_char_t *status_code_str = NULL; + status_code = axis2_msg_ctx_get_status_code(out_msg_ctx, env); + + switch (status_code) + { + case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_CONTINUE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_ACK_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_ACK_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_GONE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME; + break; + default: + status_code = AXIS2_HTTP_RESPONSE_OK_CODE_VAL; + status_code_str = + AXIS2_HTTP_RESPONSE_OK_CODE_NAME; + break; + } + + axis2_http_simple_response_set_status_line(response, env, + http_version, + status_code, + status_code_str); + request_handled = AXIS2_TRUE; + } + } + } + + if (!request_handled) + { + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_OK_CODE_VAL, + AXIS2_HTTP_RESPONSE_OK_CODE_NAME); + + if (!is_head) + { + /* This is where we append the message into the http back channel.*/ + axis2_http_simple_response_set_body_stream(response, env, out_stream); + } + } + } + else if (op_ctx) + { + /* If response is not written */ + 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 neccssary 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 *simeple_header = NULL; + size--; + simeple_header = (axis2_http_header_t *) + axutil_array_list_get(output_header_list, + env, size); + axis2_http_simple_response_set_header(response, env, + simeple_header); + } + + 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); + axis2_char_t *status_code_str = NULL; + switch (status_code) + { + case AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_RESET_CONTENT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME; + break; + default: + status_code = + AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL; + status_code_str = + AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_NAME; + break; + } + axis2_http_simple_response_set_status_line( + response, env, http_version, + status_code, + status_code_str); + } + else + { + /* status code not available in msg_ctx */ + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_VAL, + AXIS2_HTTP_RESPONSE_NO_CONTENT_CODE_NAME); + } + + request_handled = AXIS2_TRUE; + } + 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); + axis2_char_t *status_code_str = NULL; + switch (status_code) + { + case AXIS2_HTTP_RESPONSE_CONTINUE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_CONTINUE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_OK_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_OK_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_MULTIPLE_CHOICES_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_MOVED_PERMANENTLY_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_SEE_OTHER_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_NOT_MODIFIED_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_TEMPORARY_REDIRECT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_BAD_REQUEST_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_REQUEST_TIMEOUT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_CONFLICT_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_CONFLICT_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_GONE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_GONE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_PRECONDITION_FAILED_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_REQUEST_ENTITY_TOO_LARGE_CODE_NAME; + break; + case AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_VAL: + status_code_str = + AXIS2_HTTP_RESPONSE_SERVICE_UNAVAILABLE_CODE_NAME; + break; + default: + status_code = AXIS2_HTTP_RESPONSE_ACK_CODE_VAL; + status_code_str = + AXIS2_HTTP_RESPONSE_ACK_CODE_NAME; + break; + } + axis2_http_simple_response_set_status_line( + response, env, http_version, + status_code, + status_code_str); + + request_handled = AXIS2_TRUE; + } + } + } + if (!request_handled) + { + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_ACK_CODE_VAL, + AXIS2_HTTP_RESPONSE_ACK_CODE_NAME); + } + } + else + { + axis2_http_simple_response_set_status_line( + response, env, http_version, + AXIS2_HTTP_RESPONSE_ACK_CODE_VAL, + AXIS2_HTTP_RESPONSE_ACK_CODE_NAME); + } + + if (!response_written) + { + int stream_len = 0; + stream_len = axutil_stream_get_len(out_stream, env); + + /*axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, + stream_len);*/ + + /* This is where it actually write to the wire in the http back channel + * append case. */ + if(out_msg_ctx) + { + axutil_array_list_t *mime_parts = NULL; + mime_parts = axis2_msg_ctx_get_mime_parts(out_msg_ctx, env); + /* If mime_parts is there then that means we send MTOM. So + * in order to send MTOM we are enabling HTTP1.1 and cunk transfer + * encoding */ + + if(mime_parts) + { + axis2_http_header_t *transfer_enc_header = NULL; + axutil_param_t *callback_name_param = NULL; + axis2_char_t *mtom_sending_callback_name = NULL; + + /* Getting the sender callback name paramter if it is + * specified in the configuration file */ + + callback_name_param = axis2_msg_ctx_get_parameter(out_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(mtom_sending_callback_name) + { + axis2_http_simple_response_set_mtom_sending_callback_name( + response, env, mtom_sending_callback_name); + } + } + + axis2_http_simple_response_set_mime_parts(response, env, mime_parts); + + axis2_http_simple_response_set_http_version(response, env, + AXIS2_HTTP_HEADER_PROTOCOL_11); + + transfer_enc_header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED); + + axis2_http_simple_response_set_header(response, env, + transfer_enc_header); + + /* In the chunking case content-length is zero */ + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, + 0); + } + else + { + axis2_http_worker_set_response_headers(http_worker, env, svr_conn, + simple_request, response, + stream_len); + } + } + status = axis2_simple_http_svr_conn_write_response(svr_conn, + env, + response); + } + } + } + + if (url_external_form) + { + AXIS2_FREE(env->allocator, url_external_form); + url_external_form = NULL; + } + if (op_ctx) + { + axis2_msg_ctx_t *out_msg_ctx = NULL; + axis2_msg_ctx_t *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]; + + 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_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 */ + + msg_ctx = NULL; + axutil_url_free(request_url, env); + axutil_string_free(soap_action_str, env); + request_url = NULL; + return status; +} + +static axis2_status_t +axis2_http_worker_set_response_headers( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_simple_http_svr_conn_t * svr_conn, + axis2_http_simple_request_t * simple_request, + axis2_http_simple_response_t * simple_response, + axis2_ssize_t content_length) +{ + axis2_http_header_t *conn_header = NULL; + + AXIS2_PARAM_CHECK(env->error, svr_conn, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, simple_request, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, simple_response, AXIS2_FAILURE); + + if(AXIS2_FALSE == axis2_http_simple_response_contains_header(simple_response, env, + AXIS2_HTTP_HEADER_CONNECTION)) + { + conn_header = axis2_http_simple_request_get_first_header(simple_request, env, + AXIS2_HTTP_HEADER_CONNECTION); + if(conn_header) + { + axis2_char_t *value = NULL; + value = axis2_http_header_get_value(conn_header, env); + + if(0 == axutil_strcasecmp(value, AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE)) + { + /* Comment these until keep alive support is completed for simple Axis2/C server */ + /*axis2_http_header_t *header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_KEEPALIVE); + + axis2_http_simple_response_set_header(simple_response, env, header); + axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_TRUE);*/ + } + + if(0 == axutil_strcasecmp(value, AXIS2_HTTP_HEADER_CONNECTION_CLOSE)) + { + axis2_http_header_t *header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_CLOSE); + + axis2_http_simple_response_set_header(simple_response, env, header); + axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE); + } + } + else + { /* Connection Header not available */ + axis2_char_t *http_version = NULL; + http_version = axis2_http_simple_response_get_http_version(simple_response, env); + if(http_version && !axutil_strcasecmp(http_version, AXIS2_HTTP_HEADER_PROTOCOL_11)) + { + /* Comment these until keep alive support is completed for simple Axis2/C server */ + /*axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_TRUE);*/ + /* Instead add following to always send close connection header to indicate that + * we don't support http keep alive yet in simple Axis2/C server + */ + axis2_http_header_t *header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONNECTION, AXIS2_HTTP_HEADER_CONNECTION_CLOSE); + + axis2_http_simple_response_set_header(simple_response, env, header); + /*axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE);*/ + } + else + { + axis2_simple_http_svr_conn_set_keep_alive(svr_conn, env, AXIS2_FALSE); + } + } + + if(!axis2_http_simple_response_contains_header(simple_response, env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING)) + { + if(AXIS2_FALSE == axis2_http_simple_request_contains_header(simple_request, env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING)) + { + if(0 != content_length) + { + axis2_char_t content_len_str[10]; + axis2_http_header_t *content_len_hdr = NULL; + + sprintf(content_len_str, "%d", content_length); + content_len_hdr = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH, content_len_str); + axis2_http_simple_response_set_header(simple_response, env, content_len_hdr); + } + } + else + { + /* Having Transfer encoding Header */ + axis2_http_header_t *transfer_enc_header = axis2_http_header_create(env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED); + + axis2_http_simple_response_set_header(simple_response, env, transfer_enc_header); + } + } + } + return AXIS2_SUCCESS; +} + +static axutil_hash_t * +axis2_http_worker_get_headers( + axis2_http_worker_t * http_worker, + const axutil_env_t * env, + axis2_http_simple_request_t * request) +{ + axutil_array_list_t *header_list = NULL; + int hdr_count = 0; + int i = 0; + axutil_hash_t *header_map = NULL; + + AXIS2_PARAM_CHECK(env->error, request, NULL); + + header_list = axis2_http_simple_request_get_headers(request, env); + if(!header_list) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "http simple request" + "doesn't contain a header list"); + return NULL; + } + hdr_count = axutil_array_list_size(header_list, env); + if(0 == hdr_count) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "http simple request , " + "header list contains zero headers"); + return NULL; + } + + for(i = 0; i < hdr_count; i++) + { + axis2_http_header_t *tmp_hdr = NULL; + tmp_hdr = axutil_array_list_get(header_list, env, i); + if(!tmp_hdr) + { + continue; + } + if(!header_map) + { + header_map = axutil_hash_make(env); + if(!header_map) + { + return NULL; + } + } + axutil_hash_set(header_map, axis2_http_header_get_name(tmp_hdr, env), + AXIS2_HASH_KEY_STRING, tmp_hdr); + } + return header_map; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_http_worker_set_svr_port( + axis2_http_worker_t * worker, + const axutil_env_t * env, + int port) +{ + worker->svr_port = port; + return AXIS2_SUCCESS; +} +#if 0 +static axis2_char_t * +axis2_http_worker_get_server_time( + axis2_http_worker_t * http_worker, + const axutil_env_t * env) +{ + time_t tp; + char *time_str; + tp = time(&tp); + time_str = ctime(&tp); + if(!time_str) + { + return NULL; + } + if(AXIS2_NEW_LINE == time_str[strlen(time_str) - 1]) + { + time_str[strlen(time_str) - 1] = AXIS2_ESC_NULL; + } + /* We use the ANSI C Date Format, which is Legal according to RFC2616, + * Section 3.3.1. We are not a HTTP/1.1 only server, and thus, it suffices. + */ + return time_str; +} +#endif + +static axis2_http_simple_response_t * +axis2_http_worker_create_simple_response( + axis2_http_worker_t *http_worker, + const axutil_env_t *env) +{ + axis2_http_simple_response_t *response = NULL; + response = axis2_http_simple_response_create_default(env); + if(response) + { + axis2_http_header_t *server = NULL; + axis2_http_header_t *server_date = NULL; + axis2_char_t *date_str = NULL; + char *date_str_tmp = NULL; + time_t tp; + size_t date_str_len = 0; + + /* create "Date: xxxx GMT" HTTP header */ + tp = time(&tp); + date_str_tmp = ctime(&tp); + if(!date_str_tmp) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot get server time"); + return NULL; + } + + date_str_len = strlen(date_str_tmp); + if(AXIS2_NEW_LINE == date_str_tmp[date_str_len - 1]) + { + date_str_len -= 1; + date_str_tmp[date_str_len] = AXIS2_ESC_NULL; + } + /* We use the ANSI C Date Format, which is Legal according to RFC2616, + * Section 3.3.1. We are not a HTTP/1.1 only server, and thus, it suffices. + */ + + date_str = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (date_str_len + 5)); + if(!date_str) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + + } + sprintf(date_str, "%s GMT", date_str_tmp); + server_date = axis2_http_header_create(env, AXIS2_HTTP_HEADER_DATE, date_str); + AXIS2_FREE(env->allocator, date_str); + axis2_http_simple_response_set_header(response, env, server_date); + + /* create "Server: Axis2C/x.x.x (Simple Axis2 HTTP Server)" HTTP Header */ + server = axis2_http_header_create(env, AXIS2_HTTP_HEADER_SERVER, + AXIS2_HTTP_HEADER_SERVER_AXIS2C AXIS2_HTTP_SERVER); + axis2_http_simple_response_set_header(response, env, server); + } + return response; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_http_worker_set_is_application_client_side( + axis2_http_worker_t *http_worker, + const axutil_env_t *env, + axis2_bool_t application_client_side) +{ + http_worker->is_application_client_side = application_client_side; +} + + diff --git a/src/core/transport/http/common/simple_http_svr_conn.c b/src/core/transport/http/common/simple_http_svr_conn.c new file mode 100644 index 0000000..a68c48e --- /dev/null +++ b/src/core/transport/http/common/simple_http_svr_conn.c @@ -0,0 +1,504 @@ +/* + * 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_simple_http_svr_conn.h> +#include <axis2_http_transport.h> +#include <axutil_string.h> +#include <axutil_network_handler.h> +#include <axutil_http_chunked_stream.h> +#include <platforms/axutil_platform_auto_sense.h> +#include <string.h> +#include <axis2_http_simple_response.h> +#include <axis2_http_transport_utils.h> + +struct axis2_simple_http_svr_conn +{ + int socket; + axutil_stream_t *stream; + axis2_bool_t keep_alive; +}; + +static axis2_char_t * +axis2_simple_http_svr_conn_read_line( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env); + +AXIS2_EXTERN axis2_simple_http_svr_conn_t *AXIS2_CALL +axis2_simple_http_svr_conn_create( + const axutil_env_t * env, + int sockfd) +{ + axis2_simple_http_svr_conn_t *svr_conn = NULL; + svr_conn = (axis2_simple_http_svr_conn_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_simple_http_svr_conn_t)); + if(!svr_conn) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "server connection failed. Insufficient memory"); + return NULL; + } + + memset((void *)svr_conn, 0, sizeof(axis2_simple_http_svr_conn_t)); + svr_conn->socket = sockfd; + + if(-1 != svr_conn->socket) + { + svr_conn->stream = axutil_stream_create_socket(env, svr_conn->socket); + if(!svr_conn->stream) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "socket creation failed, socket %d", sockfd); + axis2_simple_http_svr_conn_free(svr_conn, env); + return NULL; + } + } + return svr_conn; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_simple_http_svr_conn_free( + axis2_simple_http_svr_conn_t *svr_conn, + const axutil_env_t * env) +{ + axis2_simple_http_svr_conn_close(svr_conn, env); + AXIS2_FREE(env->allocator, svr_conn); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_close( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + axutil_stream_free(svr_conn->stream, env); + if(-1 != svr_conn->socket) + { + axutil_network_handler_close_socket(env, svr_conn->socket); + svr_conn->socket = -1; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_simple_http_svr_conn_is_open( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + if(-1 != svr_conn->socket) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_set_keep_alive( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env, + axis2_bool_t keep_alive) +{ + svr_conn->keep_alive = keep_alive; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_simple_http_svr_conn_is_keep_alive( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return svr_conn->keep_alive; +} + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axis2_simple_http_svr_conn_get_stream( + const axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return svr_conn->stream; +} + +AXIS2_EXTERN axis2_http_response_writer_t *AXIS2_CALL +axis2_simple_http_svr_conn_get_writer( + const axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return axis2_http_response_writer_create(env, svr_conn->stream); +} + +AXIS2_EXTERN axis2_http_simple_request_t *AXIS2_CALL +axis2_simple_http_svr_conn_read_request( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + axis2_char_t* str_line = NULL; + axis2_bool_t end_of_headers = AXIS2_FALSE; + axis2_http_request_line_t *request_line = NULL; + axis2_http_simple_request_t *request = NULL; + + /* read first line of the request (which is <HTTP METHOD> <URI> <HTTP VERSION> CRLF */ + str_line = axis2_simple_http_svr_conn_read_line(svr_conn, env); + if(str_line) + { + request_line = axis2_http_request_line_parse_line(env, str_line); + AXIS2_FREE(env->allocator, str_line); + str_line = NULL; + } + + if(!request_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + return NULL; + } + request = axis2_http_simple_request_create(env, request_line, NULL, 0, svr_conn->stream); + + /* now read the headers until we find a line only having CRLF */ + while(AXIS2_FALSE == end_of_headers) + { + str_line = axis2_simple_http_svr_conn_read_line(svr_conn, env); + if(!str_line) + { + /*if nothing is read, this loop should be broken. Otherwise, going to be endless loop */ + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "reading http header failed"); + break; + } + + if(0 == axutil_strcmp(str_line, AXIS2_HTTP_CRLF)) + { + /* line contains only CRLF, so should be end of headers */ + end_of_headers = AXIS2_TRUE; + } + else + { + axis2_http_header_t *tmp_header = axis2_http_header_create_by_str(env, str_line); + if(tmp_header) + { + axis2_http_simple_request_add_header(request, env, tmp_header); + } + } + + AXIS2_FREE(env->allocator, str_line); + str_line = NULL; + } + return request; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_write_response( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env, + axis2_http_simple_response_t * response) +{ + axis2_http_response_writer_t *response_writer = NULL; + axutil_array_list_t *headers = NULL; + axutil_stream_t *response_stream = NULL; + axis2_char_t *response_body = NULL; + int body_size = 0; + + axis2_http_header_t *enc_header = NULL; + axis2_bool_t chuked_encoding = AXIS2_FALSE; + axis2_char_t *status_line = NULL; + axis2_bool_t binary_content = AXIS2_FALSE; + axis2_char_t *content_type = NULL; + + AXIS2_PARAM_CHECK(env->error, response, AXIS2_FAILURE); + + response_writer = axis2_http_response_writer_create(env, svr_conn->stream); + if(!response_writer) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create http response writer"); + return AXIS2_FAILURE; + } + + content_type = (axis2_char_t *)axis2_http_simple_response_get_content_type(response, env); + if(content_type) + { + if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED) + && strstr(content_type,AXIS2_HTTP_HEADER_ACCEPT_XOP_XML)) + { + binary_content = AXIS2_TRUE; + } + } + + enc_header = axis2_http_simple_response_get_first_header(response, env, + AXIS2_HTTP_HEADER_TRANSFER_ENCODING); + if(enc_header) + { + axis2_char_t *enc_value = axis2_http_header_get_value(enc_header, env); + if(enc_value && (0 == axutil_strcmp(enc_value, AXIS2_HTTP_HEADER_TRANSFER_ENCODING_CHUNKED))) + { + chuked_encoding = AXIS2_TRUE; + + /* remove the content length header */ + axis2_http_simple_response_remove_headers(response, env, + AXIS2_HTTP_HEADER_CONTENT_LENGTH); + } + } + + /* print status line */ + status_line = axis2_http_simple_response_get_status_line(response, env); + if(!status_line) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + axis2_http_response_writer_print_str(response_writer, env, status_line); + + headers = axis2_http_simple_response_get_headers(response, env); + if(headers) + { + int i = 0; + int count = axutil_array_list_size(headers, env); + for(; i < count; i++) + { + axis2_http_header_t *header = + (axis2_http_header_t *)axutil_array_list_get(headers, env, i); + if(header) + { + axis2_char_t *header_ext_form = axis2_http_header_to_external_form(header, env); + axis2_http_response_writer_print_str(response_writer, env, header_ext_form); + AXIS2_FREE(env->allocator, header_ext_form); + } + } + } + + /* write empty line after http headers */ + axis2_http_response_writer_print_str(response_writer, env, AXIS2_HTTP_CRLF); + + /* write the body */ + response_stream = axis2_http_simple_response_get_body(response, env); + if(response_stream) + { + body_size = axutil_stream_get_len(response_stream, env); + response_body = axutil_stream_get_buffer(response_stream, env); + axutil_stream_flush_buffer(response_stream, env); + response_body[body_size] = AXIS2_ESC_NULL; + } + + if(body_size <= 0 && !binary_content) + { + /* no body available to write. Note that this is not an error. We might want to write only + * status information and hence, this is a valid case */ + axis2_http_response_writer_free(response_writer, env); + return AXIS2_SUCCESS; + } + + if(!chuked_encoding && !binary_content) + { + /* This sending a normal SOAP response without chunk transfer encoding */ + axis2_status_t write_stat = AXIS2_FAILURE; + write_stat = axis2_http_response_writer_println_str(response_writer, env, response_body); + if(write_stat != AXIS2_SUCCESS) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_RESPONSE, AXIS2_FAILURE); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + } + else if(!binary_content) + { + /* Sending a normal SOAP response enabling http chunking */ + axutil_http_chunked_stream_t *chunked_stream = NULL; + int left = body_size; + chunked_stream = axutil_http_chunked_stream_create(env, svr_conn->stream); + while(left > 0) + { + int len = -1; + len = axutil_http_chunked_stream_write(chunked_stream, env, response_body, body_size); + if(len <= 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "cannot write data to chunked stream"); + axutil_http_chunked_stream_free(chunked_stream, env); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + left -= len; + } + axutil_http_chunked_stream_write_last_chunk(chunked_stream, env); + axutil_http_chunked_stream_free(chunked_stream, env); + } + else + { + /* In the MTOM case we enable chunking in order to send the attachment */ + axutil_http_chunked_stream_t *chunked_stream = NULL; + axis2_status_t write_stat = AXIS2_FAILURE; + axutil_array_list_t *mime_parts = NULL; + axis2_char_t *mtom_sending_callback_name = NULL; + + mime_parts = axis2_http_simple_response_get_mime_parts(response, env); + if(!mime_parts) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No mime parts are given"); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + + /* 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 */ + mtom_sending_callback_name = axis2_http_simple_response_get_mtom_sending_callback_name( + response, env); + 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"); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + } + + chunked_stream = axutil_http_chunked_stream_create(env, svr_conn->stream); + write_stat = axis2_http_transport_utils_send_mtom_message(chunked_stream, env, mime_parts, + mtom_sending_callback_name); + axutil_http_chunked_stream_free(chunked_stream, env); + + if(write_stat != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "writing mime parts failed"); + axis2_http_response_writer_free(response_writer, env); + return AXIS2_FAILURE; + } + } + + axis2_http_response_writer_free(response_writer, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_set_rcv_timeout( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env, + int timeout) +{ + return axutil_network_handler_set_sock_option(env, svr_conn->socket, SO_RCVTIMEO, timeout); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_simple_http_svr_conn_set_snd_timeout( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env, + int timeout) +{ + return axutil_network_handler_set_sock_option(env, svr_conn->socket, SO_SNDTIMEO, timeout); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_simple_http_svr_conn_get_svr_ip( + const axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return axutil_network_handler_get_svr_ip(env, svr_conn->socket); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_simple_http_svr_conn_get_peer_ip( + const axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + return axutil_network_handler_get_peer_ip(env, svr_conn->socket); +} + +static axis2_char_t * +axis2_simple_http_svr_conn_read_line( + axis2_simple_http_svr_conn_t * svr_conn, + const axutil_env_t * env) +{ + axis2_char_t* str_line = NULL; + axis2_char_t tmp_buf[2048]; + int read = -1; + + /* peek for 2047 characters to verify whether it contains CRLF character */ + while((read = axutil_stream_peek_socket(svr_conn->stream, env, tmp_buf, 2048 - 1)) > 0) + { + axis2_char_t *start = tmp_buf; + axis2_char_t *end = NULL; + tmp_buf[read] = AXIS2_ESC_NULL; + end = strstr(tmp_buf, AXIS2_HTTP_CRLF); + if(end) + { + axis2_char_t *buffer = NULL; + if(str_line) + { + /* header is more than 2048 character. this is not a common case, and not optimized + * for performance (reading in a temp buffer and then strcat to get final buffer */ + buffer = tmp_buf; + } + else + { + /* header is less than 2048 characters, this is the common case. So to improve + * the performance, the buffer is malloc and then used to read the stream. */ + buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, end - start + 3); + } + + /* read the data including CRLF (hence the size = end - start + 2) */ + read = axutil_stream_read(svr_conn->stream, env, buffer, end - start + 2); + if(read > 0) + { + buffer[read] = AXIS2_ESC_NULL; + + if(str_line) + { + axis2_char_t* tmp_str_line = NULL; + tmp_str_line = axutil_stracat(env, str_line, buffer); + if(tmp_str_line) + { + AXIS2_FREE(env->allocator, str_line); + str_line = tmp_str_line; + } + } + else + { + str_line = buffer; + } + } + else + { + /* read returns 0 or negative value, this could be an error */ + if(str_line) + { + AXIS2_FREE(env->allocator, str_line); + str_line = NULL; + } + else + { + AXIS2_FREE(env->allocator, buffer); + } + } + break; + } + else + { + /* not reached end yet */ + read = axutil_stream_read(svr_conn->stream, env, tmp_buf, 2048 - 1); + if(read > 0) + { + axis2_char_t* tmp_str_line = NULL; + tmp_buf[read] = AXIS2_ESC_NULL; + tmp_str_line = axutil_stracat(env, str_line, tmp_buf); + if(tmp_str_line) + { + if(str_line) + { + AXIS2_FREE(env->allocator, str_line); + } + str_line = tmp_str_line; + } + } + } + } + + return str_line; +} |