Skip to content
Snippets Groups Projects

Feature 2911

Merged alexander.lysikov requested to merge feature-2911 into master
2 files
+ 165
16
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -8,6 +8,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#ifdef _WIN32
#include <winsock2.h>
@@ -18,14 +19,9 @@
#include <time.h>
#endif
#include <pthread.h>
#include <curl/curl.h>
#include "utlist.h"
#include "dap_common.h"
#include "dap_http_client.h"
#include "dap_http_client_simple.h"
@@ -47,8 +43,21 @@ typedef struct dap_http_client_internal {
} dap_http_client_internal_t;
typedef struct dap_http_client_active_conn{
void *curl_h;// CURL
void *client_obj;// dap_client_pvt_t
UT_hash_handle hh;
} dap_http_client_active_conn_t;
// List of active connections
static dap_http_client_active_conn_t *s_conn_list = NULL;
// for separate access to s_conn_list
static pthread_mutex_t s_conn_list_mutex = PTHREAD_MUTEX_INITIALIZER;
CURLM *m_curl_mh = NULL; // Multi-thread handle to stack lot of parallel requests
#ifndef _WIN32
pthread_t curl_pid = 0;
#else
@@ -94,6 +103,118 @@ void dap_http_client_simple_deinit( )
curl_multi_cleanup( m_curl_mh );
}
/**
* dap_http_client_lock_active_conn
*/
int dap_http_client_lock_active_conn(void)
{
return pthread_mutex_lock(&s_conn_list_mutex);
}
/**
* dap_http_client_unlock_active_conn
*/
int dap_http_client_unlock_active_conn(void)
{
return pthread_mutex_unlock(&s_conn_list_mutex);
}
/**
* find active connection in the list by CURL
*
* return 0 OK, -1 error, -2 connection not found
*/
static dap_http_client_active_conn_t* dap_http_client_get_active_conn_by_curl(void *a_curl_h)
{
if(!a_curl_h)
return NULL;
dap_http_client_active_conn_t *l_cur_item;
HASH_FIND(hh, s_conn_list, a_curl_h, sizeof(CURL), l_cur_item);
return l_cur_item;
}
/**
* find active connection in the list by dap_http_client_internal_t
*
* return 0 OK, -1 error, -2 connection not found
*/
void* dap_http_client_get_active_conn_by_obj(void *a_client_obj)
{
if(!a_client_obj)
return NULL;
dap_http_client_active_conn_t * l_cur_item, *l_item_tmp;
HASH_ITER(hh, s_conn_list, l_cur_item, l_item_tmp)
{
if(l_cur_item->client_obj == a_client_obj)
break;
}
return (void*)l_cur_item;
}
/**
* Add new active connection to the list
*
* return 0 OK, -1 error, -2 connection present
*/
static int dap_http_client_add_active_conn(CURL *a_curl_h, dap_http_client_internal_t *a_client_obj)
{
int l_ret = 0;
if(!a_curl_h || !a_client_obj)
return -1;
pthread_mutex_lock(&s_conn_list_mutex);
dap_http_client_active_conn_t *l_cur_item = dap_http_client_get_active_conn_by_curl(a_curl_h);
if(l_cur_item == NULL) {
l_cur_item = DAP_NEW(dap_http_client_active_conn_t);
l_cur_item->curl_h = a_curl_h;
l_cur_item->client_obj = a_client_obj;
HASH_ADD(hh, s_conn_list, curl_h, sizeof(CURL), l_cur_item); // address: name of key field
l_ret = 0;
}
// connection already present
else
l_ret = -2;
//connect_list = g_list_append(connect_list, client);
pthread_mutex_unlock(&s_conn_list_mutex);
return l_ret;
}
/**
* Delete active connection from the list
*
* return 0 OK, -1 error, -2 connection not found
*/
int dap_http_client_del_active_conn(void *a_curl_h, void *a_client_obj)
{
int ret = -1;
if(!a_curl_h && !a_client_obj)
return -1;
dap_http_client_active_conn_t *l_cur_item;
pthread_mutex_lock(&s_conn_list_mutex);
do {
if(a_curl_h)
l_cur_item = dap_http_client_get_active_conn_by_curl(a_curl_h);
else if(a_client_obj)
l_cur_item = dap_http_client_get_active_conn_by_obj(a_client_obj);
if(l_cur_item != NULL) {
HASH_DEL(s_conn_list, l_cur_item);
DAP_DELETE(l_cur_item);
ret = 0;
}
// connection not found in the hash
else {
ret = -2;
break;
}
}
// maybe some active conn with the same a_client_obj, required del all of them
while(l_cur_item);
pthread_mutex_unlock(&s_conn_list_mutex);
return ret;
}
/**
* @brief dap_http_client_internal_delete
* @param a_client
@@ -115,6 +236,24 @@ void dap_http_client_internal_delete( dap_http_client_internal_t * a_client_inte
log_it( L_NOTICE,"dap_http_client_internal_delete ok" );
}
/**
* @brief dap_http_client_simple_request_break
* @param a_curl
*/
void dap_http_client_simple_request_break(long a_curl_sock)
{
//if(!a_curl)
if(a_curl_sock<0)
return;
#ifdef _WIN32
closesocket(a_curl_sock);
#else
close(a_curl_sock);
#endif
//curl_multi_remove_handle(m_curl_mh, a_curl);
//curl_easy_cleanup(a_curl);
}
/**
* @brief dap_http_client_simple_request
* @param a_url
@@ -126,11 +265,11 @@ void dap_http_client_internal_delete( dap_http_client_internal_t * a_client_inte
* @param a_error_callback
* @param a_obj
*/
void dap_http_client_simple_request_custom( const char *a_url, const char *a_method, const char *a_request_content_type,
void* dap_http_client_simple_request_custom( const char *a_url, const char *a_method, const char *a_request_content_type,
void *a_request, size_t a_request_size, char *a_cookie,
dap_http_client_simple_callback_data_t a_response_callback,
dap_http_client_simple_callback_error_t a_error_callback,
void *a_obj, char **a_custom, size_t a_custom_count )
long *curl_sockfd, void *a_obj, char **a_custom, size_t a_custom_count )
{
log_it( L_DEBUG, "Simple HTTP request with static predefined buffer (%lu bytes) on url '%s'",
DAP_HTTP_CLIENT_RESPONSE_SIZE_MAX, a_url );
@@ -190,6 +329,11 @@ void dap_http_client_simple_request_custom( const char *a_url, const char *a_met
curl_easy_setopt( l_curl_h , CURLOPT_WRITEDATA , l_client_internal );
curl_easy_setopt( l_curl_h , CURLOPT_WRITEFUNCTION , dap_http_client_curl_response_callback );
// add active connection to list
dap_http_client_add_active_conn(l_curl_h, a_obj);
//if(curl_sockfd)
//curl_easy_getinfo( l_curl_h , CURLINFO_LASTSOCKET, curl_sockfd);
curl_multi_add_handle( m_curl_mh, l_curl_h );
//curl_multi_perform(m_curl_mh, &m_curl_cond);
@@ -197,7 +341,7 @@ void dap_http_client_simple_request_custom( const char *a_url, const char *a_met
pthread_cond_signal( &m_curl_cond);
send_select_break( );
#endif
return l_curl_h;
}
/**
@@ -211,8 +355,8 @@ void dap_http_client_simple_request_custom( const char *a_url, const char *a_met
* @param a_error_callback
* @param a_obj
*/
void dap_http_client_simple_request(const char * a_url, const char * a_method, const char* a_request_content_type, void *a_request, size_t a_request_size, char * a_cookie, dap_http_client_simple_callback_data_t a_response_callback,
dap_http_client_simple_callback_error_t a_error_callback, void *a_obj, void * a_custom)
void* dap_http_client_simple_request(const char * a_url, const char * a_method, const char* a_request_content_type, void *a_request, size_t a_request_size, char * a_cookie, dap_http_client_simple_callback_data_t a_response_callback,
dap_http_client_simple_callback_error_t a_error_callback, long *curl_sockfd, void *a_obj, void * a_custom)
{
char *a_custom_new[1];
size_t a_custom_count = 0;
@@ -222,8 +366,8 @@ void dap_http_client_simple_request(const char * a_url, const char * a_method, c
if(a_custom)
a_custom_count = 1;
dap_http_client_simple_request_custom(a_url, a_method, a_request_content_type, a_request, a_request_size,
a_cookie, a_response_callback, a_error_callback, a_obj, a_custom_new, a_custom_count);
return dap_http_client_simple_request_custom(a_url, a_method, a_request_content_type, a_request, a_request_size,
a_cookie, a_response_callback, a_error_callback, curl_sockfd, a_obj, a_custom_new, a_custom_count);
}
/**
@@ -428,9 +572,12 @@ static void* dap_http_client_thread(void * arg)
else {
log_it(L_CRITICAL, "Can't get private information from libcurl handle to perform the reply to SAP connection");
}
// del active connection from list
dap_http_client_del_active_conn(e, NULL);
curl_multi_remove_handle(m_curl_mh, e);
curl_easy_cleanup(e);
}
} while(m);
Loading