config.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package splithttp
  2. import (
  3. "crypto/rand"
  4. "math/big"
  5. "net/http"
  6. "net/url"
  7. "strings"
  8. "github.com/xtls/xray-core/common"
  9. "github.com/xtls/xray-core/transport/internet"
  10. )
  11. func (c *Config) GetNormalizedPath() string {
  12. pathAndQuery := strings.SplitN(c.Path, "?", 2)
  13. path := pathAndQuery[0]
  14. if path == "" || path[0] != '/' {
  15. path = "/" + path
  16. }
  17. if path[len(path)-1] != '/' {
  18. path = path + "/"
  19. }
  20. return path
  21. }
  22. func (c *Config) GetNormalizedQuery() string {
  23. pathAndQuery := strings.SplitN(c.Path, "?", 2)
  24. query := ""
  25. if len(pathAndQuery) > 1 {
  26. query = pathAndQuery[1]
  27. }
  28. /*
  29. if query != "" {
  30. query += "&"
  31. }
  32. query += "x_version=" + core.Version()
  33. */
  34. return query
  35. }
  36. func (c *Config) GetRequestHeader(rawURL string) http.Header {
  37. header := http.Header{}
  38. for k, v := range c.Headers {
  39. header.Add(k, v)
  40. }
  41. u, _ := url.Parse(rawURL)
  42. // https://www.rfc-editor.org/rfc/rfc7541.html#appendix-B
  43. // h2's HPACK Header Compression feature employs a huffman encoding using a static table.
  44. // 'X' is assigned an 8 bit code, so HPACK compression won't change actual padding length on the wire.
  45. // https://www.rfc-editor.org/rfc/rfc9204.html#section-4.1.2-2
  46. // h3's similar QPACK feature uses the same huffman table.
  47. u.RawQuery = "x_padding=" + strings.Repeat("X", int(c.GetNormalizedXPaddingBytes().rand()))
  48. header.Set("Referer", u.String())
  49. return header
  50. }
  51. func (c *Config) WriteResponseHeader(writer http.ResponseWriter) {
  52. // CORS headers for the browser dialer
  53. writer.Header().Set("Access-Control-Allow-Origin", "*")
  54. writer.Header().Set("Access-Control-Allow-Methods", "GET, POST")
  55. // writer.Header().Set("X-Version", core.Version())
  56. writer.Header().Set("X-Padding", strings.Repeat("X", int(c.GetNormalizedXPaddingBytes().rand())))
  57. }
  58. func (c *Config) GetNormalizedXPaddingBytes() RangeConfig {
  59. if c.XPaddingBytes == nil || c.XPaddingBytes.To == 0 {
  60. return RangeConfig{
  61. From: 100,
  62. To: 1000,
  63. }
  64. }
  65. return *c.XPaddingBytes
  66. }
  67. func (c *Config) GetNormalizedScMaxEachPostBytes() RangeConfig {
  68. if c.ScMaxEachPostBytes == nil || c.ScMaxEachPostBytes.To == 0 {
  69. return RangeConfig{
  70. From: 1000000,
  71. To: 1000000,
  72. }
  73. }
  74. return *c.ScMaxEachPostBytes
  75. }
  76. func (c *Config) GetNormalizedScMinPostsIntervalMs() RangeConfig {
  77. if c.ScMinPostsIntervalMs == nil || c.ScMinPostsIntervalMs.To == 0 {
  78. return RangeConfig{
  79. From: 30,
  80. To: 30,
  81. }
  82. }
  83. return *c.ScMinPostsIntervalMs
  84. }
  85. func (c *Config) GetNormalizedScMaxBufferedPosts() int {
  86. if c.ScMaxBufferedPosts == 0 {
  87. return 30
  88. }
  89. return int(c.ScMaxBufferedPosts)
  90. }
  91. func (c *Config) GetNormalizedScStreamUpServerSecs() RangeConfig {
  92. if c.ScStreamUpServerSecs == nil || c.ScStreamUpServerSecs.To == 0 {
  93. return RangeConfig{
  94. From: 20,
  95. To: 80,
  96. }
  97. }
  98. return *c.ScMinPostsIntervalMs
  99. }
  100. func (m *XmuxConfig) GetNormalizedMaxConcurrency() RangeConfig {
  101. if m.MaxConcurrency == nil {
  102. return RangeConfig{
  103. From: 0,
  104. To: 0,
  105. }
  106. }
  107. return *m.MaxConcurrency
  108. }
  109. func (m *XmuxConfig) GetNormalizedMaxConnections() RangeConfig {
  110. if m.MaxConnections == nil {
  111. return RangeConfig{
  112. From: 0,
  113. To: 0,
  114. }
  115. }
  116. return *m.MaxConnections
  117. }
  118. func (m *XmuxConfig) GetNormalizedCMaxReuseTimes() RangeConfig {
  119. if m.CMaxReuseTimes == nil {
  120. return RangeConfig{
  121. From: 0,
  122. To: 0,
  123. }
  124. }
  125. return *m.CMaxReuseTimes
  126. }
  127. func (m *XmuxConfig) GetNormalizedHMaxRequestTimes() RangeConfig {
  128. if m.HMaxRequestTimes == nil {
  129. return RangeConfig{
  130. From: 0,
  131. To: 0,
  132. }
  133. }
  134. return *m.HMaxRequestTimes
  135. }
  136. func (m *XmuxConfig) GetNormalizedHMaxReusableSecs() RangeConfig {
  137. if m.HMaxReusableSecs == nil {
  138. return RangeConfig{
  139. From: 0,
  140. To: 0,
  141. }
  142. }
  143. return *m.HMaxReusableSecs
  144. }
  145. func init() {
  146. common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {
  147. return new(Config)
  148. }))
  149. }
  150. func (c RangeConfig) rand() int32 {
  151. if c.From == c.To {
  152. return c.From
  153. }
  154. bigInt, _ := rand.Int(rand.Reader, big.NewInt(int64(c.To-c.From)))
  155. return c.From + int32(bigInt.Int64())
  156. }