diff --git a/http/http.go b/http/http.go new file mode 100644 index 0000000..f8d8754 --- /dev/null +++ b/http/http.go @@ -0,0 +1,52 @@ +package http + +import ( + "fmt" + "gemini-grc/logging" + _ "gemini-grc/logging" + "net/http" + "time" +) + +func CreateServer(listenAddr string) *http.Server { + mux := http.NewServeMux() + mux.HandleFunc("GET /ping", wrapForError(getPing)) + + server := &http.Server{ + Addr: listenAddr, + Handler: mux, + ReadHeaderTimeout: 10 * time.Second, + } + + go func() { + // Start the server. Blocking call. + logging.LogInfo("HTTP server listening on %s", listenAddr) + if err := server.ListenAndServe(); err != nil { + panic(fmt.Sprintf("Server failed to start: %s", err)) + } + }() + return server +} + +func wrapForError(f func(http.ResponseWriter, *http.Request) error) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + err := f(w, r) + if err != nil { + code := http.StatusInternalServerError + logging.LogWarn("Error while handling request: %d %s", code, err) + http.Error(w, http.StatusText(code), code) + } + } +} + +func getPing(w http.ResponseWriter, r *http.Request) error { + method := r.Method + url := r.URL.String() + path := r.URL.Path + response := fmt.Sprintf("Pong %s %s %s", method, url, path) + _, err := w.Write([]byte(response)) + if err != nil { + return fmt.Errorf("failed to write response: %w", err) + } + return nil +}