GUpload/gupload/gupload.go

141 lines
2.9 KiB
Go
Executable File

package gupload
import (
"fmt"
"io"
"io/ioutil"
"local/router"
"log"
"net/http"
"os"
"path"
"strings"
)
type Gupload struct {
p string
r *router.Router
d string
}
func New() *Gupload {
p, ok := os.LookupEnv("PORT")
if !ok {
p = "55112"
}
d, ok := os.LookupEnv("DIR")
if !ok {
tempDir, err := ioutil.TempDir(os.TempDir(), "gupload_")
if err != nil {
panic(err)
}
d = tempDir
}
return &Gupload{
p: ":" + strings.TrimPrefix(p, ":"),
r: router.New(),
d: d,
}
}
func (g *Gupload) Run() error {
if err := g.Routes(); err != nil {
return err
}
log.Printf("Listening on %s", g.p)
return http.ListenAndServe(g.p, g.r)
}
func (g *Gupload) Routes() error {
if err := g.r.Add("/", g.form); err != nil {
return err
}
if err := g.r.Add("upload/"+router.Wildcard+router.Wildcard, g.upload); err != nil {
return err
}
if err := g.r.Add("download/"+router.Wildcard+router.Wildcard, g.download); err != nil {
return err
}
return nil
}
func (g *Gupload) form(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<form
enctype="multipart/form-data"
action="/upload"
method="post"
>
<input type="file" name="myFile" />
<input type="text" name="path" />
<input type="submit" value="upload" />
</form>
</body>
</html>
`)
}
func (g *Gupload) upload(w http.ResponseWriter, r *http.Request) {
p := strings.TrimPrefix(r.URL.Path, "/upload/")
if p == r.URL.Path {
p = strings.TrimPrefix(r.URL.Path, "/upload")
}
if len(p) < 2 {
p = r.FormValue("path")
}
p = path.Join(g.d, p)
r.ParseMultipartForm(10 << 20)
file, handler, err := r.FormFile("myFile")
if err != nil {
fmt.Fprintln(w, err)
return
}
defer file.Close()
// handler.{Filename,Size}
if err := os.MkdirAll(path.Dir(p), os.ModePerm); err != nil {
fmt.Fprintln(w, err)
return
}
f, err := os.OpenFile(p, os.O_CREATE|os.O_RDWR, os.ModePerm)
if err != nil {
fmt.Fprintln(w, err)
return
}
defer f.Close()
if n, err := io.Copy(f, file); err != nil || n != handler.Size {
fmt.Fprintln(w, err)
return
}
fmt.Fprintf(w, path.Join("download", strings.TrimPrefix(f.Name(), g.d)))
}
func (g *Gupload) download(w http.ResponseWriter, r *http.Request) {
p := strings.TrimPrefix(r.URL.Path, "/download/")
if p == r.URL.Path || p == "" {
http.NotFound(w, r)
return
}
f, err := os.OpenFile(path.Join(g.d, p), os.O_RDONLY, os.ModePerm)
if err != nil {
fmt.Fprintln(w, err)
return
}
if _, err := io.Copy(w, f); err != nil {
fmt.Fprintln(w, err)
return
}
}