Class: Arachni::HTTP::Request
- Defined in:
- lib/arachni/http/request.rb,
lib/arachni/http/request/scope.rb
Overview
HTTP Request representation.
Defined Under Namespace
Classes: Scope
Constant Summary collapse
- REDIRECT_LIMIT =
Default redirect limit, RFC says 5 max.
5
- MODES =
Supported modes of operation.
[ # Asynchronous (non-blocking) (Default) :async, # Synchronous (blocking) :sync ]
Instance Attribute Summary collapse
-
#cookies ⇒ Hash
Cookies set for this request.
-
#effective_body ⇒ String
Transmitted HTTP request body.
-
#follow_location ⇒ Bool
Follow ‘Location` headers.
-
#headers_string ⇒ String
Transmitted HTTP request headers.
- #high_priority ⇒ Bool
-
#id ⇒ Integer
Auto-incremented ID for this request (set by Client#request).
-
#max_redirects ⇒ Integer
Maximum number of redirects to follow.
-
#mode ⇒ Symbol
Mode of operation for the request.
-
#parameters ⇒ Hash
Request parameters.
-
#password ⇒ String
HTTP password.
-
#performer ⇒ Object
Entity which performed the request – mostly used to track which response was a result of which submitted element.
-
#proxy ⇒ String
‘host:port`.
- #proxy_type ⇒ String
-
#proxy_user_password ⇒ String
‘user:password`.
- #root_redirect_id ⇒ Object
-
#timeout ⇒ Integer
Timeout in milliseconds.
-
#username ⇒ String
HTTP username.
Attributes inherited from Message
Class Method Summary collapse
- .from_rpc_data(data) ⇒ Request
-
.parse_body(body) ⇒ Hash
Parses an HTTP request body generated by submitting a form.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#asynchronous? ⇒ Boolean
‘true` if #mode is `:async`, `false` otherwise.
-
#blocking? ⇒ Boolean
‘true` if #mode is `:sync`, `false` otherwise.
- #body_parameters ⇒ Object
-
#clear_callbacks ⇒ Object
Clears #on_complete callbacks.
- #effective_cookies ⇒ Object
-
#follow_location? ⇒ Bool
‘true` if redirects should be followed, `false` otherwise.
- #handle_response(response, typhoeus_response = nil) ⇒ Object
- #hash ⇒ Object
- #high_priority? ⇒ Boolean
-
#initialize(options = {}) ⇒ Request
constructor
A new instance of Request.
- #marshal_dump ⇒ Object
- #marshal_load(h) ⇒ Object
-
#method(*args) ⇒ Symbol
HTTP method.
-
#method=(verb) ⇒ Symbol
Sets the request HTTP method.
- #on_complete(&block) ⇒ Object
- #run ⇒ Response
- #to_h ⇒ Object
-
#to_rpc_data ⇒ Hash
Data representing this instance that are suitable the RPC transmission.
-
#to_s ⇒ String
HTTP request string.
-
#to_typhoeus ⇒ Typhoeus::Response
‘self` converted to a `Typhoeus::Request`.
-
#train ⇒ Object
Flags that the response should be analyzed by the Trainer for new elements.
- #train? ⇒ Bool
- #update_cookies ⇒ Object
- #update_cookies? ⇒ Bool
Methods inherited from Message
Constructor Details
#initialize(options = {}) ⇒ Request
Returns a new instance of Request.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/arachni/http/request.rb', line 122 def initialize( = {} ) [:method] ||= :get super( ) @train = false if @train.nil? @update_cookies = false if @update_cookies.nil? @follow_location = false if @follow_location.nil? @max_redirects = (Arachni::Options.http.request_redirect_limit || REDIRECT_LIMIT) @on_complete = [] @timeout ||= Arachni::Options.http.request_timeout @mode ||= :async @parameters ||= {} @cookies ||= {} end |
Instance Attribute Details
#cookies ⇒ Hash
Returns Cookies set for this request.
62 63 64 |
# File 'lib/arachni/http/request.rb', line 62 def @cookies end |
#effective_body ⇒ String
Available only via completed Arachni::HTTP::Response#request.
Returns Transmitted HTTP request body.
80 81 82 |
# File 'lib/arachni/http/request.rb', line 80 def effective_body @effective_body end |
#follow_location ⇒ Bool
Returns Follow ‘Location` headers.
44 45 46 |
# File 'lib/arachni/http/request.rb', line 44 def follow_location @follow_location end |
#headers_string ⇒ String
Available only via completed Arachni::HTTP::Response#request.
Returns Transmitted HTTP request headers.
74 75 76 |
# File 'lib/arachni/http/request.rb', line 74 def headers_string @headers_string end |
#high_priority ⇒ Bool
98 99 100 |
# File 'lib/arachni/http/request.rb', line 98 def high_priority @high_priority end |
#id ⇒ Integer
Returns Auto-incremented ID for this request (set by Client#request).
32 33 34 |
# File 'lib/arachni/http/request.rb', line 32 def id @id end |
#max_redirects ⇒ Integer
Returns Maximum number of redirects to follow.
50 51 52 |
# File 'lib/arachni/http/request.rb', line 50 def max_redirects @max_redirects end |
#mode ⇒ Symbol
Returns Mode of operation for the request.
68 69 70 |
# File 'lib/arachni/http/request.rb', line 68 def mode @mode end |
#parameters ⇒ Hash
Returns Request parameters.
36 37 38 |
# File 'lib/arachni/http/request.rb', line 36 def parameters @parameters end |
#password ⇒ String
Returns HTTP password.
58 59 60 |
# File 'lib/arachni/http/request.rb', line 58 def password @password end |
#performer ⇒ Object
Entity which performed the request – mostly used to track which response was a result of which submitted element.
84 85 86 |
# File 'lib/arachni/http/request.rb', line 84 def performer @performer end |
#proxy ⇒ String
Returns ‘host:port`.
88 89 90 |
# File 'lib/arachni/http/request.rb', line 88 def proxy @proxy end |
#proxy_type ⇒ String
95 96 97 |
# File 'lib/arachni/http/request.rb', line 95 def proxy_type @proxy_type end |
#proxy_user_password ⇒ String
Returns ‘user:password`.
92 93 94 |
# File 'lib/arachni/http/request.rb', line 92 def proxy_user_password @proxy_user_password end |
#root_redirect_id ⇒ Object
101 102 103 |
# File 'lib/arachni/http/request.rb', line 101 def root_redirect_id @root_redirect_id end |
#timeout ⇒ Integer
Returns Timeout in milliseconds.
40 41 42 |
# File 'lib/arachni/http/request.rb', line 40 def timeout @timeout end |
#username ⇒ String
Returns HTTP username.
54 55 56 |
# File 'lib/arachni/http/request.rb', line 54 def username @username end |
Class Method Details
.from_rpc_data(data) ⇒ Request
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
# File 'lib/arachni/http/request.rb', line 428 def from_rpc_data( data ) instance = allocate data.each do |name, value| value = case name when 'method', 'mode' value.to_sym else value end instance.instance_variable_set( "@#{name}", value ) end instance end |
.parse_body(body) ⇒ Hash
Parses an HTTP request body generated by submitting a form.
451 452 453 454 455 456 457 458 459 |
# File 'lib/arachni/http/request.rb', line 451 def parse_body( body ) return {} if !body body.to_s.split( '&' ).inject( {} ) do |h, pair| name, value = pair.split( '=', 2 ) h[Form.decode( name.to_s )] = Form.decode( value ) h end end |
Instance Method Details
#==(other) ⇒ Object
389 390 391 |
# File 'lib/arachni/http/request.rb', line 389 def ==( other ) hash == other.hash end |
#asynchronous? ⇒ Boolean
Returns ‘true` if #mode is `:async`, `false` otherwise.
168 169 170 |
# File 'lib/arachni/http/request.rb', line 168 def asynchronous? mode == :async end |
#blocking? ⇒ Boolean
Returns ‘true` if #mode is `:sync`, `false` otherwise.
174 175 176 |
# File 'lib/arachni/http/request.rb', line 174 def blocking? mode == :sync end |
#body_parameters ⇒ Object
216 217 218 219 |
# File 'lib/arachni/http/request.rb', line 216 def body_parameters return {} if method != :post parameters.any? ? parameters : self.class.parse_body( body ) end |
#clear_callbacks ⇒ Object
Clears #on_complete callbacks.
238 239 240 |
# File 'lib/arachni/http/request.rb', line 238 def clear_callbacks @on_complete.clear end |
#effective_cookies ⇒ Object
209 210 211 212 213 214 |
# File 'lib/arachni/http/request.rb', line 209 def Cookie.from_string( url, headers['Cookie'] || '' ).inject({}) do |h, | h[.name] = .value h end.merge( ) end |
#follow_location? ⇒ Bool
Returns ‘true` if redirects should be followed, `false` otherwise.
244 245 246 |
# File 'lib/arachni/http/request.rb', line 244 def follow_location? !!@follow_location end |
#handle_response(response, typhoeus_response = nil) ⇒ Object
285 286 287 288 289 290 291 292 293 |
# File 'lib/arachni/http/request.rb', line 285 def handle_response( response, typhoeus_response = nil ) if typhoeus_response fill_in_data_from_typhoeus_response typhoeus_response end response.request = self @on_complete.each { |b| b.call response } response end |
#hash ⇒ Object
393 394 395 |
# File 'lib/arachni/http/request.rb', line 393 def hash to_h.hash end |
#high_priority? ⇒ Boolean
139 140 141 |
# File 'lib/arachni/http/request.rb', line 139 def high_priority? !!@high_priority end |
#marshal_dump ⇒ Object
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/arachni/http/request.rb', line 397 def marshal_dump callbacks = @on_complete.dup performer = @performer ? @performer.dup : nil @performer = nil @on_complete = [] instance_variables.inject( {} ) do |h, iv| next h if iv == :@scope h[iv.to_s.gsub('@','')] = instance_variable_get( iv ) h end ensure @on_complete = callbacks @performer = performer.dup if performer end |
#marshal_load(h) ⇒ Object
414 415 416 |
# File 'lib/arachni/http/request.rb', line 414 def marshal_load( h ) h.each { |k, v| instance_variable_set( "@#{k}", v ) } end |
#method(*args) ⇒ Symbol
Returns HTTP method.
180 181 182 183 |
# File 'lib/arachni/http/request.rb', line 180 def method( *args ) return super( *args ) if args.any? # Preserve Object#method. @method end |
#method=(verb) ⇒ Symbol
Method will be normalized to a lower-case symbol.
Sets the request HTTP method.
194 195 196 |
# File 'lib/arachni/http/request.rb', line 194 def method=( verb ) @method = verb.to_s.downcase.to_sym end |
#on_complete(&block) ⇒ Object
Can be invoked multiple times.
231 232 233 234 235 |
# File 'lib/arachni/http/request.rb', line 231 def on_complete( &block ) fail 'Block is missing.' if !block_given? @on_complete << block self end |
#run ⇒ Response
Will call #on_complete callbacks.
Performs the Arachni::HTTP::Request without going through Client.
278 279 280 281 282 283 |
# File 'lib/arachni/http/request.rb', line 278 def run response = to_typhoeus.run fill_in_data_from_typhoeus_response response Response.from_typhoeus( response ).tap { |r| r.request = self } end |
#to_h ⇒ Object
377 378 379 380 381 382 383 384 385 386 387 |
# File 'lib/arachni/http/request.rb', line 377 def to_h { url: url, parameters: parameters, headers: headers, headers_string: headers_string, effective_body: effective_body, body: body, method: method } end |
#to_rpc_data ⇒ Hash
Returns Data representing this instance that are suitable the RPC transmission.
420 421 422 |
# File 'lib/arachni/http/request.rb', line 420 def to_rpc_data marshal_dump end |
#to_s ⇒ String
Returns HTTP request string.
223 224 225 |
# File 'lib/arachni/http/request.rb', line 223 def to_s "#{headers_string}#{effective_body}" end |
#to_typhoeus ⇒ Typhoeus::Response
Returns ‘self` converted to a `Typhoeus::Request`.
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/arachni/http/request.rb', line 297 def to_typhoeus headers['Cookie'] = . map { |k, v| "#{Cookie.encode( k )}=#{Cookie.encode( v )}" }. join( ';' ) headers['User-Agent'] ||= Arachni::Options.http.user_agent headers['Accept'] ||= 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' headers['From'] ||= Arachni::Options. if Arachni::Options. headers.delete( 'Cookie' ) if headers['Cookie'].empty? headers.each { |k, v| headers[k] = Header.encode( v ) if v } if (userpwd = (@username || Arachni::Options.http.authentication_username)) if (passwd = (@password || Arachni::Options.http.authentication_password)) userpwd += ":#{passwd}" end end max_size = @response_max_size || Arachni::Options.http.response_max_size # Weird I know, for some reason 0 gets ignored. max_size = 1 if max_size == 0 = { method: method, headers: headers, body: body, params: Arachni::Utilities.uri_parse_query( url ). merge( parameters || {} ), userpwd: userpwd, followlocation: follow_location?, maxredirs: @max_redirects, ssl_verifypeer: false, ssl_verifyhost: 0, accept_encoding: 'gzip, deflate', nosignal: true, maxfilesize: max_size, # Don't keep the socket alive if this is a blocking request because # it's going to be performed by an one-off Hydra. forbid_reuse: blocking?, verbose: true } [:timeout_ms] = timeout if timeout [:httpauth] = :auto if userpwd if proxy .merge!( proxy: proxy, proxytype: (proxy_type || :http).to_sym ) if proxy_user_password [:proxyuserpwd] = proxy_user_password end elsif Arachni::Options.http.proxy_host && Arachni::Options.http.proxy_port .merge!( proxy: "#{Arachni::Options.http.proxy_host}:#{Arachni::Options.http.proxy_port}", proxytype: (Arachni::Options.http.proxy_type || :http).to_sym ) if Arachni::Options.http.proxy_username && Arachni::Options.http.proxy_password [:proxyuserpwd] = "#{Arachni::Options.http.proxy_username}:#{Arachni::Options.http.proxy_password}" end end curl = parsed_url.query ? url.gsub( "?#{parsed_url.query}", '' ) : url r = Typhoeus::Request.new( curl, ) if @on_complete.any? r.on_complete do |typhoeus_response| handle_response Response.from_typhoeus( typhoeus_response ), typhoeus_response end end r end |
#train ⇒ Object
Flags that the response should be analyzed by the Trainer for new elements.
257 258 259 |
# File 'lib/arachni/http/request.rb', line 257 def train @train = true end |
#train? ⇒ Bool
Returns ‘true` if the Arachni::HTTP::Response should be analyzed by the Trainer for new elements, `false` otherwise.
251 252 253 |
# File 'lib/arachni/http/request.rb', line 251 def train? @train end |
#update_cookies ⇒ Object
Flags that the CookieJar should be updated with the Arachni::HTTP::Response cookies.
269 270 271 |
# File 'lib/arachni/http/request.rb', line 269 def @update_cookies = true end |
#update_cookies? ⇒ Bool
Returns ‘true` if the CookieJar should be updated with the Arachni::HTTP::Response cookies, `false` otherwise.
264 265 266 |
# File 'lib/arachni/http/request.rb', line 264 def @update_cookies end |