ably-em-http-request 1.1.8

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.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.github/workflows/ci.yml +22 -0
  4. data/.gitignore +9 -0
  5. data/.rspec +0 -0
  6. data/Changelog.md +78 -0
  7. data/Gemfile +14 -0
  8. data/LICENSE +21 -0
  9. data/README.md +66 -0
  10. data/Rakefile +10 -0
  11. data/ably-em-http-request.gemspec +33 -0
  12. data/benchmarks/clients.rb +170 -0
  13. data/benchmarks/em-excon.rb +87 -0
  14. data/benchmarks/em-profile.gif +0 -0
  15. data/benchmarks/em-profile.txt +65 -0
  16. data/benchmarks/server.rb +48 -0
  17. data/examples/.gitignore +1 -0
  18. data/examples/digest_auth/client.rb +25 -0
  19. data/examples/digest_auth/server.rb +28 -0
  20. data/examples/fetch.rb +30 -0
  21. data/examples/fibered-http.rb +51 -0
  22. data/examples/multi.rb +25 -0
  23. data/examples/oauth-tweet.rb +35 -0
  24. data/examples/socks5.rb +23 -0
  25. data/lib/em/io_streamer.rb +51 -0
  26. data/lib/em-http/client.rb +343 -0
  27. data/lib/em-http/core_ext/bytesize.rb +6 -0
  28. data/lib/em-http/decoders.rb +252 -0
  29. data/lib/em-http/http_client_options.rb +51 -0
  30. data/lib/em-http/http_connection.rb +408 -0
  31. data/lib/em-http/http_connection_options.rb +72 -0
  32. data/lib/em-http/http_encoding.rb +151 -0
  33. data/lib/em-http/http_header.rb +85 -0
  34. data/lib/em-http/http_status_codes.rb +59 -0
  35. data/lib/em-http/middleware/digest_auth.rb +114 -0
  36. data/lib/em-http/middleware/json_response.rb +17 -0
  37. data/lib/em-http/middleware/oauth.rb +42 -0
  38. data/lib/em-http/middleware/oauth2.rb +30 -0
  39. data/lib/em-http/multi.rb +59 -0
  40. data/lib/em-http/request.rb +25 -0
  41. data/lib/em-http/version.rb +7 -0
  42. data/lib/em-http-request.rb +1 -0
  43. data/lib/em-http.rb +20 -0
  44. data/spec/client_fiber_spec.rb +23 -0
  45. data/spec/client_spec.rb +1000 -0
  46. data/spec/digest_auth_spec.rb +48 -0
  47. data/spec/dns_spec.rb +41 -0
  48. data/spec/encoding_spec.rb +49 -0
  49. data/spec/external_spec.rb +146 -0
  50. data/spec/fixtures/google.ca +16 -0
  51. data/spec/fixtures/gzip-sample.gz +0 -0
  52. data/spec/gzip_spec.rb +91 -0
  53. data/spec/helper.rb +27 -0
  54. data/spec/http_proxy_spec.rb +268 -0
  55. data/spec/middleware/oauth2_spec.rb +15 -0
  56. data/spec/middleware_spec.rb +143 -0
  57. data/spec/multi_spec.rb +104 -0
  58. data/spec/pipelining_spec.rb +62 -0
  59. data/spec/redirect_spec.rb +430 -0
  60. data/spec/socksify_proxy_spec.rb +56 -0
  61. data/spec/spec_helper.rb +25 -0
  62. data/spec/ssl_spec.rb +67 -0
  63. data/spec/stallion.rb +334 -0
  64. data/spec/stub_server.rb +45 -0
  65. metadata +269 -0
