ably-em-http-request 1.1.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/ably-em-http-request.svg)](http://rubygems.org/gems/ably-em-http-request)
|
4
|
+
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/ably-forks/em-http-request/ci.yml)](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
|