郭學聰 Hsueh-Tsung Kuo
Sun, 02 Aug 2020
Someone (who?) said:
a game programmer should be able to draw cute anime character(?)
Leak File Descriptors
http: Accept error: accept tcp [::]:80: accept4: too many open files; retrying in 5ms
Slowloris
https://en.wikipedia.org/wiki/Slowloris_(computer_security)
The complete guide to Go net/http timeouts
https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
srv := &http.Server{ ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, IdleTimeout: 60 * time.Second, ReadHeaderTimeout: 1 * time.Second, } log.Println(srv.ListenAndServe())
c := &http.Client{ Timeout: 15 * time.Second, } resp, err := c.Get("https://blog.filippo.io/")
c := &http.Client{ Transport: &http.Transport{ Dial: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).Dial, TLSHandshakeTimeout: 10 * time.Second, ResponseHeaderTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, IdleConnTimeout: 60 * time.Second, } }
net/http: no way of manipulating timeouts in Handler #16100
https://github.com/golang/go/issues/16100
ctx := context.Background() client := http.DefaultClient requestMod := stream_http.RequestMod(func(req *http.Request) { req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("Authorization", "Bearer qawsedrftgyhujikolp") query := req.URL.Query() query.Add("param", "pvalue") req.URL.RawQuery = query.Encode() }) requestTimeout := stream_http.Timeout(500 * time.Millisecond) reqBody := bytes.NewBuffer([]byte("form=fvalue")) var respBody bytes.Buffer resp, err := stream_http.DoRequest(ctx, client, http.MethodPost, "http://httpbin.org/anything", reqBody, &respBody, requestMod, requestTimeout) //resp, err := stream_http.DoRequest(ctx, client, http.MethodGet, "http://httpbin.org/status/401", nil, &respBody, requestMod, requestTimeout) if err != nil { return err } fmt.Printf("get response with status code: %d\n%s\n", resp.StatusCode, respBody.String())
digraph client_control_flow {
nodesep=1.0 // increases the separation between nodes
node [color="hotpink" shape=box]
edge [color="hotpink" style=dashed]
with_cancel [shape="oval" label="context.WithCancel()"]
context_parent [label="parent context"]
context [label="context"]
cancel [color="gray" label="cancel()"]
client_do [shape="oval" label="client.Do()"]
timer [shape="oval" label="time.AfterFunc()"]
context_parent->with_cancel [style=solid]
with_cancel->context [style=solid]
with_cancel->cancel [style=solid]
cancel->context [color="gray"]
context->client_do [style=solid]
timer->cancel [color="orange"]
}
func handleFunc(w http.ResponseWriter, req *http.Request) { n, err := stream_http.TimeoutCopy(&reqBody, req.Body, time.Duration(-1), 500*time.Millisecond) n, err = stream_http.TimeoutCopy(w, &respBody, 500*time.Millisecond, time.Duration(-1)) }
note left of handler: receive request
handler->TimeoutCopy(): call
TimeoutCopy()->runtimeTimer: time.NewTimer()
TimeoutCopy()->copy goroutine: request/response_writer
note right of copy goroutine: chunk transmitted
copy goroutine->runtimeTimer: timer.Reset()/timer.Stop()
note right of copy goroutine: copy finished
copy goroutine->TimeoutCopy(): copyResult/panic
TimeoutCopy()->handler: copy result
note left of handler: send ok/error response
note right of runtimeTimer: timeout
runtimeTimer->TimeoutCopy(): timer.C
TimeoutCopy()->handler: error timeout
TimeoutCopy()->copy goroutine: close(doneChan)
note left of handler: send timeout response
How to correctly stop server handler?
¯\_(ツ)_/¯
time: Timer.C can still trigger even after Timer.Reset is called #11513
https://github.com/golang/go/issues/11513
Timer.Reset() note
https://golang.org/pkg/time/#Timer.Reset
if !t.Stop() { <-t.C } t.Reset(d)
This should not be done concurrent to other receives from the Timer's channel.
time: Timer.Reset is not possible to use correctly #14038
https://github.com/golang/go/issues/14038
Timer.Reset() note
https://golang.org/pkg/time/#Timer.Reset
if !t.Stop() { <-t.C // don't do this if t.C is drained from another goroutine } _ = t.Reset(d) // don't use return value
Georg Wilhelm Friedrich Hegel
https://de.wikipedia.org/wiki/Georg_Wilhelm_Friedrich_Hegel
Was die Erfahrung aber und die Geschichte lehren, ist dieses, daß Völker und Regierungen niemals etwas aus der Geschichte gelernt und nach Lehren, die aus derselben zu ziehen gewesen wären, gehandelt haben.
Georg Wilhelm Friedrich Hegel
We learn from history that we do not learn from history.
Georg Wilhelm Friedrich Hegel
郭學聰 Hsueh-Tsung Kuo2020_08_02