You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ma...@apache.org on 2008/07/22 10:43:42 UTC
svn commit: r678680 [2/4] - in /webservices/axis2/trunk/c: ./ axiom/include/
axiom/src/attachments/ axiom/src/om/ include/ samples/ samples/client/mtom/
samples/client/mtom/resources/ samples/server/ samples/server/mtom/
src/core/context/ src/core/desc...
Modified: webservices/axis2/trunk/c/axiom/src/attachments/mime_parser.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/axiom/src/attachments/mime_parser.c?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/axiom/src/attachments/mime_parser.c (original)
+++ webservices/axis2/trunk/c/axiom/src/attachments/mime_parser.c Tue Jul 22 01:43:36 2008
@@ -1,3 +1,4 @@
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -19,48 +20,201 @@
#include <axutil_string.h>
#include <axiom_data_handler.h>
#include <stdio.h>
+#include <ctype.h>
#include <axutil_http_chunked_stream.h>
-#include <ctype.h>
struct axiom_mime_parser
{
+ /* This will keep the attachment and its info*/
axutil_hash_t *mime_parts_map;
+
+ /* This is the actual SOAP part len */
int soap_body_len;
+
+ /* The SOAP part of the message */
axis2_char_t *soap_body_str;
- int chunk_buffer_size;
- int max_chunk_buffers;
+
+ /* The size of the buffer we give to the callback to
+ * read data */
+ int buffer_size;
+
+ /* The number of buffers */
+ int max_buffers;
+
+ /* The attachment dir name, in the case of caching */
+ axis2_char_t *attachment_dir;
+};
+
+struct axiom_search_info
+{
+ /*String need to be searched*/
+ const axis2_char_t *search_str;
+
+ /*The buffers and the lengths need to be searched*/
+ axis2_char_t *buffer1;
+ int len1;
+ axis2_char_t *buffer2;
+ int len2;
+
+ /*Flag to keep what type of search is this buffer has done*/
+ axis2_bool_t primary_search;
+
+ /*The offset where we found the pattern entirely in one buffer*/
+ int match_len1;
+
+ /*when pattern contains in two buffers the length of partial pattern
+ in buffer2 */
+ int match_len2;
+
+ /*Whether we need caching or not*/
+ axis2_bool_t cached;
+
+ /*A pointer to a user provided storage to which we cache the attachment*/
+ void *handler;
+
+ /* Size of the binary when writing to the buffer*/
+ int binary_size;
};
+typedef struct axiom_search_info axiom_search_info_t;
+
+
+#define AXIOM_MIME_PARSER_CONTENT_ID "content-id"
+#define AXIOM_MIME_PARSER_CONTENT_TYPE "content-type"
+
+#define AXIOM_MIME_PARSER_END_OF_MIME_MAX_COUNT 100
+
+static axis2_char_t *axiom_mime_parser_search_for_soap(
+ const axutil_env_t * env,
+ AXIS2_READ_INPUT_CALLBACK callback,
+ void *callback_ctx,
+ int *buf_num,
+ int *len_array,
+ axis2_char_t **buf_array,
+ axiom_search_info_t *search_info,
+ int size,
+ axis2_char_t *mime_boundary,
+ axiom_mime_parser_t *mime_parser);
+
+
+static axis2_char_t *axiom_mime_parser_search_for_crlf(
+ const axutil_env_t * env,
+ AXIS2_READ_INPUT_CALLBACK callback,
+ void *callback_ctx,
+ int *buf_num,
+ int *len_array,
+ axis2_char_t **buf_array,
+ axiom_search_info_t *search_info,
+ int size,
+ axiom_mime_parser_t *mime_parser);
+
+static int axiom_mime_parser_calculate_part_len(
+ const axutil_env_t *env,
+ int buf_num,
+ int *len_list,
+ int maker,
+ axis2_char_t *pos,
+ axis2_char_t *buf
+);
+
+static axis2_char_t * axiom_mime_parser_create_part (
+ const axutil_env_t *env,
+ int part_len,
+ int buf_num,
+ int *len_list,
+ int marker,
+ axis2_char_t *pos,
+ axis2_char_t **buf_list,
+ axiom_mime_parser_t *mime_parser);
+
+static axis2_char_t *axiom_mime_parser_search_string(
+ axiom_search_info_t *search_info,
+ const axutil_env_t *env);
+
+static axis2_char_t *axiom_mime_parser_search_for_attachment(
+ axiom_mime_parser_t *mime_parser,
+ const axutil_env_t * env,
+ AXIS2_READ_INPUT_CALLBACK callback,
+ void *callback_ctx,
+ int *buf_num,
+ int *len_array,
+ axis2_char_t **buf_array,
+ axiom_search_info_t *search_info,
+ int size,
+ axis2_char_t *mime_boundary,
+ axis2_char_t *mime_id);
+
+static axis2_status_t axiom_mime_parser_store_attachment(
+ const axutil_env_t *env,
+ axiom_mime_parser_t *mime_parser,
+ axis2_char_t *mime_id,
+ axis2_char_t *mime_type,
+ axis2_char_t *mime_binary,
+ int mime_binary_len,
+ axis2_bool_t cached);
+
+static void axiom_mime_parser_clear_buffers(
+ const axutil_env_t *env,
+ axis2_char_t **buf_list,
+ int free_from,
+ int free_to);
+
+static axis2_status_t axiom_mime_parser_cache_to_buffer(
+ const axutil_env_t *env,
+ axis2_char_t *buf,
+ int buf_len,
+ axiom_search_info_t *search_info,
+ axiom_mime_parser_t *mime_parser);
+
+
+static axis2_bool_t axiom_mime_parser_is_more_data(
+ axiom_mime_parser_t *mime_parser,
+ const axutil_env_t *env,
+ axis2_callback_info_t *callback_info);
+
+static axis2_char_t *
+ axiom_mime_parser_process_mime_headers(
+ const axutil_env_t *env,
+ axiom_mime_parser_t *mime_parser,
+ axis2_char_t **mime_id,
+ axis2_char_t *mime_headers);
+
+static axis2_status_t
+axiom_mime_parser_cache_to_file(
+ const axutil_env_t* env,
+ axis2_char_t *buf,
+ int buf_len,
+ void *handler);
+
+
AXIS2_EXTERN axiom_mime_parser_t *AXIS2_CALL
axiom_mime_parser_create(
- const axutil_env_t *env)
+ const axutil_env_t * env)
{
axiom_mime_parser_t *mime_parser = NULL;
AXIS2_ENV_CHECK(env, NULL);
- mime_parser = (axiom_mime_parser_t *)
- AXIS2_MALLOC(env->allocator, sizeof(axiom_mime_parser_t));
+ mime_parser = (axiom_mime_parser_t *) AXIS2_MALLOC(env->allocator,
+ sizeof
+ (axiom_mime_parser_t));
if (!mime_parser)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Cannot create MIME parser");
return NULL;
}
mime_parser->mime_parts_map = NULL;
mime_parser->soap_body_len = 0;
- mime_parser->soap_body_str = NULL;
- mime_parser->chunk_buffer_size = 1;
- mime_parser->max_chunk_buffers = AXIOM_MIME_PARSER_MAX_CHUNK_BUFFERS;
+ mime_parser->soap_body_str = NULL; /* shallow copy */
+ mime_parser->buffer_size = 1;
+ mime_parser->max_buffers = AXIOM_MIME_PARSER_MAX_BUFFERS;
+ mime_parser->attachment_dir = NULL;
mime_parser->mime_parts_map = axutil_hash_make(env);
if (!(mime_parser->mime_parts_map))
{
axiom_mime_parser_free(mime_parser, env);
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "Failed in creating MIME parts map. Cannot create MIME parser");
return NULL;
}
@@ -69,16 +223,13 @@
AXIS2_EXTERN void AXIS2_CALL
axiom_mime_parser_free(
- axiom_mime_parser_t *mime_parser,
- const axutil_env_t *env)
+ axiom_mime_parser_t * mime_parser,
+ const axutil_env_t * env)
{
- /* This map is passed on to SOAP builder, and SOAP builder take over the
- * ownership of the map
- */
- mime_parser->mime_parts_map = NULL;
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
- /* The MIME parser doesn't own the SOAP Body string */
- mime_parser->soap_body_str = NULL;
+ /* The map is passed on to SOAP builder, and SOAP builder take over the
+ ownership of the map */
if (mime_parser)
{
@@ -90,365 +241,709 @@
AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_mime_parser_parse(
- axiom_mime_parser_t *mime_parser,
- const axutil_env_t *env,
+ axiom_mime_parser_t * mime_parser,
+ const axutil_env_t * env,
AXIS2_READ_INPUT_CALLBACK callback,
void *callback_ctx,
- axis2_char_t *mime_boundary)
+ axis2_char_t * mime_boundary)
{
- axis2_char_t *buffer = NULL;
- int size = AXIOM_MIME_PARSER_BUFFER_SIZE;
- int len = 0;
- axis2_char_t *root_mime = NULL;
- axis2_char_t *soap_body_str = NULL;
- int soap_body_len = 0;
- axis2_char_t *body_mime = NULL;
- axis2_char_t *mime_binary = NULL;
- int mime_binary_len = 0;
- axis2_char_t *pos = NULL;
- axis2_bool_t end_of_mime = AXIS2_FALSE;
- int count = 0;
- int read = 0;
- int buf_num = 0;
- int buf_len = 0;
- axis2_callback_info_t *cb_ctx = NULL;
+ int size = 0;
+ axis2_char_t *soap_str = NULL;
+ int soap_len = 0;
+ axis2_char_t *mime_headers = NULL;
+ int mime_headers_len = 0;
+ int temp_mime_boundary_size = 0;
+ axis2_char_t *temp_mime_boundary = NULL;
axis2_char_t **buf_array = NULL;
int *len_array = NULL;
+ int buf_num = 0;
+ axis2_char_t *pos = NULL;
+ axiom_search_info_t *search_info = NULL;
+ int part_start = 0;
+ axis2_bool_t end_of_mime = AXIS2_FALSE;
+ int count = 0;
+ int mime_binary_len = 0;
+ axis2_char_t *mime_binary = NULL;
+ int len = 0;
+ axis2_status_t status = AXIS2_FAILURE;
+ axis2_char_t *buffer = NULL;
+ int malloc_len = 0;
+ axis2_callback_info_t *callback_info = NULL;
+
+ callback_info = (axis2_callback_info_t *)callback_ctx;
- cb_ctx = (axis2_callback_info_t *) callback_ctx;
+ /* The user will specify the mime_parser->buffer_size */
- if (cb_ctx->chunked_stream)
+ size = AXIOM_MIME_PARSER_BUFFER_SIZE * (mime_parser->buffer_size);
+
+ /*An array to keep the set of buffers*/
+
+ buf_array = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t *) * (mime_parser->max_buffers));
+
+ if (!buf_array)
{
- buf_array = AXIS2_MALLOC(env->allocator,
- sizeof(axis2_char_t *) * (mime_parser->max_chunk_buffers));
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Failed in creating buffer array");
+ return NULL;
+ }
- if (!buf_array)
- {
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in creating buffer array");
- return NULL;
- }
+ /*Keeps the corresponding lengths of buffers in buf_array*/
- len_array = AXIS2_MALLOC(env->allocator,
- sizeof(int) * (mime_parser->max_chunk_buffers));
-
- if (!len_array)
+ len_array = AXIS2_MALLOC(env->allocator,
+ sizeof(int) * (mime_parser->max_buffers));
+
+
+ if (!len_array)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Failed in creating length array");
+ return NULL;
+ }
+
+ temp_mime_boundary = axutil_stracat(env, "--", mime_boundary);
+ temp_mime_boundary_size = strlen(mime_boundary) + 2;
+
+ /*This struct keeps the pre-post search informations*/
+ search_info = AXIS2_MALLOC(env->allocator,
+ sizeof(axiom_search_info_t));
+
+ /* The first buffer is created */
+ buf_array[buf_num] = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * (size + 1));
+
+ /* The buffer is filled from the callback */
+
+ if(buf_array[buf_num])
+ {
+ len = callback(buf_array[buf_num], size, (void *) callback_ctx);
+ }
+ if(len > 0)
+ {
+ len_array[buf_num] = len;
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error reading from the stream");
+ return NULL;
+ }
+
+ /*starting buffer for the current search*/
+ part_start = buf_num;
+
+ /*We are passing the address of the buf_num , beacause that value
+ is changing inside the method.*/
+
+ /* Following call to the method will search first \r\n\r\n */
+
+ pos = axiom_mime_parser_search_for_crlf(env, callback, callback_ctx, &buf_num,
+ len_array, buf_array, search_info, size, mime_parser);
+
+ if(!pos)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in the message.");
+ return NULL;
+ }
+
+ /* The patteren contains in one buffer */
+
+ if((search_info->match_len2 == 0))
+ {
+ /*Readjusting the buffers for the next search and discarding the prevoius
+ buffers*/
+
+ /* We need the remaining part in the buffer after the \r\n\r\n*/
+
+ malloc_len = buf_array[buf_num] + len_array[buf_num] - pos - 4;
+ if(malloc_len < 0)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in creating length array");
+ "Error in parsing.");
return NULL;
}
+ else
+ {
+ /* Here we will create a new buffer of predefined size fill the
+ * first portion from the remaining part after previous search
+ * and then fill the remaining from the callback */
- size = (mime_parser->chunk_buffer_size) * AXIOM_MIME_PARSER_BUFFER_SIZE;
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+ size + 1));
- while (!axutil_http_chunked_stream_get_end_of_chunks(
- cb_ctx->chunked_stream, env))
- {
- read = 0;
-
- if (buf_num > (mime_parser->max_chunk_buffers - 1))
+ if(malloc_len > 0)
{
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "Attachment size exceeds "
- "the system MTOM configuration parameters");
- return NULL;
+ memcpy(buffer, pos + 4, malloc_len);
}
- buf_array[buf_num] = AXIS2_MALLOC(env->allocator,
- sizeof(axis2_char_t) * (size + 1));
- if (!buf_array[buf_num])
+ /* Here we need to check for more data, because if the message is too small
+ * comapred to the reading size there may be no data in the stream , instead
+ * all the remaining data may be in the buffer */
+
+ if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
{
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in creating buffer");
- return NULL;
+ /* There is more data so fill the remaining from the stream*/
+
+ len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
}
- do
+
+ /* We do not need the data in the previous buffers once we found a particular
+ * string and after worked with those buffers */
+
+ axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+
+ /* Adding the new buffer to the buffer list */
+
+ if(len >= 0)
{
- read += len;
- len = callback(buf_array[buf_num] + read, size - read,
- (void *) callback_ctx);
+ buf_array[buf_num] = buffer;
+ len_array[buf_num] = malloc_len + len;
}
- while ((read < (size-1)) && (len > 0));
-
- *(buf_array[buf_num] + read) = '\0';
- len_array[buf_num] = read;
- buf_num++;
}
- /* If we have only one buffer */
- if (buf_num == 1)
+ }
+
+ /*The pattern divides among two buffers*/
+
+ else if(search_info->match_len2 > 0)
+ {
+ malloc_len = len_array[buf_num] - search_info->match_len2;
+ if(malloc_len < 0)
{
- buffer = buf_array[buf_num - 1];
- }
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in parsing.");
+ return NULL;
+ }
else
{
- int i = 0;
- int temp = 0;
- buf_len = 0;
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+ size + 1));
- for (i = 0; i < buf_num; i++)
+ /* Here the buf_num is the second buffer. We will copy the remaining data
+ * after the partial string in the second buffer */
+
+ if(malloc_len > 0)
{
- if (buf_array[i])
- {
- buf_len += len_array[i];
- }
+ memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
}
- buffer = AXIS2_MALLOC(env->allocator, sizeof(char) * (buf_len + 1));
-
- if (!buffer)
+ if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
{
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in creating buffer");
- return NULL;
+ len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
}
-
- for (i = 0; i < buf_num; i++)
+ axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+ if(len >= 0)
{
- if (buf_array[i])
- {
- memcpy(buffer + temp, buf_array[i], len_array[i]);
- temp += len_array[i];
- AXIS2_FREE(env->allocator, buf_array[i]);
- buf_array[i] = NULL;
- }
+ buf_array[buf_num] = buffer;
+ len_array[buf_num] = malloc_len + len;
}
- *(buffer + temp) = '\0';
}
}
else
{
- size = cb_ctx->content_length + 100;
- buffer = AXIS2_MALLOC(env->allocator,
- sizeof(axis2_char_t) * (size + 1));
- if (!buffer)
- {
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in creating buffer");
- return NULL;
- }
- do
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in parsing.");
+ return NULL;
+ }
+
+ /*Resetting the previous search data and getting ready
+ for the next search */
+
+ part_start = buf_num;
+ pos = NULL;
+ malloc_len = 0;
+
+ search_info->match_len1 = 0;
+ search_info->match_len2 = 0;
+
+ /*In order to extract the soap envelope we need to search for the first
+ --MIMEBOUNDARY */
+
+ pos = axiom_mime_parser_search_for_soap(env, callback, callback_ctx, &buf_num,
+ len_array, buf_array, search_info, size, temp_mime_boundary, mime_parser);
+
+ if(!pos)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error while searching for the SOAP part ");
+ return NULL;
+ }
+
+ if(search_info->match_len2 == 0)
+ {
+ /*Calculating the length of the SOAP str*/
+
+ soap_len = axiom_mime_parser_calculate_part_len (
+ env, buf_num, len_array, part_start, pos, buf_array[buf_num]);
+ if(soap_len > 0)
{
- read += len;
- len = callback(buffer + read, size - read, (void *) callback_ctx);
- }
- while ((read < size) && (len > 0));
+ /* Get the SOAP string from the starting and end buffers containing
+ * the SOAP part */
+
+ soap_str = axiom_mime_parser_create_part(
+ env, soap_len, buf_num, len_array, part_start, pos, buf_array, mime_parser);
+ if(!soap_str)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error while creating the SOAP part from the message ");
+ return NULL;
+ }
+
+ malloc_len = len_array[buf_num] - search_info->match_len1 - temp_mime_boundary_size;
+ if(malloc_len < 0)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in parsing for mime.");
+ return NULL;
+ }
+ else
+ {
+ /* This will fill the new buffer with remaining data after the
+ * SOAP */
+
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+ size + 1));
- buffer[read+1] = '\0';
- buf_len = read;
+ memset(buffer, 0, size + 1);
+ if(malloc_len > 0)
+ {
+ memcpy(buffer, pos + temp_mime_boundary_size, malloc_len);
+ }
+ if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+ {
+ len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+ }
- if (buf_len < cb_ctx->content_length)
+ axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+ if(len >= 0)
+ {
+ buf_array[buf_num] = buffer;
+ len_array[buf_num] = malloc_len + len;
+ }
+ }
+ }
+ else
{
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "Some data in the message was not recieved");
return NULL;
}
- }
+ }
- if (buffer)
+ /* This is the condition where the --MIMEBOUNDARY is devided among two
+ * buffers */
+
+ else if(search_info->match_len2 > 0)
{
- pos = axutil_strstr(buffer, AXIS2_CRLF AXIS2_CRLF);
- if (pos)
+ soap_len = axiom_mime_parser_calculate_part_len (
+ env, buf_num - 1, len_array, part_start, pos, buf_array[buf_num - 1]);
+
+ if(soap_len > 0)
{
- root_mime = pos + 4;
- pos = NULL;
- }
- }
+ /* Here we pass buf_num-1 becasue buf_num does not have any thing we want to
+ * for this particular part. It begins with the latter part of the search string */
- if (root_mime)
- {
- pos = axutil_strstr(root_mime, mime_boundary);
- }
+ soap_str = axiom_mime_parser_create_part(
+ env, soap_len, buf_num - 1, len_array, part_start, pos, buf_array, mime_parser);
+ if(!soap_str)
+ {
+ return NULL;
+ }
- if (pos)
- {
- pos -= 2;
- soap_body_len = pos - root_mime;
- soap_body_str = AXIS2_MALLOC(env->allocator,
- sizeof(char) * (soap_body_len + 1));
- if (!soap_body_str)
+ malloc_len = len_array[buf_num] - search_info->match_len2;
+ if(malloc_len < 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+ size + 1));
+
+ if(malloc_len > 0)
+ {
+ memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
+ }
+
+ if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+ {
+ len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+ }
+ axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+ if(len >= 0)
+ {
+ buf_array[buf_num] = buffer;
+ len_array[buf_num] = malloc_len + len;
+ }
+ }
+ }
+ else
{
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in SOAP body string");
return NULL;
}
- memcpy(soap_body_str, root_mime, soap_body_len);
- soap_body_str[soap_body_len] = '\0';
- body_mime = pos;
- mime_parser->soap_body_len = soap_body_len;
- mime_parser->soap_body_str = soap_body_str;
}
+
+ mime_parser->soap_body_str = soap_str;
+ mime_parser->soap_body_len = soap_len;
+
+ /*<SOAP></SOAP>--MIMEBOUNDARY
+ mime_headr1:.......
+ mime_headr2:....
+
+ Binarstart.................
+ ...............--MIMEBOUNDARY
+ */
+ /* This loop will extract all the attachments in the message. The condition
+ * with the count is needed because if the sender not marked the end of the
+ * attachment wiht -- then this loop may run infinitely. To prevent that
+ * this additional condition has been put */
+
+
while (!end_of_mime && count < AXIOM_MIME_PARSER_END_OF_MIME_MAX_COUNT)
{
- axis2_char_t *temp_body_mime = NULL;
- axis2_char_t *temp_mime_binary = NULL;
- axis2_char_t *temp_pos = NULL;
-
+ /*First we will search for \r\n\r\n*/
+ axis2_char_t *mime_id = NULL;
+ axis2_char_t *mime_type = NULL;
+ search_info->match_len1 = 0;
+ search_info->match_len2 = 0;
pos = NULL;
+ part_start = buf_num;
+
+ malloc_len = 0;
- /* Keep track of the count to ensure that we do not go in an infinite
- * loop. It is possible that we could fall into an infinite loop if
- * there are problems in sender's message format
- */
- count++;
+ count++;
+
+ pos = axiom_mime_parser_search_for_crlf(env, callback, callback_ctx, &buf_num,
+ len_array, buf_array, search_info, size, mime_parser);
- if (body_mime)
+ if(!pos)
{
- pos = axutil_strstr(body_mime, AXIS2_CRLF AXIS2_CRLF);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in parsing for mime.");
+ return NULL;
}
-
- if (pos)
+
+ /*The pattern contains in one buffer*/
+ if(search_info->match_len2 == 0)
{
- axis2_char_t *old_pos = NULL;
+ /*We found it . so lets seperates the details of this binary into
+ mime headers.*/
- temp_mime_binary = pos + 4;
- old_pos = temp_mime_binary;
- do
+ mime_headers_len = axiom_mime_parser_calculate_part_len (
+ env, buf_num, len_array, part_start, pos, buf_array[buf_num]);
+ if(mime_headers_len > 0)
{
- pos = NULL;
-
- if (old_pos)
+ mime_headers = axiom_mime_parser_create_part(
+ env, mime_headers_len, buf_num, len_array, part_start, pos, buf_array, mime_parser);
+ if(!mime_headers)
{
- pos = memchr(old_pos, AXIOM_MIME_BOUNDARY_BYTE,
- buffer + buf_len - old_pos);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in parsing for mime headers.");
+ return NULL;
}
+ malloc_len = buf_array[buf_num] + len_array[buf_num] - pos - 4;
- if (pos)
+ /*This should be > 0 , > 0 means there is some part to copy = 0 means
+ there is nothing to copy*/
+ if(malloc_len < 0)
{
- old_pos = pos + 1;
- temp_pos = axutil_strstr(pos + 1, mime_boundary);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in parsing for mime headers");
+ return NULL;
}
- }
- while (pos && (*(pos + 1) != AXIOM_MIME_BOUNDARY_BYTE ||
- temp_pos != pos + 2));
- }
-
- if (pos && (*(pos + 1) == AXIOM_MIME_BOUNDARY_BYTE) &&
- (temp_pos == pos + 2))
- {
- mime_binary_len = (int)(pos - temp_mime_binary);
- temp_pos = pos + 2 + axutil_strlen(mime_boundary);
- end_of_mime = (AXIOM_MIME_BOUNDARY_BYTE == *(temp_pos)) &&
- (AXIOM_MIME_BOUNDARY_BYTE == *(temp_pos + 1));
+ else
+ {
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+ size + 1));
+
+ if(malloc_len > 0)
+ {
+ memcpy(buffer, pos + 4, malloc_len);
+ }
+
+ if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+ {
+ len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+ }
- temp_body_mime = pos;
- mime_binary = AXIS2_MALLOC(env->allocator,
- sizeof(char) * (mime_binary_len + 1));
- if (!mime_binary)
+ axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+ if(len >= 0)
+ {
+ buf_array[buf_num] = buffer;
+ len_array[buf_num] = malloc_len + len;
+ }
+ }
+ }
+ else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in creating binary stream");
+ "Error in parsing for mime headers.");
return NULL;
}
- memcpy(mime_binary, temp_mime_binary, mime_binary_len);
- mime_binary[mime_binary_len] = '\0';
- }
+ }
- if (mime_parser->mime_parts_map)
+ else if(search_info->match_len2 > 0)
{
- axis2_char_t *id = NULL;
- axis2_char_t *type = NULL;
+ /*Now we extract the mime headers */
- /* Get the MIME ID */
- if (body_mime)
+ mime_headers_len = axiom_mime_parser_calculate_part_len (
+ env, buf_num - 1, len_array, part_start, pos, buf_array[buf_num - 1]);
+
+ if(mime_headers_len > 0)
{
- id = axutil_strcasestr(body_mime, AXIOM_MIME_HEADER_CONTENT_ID);
- type = axutil_strcasestr(body_mime,
- AXIOM_MIME_HEADER_CONTENT_TYPE);
- if (type)
+ mime_headers = axiom_mime_parser_create_part(
+ env, soap_len, buf_num - 1, len_array, part_start, pos, buf_array, mime_parser);
+ if(!mime_headers)
{
- axis2_char_t *end = NULL;
- axis2_char_t *temp_type = NULL;
- type += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_TYPE);
- while (type && *type && *type != ':')
- {
- type++;
- }
- type++;
- while (type && *type && *type == ' ')
- {
- type++;
- }
- end = type;
- while (end && *end && !isspace(*end))
- {
- end++;
+ return NULL;
+ }
+
+ malloc_len = len_array[buf_num] - search_info->match_len2;
+ if(malloc_len < 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+ size + 1));
+
+ if(malloc_len > 0)
+ {
+ memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
+ }
+ if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+ {
+ len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+ }
+ axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+ if(len >= 0)
+ {
+ buf_array[buf_num] = buffer;
+ len_array[buf_num] = malloc_len + len;
+ }
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+
+ pos = NULL;
+
+ search_info->match_len1 = 0;
+ search_info->match_len2 = 0;
+
+ part_start = buf_num;
+ malloc_len = 0;
+
+ mime_type = axiom_mime_parser_process_mime_headers(env, mime_parser, &mime_id, mime_headers);
+
+ if(!mime_id )
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Error in parsing for mime headers.Mime id did not find");
+ return NULL;
+ }
+
+ if(!mime_type)
+ {
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+ "Mime type did not find");
+ }
+
+ /*We extract the mime headers. So lets search for the attachment.*/
+
+ pos = axiom_mime_parser_search_for_attachment(mime_parser, env, callback, callback_ctx, &buf_num,
+ len_array, buf_array, search_info, size, temp_mime_boundary, mime_id);
+
+ if(pos)
+ {
+ /*If it is small we are not caching. Hence the attachment
+ is in memory. So store it in a buffer. */
+
+ if(!search_info->cached)
+ {
+ if(search_info->match_len2 == 0)
+ {
+ /* mime_binary contains the attachment when it does not
+ * cached */
+
+ mime_binary_len = axiom_mime_parser_calculate_part_len (
+ env, buf_num, len_array, part_start, pos, buf_array[buf_num]);
+ if(mime_binary_len > 0)
+ {
+ mime_binary = axiom_mime_parser_create_part(
+ env, mime_binary_len, buf_num, len_array, part_start, pos, buf_array, mime_parser);
+ if(!mime_binary)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ return NULL;
}
- if ((end - type) > 0)
+ }
+
+ else if(search_info->match_len2 > 0)
+ {
+ mime_binary_len = axiom_mime_parser_calculate_part_len (
+ env, buf_num - 1, len_array, part_start, pos, buf_array[buf_num - 1]);
+
+ if(mime_binary_len > 0)
{
- temp_type = AXIS2_MALLOC(env->allocator,
- sizeof(axis2_char_t) * ((end - type) + 1));
- if (!temp_type)
+ mime_binary = axiom_mime_parser_create_part(
+ env, soap_len, buf_num - 1, len_array, part_start, pos, buf_array, mime_parser);
+ if(!mime_binary)
{
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in creating Content-Type");
return NULL;
}
- memcpy(temp_type, type, (end - type));
- temp_type[end - type] = '\0';
- type = temp_type;
+ }
+ else
+ {
+ return NULL;
}
}
}
- if (id)
+
+ /* The functionality below is common when it is cached or not. It deals with remaining
+ * after a particualr attachment, Those may be related to a end of mime_boundary or
+ * another attachment */
+
+ if(search_info->match_len2 == 0)
{
- id += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_ID);
- while (id && *id && *id != ':')
+ malloc_len = len_array[buf_num] - search_info->match_len1 - temp_mime_boundary_size;
+ if(malloc_len < 0)
{
- id++;
+ return NULL;
}
- if (id)
+ else
{
- while (id && *id && *id != '<')
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+ size + 1));
+
+ if(malloc_len > 0)
{
- id++;
+ memcpy(buffer, pos + temp_mime_boundary_size, malloc_len);
}
- id++;
- pos = axutil_strstr(id, ">");
- if (pos)
+
+ /*When the last buffer only containing -- we know this is the end
+ of the attachments. Hence we don't need to read again*/
+
+ if(malloc_len != 2)
{
- axis2_char_t *mime_id = NULL;
- int mime_id_len = 0;
- mime_id_len = (int)(pos - id);
- mime_id = AXIS2_MALLOC(env->allocator,
- sizeof(axis2_char_t) * mime_id_len + 1);
- /* The MIME ID will be freed by the SOAP builder */
- if (mime_id)
+ if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
{
- axiom_data_handler_t *data_handler = NULL;
- memcpy(mime_id, id, mime_id_len);
- mime_id[mime_id_len] = '\0';
- data_handler =
- axiom_data_handler_create(env, NULL, type);
-
- AXIS2_FREE(env->allocator, type);
-
- axiom_data_handler_set_binary_data(data_handler,
- env, mime_binary, mime_binary_len - 2);
- axutil_hash_set(mime_parser->mime_parts_map,
- mime_id, AXIS2_HASH_KEY_STRING, data_handler);
+ len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
}
- else
+ if(len >= 0)
{
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "No memory. Failed in creating MIME ID");
- return NULL;
+ len_array[buf_num] = malloc_len + len;
}
}
+
+ /* This means there is another attachment */
+ else
+ {
+ len_array[buf_num] = malloc_len;
+ }
+ axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+ buf_array[buf_num] = buffer;
}
- }
- else
+ }
+ else if(search_info->match_len2 > 0)
{
- axis2_char_t temp_boundry[1024];
- sprintf(temp_boundry, "--%s--", mime_boundary);
- if (body_mime && axutil_strstr(body_mime, temp_boundry))
+ malloc_len = len_array[buf_num] - search_info->match_len2;
+
+ if(malloc_len < 0)
{
- break;
+ return NULL;
+ }
+ else
+ {
+ buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+ size + 1));
+
+ if(malloc_len > 0)
+ {
+ memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
+ }
+ if(malloc_len != 2)
+ {
+ if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+ {
+ len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+ }
+ if(len >= 0)
+ {
+ len_array[buf_num] = malloc_len + len;
+ }
+ }
+ else
+ {
+ len_array[buf_num] = malloc_len;
+ }
+ axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+ buf_array[buf_num] = buffer;
}
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+
+ /*We have the attachment now either cached or not. So lets put it in the mime_parts
+ * hash map with the mime_id. Remember at this moment we have already processed the
+ * mime_headers and mime_id is already there */
+
+ /* In this case user has not specified the attachment dir . So we cached it to a memory
+ * buffer. Hence the data_handler type we need to create is different */
+
+ if((search_info->cached) && (!mime_parser->attachment_dir))
+ {
+ mime_binary = (axis2_char_t *)search_info->handler;
+ mime_binary_len = search_info->binary_size;
+ }
+
+ /* Storing the attachment in the hash map with the id*/
+
+ status = axiom_mime_parser_store_attachment(env, mime_parser, mime_id,
+ mime_type, mime_binary, mime_binary_len, search_info->cached);
+
+ /*Check wether we encounter --MIMEBOUNDARY-- to find the end of mime*/
+
+ if(buf_array[buf_num])
+ {
+ /* Here we check for the end of mime */
+
+ end_of_mime = (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num])) &&
+ (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num] + 1));
+ if(end_of_mime)
+ {
+ AXIS2_FREE(env->allocator, buf_array[buf_num]);
+ buf_array[buf_num] = NULL;
}
- body_mime = temp_body_mime;
}
- } /* end while (!end_of_mime) */
+
+ if(mime_headers)
+ {
+ AXIS2_FREE(env->allocator, mime_headers);
+ mime_headers = NULL;
+ }
+
+ if(status != AXIS2_SUCCESS)
+ {
+ return NULL;
+ }
+ }
+
+ /*Do the necessary cleaning */
if (buf_array)
{
@@ -462,49 +957,1016 @@
len_array = NULL;
}
- AXIS2_FREE(env->allocator, buffer);
+ if(temp_mime_boundary)
+ {
+ AXIS2_FREE(env->allocator, temp_mime_boundary);
+ temp_mime_boundary = NULL;
+ }
+
+ if(search_info)
+ {
+ AXIS2_FREE(env->allocator, search_info);
+ search_info = NULL;
+ }
return mime_parser->mime_parts_map;
-}
-AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
-axiom_mime_parser_get_mime_parts_map(
- axiom_mime_parser_t *mime_parser,
- const axutil_env_t *env)
-{
- return mime_parser->mime_parts_map;
}
-AXIS2_EXTERN int AXIS2_CALL
-axiom_mime_parser_get_soap_body_len(
- axiom_mime_parser_t *mime_parser,
- const axutil_env_t *env)
-{
- return mime_parser->soap_body_len;
-}
+/*This method will search for \r\n\r\n */
-AXIS2_EXTERN axis2_char_t *AXIS2_CALL
-axiom_mime_parser_get_soap_body_str(
- axiom_mime_parser_t *mime_parser,
- const axutil_env_t *env)
+static axis2_char_t *axiom_mime_parser_search_for_crlf(
+ const axutil_env_t * env,
+ AXIS2_READ_INPUT_CALLBACK callback,
+ void *callback_ctx,
+ int *buf_num,
+ int *len_array,
+ axis2_char_t **buf_array,
+ axiom_search_info_t *search_info,
+ int size,
+ axiom_mime_parser_t *mime_parser)
{
- return mime_parser->soap_body_str;
+ axis2_char_t *found = NULL;
+ int len = 0;
+
+ search_info->search_str = "\r\n\r\n";
+ search_info->buffer1 = NULL;
+ search_info->buffer2 = NULL;
+ search_info->len1 = 0;
+ search_info->len2 = 0;
+ search_info->match_len1 = 0;
+ search_info->match_len2 = 0;
+ search_info->primary_search = AXIS2_FALSE;
+ search_info->cached = AXIS2_FALSE;
+ search_info->handler = NULL;
+ search_info->binary_size = 0;
+
+ /*First do a search in the first buffer*/
+
+ if(buf_array[*buf_num])
+ {
+ search_info->buffer1 = buf_array[*buf_num];
+ search_info->len1 = len_array[*buf_num];
+ found = axiom_mime_parser_search_string(search_info, env);
+ }
+
+ while(!found)
+ {
+ /*Let's read another buffer and do a boundary search in both*/
+
+ *buf_num = *buf_num + 1;
+ buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));
+
+ if(buf_array[*buf_num])
+ {
+ len = callback(buf_array[*buf_num], size, (void *) callback_ctx);
+ }
+ if(len > 0)
+ {
+ len_array[*buf_num] = len;
+ search_info->buffer2 = buf_array[*buf_num];
+ search_info->len2 = len;
+ found = axiom_mime_parser_search_string(search_info, env);
+ }
+ else
+ {
+ break;
+ }
+ if(!found)
+ {
+ /*Let's do a full search in the second buffer*/
+
+ search_info->buffer1 = buf_array[*buf_num];
+ search_info->len1 = len_array[*buf_num];
+ search_info->primary_search = AXIS2_FALSE;
+ search_info->buffer2 = NULL;
+ search_info->len2 = 0;
+ found = axiom_mime_parser_search_string(search_info, env);
+ }
+ }
+
+ return found;
}
-AXIS2_EXTERN void AXIS2_CALL
-axiom_mime_parser_set_chunk_buffer_size(
- axiom_mime_parser_t *mime_parser,
- const axutil_env_t *env,
- int size)
+/* This method will search for the mime_boundary after the SOAP part
+ * of the message */
+
+static axis2_char_t *axiom_mime_parser_search_for_soap(
+ const axutil_env_t * env,
+ AXIS2_READ_INPUT_CALLBACK callback,
+ void *callback_ctx,
+ int *buf_num,
+ int *len_array,
+ axis2_char_t **buf_array,
+ axiom_search_info_t *search_info,
+ int size,
+ axis2_char_t *mime_boundary,
+ axiom_mime_parser_t *mime_parser)
{
- mime_parser->chunk_buffer_size = size;
+ axis2_char_t *found = NULL;
+ int len = 0;
+
+ /* What we need to search is the mime_boundary */
+
+ search_info->search_str = mime_boundary;
+ search_info->buffer1 = NULL;
+ search_info->buffer2 = NULL;
+ search_info->len1 = 0;
+ search_info->len2 = 0;
+ search_info->match_len1 = 0;
+ search_info->match_len2 = 0;
+ search_info->primary_search = AXIS2_FALSE;
+
+ if(buf_array[*buf_num])
+ {
+ search_info->buffer1 = buf_array[*buf_num];
+ search_info->len1 = len_array[*buf_num];
+ found = axiom_mime_parser_search_string(search_info, env);
+
+ /* Inside this search primary_search flag will be set to TRUE */
+ }
+
+ while(!found)
+ {
+ /* We need to create the second buffer and do the search for the
+ * mime_boundary in the both the buffers */
+
+ *buf_num = *buf_num + 1;
+ buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));
+
+ if(buf_array[*buf_num])
+ {
+ len = callback(buf_array[*buf_num], size, (void *) callback_ctx);
+ }
+ if(len > 0)
+ {
+ /* In this search we are matching end part of the first
+ * buffer and starting part of the previous buffer */
+ len_array[*buf_num] = len;
+ search_info->buffer2 = buf_array[*buf_num];
+ search_info->len2 = len;
+ found = axiom_mime_parser_search_string(search_info, env);
+ }
+ else
+ {
+ break;
+ }
+ if(!found)
+ {
+ search_info->buffer1 = buf_array[*buf_num];
+ search_info->len1 = len_array[*buf_num];
+ search_info->primary_search = AXIS2_FALSE;
+ search_info->buffer2 = NULL;
+ search_info->len2 = 0;
+ found = axiom_mime_parser_search_string(search_info, env);
+ }
+ }
+
+ return found;
}
-AXIS2_EXTERN void AXIS2_CALL
-axiom_mime_parser_set_max_chunk_buffers(
+/*The caching is done in this function. Caching happens when we did not
+ find the mime_boundary in initial two buffers. So the maximum size
+ that we are keeping in memory is 2 * size. This size can be configurable from
+ the aixs.xml. The caching may starts when the search failed with the
+ second buffer. */
+
+static axis2_char_t *axiom_mime_parser_search_for_attachment(
axiom_mime_parser_t *mime_parser,
- const axutil_env_t *env,
- int num)
+ const axutil_env_t * env,
+ AXIS2_READ_INPUT_CALLBACK callback,
+ void *callback_ctx,
+ int *buf_num,
+ int *len_array,
+ axis2_char_t **buf_array,
+ axiom_search_info_t *search_info,
+ int size,
+ axis2_char_t *mime_boundary,
+ axis2_char_t *mime_id)
{
- mime_parser->max_chunk_buffers = num;
-}
+ axis2_char_t *found = NULL;
+ int len = 0;
+ axis2_status_t status = AXIS2_FAILURE;
+ axis2_char_t *temp = NULL;
+ int temp_length = 0;
+ axis2_char_t *file_name = NULL;
+
+ search_info->search_str = mime_boundary;
+ search_info->buffer1 = NULL;
+ search_info->buffer2 = NULL;
+ search_info->len1 = 0;
+ search_info->len2 = 0;
+ search_info->match_len1 = 0;
+ search_info->match_len2 = 0;
+ search_info->primary_search = AXIS2_FALSE;
+ search_info->cached = AXIS2_FALSE;
+ search_info->handler = NULL;
+
+ /*First search in the incoming buffer*/
+
+ if(buf_array[*buf_num])
+ {
+ search_info->buffer1 = buf_array[*buf_num];
+ search_info->len1 = len_array[*buf_num];
+ found = axiom_mime_parser_search_string(search_info, env);
+ }
+
+ while(!found)
+ {
+ if(search_info->cached)
+ {
+ if(mime_parser->attachment_dir)
+ {
+ if(!(search_info->handler))
+ {
+ /* If the File is not opened yet we will open it*/
+ file_name = axutil_stracat(env, mime_parser->attachment_dir,
+ mime_id);
+ if(!file_name)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Caching file name creation error");
+ return NULL;
+ }
+ search_info->handler = (void *)fopen(file_name, "ab+");
+ if(!(search_info->handler))
+ {
+ return NULL;
+ }
+ }
+
+ /*So lets cache the previous buffer which has undergone the
+ full search and the partial search. */
+
+ status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1],
+ len_array[*buf_num - 1], search_info->handler);
+ }
+
+ else
+ {
+ /* Here the user has not specified the caching File location. So we are
+ * not going to cache. Instead we store the attachment in the buffer */
+ status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1],
+ len_array[*buf_num - 1], search_info, mime_parser);
+ }
+
+ if(status == AXIS2_FAILURE)
+ {
+ return NULL;
+ }
+ /*Here we interchange the buffers.*/
+
+ temp = buf_array[*buf_num - 1];
+ buf_array[*buf_num - 1] = buf_array[*buf_num];
+ buf_array[*buf_num] = temp;
+ temp_length = len_array[*buf_num - 1];
+ len_array[*buf_num - 1] = len_array[*buf_num];
+ len_array[*buf_num] = temp_length;
+ if(buf_array[*buf_num])
+ {
+ /*The cached buffer is the one which get filled.*/
+ len = callback(buf_array[*buf_num], size, (void *) callback_ctx);
+ }
+ }
+
+ /*Size of the data in memory not yet risen to the caching threasold
+ *So we can create the second buffer */
+ else
+ {
+ *buf_num = *buf_num + 1;
+ buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));
+
+ if(buf_array[*buf_num])
+ {
+ len = callback(buf_array[*buf_num], size, (void *) callback_ctx);
+ }
+ }
+
+ /*Doing a complete search in newly cretaed buffer*/
+
+ if(len > 0)
+ {
+ len_array[*buf_num] = len;
+ search_info->buffer2 = buf_array[*buf_num];
+ search_info->len2 = len;
+ found = axiom_mime_parser_search_string(search_info, env);
+ }
+ else
+ {
+ break;
+ }
+
+ /* Now there are two buffers. If the searching string is not
+ * here then we must cache the first buffer */
+
+ if(!found)
+ {
+ /*So now we must start caching*/
+ search_info->buffer1 = buf_array[*buf_num];
+ search_info->len1 = len_array[*buf_num];
+ search_info->primary_search = AXIS2_FALSE;
+ search_info->buffer2 = NULL;
+ search_info->len2 = 0;
+ found = axiom_mime_parser_search_string(search_info, env);
+ if(!found)
+ {
+ /* So at the begining of the next search we start
+ * that only after caching this data */
+ search_info->cached = AXIS2_TRUE;
+ }
+ }
+ }
+
+ /* Here we are out of the loop. If there is no error then this means
+ * the searching string is found */
+
+ if(search_info->cached)
+ {
+ /* If the attachment is cached then we need to cache the
+ * final buffer */
+
+ if(search_info->match_len2 == 0)
+ {
+ /* This is the case where we found the whole string in one buffer
+ * So we need to cache previous buffer and the data up to the starting
+ * point of the search string in the current buffer */
+
+ if(mime_parser->attachment_dir)
+ {
+ status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1],
+ len_array[*buf_num - 1], search_info->handler);
+ if(status == AXIS2_SUCCESS)
+ {
+ status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num],
+ found - buf_array[*buf_num], search_info->handler);
+ }
+ }
+
+ /* If the callback is not there then the data is appended to the buffer */
+
+ else
+ {
+ status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1],
+ len_array[*buf_num - 1], search_info, mime_parser);
+ if(status == AXIS2_SUCCESS)
+ {
+ status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num],
+ found - buf_array[*buf_num], search_info, mime_parser);
+ }
+ }
+ }
+ else if(search_info->match_len2 > 0)
+ {
+ /*Here the curent buffer has partial mime boundary. So we need
+ to cache only the previous buffer. */
+ if(mime_parser->attachment_dir)
+ {
+ status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1],
+ search_info->match_len1, search_info->handler);
+ }
+ else
+ {
+ status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1],
+ search_info->match_len1, search_info, mime_parser);
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+
+ if(status == AXIS2_FAILURE)
+ {
+ return NULL;
+ }
+ }
+
+ /* Parsing is done so lets close the relative handlers */
+
+ if(search_info->handler && mime_parser->attachment_dir)
+ {
+ if(fclose((FILE *)(search_info->handler)) == 0)
+ {
+ status = AXIS2_SUCCESS;
+ }
+ else
+ {
+ status = AXIS2_FAILURE;
+ }
+
+ AXIS2_FREE(env->allocator, file_name);
+ file_name = NULL;
+
+ if(status == AXIS2_FAILURE)
+ {
+ return NULL;
+ }
+ }
+ return found;
+}
+
+
+/*following two functions are used to extract important information
+ from the buffer list. eg: SOAP, MIME_HEADERS*/
+
+/*marker is the starting buffer of the required
+ part and pos is the end point of that part */
+
+static int axiom_mime_parser_calculate_part_len (
+ const axutil_env_t *env,
+ int buf_num,
+ int *len_list,
+ int marker,
+ axis2_char_t *pos,
+ axis2_char_t *buf)
+{
+ int part_len = 0;
+ int i = 0;
+
+ for(i = marker; i < buf_num; i++)
+ {
+ part_len += len_list[i];
+ }
+
+ part_len = part_len + (pos - buf);
+
+ return part_len;
+}
+
+static axis2_char_t * axiom_mime_parser_create_part(
+ const axutil_env_t *env,
+ int part_len,
+ int buf_num,
+ int *len_list,
+ int marker,
+ axis2_char_t *pos,
+ axis2_char_t **buf_list,
+ axiom_mime_parser_t *mime_parser)
+{
+ /*We will copy the set of buffers which contains the required part.
+ This part can be the SOAP message , mime headers or the mime
+ binary in the case of none cahced.*/
+
+ axis2_char_t *part_str = NULL;
+ int i = 0;
+ int temp = 0;
+
+ part_str = AXIS2_MALLOC(env->allocator, sizeof(char) * (part_len + 1));
+
+
+ if (!part_str)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Failed in creating buffer");
+ return NULL;
+ }
+
+ /* Copy from the part starting buffer to the
+ * curent buffer */
+
+ for (i = marker; i < buf_num; i++)
+ {
+ if (buf_list[i])
+ {
+ memcpy(part_str + temp, buf_list[i], len_list[i]);
+ temp += len_list[i];
+ }
+ }
+ /* Finally we are copying from the final portion */
+
+ memcpy(part_str + temp, buf_list[i], pos - buf_list[i]);
+
+ part_str[part_len] = '\0';
+
+ return part_str;
+}
+
+AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
+axiom_mime_parser_get_mime_parts_map(
+ axiom_mime_parser_t * mime_parser,
+ const axutil_env_t * env)
+{
+ return mime_parser->mime_parts_map;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axiom_mime_parser_get_soap_body_len(
+ axiom_mime_parser_t * mime_parser,
+ const axutil_env_t * env)
+{
+ return mime_parser->soap_body_len;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axiom_mime_parser_get_soap_body_str(
+ axiom_mime_parser_t * mime_parser,
+ const axutil_env_t * env)
+{
+ return mime_parser->soap_body_str;
+}
+
+/*This is the new search function. This will first do a
+search for the entire search string.Then will do a search
+for the partial string which can be divided among two buffers.*/
+
+
+static axis2_char_t *axiom_mime_parser_search_string(
+ axiom_search_info_t *search_info,
+ const axutil_env_t *env)
+{
+ axis2_char_t *pos = NULL;
+ axis2_char_t *old_pos = NULL;
+ axis2_char_t *found = NULL;
+ int str_length = 0;
+ int search_length = 0;
+
+ str_length = strlen(search_info->search_str);
+
+ /*First lets search the entire buffer*/
+ if(!search_info->primary_search)
+ {
+ old_pos = search_info->buffer1;
+
+ do
+ {
+ /*find the first byte. We need to adhere to this
+ approach rather than straightaway using strstr
+ because the buffer1 can be containg binary data*/
+
+ pos = NULL;
+
+ search_length = search_info->buffer1 + search_info->len1
+ - old_pos - str_length + 1;
+
+ if(search_length < 0)
+ {
+ break;
+ }
+
+ if (old_pos)
+ {
+ pos = memchr(old_pos, *(search_info->search_str),
+ search_length);
+ }
+
+ /* found it so lets check the remaining */
+
+ if (pos)
+ {
+ found = axutil_strstr(pos, search_info->search_str);
+ if(found)
+ {
+ search_info->match_len1 = found - search_info->buffer1;
+ break;
+ }
+ else
+ {
+ old_pos = pos + 1;
+ }
+ }
+ }
+ while (pos);
+ }
+
+ search_info->primary_search = AXIS2_TRUE;
+
+ if(found)
+ {
+ return found;
+ }
+
+ /*So we didn't find the string in the buffer
+ lets check whether it is divided in two buffers*/
+
+ else
+ {
+ int offset = 0;
+ pos = NULL;
+ old_pos = NULL;
+ found = NULL;
+ search_length = 0;
+
+ if(search_info->buffer2)
+ {
+ old_pos = search_info->buffer1 + search_info->len1 - str_length + 1;
+ do
+ {
+ /*First check the starting byte*/
+ pos = NULL;
+ found = NULL;
+
+ search_length = search_info->buffer1 + search_info->len1 - old_pos;
+
+ if(search_length < 0)
+ {
+ break;
+ }
+
+ pos = memchr(old_pos, *(search_info->search_str), search_length);
+
+ if(pos)
+ {
+ offset = search_info->buffer1 + search_info->len1 - pos;
+
+ /*First match the beginng to offset in buffer1*/
+
+ if(offset > 0)
+ {
+ if(memcmp(pos, search_info->search_str, offset)
+ == 0)
+ {
+ found = pos;
+ }
+
+ /*We found something in buffer1 so lets match the
+ remaining in buffer2*/
+
+ if(found)
+ {
+ if(memcmp(search_info->buffer2, search_info->search_str + offset,
+ str_length - offset ) == 0)
+ {
+ search_info->match_len2 = str_length - offset;
+ search_info->match_len1 = found - search_info->buffer1;
+ break;
+ }
+ else
+ {
+ old_pos = pos + 1;
+ }
+ }
+ else
+ {
+ old_pos = pos + 1;
+ }
+ }
+ }
+ }
+ while(pos);
+
+ /* We will set this to AXIS2_FALSE so when the next time this
+ * search method is called it will do a full search first for buffer1 */
+ search_info->primary_search = AXIS2_FALSE;
+
+ return found;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+}
+
+
+/* This method creates a data_handler out of the attachment
+ * and store the data_handler in the mime_parts map */
+
+static axis2_status_t
+axiom_mime_parser_store_attachment(
+ const axutil_env_t *env,
+ axiom_mime_parser_t *mime_parser,
+ axis2_char_t *mime_id,
+ axis2_char_t *mime_type,
+ axis2_char_t *mime_binary,
+ int mime_binary_len,
+ axis2_bool_t cached)
+{
+ if (mime_parser->mime_parts_map)
+ {
+ if (mime_id)
+ {
+ axiom_data_handler_t *data_handler = NULL;
+
+ /* Handling the case where attachment is cached to a file*/
+
+ if(!mime_binary && cached)
+ {
+ axis2_char_t *attachment_location = NULL;
+
+ attachment_location = axutil_stracat(env,
+ mime_parser->attachment_dir, mime_id);
+ if(attachment_location)
+ {
+ data_handler = axiom_data_handler_create(env,
+ attachment_location, mime_type);
+ if(data_handler)
+ {
+ axiom_data_handler_set_cached(data_handler, env, AXIS2_TRUE);
+ }
+ AXIS2_FREE(env->allocator, attachment_location);
+ attachment_location = NULL;
+ }
+ }
+
+ /* Attachment is in memory, either it is small to be cached or
+ * user does not provided the attachment cached directory */
+
+ else if(mime_binary)
+ {
+ data_handler = axiom_data_handler_create(env,
+ NULL, mime_type);
+ if(data_handler)
+ {
+ axiom_data_handler_set_binary_data(data_handler,
+ env, mime_binary, mime_binary_len - 2);
+ }
+ }
+ axutil_hash_set(mime_parser->mime_parts_map,
+ mime_id, AXIS2_HASH_KEY_STRING, data_handler);
+ if(mime_type)
+ {
+ AXIS2_FREE(env->allocator, mime_type);
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Mime Id or Mime rype not found");
+ return AXIS2_FAILURE;
+ /*axis2_char_t temp_boundry[1024];
+ sprintf(temp_boundry, "--%s--", mime_boundary);
+ if (body_mime && axutil_strstr(body_mime, temp_boundry))
+ {
+ break;
+ }*/
+ }
+ return AXIS2_SUCCESS;
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+}
+
+/* This method will process the mime_headers for a particualr
+ attacment and return the mime_id */
+
+
+static axis2_char_t *
+ axiom_mime_parser_process_mime_headers(
+ const axutil_env_t *env,
+ axiom_mime_parser_t *mime_parser,
+ axis2_char_t **mime_id,
+ axis2_char_t *mime_headers)
+{
+ axis2_char_t *id = NULL;
+ axis2_char_t *type = NULL;
+ axis2_char_t *pos = NULL;
+
+ /* Get the MIME ID */
+ if (mime_headers)
+ {
+ id = axutil_strcasestr(mime_headers, AXIOM_MIME_HEADER_CONTENT_ID);
+ type = axutil_strcasestr(mime_headers,
+ AXIOM_MIME_HEADER_CONTENT_TYPE);
+ if (type)
+ {
+ axis2_char_t *end = NULL;
+ axis2_char_t *temp_type = NULL;
+ type += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_TYPE);
+ while (type && *type && *type != ':')
+ {
+ type++;
+ }
+ type++;
+ while (type && *type && *type == ' ')
+ {
+ type++;
+ }
+ end = type;
+ while (end && *end && !isspace(*end))
+ {
+ end++;
+ }
+ if ((end - type) > 0)
+ {
+ temp_type = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * ((end - type) + 1));
+ if (!temp_type)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Failed in creating Content-Type");
+ return NULL;
+ }
+ memcpy(temp_type, type, (end - type));
+ temp_type[end - type] = '\0';
+ type = temp_type;
+ }
+ }
+ if (id)
+ {
+ id += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_ID);
+ while (id && *id && *id != ':')
+ {
+ id++;
+ }
+ if (id)
+ {
+ while (id && *id && *id != '<')
+ {
+ id++;
+ }
+ id++;
+ pos = axutil_strstr(id, ">");
+ if (pos)
+ {
+ int mime_id_len = 0;
+ mime_id_len = (int)(pos - id);
+ *mime_id = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * mime_id_len + 1);
+ /* The MIME ID will be freed by the SOAP builder */
+ if (*mime_id)
+ {
+ memcpy(*mime_id, id, mime_id_len);
+ (*mime_id)[mime_id_len] = '\0';
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Failed in creating MIME ID");
+ return NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*axis2_char_t temp_boundry[1024];
+ sprintf(temp_boundry, "--%s--", mime_boundary);
+ if (body_mime && axutil_strstr(body_mime, temp_boundry))
+ {
+ break;
+ }*/
+ return NULL;
+ }
+ return type;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+
+/*This is used to free some unwanted buffers. For example we did
+not want the buffers which contains the data before the soap
+envelope starts. */
+
+static void axiom_mime_parser_clear_buffers(
+ const axutil_env_t *env,
+ axis2_char_t **buf_list,
+ int free_from,
+ int free_to)
+{
+ int i = 0;
+
+ for(i = free_from; i <= free_to; i++)
+ {
+ if(buf_list[i])
+ {
+ AXIS2_FREE(env->allocator, buf_list[i]);
+ buf_list[i] = NULL;
+ }
+ }
+ return;
+}
+
+
+/* Instead of caching to a file this method will cache it
+ * to a buffer */
+
+static axis2_status_t axiom_mime_parser_cache_to_buffer(
+ const axutil_env_t *env,
+ axis2_char_t *buf,
+ int buf_len,
+ axiom_search_info_t *search_info,
+ axiom_mime_parser_t *mime_parser)
+{
+ axis2_char_t *data_buffer = NULL;
+ axis2_char_t *temp_buf = NULL;
+ int mime_binary_len = 0;
+
+ temp_buf = (axis2_char_t *)search_info->handler;
+ mime_binary_len = search_info->binary_size + buf_len;
+
+ if(mime_binary_len > 0)
+ {
+ data_buffer = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_char_t) * (mime_binary_len));
+
+
+ if(data_buffer)
+ {
+ if(temp_buf && search_info->binary_size > 0)
+ {
+ memcpy(data_buffer, temp_buf, search_info->binary_size);
+ AXIS2_FREE(env->allocator, temp_buf);
+ temp_buf = NULL;
+ }
+ memcpy(data_buffer + (search_info->binary_size),
+ buf, buf_len);
+ search_info->binary_size = mime_binary_len;
+ search_info->handler = (void *)data_buffer;
+
+ return AXIS2_SUCCESS;
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+}
+
+
+AXIS2_EXTERN void AXIS2_CALL
+axiom_mime_parser_set_buffer_size(
+ axiom_mime_parser_t *mime_parser,
+ const axutil_env_t *env,
+ int size)
+{
+ mime_parser->buffer_size = size;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axiom_mime_parser_set_max_buffers(
+ axiom_mime_parser_t *mime_parser,
+ const axutil_env_t *env,
+ int num)
+{
+ mime_parser->max_buffers = num;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axiom_mime_parser_set_attachment_dir(
+ axiom_mime_parser_t *mime_parser,
+ const axutil_env_t *env,
+ axis2_char_t *attachment_dir)
+{
+ mime_parser->attachment_dir = attachment_dir;
+}
+
+
+/* This method will tell whether there are more data in the
+ * stream */
+
+static axis2_bool_t axiom_mime_parser_is_more_data(
+ axiom_mime_parser_t *mime_parser,
+ const axutil_env_t *env,
+ axis2_callback_info_t *callback_info)
+{
+ /* In the case of axutil_http_chunked stream it is the
+ * end of chunk */
+
+ if(callback_info->chunked_stream)
+ {
+ if(axutil_http_chunked_stream_get_end_of_chunks(
+ callback_info->chunked_stream, env))
+ {
+ return AXIS2_FALSE;
+ }
+ else
+ {
+ return AXIS2_TRUE;
+ }
+ }
+
+ /* When we are using content length or any wrapped
+ * stream it will be the unread_length */
+
+ else if(callback_info->unread_len == 0)
+ {
+ return AXIS2_FALSE;
+ }
+ else
+ {
+ return AXIS2_TRUE;
+ }
+}
+
+static axis2_status_t
+axiom_mime_parser_cache_to_file(
+ const axutil_env_t* env,
+ axis2_char_t *buf,
+ int buf_len,
+ void *handler)
+{
+ int len = 0;
+ FILE *fp = NULL;
+
+ fp = (FILE *)handler;
+
+ len = fwrite(buf, 1, buf_len, fp);
+ if(len < 0)
+ {
+ return AXIS2_FAILURE;
+ }
+ else
+ {
+ return AXIS2_SUCCESS;
+ }
+}
+
Copied: webservices/axis2/trunk/c/axiom/src/attachments/mime_part.c (from r674731, webservices/axis2/branches/c/post_1_4_mtom/c/axiom/src/attachments/mime_part.c)
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/axiom/src/attachments/mime_part.c?p2=webservices/axis2/trunk/c/axiom/src/attachments/mime_part.c&p1=webservices/axis2/branches/c/post_1_4_mtom/c/axiom/src/attachments/mime_part.c&r1=674731&r2=678680&rev=678680&view=diff
==============================================================================
--- webservices/axis2/branches/c/post_1_4_mtom/c/axiom/src/attachments/mime_part.c (original)
+++ webservices/axis2/trunk/c/axiom/src/attachments/mime_part.c Tue Jul 22 01:43:36 2008
@@ -398,7 +398,7 @@
* with small buffers and attachment locations. */
-AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
axiom_mime_part_create_part_list(
const axutil_env_t *env,
axis2_char_t *soap_body,
@@ -500,7 +500,7 @@
if(!soap_part)
{
- return AXIS2_FAILURE;
+ return NULL;
}
/* The atachment's mime_boundary will start after a new line charator */
Propchange: webservices/axis2/trunk/c/axiom/src/om/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Jul 22 01:43:36 2008
@@ -0,0 +1,2 @@
+.deps
+.libs
Modified: webservices/axis2/trunk/c/axiom/src/om/om_output.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/axiom/src/om/om_output.c?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/axiom/src/om/om_output.c (original)
+++ webservices/axis2/trunk/c/axiom/src/om/om_output.c Tue Jul 22 01:43:36 2008
@@ -24,7 +24,7 @@
#include <axiom_soap_const.h>
#include <axutil_array_list.h>
#include <axutil_uuid_gen.h>
-#include <axiom_mime_output.h>
+#include <axiom_mime_part.h>
#define AXIS2_DEFAULT_CHAR_SET_ENCODING "UTF-8"
@@ -60,12 +60,12 @@
axutil_array_list_t *binary_node_list;
- axiom_mime_output_t *mime_output;
-
axis2_char_t *mime_boundry;
axis2_char_t *content_type;
+ axutil_array_list_t *mime_parts;
+
};
AXIS2_EXTERN axiom_output_t *AXIS2_CALL
@@ -96,9 +96,9 @@
om_output->xml_version = NULL;
om_output->ignore_xml_declaration = AXIS2_TRUE;
om_output->binary_node_list = NULL;
- om_output->mime_output = NULL;
om_output->mime_boundry = NULL;
om_output->content_type = NULL;
+ om_output->mime_parts = NULL;
return om_output;
}
@@ -137,10 +137,6 @@
axutil_array_list_free(om_output->binary_node_list, env);
}
- if (om_output->mime_output)
- {
- axiom_mime_output_free(om_output->mime_output, env);
- }
if (om_output->content_type)
{
AXIS2_FREE(env->allocator, om_output->content_type);
@@ -292,13 +288,9 @@
om_output->content_type =
(axis2_char_t *)
- axiom_mime_output_get_content_type_for_mime(om_output->mime_output,
- env,
- om_output->mime_boundry,
- om_output->
- root_content_id,
- om_output->
- char_set_encoding,
+ axiom_mime_part_get_content_type_for_mime(env, om_output->mime_boundry,
+ om_output->root_content_id,
+ om_output->char_set_encoding,
soap_content_type);
return om_output->content_type;
}
@@ -631,12 +623,16 @@
}
-axis2_byte_t *AXIS2_CALL
-axiom_output_flush(
+/* This method will be called from transport. After this method each and every
+ * message part needs to be send are stored in an arraylits. So the transport
+ * sender should correctly figure out how to send from the given information.
+ */
+
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axiom_output_flush(
axiom_output_t * om_output,
- const axutil_env_t * env,
- axis2_byte_t ** output_stream,
- int *output_stream_size)
+ const axutil_env_t * env)
{
const axis2_char_t *soap_content_type = NULL;
@@ -644,12 +640,13 @@
if (om_output->do_optimize)
{
- axis2_byte_t *byte_stream = NULL;
axis2_char_t *root_content_id = NULL;
- axis2_char_t *buffer =
- (axis2_char_t *) axiom_xml_writer_get_xml(om_output->xml_writer,
+ axis2_char_t *buffer = NULL;
+
+ /* Extracting the soap part */
+
+ buffer = axiom_xml_writer_get_xml(om_output->xml_writer,
env);
- int stream_size = 0;
if (om_output->is_soap11)
{
soap_content_type = AXIOM_SOAP11_CONTENT_TYPE;
@@ -658,21 +655,41 @@
{
soap_content_type = AXIOM_SOAP12_CONTENT_TYPE;
}
- om_output->mime_output = axiom_mime_output_create(env);
+
+ /* The created mime_boundary for this soap message */
+
om_output->mime_boundry = axiom_output_get_mime_boundry(om_output, env);
+
+ /* This is also created for attachments*/
root_content_id = axiom_output_get_root_content_id(om_output, env);
- axiom_mime_output_complete(om_output->mime_output,
- env, &byte_stream, &stream_size,
- buffer, om_output->binary_node_list,
- om_output->mime_boundry,
- om_output->root_content_id,
- om_output->char_set_encoding,
- soap_content_type);
-
- *output_stream = byte_stream;
- *output_stream_size = stream_size;
-
- return byte_stream;
+
+ /* different parts of the message is added according to their order
+ * to an arraylist */
+ om_output->mime_parts = axiom_mime_part_create_part_list(
+ env, buffer, om_output->binary_node_list,
+ om_output->mime_boundry,
+ om_output->root_content_id,
+ om_output->char_set_encoding,
+ soap_content_type);
+
+ if(om_output->mime_parts)
+ {
+ return AXIS2_SUCCESS;
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
}
- return NULL;
+ return AXIS2_SUCCESS;
}
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axiom_output_get_mime_parts(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ return om_output->mime_parts;
+}
+
Modified: webservices/axis2/trunk/c/include/axis2_const.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_const.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_const.h (original)
+++ webservices/axis2/trunk/c/include/axis2_const.h Tue Jul 22 01:43:36 2008
@@ -352,11 +352,9 @@
/* globally enable MTOM */
#define AXIS2_ENABLE_MTOM "enableMTOM"
-#define AXIS2_ATTACHMENT_TEMP_DIR "attachmentDIR"
-#define AXIS2_CACHE_ATTACHMENTS "cacheAttachments"
-#define AXIS2_FILE_SIZE_THRESHOLD "sizeThreshold"
-#define AXIS2_MTOM_CHUNK_BUFFER_SIZE "MTOMChunkBufferSize"
-#define AXIS2_MTOM_MAX_CHUNK_BUFFERS "MTOMMaxChunkBuffers"
+#define AXIS2_ATTACHMENT_DIR "attachmentDIR"
+#define AXIS2_MTOM_BUFFER_SIZE "MTOMBufferSize"
+#define AXIS2_MTOM_MAX_BUFFERS "MTOMMaxBuffers"
/* op_ctx persistance */
#define AXIS2_PERSIST_OP_CTX "persistOperationContext"
Modified: webservices/axis2/trunk/c/include/axis2_http_client.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_http_client.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_http_client.h (original)
+++ webservices/axis2/trunk/c/include/axis2_http_client.h Tue Jul 22 01:43:36 2008
@@ -38,6 +38,8 @@
#include <axis2_http_simple_request.h>
#include <axutil_url.h>
+
+
#ifdef __cplusplus
extern "C"
{
@@ -231,6 +233,29 @@
void *client,
const axutil_env_t * env);
+ AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axis2_http_client_set_mime_parts(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axutil_array_list_t *mime_parts);
+
+ AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+ axis2_http_client_get_mime_parts(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env);
+
+ AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axis2_http_client_set_doing_mtom(
+ axis2_http_client_t * client,
+ const axutil_env_t * env,
+ axis2_bool_t doing_mtom);
+
+ AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+ axis2_http_client_get_doing_mtom(
+ const axis2_http_client_t * client,
+ const axutil_env_t * env);
+
+
/** @} */
#ifdef __cplusplus
}
Modified: webservices/axis2/trunk/c/include/axis2_http_sender.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_http_sender.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_http_sender.h (original)
+++ webservices/axis2/trunk/c/include/axis2_http_sender.h Tue Jul 22 01:43:36 2008
@@ -201,7 +201,7 @@
axis2_http_sender_set_om_output (sender, env, om_output)
/** Set http version. */
-#define AXIOM_SENDER_SET_HTTP_VERSION(sender, env, version)\
+#define AXIS2_HTTP_SENDER_SET_HTTP_VERSION(sender, env, version)\
axis2_http_sender_set_http_version (sender, env, version)
/** Frees the soap over http sender. */
Modified: webservices/axis2/trunk/c/include/axis2_http_simple_response.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_http_simple_response.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_http_simple_response.h (original)
+++ webservices/axis2/trunk/c/include/axis2_http_simple_response.h Tue Jul 22 01:43:36 2008
@@ -298,6 +298,26 @@
axis2_http_simple_response_create_default(
const axutil_env_t * env);
+ 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);
+
+ AXIS2_EXTERN void 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);
+
+ 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);
+
+
+
+
/** @} */
#ifdef __cplusplus
}
Modified: webservices/axis2/trunk/c/include/axis2_http_status_line.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_http_status_line.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_http_status_line.h (original)
+++ webservices/axis2/trunk/c/include/axis2_http_status_line.h Tue Jul 22 01:43:36 2008
@@ -110,6 +110,14 @@
const axutil_env_t * env,
const axis2_char_t * str);
+ 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);
+
+
+
/** @} */
#ifdef __cplusplus
}