Skip to content

Commit 1f6b334

Browse files
committed
feat(API): accept JSON request by header Accept: application/json
BREAKING CHANGE Before: ```sh curl 'http://server/path?json' ``` After: ```sh curl -H 'Accept: application/json' 'http://server/path' ```
1 parent b850c4f commit 1f6b334

File tree

6 files changed

+77
-56
lines changed

6 files changed

+77
-56
lines changed

doc/en-US/api.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ curl 'http://localhost/ghfs/?sort=/T'
2828

2929
# Get JSON data of specified path
3030
```
31-
GET <path>?json[&sort=key]
31+
GET <path>[?sort=key]
32+
Accept: application/json
3233
```
3334

3435
Example:
3536
```sh
36-
curl 'http://localhost/ghfs/?json'
37+
curl -H 'Accept: application/json' 'http://localhost/ghfs/'
3738
```
3839

3940
# Render page for downloading
@@ -103,7 +104,8 @@ curl -X POST -d 'name=subdir1&name=subdir2/subdir21&name=file1&name=subdir3/file
103104
# Create directories in specific path
104105
Only work when "mkdir" is enabled.
105106
```
106-
POST <path>?mkdir[&json]
107+
POST <path>?mkdir
108+
[Accept: application/json]
107109
108110
name=<dir1path>&name=<dir2path>&...name=<dirNpath>
109111
```
@@ -116,7 +118,8 @@ curl -X POST -d 'name=dir1&name=dir2&name=foo/bar/baz' 'http://localhost/tmp/?mk
116118
# Upload files to specific path
117119
Only work when "upload" is enabled.
118120
```
119-
POST <path>?upload[&json]
121+
POST <path>?upload
122+
[Accept: application/json]
120123
```
121124
- Must use `POST` method
122125
- Must use `multipart/form-data` encoding type
@@ -145,7 +148,8 @@ curl -F 'innerdirfile=@file1.txt;filename=subdir/childdir/filename.txt' 'http://
145148
Only work when "delete" is enabled.
146149
Directories will be deleted recursively.
147150
```
148-
POST <path>?delete[&json]
151+
POST <path>?delete
152+
[Accept: application/json]
149153
150154
name=<dir1>&name=<dir2>&...name=<dirN>
151155
```

doc/zh-CN/api.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ curl 'http://localhost/ghfs/?sort=/T'
2828

2929
# 获取指定路径JSON形式的数据
3030
```
31-
GET <path>?json[&sort=key]
31+
GET <path>[?sort=key]
32+
Accept: application/json
3233
```
3334

3435
举例:
3536
```sh
36-
curl 'http://localhost/ghfs/?json'
37+
curl -H 'Accept: application/json' 'http://localhost/ghfs/'
3738
```
3839

3940
# 显示用于下载的页面
@@ -100,7 +101,8 @@ curl -X POST -d 'name=subdir1&name=subdir2/subdir21&name=file1&name=subdir3/file
100101
# 在指定路径下创建目录
101102
仅在“mkdir”选项启用时有效。
102103
```
103-
POST <path>?mkdir[&json]
104+
POST <path>?mkdir
105+
[Accept: application/json]
104106
105107
name=<dir1path>&name=<dir2path>&...name=<dirNpath>
106108
```
@@ -113,7 +115,8 @@ curl -X POST -d 'name=dir1&name=dir2&name=foo/bar/baz' 'http://localhost/tmp/?mk
113115
# 上传文件到指定路径
114116
仅在“upload”选项启用时有效。
115117
```
116-
POST <path>?upload[&json]
118+
POST <path>?upload
119+
[Accept: application/json]
117120
```
118121
- 必须使用`POST`方法
119122
- 必须使用`multipart/form-data`编码
@@ -142,7 +145,8 @@ curl -F 'innerdirfile=@file1.txt;filename=subdir/childdir/filename.txt' 'http://
142145
仅在“delete”选项启用时有效。
143146
目录将被递归删除。
144147
```
145-
POST <path>?delete[&json]
148+
POST <path>?delete
149+
[Accept: application/json]
146150
147151
name=<dir1>&name=<dir2>&...name=<dirN>
148152
```

src/serverHandler/sessionData.go

+21-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package serverHandler
22

