#c #httpserver #libevent
Вопрос:
Я разработал http-сервер (rest api) на C с использованием события lib.
Сервер получает http-запросы и отвечает на них, а также выполняет некоторые https-запросы к внешнему rest api. HTTP-запросы, выполняемые к внешнему api и http-серверу, используют одну и ту же базу событий.
Все работает нормально до тех пор, пока случайно обратный вызов, на который я получаю запросы, не прекратится. События таймера событий lib работают, потому что у меня тоже работает таймер, и выполняется обратный вызов таймера, только обратный вызов http-сервера перестает выполняться случайным образом.
После того, как я перезапущу программу, все снова начнет работать нормально.
API работает в ubuntu server 18.04, а версия libevent-2.1.6.
Кое — что из моего кода:
rest_api_t *rest_api_new(
int port,
rest_api_request_t *reqs,
unsigned reqs_len,
rest_api_authorization_cb *auth_cb,
void *ctx )
{
//evthread_use_pthreads( );
rest_api_t *api = calloc( 1, sizeof (*api) );
api->ctx = ctx;
api->base = event_base_new( );
api->http = evhttp_new( api->base );
api->auth_cb = auth_cb;
api->port = port;
// Add signal to rest api exit
api->exit = evsignal_new( api->base, SIGINT, _rest_api_exit_cb, api->base );
event_add( api->exit, NULL );
// Set requests
api->reqs = calloc( reqs_len, sizeof (*api->reqs) );
size_t reqs_size = (sizeof (rest_api_request_t) * reqs_len);
memcpy( api->reqs, reqs, reqs_size );
api->reqs_len = reqs_len;
// Set allowed methods
evhttp_set_allowed_methods( api->http,
EVHTTP_REQ_GET |
EVHTTP_REQ_POST |
EVHTTP_REQ_PATCH |
EVHTTP_REQ_DELETE |
EVHTTP_REQ_OPTIONS );
// Set buffer event callback
evhttp_set_bevcb( api->http, bufferevent_cb, NULL );
// Set requests callback
evhttp_set_gencb( api->http, _rest_api_request_cb, api );
// Set default unauthorized message
rest_api_unauthorized_msg_set( api, HTTP_UNAUTHORIZED_MSG );
return api;
}
static
void _rest_api_request_cb( struct evhttp_request *request, void *arg )
{
const enum evhttp_cmd_type http_cmd = evhttp_request_get_command( request );
const char *cmd = _http_cmd_str( http_cmd );
const char *uri = evhttp_request_get_uri( request );
log_info( "%s %s", cmd ,uri );
if ( http_cmd == EVHTTP_REQ_OPTIONS )
{
_rest_api_preflight_options_handle( request );
}
else
{
rest_api_t *api = arg;
_rest_api_request_dispatch( request, api );
}
}
bool rest_api_run( rest_api_t *api )
{
int rc = -1;
struct evhttp_bound_socket *handle = NULL;
handle = evhttp_bind_socket_with_handle( api->http, "0.0.0.0", api->port );
if ( handle != NULL )
rc = event_base_dispatch( api->base );
return ( rc >= 0 );
}
void rest_api_free( rest_api_t *api )
{
if ( api != NULL )
{
event_free( api->exit );
SSL_CTX_free( api->ssl );
evhttp_free( api->http );
event_base_free( api->base );
free( api->reqs );
free( api );
}
}
Кто-нибудь знает об этой проблеме или о том, как ее решить?