@@ -20,21 +20,11 @@ import (
2020type DialerClient interface {
2121 IsClosed () bool
2222
23- // (ctx, baseURL, payload) -> err
24- // baseURL already contains sessionId and seq
25- SendUploadRequest (context.Context , string , io.ReadWriteCloser , int64 ) error
23+ // ctx, url, body, uploadOnly
24+ OpenStream (context.Context , string , io.Reader , bool ) (io.ReadCloser , net.Addr , net.Addr , error )
2625
27- // (ctx, baseURL) -> (downloadReader, remoteAddr, localAddr)
28- // baseURL already contains sessionId
29- OpenDownload (context.Context , string ) (io.ReadCloser , net.Addr , net.Addr , error )
30-
31- // (ctx, baseURL) -> uploadWriter
32- // baseURL already contains sessionId
33- OpenUpload (context.Context , string ) io.WriteCloser
34-
35- // (ctx, pureURL) -> (uploadWriter, downloadReader)
36- // pureURL can not contain sessionId
37- Open (context.Context , string ) (io.WriteCloser , io.ReadCloser )
26+ // ctx, url, body, contentLength
27+ PostPacket (context.Context , string , io.Reader , int64 ) error
3828}
3929
4030// implements splithttp.DialerClient in terms of direct network connections
@@ -52,136 +42,56 @@ func (c *DefaultDialerClient) IsClosed() bool {
5242 return c .closed
5343}
5444
55- func (c * DefaultDialerClient ) Open (ctx context.Context , pureURL string ) (io.WriteCloser , io.ReadCloser ) {
56- reader , writer := io .Pipe ()
57- req , _ := http .NewRequestWithContext (ctx , "POST" , pureURL , reader )
58- req .Header = c .transportConfig .GetRequestHeader ()
59- if ! c .transportConfig .NoGRPCHeader {
60- req .Header .Set ("Content-Type" , "application/grpc" )
61- }
62- wrc := & WaitReadCloser {Wait : make (chan struct {})}
63- go func () {
64- response , err := c .client .Do (req )
65- if err != nil || response .StatusCode != 200 {
66- if err != nil {
67- errors .LogInfoInner (ctx , err , "failed to open " , pureURL )
68- } else {
69- // c.closed = true
70- response .Body .Close ()
71- errors .LogInfo (ctx , "unexpected status " , response .StatusCode )
72- }
73- wrc .Close ()
74- return
75- }
76- wrc .Set (response .Body )
77- }()
78- return writer , wrc
79- }
80-
81- func (c * DefaultDialerClient ) OpenUpload (ctx context.Context , baseURL string ) io.WriteCloser {
82- reader , writer := io .Pipe ()
83- req , _ := http .NewRequestWithContext (ctx , "POST" , baseURL , reader )
84- req .Header = c .transportConfig .GetRequestHeader ()
85- if ! c .transportConfig .NoGRPCHeader {
86- req .Header .Set ("Content-Type" , "application/grpc" )
87- }
88- go func () {
89- if resp , err := c .client .Do (req ); err == nil {
90- if resp .StatusCode != 200 {
91- // c.closed = true
92- }
93- resp .Body .Close ()
94- }
95- }()
96- return writer
97- }
98-
99- func (c * DefaultDialerClient ) OpenDownload (ctx context.Context , baseURL string ) (io.ReadCloser , gonet.Addr , gonet.Addr , error ) {
100- var remoteAddr gonet.Addr
101- var localAddr gonet.Addr
45+ func (c * DefaultDialerClient ) OpenStream (ctx context.Context , url string , body io.Reader , uploadOnly bool ) (wrc io.ReadCloser , remoteAddr , localAddr gonet.Addr , err error ) {
10246 // this is done when the TCP/UDP connection to the server was established,
10347 // and we can unblock the Dial function and print correct net addresses in
10448 // logs
10549 gotConn := done .New ()
50+ ctx = httptrace .WithClientTrace (ctx , & httptrace.ClientTrace {
51+ GotConn : func (connInfo httptrace.GotConnInfo ) {
52+ remoteAddr = connInfo .Conn .RemoteAddr ()
53+ localAddr = connInfo .Conn .LocalAddr ()
54+ gotConn .Close ()
55+ },
56+ })
10657
107- var downResponse io.ReadCloser
108- gotDownResponse := done .New ()
109-
110- ctx , ctxCancel := context .WithCancel (ctx )
58+ method := "GET"
59+ if body != nil {
60+ method = "POST"
61+ }
62+ req , _ := http .NewRequestWithContext (ctx , method , url , body )
63+ req .Header = c .transportConfig .GetRequestHeader ()
64+ if method == "POST" && ! c .transportConfig .NoGRPCHeader {
65+ req .Header .Set ("Content-Type" , "application/grpc" )
66+ }
11167
68+ wrc = & WaitReadCloser {Wait : make (chan struct {})}
11269 go func () {
113- trace := & httptrace.ClientTrace {
114- GotConn : func (connInfo httptrace.GotConnInfo ) {
115- remoteAddr = connInfo .Conn .RemoteAddr ()
116- localAddr = connInfo .Conn .LocalAddr ()
117- gotConn .Close ()
118- },
119- }
120-
121- // in case we hit an error, we want to unblock this part
122- defer gotConn .Close ()
123-
124- ctx = httptrace .WithClientTrace (ctx , trace )
125-
126- req , err := http .NewRequestWithContext (
127- ctx ,
128- "GET" ,
129- baseURL ,
130- nil ,
131- )
132- if err != nil {
133- errors .LogInfoInner (ctx , err , "failed to construct download http request" )
134- gotDownResponse .Close ()
135- return
136- }
137-
138- req .Header = c .transportConfig .GetRequestHeader ()
139-
140- response , err := c .client .Do (req )
141- gotConn .Close ()
70+ resp , err := c .client .Do (req )
14271 if err != nil {
143- errors .LogInfoInner (ctx , err , "failed to send download http request" )
144- gotDownResponse .Close ()
72+ errors .LogInfoInner (ctx , err , "failed to " + method + " " + url )
73+ gotConn .Close ()
74+ wrc .Close ()
14575 return
14676 }
147-
148- if response .StatusCode != 200 {
77+ if resp .StatusCode != 200 && ! uploadOnly {
14978 // c.closed = true
150- response .Body .Close ()
151- errors .LogInfo (ctx , "invalid status code on download:" , response .Status )
152- gotDownResponse .Close ()
79+ errors .LogInfo (ctx , "unexpected status " , resp .StatusCode )
80+ }
81+ if resp .StatusCode != 200 || uploadOnly {
82+ resp .Body .Close ()
83+ wrc .Close ()
15384 return
15485 }
155-
156- downResponse = response .Body
157- gotDownResponse .Close ()
86+ wrc .(* WaitReadCloser ).Set (resp .Body )
15887 }()
15988
16089 <- gotConn .Wait ()
161-
162- lazyDownload := & LazyReader {
163- CreateReader : func () (io.Reader , error ) {
164- <- gotDownResponse .Wait ()
165- if downResponse == nil {
166- return nil , errors .New ("downResponse failed" )
167- }
168- return downResponse , nil
169- },
170- }
171-
172- // workaround for https://github.com/quic-go/quic-go/issues/2143 --
173- // always cancel request context so that Close cancels any Read.
174- // Should then match the behavior of http2 and http1.
175- reader := downloadBody {
176- lazyDownload ,
177- ctxCancel ,
178- }
179-
180- return reader , remoteAddr , localAddr , nil
90+ return
18191}
18292
183- func (c * DefaultDialerClient ) SendUploadRequest (ctx context.Context , url string , payload io.ReadWriteCloser , contentLength int64 ) error {
184- req , err := http .NewRequestWithContext (ctx , "POST" , url , payload )
93+ func (c * DefaultDialerClient ) PostPacket (ctx context.Context , url string , body io.Reader , contentLength int64 ) error {
94+ req , err := http .NewRequestWithContext (ctx , "POST" , url , body )
18595 if err != nil {
18696 return err
18797 }
@@ -257,16 +167,6 @@ func (c *DefaultDialerClient) SendUploadRequest(ctx context.Context, url string,
257167 return nil
258168}
259169
260- type downloadBody struct {
261- io.Reader
262- cancel context.CancelFunc
263- }
264-
265- func (c downloadBody ) Close () error {
266- c .cancel ()
267- return nil
268- }
269-
270170type WaitReadCloser struct {
271171 Wait chan struct {}
272172 io.ReadCloser
0 commit comments