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
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

stats.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package proxy
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "sync/atomic"
  10. "time"
  11. )
  12. type statsUptime time.Time
  13. func (s statsUptime) MarshalJSON() ([]byte, error) {
  14. uptime := int(time.Since(time.Time(s)).Seconds())
  15. return []byte(strconv.Itoa(uptime)), nil
  16. }
  17. // Stats is a datastructure for statistics on work of this proxy.
  18. type Stats struct {
  19. AllConnections uint64 `json:"all_connections"`
  20. ActiveConnections uint32 `json:"active_connections"`
  21. Traffic struct {
  22. Incoming uint64 `json:"incoming"`
  23. Outgoing uint64 `json:"outgoing"`
  24. } `json:"traffic"`
  25. URLs struct {
  26. TG string `json:"tg_url"`
  27. TMe string `json:"tme_url"`
  28. TGQRCode string `json:"tg_qrcode"`
  29. TMeQRCode string `json:"tme_qrcode"`
  30. } `json:"urls"`
  31. Uptime statsUptime `json:"uptime"`
  32. }
  33. func (s *Stats) newConnection() {
  34. atomic.AddUint64(&s.AllConnections, 1)
  35. atomic.AddUint32(&s.ActiveConnections, 1)
  36. }
  37. func (s *Stats) closeConnection() {
  38. atomic.AddUint32(&s.ActiveConnections, ^uint32(0))
  39. }
  40. func (s *Stats) addIncomingTraffic(n int) {
  41. atomic.AddUint64(&s.Traffic.Incoming, uint64(n))
  42. }
  43. func (s *Stats) addOutgoingTraffic(n int) {
  44. atomic.AddUint64(&s.Traffic.Outgoing, uint64(n))
  45. }
  46. // Serve runs statistics HTTP server.
  47. func (s *Stats) Serve(host fmt.Stringer, port uint16) {
  48. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  49. w.Header().Set("Content-Type", "application/json")
  50. encoder := json.NewEncoder(w)
  51. encoder.SetEscapeHTML(false)
  52. encoder.SetIndent("", " ")
  53. encoder.Encode(s) // nolint: errcheck, gas
  54. })
  55. addr := net.JoinHostPort(host.String(), strconv.Itoa(int(port)))
  56. http.ListenAndServe(addr, nil) // nolint: errcheck, gas
  57. }
  58. // NewStats returns new instance of statistics datastructure.
  59. func NewStats(serverName string, port uint16, secret string) *Stats {
  60. urlQuery := makeURLQuery(serverName, port, secret)
  61. stat := &Stats{Uptime: statsUptime(time.Now())}
  62. stat.URLs.TG = makeTGURL(urlQuery)
  63. stat.URLs.TMe = makeTMeURL(urlQuery)
  64. stat.URLs.TGQRCode = makeQRCodeURL(stat.URLs.TG)
  65. stat.URLs.TMeQRCode = makeQRCodeURL(stat.URLs.TMe)
  66. return stat
  67. }
  68. func makeURLQuery(serverName string, port uint16, secret string) url.Values {
  69. values := url.Values{}
  70. values.Set("server", serverName)
  71. values.Set("port", strconv.Itoa(int(port)))
  72. values.Set("secret", secret)
  73. return values
  74. }
  75. func makeTGURL(values url.Values) string {
  76. tgURL := url.URL{
  77. Scheme: "tg",
  78. Host: "proxy",
  79. RawQuery: values.Encode(),
  80. }
  81. return tgURL.String()
  82. }
  83. func makeTMeURL(values url.Values) string {
  84. tMeURL := url.URL{
  85. Scheme: "https",
  86. Host: "t.me",
  87. Path: "proxy",
  88. RawQuery: values.Encode(),
  89. }
  90. return tMeURL.String()
  91. }
  92. func makeQRCodeURL(data string) string {
  93. QRURL := url.URL{
  94. Scheme: "https",
  95. Host: "api.qrserver.com",
  96. Path: "v1/create-qr-code",
  97. }
  98. values := url.Values{}
  99. values.Set("qzone", "4")
  100. values.Set("format", "svg")
  101. values.Set("data", data)
  102. QRURL.RawQuery = values.Encode()
  103. return QRURL.String()
  104. }