| 117 | } |
| 118 | |
| 119 | func (s *Server) startAPIServer(ctx context.Context) error { |
| 120 | mux := http.NewServeMux() |
| 121 | mux.HandleFunc("POST /purge", s.handlePurge) |
| 122 | mux.HandleFunc("GET /messages", s.handleMessages) |
| 123 | |
| 124 | s.httpServer = &http.Server{ |
| 125 | Handler: mux, |
| 126 | ReadHeaderTimeout: 10 * time.Second, |
| 127 | } |
| 128 | |
| 129 | listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", s.hostAddress, s.apiPort)) |
| 130 | if err != nil { |
| 131 | return xerrors.Errorf("listen on %s:%d: %w", s.hostAddress, s.apiPort, err) |
| 132 | } |
| 133 | s.httpListener = listener |
| 134 | |
| 135 | tcpAddr, valid := listener.Addr().(*net.TCPAddr) |
| 136 | if !valid { |
| 137 | err := listener.Close() |
| 138 | if err != nil { |
| 139 | s.logger.Error(ctx, "failed to close listener", slog.Error(err)) |
| 140 | } |
| 141 | return xerrors.Errorf("listener returned invalid address: %T", listener.Addr()) |
| 142 | } |
| 143 | s.apiPort = tcpAddr.Port |
| 144 | |
| 145 | go func() { |
| 146 | if err := s.httpServer.Serve(listener); err != nil && !errors.Is(err, http.ErrServerClosed) { |
| 147 | s.logger.Error(ctx, "http API server error", slog.Error(err)) |
| 148 | } |
| 149 | }() |
| 150 | |
| 151 | return nil |
| 152 | } |
| 153 | |
| 154 | func (s *Server) handlePurge(w http.ResponseWriter, _ *http.Request) { |
| 155 | s.smtpServer.MessagesAndPurge() |