英文:
How to parse http headers in 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
给定上述字符串,我如何将其解析为net/http中描述的Header对象?一种方法是手动拆分字符串并映射键和值...但我希望避免手动操作,并使用标准的(或者是维护良好的第三方)库来解析它...有什么建议吗?
英文:
I have http response headers shipped in logs from elsewhere. In my log file I have things like :-
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
Given the above as string, how go I parse it into Header object as described in net/http . One way would be to split the string myself and map the key, values... But I am looking to avoid doing that by hand and use the standard (or well maintained 3rd party) library to parse it... Any pointers?
答案1
得分: 25
内置的解析器是以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"
// 别忘了确保头部以第二个"\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和textproto.MIMEHeader都只是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"
// 我们需要确保在这里添加一个伪造的HTTP头部以构造一个有效的请求。
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)
https://golang.org/pkg/net/textproto
英文:
The builtin parser is in textproto. You can either use this directly, or add a
fake HTTP request header and use ReadRequest in the http package. Either way
you need to wrap your data into a bufio.Reader, here I'm just assuming we're
starting with a string.
With 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)
and with 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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论