Hi all!
still struggling with Async HTTP Client ... My current configuration is very simple:
#!define HTTP_API_ROUTING_ENDPOINT_MAIN " http://MY_HTTP_REST_API:18085/Endpoint" include_file "listen.cfg"
loadmodule "pv" loadmodule "tm" loadmodule "http_async_client" loadmodule "xlog" loadmodule "tmx" loadmodule "sl" loadmodule "textops" loadmodule "cfgutils" loadmodule "siputils" loadmodule "rr" loadmodule "ctl" loadmodule "jsonrpcs.so" loadmodule "jansson.so"
modparam("pv", "shvset", "http_async=i:8"); modparam("http_async_client", "workers", 1); modparam("http_async_client", "connection_timeout", 500) modparam("http_async_client", "curl_verbose", 1) # for debug purpose
#modparam("tm", "fr_timer", 750) #modparam("tm", "fr_inv_timer", 20000) #modparam("tm", "remap_503_500", 0) modparam("tm", "failure_reply_mode", 3) modparam("tm", "max_inv_lifetime",5000)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
debug=2 children=16 log_facility=LOG_LOCAL0 log_prefix="{$mt $hdr(CSeq) $ci} " disable_sctp = yes force_rport = yes rundir="/tmp"
request_route {
$avp(REQUEST_URL) = HTTP_API_ROUTING_ENDPOINT_MAIN;
if ( is_method("ACK") ) { if ( t_check_trans() ) { t_relay(); } exit; }
if(is_method("OPTIONS")){ sl_reply("200", "OK"); exit; }
if(is_method("CANCEL")){ sl_reply("200","OK"); sl_reply("487","Request Terminated"); exit; }
jansson_set("string","from" , $hdr(From) , "$var(req)"); jansson_set("string","to" , $hdr(To) , "$var(req)"); jansson_set("string","r-uri" , $ru , "$var(req)"); jansson_set("string","contact" , $hdr(Contact) , "$var(req)"); jansson_set("string","call-id" , $ci , "$var(req)");
xinfo("MAIN-ROUTE - Setting From=$hdr(From) To=$hdr(To) Contact=$hdr(Contact) ci=$ci \n");
if ( is_present_hf("Identity") ) jansson_set("string","identity" , $hdr(Identity) , "$var(req)");
if ( is_present_hf("P-Identity-Bypass") ) jansson_set("string","p-identity-bypass" , $hdr(P-Identity-Bypass) , "$var(req)");
if ( is_present_hf("P-Asserted-Identity") ) jansson_set("string","p-asserted-identity" , $hdr(P-Asserted-Identity) , "$var(req)");
if ( is_present_hf("P-STSH-UC") ) jansson_set("string","p-stsh-uc" , $hdr(P-STSH-UC) , "$var(req)"); jansson_set("string", "request-time" , $avp(requestTime), "$var(req)");
## Create transaction before http_async_query; if (is_method("INVITE")){ t_newtran(); xinfo("MAIN-ROUTE - Sending request [$var(req)]\n"); route(HTTP_ASYNC_REQUEST); } exit; }
route[HTTP_ASYNC_REQUEST] { xinfo("HTTP_ASYNC_REQUEST - Sending request [$var(req)]\n");
$http_req(all) = $null; $http_req(suspend) = 1; $http_req(timeout) = 1500; # 1 second timeout $http_req(method) = "POST"; $http_req(hdr) = "Content-Type: application/json"; $http_req(body) = $var(req);
if ( !http_async_query($avp(REQUEST_URL), "HTTP_REPLY") ) { xinfo("HTTP_ASYNC_REQUEST - http_async_query $ci FAILED. Return is [$rc]\n"); }else{ send_reply("503", "Server Error"); exit; } }
route[HTTP_REPLY] { xinfo("HTTP_REPLY - Xphere Response Code $http_rs - $ci\n");
if ( $http_ok && $http_rs==200) { xinfo("HTTP_REPLY - $ci reply ok\n"); jansson_xdecode($http_rb, "json"); xinfo("HTTP_REPLY - HTTP JSON Response: $http_rb \n");
if ( $xavp(json=>sip-response-code) == 300 ){ remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); ## "touch" the ruri to add the contact header for 3xx: $ru = $ru; send_reply("300", "Multiple Choice"); exit; }else{ xinfo("HTTP_REPLY - $ci Error Replied $xavp(json=>sip-response-code) - $xavp(json=>sip-response-text) \n");
send_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; }
} else { xinfo("HTTP_REPLY - HTTP Response Code $ci - $http_rs and error $http_err \n"); if (!$http_ok){ sl_reply("503", "No Connection to HTTP"); exit; }else if ($http_rs>=500){ sl_reply("503", "HTTP Processing Error"); exit; } else{ sl_reply("503", "Cannot Connect to HTTP"); exit; } } exit; }
The configuration is based on Ben Kaufman's kamailio_http_async https://github.com/whosgonna/kamailio_http_async example, but I have extended it a bit. Currently all the requests are being sent to the HTTP REST API. I can't find queue/buffering issues...
What I am experiencing is that , using SNGREP, I get this flow:
10.240.12.209:5060 10.242.17.146:5060 ----------*---------- ----------*---------- 17:33:46.689852 x INVITE (SDP) x +0.000530 x --------------------------> x 17:33:46.690382 x 100 trying -- your call is x +1.499822 x <-------------------------- x 17:33:48.190204 x 503 No Connection to HTTP x +0.000029 x <-------------------------- x 17:33:48.190233 x 500 I'm terribly sorry, se x +0.002130 x <-------------------------- x 17:33:48.192363 x ACK x +0.485836 x --------------------------> x 17:33:48.678199 x 500 I'm terribly sorry, se x +0.004881 x <<<------------------------ x 17:33:48.683080 x ACK x +0.973295 x ------------------------>>> x 17:33:49.656375 x 500 I'm terribly sorry, se x +0.004105 x <<<------------------------ x 17:33:49.660480 x ACK x +1.995420 x ------------------------>>> x 17:33:51.655900 x 500 I'm terribly sorry, se x +0.005361 x <<<-------------------------x 17:33:51.661261 x ACK x x ------------------------>>> x
I suspected issues with the HTTP REST service, but when using tcpdump, I can find the Request from Kamailio and a reply back from the REST API service, so doesn't seem to be a problem on the HTTP REST service So my questions are: - why is Kamailio sending a "SIP 500 I'm terribly sorry..." error after a 503 No Connection to HTTP is sent and an "exit" command is executed? - how can I get rid of these messages? - Why Kamailio keeps sending responses back to SBC after the ACK when it is set to just "exit"? - Why is Kamailio not processing the response from HTTP REST API when it is correctly received?
Logs are also weird: - I find a lot of these warnings: "Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: WARNING: http_async_client [http_async_client_mod.c:529]: ah_get_status(): an async variable was read after http error, use $http_ok to check the request's status" and "Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: ERROR: http_async_client [http_multi.c:621]: check_multi_info(): handle 0x7f375f786b30 returned error 7:"
(I am still not using EVAPI module, that will be my next step, after the holiday season) (I suspect, however, that the REST API is not being able to handle the load in this test environment (between 400 to 600 CAPS), but that is another matter.) In attach, TCPDUMP, if anyone wishes to analyse.
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
(resending, without attachment, as OP is more than 250kb size and awaits for moderator's approval)
Hi all!
still struggling with Async HTTP Client ... My current configuration is very simple:
#!define HTTP_API_ROUTING_ENDPOINT_MAIN " http://MY_HTTP_REST_API:18085/Endpoint" include_file "listen.cfg"
loadmodule "pv" loadmodule "tm" loadmodule "http_async_client" loadmodule "xlog" loadmodule "tmx" loadmodule "sl" loadmodule "textops" loadmodule "cfgutils" loadmodule "siputils" loadmodule "rr" loadmodule "ctl" loadmodule "jsonrpcs.so" loadmodule "jansson.so"
modparam("pv", "shvset", "http_async=i:8"); modparam("http_async_client", "workers", 1); modparam("http_async_client", "connection_timeout", 500) modparam("http_async_client", "curl_verbose", 1) # for debug purpose
#modparam("tm", "fr_timer", 750) #modparam("tm", "fr_inv_timer", 20000) #modparam("tm", "remap_503_500", 0) modparam("tm", "failure_reply_mode", 3) modparam("tm", "max_inv_lifetime",5000)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
debug=2 children=16 log_facility=LOG_LOCAL0 log_prefix="{$mt $hdr(CSeq) $ci} " disable_sctp = yes force_rport = yes rundir="/tmp"
request_route {
$avp(REQUEST_URL) = HTTP_API_ROUTING_ENDPOINT_MAIN;
if ( is_method("ACK") ) { if ( t_check_trans() ) { t_relay(); } exit; }
if(is_method("OPTIONS")){ sl_reply("200", "OK"); exit; }
if(is_method("CANCEL")){ sl_reply("200","OK"); sl_reply("487","Request Terminated"); exit; }
jansson_set("string","from" , $hdr(From) , "$var(req)"); jansson_set("string","to" , $hdr(To) , "$var(req)"); jansson_set("string","r-uri" , $ru , "$var(req)"); jansson_set("string","contact" , $hdr(Contact) , "$var(req)"); jansson_set("string","call-id" , $ci , "$var(req)");
xinfo("MAIN-ROUTE - Setting From=$hdr(From) To=$hdr(To) Contact=$hdr(Contact) ci=$ci \n");
if ( is_present_hf("Identity") ) jansson_set("string","identity" , $hdr(Identity) , "$var(req)");
if ( is_present_hf("P-Identity-Bypass") ) jansson_set("string","p-identity-bypass" , $hdr(P-Identity-Bypass) , "$var(req)");
if ( is_present_hf("P-Asserted-Identity") ) jansson_set("string","p-asserted-identity" , $hdr(P-Asserted-Identity) , "$var(req)");
if ( is_present_hf("P-STSH-UC") ) jansson_set("string","p-stsh-uc" , $hdr(P-STSH-UC) , "$var(req)"); jansson_set("string", "request-time" , $avp(requestTime), "$var(req)");
## Create transaction before http_async_query; if (is_method("INVITE")){ t_newtran(); xinfo("MAIN-ROUTE - Sending request [$var(req)]\n"); route(HTTP_ASYNC_REQUEST); } exit; }
route[HTTP_ASYNC_REQUEST] { xinfo("HTTP_ASYNC_REQUEST - Sending request [$var(req)]\n");
$http_req(all) = $null; $http_req(suspend) = 1; $http_req(timeout) = 1500; # 1 second timeout $http_req(method) = "POST"; $http_req(hdr) = "Content-Type: application/json"; $http_req(body) = $var(req);
if ( !http_async_query($avp(REQUEST_URL), "HTTP_REPLY") ) { xinfo("HTTP_ASYNC_REQUEST - http_async_query $ci FAILED. Return is [$rc]\n"); }else{ send_reply("503", "Server Error"); exit; } }
route[HTTP_REPLY] { xinfo("HTTP_REPLY - Xphere Response Code $http_rs - $ci\n");
if ( $http_ok && $http_rs==200) { xinfo("HTTP_REPLY - $ci reply ok\n"); jansson_xdecode($http_rb, "json"); xinfo("HTTP_REPLY - HTTP JSON Response: $http_rb \n");
if ( $xavp(json=>sip-response-code) == 300 ){ remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); ## "touch" the ruri to add the contact header for 3xx: $ru = $ru; send_reply("300", "Multiple Choice"); exit; }else{ xinfo("HTTP_REPLY - $ci Error Replied $xavp(json=>sip-response-code) - $xavp(json=>sip-response-text) \n");
send_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; }
} else { xinfo("HTTP_REPLY - HTTP Response Code $ci - $http_rs and error $http_err \n"); if (!$http_ok){ sl_reply("503", "No Connection to HTTP"); exit; }else if ($http_rs>=500){ sl_reply("503", "HTTP Processing Error"); exit; } else{ sl_reply("503", "Cannot Connect to HTTP"); exit; } } exit; }
The configuration is based on Ben Kaufman's kamailio_http_async https://github.com/whosgonna/kamailio_http_async example, but I have extended it a bit. Currently all the requests are being sent to the HTTP REST API. I can't find queue/buffering issues...
What I am experiencing is that , using SNGREP, I get this flow:
10.240.12.209:5060 10.242.17.146:5060 ----------*---------- ----------*---------- 17:33:46.689852 x INVITE (SDP) x +0.000530 x --------------------------> x 17:33:46.690382 x 100 trying -- your call is x +1.499822 x <-------------------------- x 17:33:48.190204 x 503 No Connection to HTTP x +0.000029 x <-------------------------- x 17:33:48.190233 x 500 I'm terribly sorry, se x +0.002130 x <-------------------------- x 17:33:48.192363 x ACK x +0.485836 x --------------------------> x 17:33:48.678199 x 500 I'm terribly sorry, se x +0.004881 x <<<------------------------ x 17:33:48.683080 x ACK x +0.973295 x ------------------------>>> x 17:33:49.656375 x 500 I'm terribly sorry, se x +0.004105 x <<<------------------------ x 17:33:49.660480 x ACK x +1.995420 x ------------------------>>> x 17:33:51.655900 x 500 I'm terribly sorry, se x +0.005361 x <<<-------------------------x 17:33:51.661261 x ACK x x ------------------------>>> x
I suspected issues with the HTTP REST service, but when using tcpdump, I can find the Request from Kamailio and a reply back from the REST API service, so doesn't seem to be a problem on the HTTP REST service So my questions are: - why is Kamailio sending a "SIP 500 I'm terribly sorry..." error after a 503 No Connection to HTTP is sent and an "exit" command is executed? - how can I get rid of these messages? - Why Kamailio keeps sending responses back to SBC after the ACK when it is set to just "exit"? - Why is Kamailio not processing the response from HTTP REST API when it is correctly received?
Logs are also weird: - I find a lot of these warnings: "Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: WARNING: http_async_client [http_async_client_mod.c:529]: ah_get_status(): an async variable was read after http error, use $http_ok to check the request's status" and "Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: ERROR: http_async_client [http_multi.c:621]: check_multi_info(): handle 0x7f375f786b30 returned error 7:"
(I am still not using EVAPI module, that will be my next step, after the holiday season) (I suspect, however, that the REST API is not being able to handle the load in this test environment (between 400 to 600 CAPS), but that is another matter.)
I can send the TCPDUMP, if anyone wishes to analyze.
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
Hi Sergio,
Try using t_reply() / send_reply() in your route[HTTP_REPLY]. There is transaction state, so the transaction state machine needs to be informed of the dispositive reply.
-- Alex
On Dec 29, 2024, at 1:08 pm, Sergio Charrua via sr-users sr-users@lists.kamailio.org wrote:
(resending, without attachment, as OP is more than 250kb size and awaits for moderator's approval)
Hi all!
still struggling with Async HTTP Client ... My current configuration is very simple:
#!define HTTP_API_ROUTING_ENDPOINT_MAIN "http://MY_HTTP_REST_API:18085/Endpoint" include_file "listen.cfg"
loadmodule "pv" loadmodule "tm" loadmodule "http_async_client" loadmodule "xlog" loadmodule "tmx" loadmodule "sl" loadmodule "textops" loadmodule "cfgutils" loadmodule "siputils" loadmodule "rr" loadmodule "ctl" loadmodule "jsonrpcs.so" loadmodule "jansson.so"
modparam("pv", "shvset", "http_async=i:8"); modparam("http_async_client", "workers", 1); modparam("http_async_client", "connection_timeout", 500) modparam("http_async_client", "curl_verbose", 1) # for debug purpose
#modparam("tm", "fr_timer", 750) #modparam("tm", "fr_inv_timer", 20000) #modparam("tm", "remap_503_500", 0) modparam("tm", "failure_reply_mode", 3) modparam("tm", "max_inv_lifetime",5000)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
debug=2 children=16 log_facility=LOG_LOCAL0 log_prefix="{$mt $hdr(CSeq) $ci} " disable_sctp = yes force_rport = yes rundir="/tmp"
request_route {
$avp(REQUEST_URL) = HTTP_API_ROUTING_ENDPOINT_MAIN; if ( is_method("ACK") ) { if ( t_check_trans() ) { t_relay(); } exit; } if(is_method("OPTIONS")){ sl_reply("200", "OK"); exit; } if(is_method("CANCEL")){ sl_reply("200","OK"); sl_reply("487","Request Terminated"); exit; } jansson_set("string","from" , $hdr(From) , "$var(req)"); jansson_set("string","to" , $hdr(To) , "$var(req)"); jansson_set("string","r-uri" , $ru , "$var(req)"); jansson_set("string","contact" , $hdr(Contact) , "$var(req)"); jansson_set("string","call-id" , $ci , "$var(req)"); xinfo("MAIN-ROUTE - Setting From=$hdr(From) To=$hdr(To) Contact=$hdr(Contact) ci=$ci \n"); if ( is_present_hf("Identity") ) jansson_set("string","identity" , $hdr(Identity) , "$var(req)"); if ( is_present_hf("P-Identity-Bypass") ) jansson_set("string","p-identity-bypass" , $hdr(P-Identity-Bypass) , "$var(req)"); if ( is_present_hf("P-Asserted-Identity") ) jansson_set("string","p-asserted-identity" , $hdr(P-Asserted-Identity) , "$var(req)"); if ( is_present_hf("P-STSH-UC") ) jansson_set("string","p-stsh-uc" , $hdr(P-STSH-UC) , "$var(req)"); jansson_set("string", "request-time" , $avp(requestTime), "$var(req)"); ## Create transaction before http_async_query; if (is_method("INVITE")){ t_newtran(); xinfo("MAIN-ROUTE - Sending request [$var(req)]\n"); route(HTTP_ASYNC_REQUEST); } exit;
}
route[HTTP_ASYNC_REQUEST] { xinfo("HTTP_ASYNC_REQUEST - Sending request [$var(req)]\n");
$http_req(all) = $null; $http_req(suspend) = 1; $http_req(timeout) = 1500; # 1 second timeout $http_req(method) = "POST"; $http_req(hdr) = "Content-Type: application/json"; $http_req(body) = $var(req); if ( !http_async_query($avp(REQUEST_URL), "HTTP_REPLY") ) { xinfo("HTTP_ASYNC_REQUEST - http_async_query $ci FAILED. Return is [$rc]\n"); }else{ send_reply("503", "Server Error"); exit; }
}
route[HTTP_REPLY] { xinfo("HTTP_REPLY - Xphere Response Code $http_rs - $ci\n");
if ( $http_ok && $http_rs==200) { xinfo("HTTP_REPLY - $ci reply ok\n"); jansson_xdecode($http_rb, "json"); xinfo("HTTP_REPLY - HTTP JSON Response: $http_rb \n"); if ( $xavp(json=>sip-response-code) == 300 ){ remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); ## "touch" the ruri to add the contact header for 3xx: $ru = $ru; send_reply("300", "Multiple Choice"); exit; }else{ xinfo("HTTP_REPLY - $ci Error Replied $xavp(json=>sip-response-code) - $xavp(json=>sip-response-text) \n"); send_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } } else { xinfo("HTTP_REPLY - HTTP Response Code $ci - $http_rs and error $http_err \n"); if (!$http_ok){ sl_reply("503", "No Connection to HTTP"); exit; }else if ($http_rs>=500){ sl_reply("503", "HTTP Processing Error"); exit; } else{ sl_reply("503", "Cannot Connect to HTTP"); exit; } } exit;
}
The configuration is based on Ben Kaufman's kamailio_http_async example, but I have extended it a bit. Currently all the requests are being sent to the HTTP REST API. I can't find queue/buffering issues...
What I am experiencing is that , using SNGREP, I get this flow:
10.240.12.209:5060 10.242.17.146:5060 ----------*---------- ----------*----------
17:33:46.689852 x INVITE (SDP) x +0.000530 x --------------------------> x 17:33:46.690382 x 100 trying -- your call is x +1.499822 x <-------------------------- x 17:33:48.190204 x 503 No Connection to HTTP x +0.000029 x <-------------------------- x 17:33:48.190233 x 500 I'm terribly sorry, se x +0.002130 x <-------------------------- x 17:33:48.192363 x ACK x +0.485836 x --------------------------> x 17:33:48.678199 x 500 I'm terribly sorry, se x +0.004881 x <<<------------------------ x 17:33:48.683080 x ACK x +0.973295 x ------------------------>>> x 17:33:49.656375 x 500 I'm terribly sorry, se x +0.004105 x <<<------------------------ x 17:33:49.660480 x ACK x +1.995420 x ------------------------>>> x 17:33:51.655900 x 500 I'm terribly sorry, se x +0.005361 x <<<-------------------------x 17:33:51.661261 x ACK x x ------------------------>>> x I suspected issues with the HTTP REST service, but when using tcpdump, I can find the Request from Kamailio and a reply back from the REST API service, so doesn't seem to be a problem on the HTTP REST service So my questions are:
- why is Kamailio sending a "SIP 500 I'm terribly sorry..." error after a 503 No Connection to HTTP is sent and an "exit" command is executed?
- how can I get rid of these messages?
- Why Kamailio keeps sending responses back to SBC after the ACK when it is set to just "exit"?
- Why is Kamailio not processing the response from HTTP REST API when it is correctly received?
Logs are also weird:
- I find a lot of these warnings:
"Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: WARNING: http_async_client [http_async_client_mod.c:529]: ah_get_status(): an async variable was read after http error, use $http_ok to check the request's status" and "Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: ERROR: http_async_client [http_multi.c:621]: check_multi_info(): handle 0x7f375f786b30 returned error 7:"
(I am still not using EVAPI module, that will be my next step, after the holiday season) (I suspect, however, that the REST API is not being able to handle the load in this test environment (between 400 to 600 CAPS), but that is another matter.)
I can send the TCPDUMP, if anyone wishes to analyze.
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Thanks Alex!
I changed the HTTP_REPLY route to:
route[HTTP_REPLY] { xinfo("HTTP_REPLY - HTTP Response Code $http_rs - $ci\n");
if ( $http_ok && $http_rs==200) { xinfo("HTTP_REPLY - HTTP $ci reply ok\n"); jansson_xdecode($http_rb, "json"); xinfo("HTTP_REPLY - HTTP JSON Response: $http_rb \n");
if ( $xavp(json=>sip-response-code) == 300 ){ remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); ## "touch" the ruri to add the contact header for 3xx: $ru = $ru; t_reply("300", "Multiple Choice"); exit; }else{ xinfo("HTTP_REPLY - HTTP $ci Error Replied $xavp(json=>sip-response-code) - $xavp(json=>sip-response-text) \n");
t_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; }
} else { xinfo("HTTP_REPLY - HTTP Response Code $ci - $http_rs and error $http_err \n"); if (!$http_ok){ t_reply("503", "No Connection to HTTP"); exit; }else if ($http_rs>=500){ t_reply("503", "HTTPProcessing Error"); exit; } else{ t_reply("503", "Cannot Connect to HTTP"); exit; } } exit; }
SIP Flow now show:
10.240.12.209:5060 10.242.17.146:5060 ----------x--------- ----------x--------- 20:11:21.816566 x INVITE (SDP) x +0.000349 x --------------------------> x 20:11:21.816915 x 100 trying -- your call is x +1.502925 x <-------------------------- x 20:11:23.319840 x 503 No Connection to Xpher x +0.002155 x <-------------------------- x 20:11:23.321995 x ACK x x --------------------------> x
Though better, I can't understand why Kamailio returns 503 No Connection to HTTP despite the REST Service having correctly replied with valid data and , according to TCPDump, reply was received on Kamailio....
On logs, I also find:
Dec 29 20:04:42 ire-nprod-sip1 /usr/local/sbin/kamailio[623211]: INFO: <script>: HTTP_REPLY - HTTP Response Code 0gQAAC8WAAACBAAALxYAAF6U9PQuZQx7iuhYTB5JRXhVf72rYXoOERUNmKh6yQKm7Ik0RHuS9skp6z4UGrnDog--@10.240.12.209 - <null> and err or TIMEOUT
I can't understand why $http_rs is "err or TIMEOUT" and $http_ok is <null> when the HTTP REST service did reply correctly .... May there be something that is scrambling the transactions?
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*
On Sun, Dec 29, 2024 at 8:07 PM Alex Balashov via sr-users < sr-users@lists.kamailio.org> wrote:
Hi Sergio,
Try using t_reply() / send_reply() in your route[HTTP_REPLY]. There is transaction state, so the transaction state machine needs to be informed of the dispositive reply.
-- Alex
On Dec 29, 2024, at 1:08 pm, Sergio Charrua via sr-users <
sr-users@lists.kamailio.org> wrote:
(resending, without attachment, as OP is more than 250kb size and awaits
for moderator's approval)
Hi all!
still struggling with Async HTTP Client ... My current configuration is very simple:
#!define HTTP_API_ROUTING_ENDPOINT_MAIN "
http://MY_HTTP_REST_API:18085/Endpoint"
include_file "listen.cfg"
loadmodule "pv" loadmodule "tm" loadmodule "http_async_client" loadmodule "xlog" loadmodule "tmx" loadmodule "sl" loadmodule "textops" loadmodule "cfgutils" loadmodule "siputils" loadmodule "rr" loadmodule "ctl" loadmodule "jsonrpcs.so" loadmodule "jansson.so"
modparam("pv", "shvset", "http_async=i:8"); modparam("http_async_client", "workers", 1); modparam("http_async_client", "connection_timeout", 500) modparam("http_async_client", "curl_verbose", 1) # for debug purpose
#modparam("tm", "fr_timer", 750) #modparam("tm", "fr_inv_timer", 20000) #modparam("tm", "remap_503_500", 0) modparam("tm", "failure_reply_mode", 3) modparam("tm", "max_inv_lifetime",5000)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
debug=2 children=16 log_facility=LOG_LOCAL0 log_prefix="{$mt $hdr(CSeq) $ci} " disable_sctp = yes force_rport = yes rundir="/tmp"
request_route {
$avp(REQUEST_URL) = HTTP_API_ROUTING_ENDPOINT_MAIN; if ( is_method("ACK") ) { if ( t_check_trans() ) { t_relay(); } exit; } if(is_method("OPTIONS")){ sl_reply("200", "OK"); exit; } if(is_method("CANCEL")){ sl_reply("200","OK"); sl_reply("487","Request Terminated"); exit; } jansson_set("string","from" , $hdr(From) , "$var(req)"); jansson_set("string","to" , $hdr(To) , "$var(req)"); jansson_set("string","r-uri" , $ru , "$var(req)"); jansson_set("string","contact" , $hdr(Contact) , "$var(req)"); jansson_set("string","call-id" , $ci , "$var(req)"); xinfo("MAIN-ROUTE - Setting From=$hdr(From) To=$hdr(To)
Contact=$hdr(Contact) ci=$ci \n");
if ( is_present_hf("Identity") ) jansson_set("string","identity" ,
$hdr(Identity) , "$var(req)");
if ( is_present_hf("P-Identity-Bypass") ) jansson_set("string","p-identity-bypass" ,
$hdr(P-Identity-Bypass) , "$var(req)");
if ( is_present_hf("P-Asserted-Identity") ) jansson_set("string","p-asserted-identity" ,
$hdr(P-Asserted-Identity) , "$var(req)");
if ( is_present_hf("P-STSH-UC") ) jansson_set("string","p-stsh-uc" ,
$hdr(P-STSH-UC) , "$var(req)");
jansson_set("string", "request-time" , $avp(requestTime),
"$var(req)");
## Create transaction before http_async_query; if (is_method("INVITE")){ t_newtran(); xinfo("MAIN-ROUTE - Sending request [$var(req)]\n"); route(HTTP_ASYNC_REQUEST); } exit;
}
route[HTTP_ASYNC_REQUEST] { xinfo("HTTP_ASYNC_REQUEST - Sending request [$var(req)]\n");
$http_req(all) = $null; $http_req(suspend) = 1; $http_req(timeout) = 1500; # 1 second timeout $http_req(method) = "POST"; $http_req(hdr) = "Content-Type: application/json"; $http_req(body) = $var(req); if ( !http_async_query($avp(REQUEST_URL), "HTTP_REPLY") ) { xinfo("HTTP_ASYNC_REQUEST - http_async_query $ci FAILED. Return
is [$rc]\n");
}else{ send_reply("503", "Server Error"); exit; }
}
route[HTTP_REPLY] { xinfo("HTTP_REPLY - Xphere Response Code $http_rs - $ci\n");
if ( $http_ok && $http_rs==200) { xinfo("HTTP_REPLY - $ci reply ok\n"); jansson_xdecode($http_rb, "json"); xinfo("HTTP_REPLY - HTTP JSON Response: $http_rb \n"); if ( $xavp(json=>sip-response-code) == 300 ){ remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); ## "touch" the ruri to add the contact header for 3xx: $ru = $ru; send_reply("300", "Multiple Choice"); exit; }else{ xinfo("HTTP_REPLY - $ci Error Replied
$xavp(json=>sip-response-code) - $xavp(json=>sip-response-text) \n");
send_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)");
exit; } } else { xinfo("HTTP_REPLY - HTTP Response Code $ci - $http_rs
and error $http_err \n");
if (!$http_ok){ sl_reply("503", "No Connection to HTTP"); exit; }else if ($http_rs>=500){ sl_reply("503", "HTTP Processing Error"); exit; } else{ sl_reply("503", "Cannot Connect to HTTP"); exit; } } exit;
}
The configuration is based on Ben Kaufman's kamailio_http_async example,
but I have extended it a bit.
Currently all the requests are being sent to the HTTP REST API. I can't
find queue/buffering issues...
What I am experiencing is that , using SNGREP, I get this flow:
10.240.12.209:5060 10.242.17.146:5060
----------*---------- ----------*----------
17:33:46.689852 x INVITE (SDP) x +0.000530 x --------------------------> x 17:33:46.690382 x 100 trying -- your call is x +1.499822 x <-------------------------- x 17:33:48.190204 x 503 No Connection to HTTP x +0.000029 x <-------------------------- x 17:33:48.190233 x 500 I'm terribly sorry, se x +0.002130 x <-------------------------- x 17:33:48.192363 x ACK x +0.485836 x --------------------------> x 17:33:48.678199 x 500 I'm terribly sorry, se x +0.004881 x <<<------------------------ x 17:33:48.683080 x ACK x +0.973295 x ------------------------>>> x 17:33:49.656375 x 500 I'm terribly sorry, se x +0.004105 x <<<------------------------ x 17:33:49.660480 x ACK x +1.995420 x ------------------------>>> x 17:33:51.655900 x 500 I'm terribly sorry, se x +0.005361 x <<<-------------------------x 17:33:51.661261 x ACK x x ------------------------>>> x I suspected issues with the HTTP REST service, but when using tcpdump, I
can find the Request from Kamailio and a reply back from the REST API service, so doesn't seem to be a problem on the HTTP REST service
So my questions are:
- why is Kamailio sending a "SIP 500 I'm terribly sorry..." error after
a 503 No Connection to HTTP is sent and an "exit" command is executed?
- how can I get rid of these messages?
- Why Kamailio keeps sending responses back to SBC after the ACK when it
is set to just "exit"?
- Why is Kamailio not processing the response from HTTP REST API when it
is correctly received?
Logs are also weird:
- I find a lot of these warnings:
"Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]:
WARNING: http_async_client [http_async_client_mod.c:529]: ah_get_status(): an async variable was read after http error, use $http_ok to check the request's status"
and "Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: ERROR:
http_async_client [http_multi.c:621]: check_multi_info(): handle 0x7f375f786b30 returned error 7:"
(I am still not using EVAPI module, that will be my next step, after the
holiday season)
(I suspect, however, that the REST API is not being able to handle the
load in this test environment (between 400 to 600 CAPS), but that is another matter.)
I can send the TCPDUMP, if anyone wishes to analyze.
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions --
sr-users@lists.kamailio.org
To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to
the sender!
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
when the HTTP REST service did reply correctly
I've used http_async_client many times and troubleshooted problems many times, and it's never been a fault with the module. The next step that I'd take it to analyze the TCP/HTTP in detail. You mentioned that it replied correctly, but perhaps there's some syntax error in it. Your last message shows the timeout after 1502ms, which is your configured timeout, so something has caused kamailio to determine that no response was received. How long was between the HTTP request and its response? Can you analyze the pcap (or upload it) to see whether it's correctly formatted?
James
On Sun, 29 Dec 2024 at 20:25, Sergio Charrua via sr-users sr-users@lists.kamailio.org wrote:
Thanks Alex!
I changed the HTTP_REPLY route to:
route[HTTP_REPLY] { xinfo("HTTP_REPLY - HTTP Response Code $http_rs - $ci\n");
if ( $http_ok && $http_rs==200) { xinfo("HTTP_REPLY - HTTP $ci reply ok\n"); jansson_xdecode($http_rb, "json"); xinfo("HTTP_REPLY - HTTP JSON Response: $http_rb \n"); if ( $xavp(json=>sip-response-code) == 300 ){ remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); ## "touch" the ruri to add the contact header for 3xx: $ru = $ru; t_reply("300", "Multiple Choice"); exit; }else{ xinfo("HTTP_REPLY - HTTP $ci Error Replied $xavp(json=>sip-response-code) - $xavp(json=>sip-response-text) \n"); t_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } } else { xinfo("HTTP_REPLY - HTTP Response Code $ci - $http_rs and error $http_err \n"); if (!$http_ok){ t_reply("503", "No Connection to HTTP"); exit; }else if ($http_rs>=500){ t_reply("503", "HTTPProcessing Error"); exit; } else{ t_reply("503", "Cannot Connect to HTTP"); exit; } } exit;
}
SIP Flow now show:
10.240.12.209:5060 10.242.17.146:5060 ----------x--------- ----------x---------
20:11:21.816566 x INVITE (SDP) x +0.000349 x --------------------------> x 20:11:21.816915 x 100 trying -- your call is x +1.502925 x <-------------------------- x 20:11:23.319840 x 503 No Connection to Xpher x +0.002155 x <-------------------------- x 20:11:23.321995 x ACK x x --------------------------> x
Though better, I can't understand why Kamailio returns 503 No Connection to HTTP despite the REST Service having correctly replied with valid data and , according to TCPDump, reply was received on Kamailio....
On logs, I also find:
Dec 29 20:04:42 ire-nprod-sip1 /usr/local/sbin/kamailio[623211]: INFO: <script>: HTTP_REPLY - HTTP Response Code 0gQAAC8WAAACBAAALxYAAF6U9PQuZQx7iuhYTB5JRXhVf72rYXoOERUNmKh6yQKm7Ik0RHuS9skp6z4UGrnDog--@10.240.12.209 - <null> and err or TIMEOUT
I can't understand why $http_rs is "err or TIMEOUT" and $http_ok is <null> when the HTTP REST service did reply correctly .... May there be something that is scrambling the transactions?
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Sun, Dec 29, 2024 at 8:07 PM Alex Balashov via sr-users sr-users@lists.kamailio.org wrote:
Hi Sergio,
Try using t_reply() / send_reply() in your route[HTTP_REPLY]. There is transaction state, so the transaction state machine needs to be informed of the dispositive reply.
-- Alex
On Dec 29, 2024, at 1:08 pm, Sergio Charrua via sr-users sr-users@lists.kamailio.org wrote:
(resending, without attachment, as OP is more than 250kb size and awaits for moderator's approval)
Hi all!
still struggling with Async HTTP Client ... My current configuration is very simple:
#!define HTTP_API_ROUTING_ENDPOINT_MAIN "http://MY_HTTP_REST_API:18085/Endpoint" include_file "listen.cfg"
loadmodule "pv" loadmodule "tm" loadmodule "http_async_client" loadmodule "xlog" loadmodule "tmx" loadmodule "sl" loadmodule "textops" loadmodule "cfgutils" loadmodule "siputils" loadmodule "rr" loadmodule "ctl" loadmodule "jsonrpcs.so" loadmodule "jansson.so"
modparam("pv", "shvset", "http_async=i:8"); modparam("http_async_client", "workers", 1); modparam("http_async_client", "connection_timeout", 500) modparam("http_async_client", "curl_verbose", 1) # for debug purpose
#modparam("tm", "fr_timer", 750) #modparam("tm", "fr_inv_timer", 20000) #modparam("tm", "remap_503_500", 0) modparam("tm", "failure_reply_mode", 3) modparam("tm", "max_inv_lifetime",5000)
# ----- jsonrpcs params ----- modparam("jsonrpcs", "pretty_format", 1) /* set the path to RPC fifo control file */ modparam("jsonrpcs", "fifo_name", "/tmp/kamailio_rpc.fifo") /* set the path to RPC unix socket control file */ modparam("jsonrpcs", "dgram_socket", "/tmp/kamailio_rpc.sock")
debug=2 children=16 log_facility=LOG_LOCAL0 log_prefix="{$mt $hdr(CSeq) $ci} " disable_sctp = yes force_rport = yes rundir="/tmp"
request_route {
$avp(REQUEST_URL) = HTTP_API_ROUTING_ENDPOINT_MAIN; if ( is_method("ACK") ) { if ( t_check_trans() ) { t_relay(); } exit; } if(is_method("OPTIONS")){ sl_reply("200", "OK"); exit; } if(is_method("CANCEL")){ sl_reply("200","OK"); sl_reply("487","Request Terminated"); exit; } jansson_set("string","from" , $hdr(From) , "$var(req)"); jansson_set("string","to" , $hdr(To) , "$var(req)"); jansson_set("string","r-uri" , $ru , "$var(req)"); jansson_set("string","contact" , $hdr(Contact) , "$var(req)"); jansson_set("string","call-id" , $ci , "$var(req)"); xinfo("MAIN-ROUTE - Setting From=$hdr(From) To=$hdr(To) Contact=$hdr(Contact) ci=$ci \n"); if ( is_present_hf("Identity") ) jansson_set("string","identity" , $hdr(Identity) , "$var(req)"); if ( is_present_hf("P-Identity-Bypass") ) jansson_set("string","p-identity-bypass" , $hdr(P-Identity-Bypass) , "$var(req)"); if ( is_present_hf("P-Asserted-Identity") ) jansson_set("string","p-asserted-identity" , $hdr(P-Asserted-Identity) , "$var(req)"); if ( is_present_hf("P-STSH-UC") ) jansson_set("string","p-stsh-uc" , $hdr(P-STSH-UC) , "$var(req)"); jansson_set("string", "request-time" , $avp(requestTime), "$var(req)"); ## Create transaction before http_async_query; if (is_method("INVITE")){ t_newtran(); xinfo("MAIN-ROUTE - Sending request [$var(req)]\n"); route(HTTP_ASYNC_REQUEST); } exit;
}
route[HTTP_ASYNC_REQUEST] { xinfo("HTTP_ASYNC_REQUEST - Sending request [$var(req)]\n");
$http_req(all) = $null; $http_req(suspend) = 1; $http_req(timeout) = 1500; # 1 second timeout $http_req(method) = "POST"; $http_req(hdr) = "Content-Type: application/json"; $http_req(body) = $var(req); if ( !http_async_query($avp(REQUEST_URL), "HTTP_REPLY") ) { xinfo("HTTP_ASYNC_REQUEST - http_async_query $ci FAILED. Return is [$rc]\n"); }else{ send_reply("503", "Server Error"); exit; }
}
route[HTTP_REPLY] { xinfo("HTTP_REPLY - Xphere Response Code $http_rs - $ci\n");
if ( $http_ok && $http_rs==200) { xinfo("HTTP_REPLY - $ci reply ok\n"); jansson_xdecode($http_rb, "json"); xinfo("HTTP_REPLY - HTTP JSON Response: $http_rb \n"); if ( $xavp(json=>sip-response-code) == 300 ){ remove_hf("Contact"); append_to_reply("Contact: $xavp(json=>contact)\r\n"); ## "touch" the ruri to add the contact header for 3xx: $ru = $ru; send_reply("300", "Multiple Choice"); exit; }else{ xinfo("HTTP_REPLY - $ci Error Replied $xavp(json=>sip-response-code) - $xavp(json=>sip-response-text) \n"); send_reply("$xavp(json=>sip-response-code)","$xavp(json=>sip-response-text)"); exit; } } else { xinfo("HTTP_REPLY - HTTP Response Code $ci - $http_rs and error $http_err \n"); if (!$http_ok){ sl_reply("503", "No Connection to HTTP"); exit; }else if ($http_rs>=500){ sl_reply("503", "HTTP Processing Error"); exit; } else{ sl_reply("503", "Cannot Connect to HTTP"); exit; } } exit;
}
The configuration is based on Ben Kaufman's kamailio_http_async example, but I have extended it a bit. Currently all the requests are being sent to the HTTP REST API. I can't find queue/buffering issues...
What I am experiencing is that , using SNGREP, I get this flow:
10.240.12.209:5060 10.242.17.146:5060 ----------*---------- ----------*----------
17:33:46.689852 x INVITE (SDP) x +0.000530 x --------------------------> x 17:33:46.690382 x 100 trying -- your call is x +1.499822 x <-------------------------- x 17:33:48.190204 x 503 No Connection to HTTP x +0.000029 x <-------------------------- x 17:33:48.190233 x 500 I'm terribly sorry, se x +0.002130 x <-------------------------- x 17:33:48.192363 x ACK x +0.485836 x --------------------------> x 17:33:48.678199 x 500 I'm terribly sorry, se x +0.004881 x <<<------------------------ x 17:33:48.683080 x ACK x +0.973295 x ------------------------>>> x 17:33:49.656375 x 500 I'm terribly sorry, se x +0.004105 x <<<------------------------ x 17:33:49.660480 x ACK x +1.995420 x ------------------------>>> x 17:33:51.655900 x 500 I'm terribly sorry, se x +0.005361 x <<<-------------------------x 17:33:51.661261 x ACK x x ------------------------>>> x I suspected issues with the HTTP REST service, but when using tcpdump, I can find the Request from Kamailio and a reply back from the REST API service, so doesn't seem to be a problem on the HTTP REST service So my questions are:
- why is Kamailio sending a "SIP 500 I'm terribly sorry..." error after a 503 No Connection to HTTP is sent and an "exit" command is executed?
- how can I get rid of these messages?
- Why Kamailio keeps sending responses back to SBC after the ACK when it is set to just "exit"?
- Why is Kamailio not processing the response from HTTP REST API when it is correctly received?
Logs are also weird:
- I find a lot of these warnings:
"Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: WARNING: http_async_client [http_async_client_mod.c:529]: ah_get_status(): an async variable was read after http error, use $http_ok to check the request's status" and "Dec 29 17:38:34 ire-nprod-sip1 /usr/local/sbin/kamailio[590864]: ERROR: http_async_client [http_multi.c:621]: check_multi_info(): handle 0x7f375f786b30 returned error 7:"
(I am still not using EVAPI module, that will be my next step, after the holiday season) (I suspect, however, that the REST API is not being able to handle the load in this test environment (between 400 to 600 CAPS), but that is another matter.)
I can send the TCPDUMP, if anyone wishes to analyze.
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
-- Alex Balashov Principal Consultant Evariste Systems LLC Web: https://evaristesys.com Tel: +1-706-510-6800
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
Kamailio - Users Mailing List - Non Commercial Discussions -- sr-users@lists.kamailio.org To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender!
PS.
On Dec 29, 2024, at 1:08 pm, Sergio Charrua via sr-users sr-users@lists.kamailio.org wrote:
(I am still not using EVAPI module, that will be my next step, after the holiday season)
I think Ben Kaufman has convincingly demonstrated that the performance of `http_async_client` is more than sufficient for all but the most demanding applications, and I would feel confident, in your position, investing further in your REST API-driven approach.
My fondness for EVAPI may be a baroque.
-- Alex