diff options
Diffstat (limited to 'src/core/transport/http/common/http_simple_request.c')
-rw-r--r-- | src/core/transport/http/common/http_simple_request.c | 433 |
1 files changed, 433 insertions, 0 deletions
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; +} |