Refactor config -> opts
Puts all the evasion stuff in the same place as regular HTTP options to make it easier to deal with.bug/bundler_fix
parent
5606db3f9c
commit
4edd46216f
|
@ -23,7 +23,6 @@ module Http
|
|||
###
|
||||
class Client
|
||||
|
||||
DefaultUserAgent = Rex::Proto::Http::ClientRequest::DefaultUserAgent
|
||||
|
||||
#
|
||||
# Creates a new client instance
|
||||
|
@ -41,8 +40,6 @@ class Client
|
|||
self.config = {
|
||||
'read_max_data' => (1024*1024*1),
|
||||
'vhost' => self.hostname,
|
||||
'version' => '1.1',
|
||||
'agent' => DefaultUserAgent,
|
||||
}.merge(Http::ClientRequest::DefaultConfig)
|
||||
|
||||
self.config_types = {
|
||||
|
|
|
@ -14,6 +14,25 @@ class ClientRequest
|
|||
|
||||
DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
|
||||
DefaultConfig = {
|
||||
#
|
||||
# Regular HTTP stuff
|
||||
#
|
||||
'agent' => DefaultUserAgent,
|
||||
'cgi' => true,
|
||||
'cookie' => nil,
|
||||
'data' => '',
|
||||
'headers' => {},
|
||||
'raw_headers' => '',
|
||||
'method' => 'GET',
|
||||
'path_info' => '',
|
||||
'port' => 80,
|
||||
'proto' => 'HTTP',
|
||||
'ssl' => false,
|
||||
'uri' => '/',
|
||||
'vars_get' => {},
|
||||
'vars_post' => {},
|
||||
'version' => '1.1',
|
||||
|
||||
#
|
||||
# Evasion options
|
||||
#
|
||||
|
@ -45,6 +64,7 @@ class ClientRequest
|
|||
'uri_fake_params_start' => false, # bool
|
||||
'header_folding' => false, # bool
|
||||
'chunked_size' => 0, # integer
|
||||
|
||||
#
|
||||
# NTLM Options
|
||||
#
|
||||
|
@ -61,68 +81,25 @@ class ClientRequest
|
|||
'DigestAuthIIS' => true
|
||||
}
|
||||
|
||||
attr_accessor :authorization
|
||||
attr_accessor :cgi
|
||||
attr_accessor :config
|
||||
attr_accessor :connection
|
||||
attr_accessor :content_type
|
||||
attr_accessor :cookie
|
||||
attr_accessor :data
|
||||
attr_accessor :headers
|
||||
attr_accessor :host
|
||||
attr_accessor :method
|
||||
attr_accessor :path
|
||||
attr_accessor :port
|
||||
attr_accessor :protocol
|
||||
attr_accessor :query
|
||||
attr_accessor :raw_headers
|
||||
attr_accessor :ssl
|
||||
attr_accessor :uri
|
||||
attr_accessor :user_agent
|
||||
attr_accessor :vars_get
|
||||
attr_accessor :vars_post
|
||||
attr_accessor :version
|
||||
|
||||
attr_reader :opts
|
||||
|
||||
def initialize(opts={})
|
||||
@cgi = (opts['cgi'].nil? ? true : opts['cgi'])
|
||||
@config = DefaultConfig.merge(opts['client_config'] || {})
|
||||
@connection = opts['connection']
|
||||
@content_type = opts['ctype']
|
||||
@cookie = opts['cookie']
|
||||
@data = opts['data'] || ""
|
||||
@headers = opts['headers'] || {}
|
||||
@host = opts['vhost']
|
||||
@method = opts['method'] || "GET"
|
||||
@path = opts['path_info']
|
||||
@port = opts['port'] || 80
|
||||
@protocol = opts['proto'] || "HTTP"
|
||||
@query = opts['query'] || ""
|
||||
@ssl = opts['ssl']
|
||||
@raw_headers = opts['raw_headers'] || ""
|
||||
@uri = opts['uri']
|
||||
@user_agent = opts['agent']
|
||||
@vars_get = opts['vars_get'] || {}
|
||||
@vars_post = opts['vars_post'] || {}
|
||||
@version = opts['version'] || "1.1"
|
||||
@opts = opts
|
||||
|
||||
@opts = DefaultConfig.merge(opts)
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
||||
# Start GET query string
|
||||
qstr = query.dup
|
||||
qstr = opts['query'] ? opts['query'].dup : ""
|
||||
|
||||
# Start POST data string
|
||||
pstr = data.dup
|
||||
pstr = opts['data'] ? opts['data'].dup : ""
|
||||
|
||||
if cgi
|
||||
if opts['cgi']
|
||||
uri_str= set_cgi
|
||||
|
||||
if (config['pad_get_params'])
|
||||
1.upto(config['pad_get_params_count'].to_i) do |i|
|
||||
if (opts['pad_get_params'])
|
||||
1.upto(opts['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 << '='
|
||||
|
@ -130,33 +107,33 @@ class ClientRequest
|
|||
end
|
||||
end
|
||||
|
||||
vars_get.each_pair do |var,val|
|
||||
opts['vars_get'].each_pair do |var,val|
|
||||
qstr << '&' if qstr.length > 0
|
||||
qstr << (config['encode_params'] ? set_encode_uri(var) : var)
|
||||
qstr << (opts['encode_params'] ? set_encode_uri(var) : var)
|
||||
qstr << '='
|
||||
qstr << (config['encode_params'] ? set_encode_uri(val) : val)
|
||||
qstr << (opts['encode_params'] ? set_encode_uri(val) : val)
|
||||
end
|
||||
|
||||
if (config['pad_post_params'])
|
||||
1.upto(config['pad_post_params_count'].to_i) do |i|
|
||||
if (opts['pad_post_params'])
|
||||
1.upto(opts['pad_post_params_count'].to_i) do |i|
|
||||
rand_var = Rex::Text.rand_text_alphanumeric(rand(32)+1)
|
||||
rand_val = Rex::Text.rand_text_alphanumeric(rand(32)+1)
|
||||
pstr << '&' if pstr.length > 0
|
||||
pstr << (config['encode_params'] ? set_encode_uri(rand_var) : rand_var)
|
||||
pstr << (opts['encode_params'] ? set_encode_uri(rand_var) : rand_var)
|
||||
pstr << '='
|
||||
pstr << (config['encode_params'] ? set_encode_uri(rand_val) : rand_val)
|
||||
pstr << (opts['encode_params'] ? set_encode_uri(rand_val) : rand_val)
|
||||
end
|
||||
end
|
||||
|
||||
vars_post.each_pair do |var,val|
|
||||
opts['vars_post'].each_pair do |var,val|
|
||||
pstr << '&' if pstr.length > 0
|
||||
pstr << (config['encode_params'] ? set_encode_uri(var) : var)
|
||||
pstr << (opts['encode_params'] ? set_encode_uri(var) : var)
|
||||
pstr << '='
|
||||
pstr << (config['encode_params'] ? set_encode_uri(val) : val)
|
||||
pstr << (opts['encode_params'] ? set_encode_uri(val) : val)
|
||||
end
|
||||
else
|
||||
uri_str = set_uri
|
||||
if config['encode']
|
||||
if opts['encode']
|
||||
qstr = set_encode_uri(qstr)
|
||||
end
|
||||
end
|
||||
|
@ -166,7 +143,7 @@ class ClientRequest
|
|||
req << set_method_uri_spacer()
|
||||
req << set_uri_prepend()
|
||||
|
||||
if config['encode']
|
||||
if opts['encode']
|
||||
req << set_encode_uri(uri_str)
|
||||
else
|
||||
req << uri_str
|
||||
|
@ -185,7 +162,7 @@ class ClientRequest
|
|||
req << set_host_header
|
||||
|
||||
# If an explicit User-Agent header is set, then use that instead of the value of user_agent
|
||||
unless headers.keys.map{|x| x.downcase }.include?('user-agent')
|
||||
unless opts['headers'].keys.map{|x| x.downcase }.include?('user-agent')
|
||||
req << set_agent_header
|
||||
end
|
||||
|
||||
|
@ -197,19 +174,19 @@ class ClientRequest
|
|||
req << set_content_type_header
|
||||
req << set_content_len_header(pstr.length)
|
||||
req << set_chunked_header()
|
||||
req << raw_headers
|
||||
req << opts['raw_headers']
|
||||
req << set_body(pstr)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def set_uri
|
||||
uri_str = uri.dup
|
||||
if (config['uri_dir_self_reference'])
|
||||
uri_str = opts['uri'].dup
|
||||
if (opts['uri_dir_self_reference'])
|
||||
uri_str.gsub!('/', '/./')
|
||||
end
|
||||
|
||||
if (config['uri_dir_fake_relative'])
|
||||
if (opts['uri_dir_fake_relative'])
|
||||
buf = ""
|
||||
uri_str.split('/').each do |part|
|
||||
cnt = rand(8)+2
|
||||
|
@ -222,10 +199,10 @@ class ClientRequest
|
|||
uri_str = buf
|
||||
end
|
||||
|
||||
if (config['uri_full_url'])
|
||||
url = self.ssl ? "https://" : "http://"
|
||||
url << self.config['vhost']
|
||||
url << ((self.port == 80) ? "" : ":#{self.port}")
|
||||
if (opts['uri_full_url'])
|
||||
url = opts['ssl'] ? "https://" : "http://"
|
||||
url << opts['vhost']
|
||||
url << ((opts['port'] == 80) ? "" : ":#{opts['port']}")
|
||||
url << uri_str
|
||||
url
|
||||
else
|
||||
|
@ -234,12 +211,12 @@ class ClientRequest
|
|||
end
|
||||
|
||||
def set_cgi
|
||||
uri_str = uri.dup
|
||||
if (config['uri_dir_self_reference'])
|
||||
uri_str = opts['uri'].dup
|
||||
if (opts['uri_dir_self_reference'])
|
||||
uri_str.gsub!('/', '/./')
|
||||
end
|
||||
|
||||
if (config['uri_dir_fake_relative'])
|
||||
if (opts['uri_dir_fake_relative'])
|
||||
buf = ""
|
||||
uri_str.split('/').each do |part|
|
||||
cnt = rand(8)+2
|
||||
|
@ -254,10 +231,10 @@ class ClientRequest
|
|||
|
||||
url = uri_str
|
||||
|
||||
if (config['uri_full_url'])
|
||||
url = self.ssl ? "https" : "http"
|
||||
url << self.config['vhost']
|
||||
url << (self.port == 80) ? "" : ":#{self.port}"
|
||||
if (opts['uri_full_url'])
|
||||
url = opts['ssl'] ? "https" : "http"
|
||||
url << opts['vhost']
|
||||
url << (opts['port'] == 80) ? "" : ":#{opts['port']}"
|
||||
url << uri_str
|
||||
end
|
||||
|
||||
|
@ -266,24 +243,24 @@ class ClientRequest
|
|||
|
||||
def set_encode_uri(str)
|
||||
a = str.dup
|
||||
config['uri_encode_count'].times {
|
||||
a = Rex::Text.uri_encode(a, config['uri_encode_mode'])
|
||||
opts['uri_encode_count'].times {
|
||||
a = Rex::Text.uri_encode(a, opts['uri_encode_mode'])
|
||||
}
|
||||
return a
|
||||
end
|
||||
|
||||
def set_method
|
||||
ret = method.dup
|
||||
ret = opts['method'].dup
|
||||
|
||||
if (config['method_random_valid'])
|
||||
if (opts['method_random_valid'])
|
||||
ret = ['GET', 'POST', 'HEAD'][rand(3)]
|
||||
end
|
||||
|
||||
if (config['method_random_invalid'])
|
||||
if (opts['method_random_invalid'])
|
||||
ret = Rex::Text.rand_text_alpha(rand(20)+1)
|
||||
end
|
||||
|
||||
if (config['method_random_case'])
|
||||
if (opts['method_random_case'])
|
||||
ret = Rex::Text.to_rand_case(ret)
|
||||
end
|
||||
|
||||
|
@ -291,11 +268,11 @@ class ClientRequest
|
|||
end
|
||||
|
||||
def set_method_uri_spacer
|
||||
len = config['pad_method_uri_count'].to_i
|
||||
len = opts['pad_method_uri_count'].to_i
|
||||
set = " "
|
||||
buf = ""
|
||||
|
||||
case config['pad_method_uri_type']
|
||||
case opts['pad_method_uri_type']
|
||||
when 'tab'
|
||||
set = "\t"
|
||||
when 'apache'
|
||||
|
@ -315,11 +292,11 @@ class ClientRequest
|
|||
def set_uri_prepend
|
||||
prefix = ""
|
||||
|
||||
if (config['uri_fake_params_start'])
|
||||
if (opts['uri_fake_params_start'])
|
||||
prefix << '/%3fa=b/../'
|
||||
end
|
||||
|
||||
if (config['uri_fake_end'])
|
||||
if (opts['uri_fake_end'])
|
||||
prefix << '/%20HTTP/1.0/../../'
|
||||
end
|
||||
|
||||
|
@ -331,7 +308,7 @@ class ClientRequest
|
|||
# TODO:
|
||||
# * Encode path information
|
||||
def set_path_info
|
||||
path ? path : ''
|
||||
opts['path_info'] ? opts['path_info'] : ''
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -347,11 +324,11 @@ class ClientRequest
|
|||
# Return the spacing between the uri and the version
|
||||
#
|
||||
def set_uri_version_spacer
|
||||
len = config['pad_uri_version_count'].to_i
|
||||
len = opts['pad_uri_version_count'].to_i
|
||||
set = " "
|
||||
buf = ""
|
||||
|
||||
case config['pad_uri_version_type']
|
||||
case opts['pad_uri_version_type']
|
||||
when 'tab'
|
||||
set = "\t"
|
||||
when 'apache'
|
||||
|
@ -369,17 +346,17 @@ class ClientRequest
|
|||
# Return the HTTP version string
|
||||
#
|
||||
def set_version
|
||||
ret = protocol + "/" + version
|
||||
ret = opts['proto'] + "/" + opts['version']
|
||||
|
||||
if (config['version_random_valid'])
|
||||
ret = protocol + "/" + ['1.0', '1.1'][rand(2)]
|
||||
if (opts['version_random_valid'])
|
||||
ret = opts['proto'] + "/" + ['1.0', '1.1'][rand(2)]
|
||||
end
|
||||
|
||||
if (config['version_random_invalid'])
|
||||
if (opts['version_random_invalid'])
|
||||
ret = Rex::Text.rand_text_alphanumeric(rand(20)+1)
|
||||
end
|
||||
|
||||
if (config['version_random_case'])
|
||||
if (opts['version_random_case'])
|
||||
ret = Rex::Text.to_rand_case(ret)
|
||||
end
|
||||
|
||||
|
@ -390,7 +367,7 @@ class ClientRequest
|
|||
# Return a formatted header string
|
||||
#
|
||||
def set_formatted_header(var, val)
|
||||
if (self.config['header_folding'])
|
||||
if (self.opts['header_folding'])
|
||||
"#{var}:\r\n\t#{val}\r\n"
|
||||
else
|
||||
"#{var}: #{val}\r\n"
|
||||
|
@ -401,38 +378,38 @@ class ClientRequest
|
|||
# Return the HTTP agent header
|
||||
#
|
||||
def set_agent_header
|
||||
user_agent ? set_formatted_header("User-Agent", user_agent) : ""
|
||||
opts['agent'] ? set_formatted_header("User-Agent", opts['agent']) : ""
|
||||
end
|
||||
|
||||
def set_auth_header
|
||||
authorization ? set_formatted_header("Authorization", authorization) : ""
|
||||
opts['authorization'] ? set_formatted_header("Authorization", opts['authorization']) : ""
|
||||
end
|
||||
|
||||
#
|
||||
# Return the HTTP cookie header
|
||||
#
|
||||
def set_cookie_header
|
||||
cookie ? set_formatted_header("Cookie", cookie) : ""
|
||||
opts['cookie'] ? set_formatted_header("Cookie", opts['cookie']) : ""
|
||||
end
|
||||
|
||||
#
|
||||
# Return the HTTP connection header
|
||||
#
|
||||
def set_connection_header
|
||||
connection ? set_formatted_header("Connection", connection) : ""
|
||||
opts['connection'] ? set_formatted_header("Connection", opts['connection']) : ""
|
||||
end
|
||||
|
||||
#
|
||||
# Return the content type header
|
||||
#
|
||||
def set_content_type_header
|
||||
set_formatted_header("Content-Type", content_type)
|
||||
opts['ctype'] ? set_formatted_header("Content-Type", opts['ctype']) : ""
|
||||
end
|
||||
|
||||
#
|
||||
# Return the content length header
|
||||
def set_content_len_header(clen)
|
||||
return "" if config['chunked_size'] > 0
|
||||
return "" if opts['chunked_size'] > 0
|
||||
set_formatted_header("Content-Length", clen)
|
||||
end
|
||||
|
||||
|
@ -440,8 +417,8 @@ class ClientRequest
|
|||
# Return the HTTP Host header
|
||||
#
|
||||
def set_host_header
|
||||
return "" if config['uri_full_url']
|
||||
host ||= config['vhost']
|
||||
return "" if opts['uri_full_url']
|
||||
host ||= opts['vhost']
|
||||
|
||||
# IPv6 addresses must be placed in brackets
|
||||
if Rex::Socket.is_ipv6?(host)
|
||||
|
@ -449,8 +426,8 @@ class ClientRequest
|
|||
end
|
||||
|
||||
# The port should be appended if non-standard
|
||||
if not [80,443].include?(port)
|
||||
host = host + ":#{port}"
|
||||
if not [80,443].include?(opts['port'])
|
||||
host = host + ":#{opts['port']}"
|
||||
end
|
||||
|
||||
set_formatted_header("Host", host)
|
||||
|
@ -462,8 +439,8 @@ class ClientRequest
|
|||
def set_extra_headers
|
||||
buf = ''
|
||||
|
||||
if (config['pad_fake_headers'])
|
||||
1.upto(config['pad_fake_headers_count'].to_i) do |i|
|
||||
if (opts['pad_fake_headers'])
|
||||
1.upto(opts['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)
|
||||
|
@ -471,7 +448,7 @@ class ClientRequest
|
|||
end
|
||||
end
|
||||
|
||||
headers.each_pair do |var,val|
|
||||
opts['headers'].each_pair do |var,val|
|
||||
buf << set_formatted_header(var, val)
|
||||
end
|
||||
|
||||
|
@ -479,7 +456,7 @@ class ClientRequest
|
|||
end
|
||||
|
||||
def set_chunked_header
|
||||
return "" if config['chunked_size'] == 0
|
||||
return "" if opts['chunked_size'] == 0
|
||||
set_formatted_header('Transfer-Encoding', 'chunked')
|
||||
end
|
||||
|
||||
|
@ -487,11 +464,11 @@ class ClientRequest
|
|||
# Return the HTTP seperator and body string
|
||||
#
|
||||
def set_body(bdata)
|
||||
return "\r\n" + bdata if config['chunked_size'] == 0
|
||||
return "\r\n" + bdata if opts['chunked_size'] == 0
|
||||
str = bdata.dup
|
||||
chunked = ''
|
||||
while str.size > 0
|
||||
chunk = str.slice!(0,rand(config['chunked_size']) + 1)
|
||||
chunk = str.slice!(0,rand(opts['chunked_size']) + 1)
|
||||
chunked << sprintf("%x", chunk.size) + "\r\n" + chunk + "\r\n"
|
||||
end
|
||||
"\r\n" + chunked + "0\r\n\r\n"
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'rex/proto/http/client_request'
|
|||
|
||||
shared_context "with 'uri_dir_self_reference'" do
|
||||
before(:all) do
|
||||
client_request.config['uri_dir_self_reference'] = true
|
||||
client_request.opts['uri_dir_self_reference'] = true
|
||||
end
|
||||
|
||||
it "should return the unmodified uri" do
|
||||
|
@ -14,9 +14,9 @@ end
|
|||
|
||||
shared_context "with no evasions" do
|
||||
before(:all) do
|
||||
client_request.config['uri_dir_self_reference'] = false
|
||||
client_request.config['uri_fake_params_start'] = false
|
||||
client_request.config['uri_full_url'] = false
|
||||
client_request.opts['uri_dir_self_reference'] = false
|
||||
client_request.opts['uri_fake_params_start'] = false
|
||||
client_request.opts['uri_full_url'] = false
|
||||
end
|
||||
|
||||
it "should return the unmodified uri" do
|
||||
|
@ -27,11 +27,11 @@ end
|
|||
shared_context "with 'uri_full_url'" do
|
||||
|
||||
before(:all) do
|
||||
client_request.config['uri_full_url'] = true
|
||||
client_request.opts['uri_full_url'] = true
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
client_request.config['vhost'] = host
|
||||
client_request.opts['vhost'] = host
|
||||
end
|
||||
|
||||
context "with ipv4 host" do
|
||||
|
@ -43,7 +43,7 @@ shared_context "with 'uri_full_url'" do
|
|||
context "with ipv6 host" do
|
||||
let(:host) { '2001:DB8::1' }
|
||||
#before(:each) do
|
||||
# client_request.config['vhost'] = "[#{host}]"
|
||||
# client_request.opts['vhost'] = "[#{host}]"
|
||||
#end
|
||||
|
||||
it_behaves_like "uri_full_url"
|
||||
|
@ -83,9 +83,7 @@ describe Rex::Proto::Http::ClientRequest do
|
|||
[ "with reasonable default options",
|
||||
default_options.merge({
|
||||
'agent' => "Mozilla/4.0 (compatible; Metasploit RSPEC)",
|
||||
# Yes, vhost is in the config. There is no godly reason why this
|
||||
# should be so.
|
||||
'client_config' => { 'vhost' => 'www.example.com', },
|
||||
'vhost' => 'www.example.com',
|
||||
}),
|
||||
{
|
||||
:set_cgi => { :result => "/" },
|
||||
|
@ -106,7 +104,7 @@ describe Rex::Proto::Http::ClientRequest do
|
|||
[ "with header folding",
|
||||
default_options.merge({
|
||||
'agent' => "Mozilla/4.0 (compatible; Metasploit RSPEC)",
|
||||
'client_config' => { 'header_folding' => true, }
|
||||
'header_folding' => true,
|
||||
}),
|
||||
{
|
||||
:set_uri => { :result => "/" },
|
||||
|
@ -124,7 +122,7 @@ describe Rex::Proto::Http::ClientRequest do
|
|||
|
||||
[ "with ipv6 host",
|
||||
default_options.merge({
|
||||
'client_config' => { 'vhost' => "2001:DB8::1" },
|
||||
'vhost' => "2001:DB8::1",
|
||||
}),
|
||||
{
|
||||
:set_host_header => { :result => "Host: [2001:DB8::1]\r\n" },
|
||||
|
@ -134,7 +132,7 @@ describe Rex::Proto::Http::ClientRequest do
|
|||
[ "with ipv6 host and non-default port",
|
||||
default_options.merge({
|
||||
'port' => 1234,
|
||||
'client_config' => { 'vhost' => "2001:DB8::1" },
|
||||
'vhost' => "2001:DB8::1",
|
||||
}),
|
||||
{
|
||||
:set_host_header => { :result => "Host: [2001:DB8::1]:1234\r\n" },
|
||||
|
@ -162,11 +160,9 @@ describe Rex::Proto::Http::ClientRequest do
|
|||
context "with GET paramaters" do
|
||||
subject(:client_request) {
|
||||
options_with_params = default_options.merge({
|
||||
'client_config' => {
|
||||
'uri_encode_mode' => encode_mode,
|
||||
'encode_params' => encode_params,
|
||||
'encode' => false,
|
||||
},
|
||||
'vars_get' => vars_get,
|
||||
})
|
||||
Rex::Proto::Http::ClientRequest.new(options_with_params)
|
||||
|
|
|
@ -56,8 +56,6 @@ describe Rex::Proto::Http::Client do
|
|||
req = cli.request_cgi
|
||||
req.should be_a_kind_of Rex::Proto::Http::ClientRequest
|
||||
|
||||
req.port.should == 80
|
||||
req.ssl.should be_false
|
||||
end
|
||||
|
||||
it "should attempt to connect to a server" do
|
||||
|
|
Loading…
Reference in New Issue