@@ -151,27 +151,44 @@ def set_config(opts = {})
151
151
#
152
152
# Create an arbitrary HTTP request
153
153
#
154
+ # @param opts [Hash]
155
+ # @option opts 'agent' [String] User-Agent header value
156
+ # @option opts 'basic_auth' [String] Basic-Auth header value
157
+ # @option opts 'connection' [String] Connection header value
158
+ # @option opts 'cookie' [String] Cookie header value
159
+ # @option opts 'data' [String] HTTP data (only useful with some methods, see rfc2616)
160
+ # @option opts 'encode' [Bool] URI encode the supplied URI, default: false
161
+ # @option opts 'headers' [Hash] HTTP headers, e.g. <code>{ "X-MyHeader" => "value" }</code>
162
+ # @option opts 'method' [String] HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
163
+ # @option opts 'proto' [String] protocol, default: HTTP
164
+ # @option opts 'query' [String] raw query string
165
+ # @option opts 'raw_headers' [Hash] HTTP headers
166
+ # @option opts 'uri' [String] the URI to request
167
+ # @option opts 'version' [String] version of the protocol, default: 1.1
168
+ # @option opts 'vhost' [String] Host header value
169
+ #
170
+ # @return [Request]
154
171
def request_raw ( opts = { } )
155
- c_enc = opts [ 'encode ' ] || false
156
- c_uri = opts [ 'uri ' ] || '/ '
172
+ c_ag = opts [ 'agent ' ] || config [ 'agent' ]
173
+ c_auth = opts [ 'basic_auth ' ] || config [ 'basic_auth' ] || ''
157
174
c_body = opts [ 'data' ] || ''
175
+ c_conn = opts [ 'connection' ]
176
+ c_cook = opts [ 'cookie' ] || config [ 'cookie' ]
177
+ c_enc = opts [ 'encode' ] || false
178
+ c_head = opts [ 'headers' ] || config [ 'headers' ] || { }
179
+ c_host = opts [ 'vhost' ] || config [ 'vhost' ] || self . hostname
158
180
c_meth = opts [ 'method' ] || 'GET'
159
181
c_prot = opts [ 'proto' ] || 'HTTP'
160
- c_vers = opts [ 'version' ] || config [ 'version' ] || '1.1'
161
182
c_qs = opts [ 'query' ]
162
- c_ag = opts [ 'agent' ] || config [ 'agent' ]
163
- c_cook = opts [ 'cookie' ] || config [ 'cookie' ]
164
- c_host = opts [ 'vhost' ] || config [ 'vhost' ] || self . hostname
165
- c_head = opts [ 'headers' ] || config [ 'headers' ] || { }
166
183
c_rawh = opts [ 'raw_headers' ] || config [ 'raw_headers' ] || ''
167
- c_conn = opts [ 'connection' ]
168
- c_auth = opts [ 'basic_auth ' ] || config [ 'basic_auth ' ] || ''
184
+ c_uri = opts [ 'uri' ] || '/'
185
+ c_vers = opts [ 'version ' ] || config [ 'version ' ] || '1.1 '
169
186
170
187
# An agent parameter was specified, but so was a header, prefer the header
171
188
if c_ag and c_head . keys . map { |x | x . downcase } . include? ( 'user-agent' )
172
189
c_ag = nil
173
190
end
174
-
191
+
175
192
uri = set_uri ( c_uri )
176
193
177
194
req = ''
@@ -191,7 +208,6 @@ def request_raw(opts={})
191
208
req << set_host_header ( c_host )
192
209
req << set_agent_header ( c_ag )
193
210
194
-
195
211
if ( c_auth . length > 0 )
196
212
req << set_basic_auth_header ( c_auth )
197
213
end
@@ -201,53 +217,45 @@ def request_raw(opts={})
201
217
req << set_extra_headers ( c_head )
202
218
req << set_raw_headers ( c_rawh )
203
219
req << set_body ( c_body )
204
-
205
- { :string => req , :opts => opts }
220
+
221
+ request = Request . new
222
+ request . parse ( req )
223
+ request . options = opts
224
+
225
+ request
206
226
end
207
227
208
228
209
229
#
210
230
# Create a CGI compatible request
211
231
#
212
- # Options:
213
- # - agent: User-Agent header value
214
- # - basic_auth: Basic-Auth header value
215
- # - connection: Connection header value
216
- # - cookie: Cookie header value
217
- # - ctype: Content-Type header value, default: +application/x-www-form-urlencoded+
218
- # - data: HTTP data (only useful with some methods, see rfc2616)
219
- # - encode: URI encode the supplied URI, default: false
220
- # - encode_params: URI encode the GET or POST variables (names and values), default: true
221
- # - headers: HTTP headers as a hash, e.g. <code>{ "X-MyHeader" => "value" }</code>
222
- # - method: HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
223
- # - proto: protocol, default: HTTP
224
- # - query: raw query string
225
- # - raw_headers: HTTP headers as a hash
226
- # - uri: the URI to request
227
- # - vars_get: GET variables as a hash to be translated into a query string
228
- # - vars_post: POST variables as a hash to be translated into POST data
229
- # - version: version of the protocol, default: 1.1
230
- # - vhost: Host header value
232
+ # @param (see #request_raw)
233
+ # @option opts (see #request_raw)
234
+ # @option opts 'ctype' [String] Content-Type header value, default: +application/x-www-form-urlencoded+
235
+ # @option opts 'encode_params' [Bool] URI encode the GET or POST variables (names and values), default: true
236
+ # @option opts 'vars_get' [Hash] GET variables as a hash to be translated into a query string
237
+ # @option opts 'vars_post' [Hash] POST variables as a hash to be translated into POST data
231
238
#
239
+ # @return [Request]
232
240
def request_cgi ( opts = { } )
241
+ c_ag = opts [ 'agent' ] || config [ 'agent' ]
242
+ c_body = opts [ 'data' ] || ''
243
+ c_cgi = opts [ 'uri' ] || '/'
244
+ c_conn = opts [ 'connection' ]
245
+ c_cook = opts [ 'cookie' ] || config [ 'cookie' ]
233
246
c_enc = opts [ 'encode' ] || false
234
247
c_enc_p = ( opts [ 'encode_params' ] == true or opts [ 'encode_params' ] . nil? ? true : false )
235
- c_cgi = opts [ 'uri ' ] || '/'
236
- c_body = opts [ 'data ' ] || ''
248
+ c_head = opts [ 'headers ' ] || config [ 'headers' ] || { }
249
+ c_host = opts [ 'vhost ' ] || config [ 'vhost' ]
237
250
c_meth = opts [ 'method' ] || 'GET'
251
+ c_path = opts [ 'path_info' ]
238
252
c_prot = opts [ 'proto' ] || 'HTTP'
239
- c_vers = opts [ 'version' ] || config [ 'version' ] || '1.1'
240
253
c_qs = opts [ 'query' ] || ''
241
- c_varg = opts [ 'vars_get' ] || { }
242
- c_varp = opts [ 'vars_post' ] || { }
243
- c_head = opts [ 'headers' ] || config [ 'headers' ] || { }
244
254
c_rawh = opts [ 'raw_headers' ] || config [ 'raw_headers' ] || ''
245
255
c_type = opts [ 'ctype' ] || 'application/x-www-form-urlencoded'
246
- c_ag = opts [ 'agent' ] || config [ 'agent' ]
247
- c_cook = opts [ 'cookie' ] || config [ 'cookie' ]
248
- c_host = opts [ 'vhost' ] || config [ 'vhost' ]
249
- c_conn = opts [ 'connection' ]
250
- c_path = opts [ 'path_info' ]
256
+ c_varg = opts [ 'vars_get' ] || { }
257
+ c_varp = opts [ 'vars_post' ] || { }
258
+ c_vers = opts [ 'version' ] || config [ 'version' ] || '1.1'
251
259
252
260
uri = set_cgi ( c_cgi )
253
261
qstr = c_qs
@@ -264,7 +272,7 @@ def request_cgi(opts={})
264
272
265
273
c_varg . each_pair do |var , val |
266
274
qstr << '&' if qstr . length > 0
267
- qstr << ( c_enc_p ? set_encode_uri ( var ) : var )
275
+ qstr << ( c_enc_p ? set_encode_uri ( var ) : var )
268
276
qstr << '='
269
277
qstr << ( c_enc_p ? set_encode_uri ( val ) : val )
270
278
end
@@ -315,12 +323,19 @@ def request_cgi(opts={})
315
323
req << set_raw_headers ( c_rawh )
316
324
req << set_body ( pstr )
317
325
318
- { :string => req , :opts => opts }
326
+ request = Request . new
327
+ request . parse ( req )
328
+ request . options = opts
329
+
330
+ request
319
331
end
320
332
321
333
#
322
334
# Connects to the remote server if possible.
323
335
#
336
+ # @param t [Fixnum] Timeout
337
+ # @see Rex::Socket::Tcp.create
338
+ # @return [Rex::Socket::Tcp]
324
339
def connect ( t = -1 )
325
340
# If we already have a connection and we aren't pipelining, close it.
326
341
if ( self . conn )
@@ -360,28 +375,29 @@ def close
360
375
361
376
#
362
377
# Sends a request and gets a response back
363
- # If the request is a 401, and we have creds, it will attempt to
364
- # complete authentication and return the final response
378
+ #
379
+ # If the request is a 401, and we have creds, it will attempt to complete
380
+ # authentication and return the final response
365
381
#
366
382
def send_recv ( req , t = -1 , persist = false )
367
- opts = req [ :opts ]
368
- req = req [ :string ]
369
383
res = _send_recv ( req , t , persist )
370
384
if res and res . code == 401 and res . headers [ 'WWW-Authenticate' ] and have_creds?
371
- res = send_auth ( res , opts , t , persist )
385
+ res = send_auth ( res , req . options , t , persist )
372
386
end
373
387
res
374
388
end
375
389
376
390
#
377
391
# Transmit an HTTP request and receive the response
378
- # If persist is set, then the request will attempt
379
- # to reuse an existing connection.
380
392
#
393
+ # If persist is set, then the request will attempt to reuse an existing
394
+ # connection.
395
+ #
396
+ # Call this directly instead of {#send_recv} if you don't want automatic
397
+ # authentication handling.
398
+ #
399
+ # @return [Response]
381
400
def _send_recv ( req , t = -1 , persist = false )
382
- if req . kind_of? Hash and req [ :string ]
383
- req = req [ :string ]
384
- end
385
401
@pipeline = persist
386
402
send_request ( req , t )
387
403
res = read_response ( t )
@@ -392,12 +408,14 @@ def _send_recv(req, t = -1, persist=false)
392
408
#
393
409
# Send an HTTP request to the server
394
410
#
411
+ # @param req [Request,#to_s] The request to send
412
+ # @param t (see #connect)
395
413
def send_request ( req , t = -1 )
396
414
connect ( t )
397
415
conn . put ( req . to_s )
398
416
end
399
417
400
- # Validates that the client has creds
418
+ # Validates that the client has creds
401
419
def have_creds?
402
420
!( self . username . nil? ) && self . username != ''
403
421
end
@@ -420,7 +438,7 @@ def send_auth(res, opts, t, persist)
420
438
else
421
439
opts [ 'headers' ] = { 'Authorization' => basic_auth_header ( self . username , self . password ) }
422
440
end
423
-
441
+
424
442
req = request_cgi ( opts )
425
443
res = _send_recv ( req , t , persist )
426
444
return res
@@ -628,7 +646,7 @@ def negotiate_auth(opts={})
628
646
opts [ 'password' ] ||= self . password . to_s
629
647
630
648
if opts [ 'provider' ] and opts [ 'provider' ] . include? 'Negotiate'
631
- provider = "Negotiate "
649
+ provider = "Negotiate "
632
650
else
633
651
provider = 'NTLM '
634
652
end
0 commit comments