models.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package guerrilla
  2. import (
  3. "bufio"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "net"
  8. )
  9. type EmailParts struct {
  10. User string
  11. Host string
  12. }
  13. func (ep *EmailParts) String() string {
  14. return fmt.Sprintf("%s@%s", ep.User, ep.Host)
  15. }
  16. // Backend accepts the received messages, and store/deliver/process them
  17. type Backend interface {
  18. Initialize(BackendConfig) error
  19. Process(client *Client, from *EmailParts, to []*EmailParts) string
  20. Finalize() error
  21. }
  22. const CommandMaxLength = 1024
  23. // TODO: cleanup
  24. type Client struct {
  25. State int
  26. Helo string
  27. MailFrom string
  28. RcptTo string
  29. Response string
  30. Address string
  31. Data string
  32. Subject string
  33. Hash string
  34. Time int64
  35. TLS bool
  36. Conn net.Conn
  37. Bufin *SMTPBufferedReader
  38. Bufout *bufio.Writer
  39. KillTime int64
  40. Errors int
  41. ClientID int64
  42. SavedNotify chan int
  43. }
  44. var InputLimitExceeded = errors.New("Line too long") // 500 Line too long.
  45. // we need to adjust the limit, so we embed io.LimitedReader
  46. type adjustableLimitedReader struct {
  47. R *io.LimitedReader
  48. }
  49. // bolt this on so we can adjust the limit
  50. func (alr *adjustableLimitedReader) setLimit(n int64) {
  51. alr.R.N = n
  52. }
  53. // this just delegates to the underlying reader in order to satisfy the Reader interface
  54. // Since the vanilla limited reader returns io.EOF when the limit is reached, we need a more specific
  55. // error so that we can distinguish when a limit is reached
  56. func (alr *adjustableLimitedReader) Read(p []byte) (n int, err error) {
  57. n, err = alr.R.Read(p)
  58. if err == io.EOF && alr.R.N <= 0 {
  59. // return our custom error since std lib returns EOF
  60. err = InputLimitExceeded
  61. }
  62. return
  63. }
  64. // allocate a new adjustableLimitedReader
  65. func newAdjustableLimitedReader(r io.Reader, n int64) *adjustableLimitedReader {
  66. lr := &io.LimitedReader{R: r, N: n}
  67. return &adjustableLimitedReader{lr}
  68. }
  69. // This is a bufio.Reader what will use our adjustable limit reader
  70. // We 'extend' buffio to have the limited reader feature
  71. type SMTPBufferedReader struct {
  72. *bufio.Reader
  73. alr *adjustableLimitedReader
  74. }
  75. // delegate to the adjustable limited reader
  76. func (sbr *SMTPBufferedReader) SetLimit(n int64) {
  77. sbr.alr.setLimit(n)
  78. }
  79. // allocate a new smtpBufferedReader
  80. func NewSMTPBufferedReader(rd io.Reader) *SMTPBufferedReader {
  81. alr := newAdjustableLimitedReader(rd, CommandMaxLength)
  82. s := &SMTPBufferedReader{bufio.NewReader(alr), alr}
  83. return s
  84. }