command line arguments, merge files, comments

This commit is contained in:
uan
2025-08-02 22:36:59 +02:00
parent a000d657ad
commit c2a8530398
6 changed files with 125 additions and 95 deletions

View File

@@ -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)
}

5
go.mod Normal file
View File

@@ -0,0 +1,5 @@
module com.github/shlldev/miniws
go 1.22.2
require github.com/akamensky/argparse v1.4.0 // indirect

2
go.sum Normal file
View File

@@ -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=

11
index.html Normal file
View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body style="background-color: black;">
<h1 style="color: wheat;">
test
</h1>
</body>
</html>

62
log.go
View File

@@ -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
}

116
main.go
View File

@@ -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, "/") + "/"
}