response.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // HTTP Response reading and parsing.
  5. package http
  6. import (
  7. "bufio"
  8. "bytes"
  9. "crypto/tls"
  10. "errors"
  11. "fmt"
  12. "io"
  13. "net/textproto"
  14. "net/url"
  15. "strconv"
  16. "strings"
  17. "golang.org/x/net/http/httpguts"
  18. )
  19. var respExcludeHeader = map[string]bool{
  20. "Content-Length": true,
  21. "Transfer-Encoding": true,
  22. "Trailer": true,
  23. }
  24. // Response represents the response from an HTTP request.
  25. //
  26. // The Client and Transport return Responses from servers once
  27. // the response headers have been received. The response body
  28. // is streamed on demand as the Body field is read.
  29. type Response struct {
  30. Status string // e.g. "200 OK"
  31. StatusCode int // e.g. 200
  32. Proto string // e.g. "HTTP/1.0"
  33. ProtoMajor int // e.g. 1
  34. ProtoMinor int // e.g. 0
  35. // Header maps header keys to values. If the response had multiple
  36. // headers with the same key, they may be concatenated, with comma
  37. // delimiters. (RFC 7230, section 3.2.2 requires that multiple headers
  38. // be semantically equivalent to a comma-delimited sequence.) When
  39. // Header values are duplicated by other fields in this struct (e.g.,
  40. // ContentLength, TransferEncoding, Trailer), the field values are
  41. // authoritative.
  42. //
  43. // Keys in the map are canonicalized (see CanonicalHeaderKey).
  44. Header Header
  45. // Body represents the response body.
  46. //
  47. // The response body is streamed on demand as the Body field
  48. // is read. If the network connection fails or the server
  49. // terminates the response, Body.Read calls return an error.
  50. //
  51. // The http Client and Transport guarantee that Body is always
  52. // non-nil, even on responses without a body or responses with
  53. // a zero-length body. It is the caller's responsibility to
  54. // close Body. The default HTTP client's Transport may not
  55. // reuse HTTP/1.x "keep-alive" TCP connections if the Body is
  56. // not read to completion and closed.
  57. //
  58. // The Body is automatically dechunked if the server replied
  59. // with a "chunked" Transfer-Encoding.
  60. //
  61. // As of Go 1.12, the Body will also implement io.Writer
  62. // on a successful "101 Switching Protocols" response,
  63. // as used by WebSockets and HTTP/2's "h2c" mode.
  64. Body io.ReadCloser
  65. // ContentLength records the length of the associated content. The
  66. // value -1 indicates that the length is unknown. Unless Request.Method
  67. // is "HEAD", values >= 0 indicate that the given number of bytes may
  68. // be read from Body.
  69. ContentLength int64
  70. // Contains transfer encodings from outer-most to inner-most. Value is
  71. // nil, means that "identity" encoding is used.
  72. TransferEncoding []string
  73. // Close records whether the header directed that the connection be
  74. // closed after reading Body. The value is advice for clients: neither
  75. // ReadResponse nor Response.Write ever closes a connection.
  76. Close bool
  77. // Uncompressed reports whether the response was sent compressed but
  78. // was decompressed by the http package. When true, reading from
  79. // Body yields the uncompressed content instead of the compressed
  80. // content actually set from the server, ContentLength is set to -1,
  81. // and the "Content-Length" and "Content-Encoding" fields are deleted
  82. // from the responseHeader. To get the original response from
  83. // the server, set Transport.DisableCompression to true.
  84. Uncompressed bool
  85. // Trailer maps trailer keys to values in the same
  86. // format as Header.
  87. //
  88. // The Trailer initially contains only nil values, one for
  89. // each key specified in the server's "Trailer" header
  90. // value. Those values are not added to Header.
  91. //
  92. // Trailer must not be accessed concurrently with Read calls
  93. // on the Body.
  94. //
  95. // After Body.Read has returned io.EOF, Trailer will contain
  96. // any trailer values sent by the server.
  97. Trailer Header
  98. // Request is the request that was sent to obtain this Response.
  99. // Request's Body is nil (having already been consumed).
  100. // This is only populated for Client requests.
  101. Request *Request
  102. // TLS contains information about the TLS connection on which the
  103. // response was received. It is nil for unencrypted responses.
  104. // The pointer is shared between responses and should not be
  105. // modified.
  106. TLS *tls.ConnectionState
  107. }
  108. // Cookies parses and returns the cookies set in the Set-Cookie headers.
  109. func (r *Response) Cookies() []*Cookie {
  110. return readSetCookies(r.Header)
  111. }
  112. // ErrNoLocation is returned by Response's Location method
  113. // when no Location header is present.
  114. var ErrNoLocation = errors.New("http: no Location header in response")
  115. // Location returns the URL of the response's "Location" header,
  116. // if present. Relative redirects are resolved relative to
  117. // the Response's Request. ErrNoLocation is returned if no
  118. // Location header is present.
  119. func (r *Response) Location() (*url.URL, error) {
  120. lv := r.Header.Get("Location")
  121. if lv == "" {
  122. return nil, ErrNoLocation
  123. }
  124. if r.Request != nil && r.Request.URL != nil {
  125. return r.Request.URL.Parse(lv)
  126. }
  127. return url.Parse(lv)
  128. }
  129. // ReadResponse reads and returns an HTTP response from r.
  130. // The req parameter optionally specifies the Request that corresponds
  131. // to this Response. If nil, a GET request is assumed.
  132. // Clients must call resp.Body.Close when finished reading resp.Body.
  133. // After that call, clients can inspect resp.Trailer to find key/value
  134. // pairs included in the response trailer.
  135. func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) {
  136. tp := textproto.NewReader(r)
  137. resp := &Response{
  138. Request: req,
  139. }
  140. // Parse the first line of the response.
  141. line, err := tp.ReadLine()
  142. if err != nil {
  143. if err == io.EOF {
  144. err = io.ErrUnexpectedEOF
  145. }
  146. return nil, err
  147. }
  148. proto, status, ok := strings.Cut(line, " ")
  149. if !ok {
  150. return nil, badStringError("malformed HTTP response", line)
  151. }
  152. resp.Proto = proto
  153. resp.Status = strings.TrimLeft(status, " ")
  154. statusCode, _, _ := strings.Cut(resp.Status, " ")
  155. if len(statusCode) != 3 {
  156. return nil, badStringError("malformed HTTP status code", statusCode)
  157. }
  158. resp.StatusCode, err = strconv.Atoi(statusCode)
  159. if err != nil || resp.StatusCode < 0 {
  160. return nil, badStringError("malformed HTTP status code", statusCode)
  161. }
  162. if resp.ProtoMajor, resp.ProtoMinor, ok = ParseHTTPVersion(resp.Proto); !ok {
  163. return nil, badStringError("malformed HTTP version", resp.Proto)
  164. }
  165. // Parse the response headers.
  166. mimeHeader, err := tp.ReadMIMEHeader()
  167. if err != nil {
  168. if err == io.EOF {
  169. err = io.ErrUnexpectedEOF
  170. }
  171. return nil, err
  172. }
  173. resp.Header = Header(mimeHeader)
  174. fixPragmaCacheControl(resp.Header)
  175. err = readTransfer(resp, r)
  176. if err != nil {
  177. return nil, err
  178. }
  179. return resp, nil
  180. }
  181. // RFC 7234, section 5.4: Should treat
  182. // Pragma: no-cache
  183. // like
  184. // Cache-Control: no-cache
  185. func fixPragmaCacheControl(header Header) {
  186. if hp, ok := header["Pragma"]; ok && len(hp) > 0 && hp[0] == "no-cache" {
  187. if _, presentcc := header["Cache-Control"]; !presentcc {
  188. header["Cache-Control"] = []string{"no-cache"}
  189. }
  190. }
  191. }
  192. // ProtoAtLeast reports whether the HTTP protocol used
  193. // in the response is at least major.minor.
  194. func (r *Response) ProtoAtLeast(major, minor int) bool {
  195. return r.ProtoMajor > major ||
  196. r.ProtoMajor == major && r.ProtoMinor >= minor
  197. }
  198. // Write writes r to w in the HTTP/1.x server response format,
  199. // including the status line, headers, body, and optional trailer.
  200. //
  201. // This method consults the following fields of the response r:
  202. //
  203. // StatusCode
  204. // ProtoMajor
  205. // ProtoMinor
  206. // Request.Method
  207. // TransferEncoding
  208. // Trailer
  209. // Body
  210. // ContentLength
  211. // Header, values for non-canonical keys will have unpredictable behavior
  212. //
  213. // The Response Body is closed after it is sent.
  214. func (r *Response) Write(w io.Writer) error {
  215. // Status line
  216. text := r.Status
  217. if text == "" {
  218. var ok bool
  219. text, ok = statusText[r.StatusCode]
  220. if !ok {
  221. text = "status code " + strconv.Itoa(r.StatusCode)
  222. }
  223. } else {
  224. // Just to reduce stutter, if user set r.Status to "200 OK" and StatusCode to 200.
  225. // Not important.
  226. text = strings.TrimPrefix(text, strconv.Itoa(r.StatusCode)+" ")
  227. }
  228. if _, err := fmt.Fprintf(w, "HTTP/%d.%d %03d %s\r\n", r.ProtoMajor, r.ProtoMinor, r.StatusCode, text); err != nil {
  229. return err
  230. }
  231. // Clone it, so we can modify r1 as needed.
  232. r1 := new(Response)
  233. *r1 = *r
  234. if r1.ContentLength == 0 && r1.Body != nil {
  235. // Is it actually 0 length? Or just unknown?
  236. var buf [1]byte
  237. n, err := r1.Body.Read(buf[:])
  238. if err != nil && err != io.EOF {
  239. return err
  240. }
  241. if n == 0 {
  242. // Reset it to a known zero reader, in case underlying one
  243. // is unhappy being read repeatedly.
  244. r1.Body = NoBody
  245. } else {
  246. r1.ContentLength = -1
  247. r1.Body = struct {
  248. io.Reader
  249. io.Closer
  250. }{
  251. io.MultiReader(bytes.NewReader(buf[:1]), r.Body),
  252. r.Body,
  253. }
  254. }
  255. }
  256. // If we're sending a non-chunked HTTP/1.1 response without a
  257. // content-length, the only way to do that is the old HTTP/1.0
  258. // way, by noting the EOF with a connection close, so we need
  259. // to set Close.
  260. if r1.ContentLength == -1 && !r1.Close && r1.ProtoAtLeast(1, 1) && !chunked(r1.TransferEncoding) && !r1.Uncompressed {
  261. r1.Close = true
  262. }
  263. // Process Body,ContentLength,Close,Trailer
  264. tw, err := newTransferWriter(r1)
  265. if err != nil {
  266. return err
  267. }
  268. err = tw.writeHeader(w, nil)
  269. if err != nil {
  270. return err
  271. }
  272. // Rest of header
  273. err = r.Header.WriteSubset(w, respExcludeHeader)
  274. if err != nil {
  275. return err
  276. }
  277. // contentLengthAlreadySent may have been already sent for
  278. // POST/PUT requests, even if zero length. See Issue 8180.
  279. contentLengthAlreadySent := tw.shouldSendContentLength()
  280. if r1.ContentLength == 0 && !chunked(r1.TransferEncoding) && !contentLengthAlreadySent && bodyAllowedForStatus(r.StatusCode) {
  281. if _, err := io.WriteString(w, "Content-Length: 0\r\n"); err != nil {
  282. return err
  283. }
  284. }
  285. // End-of-header
  286. if _, err := io.WriteString(w, "\r\n"); err != nil {
  287. return err
  288. }
  289. // Write body and trailer
  290. err = tw.writeBody(w)
  291. if err != nil {
  292. return err
  293. }
  294. // Success
  295. return nil
  296. }
  297. func (r *Response) closeBody() {
  298. if r.Body != nil {
  299. r.Body.Close()
  300. }
  301. }
  302. // bodyIsWritable reports whether the Body supports writing. The
  303. // Transport returns Writable bodies for 101 Switching Protocols
  304. // responses.
  305. // The Transport uses this method to determine whether a persistent
  306. // connection is done being managed from its perspective. Once we
  307. // return a writable response body to a user, the net/http package is
  308. // done managing that connection.
  309. func (r *Response) bodyIsWritable() bool {
  310. _, ok := r.Body.(io.Writer)
  311. return ok
  312. }
  313. // isProtocolSwitch reports whether the response code and header
  314. // indicate a successful protocol upgrade response.
  315. func (r *Response) isProtocolSwitch() bool {
  316. return isProtocolSwitchResponse(r.StatusCode, r.Header)
  317. }
  318. // isProtocolSwitchResponse reports whether the response code and
  319. // response header indicate a successful protocol upgrade response.
  320. func isProtocolSwitchResponse(code int, h Header) bool {
  321. return code == StatusSwitchingProtocols && isProtocolSwitchHeader(h)
  322. }
  323. // isProtocolSwitchHeader reports whether the request or response header
  324. // is for a protocol switch.
  325. func isProtocolSwitchHeader(h Header) bool {
  326. return h.Get("Upgrade") != "" &&
  327. httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade")
  328. }