AXIS2_EXTERN int AXIS2_CALL axutil_http_chunked_stream_read( axutil_http_chunked_stream_t *chunked_stream, const axutil_env_t *env, void *buffer, size_t count) { int len = -1; int yet_to_read = 0; axutil_stream_t *stream = chunked_stream->stream; if(!buffer) { return -1; } if(!stream) { AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NULL_STREAM_IN_CHUNKED_STREAM, AXIS2_FAILURE); return -1; } if(AXIS2_TRUE == chunked_stream->end_of_chunks) { return 0; } if(AXIS2_FALSE == chunked_stream->chunk_started) { axutil_http_chunked_stream_start_chunk(chunked_stream, env); } yet_to_read = (int)count; /* We are sure that the difference lies within the int range */ while(AXIS2_FALSE == chunked_stream->end_of_chunks && yet_to_read > 0) { if(chunked_stream->unread_len < yet_to_read) { len = axutil_stream_read(chunked_stream->stream, env, (axis2_char_t *)buffer + count - yet_to_read, chunked_stream->unread_len); yet_to_read -= len; chunked_stream->unread_len -= len; if(chunked_stream->unread_len <= 0) { axutil_http_chunked_stream_start_chunk(chunked_stream, env); } } else { len = axutil_stream_read(chunked_stream->stream, env, (axis2_char_t *)buffer + count - yet_to_read, yet_to_read); yet_to_read -= len; chunked_stream->unread_len -= len; } } return ((int)count - yet_to_read); /* We are sure that the difference lies within the int range */ }
/** Emulates fgets() for a axutil_stream_t. * @param st * @param env * @param buf * @param size * @param delete_cr * @return buf on success, and NULL when end of file occurs while no characters * have been read. */ char* sp_stream_getline( axutil_stream_t *st, const axutil_env_t *env, char *buf, unsigned int size, const int delete_cr) { if (NULL == st || NULL == buf) return; char c; int n_read = 1; while (size > n_read) { if ( 0 == axutil_stream_read( st, env, &c, 1)) { if (1 == n_read) return NULL; else break; } if (delete_cr) { if ('\r' == c) continue; } *buf++ = c; n_read++; if ('\n' == c || '\0' == c) break; } *buf = '\0'; return buf; }
static axis2_status_t axutil_http_chunked_stream_start_chunk( axutil_http_chunked_stream_t *chunked_stream, const axutil_env_t *env) { axis2_char_t tmp_buf[3] = ""; axis2_char_t str_chunk_len[512] = ""; axis2_char_t *tmp = NULL; int read = -1; /* remove the last CRLF of the previous chunk if any */ if(AXIS2_TRUE == chunked_stream->chunk_started) { read = axutil_stream_read(chunked_stream->stream, env, tmp_buf, 2); chunked_stream->chunk_started = AXIS2_FALSE; } /* read the len and chunk extension */ while((read = axutil_stream_read(chunked_stream->stream, env, tmp_buf, 1)) > 0) { tmp_buf[read] = '\0'; strcat(str_chunk_len, tmp_buf); if(0 != strstr(str_chunk_len, AXIS2_HTTP_CRLF)) { break; } } /* check whether we have extensions */ tmp = strchr(str_chunk_len, ';'); if(tmp) { /* we don't use extensions right now */ *tmp = '\0'; } chunked_stream->current_chunk_size = strtol(str_chunk_len, NULL, 16); if(0 == chunked_stream->current_chunk_size) { /* Read the last CRLF */ read = axutil_stream_read(chunked_stream->stream, env, tmp_buf, 2); chunked_stream->end_of_chunks = AXIS2_TRUE; } else { chunked_stream->chunk_started = AXIS2_TRUE; chunked_stream->unread_len = chunked_stream->current_chunk_size; } return AXIS2_SUCCESS; }
//----------------------------------------------------------------------------- // Reads arbitrary binary data from the file fp. // fp is positioned at the start of the file. // char *sp_load_binary_file( const axutil_env_t *env, char *header_blob, axutil_stream_t *st, int *len) { *len = 0; char *bin_data = NULL; TmpStore *ts = NULL; axutil_linked_list_t *ll = axutil_linked_list_create(env); // pre-pend header-blob (if any) in front of the remaining data if (header_blob) { int hdr_size = strlen(header_blob); if ( (hdr_size) > SP_IMG_BUF_SIZE) { // failsafe - should never happen. axutil_linked_list_free(ll, env); return NULL; } ts = (TmpStore *)AXIS2_MALLOC(env->allocator, sizeof(TmpStore)); memcpy(ts->buf, header_blob, hdr_size); ts->size = hdr_size; *len += hdr_size; axutil_linked_list_add (ll, env, (void *)ts); } int n_read = 0; while ( 1 ) { ts = (TmpStore *)AXIS2_MALLOC(env->allocator, sizeof(TmpStore)); n_read = axutil_stream_read(st, env, ts->buf, SP_IMG_BUF_SIZE); if (0 == n_read) { AXIS2_FREE(env->allocator, ts); break; } ts->size = n_read; *len += n_read; axutil_linked_list_add (ll, env, (void *)ts); } bin_data = compose_buffer(env, *len, ll); axutil_linked_list_free(ll, env); return bin_data; }
AXIS2_EXTERN int AXIS2_CALL axis2_amqp_util_on_data_request( char* buffer, int size, void* ctx) { const axutil_env_t* env = NULL; int len = -1; axis2_callback_info_t* cb_ctx = (axis2_callback_info_t*)ctx; axutil_stream_t* in_stream = NULL; if(!buffer || !ctx) { return 0; } if(cb_ctx->unread_len <= 0 && -1 != cb_ctx->content_length) { return 0; } env = ((axis2_callback_info_t*)ctx)->env; in_stream = (axutil_stream_t*)((axis2_callback_info_t *)ctx)->in_stream; --size; /* reserve space to insert trailing null */ len = axutil_stream_read(in_stream, env, buffer, size); if(len > 0) { buffer[len] = AXIS2_AMQP_ESC_NULL; ((axis2_callback_info_t*)ctx)->unread_len -= len; } else if(len == 0) { ((axis2_callback_info_t*)ctx)->unread_len = 0; } return len; }
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; }
AXIS2_EXTERN int AXIS2_CALL axis2_http_client_receive_header( axis2_http_client_t * client, const axutil_env_t * env) { int status_code = -1; axis2_http_status_line_t *status_line = NULL; axis2_char_t str_status_line[AXIS2_HTTP_STATUS_LINE_LENGTH]; axis2_char_t tmp_buf[3]; axis2_char_t str_header[AXIS2_HTTP_HEADER_LENGTH]; int read = 0; int http_status = 0; axis2_bool_t end_of_line = AXIS2_FALSE; axis2_bool_t end_of_headers = AXIS2_FALSE; if(-1 == client->sockfd || !client->data_stream || AXIS2_FALSE == client->request_sent) { axis2_char_t *host; unsigned int port; host = axutil_url_get_host(client->url, env); port = axutil_url_get_port(client->url, env); AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Client data stream null or socket error for host %s and %d port", host, port); AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_HTTP_REQUEST_NOT_SENT, AXIS2_FAILURE); return -1; } /* read the status line */ do { unsigned int str_status_line_length = 0; memset(str_status_line, 0, AXIS2_HTTP_STATUS_LINE_LENGTH); while((read = axutil_stream_read(client->data_stream, env, tmp_buf, 1)) > 0) { /* "read" variable is number of characters read by stream */ tmp_buf[read] = '\0'; /* * buffer overflow prevention : we need to ckeck if we have not reached the maximum status line size ! * a broken / evil server may try to send us more than 512 bytes in the status line ... */ str_status_line_length += read; if (str_status_line_length + 1 > AXIS2_HTTP_STATUS_LINE_LENGTH) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "reached maximum header size %i", AXIS2_HTTP_STATUS_LINE_LENGTH); break; } strcat(str_status_line, tmp_buf); if(0 != strstr(str_status_line, AXIS2_HTTP_CRLF)) { end_of_line = AXIS2_TRUE; break; } } if(read < 0) { AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "http client , response timed out"); AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE); return -2; /* specific status code for time out */ } else if(read == 0) { AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_RESPONSE_SERVER_SHUTDOWN, AXIS2_FAILURE); AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response error, Server Shutdown"); return -1; /* this is a real error ! */ } status_line = axis2_http_status_line_create(env, str_status_line); if(!status_line) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "axis2_http_status_line_create failed for \ str_status_line %s", str_status_line); AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_HTTP_HEADER_START_LINE, AXIS2_FAILURE); http_status = 0; continue; } http_status = axis2_http_status_line_get_status_code(status_line, env); }