Skip to content

Commit

Permalink
refactor http3 dailer
Browse files Browse the repository at this point in the history
  • Loading branch information
phuslu committed May 19, 2024
1 parent 86efbbd commit 1054f3b
Showing 1 changed file with 53 additions and 13 deletions.
66 changes: 53 additions & 13 deletions dialer_http3.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net/url"
"sync"
"sync/atomic"
"time"

"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/http3"
Expand Down Expand Up @@ -90,19 +91,19 @@ func (d *HTTP3Dialer) init() {
func (d *HTTP3Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
d.init()

pr, pw := io.Pipe()
req := &http.Request{
ProtoMajor: 3,
Method: http.MethodConnect,
URL: &url.URL{
Scheme: "https",
Host: addr,
},
Host: addr,
Header: http.Header{
"content-type": []string{"application/octet-stream"},
"user-agent": []string{d.UserAgent},
},
Body: nil,
Body: pr,
ContentLength: -1,
}

Expand All @@ -118,7 +119,7 @@ func (d *HTTP3Dialer) DialContext(ctx context.Context, network, addr string) (ne
},
}))

resp, err := d.transport.Load().(*http3.RoundTripper).RoundTripOpt(req, http3.RoundTripOpt{OnlyCachedConn: false})
resp, err := d.transport.Load().(*http3.RoundTripper).RoundTrip(req)
if err != nil {
return nil, err
}
Expand All @@ -129,32 +130,71 @@ func (d *HTTP3Dialer) DialContext(ctx context.Context, network, addr string) (ne
return nil, errors.New("proxy: read from " + d.Host + " error: " + resp.Status + ": " + string(data))
}

streamer, ok := resp.Body.(http3.HTTPStreamer)
if !ok {
return nil, errors.New("proxy: read from " + d.Host + " error: resp body not implemented http3.HTTPStreamer")
}

if remoteAddr == nil || localAddr == nil {
remoteAddr, localAddr = &net.UDPAddr{}, &net.UDPAddr{}
remoteAddr, localAddr = &net.TCPAddr{}, &net.TCPAddr{}
}

return &http3Stream{
Stream: streamer.HTTPStream(),
conn := &http3Stream{
r: resp.Body,
w: pw,
closed: make(chan struct{}),
remoteAddr: remoteAddr,
localAddr: localAddr,
}, nil
}

return conn, nil
}

type http3Stream struct {
quic.Stream
r io.ReadCloser
w io.Writer

closed chan struct{}

remoteAddr net.Addr
localAddr net.Addr
}

func (c *http3Stream) Read(b []byte) (n int, err error) {
return c.r.Read(b)
}

func (c *http3Stream) Write(b []byte) (n int, err error) {
return c.w.Write(b)
}

func (c *http3Stream) Close() (err error) {
select {
case <-c.closed:
return
default:
close(c.closed)
}
if rc, ok := c.r.(io.Closer); ok {
err = rc.Close()
}
if w, ok := c.w.(io.Closer); ok {
err = w.Close()
}
return
}

func (c *http3Stream) RemoteAddr() net.Addr {
return c.remoteAddr
}

func (c *http3Stream) LocalAddr() net.Addr {
return c.localAddr
}

func (c *http3Stream) SetDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "http3", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}

func (c *http3Stream) SetReadDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "http3", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}

func (c *http3Stream) SetWriteDeadline(t time.Time) error {
return &net.OpError{Op: "set", Net: "http3", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}

0 comments on commit 1054f3b

Please sign in to comment.