¿Curl tiene un tiempo de espera?

251

Hasta ahora no pude encontrar nada realmente, pero ¿es cierto que curlrealmente no se agota el tiempo?

 user@host:~# curl http://localhost/testdir/image.jpg

Lo pregunto porque estoy redirigiendo cualquier solicitud de imágenes testdira un módulo Apache separado que genera esas imágenes sobre la marcha. Pueden pasar hasta 15 minutos antes de que la imagen esté realmente lista y entregada al cliente solicitante.

Se curlespere siempre (o es que según la configuración) o hay alguna especie de tiempo de espera?

Preexo
fuente
3
Me gustaría contar con curl para tener un tiempo de espera de conexión (si no otra cosa, el sistema operativo y su pila TCP / IP es casi seguro que lo hace), pero podría no tener un tiempo de espera de lectura una vez que se ha establecido la conexión.
un CVn el

Respuestas:

340

Si.

Parámetros de tiempo de espera

curltiene dos opciones: --connect-timeouty --max-time.

Citando de la página de manual:

--connect-timeout <seconds>
    Maximum  time  in  seconds  that you allow the connection to the
    server to take.  This only limits  the  connection  phase,  once
    curl has connected this option is of no more use.  Since 7.32.0,
    this option accepts decimal values, but the actual timeout  will
    decrease in accuracy as the specified timeout increases in deci‐
    mal precision. See also the -m, --max-time option.

    If this option is used several times, the last one will be used.

y:

-m, --max-time <seconds>
    Maximum  time  in  seconds that you allow the whole operation to
    take.  This is useful for preventing your batch jobs from  hang‐
    ing  for  hours due to slow networks or links going down.  Since
    7.32.0, this option accepts decimal values, but the actual time‐
    out will decrease in accuracy as the specified timeout increases
    in decimal precision.  See also the --connect-timeout option.

    If this option is used several times, the last one will be used.

Valores predeterminados

Aquí (en Debian) deja de intentar conectarse después de 2 minutos, independientemente del tiempo especificado --connect-timeouty aunque el valor predeterminado de tiempo de espera de conexión parece ser de 5 minutos según la DEFAULT_CONNECT_TIMEOUTmacro en lib / connect.h .

--max-timeParece que no existe un valor predeterminado para , haciendo curlesperar una respuesta para siempre si la conexión inicial tiene éxito.

¿Qué usar?

Usted probablemente está interesado en esta última opción, --max-time. Para su caso, configúrelo en 900(15 minutos).

Especificar la opción --connect-timeoutde algo como 60(un minuto) también podría ser una buena idea. De curllo contrario , intentará conectarse una y otra vez, aparentemente utilizando algún algoritmo de retroceso.

scai
fuente
2
¡gracias por eso! --max-time no dice nada sobre los valores predeterminados, así que supongo que no tiene y, por lo tanto, no tiene tiempo de espera, excepto el tiempo de conexión por defecto ...?
Preexo
44
Sí, si la conexión tiene éxito, curl parece esperar para siempre una respuesta.
scai
Tenga en cuenta que tanto maxtime es un problema si la respuesta es una gran descarga que lleva más tiempo que 'maxtime'.
user92979
1
El tiempo de espera de 2 minutos también me huele a un tiempo de espera del servidor. Acabo de tener el mismo problema con el servidor http de una aplicación Node.js que tiene un tiempo de espera predeterminado de 2 minutos. Para aumentarlo, vea HTTP.server.setTimeout () .
Thalis K.
17

Hay timelimit: / usr / bin / timelimit - limita efectivamente el tiempo de ejecución absoluto de un proceso

 Options:

 -p      If the child process is terminated by a signal, timelimit
         propagates this condition, i.e. sends the same signal to itself. 
         This allows the program executing timelimit to determine 
         whether the child process was terminated by a signal or 
         actually exited with an exit code larger than 128.
 -q      Quiet operation - timelimit does not output diagnostic 
         messages about signals sent to the child process.
 -S killsig
         Specify the number of the signal to be sent to the 
         process killtime seconds after warntime has expired.  
         Defaults to 9 (SIGKILL).
 -s warnsig
         Specify the number of the signal to be sent to the 
         process warntime seconds after it has been started.  
         Defaults to 15 (SIGTERM).
 -T killtime
         Specify the maximum execution time of the process before 
         sending killsig after warnsig has been sent.  Defaults to 120 seconds.
 -t warntime
         Specify the maximum execution time of the process in 
         seconds before sending warnsig.  Defaults to 3600 seconds.

 On systems that support the setitimer(2) system call, the 
 warntime and killtime values may be specified in fractional 
 seconds with microsecond precision.
