流式传输HTTP客户端的时间很长,直到第一个响应字节

I'm trying to write a Go HTTP client intended to stream event data from a HTTP server. My problem is that the first byte of the response could take hours before I get it, this includes the response headers. It's even possible I never get a response.

I currently get net/http: request canceled (Client.Timeout exceeded while awaiting headers) using this client:

Client = &http.Client{
    Transport: &http.Transport{
        Dial: (&net.Dialer{                                                                         
            Timeout:   0,
            KeepAlive: 30 * time.Second,
        }).Dial,
        Proxy: http.ProxyURL(proxyUrl),
        ResponseHeaderTimeout: 0,
    },
    Timeout: 0,
}

I cannot think of any more timeouts to set to zero in order for my connection to not timeout. What am I missing?

I'm using go version go1.8 linux/amd64.

Edit 1: I have no possibility to change the server for which i'm writing a client.

I figured out that in the default http client, the timeouts i set to zero are already zero. So removing those from my own client leaves

Client = &http.Client{
    Transport: &http.Transport{
        Dial: (&net.Dialer{                                                                         
            KeepAlive: 30 * time.Second,
        }).Dial,
        Proxy: http.ProxyURL(proxyUrl),
    },
}

The keep alive option in Dial doesn't seem to have anything to do with it either. This leaves the proxy.

In the proxy implementation i found a client with timeout as such:

client := &http.Client{
    Timeout: 30 * time.Second,
}

Removing that timeout solved my problem.

A timeout setting won't work for this problem, you need to redesign your application.

Maybe you could do the following on the server side:

  1. Get the request arguments
  2. Convert them to a cache key (filename, memcache, database key - whatever you like), for example by sorting the arguments and hashing them using SHA-1/-256/512
  3. Check if this cache key is currently being processed (e.g. lock exists) - return something like "try again later" if true
  4. Push the long running work into a background process (maybe using Gearman?) and return "try again later"

In background:

  1. Create a lock for the cache key including a reasonable timeout
  2. Create your data (the part running for hours)
  3. Write the result to the cache

Your client could easily send the request and will get an immediate result. The result might be a "try again later" or the result from the cache. The client should sleep for some time if it receives the "try again later" message and then retry the request.