httpkit 0.6.0.pre.3 → 0.6.0.pre.5
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 +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
|
+
[](https://travis-ci.org/lgierth/httpkit) [](https://codeclimate.com/github/lgierth/httpkit) [](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
|