hub.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package http
  2. import (
  3. "context"
  4. "io"
  5. "net/http"
  6. "strings"
  7. "v2ray.com/core/common"
  8. "v2ray.com/core/common/net"
  9. "v2ray.com/core/common/serial"
  10. "v2ray.com/core/common/signal"
  11. "v2ray.com/core/transport/internet"
  12. "v2ray.com/core/transport/internet/tls"
  13. )
  14. type Listener struct {
  15. server *http.Server
  16. handler internet.ConnHandler
  17. local net.Addr
  18. config Config
  19. }
  20. func (l *Listener) Addr() net.Addr {
  21. return l.local
  22. }
  23. func (l *Listener) Close() error {
  24. return l.server.Shutdown(context.Background())
  25. }
  26. type flushWriter struct {
  27. w io.Writer
  28. }
  29. func (fw flushWriter) Write(p []byte) (n int, err error) {
  30. n, err = fw.w.Write(p)
  31. if f, ok := fw.w.(http.Flusher); ok {
  32. f.Flush()
  33. }
  34. return
  35. }
  36. func (l *Listener) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
  37. host := request.Host
  38. if !l.config.isValidHost(host) {
  39. writer.WriteHeader(404)
  40. return
  41. }
  42. path := l.config.getNormalizedPath()
  43. if !strings.HasPrefix(request.URL.Path, path) {
  44. writer.WriteHeader(404)
  45. return
  46. }
  47. writer.Header().Set("Cache-Control", "no-store")
  48. writer.WriteHeader(200)
  49. if f, ok := writer.(http.Flusher); ok {
  50. f.Flush()
  51. }
  52. done := signal.NewDone()
  53. l.handler(&Connection{
  54. Reader: request.Body,
  55. Writer: flushWriter{writer},
  56. Closer: common.NewChainedClosable(request.Body, done),
  57. Local: l.Addr(),
  58. Remote: l.Addr(),
  59. })
  60. <-done.C()
  61. }
  62. func Listen(ctx context.Context, address net.Address, port net.Port, handler internet.ConnHandler) (internet.Listener, error) {
  63. rawSettings := internet.TransportSettingsFromContext(ctx)
  64. httpSettings, ok := rawSettings.(*Config)
  65. if !ok {
  66. return nil, newError("HTTP config is not set.").AtError()
  67. }
  68. listener := &Listener{
  69. handler: handler,
  70. local: &net.TCPAddr{
  71. IP: address.IP(),
  72. Port: int(port),
  73. },
  74. config: *httpSettings,
  75. }
  76. config := tls.ConfigFromContext(ctx)
  77. if config == nil {
  78. return nil, newError("TLS must be enabled for http transport.").AtWarning()
  79. }
  80. server := &http.Server{
  81. Addr: serial.Concat(address, ":", port),
  82. TLSConfig: config.GetTLSConfig(tls.WithNextProto("h2")),
  83. Handler: listener,
  84. }
  85. listener.server = server
  86. go server.ListenAndServeTLS("", "")
  87. return listener, nil
  88. }
  89. func init() {
  90. common.Must(internet.RegisterTransportListener(internet.TransportProtocol_HTTP, Listen))
  91. }