em-http-request 1.0.2 → 1.0.3
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.
Potentially problematic release.
This version of em-http-request might be problematic. Click here for more details.
- data/.gitignore +1 -0
- data/benchmarks/clients.rb +44 -30
- data/benchmarks/server.rb +3 -3
- data/em-http-request.gemspec +33 -33
- data/lib/em-http/client.rb +5 -3
- data/lib/em-http/decoders.rb +34 -12
- data/lib/em-http/http_client_options.rb +1 -2
- data/lib/em-http/http_connection.rb +12 -5
- data/lib/em-http/http_connection_options.rb +6 -1
- data/lib/em-http/http_header.rb +3 -0
- data/lib/em-http/version.rb +1 -1
- data/spec/client_fiber_spec.rb +23 -23
- data/spec/client_spec.rb +80 -10
- data/spec/external_spec.rb +150 -128
- data/spec/fixtures/gzip-sample.gz +0 -0
- data/spec/http_proxy_spec.rb +16 -0
- data/spec/pipelining_spec.rb +65 -65
- data/spec/redirect_spec.rb +15 -0
- data/spec/socksify_proxy_spec.rb +24 -24
- data/spec/stallion.rb +23 -3
- metadata +75 -23
    
        data/.gitignore
    CHANGED
    
    
    
        data/benchmarks/clients.rb
    CHANGED
    
    | @@ -9,7 +9,7 @@ require 'rest_client' | |
| 9 9 | 
             
            require 'tach'
         | 
| 10 10 | 
             
            require 'typhoeus'
         | 
| 11 11 |  | 
| 12 | 
            -
            url = 'http://127.0.0.1/ | 
| 12 | 
            +
            url = 'http://127.0.0.1:9292/data/10000'
         | 
| 13 13 |  | 
| 14 14 | 
             
            with_server do
         | 
| 15 15 | 
             
              Tach.meter(100) do
         | 
| @@ -119,38 +119,52 @@ with_server do | |
| 119 119 | 
             
                  streamly.get(url)
         | 
| 120 120 | 
             
                end
         | 
| 121 121 |  | 
| 122 | 
            -
                tach('Typhoeus') do
         | 
| 123 | 
            -
             | 
| 122 | 
            +
                tach('Typhoeus') do |n|
         | 
| 123 | 
            +
                    hydra = Typhoeus::Hydra.new( max_concurrency: 8 )
         | 
| 124 | 
            +
                    hydra.disable_memoization
         | 
| 125 | 
            +
                    count = 0
         | 
| 126 | 
            +
                    error = 0
         | 
| 127 | 
            +
                    n.times {
         | 
| 128 | 
            +
                        req = Typhoeus::Request.new( url )
         | 
| 129 | 
            +
                        req.on_complete do |res|
         | 
| 130 | 
            +
                            count += 1
         | 
| 131 | 
            +
                            error += 1 if !res.success?
         | 
| 132 | 
            +
                            p [count, error] if count == n
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                        end
         | 
| 135 | 
            +
                        hydra.queue( req )
         | 
| 136 | 
            +
                    }
         | 
| 137 | 
            +
                    hydra.run
         | 
| 124 138 | 
             
                end
         | 
| 125 139 |  | 
| 126 140 | 
             
              end
         | 
| 127 141 | 
             
            end
         | 
| 128 142 |  | 
| 129 143 |  | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 147 | 
            -
             | 
| 148 | 
            -
             | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
             | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 | 
            -
             | 
| 156 | 
            -
             | 
| 144 | 
            +
            #+------------------------------+-----------+
         | 
| 145 | 
            +
            #| tach                         | total     |
         | 
| 146 | 
            +
            #+------------------------------+-----------+
         | 
| 147 | 
            +
            #| em-http-request (persistent) | 0.145512  |
         | 
| 148 | 
            +
            #+------------------------------+-----------+
         | 
| 149 | 
            +
            #| Excon                        | 0.181564  |
         | 
