fix(client): fix keep-alive header detection when parsing responses
This commit is contained in:
		| @@ -600,10 +600,29 @@ impl Http1Transaction for Client { | |||||||
|                 .take() |                 .take() | ||||||
|                 .unwrap_or_else(HeaderMap::new); |                 .unwrap_or_else(HeaderMap::new); | ||||||
|  |  | ||||||
|             headers.reserve(headers_len); |             let mut keep_alive = version == Version::HTTP_11; | ||||||
|             fill_headers(&mut headers, slice, &headers_indices[..headers_len]); |  | ||||||
|  |  | ||||||
|             let keep_alive = version == Version::HTTP_11; |             headers.reserve(headers_len); | ||||||
|  |             for header in &headers_indices[..headers_len] { | ||||||
|  |                 let name = header_name!(&slice[header.name.0..header.name.1]); | ||||||
|  |                 let value = header_value!(slice.slice(header.value.0, header.value.1)); | ||||||
|  |  | ||||||
|  |                 match name { | ||||||
|  |                     header::CONNECTION => { | ||||||
|  |                         // keep_alive was previously set to default for Version | ||||||
|  |                         if keep_alive { | ||||||
|  |                             // HTTP/1.1 | ||||||
|  |                             keep_alive = !headers::connection_close(&value); | ||||||
|  |  | ||||||
|  |                         } else { | ||||||
|  |                             // HTTP/1.0 | ||||||
|  |                             keep_alive = headers::connection_keep_alive(&value); | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                     _ => (), | ||||||
|  |                 } | ||||||
|  |                 headers.append(name, value); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             let head = MessageHead { |             let head = MessageHead { | ||||||
|                 version, |                 version, | ||||||
| @@ -907,14 +926,6 @@ fn record_header_indices(bytes: &[u8], headers: &[httparse::Header], indices: &m | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| fn fill_headers(headers: &mut HeaderMap, slice: Bytes, indices: &[HeaderIndices]) { |  | ||||||
|     for header in indices { |  | ||||||
|         let name = header_name!(&slice[header.name.0..header.name.1]); |  | ||||||
|         let value = header_value!(slice.slice(header.value.0, header.value.1)); |  | ||||||
|         headers.append(name, value); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Write header names as title case. The header name is assumed to be ASCII, | // Write header names as title case. The header name is assumed to be ASCII, | ||||||
| // therefore it is trivial to convert an ASCII character from lowercase to | // therefore it is trivial to convert an ASCII character from lowercase to | ||||||
| // uppercase. It is as simple as XORing the lowercase character byte with | // uppercase. It is as simple as XORing the lowercase character byte with | ||||||
| @@ -1319,6 +1330,33 @@ mod tests { | |||||||
|             transfer-encoding: chunked\r\n\ |             transfer-encoding: chunked\r\n\ | ||||||
|             \r\n\ |             \r\n\ | ||||||
|         "); |         "); | ||||||
|  |  | ||||||
|  |         // keep-alive | ||||||
|  |         assert!(parse("\ | ||||||
|  |             HTTP/1.1 200 OK\r\n\ | ||||||
|  |             content-length: 0\r\n\ | ||||||
|  |             \r\n\ | ||||||
|  |         ").keep_alive, "HTTP/1.1 keep-alive is default"); | ||||||
|  |  | ||||||
|  |         assert!(!parse("\ | ||||||
|  |             HTTP/1.1 200 OK\r\n\ | ||||||
|  |             content-length: 0\r\n\ | ||||||
|  |             connection: foo, close, bar\r\n\ | ||||||
|  |             \r\n\ | ||||||
|  |         ").keep_alive, "connection close is always close"); | ||||||
|  |  | ||||||
|  |         assert!(!parse("\ | ||||||
|  |             HTTP/1.0 200 OK\r\n\ | ||||||
|  |             content-length: 0\r\n\ | ||||||
|  |             \r\n\ | ||||||
|  |         ").keep_alive, "HTTP/1.0 close is default"); | ||||||
|  |  | ||||||
|  |         assert!(parse("\ | ||||||
|  |             HTTP/1.0 200 OK\r\n\ | ||||||
|  |             content-length: 0\r\n\ | ||||||
|  |             connection: foo, keep-alive, bar\r\n\ | ||||||
|  |             \r\n\ | ||||||
|  |         ").keep_alive, "connection keep-alive is always keep-alive"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user