#if HAVE_CRT #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #endif //HAVE_CRT /* * Copyright (C) 2020, University of the Basque Country (UPV/EHU) * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com> * * The original file was part of Open Source Doubango Framework * Copyright (C) 2010-2011 Mamadou Diop. * Copyright (C) 2012 Doubango Telecom <http://doubango.org> * * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with DOUBANGO. * */ /**@file txcap_action.c * @brief XCAP actions. * * @author Mamadou Diop <diopmamadou(at)doubango.org> * */ #include "tinyxcap/txcap_action.h" #include "tsk_options.h" #include "tsk_params.h" #include "tinyxcap/txcap_selector.h" /**@defgroup txcap_action_group XDMC (Sending Requests) */ extern char* __txcap_selector_get_url(const txcap_stack_handle_t* stack, const char* auid_id, va_list* app); extern char* __txcap_selector_get_url_no_auid(const txcap_stack_handle_t* stack, const char* auid_id, va_list* app); /** Sends HTTP/HTTPS request to the XDMS. */ int txcap_action_perform(txcap_stack_handle_t* stack, txcap_action_type_t type, txcap_action_target_t target, ...) { tsk_options_L_t* options = tsk_null; tsk_params_L_t* headers = tsk_null; char* urlstring = tsk_null; thttp_action_t* action; thttp_dialog_t* dialog; int ret = -1; txcap_action_param_type_t curr; const char* method = "GET"; const char* mime_type = tsk_null; const char* AUID_STR = tsk_null; const void* PAY_PTR = tsk_null; size_t PAY_SIZE = 0; va_list ap; txcap_stack_t* xcap_stack = stack; if(!xcap_stack){ goto bail; } else{ xcap_stack = tsk_object_ref(stack); options = tsk_list_create(); headers = tsk_list_create(); } va_start(ap, target); while((curr = va_arg(ap, txcap_action_param_type_t)) != txcap_apt_null){ switch(curr){ case txcap_apt_option: { /*(thttp_action_option_t)ID_INT, (const char*)VALUE_STR*/ thttp_action_option_t ID_INT = va_arg(ap, thttp_action_option_t); const char* VALUE_STR = va_arg(ap, const char *); tsk_options_add_option(&options, ID_INT, VALUE_STR); break; } case txcap_apt_header: { /* (const char*)NAME_STR, (const char*)VALUE_STR */ const char* NAME_STR = va_arg(ap, const char *); const char* VALUE_STR = va_arg(ap, const char *); if(VALUE_STR == (const char*)-1){ tsk_params_remove_param(headers, NAME_STR); } else{ tsk_params_add_param(&headers, NAME_STR, VALUE_STR); } break; } case txcap_apt_payload: { /*(const void*)PAY_PTR, (size_t)PAY_SIZE*/ PAY_PTR = va_arg(ap, const void *); PAY_SIZE = va_arg(ap, size_t); break; } case txcap_apt_selector: { /*(const char*)AUID_STR, __VA_ARGS__*/ AUID_STR = va_arg(ap, const char *); if(!urlstring){ urlstring = __txcap_selector_get_url(stack, AUID_STR, &ap); } break; } case txcap_apt_selector_no_auid: { /*(const char*)AUID_STR, __VA_ARGS__*/ AUID_STR = va_arg(ap, const char *); if(!urlstring){ urlstring = __txcap_selector_get_url_no_auid(stack, AUID_STR, &ap); } break; } case txcap_apt_urlstring: { /* (const char*)URI_STR */ const char* URI_STR = va_arg(ap, const char *); if(!urlstring){ urlstring = tsk_strdup(URI_STR); } break; } default: { TSK_DEBUG_ERROR("NOT SUPPORTED."); goto done; } }/* switch */ } /* while */ done: va_end(ap); /* checks urlstring */ if(!urlstring){ TSK_DEBUG_ERROR("Failed to compute XCAP URL"); goto bail; } /* HTTP method */ switch(type){ case txcap_atp_create: case txcap_atp_replace: method = "PUT"; break; case txcap_atp_fetch: method = "GET"; break; case txcap_atp_delete: method = "DELETE"; break; } /*content-type*/ switch(target){ case txcap_atg_element: mime_type = TXCAP_MIME_TYPE_ELEMENT; break; case txcap_atg_document: { if(AUID_STR){ txcap_auid_t* auid; if((auid = txcap_auid_get_by_id(xcap_stack->auids, AUID_STR))){ mime_type = (const char*)auid->mime_type; // (cont char*) do not strdup() TSK_OBJECT_SAFE_FREE(auid); } else{ TSK_DEBUG_WARN("Failed to find auid with id=%s", AUID_STR); } } break; } case txcap_atg_attribute: mime_type = TXCAP_MIME_TYPE_ATTRIBUTE; break; } /* HTTP action */ if((action = thttp_action_create(thttp_atype_o_request, urlstring, method, tsk_null))){ const tsk_list_item_t* item; if((dialog = thttp_dialog_new(xcap_stack->http_session))){ /* copy options */ tsk_list_foreach(item, options){ tsk_options_add_option(&action->options, ((const tsk_option_t*)item->data)->id, ((const tsk_option_t*)item->data)->value); } /* copy action-level headers */ tsk_list_foreach(item, headers){ tsk_params_add_param(&action->headers, ((const tsk_param_t*)item->data)->name, ((const tsk_param_t*)item->data)->value); } /* copy session-level headers ==> will be added by thttp_dialog_send_request()*/ //--tsk_list_pushback_list(action->headers, ((thttp_session_t*)xcap_stack->http_session)->headers); /* Content-Type */ if(mime_type){ if(!tsk_params_have_param(action->headers, "Content-Type")){ tsk_params_add_param(&action->headers, "Content-Type", mime_type); } } /* payload */ if(PAY_PTR && PAY_SIZE){ action->payload = tsk_buffer_create(PAY_PTR, PAY_SIZE); } /* performs */ ret = thttp_dialog_fsm_act(dialog, action->type, tsk_null, action); tsk_object_unref(dialog); } else{ TSK_DEBUG_ERROR("Failed to create new HTTP/HTTPS dialog."); ret = -2; } TSK_OBJECT_SAFE_FREE(action); } bail: TSK_FREE(urlstring); TSK_OBJECT_SAFE_FREE(options); TSK_OBJECT_SAFE_FREE(headers); tsk_object_unref(xcap_stack); return ret; }