| 150 | 
            +
            #+------------------------------+-----------+
         | 
| 151 | 
            +
            #| RestClient                   | 0.253127  |
         | 
| 152 | 
            +
            #+------------------------------+-----------+
         | 
| 153 | 
            +
            #| Net::HTTP                    | 0.294412  |
         | 
| 154 | 
            +
            #+------------------------------+-----------+
         | 
| 155 | 
            +
            #| HTTParty                     | 0.305397  |
         | 
| 156 | 
            +
            #+------------------------------+-----------+
         | 
| 157 | 
            +
            #| open-uri                     | 0.307007  |
         | 
| 158 | 
            +
            #+------------------------------+-----------+
         | 
| 159 | 
            +
            #| Net::HTTP (persistent)       | 0.313716  |
         | 
| 160 | 
            +
            #+------------------------------+-----------+
         | 
| 161 | 
            +
            #| Typhoeus                     | 0.514725  |
         | 
| 162 | 
            +
            #+------------------------------+-----------+
         | 
| 163 | 
            +
            #| curb (persistent)            | 3.981700  |
         | 
| 164 | 
            +
            #+------------------------------+-----------+
         | 
| 165 | 
            +
            #| StreamlyFFI (persistent)     | 3.989063  |
         | 
| 166 | 
            +
            #+------------------------------+-----------+
         | 
| 167 | 
            +
            #| Excon (persistent)           | 4.018761  |
         | 
| 168 | 
            +
            #+------------------------------+-----------+
         | 
| 169 | 
            +
            #| em-http-request              | 15.025291 |
         | 
| 170 | 
            +
            #+------------------------------+-----------+
         | 
    
        data/benchmarks/server.rb
    CHANGED
    
    | @@ -32,12 +32,12 @@ end | |
| 32 32 |  | 
| 33 33 | 
             
            def with_server(&block)
         | 
| 34 34 | 
             
              pid = Process.fork do
         | 
| 35 | 
            -
             | 
| 35 | 
            +
                 Benchmark::Server.run
         | 
| 36 36 | 
             
              end
         | 
| 37 37 | 
             
              loop do
         | 
| 38 38 | 
             
                sleep(1)
         | 
| 39 39 | 
             
                begin
         | 
| 40 | 
            -
                  # | 
| 40 | 
            +
                  #Excon.get('http://localhost:9292/api/foo')
         | 
| 41 41 | 
             
                  break
         | 
| 42 42 | 
             
                rescue
         | 
| 43 43 | 
             
                end
         | 
| @@ -45,4 +45,4 @@ def with_server(&block) | |
| 45 45 | 
             
              yield
         | 
| 46 46 | 
             
            ensure
         | 
| 47 47 | 
             
              Process.kill(9, pid)
         | 
| 48 | 
            -
            end
         | 
| 48 | 
            +
            end
         | 
    
        data/em-http-request.gemspec
    CHANGED
    
    | @@ -1,33 +1,33 @@ | |
| 1 | 
            -
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            -
            $:.push File.expand_path("../lib", __FILE__)
         | 
| 3 | 
            -
            require "em-http/version"
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            Gem::Specification.new do |s|
         | 
| 6 | 
            -
              s.name        = "em-http-request"
         | 
| 7 | 
            -
              s.version     = EventMachine::HttpRequest::VERSION
         | 
| 8 | 
            -
             | 
| 9 | 
            -
              s.platform    = Gem::Platform::RUBY
         | 
| 10 | 
            -
              s.authors     = ["Ilya Grigorik"]
         | 
| 11 | 
            -
              s.email       = ["ilya@igvita.com"]
         | 
| 12 | 
            -
              s.homepage    = "http://github.com/igrigorik/em-http-request"
         | 
| 13 | 
            -
              s.summary     = "EventMachine based, async HTTP Request client"
         | 
| 14 | 
            -
              s.description = s.summary
         | 
| 15 | 
            -
              s.rubyforge_project = "em-http-request"
         | 
