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 [4/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/src/core/transport/http/util/http_transport_utils.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/src/core/transport/http/util/http_transport_utils.c?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/src/core/transport/http/util/http_transport_utils.c (original)
+++ webservices/axis2/trunk/c/src/core/transport/http/util/http_transport_utils.c Tue Jul 22 01:43:36 2008
@@ -41,6 +41,7 @@
 #include <stdlib.h>
 #include <axutil_uuid_gen.h>
 #include <platforms/axutil_platform_auto_sense.h>
+#include <axiom_mime_part.h>
 
 #define AXIOM_MIME_BOUNDARY_BYTE 45
 
@@ -187,6 +188,15 @@
     axutil_hash_t * param_map,
     axis2_char_t * method);
 
+static axis2_status_t
+axis2_http_transport_utils_send_attachment(
+    const axutil_env_t * env,
+    axutil_http_chunked_stream_t *chunked_stream,
+    FILE *fp,
+    axis2_byte_t *buffer,
+    int buffer_size);
+
+/***************************** End of function headers ************************/
 
 AXIS2_EXTERN axis2_status_t AXIS2_CALL
 axis2_http_transport_utils_transport_out_init(axis2_http_transport_out_t *response, 
@@ -367,11 +377,27 @@
                and also gives out a content lenght of 0.
                We need to fix the transport design to fix sutuations like this.
              */
-            callback_ctx->content_length = AXIS2_CHUNKED_CONTENT_LENGTH;
-            callback_ctx->unread_len = callback_ctx->content_length;
+            /*callback_ctx->content_length = AXIS2_CHUNKED_CONTENT_LENGTH;
+            callback_ctx->unread_len = callback_ctx->content_length;*/
+            callback_ctx->chunked_stream =
+                    axutil_http_chunked_stream_create(env, in_stream);
+
+                if (!callback_ctx->chunked_stream)
+                {
+                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occured in"
+                                    " creating in chunked stream.");
+                    return AXIS2_FAILURE;
+                }
+
+                AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "HTTP"
+                                " stream chunked");
         }
     }
 
+    /* when the message contains does not contain pure XML we can't send it 
+     * directly to the parser, First we need to seperate the SOAP part from
+     * the attachment */
+    
     if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED))
     {
         /* get mime boundary */
@@ -385,40 +411,60 @@
         {
             axiom_mime_parser_t *mime_parser = NULL;
             int soap_body_len = 0;
-            axutil_param_t *chunk_buffer_size_param = NULL;
-            axutil_param_t *max_chunk_buffers_param = 0;
+            axutil_param_t *buffer_size_param = NULL;
+            axutil_param_t *max_buffers_param = NULL;
+            axutil_param_t *attachment_dir_param = NULL;
             axis2_char_t *value_size = NULL;
             axis2_char_t *value_num = NULL;
+            axis2_char_t *value_dir = NULL;
             int size = 0;
             int num = 0;
 
             mime_parser = axiom_mime_parser_create(env);
-
-            chunk_buffer_size_param = axis2_msg_ctx_get_parameter (msg_ctx,
+            /* This is the size of the buffer we keep inside mime_parser
+             * when parsing. */
+            buffer_size_param = axis2_msg_ctx_get_parameter (msg_ctx,
                                                                env,
-                                                               AXIS2_MTOM_CHUNK_BUFFER_SIZE);
-            if (chunk_buffer_size_param)
+                                                               AXIS2_MTOM_BUFFER_SIZE);
+            if (buffer_size_param)
             {
                 value_size =
-                    (axis2_char_t *) axutil_param_get_value (chunk_buffer_size_param, env);
+                    (axis2_char_t *) axutil_param_get_value (buffer_size_param, env);
                 if(value_size)
                 {
                     size = atoi(value_size);
-                    axiom_mime_parser_set_chunk_buffer_size(mime_parser, env, size);
+                    axiom_mime_parser_set_buffer_size(mime_parser, env, size);
                 }
             }
-
-            max_chunk_buffers_param = axis2_msg_ctx_get_parameter (msg_ctx,
+            
+            /* We create an array of buffers in order to conatin SOAP data inside
+             * mime_parser. This is the number of sucj buffers */
+            max_buffers_param = axis2_msg_ctx_get_parameter (msg_ctx,
                                                                env,
-                                                               AXIS2_MTOM_MAX_CHUNK_BUFFERS);
-            if (max_chunk_buffers_param)
+                                                               AXIS2_MTOM_MAX_BUFFERS);
+            if (max_buffers_param)
             {
                 value_num =
-                    (axis2_char_t *) axutil_param_get_value (max_chunk_buffers_param, env);
+                    (axis2_char_t *) axutil_param_get_value (max_buffers_param, env);
                 if(value_num)
                 {
                     num = atoi(value_num);
-                    axiom_mime_parser_set_max_chunk_buffers(mime_parser, env, num);
+                    axiom_mime_parser_set_max_buffers(mime_parser, env, num);
+                }
+            }
+            /* If this paramter is there mime_parser will cached the attachment 
+             * using to the directory for large attachments. */    
+            attachment_dir_param = axis2_msg_ctx_get_parameter (msg_ctx,
+                                                                   env,
+                                                                   AXIS2_ATTACHMENT_DIR);
+
+            if(attachment_dir_param)
+            {
+                value_dir =
+                    (axis2_char_t *) axutil_param_get_value (attachment_dir_param, env);
+                if(value_dir)
+                {
+                    axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
                 }
             }
 
@@ -439,6 +485,12 @@
                     axiom_mime_parser_get_soap_body_str(mime_parser, env);
             }
 
+            if(callback_ctx->chunked_stream)
+            {
+                axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env);
+                callback_ctx->chunked_stream = NULL;
+            }
+
             stream = axutil_stream_create_basic(env);
             if (stream)
             {
@@ -450,8 +502,10 @@
             }
             axiom_mime_parser_free(mime_parser, env);
             mime_parser = NULL;
