Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cellframe/libdap-server
1 result
Show changes
Commits on Source (3)
......@@ -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);
......
......@@ -15,15 +15,17 @@ typedef struct dap_http_client_simple {
int dap_http_client_simple_init( );
void dap_http_client_simple_deinit( );
void dap_http_client_simple_request_custom( const char * a_url, const char * a_method,
void dap_http_client_simple_request_break(long a_curl_sock);
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 );
void dap_http_client_simple_request( const char *a_url, const char * a_method,
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 );
dap_http_client_simple_callback_error_t a_error_callback, long *curl_sockfd, void *a_obj, void *a_custom );
#endif