summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2025-08-07 00:04:24 -0400
committerRobby Zambito <contact@robbyzambito.me>2025-08-07 00:19:11 -0400
commit6f1fb66792bd35166de5a338e5d174b22fa2c2ce (patch)
treedf164070cb6ca70b0c813facfa37fb835551d02c
parentc7ea744ebfefe79fdd138f05f0f156d3448b4b83 (diff)
Move handlers to handlers file
-rw-r--r--internal/api/handlers.go110
-rw-r--r--main.go100
2 files changed, 115 insertions, 95 deletions
diff --git a/internal/api/handlers.go b/internal/api/handlers.go
new file mode 100644
index 0000000..8d328a6
--- /dev/null
+++ b/internal/api/handlers.go
@@ -0,0 +1,110 @@
+package api
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net"
+ "strings"
+ "regexp"
+ "time"
+)
+
+var fs http.Handler
+
+func init() {
+ fs = http.FileServer(http.Dir("static"))
+}
+
+const log_length = 100
+
+type accessLog struct {
+ ClientAddr string `json:"clientAddr"`
+ RequestedPath string `json:"requestedPath"`
+ RequestTime time.Time `json:"requestTime"`
+ HttpMethod string `json:"httpMethod"`
+}
+
+func CreateFilesHandler(logs *[log_length]string, n *int, logChan chan string) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ jsonData, _ := json.Marshal(accessLog{
+ ClientAddr: redactIP(r.RemoteAddr),
+ RequestedPath: r.URL.Path,
+ RequestTime: time.Now().UTC(),
+ HttpMethod: r.Method,
+ })
+ addRotLog(logs, n, logChan, string(jsonData))
+ // Serve the index.html file from the static directory
+ http.StripPrefix("/", fs).ServeHTTP(w, r)
+ }
+}
+
+func CreateGetLogs(logs *[log_length]string) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ for _, s := range logs {
+ fmt.Fprintln(w, s)
+ }
+ }
+}
+
+func CreateLoginHandler(logs *[log_length]string, n *int, logChan chan string) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ body, err := io.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, "Bad Request", http.StatusBadRequest)
+ return
+ }
+ defer r.Body.Close()
+
+ var data map[string]any
+ if json.Unmarshal(body, &data) != nil {
+ addRotLog(logs, n, logChan, fmt.Sprintf(`{"authRequest": %s}`, string(body)))
+ http.Error(w, "Forbidden", http.StatusForbidden)
+ return
+ }
+
+ if email, ok := data["email"].(string); ok {
+ if rememberMe, ok := data["rememberMe"].(bool); ok {
+ addRotLog(logs, n, logChan, fmt.Sprintf(`{"authRequest": {"email": "%s", "password": "XXXXXXXX", "loginTime": "%s", "success": false, "rememberMe": %t}}`, email, time.Now().UTC(), rememberMe))
+ }
+ }
+ http.Error(w, "Forbidden", http.StatusForbidden)
+ }
+}
+
+func redactIP(input string) string {
+ ipRegex := `\b(?:\d{1,3}\.){3}\d{1,3}\b`
+ re := regexp.MustCompile(ipRegex)
+
+ return re.ReplaceAllStringFunc(input, func(match string) string {
+ if ip := net.ParseIP(match); ip != nil {
+ parts := strings.Split(match, ".")
+ if len(parts) == 4 {
+ parts[3] = "XXX"
+ return strings.Join(parts, ".")
+ }
+ }
+ return match
+ })
+}
+
+func addRotLog(logs *[log_length]string, last *int, parser chan string, value string) {
+ if strings.Contains(value, "\n") {
+ for _, v := range strings.Split(value, "\n") {
+ addRotLog(logs, last, parser, v)
+ }
+ } else {
+ if *last == log_length {
+ for i := 0; i < log_length-1; i++ {
+ logs[i] = logs[i+1]
+ }
+ logs[log_length-1] = value
+ parser <- value
+ } else {
+ logs[*last] = value
+ *last++
+ parser <- value
+ }
+ }
+}
diff --git a/main.go b/main.go
index f82efac..090cd17 100644
--- a/main.go
+++ b/main.go
@@ -3,13 +3,10 @@ package main
import (
"encoding/json"
"fmt"
- "io"
- "net"
"net/http"
- "regexp"
- // "strconv"
- "strings"
"time"
+
+ "git.robbyzambito.me/snorvik/internal/api"
)
// Example:
@@ -17,13 +14,6 @@ import (
const log_length = 100
-type accessLog struct {
- ClientAddr string `json:"clientAddr"`
- RequestedPath string `json:"requestedPath"`
- RequestTime time.Time `json:"requestTime"`
- HttpMethod string `json:"httpMethod"`
-}
-
type loginAttemptLog struct {
Email string `json:"email"`
Password string `json:"password"`
@@ -33,8 +23,6 @@ type loginAttemptLog struct {
}
func main() {
- fs := http.FileServer(http.Dir("static"))
-
var logs [log_length]string
n := 0
@@ -43,44 +31,10 @@ func main() {
go parser(logChan, &king)
- // Define a handler function for the root path
- http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- jsonData, _ := json.Marshal(accessLog{
- ClientAddr: RedactIP(r.RemoteAddr),
- RequestedPath: r.URL.Path,
- RequestTime: time.Now().UTC(),
- HttpMethod: r.Method,
- })
- addRotLog(&logs, &n, logChan, string(jsonData))
- // Serve the index.html file from the static directory
- http.StripPrefix("/", fs).ServeHTTP(w, r)
- })
-
- http.HandleFunc("/logs", createGetLogs(&logs))
-
- http.HandleFunc("/api/v1/auth/login", func(w http.ResponseWriter, r *http.Request) {
- body, err := io.ReadAll(r.Body)
- if err != nil {
- http.Error(w, "Bad Request", http.StatusBadRequest)
- return
- }
- defer r.Body.Close()
-
- var data map[string]any
- if json.Unmarshal(body, &data) != nil {
- addRotLog(&logs, &n, logChan, fmt.Sprintf(`{"authRequest": %s}`, string(body)))
- http.Error(w, "Forbidden", http.StatusForbidden)
- return
- }
-
- if email, ok := data["email"].(string); ok {
- if rememberMe, ok := data["rememberMe"].(bool); ok {
- addRotLog(&logs, &n, logChan, fmt.Sprintf(`{"authRequest": {"email": "%s", "password": "XXXXXXXX", "loginTime": "%s", "success": false, "rememberMe": %t}}`, email, time.Now().UTC(), rememberMe))
- }
- }
- http.Error(w, "Forbidden", http.StatusForbidden)
- })
+ http.HandleFunc("/", api.CreateFilesHandler(&logs, &n, logChan))
+ http.HandleFunc("/logs", api.CreateGetLogs(&logs))
+ http.HandleFunc("/api/v1/auth/login", api.CreateLoginHandler(&logs, &n, logChan))
http.HandleFunc("/api/v1/king", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, king)
})
@@ -93,34 +47,6 @@ func main() {
}
}
-func createGetLogs(logs *[log_length]string) func(http.ResponseWriter, *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- for _, s := range logs {
- fmt.Fprintln(w, s)
- }
- }
-}
-
-func addRotLog(logs *[log_length]string, last *int, parser chan string, value string) {
- if strings.Contains(value, "\n") {
- for _, v := range strings.Split(value, "\n") {
- addRotLog(logs, last, parser, v)
- }
- } else {
- if *last == log_length {
- for i := 0; i < log_length-1; i++ {
- logs[i] = logs[i+1]
- }
- logs[log_length-1] = value
- parser <- value
- } else {
- logs[*last] = value
- *last++
- parser <- value
- }
- }
-}
-
func parser(input chan string, king *string) {
for value := range input {
var data map[string]any
@@ -132,19 +58,3 @@ func parser(input chan string, king *string) {
}
}
-// RedactIP partially redacts an IP address by replacing the last octet with 'xxx'
-func RedactIP(input string) string {
- ipRegex := `\b(?:\d{1,3}\.){3}\d{1,3}\b`
- re := regexp.MustCompile(ipRegex)
-
- return re.ReplaceAllStringFunc(input, func(match string) string {
- if ip := net.ParseIP(match); ip != nil {
- parts := strings.Split(match, ".")
- if len(parts) == 4 {
- parts[3] = "XXX"
- return strings.Join(parts, ".")
- }
- }
- return match
- })
-}