@@ -399,7 +399,7 @@ static inline int get_easy_status(CURL *handle, CURLM *multi, CURLcode *code)
399
399
return -1 ;
400
400
}
401
401
402
- static int init_transfer (CURL * handle , char * url )
402
+ static int init_transfer (CURL * handle , char * url , unsigned long timeout_s )
403
403
{
404
404
CURLcode rc ;
405
405
@@ -414,8 +414,10 @@ static int init_transfer(CURL *handle, char *url)
414
414
tls_dom = NULL ;
415
415
}
416
416
417
- w_curl_easy_setopt (handle , CURLOPT_CONNECTTIMEOUT , connection_timeout );
418
- w_curl_easy_setopt (handle , CURLOPT_TIMEOUT , curl_timeout );
417
+ w_curl_easy_setopt (handle , CURLOPT_CONNECTTIMEOUT ,
418
+ timeout_s && timeout_s < connection_timeout ? timeout_s : connection_timeout );
419
+ w_curl_easy_setopt (handle , CURLOPT_TIMEOUT ,
420
+ timeout_s && timeout_s < curl_timeout ? timeout_s : curl_timeout );
419
421
420
422
w_curl_easy_setopt (handle , CURLOPT_VERBOSE , 1 );
421
423
w_curl_easy_setopt (handle , CURLOPT_STDERR , stdout );
@@ -702,7 +704,7 @@ int rest_sync_transfer(enum rest_client_method method, struct sip_msg *msg,
702
704
str st = STR_NULL , res_body = STR_NULL , tbody , ttype ;
703
705
704
706
curl_easy_reset (sync_handle );
705
- if (init_transfer (sync_handle , url ) != 0 ) {
707
+ if (init_transfer (sync_handle , url , 0 ) != 0 ) {
706
708
LM_ERR ("failed to init transfer to %s\n" , url );
707
709
goto cleanup ;
708
710
}
@@ -802,7 +804,7 @@ int rest_sync_transfer(enum rest_client_method method, struct sip_msg *msg,
802
804
* @url: HTTP URL to be queried
803
805
* @req_body: Body of the request (NULL if not needed)
804
806
* @req_ctype: Value for the "Content-Type: " header of the request (same as ^)
805
- * @async_parm: output param, will contain async handles
807
+ * @async_parm: in/out param, will contain async handles
806
808
* @body: reply body; gradually reallocated as data arrives
807
809
* @ctype: will eventually hold the last "Content-Type" header of the reply
808
810
* @out_fd: the fd to poll on, or a negative error code
@@ -819,7 +821,7 @@ int start_async_http_req(struct sip_msg *msg, enum rest_client_method method,
819
821
CURLMcode mrc ;
820
822
fd_set rset , wset , eset ;
821
823
int max_fd , fd , http_rc , ret = RCL_INTERNAL_ERR ;
822
- long busy_wait , timeout ;
824
+ long busy_wait , timeout , connect_timeout ;
823
825
long retry_time ;
824
826
OSS_CURLM * multi_list ;
825
827
CURLM * multi_handle ;
@@ -835,7 +837,7 @@ int start_async_http_req(struct sip_msg *msg, enum rest_client_method method,
835
837
goto cleanup ;
836
838
}
837
839
838
- if (init_transfer (handle , url ) != 0 ) {
840
+ if (init_transfer (handle , url , async_parm -> timeout_s ) != 0 ) {
839
841
LM_ERR ("failed to init transfer to %s\n" , url );
840
842
goto cleanup ;
841
843
}
@@ -889,18 +891,27 @@ int start_async_http_req(struct sip_msg *msg, enum rest_client_method method,
889
891
multi_handle = multi_list -> multi_handle ;
890
892
curl_multi_add_handle (multi_handle , handle );
891
893
892
- timeout = connection_timeout_ms ;
894
+ connect_timeout = (async_parm -> timeout_s * 1000 ) < connection_timeout_ms ?
895
+ (async_parm -> timeout_s * 1000 ) : connection_timeout_ms ;
896
+ timeout = connect_timeout ;
893
897
busy_wait = connect_poll_interval ;
894
898
895
899
/* obtain a read fd in "connection_timeout" seconds at worst */
896
- for (timeout = connection_timeout_ms ; timeout > 0 ; timeout -= busy_wait ) {
900
+ for (timeout = connect_timeout ; timeout > 0 ; timeout -= busy_wait ) {
901
+ curl_off_t connect = -1 ;
902
+ long req_sz = -1 ;
903
+
897
904
mrc = curl_multi_perform (multi_handle , & running_handles );
898
905
if (mrc != CURLM_OK && mrc != CURLM_CALL_MULTI_PERFORM ) {
899
906
LM_ERR ("curl_multi_perform: %s\n" , curl_multi_strerror (mrc ));
900
907
goto error ;
901
908
}
902
909
903
- LM_DBG ("perform code: %d, handles: %d\n" , mrc , running_handles );
910
+ curl_easy_getinfo (handle , CURLINFO_CONNECT_TIME_T , & connect );
911
+ curl_easy_getinfo (handle , CURLINFO_REQUEST_SIZE , & req_sz );
912
+
913
+ LM_DBG ("perform code: %d, handles: %d, connect: %ldµs, reqsz: %ldB\n" ,
914
+ mrc , running_handles , connect , req_sz );
904
915
905
916
/* transfer completed! But how well? */
906
917
if (running_handles == 0 ) {
@@ -923,8 +934,8 @@ int start_async_http_req(struct sip_msg *msg, enum rest_client_method method,
923
934
924
935
case CURLE_OPERATION_TIMEDOUT :
925
936
if (http_rc == 0 ) {
926
- LM_ERR ("connect timeout on %s (%lds )\n" , url ,
927
- connection_timeout );
937
+ LM_ERR ("connect timeout on %s (%ldms )\n" , url ,
938
+ connect_timeout );
928
939
ret = RCL_CONNECT_TIMEOUT ;
929
940
goto error ;
930
941
}
@@ -962,9 +973,8 @@ int start_async_http_req(struct sip_msg *msg, enum rest_client_method method,
962
973
if (max_fd != -1 ) {
963
974
for (fd = 0 ; fd <= max_fd ; fd ++ ) {
964
975
if (FD_ISSET (fd , & rset )) {
965
-
966
976
LM_DBG ("ongoing transfer on fd %d\n" , fd );
967
- if (is_new_transfer (fd )) {
977
+ if (connect > 0 && req_sz > 0 && is_new_transfer (fd )) {
968
978
LM_DBG (">>> add fd %d to ongoing transfers\n" , fd );
969
979
add_transfer (fd );
970
980
goto success ;
@@ -981,7 +991,7 @@ int start_async_http_req(struct sip_msg *msg, enum rest_client_method method,
981
991
982
992
LM_DBG ("libcurl TCP connect: we should wait up to %ldms "
983
993
"(timeout=%ldms, poll=%ldms)!\n" , retry_time ,
984
- connection_timeout_ms , connect_poll_interval );
994
+ connect_timeout , connect_poll_interval );
985
995
986
996
/*
987
997
from curl_multi_timeout() docs:
@@ -1055,8 +1065,8 @@ static enum async_ret_code _resume_async_http_req(int fd, struct sip_msg *msg,
1055
1065
if (timed_out ) {
1056
1066
char * url = NULL ;
1057
1067
curl_easy_getinfo (param -> handle , CURLINFO_EFFECTIVE_URL , & url );
1058
- LM_ERR ("async %s timed out, URL: %s\n" ,
1059
- rest_client_method_str (param -> method ), url );
1068
+ LM_ERR ("async %s timed out, URL: %s (timeout: %lds) \n" ,
1069
+ rest_client_method_str (param -> method ), url , param -> timeout_s );
1060
1070
goto cleanup ;
1061
1071
}
1062
1072
@@ -1069,10 +1079,12 @@ static enum async_ret_code _resume_async_http_req(int fd, struct sip_msg *msg,
1069
1079
LM_DBG ("perform result: %d, running: %d (break: %d)\n" , mrc , running ,
1070
1080
mrc != CURLM_CALL_MULTI_PERFORM && (mrc != CURLM_OK || !running ));
1071
1081
1072
- if (mrc == CURLM_OK && running ) {
1082
+ if (mrc == CURLM_OK ) {
1083
+ if (!running )
1084
+ break ;
1085
+
1073
1086
async_status = ASYNC_CONTINUE ;
1074
1087
return 1 ;
1075
-
1076
1088
/* this rc has been removed since cURL 7.20.0 (Feb 2010), but it's not
1077
1089
* yet marked as deprecated, so let's keep the do/while loop */
1078
1090
} else if (mrc != CURLM_CALL_MULTI_PERFORM ) {
0 commit comments