Inital commit

This commit is contained in:
2026-02-15 15:22:10 +01:00
commit 795c7eccb8
4 changed files with 131 additions and 0 deletions

3
go.mod Normal file
View File

@@ -0,0 +1,3 @@
module tilok.dev/go-http-server
go 1.25.0

43
main.go Normal file
View File

@@ -0,0 +1,43 @@
package main
import (
"bufio"
"log/slog"
"net"
rh "tilok.dev/go-http-server/response_helper"
)
func main() {
//TODO: Make interface configurable
interf := "127.0.0.1:8080"
listener, err := net.Listen("tcp", interf)
if err != nil {
slog.Error("Could not create listener", "err", err.Error())
}
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
slog.Error("Could not accept connection", "err", err.Error())
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
headers := readHeaders(reader)
if headers == nil {
rh.RespondWithStatusCode(400, conn)
return
}
slog.Info("Received request", "method", headers.Method, "uri", headers.Uri, "proto", headers.Proto, "client", conn.RemoteAddr().String())
headers.debugPrintHeaders()
}

71
readheaders.go Normal file
View File

@@ -0,0 +1,71 @@
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]
}

View File

@@ -0,0 +1,14 @@
package response_helper
import (
"fmt"
"net"
"net/http"
)
func RespondWithStatusCode(statusCode int, conn net.Conn) {
conn.Write([]byte(fmt.Sprintf("HTTP/1.1 %d %s\r\n", statusCode, http.StatusText(statusCode))))
conn.Write([]byte("Content-Type: text/plain\r\n"))
conn.Write([]byte("Content-Length: 0\r\n"))
conn.Write([]byte("\r\n"))
}