Skip to content

Commit 500e089

Browse files
committed
Add .zip download
1 parent 94f3f0b commit 500e089

File tree

4 files changed

+71
-7
lines changed

4 files changed

+71
-7
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION = 1.0.0
1+
VERSION = 1.1.0
22

33
APP := http-file-server
44
PACKAGES := $(shell go list -f {{.Dir}} ./...)

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ Or [download a binary](https://github.com/sgreben/http-file-server/releases/late
5757

5858
```sh
5959
# Linux
60-
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
60+
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
6161

6262
# OS X
63-
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
63+
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
6464

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

7070
## Use it

server.go

+22-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ const (
1515
tarGzKey = "tar.gz"
1616
tarGzValue = "true"
1717
tarGzContentType = "application/x-tar+gzip"
18+
19+
zipKey = "zip"
20+
zipValue = "true"
21+
zipContentType = "application/zip"
1822
)
1923

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

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

49+
func (f *fileHandler) serveZip(w http.ResponseWriter, r *http.Request, path string) {
50+
w.Header().Set("Content-Type", zipContentType)
51+
name := filepath.Base(path) + ".zip"
52+
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename=%q`, name))
53+
zip(w, path)
54+
}
55+
4556
func (f *fileHandler) serveDir(w http.ResponseWriter, r *http.Request, dirPath string) {
4657
d, err := os.Open(dirPath)
4758
if err != nil {
@@ -77,6 +88,13 @@ func (f *fileHandler) serveDir(w http.ResponseWriter, r *http.Request, dirPath s
7788
fmt.Fprintf(w, "<p>\n")
7889
fmt.Fprintf(w, "<a href=\"%s\">Entire directory as .tar.gz</a>\n", url.String())
7990
fmt.Fprintf(w, "</p>\n")
91+
url.RawQuery = ""
92+
q = url.Query()
93+
q.Set(zipKey, zipValue)
94+
url.RawQuery = q.Encode()
95+
fmt.Fprintf(w, "<p>\n")
96+
fmt.Fprintf(w, "<a href=\"%s\">Entire directory as .zip</a>\n", url.String())
97+
fmt.Fprintf(w, "</p>\n")
8098
}
8199
}
82100

@@ -98,8 +116,10 @@ func (f *fileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
98116
f.serveStatus(w, r, http.StatusForbidden)
99117
case err != nil:
100118
f.serveStatus(w, r, http.StatusInternalServerError)
101-
case r.URL.Query().Get(tarGzKey) != "":
119+
case r.URL.Query().Get(zipKey) != "":
102120
f.serveZip(w, r, path)
121+
case r.URL.Query().Get(tarGzKey) != "":
122+
f.serveTarGz(w, r, path)
103123
case info.IsDir():
104124
f.serveDir(w, r, path)
105125
default:

zip.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package main
2+
3+
import (
4+
zipper "archive/zip"
5+
"io"
6+
"log"
7+
"os"
8+
"path/filepath"
9+
)
10+
11+
func zip(w io.Writer, path string) error {
12+
basePath := path
13+
addFile := func(w *zipper.Writer, path string, stat os.FileInfo) error {
14+
if stat.IsDir() {
15+
return nil
16+
}
17+
file, err := os.Open(path)
18+
if err != nil {
19+
return err
20+
}
21+
defer file.Close()
22+
path, err = filepath.Rel(basePath, path)
23+
zw, err := w.Create(path)
24+
if err != nil {
25+
return err
26+
}
27+
if _, err := io.Copy(zw, file); err != nil {
28+
return err
29+
}
30+
return w.Flush()
31+
}
32+
wZip := zipper.NewWriter(w)
33+
defer func() {
34+
if err := wZip.Close(); err != nil {
35+
log.Println(err)
36+
}
37+
}()
38+
return filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
39+
if err != nil {
40+
return err
41+
}
42+
return addFile(wZip, path, info)
43+
})
44+
}

0 commit comments

Comments
 (0)