package main import ( "bufio" "fmt" "log/slog" "strings" ) type Headers struct { Method string Uri string Proto string KV map[string]string } func readHeaders(reader *bufio.Reader) *Headers { headers := Headers{} kvHeaders := make(map[string]string) versionLine, err := reader.ReadString('\n') if err != nil { slog.Error("Could not read version line", "err", err.Error()) return nil } method, uri, proto := parseRequestLine(versionLine) if method == "" || uri == "" || proto == "" { slog.Error("Invalid request line", "line", versionLine) return nil } headers.Method = method headers.Uri = uri headers.Proto = proto headerStr, err := reader.ReadString('\n') if err != nil { slog.Error("Could not read headers", "err", err.Error()) return nil } for strings.TrimSpace(headerStr) != "" { header := strings.SplitN(headerStr, ":", 2) if len(header) == 2 { kvHeaders[strings.TrimSpace(header[0])] = strings.TrimSpace(header[1]) } headerStr, err = reader.ReadString('\n') if err != nil { slog.Error("Could not read headers", "err", err.Error()) return nil } } headers.KV = kvHeaders return &headers } func (m *Headers) debugPrintHeaders() { for key, value := range m.KV { fmt.Printf("%s: %s\n", key, value) } } func parseRequestLine(versionLine string) (string, string, string) { cleanLine := strings.TrimSpace(versionLine) parts := strings.Split(cleanLine, " ") if len(parts) != 3 { return "", "", "" } return parts[0], parts[1], parts[2] }