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
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package proxy
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strconv"
  6. "sync/atomic"
  7. "time"
  8. "github.com/9seconds/mtg/config"
  9. )
  10. type statsUptime time.Time
  11. func (s statsUptime) MarshalJSON() ([]byte, error) {
  12. uptime := int(time.Since(time.Time(s)).Seconds())
  13. return []byte(strconv.Itoa(uptime)), nil
  14. }
  15. // Stats is a datastructure for statistics on work of this proxy.
  16. type Stats struct {
  17. AllConnections uint64 `json:"all_connections"`
  18. ActiveConnections uint32 `json:"active_connections"`
  19. Traffic struct {
  20. Incoming uint64 `json:"incoming"`
  21. Outgoing uint64 `json:"outgoing"`
  22. } `json:"traffic"`
  23. URLs config.IPURLs `json:"urls"`
  24. Uptime statsUptime `json:"uptime"`
  25. conf *config.Config
  26. }
  27. func (s *Stats) newConnection() {
  28. atomic.AddUint64(&s.AllConnections, 1)
  29. atomic.AddUint32(&s.ActiveConnections, 1)
  30. }
  31. func (s *Stats) closeConnection() {
  32. atomic.AddUint32(&s.ActiveConnections, ^uint32(0))
  33. }
  34. func (s *Stats) addIncomingTraffic(n int) {
  35. atomic.AddUint64(&s.Traffic.Incoming, uint64(n))
  36. }
  37. func (s *Stats) addOutgoingTraffic(n int) {
  38. atomic.AddUint64(&s.Traffic.Outgoing, uint64(n))
  39. }
  40. // Serve runs statistics HTTP server.
  41. func (s *Stats) Serve() {
  42. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  43. w.Header().Set("Content-Type", "application/json")
  44. encoder := json.NewEncoder(w)
  45. encoder.SetEscapeHTML(false)
  46. encoder.SetIndent("", " ")
  47. encoder.Encode(s) // nolint: errcheck, gas
  48. })
  49. http.ListenAndServe(s.conf.StatAddr(), nil) // nolint: errcheck, gas
  50. }
  51. // NewStats returns new instance of statistics datastructure.
  52. func NewStats(conf *config.Config) *Stats {
  53. stat := &Stats{
  54. Uptime: statsUptime(time.Now()),
  55. conf: conf,
  56. }
  57. stat.URLs = conf.GetURLs()
  58. return stat
  59. }