golang httpclient.go
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang httpclient.go相关的知识,希望对你有一定的参考价值。
package httptimeout
import (
"io"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestHttpTimeout(t *testing.T) {
http.HandleFunc("/normal", func(w http.ResponseWriter, req *http.Request) {
// Empirically, timeouts less than these seem to be flaky
time.Sleep(100 * time.Millisecond)
io.WriteString(w, "ok")
})
http.HandleFunc("/timeout", func(w http.ResponseWriter, req *http.Request) {
time.Sleep(250 * time.Millisecond)
io.WriteString(w, "ok")
})
ts := httptest.NewServer(http.DefaultServeMux)
defer ts.Close()
numDials := 0
client := &http.Client{
Transport: &TimeoutTransport{
Transport: http.Transport{
Dial: func(netw, addr string) (net.Conn, error) {
t.Logf("dial to %s://%s", netw, addr)
numDials++ // For testing only.
return net.Dial(netw, addr) // Regular ass dial.
},
},
RoundTripTimeout: time.Millisecond * 200,
},
}
addr := ts.URL
SendTestRequest(t, client, "1st", addr, "normal")
if numDials != 1 {
t.Fatalf("Should only have 1 dial at this point.")
}
SendTestRequest(t, client, "2st", addr, "normal")
if numDials != 1 {
t.Fatalf("Should only have 1 dial at this point.")
}
SendTestRequest(t, client, "3st", addr, "timeout")
if numDials != 1 {
t.Fatalf("Should only have 1 dial at this point.")
}
SendTestRequest(t, client, "4st", addr, "normal")
if numDials != 2 {
t.Fatalf("Should have our 2nd dial.")
}
time.Sleep(time.Millisecond * 700)
SendTestRequest(t, client, "5st", addr, "normal")
if numDials != 2 {
t.Fatalf("Should still only have 2 dials.")
}
}
func SendTestRequest(t *testing.T, client *http.Client, id, addr, path string) {
req, err := http.NewRequest("GET", addr+"/"+path, nil)
if err != nil {
t.Fatalf("new request failed - %s", err)
}
req.Header.Add("Connection", "keep-alive")
switch path {
case "normal":
if resp, err := client.Do(req); err != nil {
t.Fatalf("%s request failed - %s", id, err)
} else {
result, err2 := ioutil.ReadAll(resp.Body)
if err2 != nil {
t.Fatalf("%s response read failed - %s", id, err2)
}
resp.Body.Close()
t.Logf("%s request - %s", id, result)
}
case "timeout":
if _, err := client.Do(req); err == nil {
t.Fatalf("%s request not timeout", id)
} else {
t.Logf("%s request - %s", id, err)
}
}
}
package httptimeout
import (
"net/http"
"time"
"fmt"
)
type TimeoutTransport struct {
http.Transport
RoundTripTimeout time.Duration
}
type respAndErr struct {
resp *http.Response
err error
}
type netTimeoutError struct {
error
}
func (ne netTimeoutError) Timeout() bool { return true }
// If you don't set RoundTrip on TimeoutTransport, this will always timeout at 0
func (t *TimeoutTransport) RoundTrip(req *http.Request) (*http.Response, error) {
timeout := time.After(t.RoundTripTimeout)
resp := make(chan respAndErr, 1)
go func() {
r, e := t.Transport.RoundTrip(req)
resp <- respAndErr{
resp: r,
err: e,
}
}()
select {
case <-timeout:// A round trip timeout has occurred.
t.Transport.CancelRequest(req)
return nil, netTimeoutError{
error: fmt.Errorf("timed out after %s", t.RoundTripTimeout),
}
case r := <-resp: // Success!
return r.resp, r.err
}
}
golang为啥没有官方的gui包
有两个方面的原因,一是golang gui想让第三方来做 , 二是官方对golang的定位是主做后台。。。
参考技术A
因为golang官方主要把精力投入到go本身的发展中去(更准确的GC算法、更高的并发)。 而golang的主要贡献者不多,所以还不是很忙的过来,golang官方希望GUI可以靠社区推动发展,官方本身是没有意向发布GUI包的。
以上是关于golang httpclient.go的主要内容,如果未能解决你的问题,请参考以下文章
Golang 入门
Golang入门到项目实战 第一个golang应用
golang编译androidso无法加载
golang如何打印内存内容
Golang入门到项目实战 golang匿名函数
json [Golang] golang #golang #snippets中有用的片段