This repository has been archived by the owner on Dec 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrfc6266.go
63 lines (60 loc) · 1.96 KB
/
rfc6266.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package httpheader
import (
"net/http"
"strings"
)
// ContentDisposition parses the Content-Disposition header from h (RFC 6266),
// returning the disposition type, the value of the 'filename' parameter (if any),
// and a map of any other parameters.
//
// Any 'filename*' parameter is decoded from RFC 8187 encoding, and overrides
// 'filename'. Similarly for any other parameter whose name ends in an asterisk.
// UTF-8 is not validated in such strings.
func ContentDisposition(h http.Header) (dtype, filename string, params map[string]string) {
v := h.Get("Content-Disposition")
dtype, v = consumeItem(v)
dtype = strings.ToLower(dtype)
ParamsLoop:
for {
var name, value string
name, value, v = consumeParam(v)
switch name {
case "":
break ParamsLoop
case "filename":
if filename == "" { // not set from 'filename*' yet
filename = value
}
case "filename*":
if decoded, _, err := DecodeExtValue(value); err == nil {
filename = decoded
}
default:
params = insertVariform(params, name, value)
}
}
return
}
// SetContentDisposition replaces the Content-Disposition header in h (RFC 6266).
//
// If filename is not empty, it must be valid UTF-8, which is serialized into
// a 'filename' parameter in plain ASCII, or a 'filename*' parameter in RFC 8187
// encoding, or both, depending on what characters it contains.
//
// Similarly, if params contains a 'qux' or 'qux*' key, it will be serialized into
// a 'qux' and/or 'qux*' parameter depending on its contents; the asterisk
// in the key is ignored. Any 'filename' or 'filename*' in params is skipped.
func SetContentDisposition(h http.Header, dtype, filename string, params map[string]string) {
b := &strings.Builder{}
write(b, dtype)
if filename != "" {
writeVariform(b, "filename", filename)
}
for name, value := range params {
if strings.ToLower(strings.TrimSuffix(name, "*")) == "filename" {
continue
}
writeVariform(b, name, value)
}
h.Set("Content-Disposition", b.String())
}