+
+            AXIS2_FREE(env->allocator, mime_boundary);
         }
-        AXIS2_FREE(env->allocator, mime_boundary);
+        /*AXIS2_FREE(env->allocator, mime_boundary);*/
     }
 
     if(soap_action_header)
@@ -810,44 +864,61 @@
         {
             axiom_mime_parser_t *mime_parser = NULL;
             int soap_body_len = 0;
-            axutil_param_t *chunk_buffer_size_param = NULL;
-            axutil_param_t *max_chunk_buffers_param = 0;
+            axutil_param_t *buffer_size_param = NULL;
+            axutil_param_t *max_buffers_param = NULL;
+            axutil_param_t *attachment_dir_param = NULL;
             axis2_char_t *value_size = NULL;
             axis2_char_t *value_num = NULL;
+            axis2_char_t *value_dir = NULL;
             int size = 0;
             int num = 0;
 
             mime_parser = axiom_mime_parser_create(env);
 
-            chunk_buffer_size_param = 
+            buffer_size_param = 
                 axis2_msg_ctx_get_parameter (msg_ctx,
                                              env,
-                                             AXIS2_MTOM_CHUNK_BUFFER_SIZE);
-            if (chunk_buffer_size_param)
+                                             AXIS2_MTOM_BUFFER_SIZE);
+            if (buffer_size_param)
             {
                 value_size =
-                    (axis2_char_t *) axutil_param_get_value (chunk_buffer_size_param, env);
+                    (axis2_char_t *) axutil_param_get_value (buffer_size_param, env);
                 if(value_size)
                 {
                     size = atoi(value_size);
-                    axiom_mime_parser_set_chunk_buffer_size(mime_parser, env, size);
+                    axiom_mime_parser_set_buffer_size(mime_parser, env, size);
                 }
             }
 
-            max_chunk_buffers_param = axis2_msg_ctx_get_parameter (msg_ctx,
+            max_buffers_param = axis2_msg_ctx_get_parameter (msg_ctx,
                                                                env,
-                                                               AXIS2_MTOM_MAX_CHUNK_BUFFERS);
-            if (max_chunk_buffers_param)
+                                                               AXIS2_MTOM_MAX_BUFFERS);
+            if (max_buffers_param)
             {
                 value_num =
-                    (axis2_char_t *) axutil_param_get_value (max_chunk_buffers_param, env);
+                    (axis2_char_t *) axutil_param_get_value (max_buffers_param, env);
                 if(value_num)
                 {
                     num = atoi(value_num);
-                    axiom_mime_parser_set_max_chunk_buffers(mime_parser, env, num);
+                    axiom_mime_parser_set_max_buffers(mime_parser, env, num);
+                }
+            }
+   
+            attachment_dir_param = axis2_msg_ctx_get_parameter (msg_ctx,
+                                                                   env,
+                                                                   AXIS2_ATTACHMENT_DIR);
+
+            if(attachment_dir_param)
+            {
+                value_dir =
+                    (axis2_char_t *) axutil_param_get_value (attachment_dir_param, env);
+                if(value_dir)
+                {
+                    axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
                 }
             }
 
