small refactor, add available signals to README

This commit is contained in:
2025-08-24 10:33:39 +02:00
parent e6938a9f39
commit c0b9edbfb5
13 changed files with 64 additions and 56 deletions

View File

@@ -1,6 +1,8 @@
# miniws
miniws (minimal web server) is a very simple web server written in golang. its purpose is to be lightweight, easy to configure and easily expandable for personal use.
all the help you'll ever need is in this README, and in the help text (`miniws -h`). there is no other documentation you have to read.
## command line arguments
```
-h --help Print help information
@@ -21,6 +23,10 @@ in your config folder you will find `ipfilter.conf` and `useragentfilter.conf`
both files use the same format: specify `allow|deny` in the first line to tell miniws to treat the file as a whitelist or a blacklist, then specify one ip/user-agent per line.
## signals
you can pass the following signals when using -s:
- `reload`: reloads the configuration files from disk
## logging
in your logging folder you will find `access.log` and `errors.log`

View File

@@ -3,6 +3,5 @@ go 1.24.5
use (
.
./miniws
./miniws/sockets
./miniws/sockets/logplus
./miniws/ipc
)

View File

@@ -2,8 +2,8 @@ package main
import (
"fmt"
"ipc"
"os"
"sockets"
"miniws"
@@ -44,7 +44,7 @@ func main() {
// signal mode
if *signal != "" {
client := sockets.Client{}
client := ipc.Client{}
client.OneShotWrite("unix", miniws.SOCKET_PATH, []byte(*signal))
return
}

View File

@@ -2,5 +2,5 @@ go 1.24.5
use (
.
./sockets
./ipc
)

View File

@@ -1,4 +1,4 @@
package sockets
package ipc
type buffer []byte

View File

@@ -1,9 +1,8 @@
package sockets
package ipc
import (
"bufio"
"log"
"logplus"
"net"
"os"
)
@@ -12,7 +11,7 @@ type Client struct{}
func (c *Client) Start(network, address string) {
conn, err := net.Dial(network, address)
logplus.LogIfErrorFatal(err)
LogIfErrorFatal(err)
defer conn.Close()
buffer := make(buffer, 1<<12)
@@ -20,25 +19,25 @@ func (c *Client) Start(network, address string) {
for {
buffer.Zero()
scanner.Scan()
logplus.LogIfErrorFatal(scanner.Err())
LogIfErrorFatal(scanner.Err())
buffer = []byte(scanner.Text())
_, err := conn.Write(buffer)
logplus.LogIfErrorFatal(err)
LogIfErrorFatal(err)
}
}
func (c *Client) OneShotWrite(network, address string, content []byte) {
conn, err := net.Dial(network, address)
logplus.LogIfErrorFatal(err)
LogIfErrorFatal(err)
defer conn.Close()
//will recieve a byte
buffer := make(buffer, 1)
_, err = conn.Write(content)
logplus.LogIfErrorFatal(err)
LogIfErrorFatal(err)
_, err = conn.Read(buffer)
logplus.LogIfErrorFatal(err)
LogIfErrorFatal(err)
if buffer[0] == byte(0) {
log.Println("Signal", string(content), "doesn't exist!")
return

3
miniws/ipc/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module ipc
go 1.24.5

View File

@@ -1,4 +1,4 @@
package logplus
package ipc
import "log"

View File

@@ -1,8 +1,7 @@
package sockets
package ipc
import (
"io"
"logplus"
"net"
"os"
"os/signal"
@@ -14,7 +13,7 @@ type Server struct{}
func (s *Server) Start(recvBind func(string, []string) bool, network, address string) int {
socket, err := net.Listen(network, address)
logplus.LogIfErrorFatal(err)
LogIfErrorFatal(err)
//Cleanup the socket file
c := make(chan os.Signal, 1)
@@ -29,7 +28,7 @@ func (s *Server) Start(recvBind func(string, []string) bool, network, address st
//Accept connection
conn, err := socket.Accept()
logplus.LogIfErrorFatal(err)
LogIfErrorFatal(err)
//Handle the connection
//in a separate goroutine
@@ -46,20 +45,17 @@ func (s *Server) Start(recvBind func(string, []string) bool, network, address st
conn.Close()
break
}
logplus.LogIfErrorFatal(err)
LogIfErrorFatal(err)
fullstring := string(buffer)
arguments := strings.Split(fullstring, " ")
ret := recvBind(arguments[0], arguments[1:])
conn.Write([]byte{bool2byte(ret)})
if ret {
conn.Write([]byte{1})
} else {
conn.Write([]byte{0})
}
buffer.Zero()
}
}(conn)
}
}
func bool2byte(b bool) byte {
if b {
return 1
}
return 0
}

View File

@@ -1,3 +0,0 @@
module sockets
go 1.24.5

View File

@@ -1,6 +0,0 @@
go 1.24.5
use (
.
./logplus
)

View File

@@ -1,3 +0,0 @@
module logplus
go 1.22.2

View File

@@ -3,13 +3,13 @@ package miniws
import (
"bytes"
"errors"
"ipc"
"log"
"mime"
"net/http"
"os"
"path/filepath"
"slices"
"sockets"
"strconv"
"strings"
"time"
@@ -18,6 +18,7 @@ import (
)
const (
FILTER_MODE_INVALID FilterMode = -1
FILTER_MODE_WHITELIST FilterMode = 0
FILTER_MODE_BLACKLIST FilterMode = 1
@@ -67,24 +68,37 @@ func (ws *WebServer) Run() {
log.Fatalln("Fatal: missing permissions to read www folder")
}
ws.ipFilterMode, ws.ipFilter = ws.parseFilterPanics(FILENAME_IPFILTER)
ws.userAgentFilterMode, ws.userAgentFilter = ws.parseFilterPanics(FILENAME_USERAGENTFILTER)
ipFilterMode, ipFilter, err := ws.parseFilter(FILENAME_IPFILTER)
if err != nil {
log.Fatalln("Fatal: IP filter invalid:", err)
}
ws.ipFilterMode = ipFilterMode
ws.ipFilter = ipFilter
userAgentFilterMode, userAgentFilter, err := ws.parseFilter(FILENAME_USERAGENTFILTER)
if err != nil {
log.Fatalln("Fatal: UserAgent filter invalid:", err)
}
ws.userAgentFilter = userAgentFilter
ws.userAgentFilterMode = userAgentFilterMode
// create and start a unix socket server (to accept signal from another process using -s <cmd>)
socketserver := sockets.Server{}
go socketserver.Start(ws.recvBind, "unix", SOCKET_PATH)
ipcServer := ipc.Server{}
go ipcServer.Start(ws.onRecieveSignal, "unix", SOCKET_PATH)
http.HandleFunc("/", ws.get)
log.Println("Server started on port " + strconv.Itoa(ws.port))
http.ListenAndServe(":"+strconv.Itoa(ws.port), nil)
log.Println("Server starting on port " + strconv.Itoa(ws.port) + "...")
httpErr := http.ListenAndServe(":"+strconv.Itoa(ws.port), nil)
if httpErr != nil {
log.Fatalln(httpErr)
}
}
func (ws *WebServer) recvBind(command string, arguments []string) bool {
func (ws *WebServer) onRecieveSignal(command string, arguments []string) bool {
command = string(bytes.Trim([]byte(command), "\x00"))
switch command {
case "reload":
ws.parseFilterPanics(FILENAME_IPFILTER)
ws.parseFilterPanics(FILENAME_USERAGENTFILTER)
ws.parseFilter(FILENAME_IPFILTER)
ws.parseFilter(FILENAME_USERAGENTFILTER)
return true
default:
log.Println("Error: unknown command", command, arguments)
@@ -92,7 +106,7 @@ func (ws *WebServer) recvBind(command string, arguments []string) bool {
}
}
func (ws *WebServer) parseFilterPanics(fileName string) (FilterMode, []string) {
func (ws *WebServer) parseFilter(fileName string) (FilterMode, []string, error) {
log.Println("loaded filter: ", fileName)
@@ -109,17 +123,19 @@ func (ws *WebServer) parseFilterPanics(fileName string) (FilterMode, []string) {
}
if err != nil {
panic("Error opening " + fileName + ": " + err.Error())
return FILTER_MODE_INVALID, nil,
errors.New("Error opening " + fileName + ": " + err.Error())
}
if fileinfo.Size() == 0 { // empty config
return filterMode, filter
return filterMode, filter, nil
}
filterContent, err := os.ReadFile(fullPath)
if ws.logger.logIfError(err, fullPath) {
panic("Error reading " + fileName + ": " + err.Error())
return FILTER_MODE_INVALID, nil,
errors.New("Error reading " + fileName + ": " + err.Error())
}
lines := strings.Split(string(filterContent), "\n")
@@ -142,10 +158,11 @@ func (ws *WebServer) parseFilterPanics(fileName string) (FilterMode, []string) {
case "deny":
filterMode = FILTER_MODE_BLACKLIST
default:
panic("invalid filter mode for " + fileName + ": use allow|deny")
return FILTER_MODE_INVALID, nil,
errors.New("invalid filter mode for " + fileName + ": use allow|deny")
}
return filterMode, filter
return filterMode, filter, nil
}