a Go HTTP client with timeouts

go-httpclient

requires Go 1.1+ as of v0.4.0 the API has been completely re-written for Go 1.1 (for a Go 1.0.x compatible release see 1adef50)

Build Status

Provides an HTTP Transport that implements the RoundTripper interface and can be used as a built in replacement for the standard library's, providing:

  • connection timeouts
  • request timeouts

This is a thin wrapper around http.Transport that sets dial timeouts and uses Go's internal timer scheduler to call the Go 1.1+ CancelRequest() API.

Example

transport := &httpclient.Transport{
    ConnectTimeout:        1*time.Second,
    RequestTimeout:        10*time.Second,
    ResponseHeaderTimeout: 5*time.Second,
}
defer transport.Close()

client := &http.Client{Transport: transport}
req, _ := http.NewRequest("GET", "http://127.0.0.1/test", nil)
resp, err := client.Do(req)
if err != nil {
    return err
}
defer resp.Body.Close()

Note: you will want to re-use a single client object rather than creating one for each request, otherwise you will end up leaking connections.

Reference Docs

For API docs see godoc.

Comments
  • issues reusing the transport for more than 1 connection

    issues reusing the transport for more than 1 connection

    I might be doing something wrong but I'm on Go 1.1 and i'm using the new code from Master and when I do more than 1 request I get the following error:

    read tcp xxx.xxx.xxx.xxx:80: use of closed network connection

    Summary of my code:

    var TimeoutTransport = &httpclient.Transport{
        ConnectTimeout:        1*time.Second,
        RequestTimeout:        10*time.Second,
        ResponseHeaderTimeout: 5*time.Second,
    }
    
    func example() {
    client := &http.Client{Transport: TimeoutTransport}
      for _, url := range *segmentUrls {
        resp, err := client.Get(url)
        defer resp.Body.Close()
       //[...]
      }
    
    }
    

    I might be doing something wrong but I get this error randomly :(

    Might be related to: https://code.google.com/p/go/issues/detail?id=4704

  • Add an IdleTimeout to the Transport

    Add an IdleTimeout to the Transport

    Proposal for an IdleTimeout option on the httpclient.Transport.

    • This allows finer control of the timeouts on the client, and gives the caller an actual timeout error when hit, vs the closed connection error returned after canceling the request.
    • This obviously interferes with Keepalive connections. Not sure if it should disable them by default, or just note it in the documentation.
    • I punted a bit on the tests -- really need to put in a slow-writer endpoint to test for the IdleTimeout specifically.
  • Removing hc_ references in client code

    Removing hc_ references in client code

    httpclient has been cleaned up so that the user never sees any references to 'hc_http(s)?' when they get their request back OR inside their redirect policy (in response to issue #4).

    Fixing the issue for the response's resp.Request.URL object was straightforward (we simply remove it in httpclient.Do), however removing it from the redirect chain required some h4x0ring.

    In order to do this, we first clean up the new redirect to be considered and the newest entry in the array of previous requests. After consulting the user defined RedirectPolicy, we reinstate the 'hc_' prefix to the current request (or else our custom RoundTripper doesn't get triggered). Is there a better way?!

  • Added https support

    Added https support

    The "hc_" hack was generalized to also work for https connections. In addition, there now exists a TLSClientConfig object within the HttpClient object that can be used to control the TLS settings for HTTPS connections. One caviat is that the object cannot be moved anywhere in memory, so it can only be changed inplace.

  • Switch from net.Conn to *net.TCPConn

    Switch from net.Conn to *net.TCPConn

    • Switch from an interface to a struct pointer in the rwTimeoutConn wrapper. In extreme cases, the interface overhead may be up to 5% (though it's probably very close to 0% at normal network speeds). Since http is only a TCP protocol, we don't need the net.Conn abstraction anyway.
  • Handle closed cached connections

    Handle closed cached connections

    I'm not entirely sure if there is a way to handle this, but filing an issue nonetheless. Essentially once a connection is cached, it stays there and will get reused the next time the same connection is required. If during this time the remote server closes the connection, the socket has already entered the CLOSE_WAIT state on the client side, but the library will still attempt to reuse this connection but the request will fail. It would be nice if this state could be detected in checkConnCache and the cached connection were dropped and not reused. I know there is no 100% solution to detecting closed connections (especially wrt NAT), it would be great if it worked for some of the more common possibly detectable cases.

  • add copyright line to LICENSE

    add copyright line to LICENSE

    I got here trying to add improved certificate handling to Kubernetes- your package is a dependency of Google's certificate-transparency which is in turn a dependency of cfssl. There's a Kubernetes build script that is literally grepping for the "Copyright" line to assemble a combined license file and my pre-commit tests fail without it. Would you mind adding one?

  • add feature of set tcp send buffer or receive buffer.

    add feature of set tcp send buffer or receive buffer.

    add feature of set tcp send buffer or receive buffer.

    This is an advanced option for advanced users who want to tune low level TCP parameters to try and squeeze out more performance. Especially in the WAN environment.

  • Connection leak w/ example

    Connection leak w/ example

    When I tried using this example code:

    transport := &httpclient.Transport{
        ConnectTimeout: 1*time.Second,
        ResponseHeaderTimeout: 5*time.Second,
        RequestTimeout: 10*time.Second,
    }
    defer transport.Close()
    
    client := &http.Client{Transport: transport}
    req, _ := http.NewRequest("GET", "http://127.0.0.1/test", nil)
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    

    in several places in my code, I ended up getting connection leaks. After running lsof -p <pid> I would see hundreds of connections in the ESTABLISHED state, even though these connections should have been closed.

    After changing to using a single global client:

    var globalClient *http.Client
    
    func init() {
        t := &httpclient.Transport{
            ConnectTimeout:        60 * time.Second,
            RequestTimeout:        60 * time.Second,
            ResponseHeaderTimeout: 60 * time.Second,
        }
        globalClient = &http.Client{Transport: t}
    }
    
    
    func doSomeRequest() {
        req, _ := http.NewRequest("GET", destUrl, nil)
        resp, err := globalClient.Do(req)
    }
    

    the problem seemed to go away.

    I'm posting this ticket for two reason:

    1. You may want to put a note in the example code to mention that it might be wise to re-use the client object
    2. Can you think of any issues to beware of with the approach mentioned above?
  • Fix ResponseHeaderTimeout and use time.Timer instead of custom priority queue

    Fix ResponseHeaderTimeout and use time.Timer instead of custom priority queue

    • ResponseHeaderTimeout were not passed to http.Transport, fixed it
    • time.Timer already does all we need, and do it relatively well till 100_000 rps. If higher rate needed, than possibly custom queue should be kept.
  • Response URL's have residual

    Response URL's have residual "hc_"'s in the scheme

    When introspecting into a response's Request.URL object, the scheme still has the hc_ prefix from go-httpclient's internal workings. In my opinion, we should do something to clean this up so that the end user doesn't have to worry about any of the internal machinery.

    Example:

    httpclient := httpclient.New()
    req, err := http.NewRequest("GET", "http://bitly.com", nil)
    resp, err := httpclient.Do(req)
    
    log.Println("URL: ", resp.Request.URL.String())
    

    This will output:

    URL: hc_http://bitly.com
    
  • Fix function comments based on best practices from Effective Go

    Fix function comments based on best practices from Effective Go

    Every exported function in a program should have a doc comment. The first sentence should be a summary that starts with the name being declared. From effective go.

    I generated this with CodeLingo and I'm keen to get some feedback, but this is automated so feel free to close it and just say "opt out" to opt out of future CodeLingo outreach PRs.

  • Intermittent TestHttpsConnection Failures to httpbin.org

    Intermittent TestHttpsConnection Failures to httpbin.org

    Hiya!

    We use a copy of go-httpclient in one of our internal applications, but occasionally see a weird test failure

    === RUN TestHttpsConnection
    --- FAIL: TestHttpsConnection (3.00 seconds)
        httpclient_test.go:93: 1st request failed - Get https://httpbin.org/ip: read tcp 23.21.162.118:443: use of closed network connection
    === RUN TestHttpClient
    --- PASS: TestHttpClient (0.45 seconds)
    === RUN TestSlowServer
    --- PASS: TestSlowServer (0.50 seconds)
    === RUN TestMultipleRequests
    --- PASS: TestMultipleRequests (2.00 seconds)
    FAIL
    FAIL    github.com/mreiferson/go-httpclient 5.965s
    

    Have you seen this before, is it a known issue? :metal:

fhttp is a fork of net/http that provides an array of features pertaining to the fingerprint of the golang http client.

fhttp The f stands for flex. fhttp is a fork of net/http that provides an array of features pertaining to the fingerprint of the golang http client. T

Jan 1, 2023
Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http
Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http

fasthttp Fast HTTP implementation for Go. Currently fasthttp is successfully used by VertaMedia in a production serving up to 200K rps from more than

Jan 2, 2023
Speak HTTP like a local. (the simple, intuitive HTTP console, golang version)

http-gonsole This is the Go port of the http-console. Speak HTTP like a local Talking to an HTTP server with curl can be fun, but most of the time it'

Jul 14, 2021
NATS HTTP Round Tripper - This is a Golang http.RoundTripper that uses NATS as a transport.

This is a Golang http.RoundTripper that uses NATS as a transport. Included is a http.RoundTripper for clients, a server that uses normal HTTP Handlers and any existing http handler mux and a Caddy Server transport.

Dec 6, 2022
Simple HTTP package that wraps net/http

Simple HTTP package that wraps net/http

Jan 17, 2022
Http-conection - A simple example of how to establish a HTTP connection using Golang

A simple example of how to establish a HTTP connection using Golang

Feb 1, 2022
Full-featured, plugin-driven, extensible HTTP client toolkit for Go

gentleman Full-featured, plugin-driven, middleware-oriented toolkit to easily create rich, versatile and composable HTTP clients in Go. gentleman embr

Dec 23, 2022
An enhanced http client for Golang
An enhanced http client for Golang

go-http-client An enhanced http client for Golang Documentation on go.dev ?? This package provides you a http client package for your http requests. Y

Dec 23, 2022
An enhanced HTTP client for Go
An enhanced HTTP client for Go

Heimdall Description Installation Usage Making a simple GET request Creating a hystrix-like circuit breaker Creating a hystrix-like circuit breaker wi

Jan 9, 2023
Enriches the standard go http client with retry functionality.

httpRetry Enriches the standard go http client with retry functionality using a wrapper around the Roundtripper interface. The advantage of this libra

Dec 10, 2022
http client for golang
http client for golang

Request HTTP client for golang, Inspired by Javascript-axios Python-request. If you have experience about axios or requests, you will love it. No 3rd

Dec 18, 2022
Simple HTTP and REST client library for Go

Resty Simple HTTP and REST client library for Go (inspired by Ruby rest-client) Features section describes in detail about Resty capabilities Resty Co

Jan 1, 2023
A nicer interface for golang stdlib HTTP client

rq A nicer interface for golang stdlib HTTP client Documents rq: here client: here jar: here Why? Because golang HTTP client is a pain in the a... Fea

Dec 12, 2022
A Go HTTP client library for creating and sending API requests
A Go HTTP client library for creating and sending API requests

Sling Sling is a Go HTTP client library for creating and sending API requests. Slings store HTTP Request properties to simplify sending requests and d

Jan 7, 2023
GoRequest -- Simplified HTTP client ( inspired by nodejs SuperAgent )
GoRequest -- Simplified HTTP client ( inspired by nodejs SuperAgent )

GoRequest GoRequest -- Simplified HTTP client ( inspired by famous SuperAgent lib in Node.js ) "Shooting Requests like a Machine Gun" - Gopher Sending

Jan 1, 2023
gout to become the Swiss Army Knife of the http client @^^@---> gout 是http client领域的瑞士军刀,小巧,强大,犀利。具体用法可看文档,如使用迷惑或者API用得不爽都可提issues
gout to become the Swiss Army Knife of the http client @^^@--->  gout 是http client领域的瑞士军刀,小巧,强大,犀利。具体用法可看文档,如使用迷惑或者API用得不爽都可提issues

gout gout 是go写的http 客户端,为提高工作效率而开发 构架 feature 支持设置 GET/PUT/DELETE/PATH/HEAD/OPTIONS 支持设置请求 http header(可传 struct,map,array,slice 等类型) 支持设置 URL query(可

Dec 29, 2022
Retry, Race, All, Some, etc strategies for http.Client calls

reqstrategy Package reqstrategy provides functions for coordinating http.Client calls. It wraps typical call strategies like making simultaneous reque

Apr 30, 2021
An enhanced HTTP client for Go
An enhanced HTTP client for Go

Heimdall Description Installation Usage Making a simple GET request Creating a hystrix-like circuit breaker Creating a hystrix-like circuit breaker wi

Jan 2, 2023
Go Supertest is minimalize HTTP Client Testing only for Gin Framework

Go Supertest is minimalize HTTP Client Testing only for Gin Framework, inspired by Supertest package library HTTP Client Testing for Express.js Framework.

May 22, 2022