webmock 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +55 -0
- data/README.md +63 -4
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/lib/webmock.rb +3 -0
- data/lib/webmock/callback_registry.rb +35 -0
- data/lib/webmock/http_lib_adapters/em_http_request.rb +114 -0
- data/lib/webmock/http_lib_adapters/httpclient.rb +34 -7
- data/lib/webmock/http_lib_adapters/net_http.rb +24 -2
- data/lib/webmock/http_lib_adapters/net_http_response.rb +49 -0
- data/lib/webmock/http_lib_adapters/patron.rb +22 -3
- data/lib/webmock/request_pattern.rb +90 -17
- data/lib/webmock/response.rb +15 -7
- data/lib/webmock/util/uri.rb +18 -7
- data/lib/webmock/webmock.rb +8 -0
- data/spec/benchmark.rb +61 -0
- data/spec/em_http_request_spec.rb +29 -0
- data/spec/em_http_request_spec_helper.rb +64 -0
- data/spec/httpclient_spec_helper.rb +4 -0
- data/spec/net_http_spec.rb +46 -1
- data/spec/net_http_spec_helper.rb +4 -0
- data/spec/other_net_http_libs_spec.rb +1 -0
- data/spec/patron_spec_helper.rb +4 -0
- data/spec/request_pattern_spec.rb +143 -32
- data/spec/response_spec.rb +14 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/vendor/crack/lib/crack.rb +0 -0
- data/spec/webmock_spec.rb +362 -13
- data/test/test_webmock.rb +2 -2
- data/webmock.gemspec +21 -5
- metadata +58 -11
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,60 @@ | |
| 1 1 | 
             
            #Changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 1.3.0
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Added support for [em-http-request](http://github.com/igrigorik/em-http-request)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Matching query params using a hash	 
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            	 	 stub_http_request(:get, "www.example.com").with(:query => {"a" => ["b", "c"]})
         | 
| 10 | 
            +
            	 
         | 
| 11 | 
            +
            	 	 RestClient.get("http://www.example.com/?a[]=b&a[]=c") # ===> Success
         | 
| 12 | 
            +
            	 	 
         | 
| 13 | 
            +
            	 	 request(:get, "www.example.com").with(:query => {"a" => ["b", "c"]}).should have_been_made  # ===> Success
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            * Matching request body against a hash. Body can be URL-Encoded, JSON or XML.
         | 
| 16 | 
            +
              (Thanks to Steve Tooke for the idea and a solution for url-encoded bodies)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            		stub_http_request(:post, "www.example.com").
         | 
| 19 | 
            +
            			with(:body => {:data => {:a => '1', :b => 'five'}})
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            		RestClient.post('www.example.com', "data[a]=1&data[b]=five", 
         | 
| 22 | 
            +
            	  	:content_type => 'application/x-www-form-urlencoded')    # ===> Success
         | 
| 23 | 
            +
            	
         | 
| 24 | 
            +
            		RestClient.post('www.example.com', '{"data":{"a":"1","b":"five"}}', 
         | 
| 25 | 
            +
            	  	:content_type => 'application/json')    # ===> Success
         | 
| 26 | 
            +
            	
         | 
| 27 | 
            +
            		RestClient.post('www.example.com', '<data a="1" b="five" />', 
         | 
| 28 | 
            +
            			:content_type => 'application/xml' )    # ===> Success
         | 
| 29 | 
            +
            			
         | 
| 30 | 
            +
            		request(:post, "www.example.com").
         | 
| 31 | 
            +
                	with(:body => {:data => {:a => '1', :b => 'five'}},
         | 
| 32 | 
            +
                	 :headers => 'Content-Type' => 'application/json').should have_been_made	 # ===> Success
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            * Request callbacks (Thanks to Myron Marston for all suggestions)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                WebMock can now invoke callbacks for stubbed or real requests:
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            		WebMock.after_request do |request_signature, response|
         | 
| 39 | 
            +
            		  puts "Request #{request_signature} was made and #{response} was returned"
         | 
| 40 | 
            +
            		end
         | 
| 41 | 
            +
                
         | 
| 42 | 
            +
                invoke callbacks for real requests only and except requests made with Patron client
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            		WebMock.after_request(:except => [:patron], :real_requests_only => true)  do |request_signature, response|
         | 
| 45 | 
            +
            		  puts "Request #{request_signature} was made and #{response} was returned"
         | 
| 46 | 
            +
            		end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            * `to_raise()` now accepts an exception instance or a string as argument in addition to an exception class
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            		stub_request(:any, 'www.example.net').to_raise(StandardError.new("some error"))
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
            		stub_request(:any, 'www.example.net').to_raise("some error")
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            * Matching request stubs based on a URI is 30% faster
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            * Fixed constant namespace issues in HTTPClient adapter. Thanks to Nathaniel Bibler for submitting a patch.
         | 
| 57 | 
            +
             | 
| 3 58 | 
             
            ## 1.2.2
         | 
| 4 59 |  | 
| 5 60 | 
             
            * Fixed problem where ArgumentError was raised if query params were made up of an array e.g. data[]=a&data[]=b. Thanks to Steve Tooke
         | 
    
        data/README.md
    CHANGED
    
    | @@ -13,10 +13,14 @@ Features | |
| 13 13 | 
             
            * Smart matching of the same headers in different representations.
         | 
| 14 14 | 
             
            * Support for Test::Unit
         | 
| 15 15 | 
             
            * Support for RSpec 1.x and RSpec 2.x
         | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 16 | 
            +
             | 
| 17 | 
            +
            Supported HTTP libraries
         | 
| 18 | 
            +
            ------------------------
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            * Net::HTTP and libraries based on Net::HTTP (i.e RightHttpConnection, REST Client, HTTParty)
         | 
| 21 | 
            +
            * HTTPClient
         | 
| 22 | 
            +
            * Patron
         | 
| 23 | 
            +
            * EM-HTTP-Request
         | 
| 20 24 |  | 
| 21 25 | 
             
            Installation
         | 
| 22 26 | 
             
            ------------
         | 
| @@ -80,6 +84,20 @@ You can also use WebMock without RSpec or Test::Unit support: | |
| 80 84 | 
             
                res = Net::HTTP.start(uri.host, uri.port) {|http|
         | 
| 81 85 | 
             
                  http.request(req, 'hello world')
         | 
| 82 86 | 
             
                }    # ===> Success
         | 
| 87 | 
            +
                
         | 
| 88 | 
            +
            ### Matching request body against a hash. Body can be URL-Encoded, JSON or XML.
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            	stub_http_request(:post, "www.example.com").
         | 
| 91 | 
            +
            		with(:body => {:data => {:a => '1', :b => 'five'}})
         | 
| 92 | 
            +
             | 
| 93 | 
            +
            	RestClient.post('www.example.com', "data[a]=1&data[b]=five", 
         | 
| 94 | 
            +
            	  :content_type => 'application/x-www-form-urlencoded')    # ===> Success
         | 
| 95 | 
            +
            	
         | 
| 96 | 
            +
            	RestClient.post('www.example.com', '{"data":{"a":"1","b":"five"}}', 
         | 
| 97 | 
            +
            	  :content_type => 'application/json')    # ===> Success
         | 
| 98 | 
            +
            	
         | 
| 99 | 
            +
            	RestClient.post('www.example.com', '<data a="1" b="five" />', 
         | 
| 100 | 
            +
            	  :content_type => 'application/xml' )    # ===> Success
         | 
| 83 101 |  | 
| 84 102 | 
             
            ### Matching custom request headers
         | 
| 85 103 |  | 
| @@ -121,7 +139,13 @@ You can also use WebMock without RSpec or Test::Unit support: | |
| 121 139 | 
             
            	 stub_request(:any, /.*example.*/)
         | 
| 122 140 |  | 
| 123 141 | 
             
            	 Net::HTTP.get('www.example.com', '/') # ===> Success	
         | 
| 142 | 
            +
            	 
         | 
| 143 | 
            +
            ### Matching query params using hash	 
         | 
| 124 144 |  | 
| 145 | 
            +
            	 stub_http_request(:get, "www.example.com").with(:query => {"a" => ["b", "c"]})
         | 
| 146 | 
            +
            	 
         | 
| 147 | 
            +
            	 RestClient.get("http://www.example.com/?a[]=b&a[]=c") # ===> Success	
         | 
| 148 | 
            +
            	 
         | 
| 125 149 | 
             
            ### Stubbing with custom response
         | 
| 126 150 |  | 
| 127 151 | 
             
            	stub_request(:any, "www.example.com").to_return(:body => "abc", :status => 200,  :headers => { 'Content-Length' => 3 } )
         | 
| @@ -179,9 +203,19 @@ You can also use WebMock without RSpec or Test::Unit support: | |
| 179 203 |  | 
| 180 204 | 
             
            ### Raising errors
         | 
| 181 205 |  | 
| 206 | 
            +
            #### Exception declared by class
         | 
| 207 | 
            +
             | 
| 182 208 | 
             
            	stub_request(:any, 'www.example.net').to_raise(StandardError)
         | 
| 183 209 |  | 
| 184 210 | 
             
                RestClient.post('www.example.net', 'abc')    # ===> StandardError
         | 
| 211 | 
            +
                
         | 
| 212 | 
            +
            #### or by exception instance
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                stub_request(:any, 'www.example.net').to_raise(StandardError.new("some error"))
         | 
| 215 | 
            +
             | 
| 216 | 
            +
            #### or by string
         | 
| 217 | 
            +
                
         | 
| 218 | 
            +
                stub_request(:any, 'www.example.net').to_raise("some error")
         | 
| 185 219 |  | 
| 186 220 | 
             
            ### Raising timeout errors
         | 
| 187 221 |  | 
| @@ -282,6 +316,11 @@ You can also use WebMock without RSpec or Test::Unit support: | |
| 282 316 | 
             
            	WebMock.should_not have_requested(:get, "www.something.com")
         | 
| 283 317 |  | 
| 284 318 | 
             
            	WebMock.should have_requested(:post, "www.example.com").with { |req| req.body == "abc" }
         | 
| 319 | 
            +
            	
         | 
| 320 | 
            +
            	WebMock.should have_requested(:get, "www.example.com").with(:query => {"a" => ["b", "c"]}) 
         | 
| 321 | 
            +
             | 
| 322 | 
            +
            	WebMock.should have_requested(:get, "www.example.com").
         | 
| 323 | 
            +
            	  with(:body => {"a" => ["b", "c"]}, :headers => 'Content-Type' => 'application/json')
         | 
| 285 324 |  | 
| 286 325 | 
             
            ### Different way of setting expectations in RSpec
         | 
| 287 326 |  | 
| @@ -293,6 +332,11 @@ You can also use WebMock without RSpec or Test::Unit support: | |
| 293 332 |  | 
| 294 333 | 
             
            	request(:post, "www.example.com").with { |req| req.body == "abc" }.should have_been_made
         | 
| 295 334 |  | 
| 335 | 
            +
            	request(:get, "www.example.com").with(:query => {"a" => ["b", "c"]}).should have_been_made
         | 
| 336 | 
            +
            	
         | 
| 337 | 
            +
            	request(:post, "www.example.com").
         | 
| 338 | 
            +
            	  with(:body => {"a" => ["b", "c"]}, :headers => 'Content-Type' => 'application/json').should have_been_made
         | 
| 339 | 
            +
            	
         | 
| 296 340 | 
             
            ## Clearing stubs and request history
         | 
| 297 341 |  | 
| 298 342 | 
             
            If you want to reset all current stubs and history of requests use `WebMock.reset_webmock`
         | 
| @@ -402,6 +446,20 @@ i.e the following two sets of headers are equal: | |
| 402 446 |  | 
| 403 447 | 
             
            To record your application's real HTTP interactions and replay them later in tests you can use [VCR](http://github.com/myronmarston/vcr) with WebMock.
         | 
| 404 448 |  | 
| 449 | 
            +
            ## Request callbacks
         | 
| 450 | 
            +
             | 
| 451 | 
            +
            ####WebMock can invoke callbacks stubbed or real requests:
         | 
| 452 | 
            +
             | 
| 453 | 
            +
                WebMock.after_request do |request_signature, response|
         | 
| 454 | 
            +
                  puts "Request #{request_signature} was made and #{response} was returned"
         | 
| 455 | 
            +
                end
         | 
| 456 | 
            +
             | 
| 457 | 
            +
            #### invoke callbacks for real requests only and except requests made with Patron
         | 
| 458 | 
            +
             | 
| 459 | 
            +
                WebMock.after_request(:except => [:patron], :real_requests_only => true)  do |request_signature, response|
         | 
| 460 | 
            +
                  puts "Request #{request_signature} was made and #{response} was returned"
         | 
| 461 | 
            +
                end
         | 
| 462 | 
            +
             | 
| 405 463 | 
             
            ## Bugs and Issues
         | 
| 406 464 |  | 
| 407 465 | 
             
            Please submit them here [http://github.com/bblimke/webmock/issues](http://github.com/bblimke/webmock/issues)
         | 
| @@ -439,6 +497,7 @@ People who submitted patches and new features or suggested improvements. Many th | |
| 439 497 | 
             
            * Jose Angel Cortinas
         | 
| 440 498 | 
             
            * Razic
         | 
| 441 499 | 
             
            * Steve Tooke
         | 
| 500 | 
            +
            * Nathaniel Bibler
         | 
| 442 501 |  | 
| 443 502 | 
             
            ## Background
         | 
| 444 503 |  | 
    
        data/Rakefile
    CHANGED
    
    | @@ -11,9 +11,11 @@ begin | |
| 11 11 | 
             
                gem.homepage = "http://github.com/bblimke/webmock"
         | 
| 12 12 | 
             
                gem.authors = ["Bartosz Blimke"]
         | 
| 13 13 | 
             
                gem.add_dependency "addressable", ">= 2.1.1"
         | 
| 14 | 
            +
                gem.add_dependency "crack", ">=0.1.7"
         | 
| 14 15 | 
             
                gem.add_development_dependency "rspec", ">= 1.2.9"
         | 
| 15 16 | 
             
                gem.add_development_dependency "httpclient", ">= 2.1.5.2"
         | 
| 16 17 | 
             
                gem.add_development_dependency "patron", ">= 0.4.5" unless RUBY_PLATFORM =~ /java/
         | 
| 18 | 
            +
                gem.add_development_dependency "em-http-request", ">= 0.2.7" unless RUBY_PLATFORM =~ /java/
         | 
| 17 19 | 
             
              end
         | 
| 18 20 | 
             
              Jeweler::GemcutterTasks.new
         | 
| 19 21 | 
             
            rescue LoadError
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            1. | 
| 1 | 
            +
            1.3.0
         | 
    
        data/lib/webmock.rb
    CHANGED
    
    | @@ -1,10 +1,12 @@ | |
| 1 1 | 
             
            require 'singleton'
         | 
| 2 2 |  | 
| 3 3 | 
             
            require 'addressable/uri'
         | 
| 4 | 
            +
            require 'crack'
         | 
| 4 5 |  | 
| 5 6 | 
             
            require 'webmock/http_lib_adapters/net_http'
         | 
| 6 7 | 
             
            require 'webmock/http_lib_adapters/httpclient'
         | 
| 7 8 | 
             
            require 'webmock/http_lib_adapters/patron'
         | 
| 9 | 
            +
            require 'webmock/http_lib_adapters/em_http_request'
         | 
| 8 10 |  | 
| 9 11 | 
             
            require 'webmock/errors'
         | 
| 10 12 |  | 
| @@ -20,5 +22,6 @@ require 'webmock/response' | |
| 20 22 |  | 
| 21 23 | 
             
            require 'webmock/request_execution_verifier'
         | 
| 22 24 | 
             
            require 'webmock/config'
         | 
| 25 | 
            +
            require 'webmock/callback_registry'
         | 
| 23 26 | 
             
            require 'webmock/request_registry'
         | 
| 24 27 | 
             
            require 'webmock/webmock'
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            module WebMock
         | 
| 2 | 
            +
              class CallbackRegistry
         | 
| 3 | 
            +
                @@callbacks = []
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def self.add_callback(options, block)
         | 
| 6 | 
            +
                  @@callbacks << {:options => options, :block => block}
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def self.callbacks
         | 
| 10 | 
            +
                  @@callbacks
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def self.invoke_callbacks(options, request_signature, response)
         | 
| 14 | 
            +
                  return if @@callbacks.empty?
         | 
| 15 | 
            +
                  CallbackRegistry.callbacks.each do |callback|
         | 
| 16 | 
            +
                    except = callback[:options][:except]
         | 
| 17 | 
            +
                    real_only = callback[:options][:real_requests_only]
         | 
| 18 | 
            +
                    unless except && except.include?(options[:lib])
         | 
| 19 | 
            +
                      if !real_only || options[:real_request]
         | 
| 20 | 
            +
                        callback[:block].call(request_signature, response)
         | 
| 21 | 
            +
                      end
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def self.reset
         | 
| 27 | 
            +
                  @@callbacks = []
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
                
         | 
| 30 | 
            +
                def self.any_callbacks?
         | 
| 31 | 
            +
                  !@@callbacks.empty?
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| @@ -0,0 +1,114 @@ | |
| 1 | 
            +
            if defined?(EventMachine::HttpRequest)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              module EventMachine
         | 
| 4 | 
            +
                class HttpRequest
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  class WebMockFakeHttpClient < EventMachine::HttpClient
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                    def setup(response, uri, error = nil)
         | 
| 9 | 
            +
                      @uri = uri
         | 
| 10 | 
            +
                      if error
         | 
| 11 | 
            +
                        on_error(error)
         | 
| 12 | 
            +
                        fail(self)
         | 
| 13 | 
            +
                      else
         | 
| 14 | 
            +
                        receive_data(response)
         | 
| 15 | 
            +
                        succeed(self)
         | 
| 16 | 
            +
                      end
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                    
         | 
| 19 | 
            +
                    def stream(&blk)
         | 
| 20 | 
            +
                      blk.call(@response)
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    def unbind
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def send_request_with_webmock(&block)
         | 
| 29 | 
            +
                    request_signature = build_request_signature
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    if WebMock.registered_request?(request_signature)
         | 
| 34 | 
            +
                      webmock_response = WebMock.response_for_request(request_signature)
         | 
| 35 | 
            +
                      WebMock::CallbackRegistry.invoke_callbacks(
         | 
| 36 | 
            +
                        {:lib => :em_http_request}, request_signature, webmock_response)
         | 
| 37 | 
            +
                      client = WebMockFakeHttpClient.new(nil)
         | 
| 38 | 
            +
                      client.on_error("WebMock timeout error") if webmock_response.should_timeout
         | 
| 39 | 
            +
                      client.setup(make_raw_response(webmock_response), @uri,
         | 
| 40 | 
            +
                        webmock_response.should_timeout ? "WebMock timeout error" : nil)
         | 
| 41 | 
            +
                      client
         | 
| 42 | 
            +
                    elsif WebMock.net_connect_allowed?(request_signature.uri)
         | 
| 43 | 
            +
                      http = send_request_without_webmock(&block)
         | 
| 44 | 
            +
                      http.callback {
         | 
| 45 | 
            +
                        if WebMock::CallbackRegistry.any_callbacks?
         | 
| 46 | 
            +
                          webmock_response = build_webmock_response(http)
         | 
| 47 | 
            +
                          WebMock::CallbackRegistry.invoke_callbacks(
         | 
| 48 | 
            +
                            {:lib => :em_http_request, :real_request => true}, request_signature,
         | 
| 49 | 
            +
                            webmock_response)
         | 
| 50 | 
            +
                        end
         | 
| 51 | 
            +
                      }
         | 
| 52 | 
            +
                      http
         | 
| 53 | 
            +
                    else
         | 
| 54 | 
            +
                      raise WebMock::NetConnectNotAllowedError.new(request_signature)
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                  
         | 
| 58 | 
            +
                  alias_method :send_request_without_webmock, :send_request
         | 
| 59 | 
            +
                  alias_method :send_request, :send_request_with_webmock
         | 
| 60 | 
            +
                  
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  private
         | 
| 63 | 
            +
                  
         | 
| 64 | 
            +
                  def build_webmock_response(http)
         | 
| 65 | 
            +
                    webmock_response = WebMock::Response.new
         | 
| 66 | 
            +
                    webmock_response.status = [http.response_header.status, http.response_header.http_reason]
         | 
| 67 | 
            +
                    webmock_response.headers = http.response_header
         | 
| 68 | 
            +
                    webmock_response.body = http.response
         | 
| 69 | 
            +
                    webmock_response
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  def build_request_signature
         | 
| 73 | 
            +
                    
         | 
| 74 | 
            +
                    if @options[:authorization] || @options['authorization']
         | 
| 75 | 
            +
                      auth = (@options[:authorization] || @options['authorization'])
         | 
| 76 | 
            +
                      userinfo = auth.join(':')
         | 
| 77 | 
            +
                      userinfo = WebMock::Util::URI.encode_unsafe_chars_in_userinfo(userinfo)
         | 
| 78 | 
            +
                      @options.reject! {|k,v| k.to_s == 'authorization' } #we added it to url userinfo
         | 
| 79 | 
            +
                      @uri.userinfo = userinfo
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
                    
         | 
| 82 | 
            +
                   @uri.query_values = (@uri.query_values || {}).merge(@options[:query]) if @options[:query]
         | 
| 83 | 
            +
                    
         | 
| 84 | 
            +
                    WebMock::RequestSignature.new(
         | 
| 85 | 
            +
                      @method.downcase.to_sym,
         | 
| 86 | 
            +
                      @uri.to_s,
         | 
| 87 | 
            +
                      :body => (@options[:body] || @options['body']),
         | 
| 88 | 
            +
                      :headers => (@options[:head] || @options['head'])
         | 
| 89 | 
            +
                    )
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
             | 
| 93 | 
            +
                  def make_raw_response(response)            
         | 
| 94 | 
            +
                    response.raise_error_if_any
         | 
| 95 | 
            +
                    
         | 
| 96 | 
            +
                    status, headers, body = response.status, response.headers, response.body
         | 
| 97 | 
            +
                    
         | 
| 98 | 
            +
                    response_string = []
         | 
| 99 | 
            +
                    response_string << "HTTP/1.1 #{status[0]} #{status[1]}"
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                    headers.each do |header, value|
         | 
| 102 | 
            +
                      value = value.join(", ") if value.is_a?(Array)
         | 
| 103 | 
            +
                      response_string << "#{header}: #{value}"
         | 
| 104 | 
            +
                    end if headers
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    response_string << "" << body
         | 
| 107 | 
            +
                    response_string.join("\n")
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
             | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
              end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            end
         | 
| @@ -1,6 +1,6 @@ | |
| 1 | 
            -
            if defined?(HTTPClient)
         | 
| 1 | 
            +
            if defined?(::HTTPClient)
         | 
| 2 2 |  | 
| 3 | 
            -
              class HTTPClient
         | 
| 3 | 
            +
              class ::HTTPClient
         | 
| 4 4 |  | 
| 5 5 | 
             
                def do_get_block_with_webmock(req, proxy, conn, &block)
         | 
| 6 6 | 
             
                  do_get_with_webmock(req, proxy, conn, false, &block)
         | 
| @@ -18,15 +18,27 @@ if defined?(HTTPClient) | |
| 18 18 | 
             
                  if WebMock.registered_request?(request_signature)
         | 
| 19 19 | 
             
                    webmock_response = WebMock.response_for_request(request_signature)
         | 
| 20 20 | 
             
                    response = build_httpclient_response(webmock_response, stream, &block)
         | 
| 21 | 
            -
                    conn.push(response)
         | 
| 21 | 
            +
                    res = conn.push(response)
         | 
| 22 | 
            +
                    WebMock::CallbackRegistry.invoke_callbacks(
         | 
| 23 | 
            +
                      {:lib => :http_client}, request_signature, webmock_response) 
         | 
| 24 | 
            +
                    res
         | 
| 22 25 | 
             
                  elsif WebMock.net_connect_allowed?(request_signature.uri)
         | 
| 23 | 
            -
                    if stream
         | 
| 26 | 
            +
                    res = if stream
         | 
| 24 27 | 
             
                      do_get_stream_without_webmock(req, proxy, conn, &block)
         | 
| 25 28 | 
             
                    else
         | 
| 26 29 | 
             
                      do_get_block_without_webmock(req, proxy, conn, &block)
         | 
| 27 30 | 
             
                    end
         | 
| 31 | 
            +
                    res = conn.pop
         | 
| 32 | 
            +
                    conn.push(res)
         | 
| 33 | 
            +
                    if WebMock::CallbackRegistry.any_callbacks?
         | 
| 34 | 
            +
                      webmock_response = build_webmock_response(res)
         | 
| 35 | 
            +
                      WebMock::CallbackRegistry.invoke_callbacks(
         | 
| 36 | 
            +
                        {:lib => :http_client, :real_request => true}, request_signature,
         | 
| 37 | 
            +
                        webmock_response)
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                    res
         | 
| 28 40 | 
             
                  else
         | 
| 29 | 
            -
                    raise NetConnectNotAllowedError.new(request_signature)
         | 
| 41 | 
            +
                    raise WebMock::NetConnectNotAllowedError.new(request_signature)
         | 
| 30 42 | 
             
                  end
         | 
| 31 43 | 
             
                end
         | 
| 32 44 |  | 
| @@ -37,7 +49,7 @@ if defined?(HTTPClient) | |
| 37 49 | 
             
                  if WebMock.registered_request?(request_signature) || WebMock.net_connect_allowed?(request_signature.uri)
         | 
| 38 50 | 
             
                    do_request_async_without_webmock(method, uri, query, body, extheader)
         | 
| 39 51 | 
             
                  else
         | 
| 40 | 
            -
                    raise NetConnectNotAllowedError.new(request_signature)
         | 
| 52 | 
            +
                    raise WebMock::NetConnectNotAllowedError.new(request_signature)
         | 
| 41 53 | 
             
                  end
         | 
| 42 54 | 
             
                end
         | 
| 43 55 |  | 
| @@ -65,9 +77,24 @@ if defined?(HTTPClient) | |
| 65 77 | 
             
                  response
         | 
| 66 78 | 
             
                end
         | 
| 67 79 | 
             
              end
         | 
| 80 | 
            +
              
         | 
| 81 | 
            +
              def build_webmock_response(httpclient_response)
         | 
| 82 | 
            +
                webmock_response = WebMock::Response.new
         | 
| 83 | 
            +
                webmock_response.status = [httpclient_response.status, httpclient_response.reason]
         | 
| 84 | 
            +
                webmock_response.headers = httpclient_response.header.all
         | 
| 85 | 
            +
                if  httpclient_response.content.respond_to?(:read)
         | 
| 86 | 
            +
                  webmock_response.body = httpclient_response.content.read
         | 
| 87 | 
            +
                  body = HTTP::Message::Body.new
         | 
| 88 | 
            +
                  body.init_response(StringIO.new(webmock_response.body))
         | 
| 89 | 
            +
                  httpclient_response.body = body
         | 
| 90 | 
            +
                else
         | 
| 91 | 
            +
                  webmock_response.body = httpclient_response.content
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
                webmock_response
         | 
| 94 | 
            +
              end
         | 
| 68 95 |  | 
| 69 96 | 
             
              def build_request_signature(req)
         | 
| 70 | 
            -
                uri =  | 
| 97 | 
            +
                uri = WebMock::Util::URI.heuristic_parse(req.header.request_uri.to_s)
         | 
| 71 98 | 
             
                uri.query_values = req.header.request_query if req.header.request_query
         | 
| 72 99 | 
             
                uri.port = req.header.request_uri.port
         | 
| 73 100 | 
             
                uri = uri.omit(:userinfo)
         | 
| @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            require 'net/http'
         | 
| 2 2 | 
             
            require 'net/https'
         | 
| 3 3 | 
             
            require 'stringio'
         | 
| 4 | 
            +
            require File.join(File.dirname(__FILE__), 'net_http_response')
         | 
| 4 5 |  | 
| 5 6 | 
             
            class StubSocket #:nodoc:
         | 
| 6 7 |  | 
| @@ -60,10 +61,20 @@ module Net  #:nodoc: all | |
| 60 61 | 
             
                  if WebMock.registered_request?(request_signature)
         | 
| 61 62 | 
             
                    @socket = Net::HTTP.socket_type.new
         | 
| 62 63 | 
             
                    webmock_response = WebMock.response_for_request(request_signature)
         | 
| 64 | 
            +
                    WebMock::CallbackRegistry.invoke_callbacks(
         | 
| 65 | 
            +
                      {:lib => :net_http}, request_signature, webmock_response)
         | 
| 63 66 | 
             
                    build_net_http_response(webmock_response, &block)
         | 
| 64 67 | 
             
                  elsif WebMock.net_connect_allowed?(request_signature.uri)
         | 
| 65 68 | 
             
                    connect_without_webmock
         | 
| 66 | 
            -
                    request_without_webmock(request, nil | 
| 69 | 
            +
                    response = request_without_webmock(request, nil)
         | 
| 70 | 
            +
                    if WebMock::CallbackRegistry.any_callbacks? && started?
         | 
| 71 | 
            +
                      webmock_response = build_webmock_response(response)
         | 
| 72 | 
            +
                      WebMock::CallbackRegistry.invoke_callbacks(
         | 
| 73 | 
            +
                        {:lib => :net_http, :real_request => true}, request_signature, webmock_response)
         | 
| 74 | 
            +
                      response.extend WebMock::Net::HTTPResponse   
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                    yield response if block_given?
         | 
| 77 | 
            +
                    response
         | 
| 67 78 | 
             
                  else
         | 
| 68 79 | 
             
                    raise WebMock::NetConnectNotAllowedError.new(request_signature)
         | 
| 69 80 | 
             
                  end
         | 
| @@ -99,11 +110,22 @@ module Net  #:nodoc: all | |
| 99 110 |  | 
| 100 111 | 
             
                  response
         | 
| 101 112 | 
             
                end
         | 
| 113 | 
            +
                
         | 
| 114 | 
            +
                def build_webmock_response(net_http_response)
         | 
| 115 | 
            +
                  webmock_response = WebMock::Response.new
         | 
| 116 | 
            +
                  webmock_response.status = [
         | 
| 117 | 
            +
                     net_http_response.code.to_i,
         | 
| 118 | 
            +
                     net_http_response.message]
         | 
| 119 | 
            +
                  webmock_response.headers = net_http_response.to_hash
         | 
| 120 | 
            +
                  webmock_response.body = net_http_response.body   
         | 
| 121 | 
            +
                  webmock_response
         | 
| 122 | 
            +
                end
         | 
| 102 123 |  | 
| 103 124 | 
             
              end
         | 
| 104 125 |  | 
| 105 126 | 
             
            end
         | 
| 106 127 |  | 
| 128 | 
            +
             | 
| 107 129 | 
             
            module WebMock
         | 
| 108 130 | 
             
              module NetHTTPUtility
         | 
| 109 131 |  | 
| @@ -111,7 +133,7 @@ module WebMock | |
| 111 133 | 
             
                  protocol = net_http.use_ssl? ? "https" : "http"
         | 
| 112 134 |  | 
| 113 135 | 
             
                  path = request.path
         | 
| 114 | 
            -
                  path =  | 
| 136 | 
            +
                  path = WebMock::Util::URI.heuristic_parse(request.path).request_uri if request.path =~ /^http/
         | 
| 115 137 |  | 
| 116 138 | 
             
                  if request["authorization"] =~ /^Basic /
         | 
| 117 139 | 
             
                    userinfo = WebMock::Util::Headers.decode_userinfo_from_header(request["authorization"])
         |