From b2452527d7bd732ead32dfb5859b17b352a55997 Mon Sep 17 00:00:00 2001 From: Dmitriy Ivliev Date: Tue, 12 Dec 2017 22:23:49 +0400 Subject: [PATCH 1/3] wip --- lib/sniffer.rb | 1 + lib/sniffer/adapters/excon_adapter.rb | 55 +++++++++++++++++++++ sniffer.gemspec | 1 + spec/sniffer/adapters/excon_adapter_spec.rb | 23 +++++++++ spec/spec_helper.rb | 5 ++ 5 files changed, 85 insertions(+) create mode 100644 lib/sniffer/adapters/excon_adapter.rb create mode 100644 spec/sniffer/adapters/excon_adapter_spec.rb diff --git a/lib/sniffer.rb b/lib/sniffer.rb index 298df03..464e502 100644 --- a/lib/sniffer.rb +++ b/lib/sniffer.rb @@ -64,3 +64,4 @@ def logger require_relative "sniffer/adapters/curb_adapter" require_relative "sniffer/adapters/ethon_adapter" require_relative "sniffer/adapters/eventmachine_adapter" +require_relative "sniffer/adapters/excon_adapter" diff --git a/lib/sniffer/adapters/excon_adapter.rb b/lib/sniffer/adapters/excon_adapter.rb new file mode 100644 index 0000000..ef09bf8 --- /dev/null +++ b/lib/sniffer/adapters/excon_adapter.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module Sniffer + module Adapters + module ExconAdapter + def self.included(base) + base.class_eval do + middlewares = ::Excon.defaults[:middlewares] + + middlewares << Sniffer::Adapters::ExconAdapter::Request + response_parser_index = middlewares.index(::Excon::Middleware::ResponseParser) + middlewares.insert(response_parser_index + 1, Sniffer::Adapters::ExconAdapter::Response) + end + end + + class Request < ::Excon::Middleware::Base + def request_call(params) + if Sniffer.enabled? + data_item = Sniffer::DataItem.new + data_item.request = Sniffer::DataItem::Request.new(host: params[:host], + method: params[:method], + query: params[:query], + headers: params[:headers], + body: params[:body], + port: params[:port]) + + Sniffer.store(data_item) + params[:sniffer_data_item] = data_item + end + + super(params) + end + end + + class Response < ::Excon::Middleware::Base + def response_call(params) + if Sniffer.enabled? + data_item = params.delete(:sniffer_data_item) + response = params[:response] + data_item.response = Sniffer::DataItem::Response.new(status: response[:status], + headers: response[:headers], + body: response[:body], + timing: 'fake') # TODO: think abount timing + + Sniffer.store(data_item) + end + + super(params) + end + end + end + end +end + +Excon.send(:include, Sniffer::Adapters::ExconAdapter) if defined?(::Excon) diff --git a/sniffer.gemspec b/sniffer.gemspec index 0191995..6a4fbfa 100644 --- a/sniffer.gemspec +++ b/sniffer.gemspec @@ -36,4 +36,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "ethon", ">= 0.11.0" spec.add_development_dependency "typhoeus", ">= 0.9.0" spec.add_development_dependency "em-http-request", ">= 1.1.0" + spec.add_development_dependency "excon", ">= 0.59.0" end diff --git a/spec/sniffer/adapters/excon_adapter_spec.rb b/spec/sniffer/adapters/excon_adapter_spec.rb new file mode 100644 index 0000000..ef3f378 --- /dev/null +++ b/spec/sniffer/adapters/excon_adapter_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Excon do + let(:headers) { { "accept-encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", "accept" => "*/*", "user-agent" => "Ruby", "host" => "localhost:4567" } } + let(:get_request) do + Excon.get('http://localhost:4567/?lang=ruby&author=matz', headers: headers) + end + + # let(:get_request_dynamic_params) { Excon.get("http://localhost:4567/?lang=ruby", headers: headers, params: { author: 'matz' }) } + let(:post_request) { Excon.post('http://localhost:4567/data?lang=ruby', body: "author=Matz") } + let(:post_json) { Excon.post('http://localhost:4567/json', json: { 'lang' => 'Ruby', 'author' => 'Matz' }) } + + it 'logs', enabled: true do + logger = double + Sniffer.config.logger = logger + expect(logger).to receive(:log).with(0, "{\"port\":4567,\"host\":\"localhost\",\"query\":\"/?lang=ruby&author=matz\",\"rq_accept_encoding\":\"gzip;q=1.0,deflate;q=0.6,identity;q=0.3\",\"rq_accept\":\"*/*\",\"rq_user_agent\":\"Ruby\",\"rq_host\":\"localhost:4567\",\"rq_connection\":\"close\",\"method\":\"get\",\"request_body\":\"\",\"status\":200,\"rs_content_type\":\"text/html;charset=utf-8\",\"rs_x_xss_protection\":\"1; mode=block\",\"rs_x_content_type_options\":\"nosniff\",\"rs_x_frame_options\":\"SAMEORIGIN\",\"rs_connection\":\"close\",\"rs_content_length\":\"2\",\"timing\":0.0006,\"response_body\":\"OK\"}") + get_request + end + + it_behaves_like "a sniffered", 'http' +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 16c52f3..4fe6a17 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -13,6 +13,7 @@ require "typhoeus" require "ethon" require "em-http-request" +require "excon" require "sniffer" require "pry-byebug" @@ -36,6 +37,10 @@ c.syntax = :expect end + config.before(:all) do + sleep(1) + end + config.before(:each) do Sniffer.reset! end From 2f732b9cd7d4f08bb373b1d12e1507cc1781f27d Mon Sep 17 00:00:00 2001 From: Dmitriy Ivliev Date: Wed, 13 Dec 2017 21:52:51 +0400 Subject: [PATCH 2/3] add tests --- lib/sniffer/adapters/excon_adapter.rb | 10 ++++++---- spec/sniffer/adapters/excon_adapter_spec.rb | 14 +++++++++---- spec/spec_helper.rb | 2 +- spec/yaml/excon/get_response.yaml | 22 +++++++++++++++++++++ spec/yaml/excon/get_response_dynamic.yaml | 22 +++++++++++++++++++++ spec/yaml/excon/json_response.yaml | 20 +++++++++++++++++++ spec/yaml/excon/post_response.yaml | 22 +++++++++++++++++++++ 7 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 spec/yaml/excon/get_response.yaml create mode 100644 spec/yaml/excon/get_response_dynamic.yaml create mode 100644 spec/yaml/excon/json_response.yaml create mode 100644 spec/yaml/excon/post_response.yaml diff --git a/lib/sniffer/adapters/excon_adapter.rb b/lib/sniffer/adapters/excon_adapter.rb index ef09bf8..f742944 100644 --- a/lib/sniffer/adapters/excon_adapter.rb +++ b/lib/sniffer/adapters/excon_adapter.rb @@ -7,8 +7,8 @@ def self.included(base) base.class_eval do middlewares = ::Excon.defaults[:middlewares] - middlewares << Sniffer::Adapters::ExconAdapter::Request response_parser_index = middlewares.index(::Excon::Middleware::ResponseParser) + middlewares.insert(response_parser_index - 1, Sniffer::Adapters::ExconAdapter::Request) middlewares.insert(response_parser_index + 1, Sniffer::Adapters::ExconAdapter::Response) end end @@ -17,11 +17,12 @@ class Request < ::Excon::Middleware::Base def request_call(params) if Sniffer.enabled? data_item = Sniffer::DataItem.new + data_item.request = Sniffer::DataItem::Request.new(host: params[:host], method: params[:method], - query: params[:query], + query: ::Excon::Utils.query_string(params), headers: params[:headers], - body: params[:body], + body: params[:body].to_s, port: params[:port]) Sniffer.store(data_item) @@ -40,9 +41,10 @@ def response_call(params) data_item.response = Sniffer::DataItem::Response.new(status: response[:status], headers: response[:headers], body: response[:body], - timing: 'fake') # TODO: think abount timing + timing: 'fake') # TODO: think about timing Sniffer.store(data_item) + data_item.log end super(params) diff --git a/spec/sniffer/adapters/excon_adapter_spec.rb b/spec/sniffer/adapters/excon_adapter_spec.rb index ef3f378..63851e0 100644 --- a/spec/sniffer/adapters/excon_adapter_spec.rb +++ b/spec/sniffer/adapters/excon_adapter_spec.rb @@ -8,16 +8,22 @@ Excon.get('http://localhost:4567/?lang=ruby&author=matz', headers: headers) end - # let(:get_request_dynamic_params) { Excon.get("http://localhost:4567/?lang=ruby", headers: headers, params: { author: 'matz' }) } + let(:get_request_dynamic_params) do + connection = Excon.new("http://localhost:4567/") + connection.request(method: :get, query: { lang: :ruby, author: :matz }, headers: headers) + end + let(:post_request) { Excon.post('http://localhost:4567/data?lang=ruby', body: "author=Matz") } - let(:post_json) { Excon.post('http://localhost:4567/json', json: { 'lang' => 'Ruby', 'author' => 'Matz' }) } + let(:post_json) do + Excon.post('http://localhost:4567/json', body: { 'lang' => 'Ruby', 'author' => 'Matz' }.to_json, headers: { 'content-type' => 'application/json; charset=UTF-8' }) + end it 'logs', enabled: true do logger = double Sniffer.config.logger = logger - expect(logger).to receive(:log).with(0, "{\"port\":4567,\"host\":\"localhost\",\"query\":\"/?lang=ruby&author=matz\",\"rq_accept_encoding\":\"gzip;q=1.0,deflate;q=0.6,identity;q=0.3\",\"rq_accept\":\"*/*\",\"rq_user_agent\":\"Ruby\",\"rq_host\":\"localhost:4567\",\"rq_connection\":\"close\",\"method\":\"get\",\"request_body\":\"\",\"status\":200,\"rs_content_type\":\"text/html;charset=utf-8\",\"rs_x_xss_protection\":\"1; mode=block\",\"rs_x_content_type_options\":\"nosniff\",\"rs_x_frame_options\":\"SAMEORIGIN\",\"rs_connection\":\"close\",\"rs_content_length\":\"2\",\"timing\":0.0006,\"response_body\":\"OK\"}") + expect(logger).to receive(:log).with(0, "{\"port\":4567,\"host\":\"localhost\",\"query\":\"?lang=ruby&author=matz\",\"rq_accept_encoding\":\"gzip;q=1.0,deflate;q=0.6,identity;q=0.3\",\"rq_accept\":\"*/*\",\"rq_user_agent\":\"Ruby\",\"rq_host\":\"localhost:4567\",\"method\":\"get\",\"request_body\":\"\",\"status\":200,\"rs_content_type\":\"text/html;charset=utf-8\",\"rs_x_xss_protection\":\"1; mode=block\",\"rs_x_content_type_options\":\"nosniff\",\"rs_x_frame_options\":\"SAMEORIGIN\",\"rs_content_length\":\"2\",\"timing\":0.0006,\"response_body\":\"OK\"}") get_request end - it_behaves_like "a sniffered", 'http' + it_behaves_like "a sniffered", "excon" end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4fe6a17..95f5557 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -38,7 +38,7 @@ end config.before(:all) do - sleep(1) + sleep(1) # HACK: wait a little for fake server start end config.before(:each) do diff --git a/spec/yaml/excon/get_response.yaml b/spec/yaml/excon/get_response.yaml new file mode 100644 index 0000000..3e1b4b0 --- /dev/null +++ b/spec/yaml/excon/get_response.yaml @@ -0,0 +1,22 @@ +--- +:request: + :host: "localhost" + :query: "?lang=ruby&author=matz" + :headers: + accept-encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + accept: "*/*" + user-agent: Ruby + host: "localhost:4567" + :body: "" + :method: :get + :port: 4567 +:response: + :status: 200 + :headers: + content-type: text/html;charset=utf-8 + x-xss-protection: 1; mode=block + x-content-type-options: nosniff + x-frame-options: SAMEORIGIN + content-length: '2' + :body: OK + :timing: 0.0006 diff --git a/spec/yaml/excon/get_response_dynamic.yaml b/spec/yaml/excon/get_response_dynamic.yaml new file mode 100644 index 0000000..0ffce44 --- /dev/null +++ b/spec/yaml/excon/get_response_dynamic.yaml @@ -0,0 +1,22 @@ +--- +:request: + :host: "localhost" + :query: "?author=matz&lang=ruby" + :headers: + accept-encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + accept: "*/*" + user-agent: Ruby + host: "localhost:4567" + :body: "" + :method: :get + :port: 4567 +:response: + :status: 200 + :headers: + content-type: text/html;charset=utf-8 + x-xss-protection: 1; mode=block + x-content-type-options: nosniff + x-frame-options: SAMEORIGIN + content-length: '2' + :body: OK + :timing: 0.0006 diff --git a/spec/yaml/excon/json_response.yaml b/spec/yaml/excon/json_response.yaml new file mode 100644 index 0000000..734dddb --- /dev/null +++ b/spec/yaml/excon/json_response.yaml @@ -0,0 +1,20 @@ +--- +:request: + :host: "localhost" + :port: 4567 + :query: "" + :headers: + content-type: application/json; charset=UTF-8 + host: localhost:4567 + content-length: 31 + :body: '{"lang":"Ruby","author":"Matz"}' + :method: :post + :port: 4567 +:response: + :status: 200 + :headers: + content-type: text/json + x-content-type-options: nosniff + content-length: '15' + :body: '{"status":"OK"}' + :timing: 0.0006 diff --git a/spec/yaml/excon/post_response.yaml b/spec/yaml/excon/post_response.yaml new file mode 100644 index 0000000..65acda7 --- /dev/null +++ b/spec/yaml/excon/post_response.yaml @@ -0,0 +1,22 @@ +--- +:request: + :host: "localhost" + :port: 4567 + :query: "?lang=ruby" + :headers: + user-agent: "excon/0.59.0" + host: localhost:4567 + content-length: 11 + :body: author=Matz + :method: :post + :port: 4567 +:response: + :status: 201 + :headers: + content-type: text/html;charset=utf-8 + x-xss-protection: 1; mode=block + x-content-type-options: nosniff + x-frame-options: SAMEORIGIN + content-length: '7' + :body: Created + :timing: 0.0006 From 6d3d96cd68ce95f928ef038af3a0d3db51a5d9e3 Mon Sep 17 00:00:00 2001 From: Dmitriy Ivliev Date: Wed, 13 Dec 2017 21:55:40 +0400 Subject: [PATCH 3/3] update README --- README.md | 1 + lib/sniffer/adapters/excon_adapter.rb | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c53581..0d87a6a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Sniffer supports most common HTTP accessing libraries: * [Ethon](https://github.com/typhoeus/ethon) * [Typhoeus](https://github.com/typhoeus/typhoeus) * [EM-HTTP-Request](https://github.com/igrigorik/em-http-request) +* [Excon](https://github.com/excon/excon) diff --git a/lib/sniffer/adapters/excon_adapter.rb b/lib/sniffer/adapters/excon_adapter.rb index f742944..79acc59 100644 --- a/lib/sniffer/adapters/excon_adapter.rb +++ b/lib/sniffer/adapters/excon_adapter.rb @@ -17,7 +17,6 @@ class Request < ::Excon::Middleware::Base def request_call(params) if Sniffer.enabled? data_item = Sniffer::DataItem.new - data_item.request = Sniffer::DataItem::Request.new(host: params[:host], method: params[:method], query: ::Excon::Utils.query_string(params),