在golang中获取http响应的RAW标头

时间:2019-01-08 06:26:09

标签: http go response

如何以这样的字符串形式获取响应的原始报头:

alt-svc: quic=":443"; ma=2592000; v="44,43,39,35"
cache-control: private, max-age=0
content-encoding: br
content-type: text/html; charset=UTF-8
date: Tue, 08 Jan 2019 06:19:47 GMT
expires: -1
server: gws
set-cookie: 1P_JAR=2019-01-08-06; expires=Thu, 07-Feb-2019 06:19:47 GMT; path=/; domain=.google.com
set-cookie: SIDCC=ABtHo-HHNcja-cEEFEUXtBmLOdql4RTVMCWKGApEFFb8lWSAqaTF_fi0gDLoWaCzH3ogvEofah0; expires=Mon, 08-Apr-2019 06:19:47 GMT; path=/; domain=.google.com; priority=high
status: 200

因为我想从响应头中获取多个set-cookie值。 使用Http.Response.Header.Get("set-cookies")仅返回最后一行。

或者我如何获得多个Cookie?

4 个答案:

答案 0 :(得分:3)

如果要使用 raw 标头,则需要为net.Conn写一些包装,该包装器在http库对原始标头进行解释之前捕获原始标头。 / p>

但是您似乎实际上并不需要原始标头,甚至根本不需要完整的标头。如果您的目标只是读取多个Cookie,那么最简单的方法是在响应上使用Cookies方法。

这两者之间的中间选项是读取响应的整个Header字段。这将显示 full 标头,但不能保证其顺序,并且将进行最少的分析(以除去换行符等),因此不能说这是真正的“原始”。但是,如果标题重复,它会通过将所有标题值存储在[]string中来保留多个值。因此,出于这个问题的目的,这应该是完全足够的(尽管如上所述,Response.Cookies会更容易)。

答案 1 :(得分:1)

默认情况下,标准的http lib解析标头。
使用fasthttp(您将需要重新编写路由器和处理程序函数)将使您能够获取原始标头。

答案 2 :(得分:0)

在我看来,往返响应的最佳选择是 httputil#DumpResponse

package raw

import (
   "bufio"
   "bytes"
   "net/http"
   "net/http/httputil"
)

func encode(res *http.Response) ([]byte, error) {
   return httputil.DumpResponse(res, false)
}

func decode(data []byte) (*http.Response, error) {
   return http.ReadResponse(bufio.NewReader(bytes.NewReader(data)), nil)
}

或者,如果您只想要 cookie,您可以这样做:

package raw

import (
   "encoding/json"
   "net/http"
)

func encode(res *http.Response) ([]byte, error) {
   return json.Marshal(res.Cookies())
}

func decode(data []byte) ([]http.Cookie, error) {
   var c []http.Cookie
   if e := json.Unmarshal(data, &c); e != nil {
      return nil, e
   }
   return c, nil
}

或者对于单个 cookie:

package raw

import (
   "encoding/json"
   "net/http"
)

func encode(res *http.Response, name string) ([]byte, error) {
   for _, c := range res.Cookies() {
      if c.Name == name {
         return json.Marshal(c)
      }
   }
   return nil, http.ErrNoCookie
}

func decode(data []byte) (*http.Cookie, error) {
   c := new(http.Cookie)
   if e := json.Unmarshal(data, c); e != nil {
      return nil, e
   }
   return c, nil
}

https://golang.org/pkg/net/http/httputil#DumpResponse

答案 3 :(得分:-3)

使用fmt.Printf("%+v", resp.Header)

可以将所有标头写入如下所示的字符串:

map[Set-Cookie:[CASPRIVACY=""; Path=/ CASTGC=TGT-1248283-0BRja0uNQR9PntBl4HnrzKA44q5XDQXxA5FRVcnO9Xn6CkTU6S-passport; Path=/ CASLOGC=%7B%22myuniRole%22%3A0%2C%22username%22%3A%22a6051b9d08384f3ea2d203e744d3f7e6%22%2C%22mycuRole%22%3A0%2C%22userId%22%3A192676671%2C%22myinstRole%22%3A0%2C%22realName%22%3A%22%E9%9B%B7%E7%BA%A2%E6%A2%85%22%2C%22uuid%22%3A%22V4eoYpNB%22%2C%22headPic%22%3A%22http%3A%2F%2Fimage.xxx.com%2Fzhs%2Fapp%2Fcontent%2F201812%2Ff0b20d740df04d3196a20bc39f58ab56_s3.png%22%7D; Domain=.xxxx.com; Path=/ SERVERID=958b97eacbe3c49360ace2dfc0bd31b4|1546915535|1546915533;Path=/] Pragma:[no-cache] Expires:[Thu, 01 Jan 1970 00:00:00 GMT] Cache-Control:[no-cache no-store] Location:[http://online.xxx.com/onlineSchool/?ticket=ST-3285248-UiTbNt7bnUwXdtWSznIT-passport.xxxx.com] Date:[Tue, 08 Jan 2019 02:45:35 GMT] Content-Length:[0] Connection:[keep-alive]]

很难使用split和regx从字符串中获取所有cookie