Skip to content

Commit

Permalink
done timeout property #24
Browse files Browse the repository at this point in the history
  • Loading branch information
MarioRuiz committed Oct 13, 2020
1 parent ac521ca commit d1cc070
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 26 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ NiceHttp.defaults = {
host: 'reqres.in',
ssl: true,
port: 443,
timeout: 15, #seconds
debug: false,
log: "./my_logs.log",
headers: {"api-key": "the api key"}
Expand Down Expand Up @@ -289,6 +290,8 @@ Also interesting keys would be: *time_elapsed_total*, *time_elapsed* and many mo

*auto_redirect*: (true or false) in case of true it will take care of the auto redirections.

*timeout*: Integer that will set a time out for the time waiting to connect to a host or waiting for a response.

## Authentication requests

All we need to do is to add to our request the correct authentication tokens, seeds, headers.
Expand Down Expand Up @@ -584,7 +587,7 @@ threads = []
end
end

t.each(&:join)
threads.each(&:join)

# log files: nice_http_0.log, nice_http_1.log... nice_http_39.log
```
Expand Down
26 changes: 21 additions & 5 deletions lib/nice_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@

######################################################
# Attributes you can access using NiceHttp.the_attribute:
# :host, :port, :ssl, :headers, :debug, :log, :log_headers, :proxy_host, :proxy_port,
# :host, :port, :ssl, :timeout, :headers, :debug, :log, :log_headers, :proxy_host, :proxy_port,
# :last_request, :last_response, :request_id, :use_mocks, :connections,
# :active, :auto_redirect, :values_for, :create_stats, :stats, :capture, :captured, :request, :requests
#
# @attr [String] host The host to be accessed
# @attr [Integer] port The port number
# @attr [Boolean] ssl If you use ssl or not
# @attr [Integer] timeout Max time to wait until connected to the host or getting a response.
# @attr [Hash] headers Contains the headers you will be using on your connection
# @attr [Boolean] debug In case true shows all the details of the communication with the host
# @attr [String] log_path The path where the logs will be stored. By default empty string.
Expand Down Expand Up @@ -71,7 +72,7 @@ def initialize(attribute, message = "")
end

class << self
attr_accessor :host, :port, :ssl, :headers, :debug, :log_path, :log, :proxy_host, :proxy_port, :log_headers,
attr_accessor :host, :port, :ssl, :timeout, :headers, :debug, :log_path, :log, :proxy_host, :proxy_port, :log_headers,
:last_request, :last_response, :request, :request_id, :use_mocks, :connections,
:active, :auto_redirect, :log_files, :values_for, :create_stats, :stats, :capture, :captured, :requests
end
Expand All @@ -89,6 +90,7 @@ def self.reset!
@host = nil
@port = 80
@ssl = false
@timeout = nil
@headers = {}
@values_for = {}
@debug = false
Expand Down Expand Up @@ -137,18 +139,19 @@ def self.inherited(subclass)
subclass.reset!
end

attr_reader :host, :port, :ssl, :debug, :log, :log_path, :proxy_host, :proxy_port, :response, :num_redirects
attr_reader :host, :port, :ssl, :timeout, :debug, :log, :log_path, :proxy_host, :proxy_port, :response, :num_redirects
attr_accessor :headers, :cookies, :use_mocks, :auto_redirect, :logger, :values_for, :log_headers

######################################################
# Change the default values for NiceHttp supplying a Hash
#
# @param par [Hash] keys: :host, :port, :ssl, :headers, :debug, :log, :log_path, :proxy_host, :proxy_port, :use_mocks, :auto_redirect, :values_for, :create_stats, :log_headers, :capture
# @param par [Hash] keys: :host, :port, :ssl, :timeout, :headers, :debug, :log, :log_path, :proxy_host, :proxy_port, :use_mocks, :auto_redirect, :values_for, :create_stats, :log_headers, :capture
######################################################
def self.defaults=(par = {})
@host = par[:host] if par.key?(:host)
@port = par[:port] if par.key?(:port)
@ssl = par[:ssl] if par.key?(:ssl)
@timeout = par[:timeout] if par.key?(:timeout)
@headers = par[:headers].dup if par.key?(:headers)
@values_for = par[:values_for].dup if par.key?(:values_for)
@debug = par[:debug] if par.key?(:debug)
Expand Down Expand Up @@ -300,6 +303,7 @@ def self.save_stats(file_name = "")
# host -- example.com. (default blank screen)
# port -- port for the connection. 80 (default)
# ssl -- true, false (default)
# timeout -- integer or nil (default)
# headers -- hash with the headers
# values_for -- hash with the values_for
# debug -- true, false (default)
Expand Down Expand Up @@ -327,6 +331,7 @@ def initialize(args = {})
@port = self.class.port
@prepath = ""
@ssl = self.class.ssl
@timeout = self.class.timeout
@headers = self.class.headers.dup
@values_for = self.class.values_for.dup
@debug = self.class.debug
Expand Down Expand Up @@ -357,6 +362,7 @@ def initialize(args = {})
@host = args[:host] if args.keys.include?(:host)
@port = args[:port] if args.keys.include?(:port)
@ssl = args[:ssl] if args.keys.include?(:ssl)
@timeout = args[:timeout] if args.keys.include?(:timeout)
@headers = args[:headers].dup if args.keys.include?(:headers)
@values_for = args[:values_for].dup if args.keys.include?(:values_for)
@debug = args[:debug] if args.keys.include?(:debug)
Expand Down Expand Up @@ -452,6 +458,7 @@ def initialize(args = {})
raise InfoMissing, :port if @port.to_s == ""
raise InfoMissing, :host if @host.to_s == ""
raise InfoMissing, :ssl unless @ssl.is_a?(TrueClass) or @ssl.is_a?(FalseClass)
raise InfoMissing, :timeout unless @timeout.is_a?(Integer) or @timeout.nil?
raise InfoMissing, :debug unless @debug.is_a?(TrueClass) or @debug.is_a?(FalseClass)
raise InfoMissing, :auto_redirect unless auto_redirect.is_a?(TrueClass) or auto_redirect.is_a?(FalseClass)
raise InfoMissing, :use_mocks unless @use_mocks.is_a?(TrueClass) or @use_mocks.is_a?(FalseClass)
Expand All @@ -465,18 +472,26 @@ def initialize(args = {})
@http.use_ssl = @ssl
@http.set_debug_output $stderr if @debug
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
unless @timeout.nil?
@http.open_timeout = @timeout
@http.read_timeout = @timeout
end
@http.start
else
@http = Net::HTTP.new(@host, @port)
@http.use_ssl = @ssl
@http.set_debug_output $stderr if @debug
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
unless @timeout.nil?
@http.open_timeout = @timeout
@http.read_timeout = @timeout
end
@http.start
end
@message_server = "(#{self.object_id}):"
log_message = "(#{self.object_id}): Http connection created. host:#{@host}, port:#{@port}, ssl:#{@ssl}, mode:#{@mode}, proxy_host: #{@proxy_host.to_s()}, proxy_port: #{@proxy_port.to_s()} "
log_message = "(#{self.object_id}): Http connection created. host:#{@host}, port:#{@port}, ssl:#{@ssl}, timeout:#{@timeout}, mode:#{@mode}, proxy_host: #{@proxy_host.to_s()}, proxy_port: #{@proxy_port.to_s()} "
@logger.info(log_message)
@message_server += " Http connection: "
Expand All @@ -499,6 +514,7 @@ def initialize(args = {})
rescue Exception => stack
puts stack
@logger.fatal stack
raise stack
end
end
Expand Down
4 changes: 2 additions & 2 deletions nice_http.gemspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = 'nice_http'
s.version = '1.8.6'
s.version = '1.8.7'
s.summary = "NiceHttp -- simplest library for accessing and testing HTTP and REST resources. Get http logs and statistics automatically. Use hashes on your requests. Access JSON even easier."
s.description = "NiceHttp -- simplest library for accessing and testing HTTP and REST resources. Get http logs and statistics automatically. Use hashes on your requests. Access JSON even easier."
s.authors = ["Mario Ruiz"]
Expand All @@ -11,7 +11,7 @@ Gem::Specification.new do |s|
s.extra_rdoc_files = ["LICENSE","README.md"]
s.homepage = 'https://github.com/MarioRuiz/nice_http'
s.license = 'MIT'
s.add_runtime_dependency 'nice_hash', '~> 1.15', '>= 1.15.6'
s.add_runtime_dependency 'nice_hash', '~> 1.17', '>= 1.17'
s.add_development_dependency 'rspec', '~> 3.8', '>= 3.8.0'
s.test_files = s.files.grep(%r{^(test|spec|features)/})
s.require_paths = ["lib"]
Expand Down
84 changes: 66 additions & 18 deletions spec/nice_http/nice_http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
klass.host = "example.com"
klass.port = 433
klass.ssl = true
klass.timeout = 20
klass.headers = {uno: "one"}
klass.debug = true
klass.log = :screen
Expand All @@ -34,6 +35,7 @@
expect(klass.host).to eq nil
expect(klass.port).to eq 80
expect(klass.ssl).to eq false
expect(klass.timeout).to eq nil
expect(klass.headers).to eq ({})
expect(klass.debug).to eq false
expect(klass.log).to eq :fix_file
Expand All @@ -58,18 +60,18 @@

describe "port" do
it "uses the class port by default" do
klass.host = "localhost"
klass.port = 8888
expect(klass.new.port).to eq 8888
klass.host = "example.com"
klass.port = 443
expect(klass.new.port).to eq 443
end
it "uses the URI default when provided a URI and the URI has one" do
klass.port = 8888
klass.port = 80
expect(klass.new("https://example.com").port).to eq 443
expect(klass.new("lol://localhost").port).to eq 8888
expect(klass.new("lol://example.com").port).to eq 80
end
it "can be provided an explicit port" do
klass.port = 8888
klass.host = "localhost"
klass.host = "example.com"
expect(klass.new(port: 443).port).to eq 443
end
it 'raises an error when it can\'t figure out the port' do
Expand All @@ -82,9 +84,9 @@

describe "host" do
it "uses the class host by default" do
klass.host = "localhost"
klass.port = 8888
expect(klass.new.host).to eq "localhost"
klass.host = "example.com"
klass.port = 80
expect(klass.new.host).to eq "example.com"
end
it "uses the URI default when provided a URI and the URI has one" do
klass.port = 8888
Expand Down Expand Up @@ -133,6 +135,47 @@
end
end

describe "timeout" do
it "uses the class timeout by default" do
klass.timeout = 15
klass.host = "example.com"
klass.port = 443
expect(klass.new.timeout).to eq 15
end
it "can be provided an explicit timeout" do
klass.port = 443
klass.host = "localhost"
klass.timeout = 30
expect(klass.new(host: "example.com", timeout: 10).timeout).to eq 10
end
it 'raises an error when it can\'t figure out the timeout' do
klass.timeout = "xxxxxxx"
klass.host = "localhost"
klass.port = 8888
klass.new rescue err = $ERROR_INFO
expect(err.attribute).to eq :timeout
expect(err.message).to match /wrong timeout/i
end
it 'returns fatal error if timeout reached when reading' do
klass.timeout = 2
http = klass.new("https://reqres.in")
resp = http.get("/api/users?delay=3")
expect(resp.code).to be_nil
expect(resp.message).to be_nil
expect(resp.fatal_error).to eq 'Net::ReadTimeout'
end
it 'returns error if not possible to connect when connecting' do
klass.timeout = 2
http = klass.new("https://reqres4s55s.in") rescue err = $ERROR_INFO
expect(err.message).to match /Failed to open TCP/i
end
it 'returns error if timeout reached when connecting' do
klass.timeout = 2
http = klass.new("http://example.com:8888") rescue err = $ERROR_INFO
expect(err.message).to match /execution expired/i
end
end

describe "debug" do
it "uses the class debug by default" do
klass.debug = true
Expand All @@ -142,13 +185,13 @@
end
it "can be provided an explicit debug" do
klass.port = 443
klass.host = "localhost"
klass.host = "example.com"
klass.debug = false
expect(klass.new(debug: true).debug).to eq true
end
it 'raises an error when it can\'t figure out the debug' do
klass.debug = nil
klass.host = "localhost"
klass.host = "example.com"
klass.port = 8888
klass.new rescue err = $ERROR_INFO
expect(err.attribute).to eq :debug
Expand All @@ -164,7 +207,7 @@
end
it "can be provided an explicit auto_redirect" do
klass.port = 443
klass.host = "localhost"
klass.host = "example.com"
klass.auto_redirect = true
expect(klass.new(auto_redirect: false).auto_redirect).to eq false
end
Expand All @@ -188,7 +231,7 @@
end
it "can be provided an explicit log_headers" do
klass.port = 443
klass.host = "localhost"
klass.host = "example.com"
klass.log_headers = :all
expect(klass.new(log_headers: :partial).log_headers).to eq :partial
end
Expand All @@ -212,7 +255,7 @@
end
it "can be provided an explicit use_mocks" do
klass.port = 443
klass.host = "localhost"
klass.host = "example.com"
klass.use_mocks = false
expect(klass.new(use_mocks: true).use_mocks).to eq true
end
Expand All @@ -236,7 +279,7 @@
end
it "can be provided an explicit headers" do
klass.port = 443
klass.host = "localhost"
klass.host = "example.com"
klass.headers = {}
expect(klass.new(headers: {example: "test"}).headers).to eq ({example: "test"})
end
Expand All @@ -260,7 +303,7 @@
end
it "can be provided an explicit values_for" do
klass.port = 443
klass.host = "localhost"
klass.host = "example.com"
klass.values_for = {}
expect(klass.new(values_for: {example: "test"}).values_for).to eq ({example: "test"})
end
Expand Down Expand Up @@ -325,7 +368,7 @@
end
it "can be provided an explicit log" do
klass.port = 443
klass.host = "localhost"
klass.host = "example.com"
klass.log = :screen
expect(klass.new(log: :file).log).to eq (:file)
end
Expand All @@ -349,7 +392,7 @@
end
it "can be provided an explicit log_path" do
klass.port = 443
klass.host = "localhost"
klass.host = "example.com"
klass.log_path = './tmp/'
expect(klass.new(log_path: './tmp/tmp/').log_path).to eq ('./tmp/tmp/')
end
Expand All @@ -365,6 +408,9 @@
specify "ssl is false" do
expect(klass.ssl).to eq false
end
specify "timeout is nil" do
expect(klass.timeout).to eq nil
end
specify "debug is false" do
expect(klass.debug).to eq false
end
Expand Down Expand Up @@ -399,6 +445,7 @@
expect { klass.port = 8888 }.to change { klass.port }.to(8888)
expect { klass.host = "localhost" }.to change { klass.host }.to("localhost")
expect { klass.ssl = true }.to change { klass.ssl }.to(true)
expect { klass.timeout = 10 }.to change { klass.timeout }.to(10)
expect { klass.debug = true }.to change { klass.debug }.to(true)
expect { klass.auto_redirect = false }.to change { klass.auto_redirect }.to(false)
expect { klass.log_headers = :partial }.to change { klass.log_headers }.to(:partial)
Expand All @@ -414,6 +461,7 @@
expect { klass.defaults = {port: 8888} }.to change { klass.port }.to(8888)
expect { klass.defaults = {host: "localhost"} }.to change { klass.host }.to("localhost")
expect { klass.defaults = {ssl: true} }.to change { klass.ssl }.to(true)
expect { klass.defaults = {timeout: 15} }.to change { klass.timeout }.to(15)
expect { klass.defaults = {debug: true} }.to change { klass.debug }.to(true)
expect { klass.defaults = {auto_redirect: false} }.to change { klass.auto_redirect }.to(false)
expect { klass.defaults = {log_headers: :none} }.to change { klass.log_headers }.to(:none)
Expand Down

0 comments on commit d1cc070

Please sign in to comment.