go 建议:net/http:规范化逗号分隔的头部 该建议是关于规范化逗号分隔的头部,以便在处理HTTP请求时更加清晰和一致,

7ivaypg9  于 5个月前  发布在  Go
关注(0)|答案(2)|浏览(55)

考虑以下 example :

// normally the headers arrive from untrusted sources, this is just for exposition
	h := http.Header{}
	h.Add("Accept", "bar, baz")
	h.Add("Accept", "foo")

	// Intuitively this should print: []string{"bar", "baz", "foo"}
	// instead of:                    []string{"bar, baz", "foo"}
	fmt.Printf("%#v\n", h.Values("Accept"))

我不确定我们是否可以或想要修改 Values 的行为,但我认为我们仍然应该提供一种获取“规范化”值的方法 - 因为在任何情况下,如果有人真的收到了带有这些头部的请求,他们肯定会想要执行这种规范化。这尤其重要,因为不这样做(如当前函数“导致”的做法)可能导致头部混淆问题。
为了定义“规范化”,我想起了这样的事情:

for _, s := range h.Values(key) {
	for _, v := range strings.Split(s, ",") {
		values = append(values, strings.Trim(v, " \t"))
	}
}

据我所知,这符合 RFC 7230。
假设我们不想改变现有函数的行为,这可以作为(名称是一个伪名)暴露出来:

func (h Header) ValuesParsed(k string) (values []string) {
	for _, s := range h.Values(k) {
		for _, v := range strings.Split(s, ",") {
			values = append(values, strings.Trim(v, " \t"))
		}
	}
	return
}

(一个合适的实现可能会尽量减少开销,因此可能更接近这个 example )
作为一个旁注,有点遗憾的是 Values 已经被占用,因为 RFC 7230 使用 #(values) 的表示法明确地表示为逗号分隔的值列表(这在语义上等同于将这些值按顺序分布在具有相同名称的多个头部中)。
发送者必须在消息中不得生成具有相同字段名称的多个头部字段,除非该头部字段的所有字段值都被定义为逗号分隔的列表[即,#(values)],或者该头部字段是一个众所周知的例外(如下所述)。
收件人可以通过将具有相同字段名称的多个头部字段组合成一个“字段名:字段值”对来合并它们,而不改变消息的语义,方法是将每个后续字段值按顺序附加到组合字段值中,用逗号分隔。因此,接收到具有相同字段名称的头部字段的顺序对于解释组合字段值至关重要;代理在转发消息时绝对不能更改这些字段值的顺序。

相关问题