mirror of
https://github.com/shlldev/miniws.git
synced 2025-09-02 19:00:59 +02:00
Merge branch 'master' of https://github.com/shlldev/miniws
This commit is contained in:
62
logger.go
Normal file
62
logger.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FLAGS_LOG_OPEN int = os.O_APPEND | os.O_WRONLY | os.O_CREATE
|
||||||
|
FLAGS_CONFIG_OPEN int = os.O_RDONLY | os.O_CREATE
|
||||||
|
PERMS_LOG_OPEN os.FileMode = os.ModeType | os.ModePerm
|
||||||
|
PERMS_CONFIG_OPEN os.FileMode = os.ModeType | os.ModePerm
|
||||||
|
PERMS_MKDIR os.FileMode = os.ModeDir | os.ModePerm
|
||||||
|
)
|
||||||
|
|
||||||
|
type Logger struct {
|
||||||
|
logFolder string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogger(logFolder_ string) *Logger {
|
||||||
|
return &Logger{
|
||||||
|
logFolder: logFolder_,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns error != nil
|
||||||
|
func (l *Logger) logIfError(err error) bool {
|
||||||
|
if err != nil {
|
||||||
|
l.logError(err.Error())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) 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(l.logFolder, os.ModeDir|os.ModePerm)
|
||||||
|
file, err := os.OpenFile(ensureSlashSuffix(l.logFolder)+FILENAME_ACCESSLOG, FLAGS_LOG_OPEN, PERMS_LOG_OPEN)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println("couldn't open log access file at", ensureSlashSuffix(l.logFolder)+FILENAME_ACCESSLOG)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
file.WriteString(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) logError(str string) {
|
||||||
|
os.Mkdir(l.logFolder, PERMS_MKDIR)
|
||||||
|
file, err := os.OpenFile(ensureSlashSuffix(l.logFolder)+FILENAME_ERRORLOG, FLAGS_LOG_OPEN, PERMS_LOG_OPEN)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println("couldn't open log error file at", ensureSlashSuffix(l.logFolder)+FILENAME_ERRORLOG)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
file.WriteString(str + "\n")
|
||||||
|
}
|
242
main.go
242
main.go
@@ -1,48 +1,26 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"slices"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/akamensky/argparse"
|
"github.com/akamensky/argparse"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PATH_ACCESSLOG string = "access.log"
|
FILENAME_ACCESSLOG string = "access.log"
|
||||||
PATH_ERRORLOG string = "error.log"
|
FILENAME_ERRORLOG string = "error.log"
|
||||||
PATH_IPFILTER string = "ipfilter.conf"
|
FILENAME_IPFILTER string = "ipfilter.conf"
|
||||||
PATH_USERAGENTFILTER string = "useragentfilter.conf"
|
FILENAME_USERAGENTFILTER string = "useragentfilter.conf"
|
||||||
FLAGS_LOG_OPEN int = os.O_APPEND | os.O_WRONLY | os.O_CREATE
|
|
||||||
FLAGS_CONFIG_OPEN int = os.O_RDONLY | os.O_CREATE
|
|
||||||
PERMS_LOG_OPEN os.FileMode = os.ModeType | os.ModePerm
|
|
||||||
PERMS_CONFIG_OPEN os.FileMode = os.ModeType | os.ModePerm
|
|
||||||
PERMS_MKDIR os.FileMode = os.ModeDir | os.ModePerm
|
|
||||||
FILTER_MODE_WHITELIST = 0
|
|
||||||
FILTER_MODE_BLACKLIST = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
logFolder string = ""
|
|
||||||
configFolder string = ""
|
|
||||||
ipFilter []string = make([]string, 0)
|
|
||||||
ipFilterMode = FILTER_MODE_WHITELIST
|
|
||||||
userAgentFilter []string = make([]string, 0)
|
|
||||||
userAgentFilterMode = FILTER_MODE_WHITELIST
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
parser := argparse.NewParser("miniws", "")
|
parser := argparse.NewParser("miniws", "")
|
||||||
port := parser.String("p", "port", &argparse.Options{Default: "8040"})
|
|
||||||
_logFolder := parser.String("l", "logs-folder", &argparse.Options{Default: "logs"})
|
port := parser.Int("p", "port", &argparse.Options{Default: 8040})
|
||||||
_configFolder := parser.String("c", "config-folder", &argparse.Options{Default: "config"})
|
logFolder := parser.String("l", "logs-folder", &argparse.Options{Default: "logs"})
|
||||||
|
configFolder := parser.String("c", "config-folder", &argparse.Options{Default: "config"})
|
||||||
|
|
||||||
err := parser.Parse(os.Args)
|
err := parser.Parse(os.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -52,207 +30,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logFolder = *_logFolder
|
webserver := NewWebServer(*port, *logFolder, *configFolder)
|
||||||
configFolder = *_configFolder
|
webserver.Run()
|
||||||
|
|
||||||
parseIpFilter()
|
|
||||||
parseUserAgentFilter()
|
|
||||||
http.HandleFunc("/", get)
|
|
||||||
log.Println("Server started on port " + *port)
|
|
||||||
http.ListenAndServe(":"+*port, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func get(writer http.ResponseWriter, req *http.Request) {
|
|
||||||
|
|
||||||
respStatusCode := http.StatusOK
|
|
||||||
|
|
||||||
if !isIpValid(req.RemoteAddr) || !isUserAgentValid(req.UserAgent()) {
|
|
||||||
writer.WriteHeader(http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchedData, fetchErr := fetchFileContents(req.URL.Path)
|
|
||||||
|
|
||||||
sentBytes := 0
|
|
||||||
|
|
||||||
if logIfError(fetchErr) {
|
|
||||||
respStatusCode = http.StatusNotFound
|
|
||||||
writer.WriteHeader(respStatusCode)
|
|
||||||
} else {
|
|
||||||
sentBytesCount, _ := writer.Write(fetchedData)
|
|
||||||
sentBytes = sentBytesCount
|
|
||||||
}
|
|
||||||
|
|
||||||
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+" "+getHttpVersionString(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(ensureSlashSuffix(logFolder)+PATH_ACCESSLOG, FLAGS_LOG_OPEN, PERMS_LOG_OPEN)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Println("couldn't open log access file at", ensureSlashSuffix(logFolder)+PATH_ACCESSLOG)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
file.WriteString(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func logError(str string) {
|
|
||||||
os.Mkdir(logFolder, PERMS_MKDIR)
|
|
||||||
file, err := os.OpenFile(ensureSlashSuffix(logFolder)+PATH_ERRORLOG, FLAGS_LOG_OPEN, PERMS_LOG_OPEN)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Println("couldn't open log error file at", ensureSlashSuffix(logFolder)+PATH_ERRORLOG)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
file.WriteString(str + "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func getHttpVersionString(major, minor int) string {
|
|
||||||
return "HTTP/" + strconv.Itoa(major) + "." + strconv.Itoa(minor)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOrDash(str string) string {
|
|
||||||
if str == "" {
|
|
||||||
return "-"
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func ensureSlashSuffix(str string) string {
|
|
||||||
return strings.TrimSuffix(str, "/") + "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
func isIpValid(ip string) bool {
|
|
||||||
ip = strings.Split(ip, ":")[0] // remove port
|
|
||||||
switch ipFilterMode {
|
|
||||||
case FILTER_MODE_WHITELIST:
|
|
||||||
return slices.Contains(ipFilter, ip)
|
|
||||||
case FILTER_MODE_BLACKLIST:
|
|
||||||
return !slices.Contains(ipFilter, ip)
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func isUserAgentValid(userAgent string) bool {
|
|
||||||
switch userAgentFilterMode {
|
|
||||||
case FILTER_MODE_WHITELIST:
|
|
||||||
return slices.Contains(userAgentFilter, userAgent)
|
|
||||||
case FILTER_MODE_BLACKLIST:
|
|
||||||
return !slices.Contains(userAgentFilter, userAgent)
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseIpFilter() {
|
|
||||||
os.Mkdir(configFolder, PERMS_MKDIR)
|
|
||||||
fileinfo, err := os.Stat(ensureSlashSuffix(configFolder) + PATH_IPFILTER)
|
|
||||||
|
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
|
||||||
os.Create(ensureSlashSuffix(configFolder) + PATH_IPFILTER)
|
|
||||||
}
|
|
||||||
if fileinfo.Size() == 0 { // empty config
|
|
||||||
ipFilterMode = FILTER_MODE_BLACKLIST
|
|
||||||
ipFilter = make([]string, 0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ipFilterContent, err := os.ReadFile(ensureSlashSuffix(configFolder) + PATH_IPFILTER)
|
|
||||||
|
|
||||||
if logIfError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ipFilterLines := strings.Split(string(ipFilterContent), "\n")
|
|
||||||
|
|
||||||
_ipFilterMode := ipFilterLines[0]
|
|
||||||
|
|
||||||
switch _ipFilterMode {
|
|
||||||
case "allow":
|
|
||||||
ipFilterMode = FILTER_MODE_WHITELIST
|
|
||||||
case "deny":
|
|
||||||
ipFilterMode = FILTER_MODE_BLACKLIST
|
|
||||||
default:
|
|
||||||
logError("invalid ip filter mode, use allow|deny")
|
|
||||||
}
|
|
||||||
|
|
||||||
ipFilter = ipFilterLines[1:]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseUserAgentFilter() {
|
|
||||||
os.Mkdir(configFolder, PERMS_MKDIR)
|
|
||||||
fileinfo, err := os.Stat(ensureSlashSuffix(configFolder) + PATH_USERAGENTFILTER)
|
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
|
||||||
os.Create(ensureSlashSuffix(configFolder) + PATH_USERAGENTFILTER)
|
|
||||||
}
|
|
||||||
if fileinfo.Size() == 0 { // empty config
|
|
||||||
userAgentFilterMode = FILTER_MODE_BLACKLIST
|
|
||||||
userAgentFilter = make([]string, 0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userAgentFilterContent, err := os.ReadFile(ensureSlashSuffix(configFolder) + PATH_USERAGENTFILTER)
|
|
||||||
|
|
||||||
if logIfError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userAgentFilterLines := strings.Split(string(userAgentFilterContent), "\n")
|
|
||||||
_userAgentFilterMode := userAgentFilterLines[0]
|
|
||||||
|
|
||||||
println(len(userAgentFilterLines))
|
|
||||||
switch _userAgentFilterMode {
|
|
||||||
case "allow":
|
|
||||||
userAgentFilterMode = FILTER_MODE_WHITELIST
|
|
||||||
case "deny":
|
|
||||||
userAgentFilterMode = FILTER_MODE_BLACKLIST
|
|
||||||
default:
|
|
||||||
logError("invalid userAgent filter mode, use allow|deny")
|
|
||||||
}
|
|
||||||
userAgentFilter = userAgentFilterLines[1:]
|
|
||||||
}
|
|
||||||
|
21
utils.go
Normal file
21
utils.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getHttpVersionString(major, minor int) string {
|
||||||
|
return "HTTP/" + strconv.Itoa(major) + "." + strconv.Itoa(minor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOrDash(str string) string {
|
||||||
|
if str == "" {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureSlashSuffix(str string) string {
|
||||||
|
return strings.TrimSuffix(str, "/") + "/"
|
||||||
|
}
|
172
webserver.go
Normal file
172
webserver.go
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"slices"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FILTER_MODE_WHITELIST FilterMode = 0
|
||||||
|
FILTER_MODE_BLACKLIST FilterMode = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterMode int
|
||||||
|
|
||||||
|
type WebServer struct {
|
||||||
|
logger *Logger
|
||||||
|
port int
|
||||||
|
configFolder string
|
||||||
|
ipFilter []string
|
||||||
|
userAgentFilter []string
|
||||||
|
ipFilterMode FilterMode
|
||||||
|
userAgentFilterMode FilterMode
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWebServer(port_ int, logFolder_, configFolder_ string) *WebServer {
|
||||||
|
|
||||||
|
return &WebServer{
|
||||||
|
logger: NewLogger(logFolder_),
|
||||||
|
port: port_,
|
||||||
|
configFolder: configFolder_,
|
||||||
|
ipFilter: make([]string, 0),
|
||||||
|
userAgentFilter: make([]string, 0),
|
||||||
|
ipFilterMode: FILTER_MODE_BLACKLIST,
|
||||||
|
userAgentFilterMode: FILTER_MODE_BLACKLIST,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) Run() {
|
||||||
|
|
||||||
|
ws.ipFilterMode, ws.ipFilter = ws.parseFilterPanics(FILENAME_IPFILTER)
|
||||||
|
ws.userAgentFilterMode, ws.userAgentFilter = ws.parseFilterPanics(FILENAME_USERAGENTFILTER)
|
||||||
|
|
||||||
|
http.HandleFunc("/", ws.get)
|
||||||
|
log.Println("Server started on port " + strconv.Itoa(ws.port))
|
||||||
|
http.ListenAndServe(":"+strconv.Itoa(ws.port), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) parseFilterPanics(filename string) (FilterMode, []string) {
|
||||||
|
|
||||||
|
filterMode := FILTER_MODE_BLACKLIST
|
||||||
|
filter := make([]string, 0)
|
||||||
|
|
||||||
|
os.Mkdir(ws.configFolder, PERMS_MKDIR)
|
||||||
|
fileinfo, err := os.Stat(ensureSlashSuffix(ws.configFolder) + filename)
|
||||||
|
|
||||||
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
os.Create(ensureSlashSuffix(ws.configFolder) + filename)
|
||||||
|
fileinfo, err = os.Stat(ensureSlashSuffix(ws.configFolder) + filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic("Error opening " + filename + ": " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileinfo.Size() == 0 { // empty config
|
||||||
|
return filterMode, filter
|
||||||
|
}
|
||||||
|
|
||||||
|
filterContent, err := os.ReadFile(ensureSlashSuffix(ws.configFolder) + filename)
|
||||||
|
|
||||||
|
if ws.logger.logIfError(err) {
|
||||||
|
panic("Error reading " + filename + ": " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
filterLines := strings.Split(string(filterContent), "\n")
|
||||||
|
readFilterMode := filterLines[0]
|
||||||
|
|
||||||
|
switch readFilterMode {
|
||||||
|
case "allow":
|
||||||
|
filterMode = FILTER_MODE_WHITELIST
|
||||||
|
case "deny":
|
||||||
|
filterMode = FILTER_MODE_BLACKLIST
|
||||||
|
default:
|
||||||
|
panic("invalid filter mode for " + filename + ": use allow|deny")
|
||||||
|
}
|
||||||
|
|
||||||
|
filter = filterLines[1:]
|
||||||
|
|
||||||
|
return filterMode, filter
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) isIpValid(ip string) bool {
|
||||||
|
ip = strings.Split(ip, ":")[0] // remove port
|
||||||
|
switch ws.ipFilterMode {
|
||||||
|
case FILTER_MODE_WHITELIST:
|
||||||
|
return slices.Contains(ws.ipFilter, ip)
|
||||||
|
case FILTER_MODE_BLACKLIST:
|
||||||
|
return !slices.Contains(ws.ipFilter, ip)
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) isUserAgentValid(userAgent string) bool {
|
||||||
|
switch ws.userAgentFilterMode {
|
||||||
|
case FILTER_MODE_WHITELIST:
|
||||||
|
return slices.Contains(ws.userAgentFilter, userAgent)
|
||||||
|
case FILTER_MODE_BLACKLIST:
|
||||||
|
return !slices.Contains(ws.userAgentFilter, userAgent)
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) 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)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) get(writer http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
|
respStatusCode := http.StatusOK
|
||||||
|
|
||||||
|
if !ws.isIpValid(req.RemoteAddr) || !ws.isUserAgentValid(req.UserAgent()) {
|
||||||
|
writer.WriteHeader(http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchedData, fetchErr := ws.fetchFileContents(req.URL.Path)
|
||||||
|
|
||||||
|
sentBytes := 0
|
||||||
|
|
||||||
|
if ws.logger.logIfError(fetchErr) {
|
||||||
|
respStatusCode = http.StatusNotFound
|
||||||
|
writer.WriteHeader(respStatusCode)
|
||||||
|
} else {
|
||||||
|
sentBytesCount, _ := writer.Write(fetchedData)
|
||||||
|
sentBytes = sentBytesCount
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.logger.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+" "+getHttpVersionString(req.ProtoMajor, req.ProtoMinor), //HTTP version
|
||||||
|
strconv.Itoa(respStatusCode), //response code
|
||||||
|
strconv.Itoa(sentBytes), //# of sent bytes
|
||||||
|
req.Referer(), //Referer
|
||||||
|
req.UserAgent(), //User Agent
|
||||||
|
)
|
||||||
|
}
|
Reference in New Issue
Block a user