-
Notifications
You must be signed in to change notification settings - Fork 151
/
response.rb
93 lines (73 loc) · 2.21 KB
/
response.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
require "zlib"
require "stringio"
require "rack/utils"
require "httpi/dime"
require "httpi/cookie"
module HTTPI
# = HTTPI::Response
#
# Represents an HTTP response and contains various response details.
class Response
# Range of HTTP response codes considered to be successful.
SuccessfulResponseCodes = 200..299
# Initializer expects an HTTP response +code+, +headers+ and +body+.
def initialize(code, headers, body)
self.code = code.to_i
self.headers = Rack::Utils::HeaderHash.new(headers)
self.raw_body = body
end
attr_accessor :code, :headers, :raw_body, :attachments
# Returns whether the HTTP response is considered successful.
def error?
!SuccessfulResponseCodes.include? code.to_i
end
# Returns whether the HTTP response is a multipart response.
def multipart?
!!(headers["Content-Type"] =~ /^multipart/i)
end
# Returns a list of cookies from the response.
def cookies
@cookies ||= Cookie.list_from_headers(headers)
end
# Returns any DIME attachments.
def attachments
decode_body unless @body
@attachments ||= []
end
# Returns the HTTP response body.
def body
decode_body unless @body
@body
end
attr_writer :body
private
def decode_body
return @body = "" if !raw_body || raw_body.empty?
body = gzipped_response? ? decoded_gzip_body : raw_body
@body = dime_response? ? decoded_dime_body(body) : body
end
# Returns whether the response is gzipped.
def gzipped_response?
headers["Content-Encoding"] == "gzip"
end
# Returns whether this is a DIME response.
def dime_response?
headers["Content-Type"] == "application/dime"
end
# Returns the gzip decoded response body.
def decoded_gzip_body
unless gzip = Zlib::GzipReader.new(StringIO.new(raw_body))
raise ArgumentError, "Unable to create Zlib::GzipReader"
end
gzip.read
ensure
gzip.close if gzip
end
# Returns the DIME decoded response body.
def decoded_dime_body(body = nil)
dime = Dime.new(body || raw_body)
self.attachments = dime.binary_records
dime.xml_records.first.data
end
end
end