| 16 | 
            -
             | 
| 17 | 
            -
              s.add_dependency "eventmachine", ">= 1.0.0.beta.4"
         | 
| 18 | 
            -
              s.add_dependency "addressable", ">= 2.2.3"
         | 
| 19 | 
            -
              s.add_dependency "http_parser.rb", ">= 0.5.3"
         | 
| 20 | 
            -
              s.add_dependency "em-socksify"
         | 
| 21 | 
            -
              s.add_dependency "cookiejar"
         | 
| 22 | 
            -
             | 
| 23 | 
            -
              s.add_development_dependency "rspec"
         | 
| 24 | 
            -
              s.add_development_dependency "rake"
         | 
| 25 | 
            -
              s.add_development_dependency "rack"
         | 
| 26 | 
            -
              s.add_development_dependency "yajl-ruby"
         | 
| 27 | 
            -
              s.add_development_dependency "mongrel", "~> 1.2.0.pre2"
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              s.files         = `git ls-files`.split("\n")
         | 
| 30 | 
            -
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 31 | 
            -
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 32 | 
            -
              s.require_paths = ["lib"]
         | 
| 33 | 
            -
            end
         | 
| 1 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            +
            $:.push File.expand_path("../lib", __FILE__)
         | 
| 3 | 
            +
            require "em-http/version"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |s|
         | 
| 6 | 
            +
              s.name        = "em-http-request"
         | 
| 7 | 
            +
              s.version     = EventMachine::HttpRequest::VERSION
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              s.platform    = Gem::Platform::RUBY
         | 
| 10 | 
            +
              s.authors     = ["Ilya Grigorik"]
         | 
| 11 | 
            +
              s.email       = ["ilya@igvita.com"]
         | 
| 12 | 
            +
              s.homepage    = "http://github.com/igrigorik/em-http-request"
         | 
| 13 | 
            +
              s.summary     = "EventMachine based, async HTTP Request client"
         | 
| 14 | 
            +
              s.description = s.summary
         | 
| 15 | 
            +
              s.rubyforge_project = "em-http-request"
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              s.add_dependency "eventmachine", ">= 1.0.0.beta.4"
         | 
| 18 | 
            +
              s.add_dependency "addressable", ">= 2.2.3"
         | 
| 19 | 
            +
              s.add_dependency "http_parser.rb", ">= 0.5.3"
         | 
| 20 | 
            +
              s.add_dependency "em-socksify"
         | 
| 21 | 
            +
              s.add_dependency "cookiejar"
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              s.add_development_dependency "rspec"
         | 
| 24 | 
            +
              s.add_development_dependency "rake"
         | 
| 25 | 
            +
              s.add_development_dependency "rack"
         | 
| 26 | 
            +
              s.add_development_dependency "yajl-ruby"
         | 
| 27 | 
            +
              s.add_development_dependency "mongrel", "~> 1.2.0.pre2"
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              s.files         = `git ls-files`.split("\n")
         | 
| 30 | 
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 31 | 
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 32 | 
            +
              s.require_paths = ["lib"]
         | 
| 33 | 
            +
            end
         | 
    
        data/lib/em-http/client.rb
    CHANGED
    
    | @@ -133,9 +133,10 @@ module EventMachine | |
| 133 133 |  | 
| 134 134 | 
             
                def build_request
         | 
| 135 135 | 
             
                  head    = @req.headers ? munge_header_keys(@req.headers) : {}
         | 
| 136 | 
            -
             | 
| 137 | 
            -
                  if @ | 
| 138 | 
            -
                     | 
| 136 | 
            +
                  
         | 
| 137 | 
            +
                  if @conn.connopts.http_proxy?
         | 
| 138 | 
            +
                    proxy = @conn.connopts.proxy
         | 
| 139 | 
            +
                    head['proxy-authorization'] = proxy[:authorization] if proxy[:authorization]
         | 
| 139 140 | 
             
                  end
         | 
