Skip to content

Commit

Permalink
rest_client: Fix handling for async timeouts
Browse files Browse the repository at this point in the history
This patch improves all rest_client async operations such that they
now correctly time out after the minimum between:

* the "rest_client.curl_timeout" modparam (seconds)
* the async() statement timeout, if any (seconds)

Credits to Bence Szigeti for helping diagnose and fix the issue
  • Loading branch information
liviuchircu committed Dec 11, 2023
1 parent 03db368 commit 1ea1852
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
1 change: 1 addition & 0 deletions modules/rest_client/rest_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ int async_rest_method(enum rest_client_method method, struct sip_msg *msg,
rcl_release_url(host, rc == RCL_OK);

ctx->resume_f = resume_async_http_req;
ctx->timeout_s = curl_timeout;
ctx->timeout_f = time_out_async_http_req;

param->method = method;
Expand Down
20 changes: 17 additions & 3 deletions modules/rest_client/rest_methods.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,14 @@ static enum async_ret_code _resume_async_http_req(int fd, struct sip_msg *msg,

multi_handle = param->multi_list->multi_handle;

if (timed_out) {
char *url = NULL;
curl_easy_getinfo(param->handle, CURLINFO_EFFECTIVE_URL, &url);
LM_INFO("async %s timed out, URL: %s\n",
rest_client_method_str(param->method), url);
goto cleanup;
}

retr = 0;
do {
/* When @enable_expect_100 is on, both the client body upload and the
Expand All @@ -1061,9 +1069,15 @@ static enum async_ret_code _resume_async_http_req(int fd, struct sip_msg *msg,
LM_DBG("perform result: %d, running: %d (break: %d)\n", mrc, running,
mrc != CURLM_CALL_MULTI_PERFORM && (mrc != CURLM_OK || !running));

if (mrc != CURLM_CALL_MULTI_PERFORM &&
(mrc != CURLM_OK || !running))
if (mrc == CURLM_OK && running) {
async_status = ASYNC_CONTINUE;
return 1;

/* this rc has been removed since cURL 7.20.0 (Feb 2010), but it's not
* yet marked as deprecated, so let's keep the do/while loop */
} else if (mrc != CURLM_CALL_MULTI_PERFORM) {
break;
}

usleep(_async_resume_retr_itv);
retr += _async_resume_retr_itv;
Expand Down Expand Up @@ -1106,6 +1120,7 @@ static enum async_ret_code _resume_async_http_req(int fd, struct sip_msg *msg,
return 1;
}

cleanup:
curl_slist_free_all(param->header_list);

if (del_transfer(fd) != 0) {
Expand Down Expand Up @@ -1203,7 +1218,6 @@ enum async_ret_code resume_async_http_req(int fd, struct sip_msg *msg, void *_pa

enum async_ret_code time_out_async_http_req(int fd, struct sip_msg *msg, void *_param)
{
LM_INFO("transfer timed out (async statement timeout)\n");
return _resume_async_http_req(fd, msg, (rest_async_param *)_param, 1);
}

Expand Down
3 changes: 3 additions & 0 deletions modules/rest_client/rest_methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ enum rest_client_method {
REST_CLIENT_PUT,
REST_CLIENT_POST
};
#define rest_client_method_str(_m) ( \
(_m) == REST_CLIENT_GET ? "GET" : \
(_m) == REST_CLIENT_POST ? "POST" : "PUT")

/* return codes for rest_client script functions */
#define RCL_OK_LOCKED 2
Expand Down

0 comments on commit 1ea1852

Please sign in to comment.