http.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package outbound
  2. import (
  3. "context"
  4. "net"
  5. "net/http"
  6. "os"
  7. "github.com/sagernet/sing-box/adapter"
  8. "github.com/sagernet/sing-box/common/dialer"
  9. "github.com/sagernet/sing-box/common/tls"
  10. C "github.com/sagernet/sing-box/constant"
  11. "github.com/sagernet/sing-box/log"
  12. "github.com/sagernet/sing-box/option"
  13. "github.com/sagernet/sing/common"
  14. M "github.com/sagernet/sing/common/metadata"
  15. N "github.com/sagernet/sing/common/network"
  16. sHTTP "github.com/sagernet/sing/protocol/http"
  17. )
  18. var _ adapter.Outbound = (*HTTP)(nil)
  19. type HTTP struct {
  20. myOutboundAdapter
  21. client *sHTTP.Client
  22. }
  23. func NewHTTP(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HTTPOutboundOptions) (*HTTP, error) {
  24. outboundDialer, err := dialer.New(router, options.DialerOptions)
  25. if err != nil {
  26. return nil, err
  27. }
  28. detour, err := tls.NewDialerFromOptions(ctx, router, outboundDialer, options.Server, common.PtrValueOrDefault(options.TLS))
  29. if err != nil {
  30. return nil, err
  31. }
  32. var headers http.Header
  33. if options.Headers != nil {
  34. headers = make(http.Header)
  35. for key, values := range options.Headers {
  36. headers[key] = values
  37. }
  38. }
  39. return &HTTP{
  40. myOutboundAdapter{
  41. protocol: C.TypeHTTP,
  42. network: []string{N.NetworkTCP},
  43. router: router,
  44. logger: logger,
  45. tag: tag,
  46. dependencies: withDialerDependency(options.DialerOptions),
  47. },
  48. sHTTP.NewClient(sHTTP.Options{
  49. Dialer: detour,
  50. Server: options.ServerOptions.Build(),
  51. Username: options.Username,
  52. Password: options.Password,
  53. Path: options.Path,
  54. Headers: headers,
  55. }),
  56. }, nil
  57. }
  58. func (h *HTTP) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  59. ctx, metadata := adapter.AppendContext(ctx)
  60. metadata.Outbound = h.tag
  61. metadata.Destination = destination
  62. h.logger.InfoContext(ctx, "outbound connection to ", destination)
  63. return h.client.DialContext(ctx, network, destination)
  64. }
  65. func (h *HTTP) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  66. return nil, os.ErrInvalid
  67. }
  68. func (h *HTTP) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  69. return NewConnection(ctx, h, conn, metadata)
  70. }
  71. func (h *HTTP) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  72. return os.ErrInvalid
  73. }