Class: Akita::HarLogger::HttpRequest
- Inherits:
-
Object
- Object
- Akita::HarLogger::HttpRequest
- Defined in:
- lib/akita/har_logger/http_request.rb
Instance Method Summary collapse
-
#getBodySize(env) ⇒ Object
Obtains the size of the request body from an HTTP environment.
-
#getCookies(env) ⇒ Object
Builds a list of cookie objects from an HTTP environment.
-
#getHeaders(env) ⇒ Object
Builds a list of headers from an HTTP environment.
- #getHeadersSize(env) ⇒ Object
-
#getHttpVersion(env) ⇒ Object
Obtains the client-requested HTTP version from an HTTP environment.
-
#getMethod(env) ⇒ Object
Obtains the client’s request method from an HTTP environment.
-
#getPostData(env) ⇒ Object
Obtains the posted data from an HTTP environment.
-
#getPostDataCharSet(env) ⇒ Object
Obtains the character set of the posted data from an HTTP environment.
-
#getQueryString(env) ⇒ Object
Builds a list of query parameters from an HTTP environment.
-
#initialize(env) ⇒ HttpRequest
constructor
Produces an HttpRequest from a request’s HTTP environment.
- #to_json(*args) ⇒ Object
Constructor Details
#initialize(env) ⇒ HttpRequest
Produces an HttpRequest from a request’s HTTP environment.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/akita/har_logger/http_request.rb', line 9 def initialize(env) req = Rack::Request.new env @self = { method: getMethod(env), url: HarUtils.fixEncoding(req.url), httpVersion: getHttpVersion(env), cookies: getCookies(env), headers: getHeaders(env), queryString: getQueryString(env), headersSize: getHeadersSize(env), bodySize: getBodySize(env), } # Augment with post data if we have any. postData = getPostData(env) if postData != nil then @self[:postData] = postData end end |
Instance Method Details
#getBodySize(env) ⇒ Object
Obtains the size of the request body from an HTTP environment.
172 173 174 175 |
# File 'lib/akita/har_logger/http_request.rb', line 172 def getBodySize(env) # Assume no content if Content-Length header was not provided. env.key?('CONTENT_LENGTH') ? env['CONTENT_LENGTH'].to_i : 0 end |
#getCookies(env) ⇒ Object
Builds a list of cookie objects from an HTTP environment.
50 51 52 53 |
# File 'lib/akita/har_logger/http_request.rb', line 50 def getCookies(env) req = Rack::Request::new env HarUtils.hashToList req. end |
#getHeaders(env) ⇒ Object
Builds a list of headers from an HTTP environment.
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/akita/har_logger/http_request.rb', line 56 def getHeaders(env) # HTTP headers in the environment can be identified with the "HTTP_" # prefix. Filter for these. In the resulting map, rewrite keys of the # form "HTTP_FOO_BAR_BAZ" into "Foo-Bar-Baz", and convert into an # array. HarUtils.hashToList ( env.select { |k,v| k.start_with? 'HTTP_' }. transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } ) end |
#getHeadersSize(env) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/akita/har_logger/http_request.rb', line 150 def getHeadersSize(env) # 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 # request (HTTP method, full path, HTTP version, CRLF). For example, # # GET /index.html?foo=bar&baz=qux HTTP/1.1<CR><LF> req = Rack::Request::new env line_length = getMethod(env).length + 1 + req.fullpath.length + 1 + getHttpVersion(env).length + 2 # Add the size of the headers. Add 2 to the starting value to account # for the CRLF on the blank line. getHeaders(env).reduce(line_length + 2) { |accum, entry| # Header-Name: header value<CR><LF> accum + entry[:name].length + 2 + entry[:value].length + 2 } end |
#getHttpVersion(env) ⇒ Object
Obtains the client-requested HTTP version from an HTTP environment.
40 41 42 43 44 45 46 47 |
# File 'lib/akita/har_logger/http_request.rb', line 40 def getHttpVersion(env) # 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 |
#getMethod(env) ⇒ Object
Obtains the client’s request method from an HTTP environment.
35 36 37 |
# File 'lib/akita/har_logger/http_request.rb', line 35 def getMethod(env) HarUtils.fixEncoding (Rack::Request.new env).request_method end |
#getPostData(env) ⇒ Object
Obtains the posted data from an HTTP environment.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/akita/har_logger/http_request.rb', line 92 def getPostData(env) if env.key?('CONTENT_TYPE') && env['CONTENT_TYPE'] then result = { mimeType: env['CONTENT_TYPE'] } # Populate 'params' if we have URL-encoded parameters. Otherwise, # populate 'text'. req = Rack::Request.new env if env['CONTENT_TYPE'] == 'application/x-www-form-urlencoded' then # Decoded parameters can be found as a map in req.params. # # Requests originating from specs can be malformed: the values in # req.params are not necessarily strings. Encode all of req.params # in JSON and pretend the content type was "application/json". if HarUtils.allValuesAreStrings req.params then # Convert req.params into an array. # # XXX Spec has space for files, but are file uploads ever # URL-encoded? result[:params] = HarUtils.hashToList req.params else result[:mimeType] = 'application/json' result[:text] = req.params.to_json end else # Rack has been observed to use ASCII-8BIT encoding for the request # body when the request specifies UTF-8. Reinterpret the content # body according to what the request says it is, and re-encode into # UTF-8. # # Gracefully handle any characters that are invalid in the source # encoding and characters that have no UTF-8 representation by # replacing with '?'. Log a warning when this happens. sourceCharset = getPostDataCharSet(env) source = String.new(req.body.read).force_encoding(sourceCharset) utf8EncodingSuccessful = false if source.valid_encoding? then begin result[:text] = source.encode(Encoding::UTF_8) utf8EncodingSuccessful = true rescue Encoding::UndefinedConversionError Rails.logger.warn "[#{caller_locations(0, 1)}] Unable to losslessly convert request body from #{source.encoding} to UTF-8. Characters undefined in UTF-8 will be replaced with '?'." end else Rails.logger.warn "[#{caller_locations(0, 1)}] Request body is not valid #{source.encoding}. Invalid characters and characters undefined in UTF-8 will be replaced with '?'." end if !utf8EncodingSuccessful then result[:text] = source.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: '?') end end result else nil end end |
#getPostDataCharSet(env) ⇒ Object
Obtains the character set of the posted data from an HTTP environment.
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/akita/har_logger/http_request.rb', line 77 def getPostDataCharSet(env) req = Rack::Request.new env if req.content_charset != nil then return req.content_charset end # RFC 2616 says that "text/*" defaults to ISO-8859-1. if env['CONTENT_TYPE'].start_with?('text/') then return Encoding::ISO_8859_1 end Encoding::UTF_8 end |
#getQueryString(env) ⇒ Object
Builds a list of query parameters from an HTTP environment.
70 71 72 73 74 |
# File 'lib/akita/har_logger/http_request.rb', line 70 def getQueryString(env) req = Rack::Request::new env paramMap = Rack::Utils.parse_nested_query req.query_string HarUtils.hashToList paramMap end |
#to_json(*args) ⇒ Object
30 31 32 |
# File 'lib/akita/har_logger/http_request.rb', line 30 def to_json(*args) @self.to_json(*args) end |