a "Bug" in Curl's millisecond timeout -- A- thePHP Lao Yang recently our service in upgrading PHP used by Libcurl, expect the new version of Libcurl to support the millisecond time-out, so that more granular control of the backend interface timeout, thereby improving overall response time. But we found that on our CentOS server, When you set a timeout of less than 1000ms, curl does not initiate any requests and returns a time-out error (timeout reached -). Originally, there is a hole in it, curl default, on the Linux system, if the system standard DNS resolution is used, the sigalarm will be used to provide the ability to control the domain name resolution timeout, but Sigalarm does not support a timeout less than 1s, so the libcurl 7.28. 1 in the code (note the Chinese comment line):intCurl_resolv_timeout (structConnectData *Conn,Const Char*hostname,intPort,structCurl_dns_entry * *entry,LongTimeoutms) {..... #ifdef use_alarm_timeout , .....if(data->Set. no_signal)/*Ignore The timeout when signals is disabled*/Timeout=0;ElseTimeout=Timeoutms;if(!Timeout)/*Use_alarm_timeout defined, but no TIMEOUT actually requested*/returnCURL_RESOLV (conn, hostname, port, entry);if(Timeout < +)//if less than 1000, the direct timeout returns/*the alarm () function is provides integer second resolution, so Ifwe want to wait less than one second we must bail Out already now. */returnCurlresolv_timedout, ... As you can see, when your timeout is less than 1000ms, name parsing will return directly to Curlresolv_timeout, which will eventually lead to Curle_operation_timedout, then error, timeout reached ... This .... Too much of a dad .? Can we not use milliseconds to timeout? What do you offer this function for?still look at the code, or just that code, note this (Chinese comment line): #ifdef use_alarm_timeoutif(data->Set. no_signal)//watch this line./*Ignore The timeout when signals is disabled*/Timeout=0;ElseTimeout=Timeoutms;if(!Timeout)/*Use_alarm_timeout defined, but no TIMEOUT actually requested*/returnCURL_RESOLV (conn, hostname, port, entry);if(Timeout < +)/*the alarm () function is provides integer second resolution, so Ifwe want to wait less than one second we must bail Out already now. */returnCurlresolv_timedout, it seems, as long as the set.no_signal this thing is 1, you can bypass the ... So what's this thing??This is simple, grep the code, found: Casecurlopt_nosignal:/** The application asks not to set any signal () or alarm () handlers,* even when using a timeout.*/Data-Set. no_signal = (0! = Va_arg (param,Long))?True:false; Breakhaha, the original is this goods:<?phpcurl_setopt ($ch, curlopt_nosignal,1);?>with this opt, everything is finally normal.!PostScript: In this way, there will be a hidden trouble, that is, DNS resolution will not be limited by the timeout, this is in the company, generally no problem, but in case the DNS server hang up, it may cause the application timeout. So, what else??yes, that's Mike's warning, we can get Libcurl to use C .-ares (C Library forasynchronous DNS requests) to do name resolution. The specific can be in the time of Config curl:./configure--enable-ares[=PATH] So you don't have to set nosignal.
A "Bug" in Curl's millisecond timeout