em-http-request 0.2.10 → 0.2.11

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.

@@ -1,6 +1,6 @@
1
- # bytesize was introduced in 1.8.7+
2
- if RUBY_VERSION <= "1.8.6"
3
- class String
4
- def bytesize; self.size; end
5
- end
1
+ # bytesize was introduced in 1.8.7+
2
+ if RUBY_VERSION <= "1.8.6"
3
+ class String
4
+ def bytesize; self.size; end
5
+ end
6
6
  end
@@ -1,53 +1,53 @@
1
- class Hash
2
- # Stolen partially from Merb : http://noobkit.com/show/ruby/gems/development/merb/hash/to_params.html
3
- # Convert this hash to a query string:
4
- #
5
- # { :name => "Bob",
6
- # :address => {
7
- # :street => '111 Ruby Ave.',
8
- # :city => 'Ruby Central',
9
- # :phones => ['111-111-1111', '222-222-2222']
10
- # }
11
- # }.to_params
12
- # #=> "name=Bob&address[city]=Ruby Central&address[phones]=111-111-1111222-222-2222&address[street]=111 Ruby Ave."
13
- #
14
- def to_params
15
- params = ''
16
- stack = []
17
-
18
- each do |k, v|
19
- if v.is_a?(Hash)
20
- stack << [k,v]
21
- elsif v.is_a?(Array)
22
- stack << [k,Hash.from_array(v)]
23
- else
24
- params << "#{k}=#{v}&"
25
- end
26
- end
27
-
28
- stack.each do |parent, hash|
29
- hash.each do |k, v|
30
- if v.is_a?(Hash)
31
- stack << ["#{parent}[#{k}]", v]
32
- else
33
- params << "#{parent}[#{k}]=#{v}&"
34
- end
35
- end
36
- end
37
-
38
- params.chop! # trailing &
39
- params
40
- end
41
-
42
- ##
43
- # Builds a hash from an array with keys as array indices.
44
- def self.from_array(array = [])
45
- h = Hash.new
46
- array.size.times do |t|
47
- h[t] = array[t]
48
- end
49
- h
50
- end
51
-
52
- end
53
-
1
+ class Hash
2
+ # Stolen partially from Merb : http://noobkit.com/show/ruby/gems/development/merb/hash/to_params.html
3
+ # Convert this hash to a query string:
4
+ #
5
+ # { :name => "Bob",
6
+ # :address => {
7
+ # :street => '111 Ruby Ave.',
8
+ # :city => 'Ruby Central',
9
+ # :phones => ['111-111-1111', '222-222-2222']
10
+ # }
11
+ # }.to_params
12
+ # #=> "name=Bob&address[city]=Ruby Central&address[phones]=111-111-1111222-222-2222&address[street]=111 Ruby Ave."
13
+ #
14
+ def to_params
15
+ params = ''
16
+ stack = []
17
+
18
+ each do |k, v|
19
+ if v.is_a?(Hash)
20
+ stack << [k,v]
21
+ elsif v.is_a?(Array)
22
+ stack << [k,Hash.from_array(v)]
23
+ else
24
+ params << "#{k}=#{v}&"
25
+ end
26
+ end
27
+
28
+ stack.each do |parent, hash|
29
+ hash.each do |k, v|
30
+ if v.is_a?(Hash)
31
+ stack << ["#{parent}[#{k}]", v]
32
+ else
33
+ params << "#{parent}[#{k}]=#{v}&"
34
+ end
35
+ end
36
+ end
37
+
38
+ params.chop! # trailing &
39
+ params
40
+ end
41
+
42
+ ##
43
+ # Builds a hash from an array with keys as array indices.
44
+ def self.from_array(array = [])
45
+ h = Hash.new
46
+ array.size.times do |t|
47
+ h[t] = array[t]
48
+ end
49
+ h
50
+ end
51
+
52
+ end
53
+
@@ -1,122 +1,122 @@
1
- require 'zlib'
2
- require 'stringio'
3
-
4
- ##
5
- # Provides a unified callback interface to decompression libraries.
6
- module EventMachine::HttpDecoders
7
-
8
- class DecoderError < StandardError
9
- end
10
-
11
- class << self
12
- def accepted_encodings
13
- DECODERS.inject([]) { |r,d| r + d.encoding_names }
14
- end
15
-
16
- def decoder_for_encoding(encoding)
17
- DECODERS.each { |d|
18
- return d if d.encoding_names.include? encoding
19
- }
20
- nil
21
- end
22
- end
23
-
24
- class Base
25
- def self.encoding_names
26
- name = to_s.split('::').last.downcase
27
- [name]
28
- end
29
-
30
- ##
31
- # chunk_callback:: [Block] To handle a decompressed chunk
32
- def initialize(&chunk_callback)
33
- @chunk_callback = chunk_callback
34
- end
35
-
36
- def <<(compressed)
37
- return unless compressed && compressed.size > 0
38
-
39
- decompressed = decompress(compressed)
40
- receive_decompressed decompressed
41
- end
42
-
43
- def finalize!
44
- decompressed = finalize
45
- receive_decompressed decompressed
46
- end
47
-
48
- private
49
-
50
- def receive_decompressed(decompressed)
51
- if decompressed && decompressed.size > 0
52
- @chunk_callback.call(decompressed)
53
- end
54
- end
55
-
56
- protected
57
-
58
- ##
59
- # Must return a part of decompressed
60
- def decompress(compressed)
61
- nil
62
- end
63
-
64
- ##
65
- # May return last part
66
- def finalize
67
- nil
68
- end
69
- end
70
-
71
- class Deflate < Base
72
- def decompress(compressed)
73
- begin
74
- @zstream ||= Zlib::Inflate.new(nil)
75
- @zstream.inflate(compressed)
76
- rescue Zlib::Error
77
- raise DecoderError
78
- end
79
- end
80
-
81
- def finalize
82
- return nil unless @zstream
83
-
84
- begin
85
- r = @zstream.inflate(nil)
86
- @zstream.close
87
- r
88
- rescue Zlib::Error
89
- raise DecoderError
90
- end
91
- end
92
- end
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
- class GZip < Base
101
- def self.encoding_names
102
- %w(gzip compressed)
103
- end
104
-
105
- def decompress(compressed)
106
- @buf ||= ''
107
- @buf += compressed
108
- nil
109
- end
110
-
111
- def finalize
112
- begin
113
- Zlib::GzipReader.new(StringIO.new(@buf.to_s)).read
114
- rescue Zlib::Error
115
- raise DecoderError
116
- end
117
- end
118
- end
119
-
120
- DECODERS = [Deflate, GZip]
121
-
122
- end
1
+ require 'zlib'
2
+ require 'stringio'
3
+
4
+ ##
5
+ # Provides a unified callback interface to decompression libraries.
6
+ module EventMachine::HttpDecoders
7
+
8
+ class DecoderError < StandardError
9
+ end
10
+
11
+ class << self
12
+ def accepted_encodings
13
+ DECODERS.inject([]) { |r,d| r + d.encoding_names }
14
+ end
15
+
16
+ def decoder_for_encoding(encoding)
17
+ DECODERS.each { |d|
18
+ return d if d.encoding_names.include? encoding
19
+ }
20
+ nil
21
+ end
22
+ end
23
+
24
+ class Base
25
+ def self.encoding_names
26
+ name = to_s.split('::').last.downcase
27
+ [name]
28
+ end
29
+
30
+ ##
31
+ # chunk_callback:: [Block] To handle a decompressed chunk
32
+ def initialize(&chunk_callback)
33
+ @chunk_callback = chunk_callback
34
+ end
35
+
36
+ def <<(compressed)
37
+ return unless compressed && compressed.size > 0
38
+
39
+ decompressed = decompress(compressed)
40
+ receive_decompressed decompressed
41
+ end
42
+
43
+ def finalize!
44
+ decompressed = finalize
45
+ receive_decompressed decompressed
46
+ end
47
+
48
+ private
49
+
50
+ def receive_decompressed(decompressed)
51
+ if decompressed && decompressed.size > 0
52
+ @chunk_callback.call(decompressed)
53
+ end
54
+ end
55
+
56
+ protected
57
+
58
+ ##
59
+ # Must return a part of decompressed
60
+ def decompress(compressed)
61
+ nil
62
+ end
63
+
64
+ ##
65
+ # May return last part
66
+ def finalize
67
+ nil
68
+ end
69
+ end
70
+
71
+ class Deflate < Base
72
+ def decompress(compressed)
73
+ begin
74
+ @zstream ||= Zlib::Inflate.new(nil)
75
+ @zstream.inflate(compressed)
76
+ rescue Zlib::Error
77
+ raise DecoderError
78
+ end
79
+ end
80
+
81
+ def finalize
82
+ return nil unless @zstream
83
+
84
+ begin
85
+ r = @zstream.inflate(nil)
86
+ @zstream.close
87
+ r
88
+ rescue Zlib::Error
89
+ raise DecoderError
90
+ end
91
+ end
92
+ end
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
+ class GZip < Base
101
+ def self.encoding_names
102
+ %w(gzip compressed)
103
+ end
104
+
105
+ def decompress(compressed)
106
+ @buf ||= ''
107
+ @buf += compressed
108
+ nil
109
+ end
110
+
111
+ def finalize
112
+ begin
113
+ Zlib::GzipReader.new(StringIO.new(@buf.to_s)).read
114
+ rescue Zlib::Error
115
+ raise DecoderError
116
+ end
117
+ end
118
+ end
119
+
120
+ DECODERS = [Deflate, GZip]
121
+
122
+ end
@@ -1,32 +1,34 @@
1
- class HttpOptions
2
- attr_reader :uri, :method, :host, :port, :options
3
-
4
- def initialize(method, uri, options)
5
- raise ArgumentError, "invalid request path" unless /^\// === uri.path
6
-
7
- @options = options
8
- @method = method.to_s.upcase
9
- @uri = uri
10
-
11
- if proxy = options[:proxy]
12
- @host = proxy[:host]
13
- @port = proxy[:port]
14
- else
15
- @host = uri.host
16
- @port = uri.port
17
- end
18
-
19
- @options[:timeout] ||= 10 # default connect & inactivity timeouts
20
- @options[:redirects] ||= 0 # default number of redirects to follow
21
-
22
- # Make sure the ports are set as Addressable::URI doesn't
23
- # set the port if it isn't there
24
- if uri.scheme == "https"
25
- @uri.port ||= 443
26
- @port ||= 443
27
- else
28
- @uri.port ||= 80
29
- @port ||= 80
30
- end
31
- end
1
+ class HttpOptions
2
+ attr_reader :uri, :method, :host, :port, :options
3
+
4
+ def initialize(method, uri, options)
5
+ uri.normalize!
6
+
7
+ @options = options
8
+ @method = method.to_s.upcase
9
+ @uri = uri
10
+
11
+ if proxy = options[:proxy]
12
+ @host = proxy[:host]
13
+ @port = proxy[:port]
14
+ else
15
+ # optional host for cases where you may have
16
+ # pre-resolved the host, or you need an override
17
+ @host = options[:host] || uri.host
18
+ @port = uri.port
19
+ end
20
+
21
+ @options[:timeout] ||= 10 # default connect & inactivity timeouts
22
+ @options[:redirects] ||= 0 # default number of redirects to follow
23
+
24
+ # Make sure the ports are set as Addressable::URI doesn't
25
+ # set the port if it isn't there
26
+ if uri.scheme == "https"
27
+ @uri.port ||= 443
28
+ @port ||= 443
29
+ else
30
+ @uri.port ||= 80
31
+ @port ||= 80
32
+ end
33
+ end
32
34
  end
