Class: Rex::Proto::Http::Client
- Inherits:
-
Object
- Object
- Rex::Proto::Http::Client
- Defined in:
- lib/rex/proto/http/client.rb
Overview
Acts as a client to an HTTP server, sending requests and receiving responses.
See the RFC: www.w3.org/Protocols/rfc2616/rfc2616.html
Defined Under Namespace
Classes: UnitTest
Constant Summary collapse
- DefaultUserAgent =
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
Instance Attribute Summary collapse
-
#config ⇒ Object
The client request configuration.
-
#config_types ⇒ Object
The client request configuration classes.
-
#conn ⇒ Object
The underlying connection.
-
#context ⇒ Object
The calling context to pass to the socket.
-
#junk_pipeline ⇒ Object
When parsing the request, thunk off the first response from the server, since junk.
-
#local_host ⇒ Object
The local host of the client.
-
#local_port ⇒ Object
The local port of the client.
-
#pipeline ⇒ Object
Whether or not pipelining is in use.
-
#proxies ⇒ Object
The proxy list.
Instance Method Summary collapse
-
#close ⇒ Object
Closes the connection to the remote server.
-
#conn? ⇒ Boolean
Returns whether or not the conn is valid.
-
#connect(t = -1)) ⇒ Object
Connects to the remote server if possible.
-
#initialize(host, port = 80, context = {}, ssl = nil, ssl_version = nil, proxies = nil) ⇒ Client
constructor
Creates a new client instance.
-
#pipelining? ⇒ Boolean
Whether or not connections should be pipelined.
-
#read_response(t = -1)) ⇒ Object
Read a response from the server.
-
#request_cgi(opts = {}) ⇒ Object
Create a CGI compatible request.
-
#request_raw(opts = {}) ⇒ Object
Create an arbitrary HTTP request.
-
#send_recv(req, t = -1,, persist = false) ⇒ Object
Transmit an HTTP request and receive the response If persist is set, then the request will attempt to reuse an existing connection.
-
#send_request(req, t = -1)) ⇒ Object
Send an HTTP request to the server.
-
#set_agent_header(agent) ⇒ Object
Return the HTTP agent header.
-
#set_basic_auth_header(auth) ⇒ Object
Return the Authorization basic-auth header.
-
#set_body(data) ⇒ Object
Return the HTTP seperator and body string.
-
#set_cgi(uri) ⇒ Object
Return the cgi.
- #set_chunked_header ⇒ Object
-
#set_config(opts = {}) ⇒ Object
Set configuration options.
-
#set_connection_header(conn) ⇒ Object
Return the HTTP connection header.
-
#set_content_len_header(clen) ⇒ Object
Return the content length header.
-
#set_content_type_header(ctype) ⇒ Object
Return the content type header.
-
#set_cookie_header(cookie) ⇒ Object
Return the HTTP cookie header.
-
#set_encode_qs(qs) ⇒ Object
Return the encoded query string.
-
#set_encode_uri(uri) ⇒ Object
Return the encoded URI [‘none’,‘hex-normal’, ‘hex-all’, ‘u-normal’, ‘u-all’].
-
#set_extra_headers(headers) ⇒ Object
Return a string of formatted extra headers.
-
#set_formatted_header(var, val) ⇒ Object
Return a formatted header string.
-
#set_host_header(host = nil) ⇒ Object
Return the HTTP Host header.
-
#set_method(method) ⇒ Object
Return the HTTP method string.
-
#set_method_uri_spacer ⇒ Object
Return the spacing between the method and uri.
-
#set_path_info(path) ⇒ Object
Return the HTTP path info TODO: * Encode path information.
-
#set_raw_headers(data) ⇒ Object
Return a string of raw header data.
-
#set_uri(uri) ⇒ Object
Return the uri.
-
#set_uri_append ⇒ Object
Return the padding to place before the uri.
-
#set_uri_prepend ⇒ Object
Return the padding to place before the uri.
-
#set_uri_version_spacer ⇒ Object
Return the spacing between the uri and the version.
-
#set_version(protocol, version) ⇒ Object
Return the HTTP version string.
-
#stop ⇒ Object
Cleans up any outstanding connections and other resources.
Constructor Details
#initialize(host, port = 80, context = {}, ssl = nil, ssl_version = nil, proxies = nil) ⇒ Client
Creates a new client instance
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/rex/proto/http/client.rb', line 24 def initialize(host, port = 80, context = {}, ssl = nil, ssl_version = nil, proxies = nil) self.hostname = host self.port = port.to_i self.context = context self.ssl = ssl self.ssl_version = ssl_version self.proxies = proxies self.config = { 'read_max_data' => (1024*1024*1), 'vhost' => self.hostname, 'version' => '1.1', 'agent' => DefaultUserAgent, # # Evasion options # 'uri_encode_mode' => 'hex-normal', # hex-all, hex-random, u-normal, u-random, u-all 'uri_encode_count' => 1, # integer 'uri_full_url' => false, # bool 'pad_method_uri_count' => 1, # integer 'pad_uri_version_count' => 1, # integer 'pad_method_uri_type' => 'space', # space, tab, apache 'pad_uri_version_type' => 'space', # space, tab, apache 'method_random_valid' => false, # bool 'method_random_invalid' => false, # bool 'method_random_case' => false, # bool 'version_random_valid' => false, # bool 'version_random_invalid' => false, # bool 'version_random_case' => false, # bool 'uri_dir_self_reference' => false, # bool 'uri_dir_fake_relative' => false, # bool 'uri_use_backslashes' => false, # bool 'pad_fake_headers' => false, # bool 'pad_fake_headers_count' => 16, # integer 'pad_get_params' => false, # bool 'pad_get_params_count' => 8, # integer 'pad_post_params' => false, # bool 'pad_post_params_count' => 8, # integer 'uri_fake_end' => false, # bool 'uri_fake_params_start' => false, # bool 'header_folding' => false, # bool 'chunked_size' => 0 # integer } # This is not used right now... self.config_types = { 'uri_encode_mode' => ['hex-normal', 'hex-all', 'hex-random', 'u-normal', 'u-random', 'u-all'], 'uri_encode_count' => 'integer', 'uri_full_url' => 'bool', 'pad_method_uri_count' => 'integer', 'pad_uri_version_count' => 'integer', 'pad_method_uri_type' => ['space', 'tab', 'apache'], 'pad_uri_version_type' => ['space', 'tab', 'apache'], 'method_random_valid' => 'bool', 'method_random_invalid' => 'bool', 'method_random_case' => 'bool', 'version_random_valid' => 'bool', 'version_random_invalid' => 'bool', 'version_random_case' => 'bool', 'uri_dir_self_reference' => 'bool', 'uri_dir_fake_relative' => 'bool', 'uri_use_backslashes' => 'bool', 'pad_fake_headers' => 'bool', 'pad_fake_headers_count' => 'integer', 'pad_get_params' => 'bool', 'pad_get_params_count' => 'integer', 'pad_post_params' => 'bool', 'pad_post_params_count' => 'integer', 'uri_fake_end' => 'bool', 'uri_fake_params_start' => 'bool', 'header_folding' => 'bool', 'chunked_size' => 'integer' } end |
Instance Attribute Details
#config ⇒ Object
The client request configuration
803 804 805 |
# File 'lib/rex/proto/http/client.rb', line 803 def config @config end |
#config_types ⇒ Object
The client request configuration classes
807 808 809 |
# File 'lib/rex/proto/http/client.rb', line 807 def config_types @config_types end |
#conn ⇒ Object
The underlying connection.
823 824 825 |
# File 'lib/rex/proto/http/client.rb', line 823 def conn @conn end |
#context ⇒ Object
The calling context to pass to the socket
827 828 829 |
# File 'lib/rex/proto/http/client.rb', line 827 def context @context end |
#junk_pipeline ⇒ Object
When parsing the request, thunk off the first response from the server, since junk
835 836 837 |
# File 'lib/rex/proto/http/client.rb', line 835 def junk_pipeline @junk_pipeline end |
#local_host ⇒ Object
The local host of the client.
815 816 817 |
# File 'lib/rex/proto/http/client.rb', line 815 def local_host @local_host end |
#local_port ⇒ Object
The local port of the client.
819 820 821 |
# File 'lib/rex/proto/http/client.rb', line 819 def local_port @local_port end |
#pipeline ⇒ Object
Whether or not pipelining is in use.
811 812 813 |
# File 'lib/rex/proto/http/client.rb', line 811 def pipeline @pipeline end |
#proxies ⇒ Object
The proxy list
831 832 833 |
# File 'lib/rex/proto/http/client.rb', line 831 def proxies @proxies end |
Instance Method Details
#close ⇒ Object
Closes the connection to the remote server.
332 333 334 335 336 337 338 339 |
# File 'lib/rex/proto/http/client.rb', line 332 def close if (self.conn) self.conn.shutdown self.conn.close end self.conn = nil end |
#conn? ⇒ Boolean
Returns whether or not the conn is valid.
457 458 459 |
# File 'lib/rex/proto/http/client.rb', line 457 def conn? conn != nil end |
#connect(t = -1)) ⇒ Object
Connects to the remote server if possible.
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/rex/proto/http/client.rb', line 304 def connect(t = -1) # If we already have a connection and we aren't pipelining, close it. if (self.conn) if !pipelining? close else return self.conn end end timeout = (t.nil? or t == -1) ? 0 : t self.conn = Rex::Socket::Tcp.create( 'PeerHost' => self.hostname, 'PeerPort' => self.port.to_i, 'LocalHost' => self.local_host, 'LocalPort' => self.local_port, 'Context' => self.context, 'SSL' => self.ssl, 'SSLVersion'=> self.ssl_version, 'Proxies' => self.proxies, 'Timeout' => timeout ) end |
#pipelining? ⇒ Boolean
Whether or not connections should be pipelined.
464 465 466 |
# File 'lib/rex/proto/http/client.rb', line 464 def pipelining? pipeline end |
#read_response(t = -1)) ⇒ Object
Read a response from the server
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/rex/proto/http/client.rb', line 365 def read_response(t = -1) resp = Response.new resp.max_data = config['read_max_data'] # Wait at most t seconds for the full response to be read in. We only # do this if t was specified as a negative value indicating an infinite # wait cycle. If t were specified as nil it would indicate that no # response parsing is required. return resp if not t Timeout.timeout((t < 0) ? nil : t) do rv = nil while ( rv != Packet::ParseCode::Completed and rv != Packet::ParseCode::Error ) begin buff = conn.get_once(-1, 1) rv = resp.parse( buff || '' ) ########################################################################## # XXX: NOTE: BUG: get_once currently (as of r10042) rescues "Exception" # As such, the following rescue block will ever be reached. -jjd ########################################################################## # Handle unexpected disconnects rescue ::Errno::EPIPE, ::EOFError, ::IOError case resp.state when Packet::ParseState::ProcessingHeader resp = nil when Packet::ParseState::ProcessingBody # truncated request, good enough resp.error = :truncated end break end # This is a dirty hack for broken HTTP servers if rv == Packet::ParseCode::Completed rbody = resp.body rbufq = resp.bufq rblob = rbody.to_s + rbufq.to_s tries = 0 begin # XXX: This doesn't deal with chunked encoding or "Content-type: text/html; charset=..." while tries < 1000 and resp.headers["Content-Type"]== "text/html" and rblob !~ /<\/html>/i buff = conn.get_once(-1, 0.05) break if not buff rblob += buff tries += 1 end rescue ::Errno::EPIPE, ::EOFError, ::IOError end resp.bufq = "" resp.body = rblob end end end return resp if not resp # As a last minute hack, we check to see if we're dealing with a 100 Continue here. if resp.proto == '1.1' and resp.code == 100 # If so, our real response becaome the body, so we re-parse it. body = resp.body resp = Response.new resp.max_data = config['read_max_data'] rv = resp.parse(body) # XXX: At some point, this may benefit from processing post-completion code # as seen above. end resp end |
#request_cgi(opts = {}) ⇒ Object
Create a CGI compatible request
Options:
-
agent: User-Agent header value
-
basic_auth: Basic-Auth header value
-
connection: Connection header value
-
cookie: Cookie header value
-
ctype: Content-Type header value, default:
application/x-www-form-urlencoded
-
data: HTTP data (only useful with some methods, see rfc2616)
-
encode: URI encode the supplied URI
-
headers: HTTP headers as a hash, e.g.
{ "X-MyHeader" => "value" }
-
method: HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
-
proto: protocol, default: HTTP
-
query: raw query string
-
raw_headers: HTTP headers as a hash
-
uri: the URI to request
-
vars_get: GET variables as a hash to be translated into a query string
-
vars_post: POST variables as a hash to be translated into POST data
-
version: version of the protocol, default: 1.1
-
vhost: Host header value
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/rex/proto/http/client.rb', line 210 def request_cgi(opts={}) c_enc = opts['encode'] || false c_cgi = opts['uri'] || '/' c_body = opts['data'] || '' c_meth = opts['method'] || 'GET' c_prot = opts['proto'] || 'HTTP' c_vers = opts['version'] || config['version'] || '1.1' c_qs = opts['query'] || '' c_varg = opts['vars_get'] || {} c_varp = opts['vars_post'] || {} c_head = opts['headers'] || config['headers'] || {} c_rawh = opts['raw_headers']|| config['raw_headers'] || '' c_type = opts['ctype'] || 'application/x-www-form-urlencoded' c_ag = opts['agent'] || config['agent'] c_cook = opts['cookie'] || config['cookie'] c_host = opts['vhost'] || config['vhost'] c_conn = opts['connection'] c_path = opts['path_info'] c_auth = opts['basic_auth'] || config['basic_auth'] || '' uri = set_cgi(c_cgi) qstr = c_qs pstr = c_body if (config['pad_get_params']) 1.upto(config['pad_get_params_count'].to_i) do |i| qstr << '&' if qstr.length > 0 qstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1)) qstr << '=' qstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1)) end end c_varg.each_pair do |var,val| qstr << '&' if qstr.length > 0 qstr << set_encode_uri(var) qstr << '=' qstr << set_encode_uri(val) end if (config['pad_post_params']) 1.upto(config['pad_post_params_count'].to_i) do |i| pstr << '&' if qstr.length > 0 pstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1)) pstr << '=' pstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1)) end end c_varp.each_pair do |var,val| pstr << '&' if pstr.length > 0 pstr << set_encode_uri(var) pstr << '=' pstr << set_encode_uri(val) end req = '' req << set_method(c_meth) req << set_method_uri_spacer() req << set_uri_prepend() req << (c_enc ? set_encode_uri(uri):uri) if (qstr.length > 0) req << '?' req << qstr end req << set_path_info(c_path) req << set_uri_append() req << set_uri_version_spacer() req << set_version(c_prot, c_vers) req << set_host_header(c_host) req << set_agent_header(c_ag) if (c_auth.length > 0) req << set_basic_auth_header(c_auth) end req << (c_cook) req << set_connection_header(c_conn) req << set_extra_headers(c_head) req << set_content_type_header(c_type) req << set_content_len_header(pstr.length) req << set_chunked_header() req << set_raw_headers(c_rawh) req << set_body(pstr) req end |
#request_raw(opts = {}) ⇒ Object
Create an arbitrary HTTP request
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rex/proto/http/client.rb', line 133 def request_raw(opts={}) c_enc = opts['encode'] || false c_uri = opts['uri'] || '/' c_body = opts['data'] || '' c_meth = opts['method'] || 'GET' c_prot = opts['proto'] || 'HTTP' c_vers = opts['version'] || config['version'] || '1.1' c_qs = opts['query'] c_ag = opts['agent'] || config['agent'] c_cook = opts['cookie'] || config['cookie'] c_host = opts['vhost'] || config['vhost'] || self.hostname c_head = opts['headers'] || config['headers'] || {} c_rawh = opts['raw_headers']|| config['raw_headers'] || '' c_conn = opts['connection'] c_auth = opts['basic_auth'] || config['basic_auth'] || '' # An agent parameter was specified, but so was a header, prefer the header if c_ag and c_head.keys.map{|x| x.downcase }.include?('user-agent') c_ag = nil end uri = set_uri(c_uri) req = '' req << set_method(c_meth) req << set_method_uri_spacer() req << set_uri_prepend() req << (c_enc ? set_encode_uri(uri) : uri) if (c_qs) req << '?' req << (c_enc ? set_encode_qs(c_qs) : c_qs) end req << set_uri_append() req << set_uri_version_spacer() req << set_version(c_prot, c_vers) req << set_host_header(c_host) req << set_agent_header(c_ag) if (c_auth.length > 0) req << set_basic_auth_header(c_auth) end req << (c_cook) req << set_connection_header(c_conn) req << set_extra_headers(c_head) req << set_raw_headers(c_rawh) req << set_body(c_body) req end |
#send_recv(req, t = -1,, persist = false) ⇒ Object
Transmit an HTTP request and receive the response If persist is set, then the request will attempt to reuse an existing connection.
346 347 348 349 350 351 352 |
# File 'lib/rex/proto/http/client.rb', line 346 def send_recv(req, t = -1, persist=false) @pipeline = persist send_request(req, t) res = read_response(t) res.request = req.to_s if res res end |
#send_request(req, t = -1)) ⇒ Object
Send an HTTP request to the server
357 358 359 360 |
# File 'lib/rex/proto/http/client.rb', line 357 def send_request(req, t = -1) connect(t) conn.put(req.to_s) end |
#set_agent_header(agent) ⇒ Object
Return the HTTP agent header
714 715 716 |
# File 'lib/rex/proto/http/client.rb', line 714 def set_agent_header(agent) agent ? set_formatted_header("User-Agent", agent) : "" end |
#set_basic_auth_header(auth) ⇒ Object
Return the Authorization basic-auth header
749 750 751 |
# File 'lib/rex/proto/http/client.rb', line 749 def set_basic_auth_header(auth) auth ? set_formatted_header("Authorization", "Basic " + Rex::Text.encode_base64(auth)) : "" end |
#set_body(data) ⇒ Object
Return the HTTP seperator and body string
602 603 604 605 606 607 608 609 610 611 |
# File 'lib/rex/proto/http/client.rb', line 602 def set_body(data) return "\r\n" + data if self.config['chunked_size'] == 0 str = data.dup chunked = '' while str.size > 0 chunk = str.slice!(0,rand(self.config['chunked_size']) + 1) chunked << sprintf("%x", chunk.size) + "\r\n" + chunk + "\r\n" end "\r\n" + chunked + "0\r\n\r\n" end |
#set_cgi(uri) ⇒ Object
Return the cgi
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 |
# File 'lib/rex/proto/http/client.rb', line 526 def set_cgi(uri) if (self.config['uri_dir_self_reference']) uri.gsub!('/', '/./') end if (self.config['uri_dir_fake_relative']) buf = "" uri.split('/').each do |part| cnt = rand(8)+2 1.upto(cnt) { |idx| buf << "/" + Rex::Text.rand_text_alphanumeric(rand(32)+1) } buf << ("/.." * cnt) buf << "/" + part end uri = buf end url = uri if (self.config['uri_full_url']) url = self.ssl ? "https" : "http" url << self.config['vhost'] url << (self.port == 80) ? "" : ":#{self.port}" url << uri end url end |
#set_chunked_header ⇒ Object
775 776 777 778 |
# File 'lib/rex/proto/http/client.rb', line 775 def set_chunked_header() return "" if self.config['chunked_size'] == 0 set_formatted_header('Transfer-Encoding', 'chunked') end |
#set_config(opts = {}) ⇒ Object
Set configuration options
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 |
# File 'lib/rex/proto/http/client.rb', line 101 def set_config(opts = {}) opts.each_pair do |var,val| # Default type is string typ = self.config_types[var] || 'string' # These are enum types if(typ.class.to_s == 'Array') if not typ.include?(val) raise RuntimeError, "The specified value for #{var} is not one of the valid choices" end end # The caller should have converted these to proper ruby types, but # take care of the case where they didn't before setting the # config. if(typ == 'bool') val = (val =~ /^(t|y|1)$/i ? true : false || val === true) end if(typ == 'integer') val = val.to_i end self.config[var]=val end end |
#set_connection_header(conn) ⇒ Object
Return the HTTP connection header
728 729 730 |
# File 'lib/rex/proto/http/client.rb', line 728 def set_connection_header(conn) conn ? set_formatted_header("Connection", conn) : "" end |
#set_content_len_header(clen) ⇒ Object
Return the content length header
741 742 743 744 |
# File 'lib/rex/proto/http/client.rb', line 741 def set_content_len_header(clen) return "" if self.config['chunked_size'] > 0 set_formatted_header("Content-Length", clen) end |
#set_content_type_header(ctype) ⇒ Object
Return the content type header
735 736 737 |
# File 'lib/rex/proto/http/client.rb', line 735 def set_content_type_header(ctype) set_formatted_header("Content-Type", ctype) end |
#set_cookie_header(cookie) ⇒ Object
Return the HTTP cookie header
721 722 723 |
# File 'lib/rex/proto/http/client.rb', line 721 def () ? set_formatted_header("Cookie", ) : "" end |
#set_encode_qs(qs) ⇒ Object
Return the encoded query string
482 483 484 485 486 487 488 |
# File 'lib/rex/proto/http/client.rb', line 482 def set_encode_qs(qs) a = qs self.config['uri_encode_count'].times { a = Rex::Text.uri_encode(a, self.config['uri_encode_mode']) } return a end |
#set_encode_uri(uri) ⇒ Object
Return the encoded URI
- ‘none’,‘hex-normal’, ‘hex-all’, ‘u-normal’, ‘u-all’
471 472 473 474 475 476 477 |
# File 'lib/rex/proto/http/client.rb', line 471 def set_encode_uri(uri) a = uri self.config['uri_encode_count'].times { a = Rex::Text.uri_encode(a, self.config['uri_encode_mode']) } return a end |
#set_extra_headers(headers) ⇒ Object
Return a string of formatted extra headers
756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 |
# File 'lib/rex/proto/http/client.rb', line 756 def set_extra_headers(headers) buf = '' if (self.config['pad_fake_headers']) 1.upto(self.config['pad_fake_headers_count'].to_i) do |i| buf << set_formatted_header( Rex::Text.rand_text_alphanumeric(rand(32)+1), Rex::Text.rand_text_alphanumeric(rand(32)+1) ) end end headers.each_pair do |var,val| buf << set_formatted_header(var, val) end buf end |
#set_formatted_header(var, val) ⇒ Object
Return a formatted header string
790 791 792 793 794 795 796 |
# File 'lib/rex/proto/http/client.rb', line 790 def set_formatted_header(var, val) if (self.config['header_folding']) "#{var}:\r\n\t#{val}\r\n" else "#{var}: #{val}\r\n" end end |
#set_host_header(host = nil) ⇒ Object
Return the HTTP Host header
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 |
# File 'lib/rex/proto/http/client.rb', line 694 def set_host_header(host=nil) return "" if self.config['uri_full_url'] host ||= self.config['vhost'] # IPv6 addresses must be placed in brackets if Rex::Socket.is_ipv6?(host) host = "[#{host}]" end # The port should be appended if non-standard if not [80,443].include?(self.port) host = host + ":#{port}" end set_formatted_header("Host", host) end |
#set_method(method) ⇒ Object
Return the HTTP method string
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 |
# File 'lib/rex/proto/http/client.rb', line 560 def set_method(method) ret = method if (self.config['method_random_valid']) ret = ['GET', 'POST', 'HEAD'][rand(3)] end if (self.config['method_random_invalid']) ret = Rex::Text.rand_text_alpha(rand(20)+1) end if (self.config['method_random_case']) ret = Rex::Text.to_rand_case(ret) end ret end |
#set_method_uri_spacer ⇒ Object
Return the spacing between the method and uri
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
# File 'lib/rex/proto/http/client.rb', line 624 def set_method_uri_spacer len = self.config['pad_method_uri_count'].to_i set = " " buf = "" case self.config['pad_method_uri_type'] when 'tab' set = "\t" when 'apache' set = "\t \x0b\x0c\x0d" end while(buf.length < len) buf << set[ rand(set.length) ] end return buf end |
#set_path_info(path) ⇒ Object
Return the HTTP path info TODO:
* Encode path information
617 618 619 |
# File 'lib/rex/proto/http/client.rb', line 617 def set_path_info(path) path ? path : '' end |
#set_raw_headers(data) ⇒ Object
Return a string of raw header data
783 784 785 |
# File 'lib/rex/proto/http/client.rb', line 783 def set_raw_headers(data) data end |
#set_uri(uri) ⇒ Object
Return the uri
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
# File 'lib/rex/proto/http/client.rb', line 493 def set_uri(uri) if (self.config['uri_dir_self_reference']) uri.gsub!('/', '/./') end if (self.config['uri_dir_fake_relative']) buf = "" uri.split('/').each do |part| cnt = rand(8)+2 1.upto(cnt) { |idx| buf << "/" + Rex::Text.rand_text_alphanumeric(rand(32)+1) } buf << ("/.." * cnt) buf << "/" + part end uri = buf end if (self.config['uri_full_url']) url = self.ssl ? "https" : "http" url << self.config['vhost'] url << ((self.port == 80) ? "" : ":#{self.port}") url << uri url else uri end end |
#set_uri_append ⇒ Object
Return the padding to place before the uri
685 686 687 688 689 |
# File 'lib/rex/proto/http/client.rb', line 685 def set_uri_append # TODO: # * Support different padding types "" end |
#set_uri_prepend ⇒ Object
Return the padding to place before the uri
668 669 670 671 672 673 674 675 676 677 678 679 680 |
# File 'lib/rex/proto/http/client.rb', line 668 def set_uri_prepend prefix = "" if (self.config['uri_fake_params_start']) prefix << '/%3fa=b/../' end if (self.config['uri_fake_end']) prefix << '/%20HTTP/1.0/../../' end prefix end |
#set_uri_version_spacer ⇒ Object
Return the spacing between the uri and the version
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 |
# File 'lib/rex/proto/http/client.rb', line 646 def set_uri_version_spacer len = self.config['pad_uri_version_count'].to_i set = " " buf = "" case self.config['pad_uri_version_type'] when 'tab' set = "\t" when 'apache' set = "\t \x0b\x0c\x0d" end while(buf.length < len) buf << set[ rand(set.length) ] end return buf end |
#set_version(protocol, version) ⇒ Object
Return the HTTP version string
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 |
# File 'lib/rex/proto/http/client.rb', line 581 def set_version(protocol, version) ret = protocol + "/" + version if (self.config['version_random_valid']) ret = protocol + "/" + ['1.0', '1.1'][rand(2)] end if (self.config['version_random_invalid']) ret = Rex::Text.rand_text_alphanumeric(rand(20)+1) end if (self.config['version_random_case']) ret = Rex::Text.to_rand_case(ret) end ret << "\r\n" end |
#stop ⇒ Object
Cleans up any outstanding connections and other resources.
450 451 452 |
# File 'lib/rex/proto/http/client.rb', line 450 def stop close end |