|
|
|
@ -37,6 +37,9 @@ type HttpServerCfg struct {
|
|
|
|
|
key string
|
|
|
|
|
addr string
|
|
|
|
|
port string
|
|
|
|
|
page404 string
|
|
|
|
|
page403 string
|
|
|
|
|
page401 string
|
|
|
|
|
protectAuthPage []string
|
|
|
|
|
disableMIME bool
|
|
|
|
|
ctx context.Context
|
|
|
|
@ -338,15 +341,27 @@ func (h *HttpServer) Run(ctx context.Context) error {
|
|
|
|
|
if strings.Contains(v.Flags.String(), "up") {
|
|
|
|
|
addrs, err := v.Addrs()
|
|
|
|
|
if err == nil {
|
|
|
|
|
var ips []string
|
|
|
|
|
for _, ip := range addrs {
|
|
|
|
|
ips = append(ips, ip.String())
|
|
|
|
|
starlog.Cyan("Name:%s\tIP:%s\n", v.Name, ip)
|
|
|
|
|
}
|
|
|
|
|
starlog.Noticef("Name:%s IP:%s MAC:%s\n", v.Name, strings.Join(ips, ","), v.HardwareAddr)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
h.envPath, err = filepath.Abs(h.envPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("Failed to get abs path of", h.envPath)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
uconn, err := net.Dial("udp", "106.55.44.79:80")
|
|
|
|
|
if err == nil {
|
|
|
|
|
schema := "http://"
|
|
|
|
|
if h.cert != "" {
|
|
|
|
|
schema = "https://"
|
|
|
|
|
}
|
|
|
|
|
starlog.Infof("Visit: %s%s:%s\n", schema, uconn.LocalAddr().(*net.UDPAddr).IP.String(), h.port)
|
|
|
|
|
uconn.Close()
|
|
|
|
|
}
|
|
|
|
|
starlog.Infoln("Listening on " + h.addr + ":" + h.port)
|
|
|
|
|
if h.cert == "" {
|
|
|
|
|
if err := server.ListenAndServe(); err != http.ErrServerClosed {
|
|
|
|
@ -364,9 +379,39 @@ func (h *HttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
h.Listen(w, r)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *HttpServer) GiveBasicAuth(w http.ResponseWriter) {
|
|
|
|
|
w.Header().Set("WWW-Authenticate", ` Basic realm="Please Enter Passwd"`)
|
|
|
|
|
func (h *HttpServer) Page404(w http.ResponseWriter) {
|
|
|
|
|
w.WriteHeader(404)
|
|
|
|
|
if h.page404 != "" {
|
|
|
|
|
data, err := os.ReadFile(h.page404)
|
|
|
|
|
if err == nil {
|
|
|
|
|
w.Write(data)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
w.Write([]byte(`<html><title>B612 Http Server</title><body><h1 "style="text-align: center;">404 NOT FOUND</h1><hr ></body></html>`))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *HttpServer) Page403(w http.ResponseWriter) {
|
|
|
|
|
w.WriteHeader(403)
|
|
|
|
|
if h.page403 != "" {
|
|
|
|
|
data, err := os.ReadFile(h.page403)
|
|
|
|
|
if err == nil {
|
|
|
|
|
w.Write(data)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
w.Write([]byte(`<html><title>B612 Http Server</title><body><h1 "style="text-align: center;">403 Forbidden</h1><hr ></body></html>`))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *HttpServer) Page401(w http.ResponseWriter) {
|
|
|
|
|
w.WriteHeader(401)
|
|
|
|
|
if h.page401 != "" {
|
|
|
|
|
data, err := os.ReadFile(h.page401)
|
|
|
|
|
if err == nil {
|
|
|
|
|
w.Write(data)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
w.Write([]byte(`
|
|
|
|
|
<html>
|
|
|
|
|
<head><title>401 Authorization Required</title></head>
|
|
|
|
@ -377,6 +422,11 @@ func (h *HttpServer) GiveBasicAuth(w http.ResponseWriter) {
|
|
|
|
|
</html>`))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *HttpServer) GiveBasicAuth(w http.ResponseWriter) {
|
|
|
|
|
w.Header().Set("WWW-Authenticate", ` Basic realm="Please Enter Passwd"`)
|
|
|
|
|
h.Page401(w)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *HttpServer) BasicAuth(log *starlog.StarLogger, w http.ResponseWriter, r *http.Request) bool {
|
|
|
|
|
if h.basicAuthPwd != "" {
|
|
|
|
|
if len(h.protectAuthPage) != 0 {
|
|
|
|
@ -429,6 +479,8 @@ func (h *HttpServer) SetUpload(w http.ResponseWriter, r *http.Request, path stri
|
|
|
|
|
}
|
|
|
|
|
func (h *HttpServer) Listen(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
log := starlog.Std.NewFlag()
|
|
|
|
|
log.SetShowFuncName(false)
|
|
|
|
|
log.SetShowOriginFile(false)
|
|
|
|
|
w.Header().Set("X-Powered-By", "B612.ME")
|
|
|
|
|
w.Header().Set("Server", "B612/"+version)
|
|
|
|
|
if !h.BasicAuth(log, w, r) {
|
|
|
|
@ -439,14 +491,24 @@ func (h *HttpServer) Listen(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
h.uploadFile(w, r)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
fullpath := filepath.Join(h.envPath, path)
|
|
|
|
|
ua := r.Header.Get("User-Agent")
|
|
|
|
|
fullpath := filepath.Clean(filepath.Join(h.envPath, path))
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
//security check
|
|
|
|
|
if fullpath != h.envPath && !strings.HasPrefix(fullpath, h.envPath) {
|
|
|
|
|
log.Warningf("Invalid Path %s IP:%s Fullpath:%s\n", path, r.RemoteAddr, fullpath)
|
|
|
|
|
h.Page403(w)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if h.indexFile != "" && staros.IsFolder(fullpath) {
|
|
|
|
|
if staros.Exists(filepath.Join(fullpath, h.indexFile)) {
|
|
|
|
|
fullpath = filepath.Join(fullpath, h.indexFile)
|
|
|
|
|
path = filepath.Join(path, h.indexFile)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
log.Noticef("Start Method:%s Path:%s IP:%s\n", r.Method, path, r.RemoteAddr)
|
|
|
|
|
now := time.Now()
|
|
|
|
|
if h.SetUpload(w, r, path) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
@ -454,9 +516,9 @@ func (h *HttpServer) Listen(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
case "OPTIONS", "HEAD":
|
|
|
|
|
err := h.BuildHeader(w, r, fullpath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warningf("Finished Method:%s Path:%s IP:%s Err:%v\n", r.Method, path, r.RemoteAddr, err)
|
|
|
|
|
log.Warningf("%s %s From %s %s %.2fs %v\n", r.Method, path, r.RemoteAddr, ua, time.Since(now).Seconds(), err)
|
|
|
|
|
} else {
|
|
|
|
|
log.Infof("Finished Method:%s Path:%s IP:%s\n", r.Method, path, r.RemoteAddr)
|
|
|
|
|
log.Infof("%s %s From %s %s %.2fs \n", r.Method, path, r.RemoteAddr, ua, time.Since(now).Seconds())
|
|
|
|
|
}
|
|
|
|
|
case "GET":
|
|
|
|
|
err := h.BuildHeader(w, r, fullpath)
|
|
|
|
@ -465,12 +527,12 @@ func (h *HttpServer) Listen(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
}
|
|
|
|
|
err = h.ResponseGet(log, w, r, fullpath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warningf("Finished Method %s Path:%s IP:%s Err:%v\n", r.Method, path, r.RemoteAddr, err)
|
|
|
|
|
log.Warningf("%s %s From %s %s %.2fs %v\n", r.Method, path, r.RemoteAddr, ua, time.Since(now).Seconds(), err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
log.Infof("Finished Method:%s Path:%s IP:%s\n", r.Method, path, r.RemoteAddr)
|
|
|
|
|
log.Infof("%s %s From %s %s %.2fs \n", r.Method, path, r.RemoteAddr, ua, time.Since(now).Seconds())
|
|
|
|
|
default:
|
|
|
|
|
log.Warningf("Invalid Method %s Path:%s IP:%s\n", r.Method, path, r.RemoteAddr)
|
|
|
|
|
log.Errorf("Invalid %s %s From %s %s %.2fs %v\n", r.Method, path, r.RemoteAddr, ua, time.Since(now).Seconds())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -619,8 +681,7 @@ func (h *HttpServer) getFolder(log *starlog.StarLogger, w http.ResponseWriter, r
|
|
|
|
|
|
|
|
|
|
func (h *HttpServer) getFile(log *starlog.StarLogger, w http.ResponseWriter, r *http.Request, fullpath string) error {
|
|
|
|
|
if !staros.Exists(fullpath) {
|
|
|
|
|
w.WriteHeader(404)
|
|
|
|
|
w.Write([]byte(`<html><title>B612 Http Server</title><body><h1 "style="text-align: center;">404 NOT FOUND</h1><hr ></body></html>`))
|
|
|
|
|
h.Page404(w)
|
|
|
|
|
return errors.New("File Not Found! 404 ERROR")
|
|
|
|
|
}
|
|
|
|
|
//starlog.Debugln(r.Header)
|
|
|
|
@ -711,7 +772,7 @@ func (h *HttpServer) getFile(log *starlog.StarLogger, w http.ResponseWriter, r *
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
log.Debugf("206 transfer mode for %v %v\n", r.URL.Path, r.RemoteAddr)
|
|
|
|
|
log.Debugf("206 transfer mode for %v %v start %v end %v\n", r.URL.Path, r.RemoteAddr, startRange, endRange)
|
|
|
|
|
w.WriteHeader(206)
|
|
|
|
|
fp.Seek(int64(startRange), 0)
|
|
|
|
|
count := startRange
|
|
|
|
|