Last active
October 18, 2023 20:07
Revisions
-
dmichael revised this gist
Jun 5, 2013 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,10 +16,10 @@ func TimeoutDialer(config *Config) func(net, addr string) (c net.Conn, err error conn, err := net.DialTimeout(netw, addr, config.ConnectTimeout) if err != nil { return nil, err } conn.SetDeadline(time.Now().Add(config.ReadWriteTimeout)) return conn, nil } } func NewTimeoutClient(args ...interface{}) *http.Client { -
dmichael revised this gist
Jun 5, 2013 . 1 changed file with 31 additions and 31 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,49 +1,49 @@ package httpclient import ( "net" "net/http" "time" ) type Config struct { ConnectTimeout time.Duration ReadWriteTimeout time.Duration } func TimeoutDialer(config *Config) func(net, addr string) (c net.Conn, err error) { return func(netw, addr string) (net.Conn, error) { conn, err := net.DialTimeout(netw, addr, config.ConnectTimeout) if err != nil { return nil, err } conn.SetDeadline(time.Now().Add(config.ReadWriteTimeout)) return conn, nil } } func NewTimeoutClient(args ...interface{}) *http.Client { // Default configuration config := &Config{ ConnectTimeout: 1 * time.Second, ReadWriteTimeout: 1 * time.Second, } // merge the default with user input if there is one if len(args) == 1 { timeout := args[0].(time.Duration) config.ConnectTimeout = timeout config.ReadWriteTimeout = timeout } if len(args) == 2 { config.ConnectTimeout = args[0].(time.Duration) config.ReadWriteTimeout = args[1].(time.Duration) } return &http.Client{ Transport: &http.Transport{ Dial: TimeoutDialer(config), }, } } -
dmichael revised this gist
Jun 5, 2013 . 2 changed files with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ package httpclient import ( "net" "net/http" "time" ) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ package httpclient import ( "io" "net" "net/http" "sync" -
dmichael revised this gist
Jun 5, 2013 . 1 changed file with 7 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,17 +2,22 @@ This wrapper takes care of both the connection timeout and the readwrite timeout. WARNING: You must instantiate this every time you want to use it, otherwise it is likely that the timeout is reached before you actually make the call. One argument sets the connect timeout and the readwrite timeout to the same value. Other wise, 2 arguments are 1) connect and 2) readwrite It returns an *http.Client */ package main import( "httpclient" "time" ) func main() { httpClient := httpclient.NewWithTimeout(500*time.Millisecond, 1*time.Second) resp, err := httpClient.Get("http://google.com") if err != nil { fmt.Println("Rats! Google is down.") -
dmichael revised this gist
Jun 5, 2013 . 1 changed file with 20 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,20 @@ /* This wrapper takes care of both the connection timeout and the readwrite timeout. WARNING: You must instantiate this every time you want to use it, otherwise it is likely that the timeout is reached before you actually make the call. */ package main import( "httpclient" "time ) func main() { httpClient := httpclient.NewWithTimeout(500*time.Millisecond) resp, err := httpClient.Get("http://google.com") if err != nil { fmt.Println("Rats! Google is down.") } } -
dmichael created this gist
Jun 5, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,49 @@ package httpclient import ( "net" "net/http" "time" ) type Config struct { ConnectTimeout time.Duration ReadWriteTimeout time.Duration } func TimeoutDialer(config *Config) func(net, addr string) (c net.Conn, err error) { return func(netw, addr string) (net.Conn, error) { conn, err := net.DialTimeout(netw, addr, config.ConnectTimeout) if err != nil { return nil, err } conn.SetDeadline(time.Now().Add(config.ReadWriteTimeout)) return conn, nil } } func NewTimeoutClient(args ...interface{}) *http.Client { // Default configuration config := &Config{ ConnectTimeout: 1 * time.Second, ReadWriteTimeout: 1 * time.Second, } // merge the default with user input if there is one if len(args) == 1 { timeout := args[0].(time.Duration) config.ConnectTimeout = timeout config.ReadWriteTimeout = timeout } if len(args) == 2 { config.ConnectTimeout = args[0].(time.Duration) config.ReadWriteTimeout = args[1].(time.Duration) } return &http.Client{ Transport: &http.Transport{ Dial: TimeoutDialer(config), }, } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,84 @@ package httpclient import ( "io" "net" "net/http" "sync" "testing" "time" ) var starter sync.Once var addr net.Addr func testHandler(w http.ResponseWriter, req *http.Request) { time.Sleep(500 * time.Millisecond) io.WriteString(w, "hello, world!\n") } func testDelayedHandler(w http.ResponseWriter, req *http.Request) { time.Sleep(2100 * time.Millisecond) io.WriteString(w, "hello, world ... in a bit\n") } func setupMockServer(t *testing.T) { http.HandleFunc("/test", testHandler) http.HandleFunc("/test-delayed", testDelayedHandler) ln, err := net.Listen("tcp", ":0") if err != nil { t.Fatalf("failed to listen - %s", err.Error()) } go func() { err = http.Serve(ln, nil) if err != nil { t.Fatalf("failed to start HTTP server - %s", err.Error()) } }() addr = ln.Addr() } func TestDefaultConfig(t *testing.T) { starter.Do(func() { setupMockServer(t) }) httpClient := NewTimeoutClient() req, _ := http.NewRequest("GET", "http://"+addr.String()+"/test-delayed", nil) httpClient = NewTimeoutClient() _, err := httpClient.Do(req) if err == nil { t.Fatalf("request should have timed out") } } func TestHttpClient(t *testing.T) { starter.Do(func() { setupMockServer(t) }) httpClient := NewTimeoutClient() req, _ := http.NewRequest("GET", "http://"+addr.String()+"/test", nil) resp, err := httpClient.Do(req) if err != nil { t.Fatalf("1st request failed - %s", err.Error()) } defer resp.Body.Close() connectTimeout := (250 * time.Millisecond) readWriteTimeout := (50 * time.Millisecond) httpClient = NewTimeoutClient(connectTimeout, readWriteTimeout) resp, err = httpClient.Do(req) if err == nil { t.Fatalf("2nd request should have timed out") } resp, err = httpClient.Do(req) if resp != nil { t.Fatalf("3nd request should not have timed out") } }