Skip to content

Commit a158893

Browse files
committed
Return a Request object
Still changes the return type, but now at least .to_s will give you the right thing and at least a Request object is a logical thing to return.
1 parent 1095fe1 commit a158893

File tree

2 files changed

+78
-58
lines changed

2 files changed

+78
-58
lines changed

lib/rex/proto/http/client.rb

Lines changed: 76 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -151,27 +151,44 @@ def set_config(opts = {})
151151
#
152152
# Create an arbitrary HTTP request
153153
#
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]
154171
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'] || ''
157174
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
158180
c_meth = opts['method'] || 'GET'
159181
c_prot = opts['proto'] || 'HTTP'
160-
c_vers = opts['version'] || config['version'] || '1.1'
161182
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'] || {}
166183
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'
169186

170187
# An agent parameter was specified, but so was a header, prefer the header
171188
if c_ag and c_head.keys.map{|x| x.downcase }.include?('user-agent')
172189
c_ag = nil
173190
end
174-
191+
175192
uri = set_uri(c_uri)
176193

177194
req = ''
@@ -191,7 +208,6 @@ def request_raw(opts={})
191208
req << set_host_header(c_host)
192209
req << set_agent_header(c_ag)
193210

194-
195211
if (c_auth.length > 0)
196212
req << set_basic_auth_header(c_auth)
197213
end
@@ -201,53 +217,45 @@ def request_raw(opts={})
201217
req << set_extra_headers(c_head)
202218
req << set_raw_headers(c_rawh)
203219
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
206226
end
207227

208228

209229
#
210230
# Create a CGI compatible request
211231
#
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
231238
#
239+
# @return [Request]
232240
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']
233246
c_enc = opts['encode'] || false
234247
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']
237250
c_meth = opts['method'] || 'GET'
251+
c_path = opts['path_info']
238252
c_prot = opts['proto'] || 'HTTP'
239-
c_vers = opts['version'] || config['version'] || '1.1'
240253
c_qs = opts['query'] || ''
241-
c_varg = opts['vars_get'] || {}
242-
c_varp = opts['vars_post'] || {}
243-
c_head = opts['headers'] || config['headers'] || {}
244254
c_rawh = opts['raw_headers'] || config['raw_headers'] || ''
245255
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'
251259

252260
uri = set_cgi(c_cgi)
253261
qstr = c_qs
@@ -264,7 +272,7 @@ def request_cgi(opts={})
264272

265273
c_varg.each_pair do |var,val|
266274
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)
268276
qstr << '='
269277
qstr << (c_enc_p ? set_encode_uri(val) : val)
270278
end
@@ -315,12 +323,19 @@ def request_cgi(opts={})
315323
req << set_raw_headers(c_rawh)
316324
req << set_body(pstr)
317325

318-
{:string => req , :opts => opts}
326+
request = Request.new
327+
request.parse(req)
328+
request.options = opts
329+
330+
request
319331
end
320332

321333
#
322334
# Connects to the remote server if possible.
323335
#
336+
# @param t [Fixnum] Timeout
337+
# @see Rex::Socket::Tcp.create
338+
# @return [Rex::Socket::Tcp]
324339
def connect(t = -1)
325340
# If we already have a connection and we aren't pipelining, close it.
326341
if (self.conn)
@@ -360,28 +375,29 @@ def close
360375

361376
#
362377
# 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
365381
#
366382
def send_recv(req, t = -1, persist=false)
367-
opts = req[:opts]
368-
req = req[:string]
369383
res = _send_recv(req,t,persist)
370384
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)
372386
end
373387
res
374388
end
375389

376390
#
377391
# Transmit an HTTP request and receive the response
378-
# If persist is set, then the request will attempt
379-
# to reuse an existing connection.
380392
#
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]
381400
def _send_recv(req, t = -1, persist=false)
382-
if req.kind_of? Hash and req[:string]
383-
req = req[:string]
384-
end
385401
@pipeline = persist
386402
send_request(req, t)
387403
res = read_response(t)
@@ -392,12 +408,14 @@ def _send_recv(req, t = -1, persist=false)
392408
#
393409
# Send an HTTP request to the server
394410
#
411+
# @param req [Request,#to_s] The request to send
412+
# @param t (see #connect)
395413
def send_request(req, t = -1)
396414
connect(t)
397415
conn.put(req.to_s)
398416
end
399417

400-
# Validates that the client has creds
418+
# Validates that the client has creds
401419
def have_creds?
402420
!(self.username.nil?) && self.username != ''
403421
end
@@ -420,7 +438,7 @@ def send_auth(res, opts, t, persist)
420438
else
421439
opts['headers'] = { 'Authorization' => basic_auth_header(self.username,self.password)}
422440
end
423-
441+
424442
req = request_cgi(opts)
425443
res = _send_recv(req,t,persist)
426444
return res
@@ -628,7 +646,7 @@ def negotiate_auth(opts={})
628646
opts['password'] ||= self.password.to_s
629647

630648
if opts['provider'] and opts['provider'].include? 'Negotiate'
631-
provider = "Negotiate "
649+
provider = "Negotiate "
632650
else
633651
provider = 'NTLM '
634652
end

lib/rex/proto/http/request.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def initialize(uri = '/', proto = DefaultProtocol)
4848
end
4949
end
5050

51+
attr_accessor :options
52+
5153
#
5254
# Initializes an instance of an HTTP request with the supplied method, URI,
5355
# and protocol.

0 commit comments

Comments
 (0)