| 140 141 |  | 
| 141 142 | 
             
                  # Set the cookie header if provided
         | 
| @@ -217,6 +218,7 @@ module EventMachine | |
| 217 218 | 
             
                end
         | 
| 218 219 |  | 
| 219 220 | 
             
                def parse_response_header(header, version, status)
         | 
| 221 | 
            +
                  @response_header.raw = header
         | 
| 220 222 | 
             
                  header.each do |key, val|
         | 
| 221 223 | 
             
                    @response_header[key.upcase.gsub('-','_')] = val
         | 
| 222 224 | 
             
                  end
         | 
    
        data/lib/em-http/decoders.rb
    CHANGED
    
    | @@ -10,7 +10,7 @@ module EventMachine::HttpDecoders | |
| 10 10 |  | 
| 11 11 | 
             
              class << self
         | 
| 12 12 | 
             
                def accepted_encodings
         | 
| 13 | 
            -
                  DECODERS.inject([]) { |r,d| r + d.encoding_names }
         | 
| 13 | 
            +
                  DECODERS.inject([]) { |r, d| r + d.encoding_names }
         | 
| 14 14 | 
             
                end
         | 
| 15 15 |  | 
| 16 16 | 
             
                def decoder_for_encoding(encoding)
         | 
| @@ -44,7 +44,7 @@ module EventMachine::HttpDecoders | |
| 44 44 | 
             
                  decompressed = finalize
         | 
| 45 45 | 
             
                  receive_decompressed decompressed
         | 
| 46 46 | 
             
                end
         | 
| 47 | 
            -
             | 
| 47 | 
            +
             | 
| 48 48 | 
             
                private
         | 
| 49 49 |  | 
| 50 50 | 
             
                def receive_decompressed(decompressed)
         | 
| @@ -91,30 +91,52 @@ module EventMachine::HttpDecoders | |
| 91 91 | 
             
                end
         | 
| 92 92 | 
             
              end
         | 
| 93 93 |  | 
| 94 | 
            -
              ##
         | 
| 95 | 
            -
              # Oneshot decompressor, due to lack of a streaming Gzip reader
         | 
| 96 | 
            -
              # implementation. We may steal code from Zliby to improve this.
         | 
| 97 | 
            -
              #
         | 
| 98 | 
            -
              # For now, do not put `gzip' or `compressed' in your accept-encoding
         | 
| 99 | 
            -
              # header if you expect much data through the :on_response interface.
         | 
| 100 94 | 
             
              class GZip < Base
         | 
| 101 95 | 
             
                def self.encoding_names
         | 
| 102 96 | 
             
                  %w(gzip compressed)
         | 
| 103 97 | 
             
                end
         | 
| 104 98 |  | 
| 105 99 | 
             
                def decompress(compressed)
         | 
| 106 | 
            -
                  @buf ||=  | 
| 107 | 
            -
                  @buf  | 
| 108 | 
            -
             | 
| 100 | 
            +
                  @buf ||= LazyStringIO.new
         | 
| 101 | 
            +
                  @buf << compressed
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  # Zlib::GzipReader loads input in 2048 byte chunks
         | 
| 104 | 
            +
                  if @buf.size > 2048
         | 
| 105 | 
            +
                    @gzip ||= Zlib::GzipReader.new @buf
         | 
| 106 | 
            +
                    @gzip.readline
         | 
| 107 | 
            +
                  end
         | 
| 109 108 | 
             
                end
         | 
| 110 109 |  | 
| 111 110 | 
             
                def finalize
         | 
| 112 111 | 
             
                  begin
         | 
| 113 | 
            -
                    Zlib::GzipReader.new | 
| 112 | 
            +
                    @gzip ||= Zlib::GzipReader.new @buf
         | 
| 113 | 
            +
                    @gzip.read
         | 
| 114 114 | 
             
                  rescue Zlib::Error
         | 
| 115 115 | 
             
                    raise DecoderError
         | 
| 116 116 | 
             
                  end
         | 
