Skip to content

Commit 3db3573

Browse files
committed
feat: add --header option to specify custom header
1 parent db5b0a6 commit 3db3573

File tree

9 files changed

+83
-3
lines changed

9 files changed

+83
-3
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ server [options]
143143
Mount a file system path to URL path.
144144
e.g. ":/doc:/usr/share/doc"
145145
146+
--header <name>:<value> ...
147+
Set custom HTTP response header.
148+
146149
-U|--global-upload
147150
Allow upload files for all url paths.
148151
Use it with care.

README.zh-CN.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ server [选项]
142142
将某个文件系统路径挂载到URL路径下。
143143
例如:“:/doc:/usr/share/doc”。
144144
145+
--header <名称>:<值> ...
146+
设置自定义HTTP响应头。
147+
145148
-U|--global-upload
146149
对所有URL路径开启上传权限。
147150
请谨慎使用。

src/param/cli.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ func init() {
3939
err = options.AddFlagsValues("aliases", []string{"-a", "--alias"}, "", nil, "set alias path, <sep><url><sep><path>, e.g. :/doc:/usr/share/doc")
4040
serverErrHandler.CheckFatal(err)
4141

42+
err = options.AddFlagValues("globalheaders", "--header", "GHFS_HEADER", []string{}, "custom headers, e.g. <key>:<value>")
43+
serverErrHandler.CheckFatal(err)
44+
4245
err = options.AddFlags("globalupload", []string{"-U", "--global-upload"}, "", "allow upload files for all url paths")
4346
serverErrHandler.CheckFatal(err)
4447

@@ -252,6 +255,10 @@ func doParseCli() []*Param {
252255
dirIndexes, _ := result.GetStrings("dirindexes")
253256
param.DirIndexes = normalizeFilenames(dirIndexes)
254257

258+
// headers
259+
globalHeaders, _ := result.GetStrings("globalheaders")
260+
param.GlobalHeaders = entriesToHeaders(globalHeaders)
261+
255262
// certificate
256263
key, _ := result.GetString("key")
257264
cert, _ := result.GetString("cert")

src/param/main.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ type Param struct {
1414
Root string
1515
EmptyRoot bool
1616

17-
DefaultSort string
18-
DirIndexes []string
19-
Aliases map[string]string
17+
DefaultSort string
18+
DirIndexes []string
19+
Aliases map[string]string
20+
GlobalHeaders [][2]string
2021

2122
GlobalUpload bool
2223
UploadUrls []string

src/param/objUtil.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ func EntriesToUsers(entries []string) []*user {
2929
return users
3030
}
3131

32+
func entriesToHeaders(entries []string) [][2]string {
33+
headers := make([][2]string, 0, len(entries))
34+
for _, entry := range entries {
35+
colonIndex := strings.IndexByte(entry, ':')
36+
if colonIndex <= 0 || colonIndex == len(entry)-1 {
37+
continue
38+
}
39+
key := entry[:colonIndex]
40+
value := entry[colonIndex+1:]
41+
headers = append(headers, [2]string{key, value})
42+
}
43+
return headers
44+
}
45+
3246
func WildcardToRegexp(wildcards []string, found bool) (*regexp.Regexp, error) {
3347
if !found || len(wildcards) == 0 {
3448
return nil, nil

src/param/objUtil_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,22 @@ func TestEntriesToUsers(t *testing.T) {
3131
t.Fail()
3232
}
3333
}
34+
35+
func TestEntriesToHeaders(t *testing.T) {
36+
entries := []string{
37+
"",
38+
"key1:",
39+
":value2",
40+
"key3:value3",
41+
}
42+
headers := entriesToHeaders(entries)
43+
if len(headers) != 1 {
44+
t.Fatal("headers count should be 1", headers)
45+
}
46+
if headers[0][0] != "key3" {
47+
t.Error("key should be \"key3\"")
48+
}
49+
if headers[0][1] != "value3" {
50+
t.Error("value should be \"value3\"")
51+
}
52+
}

src/serverHandler/header.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package serverHandler
2+
3+
import "net/http"
4+
5+
func (h *handler) header(w http.ResponseWriter) {
6+
if len(h.globalHeaders) == 0 {
7+
return
8+
}
9+
header := w.Header()
10+
for _, headerPair := range h.globalHeaders {
11+
header.Set(headerPair[0], headerPair[1])
12+
}
13+
}

src/serverHandler/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type handler struct {
2020
dirIndexes []string
2121
aliases aliases
2222

23+
globalHeaders [][2]string
24+
2325
globalUpload bool
2426
uploadUrls []string
2527
uploadDirs []string
@@ -86,6 +88,8 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
8688
return
8789
}
8890

91+
h.header(w)
92+
8993
if data.CanCors {
9094
h.cors(w, r)
9195
}
@@ -151,6 +155,8 @@ func NewHandler(
151155
dirIndexes: p.DirIndexes,
152156
aliases: aliases,
153157

158+
globalHeaders: p.GlobalHeaders,
159+
154160
globalUpload: p.GlobalUpload,
155161
uploadUrls: p.UploadUrls,
156162
uploadDirs: p.UploadDirs,

test/case/023.custom.header.bash

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
source "$root"/lib.bash
4+
5+
"$ghfs" -l 3003 -r "$fs"/vhost1 --header foo:bar &
6+
sleep 0.05 # wait server ready
7+
8+
(curl_get_header http://127.0.0.1:3003/ | grep -q -i 'foo:\s*bar') ||
9+
fail "Custom header not exists"
10+
11+
(curl_get_header http://127.0.0.1:3003/file1.txt | grep -q -i 'foo:\s*bar') ||
12+
fail "Custom header not exists"
13+
14+
kill %1

0 commit comments

Comments
 (0)