@@ -1,91 +1,131 @@
1
1
  module EventMachine
2
+ OriginalHttpRequest = HttpRequest unless const_defined?(:OriginalHttpRequest)
3
+
2
4
  class MockHttpRequest < EventMachine::HttpRequest
3
-
5
+
4
6
  include HttpEncoding
5
-
6
- class FakeHttpClient < EventMachine::HttpClient
7
7
 
8
+ class RegisteredRequest < Struct.new(:uri, :method, :headers)
9
+ def self.build(uri, method, headers)
10
+ new(uri, method.to_s.upcase, headers || {})
11
+ end
12
+ end
13
+
14
+ class FakeHttpClient < EventMachine::HttpClient
15
+ attr_writer :response
16
+ attr_reader :data
8
17
  def setup(response, uri)
9
18
  @uri = uri
10
19
  if response == :fail
11
20
  fail(self)
12
21
  else
13
- receive_data(response)
14
- succeed(self)
22
+ if response.respond_to?(:call)
23
+ response.call(self)
24
+ @state = :body
25
+ else
26
+ receive_data(response)
27
+ end
28
+ @state == :body ? succeed(self) : fail(self)
15
29
  end
16
30
  end
17
-
31
+
18
32
  def unbind
19
33
  end
20
-
21
34
  end
