|
|
@@ -10,62 +10,10 @@ import (
|
|
|
"io/ioutil"
|
|
|
"strings"
|
|
|
"encoding/json"
|
|
|
- "path/filepath"
|
|
|
|
|
|
- "compress/gzip"
|
|
|
"bytes"
|
|
|
- "archive/tar"
|
|
|
- "io"
|
|
|
- "time"
|
|
|
- "math"
|
|
|
- "fmt"
|
|
|
"html/template"
|
|
|
)
|
|
|
-
|
|
|
-type Item struct {
|
|
|
- Name string
|
|
|
- Size int64
|
|
|
- URL string
|
|
|
- Date time.Time
|
|
|
- Valid bool
|
|
|
-}
|
|
|
-
|
|
|
-func (i Item) FDate() string {
|
|
|
- if i.Date.IsZero() {
|
|
|
- return "-"
|
|
|
- }
|
|
|
- return i.Date.Format(time.RFC822)
|
|
|
-}
|
|
|
-
|
|
|
-func (i Item) FSize() string {
|
|
|
- if i.Size == 0 {
|
|
|
- return "-"
|
|
|
- }
|
|
|
- if i.Size < 1024 {
|
|
|
- return fmt.Sprintf("%d B", i.Size)
|
|
|
- }
|
|
|
- exp := int(math.Log(float64(i.Size)) / math.Log(1024))
|
|
|
- pre := string("KMGTPE"[(exp-1)])
|
|
|
- fsize := float64(i.Size) / math.Pow(1024, float64(exp))
|
|
|
- return fmt.Sprintf("%.1f %siB", fsize, pre)
|
|
|
-}
|
|
|
-
|
|
|
-type Page struct {
|
|
|
- Title string
|
|
|
- Items []Item
|
|
|
- Error int
|
|
|
-}
|
|
|
-
|
|
|
-type Config struct {
|
|
|
- Directories map[string]Directory `json:"data"`
|
|
|
- Address string `json:"address"`
|
|
|
-}
|
|
|
-
|
|
|
-type Directory struct {
|
|
|
- Path string `json:"path"`
|
|
|
- Extension string `json:"ext"`
|
|
|
- Compress bool `json:"compress"`
|
|
|
-}
|
|
|
var config = Config{}
|
|
|
|
|
|
func main() {
|
|
|
@@ -152,11 +100,11 @@ func serveDirectory(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
page = Page{Title: urlPath, Items: make([]Item, len(files))}
|
|
|
for i, file := range files {
|
|
|
+ // TODO: Support directories
|
|
|
if file.IsDir() {
|
|
|
continue
|
|
|
}
|
|
|
- ext := strings.TrimLeft(filepath.Ext(file.Name()), ".")
|
|
|
- if strings.ToLower(ext) != strings.ToLower(configDir.Extension) {
|
|
|
+ if !strings.HasSuffix(strings.ToLower(file.Name()), strings.ToLower(configDir.Extension)) {
|
|
|
continue
|
|
|
}
|
|
|
page.Items[i] = Item{
|
|
|
@@ -190,9 +138,19 @@ func serveFile(w http.ResponseWriter, r *http.Request) {
|
|
|
handleError(w,r, err, "File does not exist", http.StatusNotFound)
|
|
|
return
|
|
|
}
|
|
|
- if configDir.Compress {
|
|
|
+ if !strings.HasSuffix(strings.ToLower(urlFile), strings.ToLower(configDir.Extension)) {
|
|
|
+ handleError(w,r, err, "File does not exist", http.StatusNotFound)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ q := r.URL.Query()
|
|
|
+ if q.Get("tarball") == "1" {
|
|
|
buf := new(bytes.Buffer)
|
|
|
- err = compress(servedFile, buf)
|
|
|
+ file, err := os.Open(servedFile)
|
|
|
+ if err != nil {
|
|
|
+ handleError(w, r, err, "Unable to serve file", http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = compress(file, buf)
|
|
|
if err != nil {
|
|
|
handleError(w, r, err, "Unable to compress file", http.StatusInternalServerError)
|
|
|
return
|
|
|
@@ -205,38 +163,12 @@ func serveFile(w http.ResponseWriter, r *http.Request) {
|
|
|
handleError(w, r, err, "Unable to read file", http.StatusInternalServerError)
|
|
|
return
|
|
|
}
|
|
|
- w.Header().Set("Content-Disposition", "attachment; filename=\""+urlFile+"\"")
|
|
|
+ // If request is not tarball - send raw file to browser not as attachment.
|
|
|
+ //w.Header().Set("Content-Disposition", "attachment; filename=\""+urlFile+"\"")
|
|
|
w.Write(file)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func compress(filePath string, buf *bytes.Buffer) error {
|
|
|
- gw := gzip.NewWriter(buf)
|
|
|
- defer gw.Close()
|
|
|
- tw := tar.NewWriter(gw)
|
|
|
- defer tw.Close()
|
|
|
-
|
|
|
- file, err := os.Open(filePath)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- defer file.Close()
|
|
|
- if stat, err := file.Stat(); err == nil {
|
|
|
- header := new(tar.Header)
|
|
|
- header.Name = path.Base(filePath)
|
|
|
- header.Size = stat.Size()
|
|
|
- header.Mode = int64(stat.Mode())
|
|
|
- header.ModTime = stat.ModTime()
|
|
|
- if err := tw.WriteHeader(header); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if _, err := io.Copy(tw, file); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
func serveIndex(w http.ResponseWriter, r *http.Request) {
|
|
|
page := Page{Title: "Index", Items: make([]Item, len(config.Directories))}
|
|
|
i := 0
|
|
|
@@ -252,5 +184,4 @@ func serveIndex(w http.ResponseWriter, r *http.Request) {
|
|
|
i++
|
|
|
}
|
|
|
tmpl.ExecuteTemplate(w, "index", &page)
|
|
|
-
|
|
|
}
|