+
             if (mime_parser)
             {
                 binary_data_map = 
@@ -1852,11 +1923,15 @@
             (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)
+        if (len > 0)
         {
             buffer[len] = AXIS2_ESC_NULL;
             ((axis2_callback_info_t *) ctx)->unread_len -= len;
         }
+        else if(len == 0)
+        {
+            ((axis2_callback_info_t *) ctx)->unread_len = 0;
+        }
     }
     return len;
 }
@@ -1981,45 +2056,61 @@
             axiom_mime_parser_t *mime_parser = NULL;
             int soap_body_len = 0;
             axis2_char_t *soap_body_str = NULL;
-            axutil_param_t *chunk_buffer_size_param = NULL;
-            axutil_param_t *max_chunk_buffers_param = 0;
+            axutil_param_t *buffer_size_param = NULL;
+            axutil_param_t *max_buffers_param = NULL;
+            axutil_param_t *attachment_dir_param = NULL;
             axis2_char_t *value_size = NULL;
             axis2_char_t *value_num = NULL;
+            axis2_char_t *value_dir = NULL;
             int size = 0;
             int num = 0;
  
             mime_parser = axiom_mime_parser_create(env);
 
-            chunk_buffer_size_param = 
+            buffer_size_param = 
                 axis2_msg_ctx_get_parameter (msg_ctx,
                                              env,
-                                             AXIS2_MTOM_CHUNK_BUFFER_SIZE);
-            if (chunk_buffer_size_param)
+                                             AXIS2_MTOM_BUFFER_SIZE);
+            if (buffer_size_param)
             {
                 value_size =
-                    (axis2_char_t *) axutil_param_get_value (chunk_buffer_size_param, env);
+                    (axis2_char_t *) axutil_param_get_value (buffer_size_param, env);
 
                 if(value_size)
                 {
                     size = atoi(value_size);
-                    axiom_mime_parser_set_chunk_buffer_size(mime_parser, env, size);
+                    axiom_mime_parser_set_buffer_size(mime_parser, env, size);
                 }
             }
 
-            max_chunk_buffers_param = axis2_msg_ctx_get_parameter (msg_ctx,
+            max_buffers_param = axis2_msg_ctx_get_parameter (msg_ctx,
                                                                    env,
-                                                                   AXIS2_MTOM_MAX_CHUNK_BUFFERS);
-            if(max_chunk_buffers_param)
+                                                                   AXIS2_MTOM_MAX_BUFFERS);
+            if(max_buffers_param)
             {
                 value_num =
-                    (axis2_char_t *) axutil_param_get_value (max_chunk_buffers_param, env);
+                    (axis2_char_t *) axutil_param_get_value (max_buffers_param, env);
                 if(value_num)
                 {
                     num = atoi(value_num);
-                    axiom_mime_parser_set_max_chunk_buffers(mime_parser, env, num);
+                    axiom_mime_parser_set_max_buffers(mime_parser, env, num);
                 }
             }
-            
+           
+            attachment_dir_param = axis2_msg_ctx_get_parameter (msg_ctx,
+                                                                   env,
+                                                                   AXIS2_ATTACHMENT_DIR);
+            if(attachment_dir_param)
+            {
+                value_dir =
+                    (axis2_char_t *) axutil_param_get_value (attachment_dir_param, env);
+                if(value_dir)
+                {
+                    axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
+                }
+            }
+   
+ 
             if (mime_parser)
             {
                 binary_data_map = 
@@ -2038,6 +2129,12 @@
                     axiom_mime_parser_get_soap_body_str(mime_parser, env);
             }
 
