serve-core/serve.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))
}