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.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/.github/workflows/ci.yml +22 -0
- data/.gitignore +9 -0
- data/.rspec +0 -0
- data/Changelog.md +78 -0
- data/Gemfile +14 -0
- data/LICENSE +21 -0
- data/README.md +66 -0
- data/Rakefile +10 -0
- data/ably-em-http-request.gemspec +33 -0
- data/benchmarks/clients.rb +170 -0
- data/benchmarks/em-excon.rb +87 -0
- data/benchmarks/em-profile.gif +0 -0
- data/benchmarks/em-profile.txt +65 -0
- data/benchmarks/server.rb +48 -0
- data/examples/.gitignore +1 -0
- data/examples/digest_auth/client.rb +25 -0
- data/examples/digest_auth/server.rb +28 -0
- data/examples/fetch.rb +30 -0
- data/examples/fibered-http.rb +51 -0
- data/examples/multi.rb +25 -0
- data/examples/oauth-tweet.rb +35 -0
- data/examples/socks5.rb +23 -0
- data/lib/em/io_streamer.rb +51 -0
- data/lib/em-http/client.rb +343 -0
- data/lib/em-http/core_ext/bytesize.rb +6 -0
- data/lib/em-http/decoders.rb +252 -0
- data/lib/em-http/http_client_options.rb +51 -0
- data/lib/em-http/http_connection.rb +408 -0
- data/lib/em-http/http_connection_options.rb +72 -0
- data/lib/em-http/http_encoding.rb +151 -0
- data/lib/em-http/http_header.rb +85 -0
- data/lib/em-http/http_status_codes.rb +59 -0
- data/lib/em-http/middleware/digest_auth.rb +114 -0
- data/lib/em-http/middleware/json_response.rb +17 -0
- data/lib/em-http/middleware/oauth.rb +42 -0
- data/lib/em-http/middleware/oauth2.rb +30 -0
- data/lib/em-http/multi.rb +59 -0
- data/lib/em-http/request.rb +25 -0
- data/lib/em-http/version.rb +7 -0
- data/lib/em-http-request.rb +1 -0
- data/lib/em-http.rb +20 -0
- data/spec/client_fiber_spec.rb +23 -0
- data/spec/client_spec.rb +1000 -0
- data/spec/digest_auth_spec.rb +48 -0
- data/spec/dns_spec.rb +41 -0
- data/spec/encoding_spec.rb +49 -0
- data/spec/external_spec.rb +146 -0
- data/spec/fixtures/google.ca +16 -0
- data/spec/fixtures/gzip-sample.gz +0 -0
- data/spec/gzip_spec.rb +91 -0
- data/spec/helper.rb +27 -0
- data/spec/http_proxy_spec.rb +268 -0
- data/spec/middleware/oauth2_spec.rb +15 -0
- data/spec/middleware_spec.rb +143 -0
- data/spec/multi_spec.rb +104 -0
- data/spec/pipelining_spec.rb +62 -0
- data/spec/redirect_spec.rb +430 -0
- data/spec/socksify_proxy_spec.rb +56 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/ssl_spec.rb +67 -0
- data/spec/stallion.rb +334 -0
- data/spec/stub_server.rb +45 -0
- metadata +269 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 78af49f284be9066641f824d9bb131c1efc379b61f106e14e7a2148b2e81992c
|
4
|
+
data.tar.gz: ae249db06b5d2b1e426a6baf69798b1b0caea85ec15c49a844063b08e78cde85
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2b3a1e26b6b05c6e7d81cebf5b387a8791d015d86e173f3f7a323cbf8c462bd5b8d1b2d13f7eedae625c338c1c1c798ad470f02542f6b923ad26003facdf39cf
|
7
|
+
data.tar.gz: 9efb2d09cccff266c4c6fb76ce7b796a1d3ba63450502de800c99a35cf7833d94eac3014624c0c26d97f3d56eb664d3333066b7e7f2a1c843c5c54345311b002
|
data/.gemtest
ADDED
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: CI
|
2
|
+
on:
|
3
|
+
pull_request:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
jobs:
|
8
|
+
spec:
|
9
|
+
name: "RSpec / Ruby ${{ matrix.ruby }}"
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
strategy:
|
12
|
+
fail-fast: false
|
13
|
+
matrix:
|
14
|
+
ruby: ["2.3", "2.4", "2.5", "2.6", "2.7", "3.0", "3.1", "3.2", "3.3"]
|
15
|
+
steps:
|
16
|
+
- run: sudo apt-get install libcurl4-openssl-dev
|
17
|
+
- uses: actions/checkout@v4
|
18
|
+
- uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: ${{ matrix.ruby }}
|
21
|
+
bundler-cache: true
|
22
|
+
- run: bundle exec rake spec
|
data/.gitignore
ADDED
data/.rspec
ADDED
File without changes
|
data/Changelog.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## Ably fork changelog
|
4
|
+
|
5
|
+
### 1.1.8
|
6
|
+
|
7
|
+
#### Bug fixes
|
8
|
+
|
9
|
+
- Fix server certificate validation ([#2](https://github.com/ably-forks/em-http-request/pull/2))
|
10
|
+
|
11
|
+
## Original changelog (appears that the author stopped updating this at some point)
|
12
|
+
|
13
|
+
### master
|
14
|
+
|
15
|
+
- User-Agent header is now removed if set to nil.
|
16
|
+
|
17
|
+
### 1.0.0.beta.1 / 2011-02-20 - The big rewrite
|
18
|
+
|
19
|
+
- Switched parser from Ragel to http_parser.rb
|
20
|
+
- Removed em_buffer C extension
|
21
|
+
- Added support for HTTP keepalive
|
22
|
+
- Added support for HTTP pipelining
|
23
|
+
- ~60% performance improvement across the board: less GC time!
|
24
|
+
- Refactored & split all tests
|
25
|
+
- Basic 100-Continue handling on POST/PUT
|
26
|
+
|
27
|
+
### 0.3.0 / 2011-01-15
|
28
|
+
|
29
|
+
- IMPORTANT: default to non-persistent connections (timeout => 0 now requires :keepalive => true)
|
30
|
+
- see: https://github.com/igrigorik/em-http-request/commit/1ca5b608e876c18fa6cfa318d0685dcf5b974e09
|
31
|
+
|
32
|
+
- added escape_utils dependency to fix slow encode on long string escapes
|
33
|
+
|
34
|
+
- bugfix: proxy authorization headers
|
35
|
+
- bugfix: default to Encoding.default_external on invalid encoding in response
|
36
|
+
- bugfix: do not normalize URI's internally
|
37
|
+
- bugfix: more robust Encoding detection
|
38
|
+
|
39
|
+
|
40
|
+
### 0.2.15 / 2010-11-18
|
41
|
+
|
42
|
+
- bugfix: follow redirects on missing content-length
|
43
|
+
- bugfix: fixed undefined warnings when running in strict mode
|
44
|
+
|
45
|
+
### 0.2.14 / 2010-10-06
|
46
|
+
|
47
|
+
- bugfix: form-encode keys/values of ruby objects passed in as body
|
48
|
+
|
49
|
+
### 0.2.13 / 2010-09-25
|
50
|
+
|
51
|
+
- added SOCKS5 proxy support
|
52
|
+
- bugfix: follow redirects on HEAD requests
|
53
|
+
|
54
|
+
### 0.2.12 / 2010-09-12
|
55
|
+
|
56
|
+
- added headers callback (http.headers {|h| p h})
|
57
|
+
- added .close method on client obj to terminate session (accepts message)
|
58
|
+
|
59
|
+
- bugfix: report 0 for response status on 1.9 on timeouts
|
60
|
+
- bugfix: handle bad Location host redirects
|
61
|
+
- bugfix: reset host override on connect
|
62
|
+
|
63
|
+
### 0.2.11 / 2010-08-16
|
64
|
+
|
65
|
+
- all URIs are now normalized prior to dispatch (and on redirect)
|
66
|
+
- default to direct proxy (instead of CONNECT handshake) - better performance
|
67
|
+
- specify :proxy => {:tunnel => true} if you need to force CONNECT route
|
68
|
+
- MultiRequest accepts block syntax for dispatching parallel requests (see specs)
|
69
|
+
- MockHttpRequest accepts block syntax (see Mock wiki page)
|
70
|
+
|
71
|
+
|
72
|
+
- bugfix: nullbyte frame for websockets
|
73
|
+
- bugfix: set @uri on DNS resolve failure
|
74
|
+
- bugfix: handle bad hosts in absolute redirects
|
75
|
+
- bugfix: reset seen content on redirects (doh!)
|
76
|
+
- bugfix: invalid multibyte escape in websocket regex (1.9.2+)
|
77
|
+
- bugfix: report etag and last_modified headers correctly
|
78
|
+
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Ilya Grigorik
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# EM-HTTP-Request
|
2
|
+
|
3
|
+
[](http://rubygems.org/gems/ably-em-http-request)
|
4
|
+
[](https://github.com/ably-forks/em-http-request/actions/workflows/ci.yml)
|
5
|
+
|
6
|
+
**Note:** This is Ably’s fork of https://github.com/igrigorik/em-http-request. We created it to fix a TLS-related issue in the original library, which seems to be no longer maintained. This fork exists to be used inside our [ably-ruby SDK](https://github.com/ably/ably-ruby). We have only made the changes required to be able to distribute this library as a separate gem; in particular, most of the documentation still refers to the original library. The constant names used in this fork have been changed so as not to clash with the original library.
|
7
|
+
|
8
|
+
Async (EventMachine) HTTP client, with support for:
|
9
|
+
|
10
|
+
- Asynchronous HTTP API for single & parallel request execution
|
11
|
+
- Keep-Alive and HTTP pipelining support
|
12
|
+
- Auto-follow 3xx redirects with max depth
|
13
|
+
- Automatic gzip & deflate decoding
|
14
|
+
- Streaming response processing
|
15
|
+
- Streaming file uploads
|
16
|
+
- HTTP proxy and SOCKS5 support
|
17
|
+
- Basic Auth & OAuth
|
18
|
+
- Connection-level & global middleware support
|
19
|
+
- HTTP parser via [http_parser.rb](https://github.com/tmm1/http_parser.rb)
|
20
|
+
- Works wherever EventMachine runs: Rubinius, JRuby, MRI
|
21
|
+
|
22
|
+
## Getting started
|
23
|
+
|
24
|
+
gem install ably-em-http-request
|
25
|
+
|
26
|
+
- Introductory [screencast](http://everburning.com/news/eventmachine-screencast-em-http-request)
|
27
|
+
- [Issuing GET/POST/etc requests](https://github.com/igrigorik/em-http-request/wiki/Issuing-Requests)
|
28
|
+
- [Issuing parallel requests with Multi interface](https://github.com/igrigorik/em-http-request/wiki/Parallel-Requests)
|
29
|
+
- [Handling Redirects & Timeouts](https://github.com/igrigorik/em-http-request/wiki/Redirects-and-Timeouts)
|
30
|
+
- [Keep-Alive and HTTP Pipelining](https://github.com/igrigorik/em-http-request/wiki/Keep-Alive-and-HTTP-Pipelining)
|
31
|
+
- [Stream processing responses & uploads](https://github.com/igrigorik/em-http-request/wiki/Streaming)
|
32
|
+
- [Issuing requests through HTTP & SOCKS5 proxies](https://github.com/igrigorik/em-http-request/wiki/Proxy)
|
33
|
+
- [Basic Auth & OAuth](https://github.com/igrigorik/em-http-request/wiki/Basic-Auth-and-OAuth)
|
34
|
+
- [GZIP & Deflate decoding](https://github.com/igrigorik/em-http-request/wiki/Compression)
|
35
|
+
- [EM-HTTP Middleware](https://github.com/igrigorik/em-http-request/wiki/Middleware)
|
36
|
+
|
37
|
+
## Extensions
|
38
|
+
|
39
|
+
Several higher-order Ruby projects have incorporated em-http and other Ruby HTTP clients:
|
40
|
+
|
41
|
+
- [EM-Synchrony](https://github.com/igrigorik/em-synchrony) - Collection of convenience classes and primitives to help untangle evented code (Ruby 1.9 + Fibers).
|
42
|
+
- [Rack-Client](https://github.com/halorgium/rack-client) - Use Rack API for server, test, and client side. Supports Rack middleware!
|
43
|
+
- [Example in action](https://gist.github.com/802391)
|
44
|
+
- [Faraday](https://github.com/lostisland/faraday) - Modular HTTP client library using middleware heavily inspired by Rack.
|
45
|
+
- [Example in action](https://gist.github.com/802395)
|
46
|
+
|
47
|
+
## Testing
|
48
|
+
|
49
|
+
- [WebMock](https://github.com/bblimke/webmock) - Library for stubbing and setting expectations on HTTP requests in Ruby.
|
50
|
+
- Example of [using WebMock, VCR & EM-HTTP](https://gist.github.com/802553)
|
51
|
+
|
52
|
+
## Other libraries & applications using EM-HTTP
|
53
|
+
|
54
|
+
- [VMWare CloudFoundry](https://github.com/cloudfoundry) - The open platform-as-a-service project
|
55
|
+
- [PubSubHubbub](https://github.com/igrigorik/PubSubHubbub) - Asynchronous PubSubHubbub ruby client
|
56
|
+
- [em-net-http](https://github.com/jfairbairn/em-net-http) - Monkeypatching Net::HTTP to play ball with EventMachine
|
57
|
+
- [chirpstream](https://github.com/joshbuddy/chirpstream) - EM client for Twitters Chirpstream API
|
58
|
+
- [rsolr-async](https://github.com/mwmitchell/rsolr-async) - An asynchronus connection adapter for RSolr
|
59
|
+
- [Firering](https://github.com/EmmanuelOga/firering) - Eventmachine powered Campfire API
|
60
|
+
- [RDaneel](https://github.com/hasmanydevelopers/RDaneel) - Ruby crawler which respects robots.txt
|
61
|
+
- [em-eventsource](https://github.com/AF83/em-eventsource) - EventSource client for EventMachine
|
62
|
+
- and many others.. drop me a link if you want yours included!
|
63
|
+
|
64
|
+
### License
|
65
|
+
|
66
|
+
(MIT License) - Copyright (c) 2011 Ilya Grigorik
|
data/Rakefile
ADDED
@@ -0,0 +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 = 'ably-em-http-request'
|
7
|
+
s.version = EventMachine::AblyHttpRequest::HttpRequest::VERSION
|
8
|
+
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Ilya Grigorik"]
|
11
|
+
s.email = ['lawrence.forooghian@ably.com', 'lewis@lmars.net', 'matt@ably.io']
|
12
|
+
s.homepage = 'https://github.com/ably-forks/em-http-request'
|
13
|
+
s.summary = 'EventMachine based, async HTTP Request client'
|
14
|
+
s.description = s.summary
|
15
|
+
s.license = 'MIT'
|
16
|
+
|
17
|
+
s.add_dependency 'addressable', '>= 2.3.4'
|
18
|
+
s.add_dependency 'cookiejar', '!= 0.3.1'
|
19
|
+
s.add_dependency 'em-socksify', '>= 0.3'
|
20
|
+
s.add_dependency 'eventmachine', '>= 1.0.3'
|
21
|
+
s.add_dependency 'http_parser.rb', '>= 0.6.0'
|
22
|
+
|
23
|
+
s.add_development_dependency 'mongrel', '~> 1.2.0.pre2'
|
24
|
+
s.add_development_dependency 'multi_json'
|
25
|
+
s.add_development_dependency 'rack', '< 2.0'
|
26
|
+
s.add_development_dependency 'rake'
|
27
|
+
s.add_development_dependency 'rspec'
|
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
|
@@ -0,0 +1,170 @@
|
|
1
|
+
$: << './benchmarks'
|
2
|
+
require 'server'
|
3
|
+
|
4
|
+
require 'excon'
|
5
|
+
require 'httparty'
|
6
|
+
require 'net/http'
|
7
|
+
require 'open-uri'
|
8
|
+
require 'rest_client'
|
9
|
+
require 'tach'
|
10
|
+
require 'typhoeus'
|
11
|
+
|
12
|
+
url = 'http://127.0.0.1:9292/data/10000'
|
13
|
+
|
14
|
+
with_server do
|
15
|
+
Tach.meter(100) do
|
16
|
+
|
17
|
+
tach('curb (persistent)') do |n|
|
18
|
+
curb = Curl::Easy.new
|
19
|
+
|
20
|
+
n.times do
|
21
|
+
curb.url = url
|
22
|
+
curb.http_get
|
23
|
+
curb.body_str
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
tach('em-http-request') do |n|
|
28
|
+
EventMachine.run {
|
29
|
+
count = 0
|
30
|
+
error = 0
|
31
|
+
|
32
|
+
n.times do
|
33
|
+
http = EventMachine::AblyHttpRequest::HttpRequest.new(url).get
|
34
|
+
|
35
|
+
http.callback {
|
36
|
+
count += 1
|
37
|
+
if count == n
|
38
|
+
p [count, error]
|
39
|
+
EM.stop
|
40
|
+
end
|
41
|
+
}
|
42
|
+
|
43
|
+
http.errback {
|
44
|
+
count += 1
|
45
|
+
error += 1
|
46
|
+
if count == n
|
47
|
+
p [count, error]
|
48
|
+
EM.stop
|
49
|
+
end
|
50
|
+
}
|
51
|
+
end
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
tach('em-http-request (persistent)') do |n|
|
56
|
+
EventMachine.run {
|
57
|
+
count = 0
|
58
|
+
error = 0
|
59
|
+
|
60
|
+
conn = EventMachine::AblyHttpRequest::HttpRequest.new(url)
|
61
|
+
|
62
|
+
n.times do
|
63
|
+
http = conn.get :keepalive => true
|
64
|
+
http.callback {
|
65
|
+
count += 1
|
66
|
+
if count == n
|
67
|
+
p [count, error]
|
68
|
+
EM.stop
|
69
|
+
end
|
70
|
+
}
|
71
|
+
|
72
|
+
http.errback {
|
73
|
+
count += 1
|
74
|
+
error += 1
|
75
|
+
if count == n
|
76
|
+
p [count, error]
|
77
|
+
EM.stop
|
78
|
+
end
|
79
|
+
}
|
80
|
+
end
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
tach('Excon') do
|
85
|
+
Excon.get(url).body
|
86
|
+
end
|
87
|
+
|
88
|
+
excon = Excon.new(url)
|
89
|
+
tach('Excon (persistent)') do
|
90
|
+
excon.request(:method => 'get').body
|
91
|
+
end
|
92
|
+
|
93
|
+
tach('HTTParty') do
|
94
|
+
HTTParty.get(url).body
|
95
|
+
end
|
96
|
+
|
97
|
+
uri = Addressable::URI.parse(url)
|
98
|
+
tach('Net::HTTP') do
|
99
|
+
Net::HTTP.start(uri.host, uri.port) {|http| http.get(uri.path).body }
|
100
|
+
end
|
101
|
+
|
102
|
+
uri = Addressable::URI.parse(url)
|
103
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
104
|
+
tach('Net::HTTP (persistent)') do
|
105
|
+
http.get(uri.path).body
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
tach('open-uri') do
|
110
|
+
open(url).read
|
111
|
+
end
|
112
|
+
|
113
|
+
tach('RestClient') do
|
114
|
+
RestClient.get(url)
|
115
|
+
end
|
116
|
+
|
117
|
+
streamly = StreamlyFFI::Connection.new
|
118
|
+
tach('StreamlyFFI (persistent)') do
|
119
|
+
streamly.get(url)
|
120
|
+
end
|
121
|
+
|
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
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
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
|
+
#+------------------------------+-----------+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
$: << './benchmarks'
|
2
|
+
require 'server'
|
3
|
+
|
4
|
+
url = 'http://127.0.0.1/10k.html'
|
5
|
+
|
6
|
+
with_server do
|
7
|
+
Tach.meter(100) do
|
8
|
+
|
9
|
+
excon = Excon.new(url)
|
10
|
+
tach('Excon (persistent)') do
|
11
|
+
excon.request(:method => 'get').body
|
12
|
+
end
|
13
|
+
|
14
|
+
tach('Excon') do
|
15
|
+
Excon.get(url).body
|
16
|
+
end
|
17
|
+
|
18
|
+
tach('em-http-request') do |n|
|
19
|
+
EventMachine.run {
|
20
|
+
count = 0
|
21
|
+
error = 0
|
22
|
+
n.times do
|
23
|
+
EM.next_tick do
|
24
|
+
http = EventMachine::AblyHttpRequest::HttpRequest.new(url, :connect_timeout => 1).get
|
25
|
+
|
26
|
+
http.callback {
|
27
|
+
count += 1
|
28
|
+
if count == n
|
29
|
+
p [count, error]
|
30
|
+
EM.stop
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
http.errback {
|
35
|
+
count += 1
|
36
|
+
error += 1
|
37
|
+
if count == n
|
38
|
+
p [count, error]
|
39
|
+
EM.stop
|
40
|
+
end
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
tach('em-http-request (persistent)') do |n|
|
48
|
+
EventMachine.run {
|
49
|
+
count = 0
|
50
|
+
error = 0
|
51
|
+
conn = EventMachine::AblyHttpRequest::HttpRequest.new(url)
|
52
|
+
|
53
|
+
n.times do
|
54
|
+
http = conn.get :keepalive => true
|
55
|
+
http.callback {
|
56
|
+
count += 1
|
57
|
+
if count == n
|
58
|
+
p [count, error]
|
59
|
+
EM.stop
|
60
|
+
end
|
61
|
+
}
|
62
|
+
|
63
|
+
http.errback {
|
64
|
+
count += 1
|
65
|
+
error += 1
|
66
|
+
if count == n
|
67
|
+
p [count, error]
|
68
|
+
EM.stop
|
69
|
+
end
|
70
|
+
}
|
71
|
+
end
|
72
|
+
}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# +------------------------------+----------+
|
78
|
+
# | tach | total |
|
79
|
+
# +------------------------------+----------+
|
80
|
+
# | em-http-request (persistent) | 0.018133 |
|
81
|
+
# +------------------------------+----------+
|
82
|
+
# | Excon (persistent) | 0.023975 |
|
83
|
+
# +------------------------------+----------+
|
84
|
+
# | Excon | 0.032877 |
|
85
|
+
# +------------------------------+----------+
|
86
|
+
# | em-http-request | 0.042891 |
|
87
|
+
# +------------------------------+----------+
|
Binary file
|
@@ -0,0 +1,65 @@
|
|
1
|
+
Total: 143 samples
|
2
|
+
67 46.9% 46.9% 109 76.2% Kernel#gem_original_require
|
3
|
+
17 11.9% 58.7% 17 11.9% garbage_collector
|
4
|
+
12 8.4% 67.1% 12 8.4% EventMachine.connect_server
|
5
|
+
11 7.7% 74.8% 11 7.7% Dir.[]
|
6
|
+
11 7.7% 82.5% 11 7.7% File.file?
|
7
|
+
4 2.8% 85.3% 4 2.8% Kernel#eval
|
8
|
+
3 2.1% 87.4% 16 11.2% Enumerable#find
|
9
|
+
3 2.1% 89.5% 3 2.1% Regexp#initialize
|
10
|
+
2 1.4% 90.9% 16 11.2% EventMachine.run_machine
|
11
|
+
2 1.4% 92.3% 2 1.4% Regexp#match
|
12
|
+
1 0.7% 93.0% 1 0.7% FFI::DynamicLibrary.open
|
13
|
+
1 0.7% 93.7% 1 0.7% Hash#values
|
14
|
+
1 0.7% 94.4% 7 4.9% Kernel#load
|
15
|
+
1 0.7% 95.1% 3 2.1% MIME::Type#initialize
|
16
|
+
1 0.7% 95.8% 1 0.7% MatchData#captures
|
17
|
+
1 0.7% 96.5% 13 9.1% Module#bind_connect
|
18
|
+
1 0.7% 97.2% 17 11.9% Module#searcher
|
19
|
+
1 0.7% 97.9% 1 0.7% String#downcase
|
20
|
+
1 0.7% 98.6% 1 0.7% String#scan
|
21
|
+
1 0.7% 99.3% 1 0.7% String#strip
|
22
|
+
1 0.7% 100.0% 1 0.7% TCPSocket#initialize
|
23
|
+
0 0.0% 100.0% 1 0.7% Array#map
|
24
|
+
0 0.0% 100.0% 14 9.8% Array#reverse_each
|
25
|
+
0 0.0% 100.0% 14 9.8% Class#from_gems_in
|
26
|
+
0 0.0% 100.0% 14 9.8% Class#from_installed_gems
|
27
|
+
0 0.0% 100.0% 14 9.8% Class#load
|
28
|
+
0 0.0% 100.0% 1 0.7% Class#parse
|
29
|
+
0 0.0% 100.0% 1 0.7% Class#simplified
|
30
|
+
0 0.0% 100.0% 6 4.2% Enumerable#each_with_index
|
31
|
+
0 0.0% 100.0% 1 0.7% Excon::Connection#connect
|
32
|
+
0 0.0% 100.0% 1 0.7% Excon::Connection#request
|
33
|
+
0 0.0% 100.0% 1 0.7% Excon::Connection#socket
|
34
|
+
0 0.0% 100.0% 1 0.7% FFI::Library#ffi_lib
|
35
|
+
0 0.0% 100.0% 10 7.0% Gem::GemPathSearcher#find
|
36
|
+
0 0.0% 100.0% 1 0.7% Gem::GemPathSearcher#find_active
|
37
|
+
0 0.0% 100.0% 16 11.2% Gem::GemPathSearcher#init_gemspecs
|
38
|
+
0 0.0% 100.0% 16 11.2% Gem::GemPathSearcher#initialize
|
39
|
+
0 0.0% 100.0% 11 7.7% Gem::GemPathSearcher#matching_file?
|
40
|
+
0 0.0% 100.0% 11 7.7% Gem::GemPathSearcher#matching_files
|
41
|
+
0 0.0% 100.0% 14 9.8% Gem::SourceIndex#load_gems_in
|
42
|
+
0 0.0% 100.0% 14 9.8% Gem::SourceIndex#refresh!
|
43
|
+
0 0.0% 100.0% 1 0.7% Gem::SourceIndex#search
|
44
|
+
0 0.0% 100.0% 1 0.7% HttpOptions#initialize
|
45
|
+
0 0.0% 100.0% 1 0.7% HttpOptions#set_uri
|
46
|
+
0 0.0% 100.0% 14 9.8% Integer#times
|
47
|
+
0 0.0% 100.0% 1 0.7% Kernel#loop
|
48
|
+
0 0.0% 100.0% 109 76.2% Kernel#require
|
49
|
+
0 0.0% 100.0% 1 0.7% Module#activate
|
50
|
+
0 0.0% 100.0% 13 9.1% Module#connect
|
51
|
+
0 0.0% 100.0% 1 0.7% Module#get
|
52
|
+
0 0.0% 100.0% 2 1.4% Module#load_full_rubygems_library
|
53
|
+
0 0.0% 100.0% 5 3.5% Module#loaded_path?
|
54
|
+
0 0.0% 100.0% 16 11.2% Module#meter
|
55
|
+
0 0.0% 100.0% 16 11.2% Module#run
|
56
|
+
0 0.0% 100.0% 16 11.2% Module#source_index
|
57
|
+
0 0.0% 100.0% 30 21.0% Module#try_activate
|
58
|
+
0 0.0% 100.0% 17 11.9% Object#with_server
|
59
|
+
0 0.0% 100.0% 2 1.4% Regexp.union
|
60
|
+
0 0.0% 100.0% 1 0.7% TCPSocket.open
|
61
|
+
0 0.0% 100.0% 16 11.2% Tach::Meter#initialize
|
62
|
+
0 0.0% 100.0% 16 11.2% Tach::Meter#run_tach
|
63
|
+
0 0.0% 100.0% 1 0.7% URI::Parser#initialize
|
64
|
+
0 0.0% 100.0% 1 0.7% URI::Parser#initialize_regexp
|
65
|
+
0 0.0% 100.0% 7 4.9% YAML::EngineManager#yamler=
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'httparty'
|
3
|
+
require 'net/http'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'rest_client'
|
6
|
+
require 'tach'
|
7
|
+
require 'typhoeus'
|
8
|
+
require 'sinatra/base'
|
9
|
+
require 'streamly_ffi'
|
10
|
+
require 'curb'
|
11
|
+
|
12
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'em-http')
|
13
|
+
|
14
|
+
module Benchmark
|
15
|
+
class Server < Sinatra::Base
|
16
|
+
|
17
|
+
def self.run
|
18
|
+
Rack::Handler::WEBrick.run(
|
19
|
+
Benchmark::Server.new,
|
20
|
+
:Port => 9292,
|
21
|
+
:AccessLog => [],
|
22
|
+
:Logger => WEBrick::Log.new(nil, WEBrick::Log::ERROR)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
get '/data/:amount' do |amount|
|
27
|
+
'x' * amount.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def with_server(&block)
|
34
|
+
pid = Process.fork do
|
35
|
+
Benchmark::Server.run
|
36
|
+
end
|
37
|
+
loop do
|
38
|
+
sleep(1)
|
39
|
+
begin
|
40
|
+
#Excon.get('http://localhost:9292/api/foo')
|
41
|
+
break
|
42
|
+
rescue
|
43
|
+
end
|
44
|
+
end
|
45
|
+
yield
|
46
|
+
ensure
|
47
|
+
Process.kill(9, pid)
|
48
|
+
end
|
data/examples/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
twitter_auth.rb
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$: << 'lib' << '../../lib'
|
2
|
+
|
3
|
+
require 'em-http'
|
4
|
+
require 'em-http/middleware/digest_auth'
|
5
|
+
|
6
|
+
digest_config = {
|
7
|
+
:username => 'digest_username',
|
8
|
+
:password => 'digest_password'
|
9
|
+
}
|
10
|
+
|
11
|
+
EM.run do
|
12
|
+
|
13
|
+
conn_handshake = EM::AblyHttpRequest::HttpRequest.new('http://localhost:3000')
|
14
|
+
http_handshake = conn_handshake.get
|
15
|
+
|
16
|
+
http_handshake.callback do
|
17
|
+
conn = EM::AblyHttpRequest::HttpRequest.new('http://localhost:3000')
|
18
|
+
conn.use EM::AblyHttpRequest::Middleware::DigestAuth, http_handshake.response_header['WWW_AUTHENTICATE'], digest_config
|
19
|
+
http = conn.get
|
20
|
+
http.callback do
|
21
|
+
puts http.response
|
22
|
+
EM.stop
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|