httpkit 0.6.0.pre.3 → 0.6.0.pre.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.rspec +0 -1
- data/.travis.yml +5 -4
- data/Gemfile +0 -2
- data/Gemfile.devtools +27 -22
- data/README.md +11 -13
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/reek.yml +11 -5
- data/config/rubocop.yml +47 -5
- data/examples/echo_server.rb +2 -2
- data/examples/getting_started.rb +16 -10
- data/httpkit.gemspec +5 -4
- data/lib/httpkit.rb +15 -5
- data/lib/httpkit/body.rb +44 -33
- data/lib/httpkit/client.rb +52 -23
- data/lib/httpkit/client/body_handler.rb +21 -0
- data/lib/httpkit/client/{keep_alive.rb → keep_alive_handler.rb} +1 -1
- data/lib/httpkit/client/mandatory_handler.rb +29 -0
- data/lib/httpkit/client/{timeouts.rb → timeouts_handler.rb} +1 -1
- data/lib/httpkit/connection/eventmachine.rb +4 -4
- data/lib/httpkit/request.rb +46 -10
- data/lib/httpkit/response.rb +37 -5
- data/lib/httpkit/serializer.rb +33 -25
- data/lib/httpkit/server.rb +14 -19
- data/lib/httpkit/server/body_handler.rb +25 -0
- data/lib/httpkit/server/{keep_alive.rb → keep_alive_handler.rb} +22 -13
- data/lib/httpkit/server/mandatory_handler.rb +23 -0
- data/lib/httpkit/server/{timeouts.rb → timeouts_handler.rb} +1 -1
- data/lib/httpkit/support/handler_manager.rb +8 -5
- data/lib/httpkit/support/message.rb +28 -15
- data/lib/httpkit/version.rb +1 -1
- data/spec/integration/keep_alive_spec.rb +6 -7
- data/spec/integration/smoke_spec.rb +4 -4
- data/spec/integration/streaming_spec.rb +2 -3
- data/spec/integration/timeouts_spec.rb +6 -6
- data/spec/shared/integration/server_client_pair.rb +1 -1
- data/spec/spec_helper.rb +3 -2
- data/spec/support/handler.rb +1 -1
- data/spec/support/helper.rb +6 -4
- data/spec/unit/body_spec.rb +6 -0
- data/spec/unit/client/keep_alive_handler_spec.rb +6 -0
- data/spec/unit/client/mandatory_handler_spec.rb +31 -0
- data/spec/unit/client/timeouts_handler_spec.rb +6 -0
- data/spec/unit/client_spec.rb +83 -34
- data/spec/unit/connection/eventmachine_spec.rb +12 -13
- data/spec/unit/httpkit_spec.rb +65 -24
- data/spec/unit/promise_spec.rb +1 -1
- data/spec/unit/request_spec.rb +2 -10
- data/spec/unit/response_spec.rb +7 -15
- data/spec/unit/serializer_spec.rb +83 -0
- data/spec/unit/server/{keep_alive_spec.rb → keep_alive_handler_spec.rb} +5 -2
- data/spec/unit/server/mandatory_handler_spec.rb +30 -0
- data/spec/unit/server/timeouts_handler_spec.rb +6 -0
- data/spec/unit/server_spec.rb +26 -32
- data/spec/unit/support/handler_manager_spec.rb +38 -7
- data/spec/unit/support/message_spec.rb +45 -20
- metadata +57 -36
- data/lib/httpkit/serializer/encoding.rb +0 -43
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YjQ5NTA0NGVmZTllMzYyZDQ2NmFlMGFkMTRiNzZhNWIwMjY3MzQ2Mw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OWU0MTU3ZGZmYmE3OWVjZjRlOTZjZGYzMTU2MWFiNmQ5OWUxMTczNQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZTYyYTczNzczNDA4YWFiMGIwZDE0ZTBkYzcxY2E3NWEwMGM5OTE1Yzg4ZDY2
|
10
|
+
YzI5NWMxY2IxMDA5MjEzNDI0MTU4NDA4NTFlMjljNGYxZDg1YzM3ZWQ1MjE3
|
11
|
+
YWQzYmViMmJhM2QxYmE1ZDI5YTFiOTYwYTI4YjAxMjhlMDkxYjQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Y2NiZjliN2Q1NDI1NmMwYWJiMmJmNTA3YTc1Mjc3M2MwNDgyMzc3NGIwMjk4
|
14
|
+
MDNkY2ExNzkyMTVhZWUxOTAwNGEwMjZhZTQxMjlkMWMyYzYxY2M0NTQ3ODQ5
|
15
|
+
Yzg5YjM1OTEyNjEzM2U2MmVmMzBmNmNjY2NmYWY5OTJlOWNjMjI=
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 1.9
|
4
|
-
- 2.0
|
3
|
+
- 1.9
|
4
|
+
- 2.0
|
5
|
+
- 2.1
|
5
6
|
- jruby
|
6
|
-
- rbx
|
7
|
+
- rbx-2
|
7
8
|
- ruby-head
|
8
9
|
- jruby-head
|
9
10
|
matrix:
|
@@ -12,4 +13,4 @@ matrix:
|
|
12
13
|
- rvm: ruby-head
|
13
14
|
- rvm: jruby-head
|
14
15
|
fast_finish: true
|
15
|
-
script: bundle exec rake -t ci:metrics spec:integration
|
16
|
+
script: "bundle exec rake -t ci:metrics spec:integration && (bundle exec rake -t metrics:mutant || true)"
|
data/Gemfile
CHANGED
data/Gemfile.devtools
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
group :development do
|
4
|
-
gem 'rake',
|
5
|
-
gem 'rspec',
|
6
|
-
gem '
|
4
|
+
gem 'rake', '~> 10.3.2'
|
5
|
+
gem 'rspec', '~> 2.99.0'
|
6
|
+
gem 'rspec-core', '~> 2.99.0'
|
7
|
+
gem 'rspec-its', '~> 1.0.1'
|
8
|
+
gem 'yard', '~> 0.8.7.4'
|
7
9
|
|
8
10
|
platform :rbx do
|
9
11
|
gem 'rubysl-singleton', '~> 2.0.0'
|
@@ -11,48 +13,51 @@ group :development do
|
|
11
13
|
end
|
12
14
|
|
13
15
|
group :yard do
|
14
|
-
gem 'kramdown', '~> 1.
|
16
|
+
gem 'kramdown', '~> 1.3.3'
|
15
17
|
end
|
16
18
|
|
17
19
|
group :guard do
|
18
|
-
gem 'guard', '~> 2.
|
20
|
+
gem 'guard', '~> 2.6.1'
|
19
21
|
gem 'guard-bundler', '~> 2.0.0'
|
20
|
-
gem 'guard-rspec', '~> 4.
|
21
|
-
gem 'guard-rubocop', '~> 1.
|
22
|
+
gem 'guard-rspec', '~> 4.2.9'
|
23
|
+
gem 'guard-rubocop', '~> 1.1.0'
|
22
24
|
|
23
25
|
# file system change event handling
|
24
|
-
gem 'listen', '~> 2.
|
26
|
+
gem 'listen', '~> 2.7.7'
|
25
27
|
gem 'rb-fchange', '~> 0.0.6', require: false
|
26
|
-
gem 'rb-fsevent', '~> 0.9.
|
27
|
-
gem 'rb-inotify', '~> 0.9.
|
28
|
+
gem 'rb-fsevent', '~> 0.9.4', require: false
|
29
|
+
gem 'rb-inotify', '~> 0.9.5', require: false
|
28
30
|
|
29
31
|
# notification handling
|
30
|
-
gem 'libnotify', '~> 0.8.
|
32
|
+
gem 'libnotify', '~> 0.8.3', require: false
|
31
33
|
gem 'rb-notifu', '~> 0.0.4', require: false
|
32
34
|
gem 'terminal-notifier-guard', '~> 1.5.3', require: false
|
33
35
|
end
|
34
36
|
|
35
37
|
group :metrics do
|
36
38
|
gem 'coveralls', '~> 0.7.0'
|
37
|
-
gem 'flay', '~> 2.
|
38
|
-
gem 'flog', '~> 4.2.
|
39
|
-
gem 'reek', '~> 1.3.
|
40
|
-
gem 'rubocop', '~> 0.
|
41
|
-
gem 'simplecov', '~> 0.
|
42
|
-
gem 'yardstick', '~> 0.9.
|
39
|
+
gem 'flay', '~> 2.5.0'
|
40
|
+
gem 'flog', '~> 4.2.1'
|
41
|
+
gem 'reek', '~> 1.3.7'
|
42
|
+
gem 'rubocop', '~> 0.23.0'
|
43
|
+
gem 'simplecov', '~> 0.7.1'
|
44
|
+
gem 'yardstick', '~> 0.9.9'
|
45
|
+
|
46
|
+
platforms :mri do
|
47
|
+
gem 'mutant', '~> 0.5.23'
|
48
|
+
gem 'mutant-rspec', '~> 0.5.21'
|
49
|
+
end
|
43
50
|
|
44
51
|
platforms :ruby_19, :ruby_20 do
|
45
|
-
gem 'mutant', '~> 0.3.0.rc3', git: 'https://github.com/mbj/mutant.git'
|
46
|
-
gem 'unparser', '~> 0.1.5', git: 'https://github.com/mbj/unparser.git'
|
47
52
|
gem 'yard-spellcheck', '~> 0.1.5'
|
48
53
|
end
|
49
54
|
|
50
55
|
platform :rbx do
|
51
56
|
gem 'json', '~> 1.8.1'
|
52
|
-
gem 'racc', '~> 1.4.
|
57
|
+
gem 'racc', '~> 1.4.11'
|
53
58
|
gem 'rubysl-logger', '~> 2.0.0'
|
54
59
|
gem 'rubysl-open-uri', '~> 2.0.0'
|
55
|
-
gem 'rubysl-prettyprint', '~> 2.0.
|
60
|
+
gem 'rubysl-prettyprint', '~> 2.0.3'
|
56
61
|
end
|
57
62
|
end
|
58
63
|
|
@@ -62,6 +67,6 @@ end
|
|
62
67
|
|
63
68
|
platform :jruby do
|
64
69
|
group :jruby do
|
65
|
-
gem 'jruby-openssl', '~> 0.
|
70
|
+
gem 'jruby-openssl', '~> 0.9.4'
|
66
71
|
end
|
67
72
|
end
|
data/README.md
CHANGED
@@ -1,26 +1,24 @@
|
|
1
|
-
# The HTTP toolkit for Ruby
|
1
|
+
# The HTTP toolkit for Ruby
|
2
2
|
|
3
3
|
HTTPkit is a Ruby toolkit for building HTTP clients and servers,
|
4
4
|
as well as compositions of them.
|
5
5
|
|
6
|
-
|
6
|
+
[![Build Status](https://travis-ci.org/lgierth/httpkit.png?branch=master)](https://travis-ci.org/lgierth/httpkit) [![Code Climate](https://codeclimate.com/github/lgierth/httpkit.png)](https://codeclimate.com/github/lgierth/httpkit) [![Coverage Status](https://coveralls.io/repos/lgierth/httpkit/badge.png?branch=master)](https://coveralls.io/r/lgierth/httpkit?branch=master)
|
7
|
+
|
8
|
+
- \#1 feature: readable, high-quality, extendable code with 71.88% mutation coverage (wip)
|
7
9
|
- \#2 feature: sophisticated request and response streaming
|
8
|
-
- \#3 feature: compatible with Rack, Faraday,
|
9
|
-
- \#4 feature:
|
10
|
-
- Non-concurrent using one-off EventMachine reactor (clients only)
|
11
|
-
- Evented using EventMachine
|
12
|
-
- Synchronously evented using EventMachine and Fibers
|
13
|
-
- Threaded using Celluloid (todo)
|
10
|
+
- \#3 feature: compatible with Rack, Faraday, Webmachine for Ruby, and VCR (all todo)
|
11
|
+
- \#4 feature: backed by Celluloid (wip) or Eventmachine
|
14
12
|
|
15
|
-
*Note:* The `master` branch contains the
|
16
|
-
`0.5.x` branch for stable, but
|
17
|
-
Hatetepe.
|
13
|
+
*Note:* The `master` branch contains the in-progress rewrite towards
|
14
|
+
HTTPkit 1.0. Look at the `0.5.x` branch for stable, but outdated and largely
|
15
|
+
unmaintained releases. HTTPkit used to be called Hatetepe.
|
18
16
|
|
19
17
|
## Installation
|
20
18
|
|
21
19
|
Add this line to your application's Gemfile:
|
22
20
|
|
23
|
-
gem 'httpkit'
|
21
|
+
gem 'httpkit', '0.6.0.pre.3'
|
24
22
|
|
25
23
|
And then execute:
|
26
24
|
|
@@ -28,7 +26,7 @@ And then execute:
|
|
28
26
|
|
29
27
|
Or install it yourself as:
|
30
28
|
|
31
|
-
$ gem install httpkit
|
29
|
+
$ gem install httpkit --pre
|
32
30
|
|
33
31
|
## Usage
|
34
32
|
|
data/config/flay.yml
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
3
|
-
total_score:
|
2
|
+
threshold: 10
|
3
|
+
total_score: 279
|
data/config/flog.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
threshold: 10.
|
2
|
+
threshold: 10.8
|
data/config/reek.yml
CHANGED
@@ -31,7 +31,8 @@ IrresponsibleModule:
|
|
31
31
|
exclude: []
|
32
32
|
LongParameterList:
|
33
33
|
enabled: true
|
34
|
-
exclude:
|
34
|
+
exclude:
|
35
|
+
- "HTTPkit::Request#initialize"
|
35
36
|
max_params: 2
|
36
37
|
overrides:
|
37
38
|
initialize:
|
@@ -49,7 +50,8 @@ NestedIterators:
|
|
49
50
|
ignore_iterators: []
|
50
51
|
NilCheck:
|
51
52
|
enabled: true
|
52
|
-
exclude:
|
53
|
+
exclude:
|
54
|
+
- "HTTPkit::Body#length_known?"
|
53
55
|
RepeatedConditional:
|
54
56
|
enabled: true
|
55
57
|
exclude: []
|
@@ -58,15 +60,19 @@ TooManyInstanceVariables:
|
|
58
60
|
enabled: true
|
59
61
|
exclude:
|
60
62
|
- HTTPkit::Connection::EventMachine
|
61
|
-
|
63
|
+
- HTTPkit::Request
|
64
|
+
- HTTPkit::Client
|
65
|
+
max_instance_variables: 5
|
62
66
|
TooManyMethods:
|
63
67
|
enabled: true
|
64
|
-
exclude:
|
65
|
-
|
68
|
+
exclude:
|
69
|
+
- HTTPkit::Response
|
70
|
+
max_methods: 13
|
66
71
|
TooManyStatements:
|
67
72
|
enabled: true
|
68
73
|
exclude:
|
69
74
|
- each
|
75
|
+
- "HTTPkit::Request#initialize"
|
70
76
|
max_statements: 5
|
71
77
|
UncommunicativeMethodName:
|
72
78
|
enabled: true
|
data/config/rubocop.yml
CHANGED
@@ -1,16 +1,22 @@
|
|
1
1
|
AllCops:
|
2
|
-
|
2
|
+
Include:
|
3
3
|
- '**/*.rake'
|
4
4
|
- 'Gemfile'
|
5
5
|
- 'Gemfile.devtools'
|
6
|
-
|
6
|
+
Exclude:
|
7
7
|
- '**/vendor/**'
|
8
8
|
- '**/benchmarks/**'
|
9
9
|
|
10
10
|
# Avoid parameter lists longer than five parameters.
|
11
11
|
ParameterLists:
|
12
|
-
|
13
|
-
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
MethodLength:
|
15
|
+
CountComments: false
|
16
|
+
Max: 10
|
17
|
+
|
18
|
+
ClassLength:
|
19
|
+
Enabled: false
|
14
20
|
|
15
21
|
# Avoid more than `Max` levels of nesting.
|
16
22
|
BlockNesting:
|
@@ -25,7 +31,7 @@ CollectionMethods:
|
|
25
31
|
find_all: 'select'
|
26
32
|
|
27
33
|
AccessModifierIndentation:
|
28
|
-
|
34
|
+
Enabled: false
|
29
35
|
|
30
36
|
# Limit line length
|
31
37
|
LineLength:
|
@@ -47,6 +53,9 @@ CaseEquality:
|
|
47
53
|
ConstantName:
|
48
54
|
Enabled: false
|
49
55
|
|
56
|
+
ClassAndModuleChildren:
|
57
|
+
Enabled: false
|
58
|
+
|
50
59
|
# Not all trivial readers/writers can be defined with attr_* methods
|
51
60
|
TrivialAccessors:
|
52
61
|
Enabled: false
|
@@ -54,3 +63,36 @@ TrivialAccessors:
|
|
54
63
|
SignalException:
|
55
64
|
# Valid values are: semantic, only_raise and only_fail
|
56
65
|
EnforcedStyle: only_raise
|
66
|
+
|
67
|
+
# Do not prefer do/end over {} for multiline blocks
|
68
|
+
Blocks:
|
69
|
+
Enabled: false
|
70
|
+
|
71
|
+
# Allow empty lines around body
|
72
|
+
EmptyLinesAroundBody:
|
73
|
+
Enabled: false
|
74
|
+
|
75
|
+
# Prefer String#% over Kernel#sprintf
|
76
|
+
FormatString:
|
77
|
+
Enabled: false
|
78
|
+
|
79
|
+
# Use square brackets for literal Array objects
|
80
|
+
PercentLiteralDelimiters:
|
81
|
+
PreferredDelimiters:
|
82
|
+
'%': ()
|
83
|
+
'%i': '[]'
|
84
|
+
'%q': ()
|
85
|
+
'%Q': ()
|
86
|
+
'%r': '{}'
|
87
|
+
'%s': ()
|
88
|
+
'%w': '[]'
|
89
|
+
'%W': '[]'
|
90
|
+
'%x': ()
|
91
|
+
|
92
|
+
GuardClause:
|
93
|
+
Enabled: false
|
94
|
+
|
95
|
+
# Disabled because reduce vs each_with_object is not a question of style, ffs.
|
96
|
+
# See lib/httpkit/support/handler_manager.rb
|
97
|
+
EachWithObject:
|
98
|
+
Enabled: false
|
data/examples/echo_server.rb
CHANGED
@@ -19,7 +19,7 @@ class EchoServer
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def serialize(request, response)
|
22
|
-
writer = response.body.
|
22
|
+
writer = response.body.method(:write)
|
23
23
|
serializer = HTTPkit::Serializer.new(request, writer)
|
24
24
|
serializer.serialize
|
25
25
|
end
|
@@ -28,7 +28,7 @@ end
|
|
28
28
|
HTTPkit.start do
|
29
29
|
HTTPkit::Server.start(address: ENV.fetch('ADDRESS', '127.0.0.1'),
|
30
30
|
port: ENV.fetch('PORT', 3000).to_i,
|
31
|
-
handlers: [HTTPkit::Server::
|
31
|
+
handlers: [HTTPkit::Server::KeepAliveHandler.new,
|
32
32
|
EchoServer.new])
|
33
33
|
|
34
34
|
Signal.trap(:INT) { HTTPkit.stop }
|
data/examples/getting_started.rb
CHANGED
@@ -4,11 +4,14 @@ require 'httpkit'
|
|
4
4
|
|
5
5
|
class HelloServer
|
6
6
|
def serve(request, served)
|
7
|
-
p request.http_method
|
8
|
-
|
9
|
-
p request.
|
10
|
-
|
11
|
-
p request.
|
7
|
+
p request.http_method
|
8
|
+
# => :get
|
9
|
+
p request.uri
|
10
|
+
# => "/"
|
11
|
+
p request.headers
|
12
|
+
# => {"Host"=>"127.0.0.1:3000", "Content-Length"=>"0"}
|
13
|
+
p request.body.to_s
|
14
|
+
# => ""
|
12
15
|
|
13
16
|
served.fulfill(response)
|
14
17
|
end
|
@@ -26,9 +29,12 @@ HTTPkit.run do
|
|
26
29
|
|
27
30
|
response = client.request(:get, '/')
|
28
31
|
|
29
|
-
p response.status
|
30
|
-
|
31
|
-
p response.
|
32
|
-
|
33
|
-
p response.
|
32
|
+
p response.status
|
33
|
+
# => 200
|
34
|
+
p response.status_name
|
35
|
+
# => "OK"
|
36
|
+
p response.headers
|
37
|
+
# => {"Content-Type"=>"text/plain", "Content-Length"=>"5"}
|
38
|
+
p response.body.to_s
|
39
|
+
# => "hello"
|
34
40
|
end
|
data/httpkit.gemspec
CHANGED
@@ -19,9 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^spec/})
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.add_dependency "eventmachine"
|
23
|
-
spec.add_dependency "http_parser.rb"
|
24
|
-
spec.add_dependency "promise.rb", "~> 0.6"
|
22
|
+
spec.add_dependency "eventmachine", "~> 1.0"
|
23
|
+
spec.add_dependency "http_parser.rb", "~> 0.6.0"
|
24
|
+
spec.add_dependency "promise.rb", "~> 0.6.0"
|
25
|
+
spec.add_dependency "adamantium", "~> 0.2.0"
|
25
26
|
|
26
|
-
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
28
|
end
|
data/lib/httpkit.rb
CHANGED
@@ -5,6 +5,7 @@ require 'fiber'
|
|
5
5
|
require 'promise'
|
6
6
|
require 'http/parser'
|
7
7
|
require 'time'
|
8
|
+
require 'adamantium'
|
8
9
|
|
9
10
|
require 'httpkit/version'
|
10
11
|
|
@@ -18,15 +19,18 @@ require 'httpkit/response'
|
|
18
19
|
|
19
20
|
require 'httpkit/connection/eventmachine'
|
20
21
|
require 'httpkit/connection/status'
|
21
|
-
require 'httpkit/serializer/encoding'
|
22
22
|
require 'httpkit/serializer'
|
23
23
|
|
24
24
|
require 'httpkit/client'
|
25
|
-
require 'httpkit/client/
|
26
|
-
require 'httpkit/client/
|
25
|
+
require 'httpkit/client/body_handler'
|
26
|
+
require 'httpkit/client/mandatory_handler'
|
27
|
+
require 'httpkit/client/keep_alive_handler'
|
28
|
+
require 'httpkit/client/timeouts_handler'
|
27
29
|
require 'httpkit/server'
|
28
|
-
require 'httpkit/server/
|
29
|
-
require 'httpkit/server/
|
30
|
+
require 'httpkit/server/body_handler'
|
31
|
+
require 'httpkit/server/mandatory_handler'
|
32
|
+
require 'httpkit/server/keep_alive_handler'
|
33
|
+
require 'httpkit/server/timeouts_handler'
|
30
34
|
|
31
35
|
module HTTPkit
|
32
36
|
def self.run
|
@@ -46,4 +50,10 @@ module HTTPkit
|
|
46
50
|
EM.stop
|
47
51
|
EM.next_tick {}
|
48
52
|
end
|
53
|
+
|
54
|
+
def self.sleep(duration)
|
55
|
+
promise = Promise.new
|
56
|
+
EM.add_timer(duration) { promise.fulfill }
|
57
|
+
promise.sync
|
58
|
+
end
|
49
59
|
end
|
data/lib/httpkit/body.rb
CHANGED
@@ -2,66 +2,77 @@
|
|
2
2
|
|
3
3
|
module HTTPkit
|
4
4
|
class Body
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
include Adamantium::Mutable
|
6
|
+
|
7
|
+
def self.build(source = nil, length = nil)
|
8
|
+
if source.is_a?(self)
|
9
|
+
source
|
8
10
|
else
|
9
|
-
|
10
|
-
body.closed.fulfill
|
11
|
-
body
|
11
|
+
new(source, length)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
attr_reader :closed
|
16
16
|
|
17
|
-
#
|
18
|
-
def initialize(
|
19
|
-
@
|
17
|
+
# @param [String,#each,nil] source
|
18
|
+
def initialize(source = nil, length = nil, closed = Promise.new)
|
19
|
+
@source, @length = source, length
|
20
|
+
@closed = closed
|
21
|
+
@chunks = []
|
20
22
|
|
21
|
-
|
22
|
-
closed.
|
23
|
+
apply_source
|
24
|
+
@closed.fulfill if source
|
23
25
|
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
def gets(*args)
|
28
|
-
closed.sync
|
29
|
-
@io.gets(*args)
|
27
|
+
def length
|
28
|
+
@length || 0
|
30
29
|
end
|
31
30
|
|
32
|
-
def
|
33
|
-
|
34
|
-
@io.read(length, buffer)
|
31
|
+
def length_known?
|
32
|
+
!@length.nil?
|
35
33
|
end
|
36
34
|
|
37
|
-
def
|
38
|
-
closed.
|
39
|
-
|
35
|
+
def write(chunk)
|
36
|
+
if @closed.pending? && !chunk.empty?
|
37
|
+
@chunks << chunk
|
38
|
+
@closed.progress(chunk)
|
39
|
+
end
|
40
40
|
end
|
41
41
|
|
42
42
|
def each(&block)
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
return to_enum(__method__) unless block
|
44
|
+
|
45
|
+
if @source.respond_to?(:each)
|
46
|
+
@source.each(&block)
|
47
|
+
else
|
48
|
+
each_chunk(&block)
|
49
|
+
end
|
46
50
|
end
|
47
51
|
|
48
52
|
def to_s
|
49
|
-
|
50
|
-
@io.string
|
53
|
+
each.to_a.join
|
51
54
|
end
|
52
55
|
|
53
|
-
def
|
54
|
-
|
56
|
+
def inspect
|
57
|
+
len = length_known? ? length : 'unknown'
|
58
|
+
sprintf('#<%s:0x%d @length=%s>', self.class.name, object_id, len)
|
55
59
|
end
|
56
60
|
|
57
61
|
private
|
58
62
|
|
59
|
-
def
|
60
|
-
|
63
|
+
def apply_source
|
64
|
+
if @source.respond_to?(:to_str) && (chunk = @source.to_str)
|
65
|
+
@length = chunk.bytesize
|
66
|
+
write(chunk)
|
67
|
+
elsif @source.respond_to?(:bytesize)
|
68
|
+
@length = @source.bytesize
|
69
|
+
end
|
61
70
|
end
|
62
71
|
|
63
|
-
def
|
64
|
-
|
72
|
+
def each_chunk(&block)
|
73
|
+
@closed.on_progress(&block)
|
74
|
+
@chunks.dup.each(&block)
|
75
|
+
@closed.sync
|
65
76
|
end
|
66
77
|
end
|
67
78
|
end
|