You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Victorique/vtqe/tools/http.go

196 lines
5.1 KiB
Go

package tools
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"b612.me/starainrt"
"b612.me/starlog"
"github.com/spf13/cobra"
)
var port, ip, path string
var up bool
type TraceHandler struct {
h http.Handler
}
// httpCmd represents the http command
var httpcmd = &cobra.Command{
Use: "http",
Short: "HTTP文件服务器",
Long: `HTTP文件服务器`,
Run: func(cmd *cobra.Command, args []string) {
http.HandleFunc("/", httplisten)
path, _ = filepath.Abs(path)
fmt.Println("Listening On Port:" + port)
if up {
fmt.Println("upload is openned,path is /vtqeupload1127")
http.HandleFunc("/vtqeupload1127", uploadfile)
}
err := http.ListenAndServe(ip+":"+port, nil)
if err != nil {
starlog.Println("Error:"+err.Error(), "red", "")
}
},
}
func uploadfile(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
w.Write([]byte("USE POST METHOD!"))
return
}
r.ParseMultipartForm(10485760)
file, handler, err := r.FormFile("victorique")
if err != nil {
fmt.Println(err)
w.WriteHeader(502)
w.Write([]byte(err.Error()))
return
}
defer file.Close()
fmt.Printf("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)
return
}
defer f.Close()
io.Copy(f, file)
}
func httplisten(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Server", "Vicorique")
p := r.URL.Path
cmd := r.URL.Query()["cmd"]
fmt.Println("Get " + p + " " + r.RemoteAddr)
fullpath, _ := filepath.Abs(path + p)
if p == "/" {
ReadFolder(w, r, fullpath, true)
return
}
if up {
if p == "/vtqeupload1127/web" {
w.Write([]byte(`<html><body><form id= "uploadForm" action= "../vtqeupload1127" method= "post" enctype ="multipart/form-data">
<h1 >Victorique's File Upload Page </h1>
<p >上传文件: <input type ="file" name="victorique" /></p>
<input type ="submit" value="上传"/>
</form>
<h2>Copyright@b612.me </h2></body></html>`))
return
}
}
if !starainrt.Exists(fullpath) {
w.WriteHeader(404)
if len(cmd) != 0 {
if cmd[0] == "header" {
for k, v := range r.Header {
for _, v2 := range v {
fmt.Fprintf(w, "%s:%s\n", k, v2)
}
}
}
}
w.Write([]byte("<h1>404 NOT FOUND</h1>"))
return
}
if starainrt.IsFolder(fullpath) {
ReadFolder(w, r, fullpath, false)
return
}
fpdst, err := os.Open(fullpath)
if err != nil {
fmt.Println(err)
w.WriteHeader(502)
w.Write([]byte("<h1>502 ERROR</h1>"))
return
}
fpinfo, _ := os.Stat(fullpath)
name := filepath.Base(fullpath)
tmp := strings.Split(name, ".")
ext := ""
if len(tmp) >= 2 {
ext = strings.ToLower(tmp[len(tmp)-1])
}
switch ext {
case "jpeg", "jpg", "jpe":
w.Header().Set("Content-Type", "image/jpeg")
case "mpeg", "mpg", "mkv":
w.Header().Set("Content-Type", "video/mpeg")
case "mp4":
w.Header().Set("Content-Type", "video/mp4")
case "pdf":
w.Header().Set("Content-Type", "application/pdf")
default:
w.Header().Set("Content-Type", "application/download")
w.Header().Set("Content-Disposition", "attachment;filename="+name)
}
w.Header().Set("Content-Transfer-Encoding", "binary")
w.Header().Set("Accept-Ranges", "bytes")
w.Header().Set("Content-Length", strconv.Itoa(int(fpinfo.Size())))
w.WriteHeader(200)
defer fpdst.Close()
for {
buf := make([]byte, 1048576)
n, err := fpdst.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return
}
w.Write(buf[0:n])
}
}
func ReadFolder(w http.ResponseWriter, r *http.Request, fullpath string, isroot bool) {
dir, err := ioutil.ReadDir(fullpath)
if err != nil {
fmt.Println(err)
w.WriteHeader(403)
w.Write([]byte("<h1>Cannot Access!</h1>"))
return
}
w.Write([]byte("<html>\n<style>\np{margin: 2px auto}\n</style>\n<h1>Victorique Http Server - " + Version + "</h1>"))
if up {
w.Write([]byte("<a href=/vtqeupload1127/web>Upload Web Page Is Openned!</a><br /><br />"))
}
w.Write([]byte("<hr /><pre>\n"))
if !isroot {
w.Write([]byte(fmt.Sprintf("<p><a href='%s'>%s</a> %s</p>\n", r.URL.Path+"/..", "..", "上层文件夹")))
}
if r.URL.Path == "/" {
r.URL.Path = ""
}
for _, v := range dir {
if v.Name() != "." || v.Name() != ".." {
if !v.IsDir() {
w.Write([]byte(fmt.Sprintf("<p><a href='%s'>%s</a> %d %s</p>\n", r.URL.Path+"/"+v.Name(), v.Name(), int(v.Size()), v.ModTime().Format("2006-01-02 15:04:05"))))
} else {
w.Write([]byte(fmt.Sprintf("<p><a href='%s'>%s</a> %s %s</p>\n", r.URL.Path+"/"+v.Name(), v.Name(), "文件夹", v.ModTime().Format("2006-01-02 15:04:05"))))
}
}
}
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)
}