|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
package tools
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"io/ioutil"
|
|
|
|
@ -19,27 +20,48 @@ import (
|
|
|
|
|
|
|
|
|
|
var port, ip, path string
|
|
|
|
|
var up bool
|
|
|
|
|
var basicAuth, certKey string
|
|
|
|
|
|
|
|
|
|
type TraceHandler struct {
|
|
|
|
|
h http.Handler
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
httpcmd.Flags().StringVarP(&port, "port", "p", "80", "监听端口")
|
|
|
|
|
httpcmd.Flags().StringVarP(&ip, "ip", "i", "0.0.0.0", "监听ip")
|
|
|
|
|
httpcmd.Flags().StringVarP(&path, "folder", "f", "./", "本地文件地址")
|
|
|
|
|
httpcmd.Flags().BoolVarP(&up, "upload", "u", false, "是否开启文件上传")
|
|
|
|
|
httpcmd.Flags().StringVarP(&basicAuth, "auth", "a", "", "HTTP BASIC AUTH认证(用户名:密码)")
|
|
|
|
|
httpcmd.Flags().StringVarP(&certKey, "cert", "c", "", "TLS证书路径,用:分割证书与密钥")
|
|
|
|
|
Maincmd.AddCommand(httpcmd)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// httpCmd represents the http command
|
|
|
|
|
var httpcmd = &cobra.Command{
|
|
|
|
|
Use: "http",
|
|
|
|
|
Short: "HTTP文件服务器",
|
|
|
|
|
Long: `HTTP文件服务器`,
|
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
|
var err error
|
|
|
|
|
http.HandleFunc("/", httplisten)
|
|
|
|
|
path, _ = filepath.Abs(path)
|
|
|
|
|
fmt.Println("Listening On Port:" + port)
|
|
|
|
|
starlog.Infoln("Listening On Port:" + port)
|
|
|
|
|
if up {
|
|
|
|
|
fmt.Println("upload is openned,path is /vtqeupload1127")
|
|
|
|
|
starlog.Infoln("upload is openned,path is /vtqeupload1127")
|
|
|
|
|
http.HandleFunc("/vtqeupload1127", uploadfile)
|
|
|
|
|
}
|
|
|
|
|
err := http.ListenAndServe(ip+":"+port, nil)
|
|
|
|
|
if certKey == "" {
|
|
|
|
|
err = http.ListenAndServe(ip+":"+port, nil)
|
|
|
|
|
} else {
|
|
|
|
|
certs := strings.Split(certKey, ":")
|
|
|
|
|
if len(certs) != 2 {
|
|
|
|
|
starlog.Criticalln("证书不正确!")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = http.ListenAndServeTLS(ip+":"+port, certs[0], certs[1], nil)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.StdPrintln(0, starlog.RED, "Error:"+err.Error())
|
|
|
|
|
starlog.Criticalln("Error:" + err.Error())
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
@ -52,18 +74,18 @@ func uploadfile(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
r.ParseMultipartForm(10485760)
|
|
|
|
|
file, handler, err := r.FormFile("victorique")
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
starlog.Errorln(err)
|
|
|
|
|
w.WriteHeader(502)
|
|
|
|
|
w.Write([]byte(err.Error()))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
fmt.Printf("Upload %s From %s\n", handler.Filename, r.RemoteAddr)
|
|
|
|
|
starlog.Noticef("Upload %s From %s\n", handler.Filename, r.RemoteAddr)
|
|
|
|
|
fmt.Fprintf(w, `<html><body><p>%v</p><h2><a href="./vtqeupload1127/web">Return To Web Page</a></h2></body></html>`, handler.Header)
|
|
|
|
|
os.Mkdir("./vtqeupload1127", 0755)
|
|
|
|
|
f, err := os.OpenFile("./vtqeupload1127/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0755)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
starlog.Errorln(err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
defer f.Close()
|
|
|
|
@ -71,11 +93,40 @@ func uploadfile(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func httplisten(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
log := starlog.Std.NewFlag()
|
|
|
|
|
w.Header().Set("Server", "Vicorique")
|
|
|
|
|
w.Header().Set("Powered", "B612.ME")
|
|
|
|
|
write401 := func() {
|
|
|
|
|
w.Header().Set("WWW-Authenticate", ` Basic realm="Please Enter Passwd"`)
|
|
|
|
|
w.WriteHeader(401)
|
|
|
|
|
w.Write([]byte(`
|
|
|
|
|
<html>
|
|
|
|
|
<head><title>401 Authorization Required</title></head>
|
|
|
|
|
<body>
|
|
|
|
|
<center><h1>401 Authorization Required</h1></center>
|
|
|
|
|
<hr><center>B612 HTTP SERVER</center>
|
|
|
|
|
</body>
|
|
|
|
|
</html>`))
|
|
|
|
|
}
|
|
|
|
|
if basicAuth != "" {
|
|
|
|
|
authHeader := strings.TrimSpace(r.Header.Get("Authorization"))
|
|
|
|
|
if len(authHeader) == 0 {
|
|
|
|
|
log.Noticeln("No Authed! Get Path is", r.URL.Path, r.RemoteAddr)
|
|
|
|
|
write401()
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
userAuth := base64.StdEncoding.EncodeToString([]byte(basicAuth))
|
|
|
|
|
authStr := strings.Split(authHeader, " ")
|
|
|
|
|
if strings.TrimSpace(authStr[1]) != userAuth {
|
|
|
|
|
log.Noticeln("Auth Failed! Get Path is", r.URL.Path, r.RemoteAddr, "pwd enter is", authHeader)
|
|
|
|
|
write401()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
p := r.URL.Path
|
|
|
|
|
cmd := r.URL.Query()["cmd"]
|
|
|
|
|
fmt.Println("Get " + p + " " + r.RemoteAddr)
|
|
|
|
|
log.Noticeln("Get " + p + " " + r.RemoteAddr)
|
|
|
|
|
fullpath, _ := filepath.Abs(path + p)
|
|
|
|
|
|
|
|
|
|
if p == "/" {
|
|
|
|
@ -113,7 +164,7 @@ func httplisten(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
}
|
|
|
|
|
fpdst, err := os.Open(fullpath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
log.Errorln(err)
|
|
|
|
|
w.WriteHeader(403)
|
|
|
|
|
w.Write([]byte("<h1>403 NO ACCESS</h1>"))
|
|
|
|
|
return
|
|
|
|
@ -142,7 +193,7 @@ func httplisten(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.Header().Set("Content-Transfer-Encoding", "binary")
|
|
|
|
|
w.Header().Set("Accept-Ranges", "bytes")
|
|
|
|
|
w.Header().Set("ETag", etag)
|
|
|
|
|
w.Header().Set("Last-Modified", fpinfo.ModTime().Format("Mon,2 Jan 2006 15:04:05 MST"))
|
|
|
|
|
w.Header().Set("Last-Modified", strings.ReplaceAll(fpinfo.ModTime().UTC().Format("Mon, 2 Jan 2006 15:04:05 MST"), "UTC", "GMT"))
|
|
|
|
|
isRange := false
|
|
|
|
|
var rangeStart, rangeEnd int64
|
|
|
|
|
rangeEnd = -1
|
|
|
|
@ -166,19 +217,26 @@ func httplisten(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
defer fpdst.Close()
|
|
|
|
|
var transferData int
|
|
|
|
|
if !isRange {
|
|
|
|
|
w.Header().Set("Content-Length", strconv.FormatInt(fpinfo.Size(), 10))
|
|
|
|
|
w.WriteHeader(200)
|
|
|
|
|
for {
|
|
|
|
|
buf := make([]byte, 1048576)
|
|
|
|
|
n, err := fpdst.Read(buf)
|
|
|
|
|
if n != 0 {
|
|
|
|
|
ns, err := w.Write(buf[0:n])
|
|
|
|
|
transferData += ns
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("Transfer Error:", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
if err == io.EOF {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
w.Write(buf[0:n])
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
w.Header().Set("Content-Length", strconv.FormatInt(fpinfo.Size(), 10))
|
|
|
|
@ -202,7 +260,11 @@ func httplisten(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if rangeEnd == -1 {
|
|
|
|
|
w.Write(buf[0:n])
|
|
|
|
|
ns, err := w.Write(buf[0:n])
|
|
|
|
|
transferData += ns
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("Transfer Error:", err)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if count > rangeEnd {
|
|
|
|
|
break
|
|
|
|
@ -211,19 +273,34 @@ func httplisten(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
w.Write(buf[0 : rangeEnd-count+1])
|
|
|
|
|
break
|
|
|
|
|
} else {
|
|
|
|
|
w.Write(buf[0:n])
|
|
|
|
|
ns, err := w.Write(buf[0:n])
|
|
|
|
|
transferData += ns
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("Transfer Error:", err)
|
|
|
|
|
}
|
|
|
|
|
count += int64(n)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fmt.Println(fpinfo.Name(), "客户端下载已结束")
|
|
|
|
|
}
|
|
|
|
|
var tani string
|
|
|
|
|
tani = fmt.Sprintf("%v Byte", transferData)
|
|
|
|
|
if f64 := float64(transferData) / 1024; f64 > 1 {
|
|
|
|
|
tani = fmt.Sprintf("%v KB", f64)
|
|
|
|
|
if f64 = float64(f64) / 1024; f64 > 1 {
|
|
|
|
|
tani = fmt.Sprintf("%v MB", f64)
|
|
|
|
|
if f64 = float64(f64) / 1024; f64 > 1 {
|
|
|
|
|
tani = fmt.Sprintf("%v GB", f64)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
log.Infoln(fpinfo.Name(), "客户端下载已结束,共传输大小:"+tani)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ReadFolder(w http.ResponseWriter, r *http.Request, fullpath string, isroot bool) {
|
|
|
|
|
dir, err := ioutil.ReadDir(fullpath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
starlog.Errorln(err)
|
|
|
|
|
w.WriteHeader(403)
|
|
|
|
|
w.Write([]byte("<h1>May Cannot Access!</h1>"))
|
|
|
|
|
}
|
|
|
|
@ -252,10 +329,3 @@ func ReadFolder(w http.ResponseWriter, r *http.Request, fullpath string, isroot
|
|
|
|
|
w.Write([]byte("</pre>\n</html>"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
func init() {
|
|
|
|
|
httpcmd.Flags().StringVarP(&port, "port", "p", "80", "监听端口")
|
|
|
|
|
httpcmd.Flags().StringVarP(&ip, "ip", "i", "0.0.0.0", "监听ip")
|
|
|
|
|
httpcmd.Flags().StringVarP(&path, "folder", "f", "./", "本地文件地址")
|
|
|
|
|
httpcmd.Flags().BoolVarP(&up, "upload", "u", false, "是否开启文件上传")
|
|
|
|
|
Maincmd.AddCommand(httpcmd)
|
|
|
|
|
}
|
|
|
|
|