perpetuidad
fuente
1
No está disponible por defecto en macOS 10.13.4 al menos.
Thorbjørn Ravn Andersen
14

Mejor que --max-timelas --speed-limity las --speed-timeopciones. En resumen, --speed-limitespecifica la velocidad promedio mínima que está dispuesto a aceptar, y --speed-timeespecifica cuánto tiempo la velocidad de transferencia puede permanecer por debajo de ese límite antes de que la transferencia se agote y se cancele.

Alex D
fuente
99
Creo que ninguno de los dos es mejor, pero en mi caso de uso, max-time es en realidad más apropiado porque algo más de 10 segundos haría que mi programa fuera inútil.
Jorge Bucaran
Estoy usando curl como biblioteca en una aplicación de escritorio (no solo llamándolo desde la CLI) y para mí su opción fue la mejor. Mi aplicación debe ser capaz de admitir descargas largas, por lo que un simple --max-time no era una buena opción para detectar "descargas bloqueadas" (que es el caso si, por ejemplo, el usuario se desconecta mientras se realiza una descarga) progreso), así que fui con un límite de velocidad de 1024 y un tiempo de velocidad de 30 para detectarlos.
André Morujão
1
¿Útil? Ciertamente. ¿Mejor? Creo que eso depende mucho de sus requisitos
Brian Agnew
Los tiempos de espera son un problema si la respuesta podría ser una gran descarga de tamaño desconocido (¡o incluso conocido!). maxtime expirará si la descarga grande tarda, por ejemplo, más de 15 minutos. Y los límites de velocidad pueden ser disparados por proxies que almacenan en caché la respuesta completa primero antes de reenviar cualquier cosa. A veces parecen reenviar 1 byte por minuto, pero ¿cómo saber si se trata de un proxy de almacenamiento en caché en una red rápida o una conexión muy lenta que se debe volver a intentar? Así que al final me di por vencido y desactivé los tiempos de espera para consultas de descarga. No estoy seguro si hay una mejor manera.
user92979
3

Si tiene coreutils instalados en MacOS, puede usar el comando GNU timeout que se incluye con ese paquete. Todas las herramientas de GNU tienen el prefijo a, gpor lo que sería la CLI gtimeout.

gtimeout --help
Usage: gtimeout [OPTION] DURATION COMMAND [ARG]...
 or:  gtimeout [OPTION]
Start COMMAND, and kill it if still running after DURATION.

Ejemplo

$ gtimeout 1s curl -I http://www.google.com/
HTTP/1.1 200 OK
Date: Wed, 31 Oct 2018 03:36:08 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: 1P_JAR=2018-10-31-03; expires=Fri, 30-Nov-2018 03:36:08 GMT; path=/; domain=.google.com
HttpOnly
Transfer-Encoding: chunked
Accept-Ranges: none
Vary: Accept-Encoding
slm
fuente
0

Un par de soluciones en BASH4 +

# -- server available to check via port xxx ?  --
function isServerAvailableNC() {
    max_secs_run="${3}"
    if timeout $max_secs_run nc -z ${1} ${2} 2>/dev/null >/dev/null; then
        #echo "${1} ✓"
        true
   else
        #echo "${1} ✗"
        return
   fi
}


# -- server available to check via port xxx ?  --
# -- supported protocols (HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, DICT, TELNET, LDAP or FILE) --
#/usr/bin/curl -sSf --max-time 3 https://ifwewanted.to.confirm.https.com/ --insecure

function isServerAvailableCURL() {

    max_secs_run="${3}"

    proto="http://"
    if [ ! -z ${2} ] || [ ${2} -gt 80 ] ;then
        proto="https://"
    fi

    if /usr/bin/curl -sSf --max-time "${max_secs_run}" "${1}" --insecure 2>/dev/null >/dev/null; then
        #echo "${1} ✓"
        true
    else
        #echo "${1} ✗"
        false
    fi
}

Uso de la muestra:

RECOMIENDA QUE NC se use si necesitamos un puerto específico

host="1.2.3.4"
if isServerAvailableCURL "$host" "80" "3";then
    check_remote_domain_cert "$host"
fi


host="1.2.3.4"
if isServerAvailableNC "$host" "80" "3";then
    check_remote_domain_cert "$host"
fi
Mike Q
fuente