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:
@@ -14,7 +14,7 @@ miniws (minimalist web sever) is a very simple web server written in golang. its
|
|||||||
## how to configure
|
## how to configure
|
||||||
in your config folder you will find `ipfilter.conf` and `useragentfilter.conf`
|
in your config folder you will find `ipfilter.conf` and `useragentfilter.conf`
|
||||||
|
|
||||||
both files use the same format: specify `allow|deny` in the first row to tell miniws to treat the file as a whitelist or a blacklist, then specify one ip/user-agent per row.
|
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.
|
||||||
|
|
||||||
## logging
|
## logging
|
||||||
|
|
||||||
|
@@ -128,19 +128,34 @@ func (ws *WebServer) isUserAgentValid(userAgent string) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WebServer) fetchFileContents(filepath string) ([]byte, error) {
|
// fetchFile is a safe wrapper for os.OpenFile, which sanitizes the
|
||||||
|
// provided filepath, and, if a folder is passed, it looks for an
|
||||||
|
// index.html to fetch.
|
||||||
|
//
|
||||||
|
// IMPORTANT: remember to close the file after use!!!! fetchFile doesn't
|
||||||
|
// do it for you for obvious reasons
|
||||||
|
func (ws *WebServer) fetchFile(filepath string) (*os.File, error) {
|
||||||
|
return os.OpenFile(ws._cleanFilepath(filepath), os.O_RDONLY, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) fetchStat(filepath string) (os.FileInfo, error) {
|
||||||
|
clean_filepath := ws._cleanFilepath(filepath)
|
||||||
|
return os.Stat(clean_filepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) _cleanFilepath(filepath string) string {
|
||||||
if filepath == "/" {
|
if filepath == "/" {
|
||||||
filepath = "."
|
filepath = "."
|
||||||
}
|
}
|
||||||
fileinfo, err := os.Stat(filepath)
|
fileinfo, err := os.Stat(filepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
ws.logger.logError(err.Error())
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
if fileinfo.IsDir() {
|
if fileinfo.IsDir() {
|
||||||
filepath += "/index.html"
|
filepath += "/index.html"
|
||||||
}
|
}
|
||||||
return os.ReadFile(filepath)
|
return filepath
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WebServer) get(writer http.ResponseWriter, req *http.Request) {
|
func (ws *WebServer) get(writer http.ResponseWriter, req *http.Request) {
|
||||||
@@ -164,19 +179,24 @@ func (ws *WebServer) get(writer http.ResponseWriter, req *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchedData, fetchErr := ws.fetchFileContents(ensureSlashSuffix(ws.wwwFolder) + strings.TrimPrefix(req.URL.Path, "/"))
|
fileToFetch := ensureSlashSuffix(ws.wwwFolder) + strings.TrimPrefix(req.URL.Path, "/")
|
||||||
|
fetchedFile, fetchErr := ws.fetchFile(fileToFetch)
|
||||||
|
fetchedFileStat, _ := fetchedFile.Stat()
|
||||||
|
fetchedStat, _ := ws.fetchStat(fileToFetch)
|
||||||
|
|
||||||
sentBytes := 0
|
sentBytes := int64(0)
|
||||||
|
|
||||||
if ws.logger.logIfError(fetchErr) {
|
if ws.logger.logIfError(fetchErr) {
|
||||||
respStatusCode = http.StatusNotFound
|
respStatusCode = http.StatusNotFound
|
||||||
writer.WriteHeader(respStatusCode)
|
writer.WriteHeader(respStatusCode)
|
||||||
} else {
|
} else {
|
||||||
|
http.ServeContent(writer, req, fileToFetch, fetchedStat.ModTime(), fetchedFile)
|
||||||
writer.Header().Add("Content-Type", mime.TypeByExtension(filepath.Ext(req.URL.Path)))
|
writer.Header().Add("Content-Type", mime.TypeByExtension(filepath.Ext(req.URL.Path)))
|
||||||
sentBytesCount, _ := writer.Write(fetchedData)
|
sentBytes = fetchedFileStat.Size()
|
||||||
sentBytes = sentBytesCount
|
fetchedFile.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this thing writes to the log using the NCSA Combined Log Format
|
||||||
ws.logger.logAccess(
|
ws.logger.logAccess(
|
||||||
strings.Split(req.RemoteAddr, ":")[0], //remote address
|
strings.Split(req.RemoteAddr, ":")[0], //remote address
|
||||||
"-", //identifier (can't get)
|
"-", //identifier (can't get)
|
||||||
@@ -184,7 +204,7 @@ func (ws *WebServer) get(writer http.ResponseWriter, req *http.Request) {
|
|||||||
time.Now().Format("02/Jan/2006:15:04:05 -0700"), //timestamp
|
time.Now().Format("02/Jan/2006:15:04:05 -0700"), //timestamp
|
||||||
req.Method+" "+req.URL.Path+" "+getHttpVersionString(req.ProtoMajor, req.ProtoMinor), //HTTP version
|
req.Method+" "+req.URL.Path+" "+getHttpVersionString(req.ProtoMajor, req.ProtoMinor), //HTTP version
|
||||||
strconv.Itoa(respStatusCode), //response code
|
strconv.Itoa(respStatusCode), //response code
|
||||||
strconv.Itoa(sentBytes), //# of sent bytes
|
strconv.Itoa(int(sentBytes)), //# of sent bytes
|
||||||
req.Referer(), //Referer
|
req.Referer(), //Referer
|
||||||
req.UserAgent(), //User Agent
|
req.UserAgent(), //User Agent
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user