Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
jkroepke committed Nov 19, 2024
1 parent 9d2be06 commit d5d4cbe
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
21 changes: 21 additions & 0 deletions internal/smtp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (s *Server) Start() error {
if err != nil {
return fmt.Errorf("error starting SMTP server: %w", err)
}

s.listener = listener

for {
Expand All @@ -69,12 +70,14 @@ func (s *Server) Start() error {
return nil
default:
}

if err != nil {
return fmt.Errorf("connection error: %w", err)
}
}

s.wg.Add(1)

go func() {
defer s.wg.Done()

Expand All @@ -90,6 +93,7 @@ func (s *Server) Close() error {
if s.listener != nil {
return s.listener.Close()
}

return nil
}

Expand Down Expand Up @@ -138,6 +142,7 @@ func (s *Server) handleConnection(conn net.Conn) error {
if err != nil {
return fmt.Errorf("error reading command: %w", err)
}

line = strings.TrimSpace(line)

switch {
Expand Down Expand Up @@ -178,7 +183,9 @@ func (s *Server) handleConnection(conn net.Conn) error {

return nil
}

_, _ = writer.WriteString("250 OK\r\n")

if err = writer.Flush(); err != nil {
return fmt.Errorf("error flushing writer: %w", err)
}
Expand Down Expand Up @@ -228,6 +235,7 @@ func (s *Server) handleConnection(conn net.Conn) error {
// Invoke the callback function
if err := s.callBackFn(msg); err != nil {
_, _ = writer.WriteString(fmt.Sprintf("550 Error processing mail: %v\r\n", err))

if err = writer.Flush(); err != nil {
return fmt.Errorf("error flushing writer: %w", err)
}
Expand All @@ -236,6 +244,7 @@ func (s *Server) handleConnection(conn net.Conn) error {
}

_, _ = writer.WriteString("250 OK\r\n")

if err = writer.Flush(); err != nil {
return fmt.Errorf("error flushing writer: %w", err)
}
Expand All @@ -251,6 +260,7 @@ func (s *Server) handleConnection(conn net.Conn) error {
return nil // Close connection after QUIT command
case strings.HasPrefix(line, "NOOP"):
_, _ = writer.WriteString("250 OK\r\n")

if err = writer.Flush(); err != nil {
return fmt.Errorf("error flushing writer: %w", err)
}
Expand All @@ -261,6 +271,7 @@ func (s *Server) handleConnection(conn net.Conn) error {

default:
_, _ = writer.WriteString("250 OK\r\n")

if err = writer.Flush(); err != nil {
return fmt.Errorf("error flushing writer: %w", err)
}
Expand All @@ -271,16 +282,20 @@ func (s *Server) handleConnection(conn net.Conn) error {
// collectMailData reads the raw mail data from the client until the SMTP end marker (".").
func collectMailData(reader *bufio.Reader) string {
var mailData strings.Builder

for {
line, err := reader.ReadString('\n')
if err != nil {
return ""
}

if strings.TrimSpace(line) == "." {
break
}

mailData.WriteString(line)
}

return strings.TrimSpace(mailData.String())
}

Expand All @@ -298,6 +313,7 @@ func parseMailData(data string) (*MailMessage, error) {
return v
}
}

return ""
}

Expand All @@ -307,6 +323,7 @@ func parseMailData(data string) (*MailMessage, error) {

contentType := getHeader("Content-Type")
mediaType, params, err := mime.ParseMediaType(contentType)

if err != nil && contentType != "" {
return nil, fmt.Errorf("error parsing Content-Type: %w", err)
}
Expand Down Expand Up @@ -339,17 +356,20 @@ func parseHeadersAndBody(data string) (map[string]string, string, error) {
}

headers := make(map[string]string)

for _, line := range strings.Split(parts[0], "\r\n") {
colonIndex := strings.Index(line, ":")
if colonIndex == -1 {
return nil, "", fmt.Errorf("invalid header format: %s", line)

Check failure on line 363 in internal/smtp/server.go

View workflow job for this annotation

GitHub Actions / lint

do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"invalid header format: %s\", line)" (err113)
}

key := strings.TrimSpace(line[:colonIndex])
value := strings.TrimSpace(line[colonIndex+1:])
headers[key] = value
}

body := parts[1]

return headers, body, nil
}

Expand Down Expand Up @@ -424,5 +444,6 @@ func (s *Server) parseAddress(line string) (string, error) {
}

address := strings.TrimSpace(parts[1])

return strings.Trim(address, "<>"), nil
}
1 change: 0 additions & 1 deletion internal/smtp/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ Your Name`,
},
} {
t.Run(test.name, func(t *testing.T) {

logger := slog.New(slog.NewTextHandler(os.Stderr, nil))

// Create a new server
Expand Down

0 comments on commit d5d4cbe

Please sign in to comment.