+            if(callback_ctx->chunked_stream)
+            {
+                axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env);
+                callback_ctx->chunked_stream = NULL;
+            }
+
             stream = axutil_stream_create_basic(env);
             if (stream)
             {
@@ -2118,6 +2215,12 @@
 			axutil_stream_free(stream, env);
 			callback_ctx->in_stream = NULL;
 		}
+        if(callback_ctx->chunked_stream)
+        {
+            axutil_http_chunked_stream_free(callback_ctx->chunked_stream, env);
+            callback_ctx->chunked_stream = NULL;
+        }
+
     }
     else
     {
@@ -3043,5 +3146,210 @@
 	return status;
 }
 
+/* This method takes an array_list as the input. It has items some 
+   may be buffers and some may be files. This will send these part
+   one by one to the wire using the chunked stream.*/
 
+AXIS2_EXTERN axis2_status_t AXIS2_CALL  
+axis2_http_transport_utils_send_mtom_message(
+    axutil_http_chunked_stream_t * chunked_stream,
+    const axutil_env_t * env,
+    axutil_array_list_t *mime_parts)
+{
+    int i = 0;
+    axiom_mime_part_t *mime_part = NULL;
+    axis2_status_t status = AXIS2_SUCCESS;
+    int written = 0;
+    int len = 0;    
 
+    if(mime_parts)
+    {
+        for(i = 0; i < axutil_array_list_size
+                (mime_parts, env); i++)
+        {
+            mime_part = (axiom_mime_part_t *)axutil_array_list_get(
+                mime_parts, env, i);
+            
+            /* If it is a buffer just wite it to the wire. This incudes mime_bounadaries,
+             * mime_headers and SOAP */
+            
+            if((mime_part->type) == AXIOM_MIME_PART_BUFFER)
+            {
+                written = 0;
+                while(written < mime_part->part_size)
+                {
+                    len = 0;
+                    len = axutil_http_chunked_stream_write(chunked_stream, env,
+                        mime_part->part + written, mime_part->part_size - written);
+                    if (len == -1)
+                    {
+                        status = AXIS2_FAILURE;
+                        break;
+                    }
+                    else
+                    {
+                        written += len;
+                    }
+                }
+            }
+            
+            /* If it is a file we load a very little portion to memory 
+             * and send it as chunked , we keep on doing this until we find
+             * the end of the file */ 
+            else if((mime_part->type) == AXIOM_MIME_PART_FILE)
+            {
+                FILE *f = NULL;
+                axis2_byte_t *output_buffer = NULL;                
+                int output_buffer_size = 0;
+
+                f = fopen(mime_part->file_name, "rb");
+                if (!f)
+                {
+                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                        "Error opening file %s for reading",
+                    mime_part->file_name);
+                    return AXIS2_FAILURE;
+                }
+                
+                /*If the part_size is less than the defined buffer size then 
+                 *from the first write to the wire we can send the file */
+                
+                if(mime_part->part_size > AXIS2_MTOM_OUTPUT_BUFFER_SIZE)
+                {
+                    output_buffer_size = AXIS2_MTOM_OUTPUT_BUFFER_SIZE;
+                }
+                else
+                {
+                    output_buffer_size = mime_part->part_size;
+                }
+               
+                output_buffer =  AXIS2_MALLOC(env->allocator, 
+                    (output_buffer_size + 1) * sizeof(axis2_char_t));
+ 
+                /*This is the method responsible for writing to the wire */    
+                status = axis2_http_transport_utils_send_attachment(env, chunked_stream, 
+                    f, output_buffer, output_buffer_size);
+                if(status == AXIS2_FAILURE)
+                {
+                    return status;
+                }
+            }
+            else
+            {
+                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unknown mime_part.");
+                return AXIS2_FAILURE;
+            }
+            if(status == AXIS2_FAILURE)
+            {
+                break;
+            }
+        }
+        if(status == AXIS2_SUCCESS)
+        {
+           /* send the end of chunk */
+            axutil_http_chunked_stream_write_last_chunk(chunked_stream, env);
+            return AXIS2_SUCCESS;
+        }
+        else
+        {
+            return status;
+        }
+    }    
+    else
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot send the attachment.Mime"
+                "Parts are not set properly.");
+        return AXIS2_FAILURE;
+    }    
+}
+
+
+static axis2_status_t
+axis2_http_transport_utils_send_attachment(
+    const axutil_env_t * env,
+    axutil_http_chunked_stream_t *chunked_stream,
+    FILE *fp,
+    axis2_byte_t *buffer,
+    int buffer_size)
+{
+
+    int count = 0;     
+    int len = 0;
+    int written = 0;
+    axis2_status_t status = AXIS2_SUCCESS;   
+ 
+    /*We do not load the whole file to memory. Just load a buffer_size portion
+     *and send it. Keep on doing this until the end of file */
+    
+    do
+    {
+        count = (int)fread(buffer, 1, buffer_size + 1, fp);
+        if (ferror(fp))
+        {
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                "Error in reading file containg the attachment");
+            if (buffer)
+            {
+                AXIS2_FREE(env->allocator, buffer);
+                buffer = NULL;
+            }
+            fclose(fp);
+            return AXIS2_FAILURE;
+        }
+
+        /*Writing the part we loaded to memory to the wire*/
+        if(count > 0)
+        {
+            written = 0;
+            while(written < count)
+            {
+                len = 0;
+                len = axutil_http_chunked_stream_write(chunked_stream, env,
+                    buffer + written, count - written);
+                if (len == -1)
+                {
+                    status = AXIS2_FAILURE;
+                    break;
+                }
+                else
+                {
+                    written += len;
+                }
+            }
+        }
+        else
+        {
+            if (buffer)
+            {
+                AXIS2_FREE(env->allocator, buffer);
+                buffer = NULL;
+            }
+            fclose(fp);
+            return AXIS2_FAILURE;
+        }  
+        
+        /*We keep on loading the next part to the same buffer. So need to reset 
+         * te buffer */
+        memset(buffer, 0, buffer_size);    
+        if(status == AXIS2_FAILURE)
+        {
+            if (buffer)
+            {
+                AXIS2_FREE(env->allocator, buffer);
+                buffer = NULL;
+            }
+            fclose(fp);
+            return AXIS2_FAILURE;
+        } 
+    }
+    while(!feof(fp));
+    
+    if(buffer)
+    {
+        AXIS2_FREE(env->allocator, buffer);    
+        buffer = NULL;
+    }
+
+    fclose(fp);
+    return AXIS2_SUCCESS;    
+}