| 117 117 | 
             
                end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                class LazyStringIO
         | 
| 120 | 
            +
                  def initialize(string="")
         | 
| 121 | 
            +
                    @stream = string
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                  def <<(string)
         | 
| 125 | 
            +
                    @stream << string
         | 
| 126 | 
            +
                  end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                  def read(length=nil, buffer=nil)
         | 
| 129 | 
            +
                    buffer ||= ""
         | 
| 130 | 
            +
                    length ||= 0
         | 
| 131 | 
            +
                    buffer << @stream[0..(length-1)]
         | 
| 132 | 
            +
                    @stream = @stream[length..-1]
         | 
| 133 | 
            +
                    buffer
         | 
| 134 | 
            +
                  end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                  def size
         | 
| 137 | 
            +
                    @stream.size
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
                end
         | 
| 118 140 | 
             
              end
         | 
| 119 141 |  | 
| 120 142 | 
             
              DECODERS = [Deflate, GZip]
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            class HttpClientOptions
         | 
| 2 | 
            -
              attr_reader :uri, :method, :host, :port | 
| 2 | 
            +
              attr_reader :uri, :method, :host, :port
         | 
| 3 3 | 
             
              attr_reader :headers, :file, :body, :query, :path
         | 
| 4 4 | 
             
              attr_reader :keepalive, :pass_cookies, :decoding
         | 
| 5 5 |  | 
| @@ -25,7 +25,6 @@ class HttpClientOptions | |
| 25 25 | 
             
              end
         | 
| 26 26 |  | 
| 27 27 | 
             
              def follow_redirect?; @followed < @redirects; end
         | 
| 28 | 
            -
              def http_proxy?; @proxy && [nil, :http].include?(@proxy[:type]); end
         | 
| 29 28 | 
             
              def ssl?; @uri.scheme == "https" || @uri.port == 443; end
         | 
| 30 29 | 
             
              def no_body?; @method == "HEAD"; end
         | 
| 31 30 |  | 
| @@ -1,11 +1,13 @@ | |
| 1 1 | 
             
            module EventMachine
         | 
| 2 2 |  | 
| 3 3 | 
             
              module HTTPMethods
         | 
| 4 | 
            -
                def get | 
| 5 | 
            -
                def head | 
| 6 | 
            -
                def delete | 
| 7 | 
            -
                def put | 
| 8 | 
            -
                def post | 
| 4 | 
            +
                def get      options = {}, &blk;  setup_request(:get,     options, &blk); end
         | 
| 5 | 
            +
                def head     options = {}, &blk;  setup_request(:head,    options, &blk); end
         | 
| 6 | 
            +
                def delete   options = {}, &blk;  setup_request(:delete,  options, &blk); end
         | 
| 7 | 
            +
                def put      options = {}, &blk;  setup_request(:put,     options, &blk); end
         | 
| 8 | 
            +
                def post     options = {}, &blk;  setup_request(:post,    options, &blk); end
         | 
| 9 | 
            +
                def patch    options = {}, &blk;  setup_request(:patch,   options, &blk); end
         | 
| 10 | 
            +
                def options  options = {}, &blk;  setup_request(:options, options, &blk); end
         | 
| 9 11 | 
             
              end
         | 
| 10 12 |  | 
| 11 13 | 
             
              class HttpStubConnection < Connection
         | 
| @@ -180,10 +182,15 @@ module EventMachine | |
| 180 182 | 
             
                        @conn.reconnect(r.req.host, r.req.port)
         | 
| 181 183 | 
             
                      end
         | 
| 182 184 |  | 
| 185 | 
            +
                      @conn.pending_connect_timeout = @connopts.connect_timeout
         | 
| 186 | 
            +
                      @conn.comm_inactivity_timeout = @connopts.inactivity_timeout
         | 
| 183 187 | 
             
                      @conn.callback { r.connection_completed }
         | 
| 184 188 | 
             
                    rescue EventMachine::ConnectionError => e
         | 
