mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-23 00:17:16 +08:00
Update On Sun Mar 29 20:57:20 CEST 2026
This commit is contained in:
+8
-8
@@ -378,7 +378,7 @@ jobs:
|
||||
EOF
|
||||
|
||||
- name: Upload Prerelease
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
tag_name: Prerelease-${{ github.ref_name }}
|
||||
@@ -468,10 +468,10 @@ jobs:
|
||||
working-directory: bin
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Setup Docker buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
@@ -480,7 +480,7 @@ jobs:
|
||||
- name: Extract Docker metadata
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
id: meta_alpha
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: '${{ env.REGISTRY }}/${{ github.repository }}'
|
||||
|
||||
@@ -489,7 +489,7 @@ jobs:
|
||||
- name: Extract Docker metadata
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }}
|
||||
id: meta_release
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: '${{ env.REGISTRY }}/${{ github.repository }}'
|
||||
tags: |
|
||||
@@ -504,7 +504,7 @@ jobs:
|
||||
ls bin/
|
||||
|
||||
- name: login to docker REGISTRY
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.DOCKER_HUB_USER }}
|
||||
@@ -514,7 +514,7 @@ jobs:
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push Docker image
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@@ -529,7 +529,7 @@ jobs:
|
||||
|
||||
- name: Build and push Docker image
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }}
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
|
||||
+4
-3
@@ -16,11 +16,12 @@ jobs:
|
||||
trigger-CMFA-update:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: tibdex/github-app-token@v1
|
||||
- uses: actions/create-github-app-token@v3
|
||||
id: generate-token
|
||||
with:
|
||||
app_id: ${{ secrets.MAINTAINER_APPID }}
|
||||
private_key: ${{ secrets.MAINTAINER_APP_PRIVATE_KEY }}
|
||||
app-id: ${{ secrets.MAINTAINER_APPID }}
|
||||
private-key: ${{ secrets.MAINTAINER_APP_PRIVATE_KEY }}
|
||||
owner: ${{ github.repository_owner }}
|
||||
|
||||
- name: Trigger update-dependencies
|
||||
run: |
|
||||
|
||||
@@ -267,8 +267,6 @@ func (v *Vless) dialXHTTPConn(ctx context.Context) (net.Conn, error) {
|
||||
case "stream-one":
|
||||
return xhttp.DialStreamOne(
|
||||
ctx,
|
||||
v.option.Server,
|
||||
v.option.Port,
|
||||
cfg,
|
||||
func(ctx context.Context) (net.Conn, error) {
|
||||
return v.dialer.DialContext(ctx, "tcp", v.addr)
|
||||
@@ -280,8 +278,6 @@ func (v *Vless) dialXHTTPConn(ctx context.Context) (net.Conn, error) {
|
||||
case "packet-up":
|
||||
return xhttp.DialPacketUp(
|
||||
ctx,
|
||||
v.option.Server,
|
||||
v.option.Port,
|
||||
cfg,
|
||||
func(ctx context.Context) (net.Conn, error) {
|
||||
return v.dialer.DialContext(ctx, "tcp", v.addr)
|
||||
|
||||
@@ -1,31 +1,15 @@
|
||||
package gun
|
||||
package httputils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
"github.com/metacubex/http/httptrace"
|
||||
)
|
||||
|
||||
type Transport struct {
|
||||
transport *http.Http2Transport
|
||||
cfg *Config
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func (t *Transport) Close() error {
|
||||
t.closeOnce.Do(func() {
|
||||
t.cancel()
|
||||
CloseHttp2Transport(t.transport)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
type NetAddr struct {
|
||||
remoteAddr net.Addr
|
||||
localAddr net.Addr
|
||||
@@ -39,7 +23,7 @@ func (addr NetAddr) LocalAddr() net.Addr {
|
||||
return addr.localAddr
|
||||
}
|
||||
|
||||
func (addr *NetAddr) SetAddrFromRequest(request *http.Request) {
|
||||
func SetAddrFromRequest(addr *NetAddr, request *http.Request) {
|
||||
if request.RemoteAddr != "" {
|
||||
metadata := C.Metadata{}
|
||||
if err := metadata.SetRemoteAddress(request.RemoteAddr); err == nil {
|
||||
@@ -51,10 +35,11 @@ func (addr *NetAddr) SetAddrFromRequest(request *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func (addr *NetAddr) SetRemoteAddr(remoteAddr net.Addr) {
|
||||
addr.remoteAddr = remoteAddr
|
||||
}
|
||||
|
||||
func (addr *NetAddr) SetLocalAddr(localAddr net.Addr) {
|
||||
addr.localAddr = localAddr
|
||||
func NewAddrContext(addr *NetAddr, ctx context.Context) context.Context {
|
||||
return httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{
|
||||
GotConn: func(connInfo httptrace.GotConnInfo) {
|
||||
addr.localAddr = connInfo.Conn.LocalAddr()
|
||||
addr.remoteAddr = connInfo.Conn.RemoteAddr()
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package httputils
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
)
|
||||
|
||||
type closeIdleTransport interface {
|
||||
CloseIdleConnections()
|
||||
}
|
||||
|
||||
func CloseTransport(roundTripper http.RoundTripper) {
|
||||
if tr, ok := roundTripper.(closeIdleTransport); ok {
|
||||
tr.CloseIdleConnections() // for *http.Transport
|
||||
}
|
||||
if tr, ok := roundTripper.(*http.Http2Transport); ok {
|
||||
closeHttp2Transport(tr) // for *http2.Transport
|
||||
}
|
||||
if tr, ok := roundTripper.(io.Closer); ok {
|
||||
_ = tr.Close() // for *http3.Transport
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package gun
|
||||
package httputils
|
||||
|
||||
import (
|
||||
"net"
|
||||
@@ -44,7 +44,7 @@ func closeClientConn(cc *http.Http2ClientConn) { // like forceCloseConn() in htt
|
||||
_ = cc.Close()
|
||||
}
|
||||
|
||||
func CloseHttp2Transport(tr *http.Http2Transport) {
|
||||
func closeHttp2Transport(tr *http.Http2Transport) {
|
||||
connPool := transportConnPool(tr)
|
||||
p := (*clientConnPool)((*efaceWords)(unsafe.Pointer(&connPool)).data)
|
||||
p.mu.Lock()
|
||||
@@ -17,13 +17,13 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/buf"
|
||||
"github.com/metacubex/mihomo/common/httputils"
|
||||
"github.com/metacubex/mihomo/common/pool"
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/vmess"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
"github.com/metacubex/http/httptrace"
|
||||
"github.com/metacubex/tls"
|
||||
)
|
||||
|
||||
@@ -40,10 +40,10 @@ var defaultHeader = http.Header{
|
||||
type DialFn = func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
|
||||
type Conn struct {
|
||||
initFn func() (io.ReadCloser, NetAddr, error)
|
||||
initFn func(addr *httputils.NetAddr) (io.ReadCloser, error)
|
||||
writer io.Writer // writer must not nil
|
||||
closer io.Closer
|
||||
NetAddr
|
||||
httputils.NetAddr
|
||||
|
||||
initOnce sync.Once
|
||||
initErr error
|
||||
@@ -66,7 +66,7 @@ type Config struct {
|
||||
}
|
||||
|
||||
func (g *Conn) initReader() {
|
||||
reader, addr, err := g.initFn()
|
||||
reader, err := g.initFn(&g.NetAddr)
|
||||
if err != nil {
|
||||
g.initErr = err
|
||||
if closer, ok := g.writer.(io.Closer); ok {
|
||||
@@ -74,7 +74,6 @@ func (g *Conn) initReader() {
|
||||
}
|
||||
return
|
||||
}
|
||||
g.NetAddr = addr
|
||||
|
||||
g.closeMutex.Lock()
|
||||
defer g.closeMutex.Unlock()
|
||||
@@ -152,8 +151,10 @@ func (g *Conn) Write(b []byte) (n int, err error) {
|
||||
buf.Write(b)
|
||||
|
||||
_, err = g.writer.Write(buf.Bytes())
|
||||
if err == io.ErrClosedPipe && g.initErr != nil {
|
||||
err = g.initErr
|
||||
if err == io.ErrClosedPipe {
|
||||
if initErr := g.Init(); initErr != nil {
|
||||
err = initErr
|
||||
}
|
||||
}
|
||||
|
||||
if flusher, ok := g.writer.(http.Flusher); ok {
|
||||
@@ -175,8 +176,10 @@ func (g *Conn) WriteBuffer(buffer *buf.Buffer) error {
|
||||
binary.PutUvarint(header[6:], uint64(dataLen))
|
||||
_, err := g.writer.Write(buffer.Bytes())
|
||||
|
||||
if err == io.ErrClosedPipe && g.initErr != nil {
|
||||
err = g.initErr
|
||||
if err == io.ErrClosedPipe {
|
||||
if initErr := g.Init(); initErr != nil {
|
||||
err = initErr
|
||||
}
|
||||
}
|
||||
|
||||
if flusher, ok := g.writer.(http.Flusher); ok {
|
||||
@@ -191,10 +194,6 @@ func (g *Conn) FrontHeadroom() int {
|
||||
}
|
||||
|
||||
func (g *Conn) Close() error {
|
||||
g.initOnce.Do(func() { // if initReader not called, it should not be run anymore
|
||||
g.initErr = net.ErrClosed
|
||||
})
|
||||
|
||||
g.closeMutex.Lock()
|
||||
defer g.closeMutex.Unlock()
|
||||
if g.closed {
|
||||
@@ -247,6 +246,22 @@ func (g *Conn) SetDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Transport struct {
|
||||
transport *http.Http2Transport
|
||||
cfg *Config
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func (t *Transport) Close() error {
|
||||
t.closeOnce.Do(func() {
|
||||
t.cancel()
|
||||
httputils.CloseTransport(t.transport)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewTransport(dialFn DialFn, tlsConfig *vmess.TLSConfig, gunCfg *Config) *Transport {
|
||||
dialFunc := func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, C.DefaultTLSTimeout)
|
||||
@@ -340,27 +355,27 @@ func (t *Transport) Dial() (net.Conn, error) {
|
||||
Header: header,
|
||||
}
|
||||
request = request.WithContext(t.ctx)
|
||||
initStarted := make(chan struct{})
|
||||
|
||||
conn := &Conn{
|
||||
initFn: func() (io.ReadCloser, NetAddr, error) {
|
||||
nAddr := NetAddr{}
|
||||
trace := &httptrace.ClientTrace{
|
||||
GotConn: func(connInfo httptrace.GotConnInfo) {
|
||||
nAddr.SetLocalAddr(connInfo.Conn.LocalAddr())
|
||||
nAddr.SetRemoteAddr(connInfo.Conn.RemoteAddr())
|
||||
},
|
||||
}
|
||||
request = request.WithContext(httptrace.WithClientTrace(request.Context(), trace))
|
||||
initFn: func(addr *httputils.NetAddr) (io.ReadCloser, error) {
|
||||
close(initStarted)
|
||||
request = request.WithContext(httputils.NewAddrContext(addr, request.Context()))
|
||||
response, err := t.transport.RoundTrip(request)
|
||||
if err != nil {
|
||||
return nil, nAddr, err
|
||||
return nil, err
|
||||
}
|
||||
return response.Body, nAddr, nil
|
||||
return response.Body, nil
|
||||
},
|
||||
writer: writer,
|
||||
}
|
||||
|
||||
go conn.Init()
|
||||
|
||||
// ensure conn.initOnce.Do has been called before return
|
||||
// prevent the race caused by the return side immediately calling conn.Close
|
||||
<-initStarted
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/buf"
|
||||
"github.com/metacubex/mihomo/common/httputils"
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
@@ -41,10 +42,9 @@ func NewServerHandler(options ServerOption) http.Handler {
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
|
||||
conn := &Conn{
|
||||
initFn: func() (io.ReadCloser, NetAddr, error) {
|
||||
nAddr := NetAddr{}
|
||||
nAddr.SetAddrFromRequest(request)
|
||||
return request.Body, nAddr, nil
|
||||
initFn: func(addr *httputils.NetAddr) (io.ReadCloser, error) {
|
||||
httputils.SetAddrFromRequest(addr, request)
|
||||
return request.Body, nil
|
||||
},
|
||||
writer: writer,
|
||||
}
|
||||
|
||||
@@ -11,20 +11,15 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/httputils"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/vmess"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
"github.com/metacubex/http/httptrace"
|
||||
"github.com/metacubex/tls"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type RoundTripper interface {
|
||||
http.RoundTripper
|
||||
CloseIdleConnections()
|
||||
}
|
||||
|
||||
type ResolvUDPFunc func(ctx context.Context, server string) (netip.AddrPort, error)
|
||||
|
||||
type ClientOptions struct {
|
||||
@@ -46,7 +41,7 @@ type Client struct {
|
||||
resolv ResolvUDPFunc
|
||||
server string
|
||||
auth string
|
||||
roundTripper RoundTripper
|
||||
roundTripper http.RoundTripper
|
||||
startOnce sync.Once
|
||||
healthCheck bool
|
||||
healthCheckTimer *time.Timer
|
||||
@@ -144,13 +139,7 @@ func (c *Client) roundTrip(request *http.Request, conn *httpConn) {
|
||||
go func() {
|
||||
timeout := time.AfterFunc(C.DefaultTCPTimeout, cancel) // only cancel when RoundTrip timeout
|
||||
defer timeout.Stop() // RoundTrip already returned, stop the timer
|
||||
trace := &httptrace.ClientTrace{
|
||||
GotConn: func(connInfo httptrace.GotConnInfo) {
|
||||
conn.SetLocalAddr(connInfo.Conn.LocalAddr())
|
||||
conn.SetRemoteAddr(connInfo.Conn.RemoteAddr())
|
||||
},
|
||||
}
|
||||
request = request.WithContext(httptrace.WithClientTrace(ctx, trace))
|
||||
request = request.WithContext(httputils.NewAddrContext(&conn.NetAddr, ctx))
|
||||
response, err := c.roundTripper.RoundTrip(request)
|
||||
if err != nil {
|
||||
_ = pipeWriter.CloseWithError(err)
|
||||
@@ -221,7 +210,7 @@ func (c *Client) ListenICMP(ctx context.Context) (*IcmpConn, error) {
|
||||
}
|
||||
|
||||
func (c *Client) Close() error {
|
||||
forceCloseAllConnections(c.roundTripper)
|
||||
httputils.CloseTransport(c.roundTripper)
|
||||
if c.healthCheckTimer != nil {
|
||||
c.healthCheckTimer.Stop()
|
||||
}
|
||||
@@ -229,7 +218,7 @@ func (c *Client) Close() error {
|
||||
}
|
||||
|
||||
func (c *Client) ResetConnections() {
|
||||
forceCloseAllConnections(c.roundTripper)
|
||||
httputils.CloseTransport(c.roundTripper)
|
||||
c.resetHealthCheckTimer()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package trusttunnel
|
||||
|
||||
import (
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
"github.com/metacubex/quic-go/http3"
|
||||
)
|
||||
|
||||
func forceCloseAllConnections(roundTripper RoundTripper) {
|
||||
roundTripper.CloseIdleConnections()
|
||||
switch tr := roundTripper.(type) {
|
||||
case *http.Http2Transport:
|
||||
gun.CloseHttp2Transport(tr)
|
||||
case *http3.Transport:
|
||||
_ = tr.Close()
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/httputils"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -98,7 +98,7 @@ type httpConn struct {
|
||||
created chan struct{}
|
||||
createErr error
|
||||
cancelFn func()
|
||||
gun.NetAddr
|
||||
httputils.NetAddr
|
||||
|
||||
// deadlines
|
||||
deadline *time.Timer
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/httputils"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
"github.com/metacubex/http/h2c"
|
||||
"github.com/metacubex/quic-go/http3"
|
||||
@@ -160,7 +162,7 @@ func (s *Service) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
},
|
||||
},
|
||||
}
|
||||
conn.SetAddrFromRequest(request)
|
||||
httputils.SetAddrFromRequest(&conn.NetAddr, request)
|
||||
conn.setUp(request.Body, nil)
|
||||
firstPacket := buf.NewPacket()
|
||||
destination, err := conn.ReadPacket(firstPacket)
|
||||
@@ -197,7 +199,7 @@ func (s *Service) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
created: make(chan struct{}),
|
||||
},
|
||||
}
|
||||
conn.SetAddrFromRequest(request)
|
||||
httputils.SetAddrFromRequest(&conn.NetAddr, request)
|
||||
conn.setUp(request.Body, nil)
|
||||
s.icmpHandler.NewICMPConnection(ctx, conn)
|
||||
}
|
||||
@@ -220,7 +222,7 @@ func (s *Service) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
created: make(chan struct{}),
|
||||
},
|
||||
}
|
||||
conn.SetAddrFromRequest(request)
|
||||
httputils.SetAddrFromRequest(&conn.NetAddr, request)
|
||||
conn.setUp(request.Body, nil)
|
||||
_ = s.handler.NewConnection(ctx, conn, M.Metadata{
|
||||
Protocol: "trusttunnel",
|
||||
|
||||
@@ -10,47 +10,33 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/contextutils"
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
"github.com/metacubex/mihomo/common/httputils"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
"github.com/metacubex/http/httptrace"
|
||||
"github.com/metacubex/tls"
|
||||
)
|
||||
|
||||
type DialRawFunc func(ctx context.Context) (net.Conn, error)
|
||||
type WrapTLSFunc func(ctx context.Context, conn net.Conn, isH2 bool) (net.Conn, error)
|
||||
|
||||
type PacketUpConn struct {
|
||||
type PacketUpWriter struct {
|
||||
ctx context.Context
|
||||
cfg *Config
|
||||
address string
|
||||
port int
|
||||
host string
|
||||
sessionID string
|
||||
client *http.Client
|
||||
transport http.RoundTripper
|
||||
writeMu sync.Mutex
|
||||
seq uint64
|
||||
reader io.ReadCloser
|
||||
gun.NetAddr
|
||||
|
||||
// deadlines
|
||||
deadline *time.Timer
|
||||
}
|
||||
|
||||
func (c *PacketUpConn) Read(b []byte) (int, error) {
|
||||
return c.reader.Read(b)
|
||||
}
|
||||
|
||||
func (c *PacketUpConn) Write(b []byte) (int, error) {
|
||||
func (c *PacketUpWriter) Write(b []byte) (int, error) {
|
||||
c.writeMu.Lock()
|
||||
defer c.writeMu.Unlock()
|
||||
|
||||
u := url.URL{
|
||||
Scheme: "https",
|
||||
Host: c.host,
|
||||
Host: c.cfg.Host,
|
||||
Path: c.cfg.NormalizedPath(),
|
||||
}
|
||||
|
||||
@@ -65,9 +51,9 @@ func (c *PacketUpConn) Write(b []byte) (int, error) {
|
||||
if err := c.cfg.FillPacketRequest(req, c.sessionID, seqStr, b); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
req.Host = c.host
|
||||
req.Host = c.cfg.Host
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
resp, err := c.transport.RoundTrip(req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -81,51 +67,20 @@ func (c *PacketUpConn) Write(b []byte) (int, error) {
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (c *PacketUpConn) Close() error {
|
||||
if c.reader != nil {
|
||||
return c.reader.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *PacketUpConn) SetReadDeadline(t time.Time) error { return c.SetDeadline(t) }
|
||||
func (c *PacketUpConn) SetWriteDeadline(t time.Time) error { return c.SetDeadline(t) }
|
||||
|
||||
func (c *PacketUpConn) SetDeadline(t time.Time) error {
|
||||
if t.IsZero() {
|
||||
if c.deadline != nil {
|
||||
c.deadline.Stop()
|
||||
c.deadline = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
d := time.Until(t)
|
||||
if c.deadline != nil {
|
||||
c.deadline.Reset(d)
|
||||
return nil
|
||||
}
|
||||
c.deadline = time.AfterFunc(d, func() {
|
||||
c.Close()
|
||||
})
|
||||
func (c *PacketUpWriter) Close() error {
|
||||
httputils.CloseTransport(c.transport)
|
||||
return nil
|
||||
}
|
||||
|
||||
func DialStreamOne(
|
||||
ctx context.Context,
|
||||
address string,
|
||||
port int,
|
||||
cfg *Config,
|
||||
dialRaw DialRawFunc,
|
||||
wrapTLS WrapTLSFunc,
|
||||
) (net.Conn, error) {
|
||||
host := cfg.Host
|
||||
if host == "" {
|
||||
host = address
|
||||
}
|
||||
|
||||
requestURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: host,
|
||||
Host: cfg.Host,
|
||||
Path: cfg.NormalizedPath(),
|
||||
}
|
||||
|
||||
@@ -144,30 +99,19 @@ func DialStreamOne(
|
||||
},
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
pr, pw := io.Pipe()
|
||||
|
||||
conn := &Conn{
|
||||
writer: pw,
|
||||
}
|
||||
|
||||
trace := &httptrace.ClientTrace{
|
||||
GotConn: func(connInfo httptrace.GotConnInfo) {
|
||||
conn.SetLocalAddr(connInfo.Conn.LocalAddr())
|
||||
conn.SetRemoteAddr(connInfo.Conn.RemoteAddr())
|
||||
},
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(httptrace.WithClientTrace(contextutils.WithoutCancel(ctx), trace), http.MethodPost, requestURL.String(), pr)
|
||||
req, err := http.NewRequestWithContext(httputils.NewAddrContext(&conn.NetAddr, contextutils.WithoutCancel(ctx)), http.MethodPost, requestURL.String(), pr)
|
||||
if err != nil {
|
||||
_ = pr.Close()
|
||||
_ = pw.Close()
|
||||
return nil, err
|
||||
}
|
||||
req.Host = host
|
||||
req.Host = cfg.Host
|
||||
|
||||
if err := cfg.FillStreamRequest(req); err != nil {
|
||||
_ = pr.Close()
|
||||
@@ -175,34 +119,25 @@ func DialStreamOne(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type respResult struct {
|
||||
resp *http.Response
|
||||
err error
|
||||
}
|
||||
|
||||
respCh := make(chan respResult, 1)
|
||||
|
||||
go func() {
|
||||
resp, err := client.Do(req)
|
||||
respCh <- respResult{resp: resp, err: err}
|
||||
}()
|
||||
|
||||
result := <-respCh
|
||||
if result.err != nil {
|
||||
resp, err := transport.RoundTrip(req)
|
||||
if err != nil {
|
||||
_ = pr.Close()
|
||||
_ = pw.Close()
|
||||
return nil, result.err
|
||||
httputils.CloseTransport(transport)
|
||||
return nil, err
|
||||
}
|
||||
if result.resp.StatusCode < 200 || result.resp.StatusCode >= 300 {
|
||||
_ = result.resp.Body.Close()
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
_ = resp.Body.Close()
|
||||
_ = pr.Close()
|
||||
_ = pw.Close()
|
||||
return nil, fmt.Errorf("xhttp stream-one bad status: %s", result.resp.Status)
|
||||
httputils.CloseTransport(transport)
|
||||
return nil, fmt.Errorf("xhttp stream-one bad status: %s", resp.Status)
|
||||
}
|
||||
conn.reader = result.resp.Body
|
||||
conn.reader = resp.Body
|
||||
conn.onClose = func() {
|
||||
_ = result.resp.Body.Close()
|
||||
_ = resp.Body.Close()
|
||||
_ = pr.Close()
|
||||
httputils.CloseTransport(transport)
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
@@ -210,17 +145,10 @@ func DialStreamOne(
|
||||
|
||||
func DialPacketUp(
|
||||
ctx context.Context,
|
||||
address string,
|
||||
port int,
|
||||
cfg *Config,
|
||||
dialRaw DialRawFunc,
|
||||
wrapTLS WrapTLSFunc,
|
||||
) (net.Conn, error) {
|
||||
host := cfg.Host
|
||||
if host == "" {
|
||||
host = address
|
||||
}
|
||||
|
||||
transport := &http.Http2Transport{
|
||||
DialTLSContext: func(ctx context.Context, network string, addr string, _ *tls.Config) (net.Conn, error) {
|
||||
raw, err := dialRaw(ctx)
|
||||
@@ -236,49 +164,40 @@ func DialPacketUp(
|
||||
},
|
||||
}
|
||||
|
||||
client := &http.Client{Transport: transport}
|
||||
|
||||
sessionID := newSessionID()
|
||||
|
||||
downloadURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: host,
|
||||
Host: cfg.Host,
|
||||
Path: cfg.NormalizedPath(),
|
||||
}
|
||||
|
||||
conn := &PacketUpConn{
|
||||
ctx: contextutils.WithoutCancel(ctx),
|
||||
ctx = contextutils.WithoutCancel(ctx)
|
||||
writer := &PacketUpWriter{
|
||||
ctx: ctx,
|
||||
cfg: cfg,
|
||||
address: address,
|
||||
port: port,
|
||||
host: host,
|
||||
sessionID: sessionID,
|
||||
client: client,
|
||||
transport: transport,
|
||||
seq: 0,
|
||||
}
|
||||
conn := &Conn{writer: writer}
|
||||
|
||||
trace := &httptrace.ClientTrace{
|
||||
GotConn: func(connInfo httptrace.GotConnInfo) {
|
||||
conn.SetLocalAddr(connInfo.Conn.LocalAddr())
|
||||
conn.SetRemoteAddr(connInfo.Conn.RemoteAddr())
|
||||
},
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(httptrace.WithClientTrace(conn.ctx, trace), http.MethodGet, downloadURL.String(), nil)
|
||||
req, err := http.NewRequestWithContext(httputils.NewAddrContext(&conn.NetAddr, ctx), http.MethodGet, downloadURL.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := cfg.FillDownloadRequest(req, sessionID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Host = host
|
||||
req.Host = cfg.Host
|
||||
|
||||
resp, err := client.Do(req)
|
||||
resp, err := transport.RoundTrip(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
_ = resp.Body.Close()
|
||||
httputils.CloseTransport(transport)
|
||||
return nil, fmt.Errorf("xhttp packet-up download bad status: %s", resp.Status)
|
||||
}
|
||||
conn.reader = resp.Body
|
||||
|
||||
@@ -4,14 +4,14 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
"github.com/metacubex/mihomo/common/httputils"
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
writer io.WriteCloser
|
||||
reader io.ReadCloser
|
||||
onClose func()
|
||||
gun.NetAddr
|
||||
httputils.NetAddr
|
||||
|
||||
// deadlines
|
||||
deadline *time.Timer
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/httputils"
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
|
||||
"github.com/metacubex/http"
|
||||
@@ -194,7 +195,7 @@ func (h *requestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
writer: httpSC,
|
||||
reader: httpSC,
|
||||
}
|
||||
conn.SetAddrFromRequest(r)
|
||||
httputils.SetAddrFromRequest(&conn.NetAddr, r)
|
||||
|
||||
go h.connHandler(N.NewDeadlineConn(conn))
|
||||
|
||||
@@ -228,7 +229,7 @@ func (h *requestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
h.deleteSession(sessionID)
|
||||
},
|
||||
}
|
||||
conn.SetAddrFromRequest(r)
|
||||
httputils.SetAddrFromRequest(&conn.NetAddr, r)
|
||||
|
||||
go h.connHandler(N.NewDeadlineConn(conn))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user