Repository: martinbtt/net-http-spy Branch: master Commit: 73c30b3b2855 Files: 15 Total size: 12.3 KB Directory structure: gitextract__b7ldh8x/ ├── Rakefile ├── VERSION ├── examples/ │ ├── fogbugz.rb │ ├── google.rb │ ├── twitter-calltrace.rb │ ├── twitter-customlog.rb │ ├── twitter-simple.rb │ ├── twitter-verbose.rb │ └── twitter-withbody.rb ├── lib/ │ └── net-http-spy.rb ├── net-http-spy.gemspec ├── readme.markdown └── spec/ ├── spec.opts ├── spec_helper.rb └── spy_spec.rb ================================================ FILE CONTENTS ================================================ ================================================ FILE: Rakefile ================================================ require "rubygems" require "rake/gempackagetask" require "rake/rdoctask" begin require 'jeweler' Jeweler::Tasks.new do |gemspec| gemspec.name = "net-http-spy" gemspec.summary = "Ever wondered what HTTP requests the Ruby gem you are using to connect to a third party API is making? Use HTTP Spy to see what is going on behind the scenes." gemspec.email = "martin@beyondthetype.com" gemspec.homepage = "http://github.com/martinbtt/net-http-spy" gemspec.description = "Ever wondered what HTTP requests the Ruby gem you are using to connect to a third party API is making? Use HTTP Spy to see what is going on behind the scenes." gemspec.authors = ["Martin Sadler"] gemspec.files.include Dir["examples/*.rb"] + ["readme.markdown"] end rescue LoadError puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com" end task :default => :spec require "spec" require "spec/rake/spectask" Spec::Rake::SpecTask.new do |t| t.spec_opts = %w(--format specdoc --colour) t.libs = ["spec"] end # Generate documentation Rake::RDocTask.new do |rd| rd.main = "readme.markdown" rd.rdoc_files.include("readme.markdown", "lib/**/*.rb") rd.rdoc_dir = "rdoc" end desc 'Clear out RDoc and generated packages' task :clean => [:clobber_rdoc, :clobber_package] do rm "#{spec.name}.gemspec" end ================================================ FILE: VERSION ================================================ 0.2.1 ================================================ FILE: examples/fogbugz.rb ================================================ # Just showing an example of something other than Twitter. require 'rubygems' require 'fogbugz-api' # sudo gem install austinmoody-fogbugz-api require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','spy')) config = {:username => "yourusername", :password => "yourpass", :domain => "yourdomain.fogbugz.com" } Net::HTTP.http_logger_options = {:body => true, :trace => false} @fogbugz = FogBugz.new(config[:domain],true) # create instance @fogbugz.logon(config[:username],config[:password]) # logs into FogBugz and sets *token* ================================================ FILE: examples/google.rb ================================================ # Just showing an example of something other than Twitter. # Garb lets you access the Google Analytics API require 'rubygems' require 'garb' require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','net-http-spy')) Net::HTTP.http_logger_options = {:body => false, :trace => false, :verbose => false} Garb::Session.login('yourgoogleusername', 'yourpassword') ================================================ FILE: examples/twitter-calltrace.rb ================================================ # See where the external API calls take place within the gem you are using with the :trace option require 'rubygems' require 'twitter' require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','net-http-spy')) Net::HTTP.http_logger_options = {:trace => true} Twitter::Search.new('httparty').each { |r| r } ================================================ FILE: examples/twitter-customlog.rb ================================================ # By default the logger outputs to STDOUT, it's easy to change this to a file if you like # Great to capture and then use for testing with tools like FakeWeb when combined with :body => true require 'rubygems' require 'twitter' require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','net-http-spy')) Net::HTTP.http_logger = Logger.new('twitter.log') Twitter::Search.new('httparty').each { |r| r } ================================================ FILE: examples/twitter-simple.rb ================================================ # Simplist example. All you need to do is include the spy lib for it to start doing the right thing require 'rubygems' require 'twitter' require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','net-http-spy')) Twitter::Search.new('httparty').each { |r| r } ================================================ FILE: examples/twitter-verbose.rb ================================================ # Net::HTTP has it's own logging/debug functionality. Turn on :verbose to show the full raw HTTP communication require 'rubygems' require 'twitter' require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','net-http-spy')) Net::HTTP.http_logger_options = {:verbose => true} Twitter::Search.new('httparty').each { |r| r } ================================================ FILE: examples/twitter-withbody.rb ================================================ # Display the full response/request body. Usually just the response code is shown. require 'rubygems' require 'twitter' require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','net-http-spy')) Net::HTTP.http_logger_options = {:body => true} Twitter::Search.new('httparty').each { |r| r } ================================================ FILE: lib/net-http-spy.rb ================================================ require 'net/https' require 'logger' require 'cgi' # HTTP SPY module Net class HTTP alias :old_initialize :initialize alias :old_request :request class << self attr_accessor :http_logger attr_accessor :http_logger_options end def initialize(*args, &block) self.class.http_logger_options ||= {} defaults = {:body => false, :trace => false, :verbose => false, :limit => -1} self.class.http_logger_options = (self.class.http_logger_options == :default) ? defaults : self.class.http_logger_options @logger_options = defaults.merge(self.class.http_logger_options) @params_limit = @logger_options[:params_limit] || @logger_options[:limit] @body_limit = @logger_options[:body_limit] || @logger_options[:limit] self.class.http_logger.info "CONNECT: #{args.inspect}" if !@logger_options[:verbose] old_initialize(*args, &block) @debug_output = self.class.http_logger if @logger_options[:verbose] end def request(*args, &block) unless started? || @logger_options[:verbose] req = args[0].class::METHOD self.class.http_logger.info "#{req} #{args[0].path}" end result = old_request(*args, &block) unless started? || @logger_options[:verbose] self.class.http_logger.info "PARAMS #{CGI.parse(args[0].body).inspect[0..@params_limit]} " if args[0].body && req != 'CONNECT' self.class.http_logger.info "TRACE: #{caller.reverse}" if @logger_options[:trace] self.class.http_logger.info "BODY: #{(@logger_options[:body] ? result.body : result.class.name)[0..@body_limit]}" end result end end end Net::HTTP.http_logger = Logger.new(STDOUT) ================================================ FILE: net-http-spy.gemspec ================================================ # Generated by jeweler # DO NOT EDIT THIS FILE DIRECTLY # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command # -*- encoding: utf-8 -*- Gem::Specification.new do |s| s.name = %q{net-http-spy} s.version = "0.2.1" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Martin Sadler"] s.date = %q{2009-12-05} s.description = %q{Ever wondered what HTTP requests the Ruby gem you are using to connect to a third party API is making? Use HTTP Spy to see what is going on behind the scenes.} s.email = %q{martin@beyondthetype.com} s.files = [ "Rakefile", "VERSION", "examples/fogbugz.rb", "examples/google.rb", "examples/twitter-calltrace.rb", "examples/twitter-customlog.rb", "examples/twitter-simple.rb", "examples/twitter-verbose.rb", "examples/twitter-withbody.rb", "lib/net-http-spy.rb", "net-http-spy.gemspec", "readme.markdown", "spec/spec.opts", "spec/spec_helper.rb", "spec/spy_spec.rb" ] s.homepage = %q{http://github.com/martinbtt/net-http-spy} s.rdoc_options = ["--charset=UTF-8"] s.require_paths = ["lib"] s.rubygems_version = %q{1.3.5} s.summary = %q{Ever wondered what HTTP requests the Ruby gem you are using to connect to a third party API is making? Use HTTP Spy to see what is going on behind the scenes.} s.test_files = [ "spec/spec_helper.rb", "spec/spy_spec.rb", "examples/fogbugz.rb", "examples/google.rb", "examples/twitter-calltrace.rb", "examples/twitter-customlog.rb", "examples/twitter-simple.rb", "examples/twitter-verbose.rb", "examples/twitter-withbody.rb" ] if s.respond_to? :specification_version then current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION s.specification_version = 3 if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then else end else end end ================================================ FILE: readme.markdown ================================================ ## About Ever wondered what HTTP requests the Ruby gem you are using to connect to a third party API is making? Use HTTP Spy to see what is going on behind the scenes. ## Installation sudo gem install martinbtt-net-http-spy ## Example Usage require 'rubygems' require 'twitter' gem 'net-http-spy' require 'net-http-spy' Twitter::Search.new('httparty').each { |r| r } # Outputs... -- : CONNECT: ["search.twitter.com", 80] -- : GET /search.json?q=httparty -- : BODY: Net::HTTPOK See the examples folder for more. ## Further Options Show the call trace to the originating line of code in the third party gem Net::HTTP.http_logger_options = {:trace => true} Output the body of the request Net::HTTP.http_logger_options = {:body => true} Show the full raw HTTP output Net::HTTP.http_logger_options = {:verbose => true} Change the logger. By default HTTP spy logs to STDOUT Net::HTTP.http_logger = Logger.new('twitter.log') ## Bonus Points Use it to grab sample data for FakeWeb = testing goodness. ## Notes This is a pretty early release. I'm sure there is plenty that can be done to improve compatibility as several libraries call Net::HTTP in a slightly different way. Feel free to fork and send in pull requests/patches. ## Find Me Martin Sadler (martin -- at -- beyondthetype.com) * Blog: http://www.beyondthetype.com * Follow: http://twitter.com/martinbtt * Code: http://github.com/martinbtt * Recommend: http://www.workingwithrails.com/person/5152-martin-sadler ================================================ FILE: spec/spec.opts ================================================ --format progress --colour ================================================ FILE: spec/spec_helper.rb ================================================ require 'rubygems' gem 'rspec' require 'spec' require 'net/http' require 'open-uri' require 'twitter' require 'mechanize' require 'webmock/rspec' include WebMock LIVE = ENV['LIVE'] WebMock.allow_net_connect! if LIVE require File.join(File.dirname(__FILE__), '..', 'lib', 'net-http-spy') class DummyLogger attr_accessor :lines def initialize reset! end def <<(msg) @lines << msg end def info(msg) @lines << msg end def reset! @lines = [] end end ================================================ FILE: spec/spy_spec.rb ================================================ require File.join(File.dirname(__FILE__), 'spec_helper') # Bare bones spec to make sure the core functionality is working describe "Net:HTTP Spying on" do before(:all) do Net::HTTP.http_logger = DummyLogger.new() end describe "a get request with default options" do before(:all) do stub_request(:any, "search.twitter.com/search.json?q=httparty").to_return(:body => "\{\"results\"\: 1\}", :status => 200) unless LIVE Net::HTTP.http_logger_options = :default Twitter::Search.new('httparty').fetch end it "should give the connection" do Net::HTTP.http_logger.lines.should include("CONNECT: [\"search.twitter.com\", 80]") end it "should give GET uri and query string" do Net::HTTP.http_logger.lines.should include("GET /search.json?q=httparty") end it "should give the BODY response code" do Net::HTTP.http_logger.lines.should include("BODY: Net::HTTPOK") end end describe "a get request with body option set to true" do before(:each) do stub_request(:any, "search.twitter.com/search.json?q=httparty").to_return(:body => "\{\"results\"\: 1\}", :status => 200) unless LIVE Net::HTTP.http_logger_options = {:body => true} end it "should give the body output" do Twitter::Search.new('httparty').fetch Net::HTTP.http_logger.lines Net::HTTP.http_logger.lines.grep(/BODY: \{\"results\":/).should_not be_empty end end describe "a get request with trace option set to true" do before(:each) do Net::HTTP.http_logger_options = {:trace => true} stub_request(:any, "search.twitter.com/search.json?q=httparty").to_return(:body => "\{\"results\"\: 1\}", :status => 200) unless LIVE end it "should give the trace output" do Twitter::Search.new('httparty').fetch Net::HTTP.http_logger.lines.grep(/TRACE: /).should_not be_empty end end describe "a post request with default options" do before(:all) do Net::HTTP.http_logger_options = {:verbose => false} stub_request(:any, "search.twitter.com/search").to_return(:body => "\{\"results\"\: 1\}", :status => 200) unless LIVE @connection = Net::HTTP.new('search.twitter.com') @connection.post('/search','?q=hello') end it "should give the post url" do Net::HTTP.http_logger.lines.should include("POST /search") end if LIVE # only works if real live request it "should give the post params" do Net::HTTP.http_logger.lines.should include("PARAMS {\"?q\"=>[\"hello\"]} ") end end it "should give the BODY response code" do Net::HTTP.http_logger.lines.should include("BODY: Net::HTTPOK") end end after(:all) do Net::HTTP.http_logger.reset! end end