| 185 189 | 
             
                      @clients.pop.close(e.message)
         | 
| 186 190 | 
             
                    end
         | 
| 191 | 
            +
                  else
         | 
| 192 | 
            +
                    @deferred = true
         | 
| 193 | 
            +
                    @conn.close_connection
         | 
| 187 194 | 
             
                  end
         | 
| 188 195 | 
             
                end
         | 
| 189 196 | 
             
                alias :close :unbind
         | 
| @@ -11,7 +11,10 @@ class HttpConnectionOptions | |
| 11 11 |  | 
| 12 12 | 
             
                if bind = options[:bind]
         | 
| 13 13 | 
             
                  @bind = bind[:host] || '0.0.0.0'
         | 
| 14 | 
            -
             | 
| 14 | 
            +
             | 
| 15 | 
            +
                  # Eventmachine will open a UNIX socket if bind :port
         | 
| 16 | 
            +
                  # is explicitly set to nil
         | 
| 17 | 
            +
                  @bind_port = bind[:port]
         | 
| 15 18 | 
             
                end
         | 
| 16 19 |  | 
| 17 20 | 
             
                uri = uri.kind_of?(Addressable::URI) ? uri : Addressable::URI::parse(uri.to_s)
         | 
| @@ -25,4 +28,6 @@ class HttpConnectionOptions | |
| 25 28 | 
             
                  @port = uri.port
         | 
| 26 29 | 
             
                end
         | 
| 27 30 | 
             
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def http_proxy?; @proxy && [nil, :http].include?(@proxy[:type]); end
         | 
| 28 33 | 
             
            end
         | 
    
        data/lib/em-http/http_header.rb
    CHANGED
    
    
    
        data/lib/em-http/version.rb
    CHANGED
    
    
    
        data/spec/client_fiber_spec.rb
    CHANGED
    
    | @@ -1,23 +1,23 @@ | |
| 1 | 
            -
            require 'helper'
         | 
| 2 | 
            -
            require 'fiber'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            describe EventMachine::HttpRequest do
         | 
| 5 | 
            -
              context "with fibers" do
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                it "should be transparent to connection errors" do
         | 
| 8 | 
            -
                  EventMachine.run do
         | 
| 9 | 
            -
                    Fiber.new do
         | 
| 10 | 
            -
                      f = Fiber.current
         | 
| 11 | 
            -
                      fired = false
         | 
| 12 | 
            -
                      http = EventMachine::HttpRequest.new('http://non-existing.domain/', :connection_timeout => 0.1).get
         | 
| 13 | 
            -
                      http.callback { failed(http) }
         | 
| 14 | 
            -
                      http.errback { f.resume :errback }
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                      Fiber.yield.should == :errback
         | 
| 17 | 
            -
                      EM.stop
         | 
| 18 | 
            -
                    end.resume
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
            end
         | 
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
            require 'fiber'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe EventMachine::HttpRequest do
         | 
| 5 | 
            +
              context "with fibers" do
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                it "should be transparent to connection errors" do
         | 
| 8 | 
            +
                  EventMachine.run do
         | 
| 9 | 
            +
                    Fiber.new do
         | 
| 10 | 
            +
                      f = Fiber.current
         | 
| 11 | 
            +
                      fired = false
         | 
| 12 | 
            +
                      http = EventMachine::HttpRequest.new('http://non-existing.domain/', :connection_timeout => 0.1).get
         | 
| 13 | 
            +
                      http.callback { failed(http) }
         | 
| 14 | 
            +
                      http.errback { f.resume :errback }
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                      Fiber.yield.should == :errback
         | 
| 17 | 
            +
                      EM.stop
         | 
| 18 | 
            +
                    end.resume
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
    
        data/spec/client_spec.rb
    CHANGED
    
    | @@ -188,6 +188,19 @@ describe EventMachine::HttpRequest do | |
| 188 188 | 
             
                }
         | 
| 189 189 | 
             
              end
         | 
