server_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package guerrilla
  2. import (
  3. "testing"
  4. "bufio"
  5. "net/textproto"
  6. "strings"
  7. "sync"
  8. "github.com/flashmob/go-guerrilla/backends"
  9. "github.com/flashmob/go-guerrilla/log"
  10. "github.com/flashmob/go-guerrilla/mail"
  11. "github.com/flashmob/go-guerrilla/mocks"
  12. )
  13. // getMockServerConfig gets a mock ServerConfig struct used for creating a new server
  14. func getMockServerConfig() *ServerConfig {
  15. sc := &ServerConfig{
  16. IsEnabled: true, // not tested here
  17. Hostname: "saggydimes.test.com",
  18. MaxSize: 1024, // smtp message max size
  19. PrivateKeyFile: "./tests/mail.guerrillamail.com.key.pem",
  20. PublicKeyFile: "./tests/mail.guerrillamail.com.cert.pem",
  21. Timeout: 5,
  22. ListenInterface: "127.0.0.1:2529",
  23. StartTLSOn: true,
  24. TLSAlwaysOn: false,
  25. MaxClients: 30, // not tested here
  26. LogFile: "./tests/testlog",
  27. }
  28. return sc
  29. }
  30. // getMockServerConn gets a new server using sc. Server will be using a mocked TCP connection
  31. // using the dummy backend
  32. // RCP TO command only allows test.com host
  33. func getMockServerConn(sc *ServerConfig, t *testing.T) (*mocks.Conn, *server) {
  34. var logOpenError error
  35. var mainlog log.Logger
  36. mainlog, logOpenError = log.GetLogger(sc.LogFile, "debug")
  37. if logOpenError != nil {
  38. mainlog.WithError(logOpenError).Errorf("Failed creating a logger for mock conn [%s]", sc.ListenInterface)
  39. }
  40. backend, err := backends.New(
  41. backends.BackendConfig{"log_received_mails": true, "save_workers_size": 1},
  42. mainlog)
  43. if err != nil {
  44. t.Error("new dummy backend failed because:", err)
  45. }
  46. server, err := newServer(sc, backend, mainlog)
  47. if err != nil {
  48. //t.Error("new server failed because:", err)
  49. } else {
  50. server.setAllowedHosts([]string{"test.com"})
  51. }
  52. conn := mocks.NewConn()
  53. return conn, server
  54. }
  55. func TestHandleClient(t *testing.T) {
  56. var mainlog log.Logger
  57. var logOpenError error
  58. sc := getMockServerConfig()
  59. mainlog, logOpenError = log.GetLogger(sc.LogFile, "debug")
  60. if logOpenError != nil {
  61. mainlog.WithError(logOpenError).Errorf("Failed creating a logger for mock conn [%s]", sc.ListenInterface)
  62. }
  63. conn, server := getMockServerConn(sc, t)
  64. // call the serve.handleClient() func in a goroutine.
  65. client := NewClient(conn.Server, 1, mainlog, mail.NewPool(5))
  66. var wg sync.WaitGroup
  67. wg.Add(1)
  68. go func() {
  69. server.handleClient(client)
  70. wg.Done()
  71. }()
  72. // Wait for the greeting from the server
  73. r := textproto.NewReader(bufio.NewReader(conn.Client))
  74. line, _ := r.ReadLine()
  75. // fmt.Println(line)
  76. w := textproto.NewWriter(bufio.NewWriter(conn.Client))
  77. w.PrintfLine("HELO test.test.com")
  78. line, _ = r.ReadLine()
  79. //fmt.Println(line)
  80. w.PrintfLine("QUIT")
  81. line, _ = r.ReadLine()
  82. //fmt.Println("line is:", line)
  83. expected := "221 2.0.0 Bye"
  84. if strings.Index(line, expected) != 0 {
  85. t.Error("expected", expected, "but got:", line)
  86. }
  87. wg.Wait() // wait for handleClient to exit
  88. }
  89. func TestXClient(t *testing.T) {
  90. var mainlog log.Logger
  91. var logOpenError error
  92. sc := getMockServerConfig()
  93. sc.XClientOn = true
  94. mainlog, logOpenError = log.GetLogger(sc.LogFile, "debug")
  95. if logOpenError != nil {
  96. mainlog.WithError(logOpenError).Errorf("Failed creating a logger for mock conn [%s]", sc.ListenInterface)
  97. }
  98. conn, server := getMockServerConn(sc, t)
  99. // call the serve.handleClient() func in a goroutine.
  100. client := NewClient(conn.Server, 1, mainlog, mail.NewPool(5))
  101. var wg sync.WaitGroup
  102. wg.Add(1)
  103. go func() {
  104. server.handleClient(client)
  105. wg.Done()
  106. }()
  107. // Wait for the greeting from the server
  108. r := textproto.NewReader(bufio.NewReader(conn.Client))
  109. line, _ := r.ReadLine()
  110. // fmt.Println(line)
  111. w := textproto.NewWriter(bufio.NewWriter(conn.Client))
  112. w.PrintfLine("HELO test.test.com")
  113. line, _ = r.ReadLine()
  114. //fmt.Println(line)
  115. w.PrintfLine("XCLIENT ADDR=212.96.64.216 NAME=[UNAVAILABLE]")
  116. line, _ = r.ReadLine()
  117. if client.RemoteIP != "212.96.64.216" {
  118. t.Error("client.RemoteIP should be 212.96.64.216, but got:", client.RemoteIP)
  119. }
  120. expected := "250 2.1.0 OK"
  121. if strings.Index(line, expected) != 0 {
  122. t.Error("expected", expected, "but got:", line)
  123. }
  124. // try malformed input
  125. w.PrintfLine("XCLIENT c")
  126. line, _ = r.ReadLine()
  127. expected = "250 2.1.0 OK"
  128. if strings.Index(line, expected) != 0 {
  129. t.Error("expected", expected, "but got:", line)
  130. }
  131. w.PrintfLine("QUIT")
  132. line, _ = r.ReadLine()
  133. wg.Wait() // wait for handleClient to exit
  134. }
  135. // TODO
  136. // - test github issue #44 and #42