diff --git a/cmd/web_server/main.go b/cmd/web_server/main.go index 66e1f6c..ed5717a 100644 --- a/cmd/web_server/main.go +++ b/cmd/web_server/main.go @@ -1,6 +1,8 @@ package main import ( + "database/sql" + "encoding/json" "fmt" "log" "net/http" @@ -8,20 +10,92 @@ import ( "strconv" "github.com/go-chi/chi" + _ "github.com/mattn/go-sqlite3" ) +type mail struct { + Id int + Arrived_at int + Rcpt_addr, From_addr string + Data []byte +} + func main() { + db, err := sql.Open("sqlite3", "./db.db") + if err != nil { + log.Fatal(err) + } + defer db.Close() + router := chi.NewRouter() - router.Get("/", func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("Hello world")) + router.Get("/{rcpt-addr}", func(res http.ResponseWriter, req *http.Request) { + rcpt_addr := chi.URLParam(req, "rcpt-addr") + if len(rcpt_addr) == 0 { + res.WriteHeader(404) + res.Write([]byte("inbox not found")) + return + } + + tx, err := db.Begin() + if err != nil { + res.WriteHeader(500) + res.Write([]byte("internal server error")) + + log.Println("could not begin db transaction") + return + } + + stmt, err := tx.Prepare("SELECT mails.id, mails.arrived_at, mails.rcpt_addr, mails.from_addr, mails.data FROM mails WHERE mails.rcpt_addr = ?") + if err != nil { + res.WriteHeader(500) + res.Write([]byte("internal server error")) + + log.Println("could not prepare db stmt") + return + } + defer stmt.Close() + + rows, err := stmt.Query(rcpt_addr) + if err != nil { + res.WriteHeader(500) + res.Write([]byte("internal server error")) + + log.Println("could not query db stmt") + return + } + defer rows.Close() + + var mails []mail + for rows.Next() { + var m mail + err = rows.Scan(&m.Id, &m.Arrived_at, &m.Rcpt_addr, &m.From_addr, &m.Data) + if err != nil { + res.WriteHeader(500) + res.Write([]byte("internal server error")) + + log.Println("could not scan db row") + return + } + + mails = append(mails, m) + } + b, err := json.Marshal(mails) + if err != nil { + res.WriteHeader(500) + res.Write([]byte("internal server error")) + + log.Println("could not marshal json") + return + } + + res.Write([]byte(b)) }) var port int - var err error port_str, exists := os.LookupEnv("WEB_SERVER_PORT") if exists { - port, err = strconv.Atoi(port_str) + port, err = strconv.Atoi(port_str) if err != nil { log.Fatal("env:MAIL_SERVER_PORT is not a number") } @@ -29,6 +103,6 @@ func main() { port = 3000 } - log.Println("Listening on port", port) - http.ListenAndServe(fmt.Sprintf(":%d", port), router) + log.Println("Listening on port", port) + http.ListenAndServe(fmt.Sprintf(":%d", port), router) }