diff --git a/.yardopts b/.yardopts index a64d594..2c45e19 100644 --- a/.yardopts +++ b/.yardopts @@ -2,8 +2,9 @@ --title 'nice_http - NiceHttp -- simplest library for accessing and testing HTTP and REST resources.' --charset utf-8 --markup markdown -'lib/nice_http.rb' -'lib/nice_http/http_methods.rb' -'lib/nice_http/utils.rb' -'*.md' -'LICENSE' \ No newline at end of file +- +lib/nice_http.rb +lib/nice_http/http_methods.rb +lib/nice_http/utils.rb + +LICENSE \ No newline at end of file diff --git a/README.md b/README.md index abb2b25..ad214cc 100644 --- a/README.md +++ b/README.md @@ -380,6 +380,11 @@ Other values you can supply: * :file_run, will generate a log file with the name where the object was created and extension .log, fex: myfile.rb.log * String, the path and file name where the logs will be stored. +In case you want to hide the header values from the requests on the logs use the option `log_headers`. Possible values: +* :all, (default), will log all header values. +* :none, won't log any value of the headers. +* :partial, will log only the last 10 characters of the header values. + Example of logs: ``` I, [2019-03-22T18:38:58.518964 #29412] INFO -- : (47266856647720): Http connection created. host:reqres.in, port:443, ssl:true, mode:, proxy_host: , proxy_port: diff --git a/lib/nice_http.rb b/lib/nice_http.rb index f9d6401..fae0419 100644 --- a/lib/nice_http.rb +++ b/lib/nice_http.rb @@ -7,7 +7,7 @@ ###################################################### # Attributes you can access using NiceHttp.the_attribute: -# :host, :port, :ssl, :headers, :debug, :log, :proxy_host, :proxy_port, +# :host, :port, :ssl, :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 # @@ -24,6 +24,7 @@ # :file, will be generated a log file with name: nice_http_YY-mm-dd-HHMMSS.log. # :file_run, will generate a log file with the name where the object was created and extension .log, fex: myfile.rb.log # String the path and file name where the logs will be stored. +# @attr [Symbol] log_headers. :all, :partial, :none (default :all) If :all will log all the headers. If :partial will log the last 10 characters. If :none no headers. # @attr [String] proxy_host the proxy host to be used # @attr [Integer] proxy_port the proxy port to be used # @attr [String] last_request The last request with all the content sent @@ -66,7 +67,7 @@ def initialize(attribute, message = "") end class << self - attr_accessor :host, :port, :ssl, :headers, :debug, :log_path, :log, :proxy_host, :proxy_port, + attr_accessor :host, :port, :ssl, :headers, :debug, :log_path, :log, :proxy_host, :proxy_port, :log_headers, :last_request, :last_response, :request_id, :use_mocks, :connections, :active, :auto_redirect, :log_files, :values_for, :create_stats, :stats end @@ -89,6 +90,7 @@ def self.reset! @debug = false @log = :fix_file @log_path = '' + @log_headers = :all @proxy_host = nil @proxy_port = nil @last_request = nil @@ -128,12 +130,12 @@ def self.inherited(subclass) end attr_reader :host, :port, :ssl, :debug, :log, :log_path, :proxy_host, :proxy_port, :response, :num_redirects - attr_accessor :headers, :cookies, :use_mocks, :auto_redirect, :logger, :values_for + 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 + # @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 ###################################################### def self.defaults=(par = {}) @host = par[:host] if par.key?(:host) @@ -144,6 +146,7 @@ def self.defaults=(par = {}) @debug = par[:debug] if par.key?(:debug) @log_path = par[:log_path] if par.key?(:log_path) @log = par[:log] if par.key?(:log) + @log_headers = par[:log_headers] if par.key?(:log_headers) @proxy_host = par[:proxy_host] if par.key?(:proxy_host) @proxy_port = par[:proxy_port] if par.key?(:proxy_port) @use_mocks = par[:use_mocks] if par.key?(:use_mocks) @@ -293,6 +296,7 @@ def self.save_stats(file_name = "") # debug -- true, false (default) # log_path -- string with path for the logs, empty string (default) # log -- :no, :screen, :file, :fix_file (default). + # log_headers -- :all, :none, :partial (default). # A string with a path can be supplied. # If :fix_file: nice_http.log # In case :file it will be generated a log file with name: nice_http_YY-mm-dd-HHMMSS.log @@ -319,6 +323,7 @@ def initialize(args = {}) @debug = self.class.debug @log = self.class.log @log_path = self.class.log_path + @log_headers = self.class.log_headers @proxy_host = self.class.proxy_host @proxy_port = self.class.proxy_port @use_mocks = self.class.use_mocks @@ -347,6 +352,7 @@ def initialize(args = {}) @debug = args[:debug] if args.keys.include?(:debug) @log = args[:log] if args.keys.include?(:log) @log_path = args[:log_path] if args.keys.include?(:log_path) + @log_headers = args[:log_headers] if args.keys.include?(:log_headers) @proxy_host = args[:proxy_host] if args.keys.include?(:proxy_host) @proxy_port = args[:proxy_port] if args.keys.include?(:proxy_port) @use_mocks = args[:use_mocks] if args.keys.include?(:use_mocks) @@ -433,7 +439,6 @@ def initialize(args = {}) @ssl = true if !uri.scheme.nil? && (uri.scheme == "https") @prepath = uri.path unless uri.path == "/" end - 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) @@ -442,6 +447,7 @@ def initialize(args = {}) raise InfoMissing, :use_mocks unless @use_mocks.is_a?(TrueClass) or @use_mocks.is_a?(FalseClass) raise InfoMissing, :headers unless @headers.is_a?(Hash) raise InfoMissing, :values_for unless @values_for.is_a?(Hash) + raise InfoMissing, :log_headers unless [:all, :none, :partial].include?(@log_headers) begin if !@proxy_host.nil? && !@proxy_port.nil? diff --git a/lib/nice_http/manage_request.rb b/lib/nice_http/manage_request.rb index af5f29f..3a6eb42 100644 --- a/lib/nice_http/manage_request.rb +++ b/lib/nice_http/manage_request.rb @@ -196,7 +196,23 @@ def manage_request(*arguments) end headers_ts = "" - headers_t.each { |key, val| headers_ts += key.to_s + ":" + val.to_s() + ", " } + + if @log_headers == :none + @logger.info "No header values since option log_headers is set to :none" + headers_t.each { |key, val| headers_ts += key.to_s + ":" + "''" + ", " } + elsif @log_headers == :partial + @logger.info "Just the last 10 characters on header values since option log_headers is set to :partial" + headers_t.each { |key, val| + if val.to_s.size>10 + headers_ts += key.to_s + ": ..." + (val.to_s[-10..-1] || val.to_s) + ", " + else + headers_ts += key.to_s + ":" + (val.to_s[-10..-1] || val.to_s) + ", " + end + } + else + headers_t.each { |key, val| headers_ts += key.to_s + ":" + val.to_s() + ", " } + end + message = "\n\n#{"- " * 25}\n" if arguments.size == 1 and arguments[0].kind_of?(Hash) and arguments[0].key?(:name) message += "#{method_s.upcase} Request: #{arguments[0][:name]}" diff --git a/nice_http.gemspec b/nice_http.gemspec index 1a8c3a3..f880865 100644 --- a/nice_http.gemspec +++ b/nice_http.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'nice_http' - s.version = '1.7.19' + s.version = '1.7.20' 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"] @@ -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.14', '>= 1.14.0' + s.add_runtime_dependency 'nice_hash', '~> 1.15', '>= 1.15.3' s.add_development_dependency 'rspec', '~> 3.8', '>= 3.8.0' s.test_files = s.files.grep(%r{^(test|spec|features)/}) s.require_paths = ["lib"] diff --git a/spec/nice_http/logs_spec.rb b/spec/nice_http/logs_spec.rb index 4ee4a8c..cf27d36 100644 --- a/spec/nice_http/logs_spec.rb +++ b/spec/nice_http/logs_spec.rb @@ -145,5 +145,39 @@ content = File.read("./nice_http.log") expect(content).to match /It was not possible to close the HTTP connection, already closed/ end - end + + it 'logs all the headers if log_headers is :all' do + http = klass.new("http://example.com") + http.log_headers = :all + http.headers = {uno: 'abcdefghijklmnopqrstuvwxyz', dos: '2', tres: '00000000001234567890'} + http.get('/') + content = File.read("./nice_http.log") + expected = "headers: {uno:abcdefghijklmnopqrstuvwxyz, dos:2, tres:00000000001234567890," + expect(content).to match(expected) + end + + it 'doesn\'t log any headers if log_headers is :none' do + http = klass.new("http://example.com") + http.log_headers = :none + http.headers = {uno: 'abcdefghijklmnopqrstuvwxyz', dos: '2', tres: '00000000001234567890'} + http.get('/') + content = File.read("./nice_http.log") + expected = "headers: {uno:'', dos:'', tres:''," + expect(content).to match(expected) + expect(content).to match('No header values since option log_headers is set to :none') + end + + it 'logs only 10 last chars of headers if log_headers is :partial' do + http = klass.new("http://example.com") + http.log_headers = :partial + http.headers = {uno: 'abcdefghijklmnopqrstuvwxyz', dos: '2', tres: '00000000001234567890'} + http.get('/') + content = File.read("./nice_http.log") + expected = "{uno: ...qrstuvwxyz, dos:2, tres: ...1234567890" + expect(content).to match(expected) + expect(content).to match('Just the last 10 characters on header values since option log_headers is set to :partial') + end + + + end end \ No newline at end of file diff --git a/spec/nice_http/nice_http_spec.rb b/spec/nice_http/nice_http_spec.rb index 0fec38e..f239fe1 100644 --- a/spec/nice_http/nice_http_spec.rb +++ b/spec/nice_http/nice_http_spec.rb @@ -22,6 +22,7 @@ klass.connections = [1, 1] klass.active = 1 klass.auto_redirect = false + klass.log_headers = :none klass.values_for = {one: 1} klass.create_stats = true klass.stats = {one: 1} @@ -44,6 +45,7 @@ expect(klass.connections).to eq [] expect(klass.active).to eq 0 expect(klass.auto_redirect).to eq true + expect(klass.log_headers).to eq :all expect(klass.values_for).to eq ({}) expect(klass.create_stats).to eq false expect(klass.stats[:all][:num_requests]).to eq 0 @@ -160,7 +162,7 @@ klass.port = 443 klass.host = "localhost" klass.auto_redirect = true - expect(klass.new(auto_redirect: false).debug).to eq false + expect(klass.new(auto_redirect: false).auto_redirect).to eq false end it 'raises an error when it can\'t figure out the auto_redirect' do klass.auto_redirect = nil @@ -173,6 +175,30 @@ end end + describe "log_headers" do + it "uses the class log_headers by default" do + klass.host = "example.com" + klass.port = 443 + klass.log_headers = :none + expect(klass.new.log_headers).to eq :none + end + it "can be provided an explicit log_headers" do + klass.port = 443 + klass.host = "localhost" + klass.log_headers = :all + expect(klass.new(log_headers: :partial).log_headers).to eq :partial + end + it 'raises an error when it can\'t figure out the log_headers' do + klass.log_headers = nil + klass.host = "example.com" + klass.port = 443 + klass.new rescue err = $ERROR_INFO + expect(err.class).to eq NiceHttp::InfoMissing + expect(err.attribute).to eq :log_headers + expect(err.message).to match(/wrong log_headers/i) + end + end + describe "use_mocks" do it "uses the class use_mocks by default" do klass.use_mocks = true @@ -186,7 +212,7 @@ klass.use_mocks = false expect(klass.new(use_mocks: true).use_mocks).to eq true end - it 'raises an error when it can\'t figure out the auto_redirect' do + it 'raises an error when it can\'t figure out the use_mocks' do klass.use_mocks = nil klass.host = "example.com" klass.port = 443 @@ -325,7 +351,6 @@ end end - describe "class defaults" do specify "port is 80" do expect(klass.port).to eq 80 @@ -342,6 +367,9 @@ specify "auto_redirect is true" do expect(klass.auto_redirect).to eq true end + specify "log_headers is :all" do + expect(klass.log_headers).to eq :all + end specify "use_mocks is false" do expect(klass.use_mocks).to eq false end @@ -366,6 +394,7 @@ expect { klass.ssl = true }.to change { klass.ssl }.to(true) 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) expect { klass.use_mocks = true }.to change { klass.use_mocks }.to(true) expect { klass.headers = {example: "test"} }.to change { klass.headers }.to({example: "test"}) expect { klass.values_for = {example: "test"} }.to change { klass.values_for }.to({example: "test"}) @@ -379,6 +408,7 @@ expect { klass.defaults = {ssl: true} }.to change { klass.ssl }.to(true) 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) expect { klass.defaults = {use_mocks: true} }.to change { klass.use_mocks }.to(true) expect { klass.defaults = {headers: {example: "test"}} }.to change { klass.headers }.to({example: "test"}) expect { klass.defaults = {values_for: {example: "test"}} }.to change { klass.values_for }.to({example: "test"})