diff options
-rw-r--r-- | axiom/include/axiom_data_handler.h | 13 | ||||
-rw-r--r-- | axiom/include/axiom_mime_part.h | 13 | ||||
-rw-r--r-- | axiom/include/axiom_mtom_sending_callback.h | 8 | ||||
-rw-r--r-- | axiom/src/attachments/data_handler.c | 109 | ||||
-rw-r--r-- | src/core/transport/http/util/http_transport_utils.c | 30 |
5 files changed, 170 insertions, 3 deletions
diff --git a/axiom/include/axiom_data_handler.h b/axiom/include/axiom_data_handler.h index 0cf65c9..5442a2f 100644 --- a/axiom/include/axiom_data_handler.h +++ b/axiom/include/axiom_data_handler.h @@ -31,6 +31,7 @@ #include <axutil_allocator.h> #include <axutil_string.h> #include <axutil_array_list.h> +#include <axiom_mtom_sending_callback.h> #ifdef __cplusplus extern "C" @@ -41,6 +42,7 @@ extern "C" { AXIOM_DATA_HANDLER_TYPE_FILE, AXIOM_DATA_HANDLER_TYPE_BUFFER, + AXIOM_DATA_HANDLER_TYPE_HANDLER, AXIOM_DATA_HANDLER_TYPE_CALLBACK } axiom_data_handler_type_t; @@ -240,6 +242,17 @@ extern "C" const axutil_env_t *env, axiom_data_handler_type_t data_handler_type); + AXIS2_EXTERN void AXIS2_CALL + axiom_data_handler_set_read_handler( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + int (* handler_create)( + axiom_mtom_sending_callback_t **, + const axutil_env_t *), + int (* handler_remove)( + axiom_mtom_sending_callback_t *, + const axutil_env_t *)); + AXIS2_EXTERN void *AXIS2_CALL axiom_data_handler_get_user_param( axiom_data_handler_t *data_handler, diff --git a/axiom/include/axiom_mime_part.h b/axiom/include/axiom_mime_part.h index e4cfc36..c56f50a 100644 --- a/axiom/include/axiom_mime_part.h +++ b/axiom/include/axiom_mime_part.h @@ -30,6 +30,7 @@ #include <axutil_allocator.h> #include <axutil_string.h> #include <axutil_array_list.h> +#include <axiom_mtom_sending_callback.h> #ifdef __cplusplus extern "C" @@ -53,6 +54,9 @@ extern "C" /* User specified callback */ AXIOM_MIME_PART_CALLBACK, + /* User specified handler functions */ + AXIOM_MIME_PART_HANDLER, + /* unknown type*/ AXIOM_MIME_PART_UNKNOWN @@ -78,6 +82,15 @@ extern "C" /* This is required in the case of the callback */ void *user_param; + + /* Required for type AXIOM_MIME_PART_HANDLER, specify + * functions for reading data */ + int (* read_handler_create)( + axiom_mtom_sending_callback_t ** inst, + const axutil_env_t * env); + int (* read_handler_remove)( + axiom_mtom_sending_callback_t * inst, + const axutil_env_t * env); }; diff --git a/axiom/include/axiom_mtom_sending_callback.h b/axiom/include/axiom_mtom_sending_callback.h index ce2587e..fb97d5e 100644 --- a/axiom/include/axiom_mtom_sending_callback.h +++ b/axiom/include/axiom_mtom_sending_callback.h @@ -73,6 +73,11 @@ extern "C" void *handler, axis2_char_t **buffer); + int (AXIS2_CALL* + data_size)(axiom_mtom_sending_callback_t *mtom_sending_callback, + const axutil_env_t* env, + void *handler); + axis2_status_t (AXIS2_CALL* close_handler)(axiom_mtom_sending_callback_t *mtom_sending_callback, const axutil_env_t* env, @@ -96,6 +101,9 @@ extern "C" #define AXIOM_MTOM_SENDING_CALLBACK_LOAD_DATA(mtom_sending_callback, env, handler, buffer) \ ((mtom_sending_callback)->ops->load_data(mtom_sending_callback, env, handler, buffer)) +#define AXIOM_MTOM_SENDING_CALLBACK_DATA_SIZE(mtom_sending_callback, env, handler) \ + ((mtom_sending_callback)->ops->data_size(mtom_sending_callback, env, handler)) + #define AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(mtom_sending_callback, env, handler) \ ((mtom_sending_callback)->ops->close_handler(mtom_sending_callback, env, handler)) diff --git a/axiom/src/attachments/data_handler.c b/axiom/src/attachments/data_handler.c index 3be8a9d..7a7541b 100644 --- a/axiom/src/attachments/data_handler.c +++ b/axiom/src/attachments/data_handler.c @@ -43,6 +43,14 @@ struct axiom_data_handler /* The Content Id */ axis2_char_t *mime_id; + /* In the case of TYPE_HANDLER these are required */ + int (* read_handler_create)( + axiom_mtom_sending_callback_t ** inst, + const axutil_env_t * env); + int (* read_handler_remove)( + axiom_mtom_sending_callback_t * inst, + const axutil_env_t * env); + /* In the case of sending callback this is required */ void *user_param; @@ -206,8 +214,7 @@ axiom_data_handler_read_from( *output_stream = data_handler->buffer; *output_stream_size = data_handler->buffer_len; } - else if(data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_FILE - && data_handler->file_name) + else if(data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_FILE) { FILE *f = NULL; axis2_byte_t *byte_stream = NULL; @@ -219,6 +226,11 @@ axiom_data_handler_read_from( int count = 0; struct stat stat_p; + if (!data_handler->file_name) + { + return AXIS2_FAILURE; + } + f = fopen(data_handler->file_name, "rb"); if(!f) { @@ -336,9 +348,79 @@ axiom_data_handler_read_from( *output_stream = byte_stream; *output_stream_size = byte_stream_size; } + else if (data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_HANDLER) + { + axis2_byte_t *byte_stream = NULL; + axis2_byte_t *buffer_ptr = NULL; + axis2_byte_t *temp_buffer = NULL; + int byte_stream_size = 0; + int temp_buffer_size = 1; + int total_byte_size = 0; + axiom_mtom_sending_callback_t *callback = NULL; + void *handler_data = NULL; + axis2_status_t status = AXIS2_FAILURE; + + if (data_handler->read_handler_create(&callback, env) == AXIS2_FAILURE) + { + return AXIS2_FAILURE; + } + + handler_data = AXIOM_MTOM_SENDING_CALLBACK_INIT_HANDLER(callback, env, + data_handler->user_param); + + if (handler_data) + { + total_byte_size = AXIOM_MTOM_SENDING_CALLBACK_DATA_SIZE(callback, + env, handler_data); + + byte_stream = (axis2_byte_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_byte_t) * total_byte_size); + buffer_ptr = byte_stream; + + while ((temp_buffer_size > 0) && + (byte_stream_size < total_byte_size)) + { + temp_buffer_size = AXIOM_MTOM_SENDING_CALLBACK_LOAD_DATA( + callback, env, handler_data, &temp_buffer); + + if (temp_buffer_size > 0) + { + if ((byte_stream_size + temp_buffer_size) > total_byte_size) + { + temp_buffer_size = total_byte_size - byte_stream_size; + } + + memcpy(buffer_ptr, temp_buffer, temp_buffer_size); + buffer_ptr += temp_buffer_size; + byte_stream_size += temp_buffer_size; + + AXIS2_FREE(env->allocator, temp_buffer); + } + } + + status = AXIOM_MTOM_SENDING_CALLBACK_CLOSE_HANDLER(callback, env, + handler_data); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No data received from handler init function"); + status = AXIS2_FAILURE; + } + + data_handler->read_handler_remove(callback, env); + + if (status == AXIS2_FAILURE) + { + return status; + } + + *output_stream = byte_stream; + *output_stream_size = byte_stream_size; + } else { - /* Data Handler File Name is missing */ + /* unsupported handler type */ return AXIS2_FAILURE; } @@ -489,6 +571,16 @@ axiom_data_handler_add_binary_data( binary_part->type = AXIOM_MIME_PART_FILE; } } + /* In the case where the user has specified some handler functions. Set + * the correct type and pass the handler functions on to the MIME part */ + + else if(data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_HANDLER) + { + binary_part->type = AXIOM_MIME_PART_HANDLER; + binary_part->user_param = data_handler->user_param; + binary_part->read_handler_create = data_handler->read_handler_create; + binary_part->read_handler_remove = data_handler->read_handler_remove; + } /* In the case of Callback the user should specify the callback name in the * configuration file. We just set the correct type. Inside the transport * it will load the callback and send the attachment appropriately */ @@ -552,6 +644,17 @@ axiom_data_handler_set_data_handler_type( return; } +AXIS2_EXTERN void AXIS2_CALL +axiom_data_handler_set_read_handler( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + int (* handler_create)(axiom_mtom_sending_callback_t **, const axutil_env_t *), + int (* handler_remove)(axiom_mtom_sending_callback_t *, const axutil_env_t *)) +{ + data_handler->read_handler_create = handler_create; + data_handler->read_handler_remove = handler_remove; +} + AXIS2_EXTERN void *AXIS2_CALL axiom_data_handler_get_user_param( axiom_data_handler_t *data_handler, diff --git a/src/core/transport/http/util/http_transport_utils.c b/src/core/transport/http/util/http_transport_utils.c index 552cde5..90acc60 100644 --- a/src/core/transport/http/util/http_transport_utils.c +++ b/src/core/transport/http/util/http_transport_utils.c @@ -3256,7 +3256,37 @@ axis2_http_transport_utils_send_mtom_message( AXIS2_FREE(env->allocator, output_buffer); fclose(f); } + else if((mime_part->type) == AXIOM_MIME_PART_HANDLER) + { + void *handler_data = NULL; + axiom_mtom_sending_callback_t *callback = NULL; + + status = mime_part->read_handler_create(&callback, env); + + if(callback) + { + handler_data = AXIOM_MTOM_SENDING_CALLBACK_INIT_HANDLER(callback, env, + mime_part->user_param); + + if (handler_data) + { + status = axis2_http_transport_utils_send_attachment_using_callback(env, + chunked_stream, callback, handler_data, mime_part->user_param); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MTOM Sending Handler loading failed"); + status = AXIS2_FAILURE; + } + mime_part->read_handler_remove(callback, env); + } + + if(status == AXIS2_FAILURE) + { + return status; + } + } /* if the callback is given, send data using callback */ else if((mime_part->type) == AXIOM_MIME_PART_CALLBACK) { |