/** * Copyright 2016 (C) Federico Cabiddu * Copyright 2016 (C) Giacomo Vacca * Copyright 2016 (C) Orange - Camille Oudot * * This file is part of Kamailio, a free SIP server. * * This file 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 2 of the License, or * (at your option) any later version * * * This file 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /*! \file * \brief Kamailio http_async_client :: Async HTTP * \ingroup http_async_client */ #ifndef _ASYNC_HTTP_ #define _ASYNC_HTTP_ #define RC_AVP_NAME "http_rc" #define RC_AVP_NAME_LENGTH 7 #define RB_AVP_NAME "http_rb" #define RB_AVP_NAME_LENGTH 7 #define ERROR_AVP_NAME "http_error" #define ERROR_AVP_NAME_LENGTH 10 #include #include #include "../../pvar.h" #include "http_multi.h" extern int num_workers; extern int http_timeout; /* query timeout in ms */ extern struct sip_msg *ah_reply; extern str ah_error; extern int tls_verify_host; extern int tls_verify_peer; extern str tls_client_cert; extern str tls_client_key; extern str tls_ca_path; typedef struct async_http_worker { int notication_socket[2]; struct event_base *evbase; struct event *socket_event; struct http_m_global *g; } async_http_worker_t; extern async_http_worker_t *workers; typedef enum { AH_METH_DEFAULT = 0, AH_METH_GET, AH_METH_POST, AH_METH_PUT, AH_METH_DELETE } async_http_method_t; struct header_list { char ** t; int len; }; struct query_params { async_http_method_t method:3; unsigned int tls_verify_peer:1; unsigned int tls_verify_host:1; unsigned int suspend_transaction:1; /* (create and) suspend the current transaction */ unsigned int call_route:1; /* call script route on reply */ unsigned int timeout; struct header_list headers; str tls_client_cert; str tls_client_key; str tls_ca_path; }; extern struct query_params ah_params; typedef struct async_query { str query; str post; unsigned int tindex; unsigned int tlabel; struct query_params query_params; void *param; } async_query_t; int async_http_init_sockets(async_http_worker_t *worker); int async_http_init_worker(int prank, async_http_worker_t* worker); void async_http_run_worker(async_http_worker_t* worker); int async_send_query(sip_msg_t *msg, str *query, str *post, cfg_action_t *act); int async_push_query(async_query_t *aq); void notification_socket_cb(int fd, short event, void *arg); int init_socket(async_http_worker_t* worker); void async_http_cb(struct http_m_reply *reply, void *param); void init_query_params(struct query_params*); void set_query_params(struct query_params*); int header_list_add(struct header_list *hl, str* hdr); int query_params_set_method(struct query_params *qp, str *meth); static inline void free_async_query(async_query_t *aq) { if (!aq) return; LM_DBG("freeing query %p\n", aq); if (aq->query.s && aq->query.len) { shm_free(aq->query.s); aq->query.s=0; aq->query.len=0; } if (aq->post.s && aq->post.len) { shm_free(aq->post.s); aq->post.s=0; aq->post.len=0; } if(aq->query_params.headers.t) { while(aq->query_params.headers.len--) shm_free(aq->query_params.headers.t[aq->query_params.headers.len]); shm_free(aq->query_params.headers.t); } if (aq->query_params.tls_client_cert.s && aq->query_params.tls_client_cert.len > 0) { shm_free(aq->query_params.tls_client_cert.s); aq->query_params.tls_client_cert.s = NULL; aq->query_params.tls_client_cert.len = 0; } if (aq->query_params.tls_client_key.s && aq->query_params.tls_client_key.len > 0) { shm_free(aq->query_params.tls_client_key.s); aq->query_params.tls_client_key.s = NULL; aq->query_params.tls_client_key.len = 0; } if (aq->query_params.tls_ca_path.s && aq->query_params.tls_ca_path.len > 0) { shm_free(aq->query_params.tls_ca_path.s); aq->query_params.tls_ca_path.s = NULL; aq->query_params.tls_ca_path.len = 0; } shm_free(aq); } #endif