Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

proxy_test.go 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. package mtglib_test
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "encoding/hex"
  6. "encoding/json"
  7. "fmt"
  8. "io"
  9. "net"
  10. "net/http"
  11. "testing"
  12. "time"
  13. "github.com/9seconds/mtg/v2/antireplay"
  14. "github.com/9seconds/mtg/v2/events"
  15. "github.com/9seconds/mtg/v2/ipblocklist"
  16. "github.com/9seconds/mtg/v2/logger"
  17. "github.com/9seconds/mtg/v2/mtglib"
  18. "github.com/9seconds/mtg/v2/network"
  19. "github.com/gotd/td/telegram"
  20. "github.com/gotd/td/telegram/dcs"
  21. "github.com/gotd/td/tg"
  22. "github.com/stretchr/testify/suite"
  23. )
  24. type ProxyTestSuite struct {
  25. suite.Suite
  26. opts *mtglib.ProxyOpts
  27. p *mtglib.Proxy
  28. listener net.Listener
  29. }
  30. func (suite *ProxyTestSuite) ProxyAddress() string {
  31. _, port, _ := net.SplitHostPort(suite.listener.Addr().String())
  32. return net.JoinHostPort("127.0.0.1", port)
  33. }
  34. func (suite *ProxyTestSuite) ProxySecret() string {
  35. return suite.opts.Secret.Hex()
  36. }
  37. func (suite *ProxyTestSuite) SetupSuite() {
  38. dialer, err := network.NewDefaultDialer(0, 0)
  39. suite.NoError(err)
  40. ntw, err := network.NewNetwork(dialer, "mtgtest", "1.1.1.1", 0)
  41. suite.NoError(err)
  42. suite.opts = &mtglib.ProxyOpts{
  43. Secret: mtglib.GenerateSecret("httpbin.org"),
  44. Network: ntw,
  45. AntiReplayCache: antireplay.NewNoop(),
  46. IPBlocklist: ipblocklist.NewNoop(),
  47. EventStream: events.NewNoopStream(),
  48. Logger: logger.NewNoopLogger(),
  49. UseTestDCs: true,
  50. }
  51. proxy, err := mtglib.NewProxy(*suite.opts)
  52. suite.NoError(err)
  53. suite.p = proxy
  54. listener, err := net.Listen("tcp", ":0")
  55. suite.NoError(err)
  56. suite.listener = listener
  57. go suite.p.Serve(suite.listener) // nolint: errcheck
  58. }
  59. func (suite *ProxyTestSuite) TearDownSuite() {
  60. if suite.listener != nil {
  61. suite.listener.Close()
  62. }
  63. if suite.p != nil {
  64. suite.p.Shutdown()
  65. }
  66. }
  67. func (suite *ProxyTestSuite) TestCannotInitNoSecret() {
  68. opts := *suite.opts
  69. opts.Secret = mtglib.Secret{}
  70. _, err := mtglib.NewProxy(opts)
  71. suite.Error(err)
  72. }
  73. func (suite *ProxyTestSuite) TestCannotInitNoNetwork() {
  74. opts := *suite.opts
  75. opts.Network = nil
  76. _, err := mtglib.NewProxy(opts)
  77. suite.Error(err)
  78. }
  79. func (suite *ProxyTestSuite) TestCannotInitNoAntiReplayCache() {
  80. opts := *suite.opts
  81. opts.AntiReplayCache = nil
  82. _, err := mtglib.NewProxy(opts)
  83. suite.Error(err)
  84. }
  85. func (suite *ProxyTestSuite) TestCannotInitNoIPBlocklist() {
  86. opts := *suite.opts
  87. opts.IPBlocklist = nil
  88. _, err := mtglib.NewProxy(opts)
  89. suite.Error(err)
  90. }
  91. func (suite *ProxyTestSuite) TestCannotInitNoEventStream() {
  92. opts := *suite.opts
  93. opts.EventStream = nil
  94. _, err := mtglib.NewProxy(opts)
  95. suite.Error(err)
  96. }
  97. func (suite *ProxyTestSuite) TestCannotInitNoLogger() {
  98. opts := *suite.opts
  99. opts.Logger = nil
  100. _, err := mtglib.NewProxy(opts)
  101. suite.Error(err)
  102. }
  103. func (suite *ProxyTestSuite) TestCannotInitIncorrectPreferIP() {
  104. opts := *suite.opts
  105. opts.PreferIP = "xxx"
  106. _, err := mtglib.NewProxy(opts)
  107. suite.Error(err)
  108. }
  109. func (suite *ProxyTestSuite) TestDomainFrontingAddress() {
  110. suite.Equal("httpbin.org:443", suite.p.DomainFrontingAddress())
  111. }
  112. func (suite *ProxyTestSuite) TestHTTPSRequest() {
  113. client := &http.Client{
  114. Transport: &http.Transport{
  115. TLSClientConfig: &tls.Config{
  116. InsecureSkipVerify: true,
  117. },
  118. },
  119. Timeout: 5 * time.Second,
  120. }
  121. addr := fmt.Sprintf("https://%s/headers", suite.ProxyAddress())
  122. resp, err := client.Get(addr) // nolint: noctx
  123. suite.NoError(err)
  124. defer resp.Body.Close()
  125. suite.Equal(http.StatusOK, resp.StatusCode)
  126. data, err := io.ReadAll(resp.Body)
  127. suite.NoError(err)
  128. jsonStruct := struct {
  129. Headers struct {
  130. TraceID string `json:"X-Amzn-Trace-Id"` // nolint: tagliatelle
  131. } `json:"headers"`
  132. }{}
  133. suite.NoError(json.Unmarshal(data, &jsonStruct))
  134. suite.NotEmpty(jsonStruct.Headers.TraceID)
  135. }
  136. func (suite *ProxyTestSuite) TestMakeRealRequest() {
  137. secret, _ := hex.DecodeString(suite.opts.Secret.Hex())
  138. resolver, err := dcs.MTProxyResolver(
  139. suite.ProxyAddress(),
  140. secret,
  141. dcs.MTProxyOptions{},
  142. )
  143. suite.NoError(err)
  144. tgClient := telegram.NewClient(telegram.TestAppID,
  145. telegram.TestAppHash,
  146. telegram.Options{
  147. Resolver: resolver,
  148. })
  149. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  150. defer cancel()
  151. suite.NoError(tgClient.Run(ctx, func(ctx context.Context) error {
  152. _, err := tg.NewClient(tgClient).HelpGetConfig(ctx)
  153. suite.NoError(err)
  154. return err // nolint: wrapcheck
  155. }))
  156. }
  157. func TestProxy(t *testing.T) {
  158. t.Parallel()
  159. suite.Run(t, &ProxyTestSuite{})
  160. }