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, ` Document
`) } 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 } }