| 190 190 |  | 
| 191 | 
            +
              it "should perform successful PATCH" do
         | 
| 192 | 
            +
                EventMachine.run {
         | 
| 193 | 
            +
                  http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').patch :body => "data"
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                  http.errback { failed(http) }
         | 
| 196 | 
            +
                  http.callback {
         | 
| 197 | 
            +
                    http.response_header.status.should == 200
         | 
| 198 | 
            +
                    http.response.should match(/data/)
         | 
| 199 | 
            +
                    EventMachine.stop
         | 
| 200 | 
            +
                  }
         | 
| 201 | 
            +
                }
         | 
| 202 | 
            +
              end
         | 
| 203 | 
            +
             | 
| 191 204 | 
             
              it "should escape body on POST" do
         | 
| 192 205 | 
             
                EventMachine.run {
         | 
| 193 206 | 
             
                  http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => {:stuff => 'string&string'}
         | 
| @@ -214,7 +227,7 @@ describe EventMachine::HttpRequest do | |
| 214 227 | 
             
                  }
         | 
| 215 228 | 
             
                }
         | 
| 216 229 | 
             
              end
         | 
| 217 | 
            -
             | 
| 230 | 
            +
             | 
| 218 231 | 
             
              it "should set content-length to 0 on posts with empty bodies" do
         | 
| 219 232 | 
             
                EventMachine.run {
         | 
| 220 233 | 
             
                  http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_length_from_header').post
         | 
| @@ -343,6 +356,20 @@ describe EventMachine::HttpRequest do | |
| 343 356 | 
             
                }
         | 
| 344 357 | 
             
              end
         | 
| 345 358 |  | 
| 359 | 
            +
              it "should return raw headers in a hash" do
         | 
| 360 | 
            +
                EventMachine.run {
         | 
| 361 | 
            +
                  http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_headers').get
         | 
| 362 | 
            +
             | 
| 363 | 
            +
                  http.errback { failed(http) }
         | 
| 364 | 
            +
                  http.callback {
         | 
| 365 | 
            +
                    http.response_header.status.should == 200
         | 
| 366 | 
            +
                    http.response_header.raw['Set-Cookie'].should match('test=yes')
         | 
| 367 | 
            +
                    http.response_header.raw['X-Forward-Host'].should match('proxy.local')
         | 
| 368 | 
            +
                    EventMachine.stop
         | 
| 369 | 
            +
                  }
         | 
| 370 | 
            +
                }
         | 
| 371 | 
            +
              end
         | 
| 372 | 
            +
             | 
| 346 373 | 
             
              it "should detect deflate encoding" do
         | 
| 347 374 | 
             
                EventMachine.run {
         | 
| 348 375 |  | 
| @@ -362,18 +389,40 @@ describe EventMachine::HttpRequest do | |
| 362 389 | 
             
              it "should detect gzip encoding" do
         | 
| 363 390 | 
             
                EventMachine.run {
         | 
| 364 391 |  | 
| 365 | 
            -
                  http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/gzip').get :head => {
         | 
| 366 | 
            -
                  "accept-encoding" => "gzip, compressed"
         | 
| 367 | 
            -
                }
         | 
| 392 | 
            +
                  http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/gzip').get :head => {"accept-encoding" => "gzip, compressed"}
         | 
| 368 393 |  | 
| 369 | 
            -
             | 
| 370 | 
            -
             | 
| 371 | 
            -
             | 
| 372 | 
            -
             | 
| 373 | 
            -
             | 
| 394 | 
            +
                  http.errback { failed(http) }
         | 
| 395 | 
            +
                  http.callback {
         | 
| 396 | 
            +
                    http.response_header.status.should == 200
         | 
| 397 | 
            +
                    http.response_header["CONTENT_ENCODING"].should == "gzip"
         | 
| 398 | 
            +
                    http.response.should == "compressed"
         | 
| 374 399 |  | 
| 375 | 
            -
             | 
| 400 | 
            +
                    EventMachine.stop
         | 
| 401 | 
            +
                  }
         | 
| 376 402 | 
             
                }
         | 
