Created
August 16, 2017 14:55
-
-
Save mikemadisonweb/72067f5e7123b98259d87511236ccc78 to your computer and use it in GitHub Desktop.
Run a http.Get async with support for aborting
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 characters
package main | |
import ( | |
"errors" | |
"fmt" | |
"net" | |
"net/http" | |
"sync" | |
"time" | |
) | |
type GetResponse struct { | |
Resp *http.Response | |
Error error | |
} | |
type Request struct { | |
mu sync.Mutex | |
conn net.Conn | |
client *http.Client | |
Resp chan GetResponse | |
} | |
func abortDial(netw, addr string) (net.Conn, error) { | |
return nil, errors.New("aborted") | |
} | |
func (r *Request) Bail() { | |
r.mu.Lock() | |
defer r.mu.Unlock() | |
if r.conn != nil { | |
r.conn.Close() | |
} | |
r.client.Transport.(*http.Transport).Dial = abortDial | |
} | |
func (r *Request) set(c net.Conn) { | |
r.mu.Lock() | |
defer r.mu.Unlock() | |
r.conn = c | |
} | |
func Get(url string) (r *Request) { | |
dial := func(netw, addr string) (c net.Conn, err error) { | |
c, err = net.Dial(netw, addr) | |
r.set(c) | |
return | |
} | |
transport := &http.Transport{ | |
Proxy: http.ProxyFromEnvironment, | |
Dial: dial, | |
} | |
r = &Request{ | |
Resp: make(chan GetResponse), | |
client: &http.Client{Transport: transport}, | |
} | |
go func() { | |
resp, err := r.client.Get(url) | |
r.Resp <- GetResponse{resp, err} | |
}() | |
return | |
} | |
func main() { | |
req := Get("http://google.com") | |
for { | |
select { | |
case resp := <-req.Resp: | |
fmt.Println(resp) | |
return | |
case <-time.After(time.Second): | |
req.Bail() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment