commit a000d657ad3b609ff189b0ee24adccebe9102300 Author: Solar Date: Sat Aug 2 21:29:39 2025 +0200 first commit, everything works diff --git a/fetch.go b/fetch.go new file mode 100644 index 0000000..bea18d0 --- /dev/null +++ b/fetch.go @@ -0,0 +1,24 @@ +package main + +import ( + "os" + "strings" +) + +func fetchFileContents(filepath string) ([]byte, error) { + if filepath == "/" { + filepath = "." + } else { + filepath_relative, _ := strings.CutPrefix(filepath, "/") + filepath = filepath_relative + } + fileinfo, err := os.Stat(filepath) + if err != nil { + return nil, err + } + if fileinfo.IsDir() { + filepath += "/index.html" + } + return os.ReadFile(filepath) + +} diff --git a/log.go b/log.go new file mode 100644 index 0000000..7e461fd --- /dev/null +++ b/log.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + "log" + "os" +) + +func logIfError(err error) bool { + if err != nil { + logError(err.Error()) + return true + } + return false +} + +// func logAccess( +// remoteAddr, remoteUser, timeLocal, request, status, +// bodyBytesSent, httpReferrer, httpUseragent string, +// ) { +// out := fmt.Sprintf("%v - %v - [%v] \"%v\" %v %v \"%v\" \"%v\"\n", +// remoteAddr, remoteUser, timeLocal, request, status, bodyBytesSent, +// httpReferrer, httpUseragent, +// ) +// file, err := os.OpenFile(PATH_ACCESSLOG, os.O_APPEND|os.O_WRONLY, os.ModeType) +// if err != nil { +// log.Println("couldn't open log access file at", PATH_ACCESSLOG) +// } +// defer file.Close() +// file.WriteString(out) +// } + +func logAccess( + remoteAddr, identifier, authuser, timestamp, request, + status, bytesSent string, +) { + out := fmt.Sprintf("%v %v %v [%v] \"%v\" %v %v\n", + remoteAddr, identifier, authuser, timestamp, request, status, bytesSent, + ) + file, err := os.OpenFile(PATH_ACCESSLOG, os.O_APPEND|os.O_WRONLY, os.ModeType) + if err != nil { + log.Println("couldn't open log access file at", PATH_ACCESSLOG) + } + defer file.Close() + file.WriteString(out) +} + +func logError(str string) { + file, err := os.OpenFile(PATH_ERRORLOG, os.O_APPEND|os.O_WRONLY, os.ModeType) + if err != nil { + log.Println("couldn't open log error file at", PATH_ACCESSLOG) + } + defer file.Close() + file.WriteString(str + "\n") +} + +func getOrDash(str string) string { + if str == "" { + return "-" + } + return str +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..2a8af12 --- /dev/null +++ b/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "log" + "net/http" + "strconv" + "strings" + "time" +) + +const ( + PATH_ACCESSLOG string = "access.log" + PATH_ERRORLOG string = "error.log" +) + +func main() { + http.HandleFunc("/{resource...}", get) + log.Println("Server started") + http.ListenAndServe(":8080", nil) +} + +func get(writer http.ResponseWriter, req *http.Request) { + fetchedData, fetchErr := fetchFileContents(req.URL.Path) + respStatusCode := int(200) + var sentBytes int = 0 + if logIfError(fetchErr) { + respStatusCode = http.StatusNotFound + writer.WriteHeader(respStatusCode) + } else { + sentBytesCount, _ := writer.Write(fetchedData) + sentBytes = sentBytesCount + } + logAccess(strings.Split(req.RemoteAddr, ":")[0], "-", getOrDash(req.URL.User.Username()), time.Now().Format("02/Jan/2006:03:04:05 -0700"), + req.Method+" "+req.URL.Path+" "+getHttpString(req.ProtoMajor, req.ProtoMinor), strconv.Itoa(respStatusCode), + strconv.Itoa(sentBytes), + ) +} + +func getHttpString(major, minor int) string { + return "HTTP/" + strconv.Itoa(major) + "." + strconv.Itoa(minor) +}