Skip to content

Commit

Permalink
Add .zip download
Browse files Browse the repository at this point in the history
  • Loading branch information
sgreben committed Nov 13, 2018
1 parent 94f3f0b commit 500e089
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION = 1.0.0
VERSION = 1.1.0

APP := http-file-server
PACKAGES := $(shell go list -f {{.Dir}} ./...)
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ Or [download a binary](https://github.com/sgreben/http-file-server/releases/late

```sh
# Linux
curl -L https://github.com/sgreben/http-file-server/releases/download/1.0.0/http-file-server_1.0.0_linux_x86_64.tar.gz | tar xz
curl -L https://github.com/sgreben/http-file-server/releases/download/1.1.0/http-file-server_1.1.0_linux_x86_64.tar.gz | tar xz

# OS X
curl -L https://github.com/sgreben/http-file-server/releases/download/1.0.0/http-file-server_1.0.0_osx_x86_64.tar.gz | tar xz
curl -L https://github.com/sgreben/http-file-server/releases/download/1.1.0/http-file-server_1.1.0_osx_x86_64.tar.gz | tar xz

# Windows
curl -LO https://github.com/sgreben/http-file-server/releases/download/1.0.0/http-file-server_1.0.0_windows_x86_64.zip
unzip versions_1.0.0_windows_x86_64.zip
curl -LO https://github.com/sgreben/http-file-server/releases/download/1.1.0/http-file-server_1.1.0_windows_x86_64.zip
unzip versions_1.1.0_windows_x86_64.zip
```

## Use it
Expand Down
24 changes: 22 additions & 2 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const (
tarGzKey = "tar.gz"
tarGzValue = "true"
tarGzContentType = "application/x-tar+gzip"

zipKey = "zip"
zipValue = "true"
zipContentType = "application/zip"
)

type fileHandler struct {
Expand All @@ -35,13 +39,20 @@ func (f *fileHandler) serveStatus(w http.ResponseWriter, r *http.Request, status
w.Write([]byte(http.StatusText(status)))
}

func (f *fileHandler) serveZip(w http.ResponseWriter, r *http.Request, path string) {
func (f *fileHandler) serveTarGz(w http.ResponseWriter, r *http.Request, path string) {
w.Header().Set("Content-Type", tarGzContentType)
name := filepath.Base(path) + ".tar.gz"
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename=%q`, name))
tarGz(w, path)
}

func (f *fileHandler) serveZip(w http.ResponseWriter, r *http.Request, path string) {
w.Header().Set("Content-Type", zipContentType)
name := filepath.Base(path) + ".zip"
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename=%q`, name))
zip(w, path)
}

func (f *fileHandler) serveDir(w http.ResponseWriter, r *http.Request, dirPath string) {
d, err := os.Open(dirPath)
if err != nil {
Expand Down Expand Up @@ -77,6 +88,13 @@ func (f *fileHandler) serveDir(w http.ResponseWriter, r *http.Request, dirPath s
fmt.Fprintf(w, "<p>\n")
fmt.Fprintf(w, "<a href=\"%s\">Entire directory as .tar.gz</a>\n", url.String())
fmt.Fprintf(w, "</p>\n")
url.RawQuery = ""
q = url.Query()
q.Set(zipKey, zipValue)
url.RawQuery = q.Encode()
fmt.Fprintf(w, "<p>\n")
fmt.Fprintf(w, "<a href=\"%s\">Entire directory as .zip</a>\n", url.String())
fmt.Fprintf(w, "</p>\n")
}
}

Expand All @@ -98,8 +116,10 @@ func (f *fileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
f.serveStatus(w, r, http.StatusForbidden)
case err != nil:
f.serveStatus(w, r, http.StatusInternalServerError)
case r.URL.Query().Get(tarGzKey) != "":
case r.URL.Query().Get(zipKey) != "":
f.serveZip(w, r, path)
case r.URL.Query().Get(tarGzKey) != "":
f.serveTarGz(w, r, path)
case info.IsDir():
f.serveDir(w, r, path)
default:
Expand Down
44 changes: 44 additions & 0 deletions zip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

import (
zipper "archive/zip"
"io"
"log"
"os"
"path/filepath"
)

func zip(w io.Writer, path string) error {
basePath := path
addFile := func(w *zipper.Writer, path string, stat os.FileInfo) error {
if stat.IsDir() {
return nil
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
path, err = filepath.Rel(basePath, path)
zw, err := w.Create(path)
if err != nil {
return err
}
if _, err := io.Copy(zw, file); err != nil {
return err
}
return w.Flush()
}
wZip := zipper.NewWriter(w)
defer func() {
if err := wZip.Close(); err != nil {
log.Println(err)
}
}()
return filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
return addFile(wZip, path, info)
})
}

0 comments on commit 500e089

Please sign in to comment.