| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "axiom_mime_body_part.h" |
| #include <axiom_mime_part.h> |
| #include <axiom_data_handler.h> |
| #include <axutil_hash.h> |
| |
| struct axiom_mime_body_part |
| { |
| /* hash map to hold header name, value pairs */ |
| axutil_hash_t *header_map; |
| axiom_data_handler_t *data_handler; |
| }; |
| |
| /* This method just create a mime_body_part. It does not |
| * fill the header map. |
| */ |
| |
| AXIS2_EXTERN axiom_mime_body_part_t *AXIS2_CALL |
| axiom_mime_body_part_create( |
| const axutil_env_t *env) |
| { |
| axiom_mime_body_part_t *mime_body_part = NULL; |
| |
| AXIS2_ENV_CHECK(env, NULL); |
| mime_body_part = (axiom_mime_body_part_t *)AXIS2_MALLOC(env->allocator, |
| sizeof(axiom_mime_body_part_t)); |
| |
| if(!mime_body_part) |
| { |
| AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create MIME body part"); |
| return NULL; |
| } |
| |
| mime_body_part->header_map = NULL; |
| mime_body_part->data_handler = NULL; |
| |
| mime_body_part->header_map = axutil_hash_make(env); |
| if(!(mime_body_part->header_map)) |
| { |
| axiom_mime_body_part_free(mime_body_part, env); |
| return NULL; |
| } |
| |
| return mime_body_part; |
| } |
| |
| /* This method will create the mime_body_part and fill the header map with |
| * default information. Default information are for binary attachments. |
| * Attachment information is taken from the information in data_handler in passed |
| * om_text. |
| */ |
| |
| AXIS2_EXTERN axiom_mime_body_part_t *AXIS2_CALL |
| axiom_mime_body_part_create_from_om_text( |
| const axutil_env_t *env, |
| axiom_text_t *text) |
| { |
| axiom_data_handler_t *data_handler = NULL; |
| axiom_mime_body_part_t *mime_body_part = NULL; |
| axis2_char_t *content_id = NULL; |
| axis2_char_t *temp_content_id = NULL; |
| const axis2_char_t *content_type = AXIOM_MIME_TYPE_OCTET_STREAM; |
| |
| mime_body_part = axiom_mime_body_part_create(env); |
| if(!mime_body_part) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MIME body part creation failed"); |
| return NULL; |
| } |
| |
| /* Take the data_handler which is set by the sending applocation. */ |
| |
| data_handler = axiom_text_get_data_handler(text, env); |
| |
| if(data_handler) |
| { |
| content_type = axiom_data_handler_get_content_type(data_handler, env); |
| } |
| |
| axiom_mime_body_part_set_data_handler(mime_body_part, env, data_handler); |
| content_id = (axis2_char_t *)"<"; |
| content_id = axutil_stracat(env, content_id, axiom_text_get_content_id(text, env)); |
| temp_content_id = axutil_stracat(env, content_id, ">"); |
| |
| AXIS2_FREE(env->allocator, content_id); |
| content_id = temp_content_id; |
| |
| /* Adding the content-id */ |
| axiom_mime_body_part_add_header(mime_body_part, env, AXIOM_MIME_HEADER_CONTENT_ID, content_id); |
| |
| /* Adding the content-type */ |
| axiom_mime_body_part_add_header(mime_body_part, env, AXIOM_MIME_HEADER_CONTENT_TYPE, |
| axutil_strdup(env, content_type)); |
| |
| /* Adding the content-transfer encoding */ |
| axiom_mime_body_part_add_header(mime_body_part, env, |
| AXIOM_MIME_HEADER_CONTENT_TRANSFER_ENCODING, axutil_strdup(env, |
| AXIOM_MIME_CONTENT_TRANSFER_ENCODING_BINARY)); |
| |
| return mime_body_part; |
| } |
| |
| AXIS2_EXTERN void AXIS2_CALL |
| axiom_mime_body_part_free( |
| axiom_mime_body_part_t *mime_body_part, |
| const axutil_env_t *env) |
| { |
| if(mime_body_part->header_map) |
| { |
| axutil_hash_index_t *hash_index = NULL; |
| const void *key = NULL; |
| void *value = NULL; |
| for(hash_index = axutil_hash_first(mime_body_part->header_map, env); hash_index; hash_index |
| = axutil_hash_next(env, hash_index)) |
| { |
| axutil_hash_this(hash_index, &key, NULL, &value); |
| if(value) |
| { |
| AXIS2_FREE(env->allocator, value); |
| } |
| } |
| |
| axutil_hash_free(mime_body_part->header_map, env); |
| mime_body_part->header_map = NULL; |
| } |
| |
| if(mime_body_part) |
| { |
| AXIS2_FREE(env->allocator, mime_body_part); |
| } |
| |
| return; |
| } |
| |
| /* This method will add a mime_header to the hash */ |
| |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| axiom_mime_body_part_add_header( |
| axiom_mime_body_part_t *mime_body_part, |
| const axutil_env_t *env, |
| const axis2_char_t *name, |
| const axis2_char_t *value) |
| { |
| AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); |
| |
| if(!mime_body_part->header_map) |
| { |
| return AXIS2_FAILURE; |
| } |
| axutil_hash_set(mime_body_part->header_map, name, AXIS2_HASH_KEY_STRING, value); |
| return AXIS2_SUCCESS; |
| } |
| |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| axiom_mime_body_part_set_data_handler( |
| axiom_mime_body_part_t *mime_body_part, |
| const axutil_env_t *env, |
| axiom_data_handler_t *data_handler) |
| { |
| mime_body_part->data_handler = data_handler; |
| return AXIS2_SUCCESS; |
| } |
| |
| /* This method will fill the array_list with binary and binary_beader information. |
| * If the binary is in a file this will not load the file to the memory. Because |
| * that will cause performance degradation when the file size is large. Instead |
| * this will add file information to the list so that when writing the message |
| * through transport_sender it can send the file by chunk. |
| */ |
| |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| axiom_mime_body_part_write_to_list( |
| axiom_mime_body_part_t *mime_body_part, |
| const axutil_env_t *env, |
| axutil_array_list_t *list) |
| { |
| axutil_hash_index_t *hash_index = NULL; |
| const void *key = NULL; |
| void *value = NULL; |
| axis2_char_t *header_str = NULL; |
| axis2_char_t *temp_header_str = NULL; |
| int header_str_size = 0; |
| axis2_status_t status = AXIS2_FAILURE; |
| axiom_mime_part_t *mime_header_part = NULL; |
| |
| /* We have the mime headers in the hash with thier keys |
| * So first concatenate them to a one string */ |
| |
| for(hash_index = axutil_hash_first(mime_body_part->header_map, env); hash_index; hash_index |
| = axutil_hash_next(env, hash_index)) |
| { |
| axutil_hash_this(hash_index, &key, NULL, &value); |
| if(key && value) |
| { |
| /* First conactenate to the already conacatenated stuff */ |
| |
| temp_header_str = axutil_stracat(env, header_str, (axis2_char_t *)key); |
| if(header_str) |
| { |
| AXIS2_FREE(env->allocator, header_str); |
| } |
| header_str = temp_header_str; |
| temp_header_str = axutil_stracat(env, header_str, ": "); |
| AXIS2_FREE(env->allocator, header_str); |
| header_str = temp_header_str; |
| |
| /* Add the new stuff */ |
| temp_header_str = axutil_stracat(env, header_str, (axis2_char_t *)value); |
| AXIS2_FREE(env->allocator, header_str); |
| header_str = temp_header_str; |
| |
| /* Next header will be in a new line. So lets add it */ |
| |
| temp_header_str = axutil_stracat(env, header_str, AXIS2_CRLF); |
| AXIS2_FREE(env->allocator, header_str); |
| header_str = temp_header_str; |
| } |
| } |
| |
| /* If there is a data handler that's mean there is an attachment. Attachment |
| * will always start after an additional new line . So let's add it .*/ |
| |
| if(mime_body_part->data_handler) |
| { |
| temp_header_str = axutil_stracat(env, header_str, AXIS2_CRLF); |
| AXIS2_FREE(env->allocator, header_str); |
| header_str = temp_header_str; |
| } |
| |
| if(header_str) |
| { |
| header_str_size = axutil_strlen(header_str); |
| } |
| |
| /* Now we have the complete mime_headers string for a particular mime part. |
| * First wrap it as a mime_part_t .Then add it to the array list so |
| * later through the transport this can be written to the wire. */ |
| |
| mime_header_part = axiom_mime_part_create(env); |
| |
| if(mime_header_part) |
| { |
| mime_header_part->part = (axis2_byte_t *)header_str; |
| mime_header_part->part_size = header_str_size; |
| mime_header_part->type = AXIOM_MIME_PART_BUFFER; |
| } |
| else |
| { |
| return AXIS2_FAILURE; |
| } |
| |
| axutil_array_list_add(list, env, mime_header_part); |
| |
| /* Then if the data_handler is there let's add the binary data, may be |
| * buffer , may be file name and information. |
| */ |
| |
| if(mime_body_part->data_handler) |
| { |
| status = axiom_data_handler_add_binary_data(mime_body_part->data_handler, env, list); |
| if(status != AXIS2_SUCCESS) |
| { |
| return status; |
| } |
| } |
| return AXIS2_SUCCESS; |
| } |