33
import (
44
"html/template"
5+
"mjpclab.dev/ghfs/src/acceptHeaders"
56
"mjpclab.dev/ghfs/src/i18n"
67
"mjpclab.dev/ghfs/src/util"
78
"net/http"
@@ -11,6 +12,21 @@ import (
1112
"strings"
1213
)
1314

15+
const (
16+
noRedirect redirectAction = iota
17+
addSlashSuffix
18+
removeSlashSuffix
19+
)
20+
21+
const contentTypeJson = "application/json"
22+
23+
var acceptContentTypes = []string{
24+
contentTypeJson,
25+
"text/html",
26+
"application/xhtml+xml",
27+
"application/xml",
28+
}
29+
1430
type pathEntry struct {
1531
Name string `json:"name"`
1632
Path string `json:"path"`
@@ -27,12 +43,6 @@ type itemHtml struct {
2743

2844
type redirectAction int
2945

30-
const (
31-
noRedirect redirectAction = iota
32-
addSlashSuffix
33-
removeSlashSuffix
34-
)
35-
3646
type sessionContext struct {
3747
prefixReqPath string
3848
vhostReqPath string
@@ -368,7 +378,10 @@ func (h *aliasHandler) getSessionData(r *http.Request) (session *sessionContext,
368378
isDelete = true
369379
isMutate = true
370380
}
371-
wantJson := strings.HasPrefix(rawQuery, "json") || strings.Contains(rawQuery, "&json")
381+
382+
accepts := acceptHeaders.ParseAccepts(r.Header.Get("Accept"))
383+
_, preferredContentType, _ := accepts.GetPreferredValue(acceptContentTypes)
384+
wantJson := preferredContentType == contentTypeJson
372385

373386
isRoot := vhostReqPath == "/"
374387

@@ -410,7 +423,7 @@ func (h *aliasHandler) getSessionData(r *http.Request) (session *sessionContext,
410423
}
411424

412425
restrictAccess, allowAccess := h.isAllowAccess(r, vhostReqPath, fsPath, file, item)
413-
vary := "accept-encoding"
426+
vary := "accept, accept-encoding"
414427
if restrictAccess {
415428
vary += ", referer, origin"
416429
}

test/case/042.index.bash

+10-10
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,40 @@ sleep 0.05 # wait server ready
77

88
# --index
99

10-
cnt=$(curl_get_body 'http://127.0.0.1:3003/?json' | jq '.subItems | length')
10+
cnt=$(curl_get_body -H 'accept: application/json' 'http://127.0.0.1:3003/' | jq '.subItems | length')
1111
assert "$cnt" '0'
1212

13-
cnt=$(curl_get_body 'http://127.0.0.1:3003/go/?json' | jq '.subItems | length')
13+
cnt=$(curl_get_body -H 'accept: application/json' 'http://127.0.0.1:3003/go/' | jq '.subItems | length')
1414
assert "$cnt" '0'
1515

16-
cnt=$(curl_get_body 'http://127.0.0.1:3003/hello/?json' | jq '.subItems | length')
16+
cnt=$(curl_get_body -H 'accept: application/json' 'http://127.0.0.1:3003/hello/' | jq '.subItems | length')
1717
[ "$cnt" == "0" ] && fail "subItems should not be 0"
1818

1919
# --index-dir
2020

21-
cnt=$(curl_get_body 'http://127.0.0.1:3003/world/?json' | jq '.subItems | length')
21+
cnt=$(curl_get_body -H 'accept: application/json' 'http://127.0.0.1:3003/world/' | jq '.subItems | length')
2222
[ "$cnt" == "0" ] && fail "subItems should not be 0"
2323

2424
# --index-user
2525

26-
cnt=$(curl_get_body 'http://127.0.0.1:3003/x/y/z/a/?json' | jq '.subItems | length')
26+
cnt=$(curl_get_body -H 'accept: application/json' 'http://127.0.0.1:3003/x/y/z/a/' | jq '.subItems | length')
2727
assert "$cnt" '0'
2828

29-
cnt=$(curl_get_body 'http://baz:789@127.0.0.1:3003/x/y/z/a/?json' | jq '.subItems | length')
29+
cnt=$(curl_get_body -H 'accept: application/json' 'http://baz:789@127.0.0.1:3003/x/y/z/a/' | jq '.subItems | length')
3030
assert "$cnt" '0'
3131

32-
cnt=$(curl_get_body 'http://foo:123@127.0.0.1:3003/x/y/z/a/?json' | jq '.subItems | length')
32+
cnt=$(curl_get_body -H 'accept: application/json' 'http://foo:123@127.0.0.1:3003/x/y/z/a/' | jq '.subItems | length')
3333
[ "$cnt" == "0" ] && fail "subItems should not be 0"
3434

3535
# --index-dir-user
3636

37-
cnt=$(curl_get_body 'http://127.0.0.1:3003/x/y/z/b/?json' | jq '.subItems | length')
37+
cnt=$(curl_get_body -H 'accept: application/json' 'http://127.0.0.1:3003/x/y/z/b/' | jq '.subItems | length')
3838
assert "$cnt" '0'
3939

40-
cnt=$(curl_get_body 'http://baz:789@127.0.0.1:3003/x/y/z/b/?json' | jq '.subItems | length')
40+
cnt=$(curl_get_body -H 'accept: application/json' 'http://baz:789@127.0.0.1:3003/x/y/z/b/' | jq '.subItems | length')
4141
assert "$cnt" '0'
4242

43-
cnt=$(curl_get_body 'http://bar:456@127.0.0.1:3003/x/y/z/b/?json' | jq '.subItems | length')
43+
cnt=$(curl_get_body -H 'accept: application/json' 'http://bar:456@127.0.0.1:3003/x/y/z/b/' | jq '.subItems | length')
4444
[ "$cnt" == "0" ] && fail "subItems should not be 0"
4545

4646
jobs -p | xargs kill &> /dev/null

test/lib.bash

+27-27
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,62 @@
11
#!/bin/bash
22

33
assert() {
4-
expect="$2"
5-
actual="$1"
4+
local expect="$2"
5+
local actual="$1"
66
if [ "$expect" != "$actual" ]; then
77
echo -e "$(basename $0):${BASH_LINENO[0]} expect \"\e[0;32m$expect\e[0m\", got \"\e[1;31m$actual\e[0m\"" >&2
88
fi
99
}
1010

1111
fail() {
12-
msg="$1"
12+
local msg="$1"
1313
echo -e "$(basename $0):${BASH_LINENO[0]} \e[1;31m$msg\e[0m" >&2
1414
}
1515

1616
curl_head_status() {
17-
args=($@)
18-
urlindex=$[ ${#args[@]} - 1 ]
19-
opts="${args[@]:0:urlindex}"
20-
url="${args[urlindex]}"
17+
local args=("$@")
18+
local urlindex=$[ ${#args[@]} - 1 ]
19+
local opts=("${args[@]:0:urlindex}")
20+
local url="${args[urlindex]}"
2121

22-
curl -s -k -I $opts "$url" | head -n 1 | cut -d ' ' -f 2
22+
curl -s -k -I "${opts[@]}" "$url" | head -n 1 | cut -d ' ' -f 2
2323
}
2424

2525
curl_get_status() {
26-
args=($@)
27-
urlindex=$[ ${#args[@]} - 1 ]
28-
opts="${args[@]:0:urlindex}"
29-
url="${args[urlindex]}"
26+
local args=("$@")
27+
local urlindex=$[ ${#args[@]} - 1 ]
28+
local opts=("${args[@]:0:urlindex}")
29+
local url="${args[urlindex]}"
3030

31-
curl -s -k -i $opts "$url" | head -n 1 | cut -d ' ' -f 2
31+
curl -s -k -i "${opts[@]}" "$url" | head -n 1 | cut -d ' ' -f 2
3232
}
3333

3434
curl_get_header() {
35-
args=($@)
36-
urlindex=$[ ${#args[@]} - 1 ]
37-
opts="${args[@]:0:urlindex}"
38-
url="${args[urlindex]}"
35+
local args=("$@")
36+
local urlindex=$[ ${#args[@]} - 1 ]
37+
local opts=("${args[@]:0:urlindex}")
38+
local url="${args[urlindex]}"
3939

40-
curl -s -k -i $opts "$url" | sed -e '/^$/q'
40+
curl -s -k -i "${opts[@]}" "$url" | sed -e '/^$/q'
4141
}
4242

4343
curl_get_body() {
44-
args=($@)
45-
urlindex=$[ ${#args[@]} - 1 ]
46-
opts="${args[@]:0:urlindex}"
47-
url="${args[urlindex]}"
44+
local args=("$@")
45+
local urlindex=$[ ${#args[@]} - 1 ]
46+
local opts=("${args[@]:0:urlindex}")
47+
local url="${args[urlindex]}"
4848

49-
curl -s -k $opts "$url"
49+
curl -s -k "${opts[@]}" "$url"
5050
}
5151

5252
curl_post_status() {
5353
curl_get_status -X POST "$@"
5454
}
5555

5656
curl_upload_content() {
57-
url="$1"
58-
name="$2"
59-
value="$3"
60-
filename="$4"
57+
local url="$1"
58+
local name="$2"
59+
local value="$3"
60+
local filename="$4"
6161
curl -s -k -F "$name=$value;filename=$filename" "$url"
6262
}

test/main.bash

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
cd $(dirname $0)
44

5-
for cmd in realpath curl grep sed xargs; do
5+
for cmd in realpath curl grep sed xargs jq; do
66
type "$cmd" &> /dev/null
77
if [ $? -ne 0 ]; then
88
echo "command '$cmd' not found" >&2

0 commit comments

Comments
 (0)