From 1f4ba997b7243767b80f24342749a3536bdf4719 Mon Sep 17 00:00:00 2001 From: lbenedar Date: Mon, 23 Feb 2026 15:00:41 +0300 Subject: [PATCH] add ch13 --- ch13/1/ch13_1.go | 28 ++++++++++++++++ ch13/1/go.mod | 3 ++ ch13/2/ch13_2.go | 46 ++++++++++++++++++++++++++ ch13/2/go.mod | 3 ++ ch13/3/ch13_3.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ ch13/3/go.mod | 3 ++ 6 files changed, 169 insertions(+) create mode 100644 ch13/1/ch13_1.go create mode 100644 ch13/1/go.mod create mode 100644 ch13/2/ch13_2.go create mode 100644 ch13/2/go.mod create mode 100644 ch13/3/ch13_3.go create mode 100644 ch13/3/go.mod diff --git a/ch13/1/ch13_1.go b/ch13/1/ch13_1.go new file mode 100644 index 0000000..1840a34 --- /dev/null +++ b/ch13/1/ch13_1.go @@ -0,0 +1,28 @@ +package main + +import ( + "net/http" + "time" +) + +type TimeHandler struct{} + +func (th TimeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(time.Now().Format(time.RFC3339))) +} + +func main() { + server := http.Server{ + Addr: ":10100", + ReadTimeout: 30 * time.Second, + WriteTimeout: 90 * time.Second, + IdleTimeout: 120 * time.Second, + Handler: TimeHandler{}, + } + err := server.ListenAndServe() + if err != nil { + if err != http.ErrServerClosed { + panic(err) + } + } +} diff --git a/ch13/1/go.mod b/ch13/1/go.mod new file mode 100644 index 0000000..0a5f101 --- /dev/null +++ b/ch13/1/go.mod @@ -0,0 +1,3 @@ +module gitea.local.lab/Lbenedar/learning_go/ch13/1 + +go 1.25.0 diff --git a/ch13/2/ch13_2.go b/ch13/2/ch13_2.go new file mode 100644 index 0000000..a877d51 --- /dev/null +++ b/ch13/2/ch13_2.go @@ -0,0 +1,46 @@ +package main + +import ( + "fmt" + "log/slog" + "net" + "net/http" + "time" +) + +type TimeHandler struct{} + +func (th TimeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(time.Now().Format(time.RFC3339))) +} + +func RequestToIP(r *http.Request) string { + ip, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + slog.Error(fmt.Sprintf("Wrong format of address: %q", r.RemoteAddr)) + } + return ip +} + +func RequestIPHandler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + slog.Info(RequestToIP(r)) + h.ServeHTTP(w, r) + }) +} + +func main() { + server := http.Server{ + Addr: ":10100", + ReadTimeout: 30 * time.Second, + WriteTimeout: 90 * time.Second, + IdleTimeout: 120 * time.Second, + Handler: RequestIPHandler(TimeHandler{}), + } + err := server.ListenAndServe() + if err != nil { + if err != http.ErrServerClosed { + panic(err) + } + } +} diff --git a/ch13/2/go.mod b/ch13/2/go.mod new file mode 100644 index 0000000..6271f23 --- /dev/null +++ b/ch13/2/go.mod @@ -0,0 +1,3 @@ +module gitea.local.lab/Lbenedar/learning_go/ch13/2 + +go 1.25.0 diff --git a/ch13/3/ch13_3.go b/ch13/3/ch13_3.go new file mode 100644 index 0000000..691acfa --- /dev/null +++ b/ch13/3/ch13_3.go @@ -0,0 +1,86 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "log/slog" + "net" + "net/http" + "time" +) + +type RFCTime struct { + DayOfWeek string `json:"day_of_week"` + DayOfMonth int `json:"day_of_month"` + Month string `json:"month"` + Year int `json:"year"` + Hour int `json:"hour"` + Minute int `json:"minute"` + Second int `json:"second"` +} + +type TimeHandler struct{} + +func StructToJsString(data any) string { + var b bytes.Buffer + enc := json.NewEncoder(&b) + err := enc.Encode(data) + if err != nil { + slog.Error("Problems with encoding json") + } + return b.String() +} + +func (th TimeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + headerAccept := http.Header.Get(r.Header, "Accept") + var output string + switch headerAccept { + case "application/json": + currTime := time.Now() + rfcTime := RFCTime{ + DayOfWeek: currTime.Weekday().String(), + DayOfMonth: currTime.Day(), + Month: currTime.Month().String(), + Year: currTime.Year(), + Hour: currTime.Hour(), + Minute: currTime.Minute(), + Second: currTime.Second(), + } + output = StructToJsString(rfcTime) + default: + output = time.Now().Format(time.RFC3339) + } + w.Write([]byte(output)) +} + +func RequestToIP(r *http.Request) string { + ip, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + slog.Error(fmt.Sprintf("Wrong format of address: %q", r.RemoteAddr)) + } + return ip +} + +func RequestIPHandler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + slog.Info(RequestToIP(r)) + h.ServeHTTP(w, r) + }) +} + +func main() { + server := http.Server{ + Addr: ":10100", + ReadTimeout: 30 * time.Second, + WriteTimeout: 90 * time.Second, + IdleTimeout: 120 * time.Second, + Handler: RequestIPHandler(TimeHandler{}), + } + err := server.ListenAndServe() + if err != nil { + if err != http.ErrServerClosed { + panic(err) + } + } +} diff --git a/ch13/3/go.mod b/ch13/3/go.mod new file mode 100644 index 0000000..989d243 --- /dev/null +++ b/ch13/3/go.mod @@ -0,0 +1,3 @@ +module gitea.local.lab/Lbenedar/learning_go/ch13/3 + +go 1.25.0