forwarder.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package browserforwarder
  2. import (
  3. "bytes"
  4. "context"
  5. "github.com/v2fly/BrowserBridge/handler"
  6. "github.com/v2fly/v2ray-core/v4/common"
  7. "github.com/v2fly/v2ray-core/v4/common/net"
  8. "github.com/v2fly/v2ray-core/v4/common/platform/securedload"
  9. "github.com/v2fly/v2ray-core/v4/features/ext"
  10. "github.com/v2fly/v2ray-core/v4/transport/internet"
  11. "io"
  12. "net/http"
  13. "time"
  14. )
  15. //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
  16. type Forwarder struct {
  17. ctx context.Context
  18. forwarder *handler.HTTPHandle
  19. httpserver *http.Server
  20. config *Config
  21. }
  22. func (f *Forwarder) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
  23. requestPath := request.URL.Path[1:]
  24. switch requestPath {
  25. case "":
  26. fallthrough
  27. case "index.js":
  28. BridgeResource(writer, request, requestPath)
  29. break
  30. case "link":
  31. f.forwarder.ServeBridge(writer, request)
  32. }
  33. }
  34. func (f *Forwarder) DialWebsocket(url string, header http.Header) (io.ReadWriteCloser, error) {
  35. return f.forwarder.Dial(url)
  36. }
  37. func (f *Forwarder) Type() interface{} {
  38. return ext.BrowserForwarderType()
  39. }
  40. func (f *Forwarder) Start() error {
  41. f.forwarder = handler.NewHttpHandle()
  42. f.httpserver = &http.Server{Handler: f}
  43. address := net.ParseAddress(f.config.ListenAddr)
  44. listener, err := internet.ListenSystem(f.ctx, &net.TCPAddr{IP: address.IP(), Port: int(f.config.ListenPort)}, nil)
  45. if err != nil {
  46. return newError("forwarder cannot listen on the port").Base(err)
  47. }
  48. go func() {
  49. err = f.httpserver.Serve(listener)
  50. if err != nil {
  51. newError("cannot serve http forward server").Base(err).WriteToLog()
  52. }
  53. }()
  54. return nil
  55. }
  56. func (f *Forwarder) Close() error {
  57. if f.httpserver != nil {
  58. return f.httpserver.Close()
  59. }
  60. return nil
  61. }
  62. func BridgeResource(rw http.ResponseWriter, r *http.Request, path string) {
  63. content := path
  64. data, err := securedload.GetAssetSecured("browserforwarder/" + content)
  65. if err != nil {
  66. err = newError("cannot load necessary resources").Base(err)
  67. http.Error(rw, err.Error(), 403)
  68. return
  69. }
  70. http.ServeContent(rw, r, path, time.Now(), bytes.NewReader(data))
  71. }
  72. func NewForwarder(ctx context.Context, cfg *Config) *Forwarder {
  73. return &Forwarder{config: cfg, ctx: ctx}
  74. }
  75. func init() {
  76. common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
  77. return NewForwarder(ctx, cfg.(*Config)), nil
  78. }))
  79. }