如何在Go中解析http标头

时间:2014-03-21 14:33:34

标签: http go

我在其他地方的日志中提供了http响应标头。在我的日志文件中,我有以下内容: -

Date: Fri, 21 Mar 2014 06:45:15 GMT\r\nContent-Encoding: gzip\r\nLast-Modified: Tue, 20 Aug 2013 15:45:41 GMT\r\nServer: nginx/0.8.54\r\nAge: 18884\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\nCache-Control: max-age=864000, public\r\nX-UA-Compatible: IE=Edge,chrome=1\r\nTiming-Allow-Origin: *\r\nContent-Length: 14888\r\nExpires: Mon, 31 Mar 2014 06:45:15 GMT\r\n

鉴于上面的字符串,如何将其解析为Header对象,如net / http中所述。一种方法是自己拆分字符串并映射键,值...但我希望避免手动执行并使用标准(或维护良好的第三方)库来解析它...任何指针?< / p>

1 个答案:

答案 0 :(得分:13)

内置解析器在textproto中。您可以直接使用它,也可以添加虚假的HTTP请求标头,并在http包中使用ReadRequest。无论哪种方式,您需要将数据包装到bufio.Reader中,这里我假设我们以字符串开头。

使用textproto:

logEntry := "Content-Encoding: gzip\r\nLast-Modified: Tue, 20 Aug 2013 15:45:41 GMT\r\nServer: nginx/0.8.54\r\nAge: 18884\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\nCache-Control: max-age=864000, public\r\nX-UA-Compatible: IE=Edge,chrome=1\r\nTiming-Allow-Origin: *\r\nContent-Length: 14888\r\nExpires: Mon, 31 Mar 2014 06:45:15 GMT\r\n"

// don't forget to make certain the headers end with a second "\r\n"
reader := bufio.NewReader(strings.NewReader(logEntry + "\r\n"))
tp := textproto.NewReader(reader)

mimeHeader, err := tp.ReadMIMEHeader()
if err != nil {
    log.Fatal(err)
}

// http.Header and textproto.MIMEHeader are both just a map[string][]string
httpHeader := http.Header(mimeHeader)
log.Println(httpHeader)

并使用http.ReadRequest:

logEntry := "Content-Encoding: gzip\r\nLast-Modified: Tue, 20 Aug 2013 15:45:41 GMT\r\nServer: nginx/0.8.54\r\nAge: 18884\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\nCache-Control: max-age=864000, public\r\nX-UA-Compatible: IE=Edge,chrome=1\r\nTiming-Allow-Origin: *\r\nContent-Length: 14888\r\nExpires: Mon, 31 Mar 2014 06:45:15 GMT\r\n"

// we need to make sure to add a fake HTTP header here to make a valid request.
reader := bufio.NewReader(strings.NewReader("GET / HTTP/1.1\r\n" + logEntry + "\r\n"))

logReq, err := http.ReadRequest(reader)
if err != nil {
    log.Fatal(err)
}

log.Println(logReq.Header)