@@ -0,0 +1,15 @@
1
+ describe EventMachine::AblyHttpRequest::Middleware::OAuth2 do
2
+ it "should add an access token to a URI with no query parameters" do
3
+ middleware = EventMachine::AblyHttpRequest::Middleware::OAuth2.new(:access_token => "fedcba9876543210")
4
+ uri = Addressable::URI.parse("https://graph.facebook.com/me")
5
+ middleware.update_uri! uri
6
+ uri.to_s.should == "https://graph.facebook.com/me?access_token=fedcba9876543210"
7
+ end
8
+
9
+ it "should add an access token to a URI with query parameters" do
10
+ middleware = EventMachine::AblyHttpRequest::Middleware::OAuth2.new(:access_token => "fedcba9876543210")
11
+ uri = Addressable::URI.parse("https://graph.facebook.com/me?fields=photo")
12
+ middleware.update_uri! uri
13
+ uri.to_s.should == "https://graph.facebook.com/me?fields=photo&access_token=fedcba9876543210"
14
+ end
15
+ end
@@ -0,0 +1,143 @@
1
+ require 'helper'
2
+
3
+ describe EventMachine::AblyHttpRequest::HttpRequest do
4
+
5
+ class EmptyMiddleware; end
6
+
7
+ class GlobalMiddleware
8
+ def response(resp)
9
+ resp.response_header['X-Global'] = 'middleware'
10
+ end
11
+ end
12
+
13
+ it "should accept middleware" do
14
+ EventMachine.run {
15
+ lambda {
16
+ conn = EM::AblyHttpRequest::HttpRequest.new('http://127.0.0.1:8090')
17
+ conn.use ResponseMiddleware
18
+ conn.use EmptyMiddleware
19
+
20
+ EM.stop
21
+ }.should_not raise_error
22
+ }
23
+ end
24
+
25
+ context "configuration" do
26
+ class ConfigurableMiddleware
27
+ def initialize(conf, &block)
28
+ @conf = conf
29
+ @block = block
30
+ end
31
+
32
+ def response(resp)
33
+ resp.response_header['X-Conf'] = @conf
34
+ resp.response_header['X-Block'] = @block.call
35
+ end
36
+ end
37
+
38
+ it "should accept middleware initialization parameters" do
39
+ EventMachine.run {
40
+ conn = EM::AblyHttpRequest::HttpRequest.new('http://127.0.0.1:8090')
41
+ conn.use ConfigurableMiddleware, 'conf-value' do
42
+ 'block-value'
43
+ end
44
+
45
+ req = conn.get
46
+ req.callback {
47
+ req.response_header['X-Conf'].should match('conf-value')
48
+ req.response_header['X-Block'].should match('block-value')
49
+ EM.stop
50
+ }
51
+ }
52
+ end
53
+ end
54
+
55
+ context "request" do
56
+ class ResponseMiddleware
57
+ def response(resp)
58
+ resp.response_header['X-Header'] = 'middleware'
59
+ resp.response = 'Hello, Middleware!'
60
+ end
61
+ end
62
+
63
+ it "should execute response middleware before user callbacks" do
64
+ EventMachine.run {
65
+ conn = EM::AblyHttpRequest::HttpRequest.new('http://127.0.0.1:8090')
66
+ conn.use ResponseMiddleware
67
+
68
+ req = conn.get
69
+ req.callback {
70
+ req.response_header['X-Header'].should match('middleware')
71
+ req.response.should match('Hello, Middleware!')
72
+ EM.stop
73
+ }
74
+ }
75
+ end
76
+
77
+ it "should execute global response middleware before user callbacks" do
78
+ EventMachine.run {
79
+ EM::AblyHttpRequest::HttpRequest.use GlobalMiddleware
80
+
81
+ conn = EM::AblyHttpRequest::HttpRequest.new('http://127.0.0.1:8090')
82
+
83
+ req = conn.get
84
+ req.callback {
85
+ req.response_header['X-Global'].should match('middleware')
86
+ EM.stop
87
+ }
88
+ }
89
+ end
90
+ end
91
+
92
+ context "request" do
93
+ class RequestMiddleware
94
+ def request(client, head, body)
95
+ head['X-Middleware'] = 'middleware' # insert new header
96
+ body += ' modified' # modify post body
97
+
98
+ [head, body]
99
+ end
100
+ end
101
+
102
+ it "should execute request middleware before dispatching request" do
103
+ EventMachine.run {
104
+ conn = EventMachine::AblyHttpRequest::HttpRequest.new('http://127.0.0.1:8090/')
105
+ conn.use RequestMiddleware
106
+
107
+ req = conn.post :body => "data"
108
+ req.callback {
109
+ req.response_header.status.should == 200
110
+ req.response.should match(/data modified/)
111
+ EventMachine.stop
112
+ }
113
+ }
114
+ end
115
+ end
116
+
117
+ context "jsonify" do
118
+ class JSONify
119
+ def request(client, head, body)
120
+ [head, MultiJson.dump(body)]
121
+ end
122
+
123
+ def response(resp)
124
+ resp.response = MultiJson.load(resp.response)
125
+ end
126
+ end
127
+
128
+ it "should use middleware to JSON encode and JSON decode the body" do
129
+ EventMachine.run {
130
+ conn = EventMachine::AblyHttpRequest::HttpRequest.new('http://127.0.0.1:8090/')
131
+ conn.use JSONify
132
+
133
+ req = conn.post :body => {:ruby => :hash}
134
+ req.callback {
135
+ req.response_header.status.should == 200
136
+ req.response.should == {"ruby" => "hash"}
137
+ EventMachine.stop
138
+ }
139
+ }
140
+ end
141
+ end
142
+
143
+ end
@@ -0,0 +1,104 @@
1
+ require 'helper'
2
+ require 'stallion'
3
+
4
+ describe EventMachine::AblyHttpRequest::MultiRequest do
5
+
6
+ let(:multi) { EventMachine::AblyHttpRequest::MultiRequest.new }
7
+ let(:url) { 'http://127.0.0.1:8090/' }
8
+
9
+ it "should submit multiple requests in parallel and return once all of them are complete" do
10
+ EventMachine.run {
11
+ multi.add :a, EventMachine::AblyHttpRequest::HttpRequest.new(url).get
12
+ multi.add :b, EventMachine::AblyHttpRequest::HttpRequest.new(url).post
13
+ multi.add :c, EventMachine::AblyHttpRequest::HttpRequest.new(url).head
14
+ multi.add :d, EventMachine::AblyHttpRequest::HttpRequest.new(url).delete
15
+ multi.add :e, EventMachine::AblyHttpRequest::HttpRequest.new(url).put
16
+
17
+ multi.callback {
18
+ multi.responses[:callback].size.should == 5
19
+ multi.responses[:callback].each { |name, response|
20
+ [ :a, :b, :c, :d, :e ].should include(name)
21
+ response.response_header.status.should == 200
22
+ }
23
+ multi.responses[:errback].size.should == 0
24
+
25
+ EventMachine.stop
26
+ }
27
+ }
28
+ end
29
+
30
+ it "should require unique keys for each deferrable" do
31
+ lambda do
32
+ multi.add :df1, EM::DefaultDeferrable.new
33
+ multi.add :df1, EM::DefaultDeferrable.new
34
+ end.should raise_error("Duplicate Multi key")
35
+ end
36
+
37
+
38
+ describe "#requests" do
39
+ it "should return the added requests" do
40
+ request1 = double('request1', :callback => nil, :errback => nil)
41
+ request2 = double('request2', :callback => nil, :errback => nil)
42
+
43
+ multi.add :a, request1
44
+ multi.add :b, request2
45
+
46
+ multi.requests.should == {:a => request1, :b => request2}
47
+ end
48
+ end
49
+
50
+ describe "#responses" do
51
+ it "should have an empty :callback hash" do
52
+ multi.responses[:callback].should be_a(Hash)
53
+ multi.responses[:callback].size.should == 0
54
+ end
55
+
56
+ it "should have an empty :errback hash" do
57
+ multi.responses[:errback].should be_a(Hash)
58
+ multi.responses[:errback].size.should == 0
59
+ end
60
+
61
+ it "should provide access to the requests by name" do
62
+ EventMachine.run {
63
+ request1 = EventMachine::AblyHttpRequest::HttpRequest.new(url).get
64
+ request2 = EventMachine::AblyHttpRequest::HttpRequest.new(url).post
65
+ multi.add :a, request1
66
+ multi.add :b, request2
67
+
68
+ multi.callback {
69
+ multi.responses[:callback][:a].should equal(request1)
70
+ multi.responses[:callback][:b].should equal(request2)
71
+
72
+ EventMachine.stop
73
+ }
74
+ }
75
+ end
76
+ end
77
+
78
+ describe "#finished?" do
79
+ it "should be true when no requests have been added" do
80
+ multi.should be_finished
81
+ end
82
+
83
+ it "should be false while the requests are not finished" do
84
+ EventMachine.run {
85
+ multi.add :a, EventMachine::AblyHttpRequest::HttpRequest.new(url).get
86
+ multi.should_not be_finished
87
+
88
+ EventMachine.stop
89
+ }
90
+ end
91
+
92
+ it "should be finished when all requests are finished" do
93
+ EventMachine.run {
94
+ multi.add :a, EventMachine::AblyHttpRequest::HttpRequest.new(url).get
95
+ multi.callback {
96
+ multi.should be_finished
97
+
98
+ EventMachine.stop
99
+ }
100
+ }
101
+ end
102
+ end
103
+
104
+ end
@@ -0,0 +1,62 @@
1
+ require 'helper'
2
+
3
+ describe EventMachine::AblyHttpRequest::HttpRequest do
4
+
5
+ it "should perform successful pipelined GETs" do
6
+ EventMachine.run do
7
+
8
+ # Mongrel doesn't support pipelined requests - bah!
9
+ conn = EventMachine::AblyHttpRequest::HttpRequest.new('http://www.bing.com/')
10
+
11
+ pipe1 = conn.get :keepalive => true
12
+ pipe2 = conn.get :path => '/news', :keepalive => true
13
+
14
+ processed = 0
15
+ stop = proc { EM.stop if processed == 2}
16
+
17
+ pipe1.errback { failed(conn) }
18
+ pipe1.callback {
19
+ processed += 1
20
+ pipe1.response_header.status.should == 200
21
+ stop.call
22
+ }
23
+
24
+ pipe2.errback { failed(conn) }
25
+ pipe2.callback {
26
+ processed += 1
27
+ pipe2.response_header.status.should == 200
28
+ pipe2.response.should match(/html/i)
29
+ stop.call
30
+ }
31
+
32
+ end
33
+ end
34
+
35
+ it "should perform successful pipelined HEAD requests" do
36
+ EventMachine.run do
37
+ conn = EventMachine::AblyHttpRequest::HttpRequest.new('http://www.bing.com/')
38
+
39
+ pipe1 = conn.head :keepalive => true
40
+ pipe2 = conn.head :path => '/news', :keepalive => true
41
+
42
+ processed = 0
43
+ stop = proc { EM.stop if processed == 2}
44
+
45
+ pipe1.errback { failed(conn) }
46
+ pipe1.callback {
47
+ processed += 1
48
+ pipe1.response_header.status.should == 200
49
+ stop.call
50
+ }
51
+
52
+ pipe2.errback { failed(conn) }
53
+ pipe2.callback {
54
+ processed += 1
55
+ pipe2.response_header.status.should == 200
56
+ stop.call
57
+ }
58
+
59
+ end
60
+
61
+ end
62
+ end