Skip to content

Timeout only applies to the response headers #141

@niteria

Description

@niteria

Repro steps:

stack repl --package wreq
Prelude> import Network.Wreq
Prelude Network.Wreq> :set +s

# Quick request, no delays:
Prelude Network.Wreq> get "http://httpbin.org/drip?duration=0&numbytes=10&code=200&delay=0"
Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Date","Wed, 22 Jul 2020 20:13:46 GMT"),("Content-Type","application/octet-stream"),("Content-Length","10"),("Connection","keep-alive"),("Server","gunicorn/19.9.0"),("Access-Control-Allow-Origin","*"),("Access-Control-Allow-Credentials","true")], responseBody = "**********", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}
(0.37 secs, 13,573,776 bytes)

# Request that takes 40s for the header to be produced and produces the body immediately (default timeout is 30s, so that's expected):
Prelude Network.Wreq> get "http://httpbin.org/drip?duration=0&numbytes=10&code=200&delay=40"
*** Exception: HttpExceptionRequest Request {
  host                 = "httpbin.org"
  port                 = 80
  secure               = False
  requestHeaders       = [("User-Agent","haskell wreq-0.5.3.2")]
  path                 = "/drip"
  queryString          = "?duration=0&numbytes=10&code=200&delay=40"
  method               = "GET"
  proxy                = Nothing
  rawBody              = False
  redirectCount        = 10
  responseTimeout      = ResponseTimeoutDefault
  requestVersion       = HTTP/1.1
}
 ResponseTimeout

# Request that produces the header immediately and takes 60s 
# for the body to be produced (surprisingly, no timeout)
Prelude Network.Wreq> get "http://httpbin.org/drip?duration=60&numbytes=10&code=200&delay=0"
Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Date","Wed, 22 Jul 2020 20:17:05 GMT"),("Content-Type","application/octet-stream"),("Content-Length","10"),("Connection","keep-alive"),("Server","gunicorn/19.9.0"),("Access-Control-Allow-Origin","*"),("Access-Control-Allow-Credentials","true")], responseBody = "**********", responseCookieJar = 
CJ {expose = []}, responseClose' = ResponseClose}
(54.43 secs, 13,661,864 bytes)

AFAIK this is a behavior that was inherited from http-client, here's the correspoding issue: snoyberg/http-client#416.

Maybe this is intended, but it surprised me and led to my app hanging every few weeks and quite extensive debugging before I wrapped get in System.Timeout.timeout.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions