Skip to content

Commit 97307bb

Browse files
committed
single file backend, because this is not Ruby
1 parent 0584a8b commit 97307bb

File tree

4 files changed

+78
-126
lines changed

4 files changed

+78
-126
lines changed

backend/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/piger/nginx-lab
22

3-
go 1.18
3+
go 1.24

backend/main.go

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,96 @@
22
package main
33

44
import (
5+
"encoding/json"
6+
"errors"
57
"flag"
8+
"fmt"
69
"log"
7-
8-
"github.com/piger/nginx-lab/server"
10+
"log/slog"
11+
"net/http"
12+
"os"
13+
"strings"
14+
"time"
915
)
1016

11-
var (
12-
listenAddress = flag.String("addr", "0.0.0.0", "Address to bind to")
13-
listenPort = flag.Int("port", 4444, "Port to listen on")
14-
)
17+
type logMiddleware struct {
18+
inner http.Handler
19+
logger *slog.Logger
20+
}
1521

16-
func run() error {
17-
flag.Parse()
22+
func (l logMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
23+
start := time.Now().UTC()
24+
l.inner.ServeHTTP(w, r)
25+
l.logger.Info("request", "method", r.Method, "url", r.URL.String(), "remote_addr", r.RemoteAddr, "elapsed", time.Since(start).String())
26+
}
27+
28+
func withLog(h http.HandlerFunc, logger *slog.Logger) http.Handler {
29+
return logMiddleware{inner: h, logger: logger}
30+
}
31+
32+
type echoResponse struct {
33+
Method string `json:"method"`
34+
URL string `json:"url"`
35+
Proto string `json:"proto"`
36+
Headers map[string]string `json:"headers"`
37+
Host string `json:"host"`
38+
RequestURI string `json:"request_uri"`
39+
RemoteAddr string `json:"remote_addr"`
40+
}
1841

19-
srv := server.New(*listenAddress, *listenPort)
20-
if err := srv.Run(); err != nil {
42+
// echoHandler is an handler that returns a JSON object containing information about the received request.
43+
func echoHandler(w http.ResponseWriter, r *http.Request) {
44+
headers := make(map[string]string)
45+
for k, v := range r.Header {
46+
headers[k] = strings.Join(v, ", ")
47+
}
48+
49+
resp := echoResponse{
50+
Method: r.Method,
51+
URL: r.URL.String(),
52+
Proto: r.Proto,
53+
Headers: headers,
54+
Host: r.Host,
55+
RequestURI: r.RequestURI,
56+
RemoteAddr: r.RemoteAddr,
57+
}
58+
59+
w.Header().Set("Content-Type", "application/json")
60+
61+
if err := json.NewEncoder(w).Encode(resp); err != nil {
62+
w.WriteHeader(http.StatusInternalServerError)
63+
fmt.Fprintf(w, "ERROR: %s\n", err)
64+
return
65+
}
66+
}
67+
68+
func run(addr string, logger *slog.Logger) error {
69+
mux := http.NewServeMux()
70+
mux.Handle("/", withLog(echoHandler, logger))
71+
72+
srv := http.Server{
73+
Addr: addr,
74+
Handler: mux,
75+
ReadTimeout: 10 * time.Second,
76+
WriteTimeout: 10 * time.Second,
77+
MaxHeaderBytes: 1 << 20, // 1 MiB
78+
}
79+
80+
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
2181
return err
2282
}
2383

2484
return nil
2585
}
2686

2787
func main() {
28-
if err := run(); err != nil {
88+
flagAddr := flag.String("addr", ":4444", "Address to listen to (e.g. 0.0.0.0:4444)")
89+
flag.Parse()
90+
91+
logger := slog.New(slog.NewJSONHandler(os.Stderr, nil))
92+
slog.SetDefault(logger)
93+
94+
if err := run(*flagAddr, logger); err != nil {
2995
log.Fatalf("error: %s", err)
3096
}
3197
}

backend/server/routes.go

Lines changed: 0 additions & 45 deletions
This file was deleted.

backend/server/server.go

Lines changed: 0 additions & 69 deletions
This file was deleted.

0 commit comments

Comments
 (0)