/* * 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 #include #include #include #include #include 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; }