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.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package stream
  2. import (
  3. "bytes"
  4. "io"
  5. "net"
  6. "sync"
  7. "time"
  8. "github.com/9seconds/mtg/conntypes"
  9. "go.uber.org/zap"
  10. )
  11. type ReadWriteCloseRewinder interface {
  12. conntypes.StreamReadWriteCloser
  13. Rewind()
  14. }
  15. type wrapperRewind struct {
  16. parent conntypes.StreamReadWriteCloser
  17. activeReader io.Reader
  18. buf bytes.Buffer
  19. mutex sync.Mutex
  20. }
  21. func (w *wrapperRewind) Write(p []byte) (int, error) {
  22. return w.parent.Write(p)
  23. }
  24. func (w *wrapperRewind) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
  25. return w.parent.WriteTimeout(p, timeout)
  26. }
  27. func (w *wrapperRewind) Read(p []byte) (int, error) {
  28. w.mutex.Lock()
  29. defer w.mutex.Unlock()
  30. return w.activeReader.Read(p)
  31. }
  32. func (w *wrapperRewind) ReadTimeout(p []byte, _ time.Duration) (int, error) {
  33. w.mutex.Lock()
  34. defer w.mutex.Unlock()
  35. return w.activeReader.Read(p)
  36. }
  37. func (w *wrapperRewind) Conn() net.Conn {
  38. return w.parent.Conn()
  39. }
  40. func (w *wrapperRewind) Logger() *zap.SugaredLogger {
  41. return w.parent.Logger().Named("rewinded")
  42. }
  43. func (w *wrapperRewind) LocalAddr() *net.TCPAddr {
  44. return w.parent.LocalAddr()
  45. }
  46. func (w *wrapperRewind) RemoteAddr() *net.TCPAddr {
  47. return w.parent.RemoteAddr()
  48. }
  49. func (w *wrapperRewind) Close() error {
  50. w.buf.Reset()
  51. return w.parent.Close()
  52. }
  53. func (w *wrapperRewind) Rewind() {
  54. w.mutex.Lock()
  55. w.activeReader = io.MultiReader(&w.buf, w.parent)
  56. w.mutex.Unlock()
  57. }
  58. func NewRewind(parent conntypes.StreamReadWriteCloser) ReadWriteCloseRewinder {
  59. rv := &wrapperRewind{
  60. parent: parent,
  61. }
  62. rv.activeReader = io.TeeReader(parent, &rv.buf)
  63. return rv
  64. }