141 lines
2.9 KiB
Go
Executable File
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
|
|
}
|
|
}
|