73 lines
2.4 KiB
Go
73 lines
2.4 KiB
Go
|
// Copyright 2018 hybris. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE.md file.
|
||
|
|
||
|
// simple wrapper around http.Fileserver and http.ServeFile
|
||
|
package serve
|
||
|
|
||
|
import (
|
||
|
"os"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"net/http"
|
||
|
"path/filepath"
|
||
|
"github.com/kpango/glg"
|
||
|
)
|
||
|
|
||
|
|
||
|
func Serve(path_tainted string, ip_tainted string, port_tainted int) {
|
||
|
if (os.Geteuid() == 0) {
|
||
|
glg.Warn("running as root")
|
||
|
}
|
||
|
|
||
|
path, err_path := validatePath(path_tainted)
|
||
|
ip, err_ip := validateAddress(ip_tainted)
|
||
|
port, err_port := validatePort(port_tainted)
|
||
|
|
||
|
listen := strings.Join([]string{ip,strconv.Itoa(port)}, ":")
|
||
|
|
||
|
if (err_path == nil && err_ip == nil && err_port == nil) {
|
||
|
fi, _ := os.Stat(path)
|
||
|
switch mode := fi.Mode(); {
|
||
|
case mode.IsDir():
|
||
|
serveDirectory(path,listen)
|
||
|
break
|
||
|
case mode.IsRegular():
|
||
|
serveFile(path,listen)
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ServeDirectory will start a http.FileServer for the given path on the given listen address
|
||
|
// expects `path` to be a valid directory
|
||
|
func serveDirectory(path,listen string) {
|
||
|
glg.Infof("serving directory %s on %s",path,listen)
|
||
|
if (strings.Compare(path,"/") == 0) {
|
||
|
glg.Warn("you are serving your whole filesystem right now, use with care")
|
||
|
}
|
||
|
panic(http.ListenAndServe(listen, loggingHandler(http.FileServer(http.Dir(path)))))
|
||
|
}
|
||
|
|
||
|
// custom handler to achieve access logging for http.FileServer
|
||
|
func loggingHandler(h http.Handler) http.Handler {
|
||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
glg.Infof("Access: from: %s method: %s full_path: %s%s",r.RemoteAddr,r.Method,r.Host,r.URL.Path)
|
||
|
h.ServeHTTP(w, r)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// ServeFile will start http.ListenAndServe and answer request on "/" with the file from the given path
|
||
|
// expects `path` to be a valid file
|
||
|
func serveFile(path,listen string) {
|
||
|
glg.Infof("serving file '%s' on '%s'",path,listen)
|
||
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){
|
||
|
glg.Infof("Access: from: %s method: %s full_path: %s%s",r.RemoteAddr,r.Method,r.Host,r.URL.Path)
|
||
|
var header_string = "attachment; filename="
|
||
|
header_string += filepath.Base(path)
|
||
|
w.Header().Set("Content-Disposition", header_string)
|
||
|
http.ServeFile(w, r, path)
|
||
|
})
|
||
|
panic(http.ListenAndServe(listen,nil))
|
||
|
}
|