33// that can be found in the LICENSE file.
44module http
55
6+ import compress.gzip
7+ import compress.zlib
68import net.http.chunked
79import strconv
810
@@ -40,9 +42,10 @@ pub fn parse_response(resp string) !Response {
4042 start_idx , end_idx := find_headers_range (resp)!
4143 header := parse_headers (resp.substr (start_idx, end_idx))!
4244 mut body := resp.substr (end_idx, resp.len)
43- if header.get (.transfer_encoding) or { '' } == 'chunked' {
45+ if has_header_token ( header.get (.transfer_encoding) or { '' }, 'chunked' ) {
4446 body = chunked.decode (body)!
4547 }
48+ body = decode_response_body (body, header.get (.content_encoding) or { '' })
4649 return Response{
4750 http_version: version
4851 status_code: status_code
@@ -52,6 +55,55 @@ pub fn parse_response(resp string) !Response {
5255 }
5356}
5457
58+ fn has_header_token (header_value string , expected_token string ) bool {
59+ for token in parse_header_tokens (header_value) {
60+ if token == expected_token.to_lower () {
61+ return true
62+ }
63+ }
64+ return false
65+ }
66+
67+ fn parse_header_tokens (header_value string ) []string {
68+ mut tokens := []string {}
69+ for part in header_value.split (',' ) {
70+ token := part.all_before (';' ).trim_space ().to_lower ()
71+ if token != '' {
72+ tokens << token
73+ }
74+ }
75+ return tokens
76+ }
77+
78+ fn decode_response_body (body string , content_encoding string ) string {
79+ if body.len == 0 {
80+ return body
81+ }
82+ encodings := parse_header_tokens (content_encoding)
83+ if encodings.len == 0 {
84+ return body
85+ }
86+ mut decoded := body.bytes ()
87+ for i := encodings.len - 1 ; i > = 0 ; i-- {
88+ encoding := encodings[i]
89+ decoded = match encoding {
90+ 'gzip' , 'x-gzip' {
91+ gzip.decompress (decoded) or { return body }
92+ }
93+ 'deflate' {
94+ zlib.decompress (decoded) or { return body }
95+ }
96+ 'identity' {
97+ decoded
98+ }
99+ else {
100+ return body
101+ }
102+ }
103+ }
104+ return decoded.bytestr ()
105+ }
106+
55107// parse_status_line parses the first HTTP response line into the HTTP
56108// version, status code, and reason phrase
57109fn parse_status_line (line string ) ! (string , int , string ) {
0 commit comments