http - 具有多个值的golang http解析 header

标签 http go

如何从具有多个逗号分隔值的 header 中获取值。例如,

url := "https://accounts.google.com/.well-known/openid-configuration"
resp, err := http.Get(url)
field := resp.Header.Get("Cache-Control") // "public, max-age=3600"

在这种情况下,我想要获取 max-age 值。我看到 2 个案例:

  • 使用 strings.Split()Trim() 等(我认为这不是个好主意)
  • bufio.ScannerSplitFunc 结合使用(稍微好一点)

有什么好主意或最佳做法吗?

编辑 1. 使用 strings.FieldsFunc()

const input = "   public,max-age=3000,   anothercase   "

sep := func(c rune) bool {
    return c == ',' || c == ' '
}
values := strings.FieldsFunc(input, sep)

关于基准

BenchmarkTrim-4  2000000  861 ns/op  48 B/op  1 allocs/op

编辑 2. 使用 Scaner()

那么让我们对其进行基准测试

func ScanHeaderValues(data []byte, atEOF bool) (advance int, token []byte, err error) {
    // Skip leading spaces.
    var start int
    for start = 0; start < len(data); start++ {
        if data[start] != ' ' {
            break
        }
    }
    // Scan until comma
    for i := start; i < len(data); i++ {
        if data[i] == ',' {
            return i + 1, data[start:i], nil
        }
    }
    // If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
    if atEOF && len(data) > start {
        return len(data), data[start:], nil
    }
    // Request more data.
    return start, nil, nil
}

func BenchmarkScanner(b *testing.B) {
    const input = "   public,max-age=3000,   anothercase   "
    scanner := bufio.NewScanner(strings.NewReader(input))
    split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
        advance, token, err = ScanHeaderValues(data, atEOF)
        return
    }
    scanner.Split(split)

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        for scanner.Scan() {
            // a := scanner.Text()
            // b.Logf("%+v\n", a)
        }
    }
}

结果:

BenchmarkTrim-4     2000000   861  ns/op  48 B/op  1 allocs/op
BenchmarkScanner-4  50000000  21.2 ns/op  0  B/op  0 allocs/op

如果您有任何其他更好的解决方案,我希望看到。

最佳答案

没有错:

url := "https://accounts.google.com/.well-known/openid-configuration"
resp, err := http.Get(url)
fields := strings.Split(resp.Header.Get("Cache-Control"), ",")
for i, field := range field {
    fields[i] = strings.Trim(field, " ")
}

编辑:如果逗号后的空格缺失,现在可以编辑

关于http - 具有多个值的golang http解析 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40488409/

相关文章:

objective-c - iOS - 向 CakePHP REST 发出 POST 请求

http - http非长连接模式有什么用

go - Go channel 似乎没有受到阻碍,尽管应该是

c++ - cURL 返回上次请求的数据

http - Redis 如何适应 ASP.NET Web API OData 世界?

python - 如何在 SSH 中发送 HTTP 请求?

css - 模板中的 Golang ttf 字体

linux - 在fsync中使用mmap是否安全? (fsync将使mmap上的某些页面无效吗?)

Golang 中的结构文字

Golang 一起调用方法的最有效方式