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.StdPrintln(0, starlog.RED, "Error:"+err.Error()) } }, } 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, `

%v

Return To Web Page

`, 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") w.Header().Set("Powered", "B612.ME") 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(`

B612 File Upload Page

上传文件:

Copyright@b612.me

`)) 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("

404 NOT FOUND

")) return } if starainrt.IsFolder(fullpath) { ReadFolder(w, r, fullpath, false) return } fpdst, err := os.Open(fullpath) if err != nil { fmt.Println(err) w.WriteHeader(403) w.Write([]byte("

403 NO ACCESS

")) 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) } etag := new(starainrt.StarCrypto).MD5([]byte(fpinfo.ModTime().String())) 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")) isRange := false var rangeStart, rangeEnd int64 rangeEnd = -1 for k, v := range r.Header { if strings.ToLower(k) == "range" { if strings.Index(v[0], "bytes=") < 0 { break } v[0] = strings.Replace(v[0], "bytes=", "", -1) data := strings.Split(v[0], "-") if len(data) == 0 { break } rangeStart, _ = strconv.ParseInt(data[0], 10, 64) if len(data) == 2 { rangeEnd, _ = strconv.ParseInt(data[1], 10, 64) } //w.WriteHeader(206) //206 支持断点续传 isRange = true break } } defer fpdst.Close() 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 err != nil { if err == io.EOF { break } return } w.Write(buf[0:n]) } } else { w.Header().Set("Content-Length", strconv.FormatInt(fpinfo.Size(), 10)) if rangeEnd == -1 { w.Header().Set("Content-Range", `bytes `+strconv.FormatInt(rangeStart, 10)+"-"+strconv.FormatInt(fpinfo.Size(), 10)+"/"+strconv.FormatInt(fpinfo.Size(), 10)) //w.Header().Set("Content-Length", strconv.FormatInt(fpinfo.Size()-rangeStart, 10)) } else { w.Header().Set("Content-Range", `bytes `+strconv.FormatInt(rangeStart, 10)+"-"+strconv.FormatInt(rangeEnd, 10)+"/"+strconv.FormatInt(fpinfo.Size(), 10)) //w.Header().Set("Content-Length", strconv.FormatInt(1+rangeEnd-rangeStart, 10)) } w.WriteHeader(206) fpdst.Seek(int64(rangeStart), 0) count := rangeStart for { buf := make([]byte, 1048576) n, err := fpdst.Read(buf) if err != nil { if err == io.EOF { break } return } if rangeEnd == -1 { w.Write(buf[0:n]) } else { if count > rangeEnd { break } if count+int64(n) > rangeEnd { w.Write(buf[0 : rangeEnd-count+1]) break } else { w.Write(buf[0:n]) count += int64(n) } } } fmt.Println(fpinfo.Name(), "客户端下载已结束") } } 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("

May Cannot Access!

")) } w.Write([]byte("\n\n

B612 Http Server - " + Version + "

")) if up { w.Write([]byte("Upload Web Page Is Openned!

")) } w.Write([]byte("
\n"))
	if r.URL.Path == "/" {
		r.URL.Path = ""
	} else if r.URL.Path[len(r.URL.Path)-1:] == "/" {
		r.URL.Path = r.URL.Path[0 : len(r.URL.Path)-1]
	}
	if !isroot {
		w.Write([]byte(fmt.Sprintf("

%s %s

\n", r.URL.Path+"/..", "..", "上层文件夹"))) } for _, v := range dir { if v.Name() != "." || v.Name() != ".." { if !v.IsDir() { w.Write([]byte(fmt.Sprintf("

%s %d %s

\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("

%s %s %s

\n", r.URL.Path+"/"+v.Name(), v.Name(), "文件夹", v.ModTime().Format("2006-01-02 15:04:05")))) } } } w.Write([]byte("
\n")) 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) }