github.com/sagernet/sing-box@v1.9.0-rc.20/inbound/http.go (about) 1 package inbound 2 3 import ( 4 std_bufio "bufio" 5 "context" 6 "net" 7 "os" 8 9 "github.com/sagernet/sing-box/adapter" 10 "github.com/sagernet/sing-box/common/tls" 11 "github.com/sagernet/sing-box/common/uot" 12 C "github.com/sagernet/sing-box/constant" 13 "github.com/sagernet/sing-box/log" 14 "github.com/sagernet/sing-box/option" 15 "github.com/sagernet/sing/common" 16 "github.com/sagernet/sing/common/auth" 17 E "github.com/sagernet/sing/common/exceptions" 18 N "github.com/sagernet/sing/common/network" 19 "github.com/sagernet/sing/protocol/http" 20 ) 21 22 var ( 23 _ adapter.Inbound = (*HTTP)(nil) 24 _ adapter.InjectableInbound = (*HTTP)(nil) 25 ) 26 27 type HTTP struct { 28 myInboundAdapter 29 authenticator *auth.Authenticator 30 tlsConfig tls.ServerConfig 31 } 32 33 func NewHTTP(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HTTPMixedInboundOptions) (*HTTP, error) { 34 inbound := &HTTP{ 35 myInboundAdapter: myInboundAdapter{ 36 protocol: C.TypeHTTP, 37 network: []string{N.NetworkTCP}, 38 ctx: ctx, 39 router: uot.NewRouter(router, logger), 40 logger: logger, 41 tag: tag, 42 listenOptions: options.ListenOptions, 43 setSystemProxy: options.SetSystemProxy, 44 }, 45 authenticator: auth.NewAuthenticator(options.Users), 46 } 47 if options.TLS != nil { 48 tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS)) 49 if err != nil { 50 return nil, err 51 } 52 inbound.tlsConfig = tlsConfig 53 } 54 inbound.connHandler = inbound 55 return inbound, nil 56 } 57 58 func (h *HTTP) Start() error { 59 if h.tlsConfig != nil { 60 err := h.tlsConfig.Start() 61 if err != nil { 62 return E.Cause(err, "create TLS config") 63 } 64 } 65 return h.myInboundAdapter.Start() 66 } 67 68 func (h *HTTP) Close() error { 69 return common.Close( 70 &h.myInboundAdapter, 71 h.tlsConfig, 72 ) 73 } 74 75 func (h *HTTP) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 76 var err error 77 if h.tlsConfig != nil { 78 conn, err = tls.ServerHandshake(ctx, conn, h.tlsConfig) 79 if err != nil { 80 return err 81 } 82 } 83 return http.HandleConnection(ctx, conn, std_bufio.NewReader(conn), h.authenticator, h.upstreamUserHandler(metadata), adapter.UpstreamMetadata(metadata)) 84 } 85 86 func (h *HTTP) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 87 return os.ErrInvalid 88 } 89 90 func (a *myInboundAdapter) upstreamUserHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter { 91 return adapter.NewUpstreamHandler(metadata, a.newUserConnection, a.streamUserPacketConnection, a) 92 } 93 94 func (a *myInboundAdapter) newUserConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 95 user, loaded := auth.UserFromContext[string](ctx) 96 if !loaded { 97 a.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination) 98 return a.router.RouteConnection(ctx, conn, metadata) 99 } 100 metadata.User = user 101 a.logger.InfoContext(ctx, "[", user, "] inbound connection to ", metadata.Destination) 102 return a.router.RouteConnection(ctx, conn, metadata) 103 } 104 105 func (a *myInboundAdapter) streamUserPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 106 user, loaded := auth.UserFromContext[string](ctx) 107 if !loaded { 108 a.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination) 109 return a.router.RoutePacketConnection(ctx, conn, metadata) 110 } 111 metadata.User = user 112 a.logger.InfoContext(ctx, "[", user, "] inbound packet connection to ", metadata.Destination) 113 return a.router.RoutePacketConnection(ctx, conn, metadata) 114 }