diff --git a/fetch.go b/fetch.go
deleted file mode 100644
index bea18d0..0000000
--- a/fetch.go
+++ /dev/null
@@ -1,24 +0,0 @@
-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/go.mod b/go.mod
new file mode 100644
index 0000000..68e91f0
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module com.github/shlldev/miniws
+
+go 1.22.2
+
+require github.com/akamensky/argparse v1.4.0 // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..5bf91e2
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
+github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc=
+github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA=
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..2a90e08
--- /dev/null
+++ b/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+ test
+
+
+
\ No newline at end of file
diff --git a/log.go b/log.go
deleted file mode 100644
index 7e461fd..0000000
--- a/log.go
+++ /dev/null
@@ -1,62 +0,0 @@
-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
index 2a8af12..0bb5dd3 100644
--- a/main.go
+++ b/main.go
@@ -1,28 +1,52 @@
package main
import (
+ "fmt"
"log"
"net/http"
+ "os"
"strconv"
"strings"
"time"
+
+ "github.com/akamensky/argparse"
)
const (
- PATH_ACCESSLOG string = "access.log"
- PATH_ERRORLOG string = "error.log"
+ PATH_ACCESSLOG string = "access.log"
+ PATH_ERRORLOG string = "error.log"
+ FLAGS_LOG_OPEN int = os.O_APPEND | os.O_WRONLY | os.O_CREATE
+ PERMS_LOG_OPEN os.FileMode = os.ModeType | os.ModePerm
)
+var _logFolder string = ""
+
func main() {
+
+ parser := argparse.NewParser("miniws", "")
+ port := parser.String("p", "port", &argparse.Options{Default: "8040"})
+ logFolder := parser.String("l", "logs-folder", &argparse.Options{Default: "logs"})
+
+ err := parser.Parse(os.Args)
+ if err != nil {
+ // In case of error print error and print usage
+ // This can also be done by passing -h or --help flags
+ fmt.Print(parser.Usage(err))
+ }
+
+ _logFolder = *logFolder
+
http.HandleFunc("/{resource...}", get)
- log.Println("Server started")
- http.ListenAndServe(":8080", nil)
+ log.Println("Server started on port " + *port)
+ http.ListenAndServe(":"+*port, nil)
}
func get(writer http.ResponseWriter, req *http.Request) {
fetchedData, fetchErr := fetchFileContents(req.URL.Path)
- respStatusCode := int(200)
- var sentBytes int = 0
+
+ sentBytes := 0
+ respStatusCode := http.StatusOK
+
if logIfError(fetchErr) {
respStatusCode = http.StatusNotFound
writer.WriteHeader(respStatusCode)
@@ -30,12 +54,86 @@ func get(writer http.ResponseWriter, req *http.Request) {
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),
+
+ logAccess(
+ strings.Split(req.RemoteAddr, ":")[0], //remote address
+ "-", //identifier (can't get)
+ getOrDash(req.URL.User.Username()), //username
+ time.Now().Format("02/Jan/2006:15:04:05 -0700"), //timestamp
+ req.Method+" "+req.URL.Path+" "+getHttpString(req.ProtoMajor, req.ProtoMinor), //HTTP version
+ strconv.Itoa(respStatusCode), //response code
+ strconv.Itoa(sentBytes), //# of sent bytes
+ req.Referer(), //Referer
+ req.UserAgent(), //User Agent
)
}
+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)
+
+}
+
+// returns error != nil
+func logIfError(err error) bool {
+ if err != nil {
+ logError(err.Error())
+ return true
+ }
+ return false
+}
+
+func logAccess(
+ remoteAddr, identifier, authuser, timestamp, request,
+ status, bytesSent, referer, user_agent string,
+) {
+ out := fmt.Sprintf("%v %v %v [%v] \"%v\" %v %v \"%v\" \"%v\"\n",
+ remoteAddr, identifier, authuser, timestamp, request, status, bytesSent, referer, user_agent,
+ )
+ os.Mkdir(_logFolder, os.ModeDir|os.ModePerm)
+ file, err := os.OpenFile(assureSlash(_logFolder)+PATH_ACCESSLOG, FLAGS_LOG_OPEN, PERMS_LOG_OPEN)
+
+ if err != nil {
+ log.Println("couldn't open log access file at", assureSlash(_logFolder)+PATH_ACCESSLOG)
+ }
+ defer file.Close()
+ file.WriteString(out)
+}
+
+func logError(str string) {
+ file, err := os.OpenFile(assureSlash(_logFolder)+PATH_ERRORLOG, FLAGS_LOG_OPEN, PERMS_LOG_OPEN)
+ os.Mkdir(_logFolder, os.ModeDir|os.ModePerm)
+
+ if err != nil {
+ log.Println("couldn't open log error file at", assureSlash(_logFolder)+PATH_ERRORLOG)
+ }
+ defer file.Close()
+ file.WriteString(str + "\n")
+}
+
func getHttpString(major, minor int) string {
return "HTTP/" + strconv.Itoa(major) + "." + strconv.Itoa(minor)
}
+
+func getOrDash(str string) string {
+ if str == "" {
+ return "-"
+ }
+ return str
+}
+
+func assureSlash(str string) string {
+ return strings.TrimSuffix(str, "/") + "/"
+}