|
@@ -8,6 +8,7 @@ import (
|
|
|
"net/http"
|
|
"net/http"
|
|
|
"net/url"
|
|
"net/url"
|
|
|
"sync"
|
|
"sync"
|
|
|
|
|
+ "time"
|
|
|
|
|
|
|
|
"golang.org/x/net/http2"
|
|
"golang.org/x/net/http2"
|
|
|
|
|
|
|
@@ -79,14 +80,23 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|
|
var user *protocol.MemoryUser
|
|
var user *protocol.MemoryUser
|
|
|
var conn internet.Connection
|
|
var conn internet.Connection
|
|
|
|
|
|
|
|
- mbuf, _ := link.Reader.ReadMultiBuffer()
|
|
|
|
|
- len := mbuf.Len()
|
|
|
|
|
- firstPayload := bytespool.Alloc(len)
|
|
|
|
|
- mbuf, _ = buf.SplitBytes(mbuf, firstPayload)
|
|
|
|
|
- firstPayload = firstPayload[:len]
|
|
|
|
|
-
|
|
|
|
|
- buf.ReleaseMulti(mbuf)
|
|
|
|
|
- defer bytespool.Free(firstPayload)
|
|
|
|
|
|
|
+ var firstPayload []byte
|
|
|
|
|
+
|
|
|
|
|
+ if reader, ok := link.Reader.(buf.TimeoutReader); ok {
|
|
|
|
|
+ // 0-RTT optimization for HTTP/2: If the payload comes within 50 ms, it can be
|
|
|
|
|
+ // transmitted together. Note we should not get stuck here, as the payload may
|
|
|
|
|
+ // not exist (considering to access MySQL database via a HTTP proxy, where the
|
|
|
|
|
+ // server sends hello to the client first).
|
|
|
|
|
+ if mbuf, _ := reader.ReadMultiBufferTimeout(50 * time.Millisecond); mbuf != nil {
|
|
|
|
|
+ mlen := mbuf.Len()
|
|
|
|
|
+ firstPayload = bytespool.Alloc(mlen)
|
|
|
|
|
+ mbuf, _ = buf.SplitBytes(mbuf, firstPayload)
|
|
|
|
|
+ firstPayload = firstPayload[:mlen]
|
|
|
|
|
+
|
|
|
|
|
+ buf.ReleaseMulti(mbuf)
|
|
|
|
|
+ defer bytespool.Free(firstPayload)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
|
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
|
|
server := c.serverPicker.PickServer()
|
|
server := c.serverPicker.PickServer()
|