Modified: webservices/axis2/trunk/c/util/include/axutil_utils.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/include/axutil_utils.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/util/include/axutil_utils.h (original)
+++ webservices/axis2/trunk/c/util/include/axutil_utils.h Tue Jul 22 01:43:36 2008
@@ -246,6 +246,13 @@
         const axutil_env_t * env,
         axis2_char_t * dest,
         axis2_char_t * src);
+    
+    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_char_2_byte(
+        const axutil_env_t *env,
+        axis2_char_t *char_buffer,
+        axis2_byte_t **byte_buffer,
+        int *byte_buffer_size);
 
     /** @} */
 

Propchange: webservices/axis2/trunk/c/util/src/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Jul 22 01:43:36 2008
@@ -0,0 +1,2 @@
+.deps
+.libs

Modified: webservices/axis2/trunk/c/util/src/utils.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/util/src/utils.c?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/util/src/utils.c (original)
+++ webservices/axis2/trunk/c/util/src/utils.c Tue Jul 22 01:43:36 2008
@@ -582,3 +582,36 @@
     }
     return 0;    
 }
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_char_2_byte(
+    const axutil_env_t *env,
+    axis2_char_t *char_buffer,
+    axis2_byte_t **byte_buffer,
+    int *byte_buffer_size)
+{
+    int length = 0;
+    int i = 0;
+    axis2_byte_t *bytes = NULL;
+
+    length = (int) axutil_strlen(char_buffer);
+    bytes = (axis2_byte_t *)
+        AXIS2_MALLOC(env->allocator, length * sizeof(axis2_byte_t));
+
+    if (!bytes)
+    {
+        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "No memory. Cannot create byte buffer");
+        return AXIS2_FAILURE;
+    }
+
+    for (i = 0; i < length; i++)
+    {
+        bytes[i] = (axis2_byte_t) char_buffer[i];
+    }
+    *byte_buffer = bytes;
+    *byte_buffer_size = length;
+    return AXIS2_SUCCESS;
+}
+