c732d49e |
#if HAVE_CRT
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif //HAVE_CRT
/*
* Copyright (C) 2017, 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;
}
|