servefile net golang body http get timeout go

net - http servefile



¿Cómo establecer el tiempo de espera para las solicitudes de http.Get() en Golang? (6)

Estoy haciendo una búsqueda de URL en Ir y tengo una lista de URL para buscar. http.Get() solicitudes http.Get() a cada URL y http.Get() su respuesta.

resp,fetch_err := http.Get(url)

¿Cómo puedo establecer un tiempo de espera personalizado para cada solicitud Get? (El tiempo predeterminado es muy largo y eso hace que mi captura sea realmente lenta.) Quiero que mi captura tenga un tiempo de espera de alrededor de 40-45 segundos, después de lo cual debe devolver "tiempo de espera de solicitud agotado" y pasar a la siguiente URL.

¿Cómo puedo conseguir esto?


Al final, terminé usando esta función de utilidad para todas las solicitudes que requieren tiempo de espera. Por alguna razón, el código de @sparrovv estaba actuando.

// reqType is one of HTTP request strings (GET, POST, PUT, DELETE, etc.) func DoRequest(reqType string, url string, headers map[string]string, data []byte, timeoutSeconds int) (int, []byte, map[string][]string, error) { var reader io.Reader if data != nil && len(data) > 0 { reader = bytes.NewReader(data) } req, err := http.NewRequest(reqType, url, reader) if err != nil { return 0, nil, nil, err } // I strongly advise setting user agent as some servers ignore request without it req.Header.Set("User-Agent", "YourUserAgentString") if headers != nil { for k, v := range headers { req.Header.Set(k, v) } } var ( statusCode int body []byte timeout time.Duration ctx context.Context cancel context.CancelFunc header map[string][]string ) timeout = time.Duration(time.Duration(timeoutSeconds) * time.Second) ctx, cancel = context.WithTimeout(context.Background(), timeout) defer cancel() err = httpDo(ctx, req, func(resp *http.Response, err error) error { if err != nil { return err } defer resp.Body.Close() body, _ = ioutil.ReadAll(resp.Body) statusCode = resp.StatusCode header = resp.Header return nil }) return statusCode, body, header, err }


Aparentemente en Go 1.3 http.Client tiene un campo de tiempo de espera

timeout := time.Duration(5 * time.Second) client := http.Client{ Timeout: timeout, } client.Get(url)

Eso ha hecho el truco para mí.


Para agregar a la respuesta de Volker, si también desea establecer el tiempo de espera de lectura / escritura además del tiempo de espera de conexión, puede hacer algo como lo siguiente

package httpclient import ( "net" "net/http" "time" ) func TimeoutDialer(cTimeout time.Duration, rwTimeout time.Duration) func(net, addr string) (c net.Conn, err error) { return func(netw, addr string) (net.Conn, error) { conn, err := net.DialTimeout(netw, addr, cTimeout) if err != nil { return nil, err } conn.SetDeadline(time.Now().Add(rwTimeout)) return conn, nil } } func NewTimeoutClient(connectTimeout time.Duration, readWriteTimeout time.Duration) *http.Client { return &http.Client{ Transport: &http.Transport{ Dial: TimeoutDialer(connectTimeout, readWriteTimeout), }, } }

Este código está probado y está trabajando en producción. La esencia completa de las pruebas está disponible aquí https://gist.github.com/dmichael/5710968

Tenga en cuenta que deberá crear un nuevo cliente para cada solicitud debido a la línea conn.SetDeadline que hace referencia a un punto en el futuro desde el momento. time.Now()



Una manera rápida y sucia:

http.DefaultTransport.(*http.Transport).ResponseHeaderTimeout = time.Second * 45

Esto es un estado global mutante sin coordinación. Sin embargo, es posible que esté bien para su buscador de URL. De lo contrario, cree una instancia privada de http.RoundTripper :

var myTransport http.RoundTripper = &http.Transport{ Proxy: http.ProxyFromEnvironment, ResponseHeaderTimeout: time.Second * 45, } var myClient = &http.Client{Transport: myTransport} resp, err := myClient.Get(url) ...

Nada arriba fue probado.


DialTimeout configurar su propio http.Client con su propio Transport que utiliza una función de Marcación personalizada que envuelve DialTimeout .

Algo así como (completamente no probado ) this :

var timeout = time.Duration(2 * time.Second) func dialTimeout(network, addr string) (net.Conn, error) { return net.DialTimeout(network, addr, timeout) } func main() { transport := http.Transport{ Dial: dialTimeout, } client := http.Client{ Transport: &transport, } resp, err := client.Get("http://some.url") }