douchuifk90315 2016-11-08 13:39
浏览 142

带有多个值的golang http解析头

How can I obtain value from header that have multiple comma separated values. For instance,

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

In this case I want get max-age value. I see 2 cases:

  • using strings.Split(), Trim() and etc (I think it's not good idea)
  • using bufio.Scanner with SplitFunc (little bit better)

Any good idea or best practice?

Edit 1. Using strings.FieldsFunc()

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

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

Regarding benchmarks

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

Edit 2. Using Scaner()

So lets benchmark it

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
", a)
        }
    }
}

And result:

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

If you have any other better solution I would like see it.

  • 写回答

1条回答 默认 最新

  • duanqi6007 2016-11-08 14:36
    关注

    Nothing wrong with:

    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, " ")
    }
    

    Edit: Edit now works if space after comma is missing

    评论

报告相同问题?

悬赏问题

  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图