| 403 | 
            +
              end
         | 
| 404 | 
            +
             | 
| 405 | 
            +
              it "should stream gzip responses" do
         | 
| 406 | 
            +
                expected_response = Zlib::GzipReader.open(File.dirname(__FILE__) + "/fixtures/gzip-sample.gz") { |f| f.read }
         | 
| 407 | 
            +
                actual_response = ''
         | 
| 408 | 
            +
             | 
| 409 | 
            +
                EventMachine.run {
         | 
| 410 | 
            +
             | 
| 411 | 
            +
                  http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/gzip-large').get :head => {"accept-encoding" => "gzip, compressed"}
         | 
| 412 | 
            +
             | 
| 413 | 
            +
                  http.errback { failed(http) }
         | 
| 414 | 
            +
                  http.callback {
         | 
| 415 | 
            +
                    http.response_header.status.should == 200
         | 
| 416 | 
            +
                    http.response_header["CONTENT_ENCODING"].should == "gzip"
         | 
| 417 | 
            +
                    http.response.should == ''
         | 
| 418 | 
            +
             | 
| 419 | 
            +
                    actual_response.should == expected_response
         | 
| 420 | 
            +
             | 
| 421 | 
            +
                    EventMachine.stop
         | 
| 422 | 
            +
                  }
         | 
| 423 | 
            +
                  http.stream do |chunk|
         | 
| 424 | 
            +
                    actual_response << chunk
         | 
| 425 | 
            +
                  end
         | 
| 377 426 | 
             
                }
         | 
| 378 427 | 
             
              end
         | 
| 379 428 |  | 
| @@ -633,6 +682,9 @@ describe EventMachine::HttpRequest do | |
| 633 682 | 
             
              end
         | 
| 634 683 |  | 
| 635 684 | 
             
              it "should get the body without Content-Length" do
         | 
| 685 | 
            +
                pending "blocked on new http_parser.rb release"
         | 
| 686 | 
            +
                # https://github.com/igrigorik/em-http-request/issues/168
         | 
| 687 | 
            +
             | 
| 636 688 | 
             
                EventMachine.run {
         | 
| 637 689 | 
             
                  @s = StubServer.new("HTTP/1.1 200 OK\r\n\r\nFoo")
         | 
| 638 690 |  | 
| @@ -709,6 +761,24 @@ describe EventMachine::HttpRequest do | |
| 709 761 | 
             
                }
         | 
| 710 762 | 
             
              end
         | 
| 711 763 |  | 
| 764 | 
            +
              it "should reconnect if connection was closed between requests" do
         | 
| 765 | 
            +
                EventMachine.run {
         | 
| 766 | 
            +
                  conn = EM::HttpRequest.new('http://127.0.0.1:8090/', :inactivity_timeout => 0.5)
         | 
| 767 | 
            +
                  req = conn.get :keepalive => true
         | 
| 768 | 
            +
             | 
| 769 | 
            +
                  req.callback do
         | 
| 770 | 
            +
                    EM.add_timer(1) do
         | 
| 771 | 
            +
                      req = conn.get
         | 
| 772 | 
            +
             | 
| 773 | 
            +
                      req.callback do
         | 
| 774 | 
            +
                        req.response_header.status.should == 200
         | 
| 775 | 
            +
                        EventMachine.stop
         | 
| 776 | 
            +
                      end
         | 
| 777 | 
            +
                    end
         | 
| 778 | 
            +
                  end
         | 
| 779 | 
            +
                }
         | 
| 780 | 
            +
              end
         | 
| 781 | 
            +
             | 
| 712 782 | 
             
              it 'should handle malformed Content-Type header repetitions' do
         | 
| 713 783 | 
             
                EventMachine.run {
         | 
| 714 784 | 
             
                  response =<<-HTTP.gsub(/^ +/, '').strip
         |