class Akita::HarLogger::HttpResponse
Public Class Methods
new(env, status, headers, body)
click to toggle source
# File lib/akita/har_logger/http_response.rb, line 8 def initialize(env, status, headers, body) @self = { status: status, statusText: getStatusText(status), httpVersion: getHttpVersion(env), cookies: getCookies(headers), headers: (HarUtils.hashToList headers), content: getContent(headers, body), redirectURL: getRedirectUrl(headers), headersSize: getHeadersSize(env, status, headers), bodySize: getBodySize(body), } end
Public Instance Methods
getBodySize(body)
click to toggle source
# File lib/akita/har_logger/http_response.rb, line 160 def getBodySize(body) length = 0 # Convert each body part into a string in case we're dealing with # non-Rack-compliant components. body.each { |part| length += part.to_s.bytesize } length end
getContent(headers, body)
click to toggle source
# File lib/akita/har_logger/http_response.rb, line 76 def getContent(headers, body) # XXX Handle compression # XXX Figure out how to properly join together multi-part bodies. # Try to convert the body into UTF-8. If this fails, assume the body is # binary data. # XXX TODO Take charset part of Content-Type header into account. text = +"" haveBinaryData = false body.each { |part| partStr = part.to_s if partStr.encoding == Encoding::ASCII_8BIT then # Have 8-bit ASCII data. Try to interpret as UTF-8. If this fails, # treat as binary data. forced = String.new(partStr).force_encoding(Encoding::UTF_8) if forced.valid_encoding? then text << forced next end haveBinaryData = true break end if !partStr.valid_encoding? then # Source encoding is not valid. Treat as binary data. haveBinaryData = true break end # Try to re-encode as UTF-8. If this fails, treat as binary data. begin text << partStr.encode(Encoding::UTF_8) rescue Encoding::UndefinedConversionError haveBinaryData = true break end } if haveBinaryData then # TODO Encode binary body data with base64. # XXX Omit for now. text = "" end { size: getBodySize(body), # XXX What to use when no Content-Type is given? mimeType: HarUtils.fixEncoding(headers['Content-Type']), text: text, } end
getCookies(headers)
click to toggle source
# File lib/akita/har_logger/http_response.rb, line 44 def getCookies(headers) result = [] headers.each { |k, v| if "Set-Cookie".casecmp(k) != 0 then next end # Couldn't find a great library for parsing Set-Cookie headers, so # let's roll our own... # # According to RFC 6265, the value of Set-Cookie has the format # "cookieName=cookieValue", optionally followed by a semicolon and # attribute-value pairs. The cookieValue can be optionally enclosed # in double quotes. Neither cookieName nor cookieValue can contain # double quotes, semicolons, or equal signs. match = /^([^=]*)=([^;]*)(|;.*)$/.match(v) if !match then next end cookie_name = match[1] cookie_value = match[2] # Strip quotation marks from the value if they are present. match = /^"(.*)"$/.match(cookie_value) if match then cookie_value = match[1] end result << { name: HarUtils.fixEncoding(cookie_name), value: HarUtils.fixEncoding(cookie_value), } } result end
getHeadersSize(env, status, headers)
click to toggle source
# File lib/akita/har_logger/http_response.rb, line 140 def getHeadersSize(env, status, headers) # XXX This seems to under-count, compared to a HAR produced by Firefox. # Count the number of bytes needed to produce the first line of the # response (HTTP version, status code, status text, CRLF). For example, # # HTTP/1.1 404 Not Found<CR><LF> status_length = getHttpVersion(env).length + 1 + status.to_s.length + 1 + getStatusText(status).length + 2 # Add the size of the headers. Add 2 to the starting value to account # for the CRLF on the blank line. headers.reduce(status_length + 2) { |accum, (k, v)| # Header-Name: header value<CR><LF> accum + k.length + 2 + v.to_s.length + 2 } end
getHttpVersion(env)
click to toggle source
Obtains the HTTP version in the response.
# File lib/akita/har_logger/http_response.rb, line 32 def getHttpVersion(env) # XXX Assume the server replies with the same HTTP version as the # XXX request. This seems to hold true empirically. # The environment doesn't have HTTP_VERSION when running with `rspec`; # assume HTTP/1.1 when this happens. We don't return nil, so we can # calculate the size of the headers. env.key?('HTTP_VERSION') ? HarUtils.fixEncoding(env['HTTP_VERSION']) : 'HTTP/1.1' end
getRedirectUrl(headers)
click to toggle source
# File lib/akita/har_logger/http_response.rb, line 132 def getRedirectUrl(headers) # Use the "Location" header if it exists. Otherwise, based on some HAR # examples found online, it looks like an empty string is used. headers.key?('Location') ? HarUtils.fixEncoding(headers['Location']) : '' end
getStatusText(status)
click to toggle source
Obtains the status text corresponding to a status code.
# File lib/akita/har_logger/http_response.rb, line 27 def getStatusText(status) HarUtils.fixEncoding(Rack::Utils::HTTP_STATUS_CODES[status]) end
to_json(*args)
click to toggle source
# File lib/akita/har_logger/http_response.rb, line 22 def to_json(*args) @self.to_json(*args) end