22
-
23
- @@registry = nil
24
- @@registry_count = nil
25
-
35
+
36
+ @@registry = Hash.new
37
+ @@registry_count = Hash.new{|h,k| h[k] = 0}
38
+
39
+ def self.use
40
+ activate!
41
+ yield
42
+ ensure
43
+ deactivate!
44
+ end
45
+
46
+ def self.activate!
47
+ EventMachine.send(:remove_const, :HttpRequest)
48
+ EventMachine.send(:const_set, :HttpRequest, MockHttpRequest)
49
+ end
50
+
51
+ def self.deactivate!
52
+ EventMachine.send(:remove_const, :HttpRequest)
53
+ EventMachine.send(:const_set, :HttpRequest, OriginalHttpRequest)
54
+ end
55
+
26
56
  def self.reset_counts!
27
- @@registry_count = Hash.new do |registry,query|
28
- registry[query] = Hash.new{|h,k| h[k] = Hash.new(0)}
29
- end
57
+ @@registry_count.clear
30
58
  end
31
-
59
+
32
60
  def self.reset_registry!
33
- @@registry = Hash.new do |registry,query|
34
- registry[query] = Hash.new{|h,k| h[k] = {}}
35
- end
61
+ @@registry.clear
36
62
  end
37
-
38
- reset_counts!
39
- reset_registry!
40
-
63
+
41
64
  @@pass_through_requests = true
42
65
 
43
66
  def self.pass_through_requests=(pass_through_requests)
44
67
  @@pass_through_requests = pass_through_requests
45
68
  end
46
-
69
+
47
70
  def self.pass_through_requests
48
71
  @@pass_through_requests
49
72
  end
50
-
51
- def self.register(uri, method, headers, data)
52
- method = method.to_s.upcase
53
- headers = headers.to_s
54
- @@registry[uri][method][headers] = data
73
+
74
+ def self.parse_register_args(args, &proc)
75
+ args << proc{|client| proc.call(client); ''} if proc
76
+ headers, data = case args.size
77
+ when 3
78
+ args[2].is_a?(Hash) ?
79
+ [args[2][:headers], args[2][:data]] :
80
+ [{}, args[2]]
81
+ when 4
82
+ [args[2], args[3]]
83
+ else
84
+ raise
85
+ end
86
+
87
+ url = args[0]
88
+ method = args[1]
89
+ [headers, url, method, data]
55
90
  end
56
-
57
- def self.register_file(uri, method, headers, file)
58
- register(uri, method, headers, File.read(file))
91
+
92
+ def self.register(*args, &proc)
93
+ headers, url, method, data = parse_register_args(args, &proc)
94
+ @@registry[RegisteredRequest.build(url, method, headers)] = data
59
95
  end
60
-
61
- def self.count(uri, method, headers)
62
- method = method.to_s.upcase
63
- headers = headers.to_s
64
- @@registry_count[uri][method][headers] rescue 0
96
+
97
+ def self.register_file(*args)
98
+ headers, url, method, data = parse_register_args(args)
99
+ @@registry[RegisteredRequest.build(url, method, headers)] = File.read(data)
100
+ end
101
+
102
+ def self.count(url, method, headers = {})
103
+ @@registry_count[RegisteredRequest.build(url, method, headers)]
65
104
  end
66
-
67
- def self.registered?(query, method, headers)
68
- @@registry[query] and @@registry[query][method] and @@registry[query][method][headers]
105
+
106
+ def self.registered?(url, method, headers = {})
107
+ @@registry.key?(RegisteredRequest.build(url, method, headers))
69
108
  end
70
-
71
- def self.registered_content(query, method, headers)
72
- @@registry[query][method][headers]
109
+
110
+ def self.registered_content(url, method, headers = {})
111
+ @@registry[RegisteredRequest.build(url, method, headers)]
73
112
  end
74
-
75
- def self.increment_access(query, method, headers)
76
- @@registry_count[query][method][headers] += 1
113
+
114
+ def self.increment_access(url, method, headers = {})
115
+ @@registry_count[RegisteredRequest.build(url, method, headers)] += 1
77
116
  end
78
-
117
+
79
118
  alias_method :real_send_request, :send_request
80
-
119
+
81
120
  protected
82
121
  def send_request(&blk)
83
- query = "#{@req.uri.scheme}://#{@req.uri.host}:#{@req.uri.port}#{encode_query(@req.uri.path, @req.options[:query], @req.uri.query)}"
84
- headers = @req.options[:head].to_s
122
+ query = "#{@req.uri.scheme}://#{@req.uri.host}:#{@req.uri.port}#{encode_query(@req.uri, @req.options[:query])}"
123
+ headers = @req.options[:head]
85
124
  if self.class.registered?(query, @req.method, headers)
86
125
  self.class.increment_access(query, @req.method, headers)
87
126
  client = FakeHttpClient.new(nil)
88
- client.setup(self.class.registered_content(query, @req.method, headers), @req.uri)
127
+ content = self.class.registered_content(query, @req.method, headers)
128
+ client.setup(content, @req.uri)
89
129
  client
90
130
  elsif @@pass_through_requests
91
131
  real_send_request