async-http 0.40.3 → 0.41.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/async-http.gemspec +3 -3
- data/examples/request.rb +3 -3
- data/examples/upload/client.rb +2 -2
- data/examples/upload/server.rb +3 -3
- data/lib/async/http.rb +1 -1
- data/lib/async/http/body.rb +2 -11
- data/lib/async/http/body/hijack.rb +3 -3
- data/lib/async/http/body/writable.rb +3 -2
- data/lib/async/http/client.rb +11 -10
- data/lib/async/http/{url_endpoint.rb → endpoint.rb} +1 -1
- data/lib/async/http/internet.rb +6 -6
- data/lib/async/http/pool.rb +1 -1
- data/lib/async/http/protocol/http1/client.rb +19 -8
- data/lib/async/http/protocol/http1/connection.rb +8 -25
- data/lib/async/http/protocol/http1/request.rb +10 -7
- data/lib/async/http/protocol/http1/response.rb +19 -3
- data/lib/async/http/protocol/http1/server.rb +14 -2
- data/lib/async/http/protocol/http10.rb +4 -0
- data/lib/async/http/protocol/http11.rb +4 -0
- data/lib/async/http/protocol/http2.rb +8 -0
- data/lib/async/http/protocol/http2/connection.rb +11 -2
- data/lib/async/http/protocol/http2/promise.rb +2 -2
- data/lib/async/http/protocol/http2/request.rb +17 -9
- data/lib/async/http/protocol/http2/response.rb +12 -6
- data/lib/async/http/protocol/http2/server.rb +12 -10
- data/lib/async/http/protocol/http2/stream.rb +1 -1
- data/lib/async/http/protocol/request.rb +6 -6
- data/lib/async/http/protocol/response.rb +5 -6
- data/lib/async/http/relative_location.rb +5 -4
- data/lib/async/http/server.rb +7 -5
- data/lib/async/http/statistics.rb +2 -2
- data/lib/async/http/version.rb +1 -1
- data/tasks/server.rake +4 -4
- metadata +10 -29
- data/lib/async/http/accept_encoding.rb +0 -65
- data/lib/async/http/body/buffered.rb +0 -89
- data/lib/async/http/body/chunked.rb +0 -76
- data/lib/async/http/body/deflate.rb +0 -113
- data/lib/async/http/body/file.rb +0 -98
- data/lib/async/http/body/fixed.rb +0 -72
- data/lib/async/http/body/inflate.rb +0 -59
- data/lib/async/http/body/readable.rb +0 -76
- data/lib/async/http/body/reader.rb +0 -83
- data/lib/async/http/body/remainder.rb +0 -56
- data/lib/async/http/body/rewindable.rb +0 -60
- data/lib/async/http/body/streamable.rb +0 -83
- data/lib/async/http/body/wrapper.rb +0 -65
- data/lib/async/http/content_encoding.rb +0 -76
- data/lib/async/http/headers.rb +0 -27
- data/lib/async/http/middleware.rb +0 -79
- data/lib/async/http/middleware/builder.rb +0 -61
- data/lib/async/http/request.rb +0 -71
- data/lib/async/http/response.rb +0 -90
@@ -1,60 +0,0 @@
|
|
1
|
-
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require_relative 'wrapper'
|
22
|
-
|
23
|
-
module Async
|
24
|
-
module HTTP
|
25
|
-
module Body
|
26
|
-
# A body which buffers all it's contents as it is `#read`.
|
27
|
-
class Rewindable < Wrapper
|
28
|
-
def initialize(body)
|
29
|
-
super(body)
|
30
|
-
|
31
|
-
@chunks = []
|
32
|
-
@index = 0
|
33
|
-
end
|
34
|
-
|
35
|
-
def read
|
36
|
-
if @index < @chunks.count
|
37
|
-
chunk = @chunks[@index]
|
38
|
-
@index += 1
|
39
|
-
else
|
40
|
-
if chunk = super
|
41
|
-
@chunks << chunk
|
42
|
-
@index += 1
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# We dup them on the way out, so that if someone modifies the string, it won't modify the rewindability.
|
47
|
-
return chunk&.dup
|
48
|
-
end
|
49
|
-
|
50
|
-
def rewind
|
51
|
-
@index = 0
|
52
|
-
end
|
53
|
-
|
54
|
-
def inspect
|
55
|
-
"\#<#{self.class} #{@index}/#{@chunks.count} chunks read>"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require_relative 'wrapper'
|
22
|
-
|
23
|
-
module Async
|
24
|
-
module HTTP
|
25
|
-
module Body
|
26
|
-
# Invokes a callback once the body has finished reading.
|
27
|
-
class Streamable < Wrapper
|
28
|
-
def self.wrap(message, &block)
|
29
|
-
if message and body = message.body
|
30
|
-
if remaining = body.length
|
31
|
-
remaining = Integer(remaining)
|
32
|
-
end
|
33
|
-
|
34
|
-
message.body = self.new(message.body, block, remaining)
|
35
|
-
else
|
36
|
-
yield
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def initialize(body, callback, remaining = nil)
|
41
|
-
super(body)
|
42
|
-
|
43
|
-
@callback = callback
|
44
|
-
@remaining = remaining
|
45
|
-
end
|
46
|
-
|
47
|
-
def finish
|
48
|
-
if @body
|
49
|
-
result = super
|
50
|
-
|
51
|
-
@callback.call
|
52
|
-
|
53
|
-
@body = nil
|
54
|
-
|
55
|
-
return result
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def close(*)
|
60
|
-
if @body
|
61
|
-
super
|
62
|
-
|
63
|
-
@callback.call
|
64
|
-
|
65
|
-
@body = nil
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def read
|
70
|
-
if chunk = super
|
71
|
-
@remaining -= chunk.bytesize if @remaining
|
72
|
-
else
|
73
|
-
if @remaining and @remaining > 0
|
74
|
-
raise EOFError, "Expected #{@remaining} more bytes!"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
return chunk
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require_relative 'readable'
|
22
|
-
|
23
|
-
module Async
|
24
|
-
module HTTP
|
25
|
-
module Body
|
26
|
-
# Wrapping body instance. Typically you'd override `#read`.
|
27
|
-
class Wrapper < Readable
|
28
|
-
def initialize(body)
|
29
|
-
@body = body
|
30
|
-
end
|
31
|
-
|
32
|
-
# The wrapped body.
|
33
|
-
attr :body
|
34
|
-
|
35
|
-
# Buffer any remaining body.
|
36
|
-
def finish
|
37
|
-
@body.finish
|
38
|
-
end
|
39
|
-
|
40
|
-
def close(error = nil)
|
41
|
-
@body.close(error)
|
42
|
-
|
43
|
-
super
|
44
|
-
end
|
45
|
-
|
46
|
-
def empty?
|
47
|
-
@body.empty?
|
48
|
-
end
|
49
|
-
|
50
|
-
def length
|
51
|
-
@body.length
|
52
|
-
end
|
53
|
-
|
54
|
-
# Read the next available chunk.
|
55
|
-
def read
|
56
|
-
@body.read
|
57
|
-
end
|
58
|
-
|
59
|
-
def inspect
|
60
|
-
@body.inspect
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require_relative 'middleware'
|
22
|
-
|
23
|
-
require_relative 'body/buffered'
|
24
|
-
require_relative 'body/deflate'
|
25
|
-
|
26
|
-
module Async
|
27
|
-
module HTTP
|
28
|
-
# Encode a response according the the request's acceptable encodings.
|
29
|
-
class ContentEncoding < Middleware
|
30
|
-
DEFAULT_WRAPPERS = {
|
31
|
-
'gzip' => Body::Deflate.method(:for)
|
32
|
-
}
|
33
|
-
|
34
|
-
DEFAULT_CONTENT_TYPES = %r{^(text/.*?)|(.*?/json)|(.*?/javascript)$}
|
35
|
-
|
36
|
-
def initialize(app, content_types = DEFAULT_CONTENT_TYPES, wrappers = DEFAULT_WRAPPERS)
|
37
|
-
super(app)
|
38
|
-
|
39
|
-
@content_types = content_types
|
40
|
-
@wrappers = wrappers
|
41
|
-
end
|
42
|
-
|
43
|
-
def call(request)
|
44
|
-
response = super
|
45
|
-
|
46
|
-
# Early exit if the response has already specified a content-encoding.
|
47
|
-
return response if response.headers['content-encoding']
|
48
|
-
|
49
|
-
# This is a very tricky issue, so we avoid it entirely.
|
50
|
-
# https://lists.w3.org/Archives/Public/ietf-http-wg/2014JanMar/1179.html
|
51
|
-
return response if response.partial?
|
52
|
-
|
53
|
-
# TODO use http-accept and sort by priority
|
54
|
-
if !response.body.empty? and accept_encoding = request.headers['accept-encoding']
|
55
|
-
if content_type = response.headers['content-type'] and @content_types =~ content_type
|
56
|
-
body = response.body
|
57
|
-
|
58
|
-
accept_encoding.each do |name|
|
59
|
-
if wrapper = @wrappers[name]
|
60
|
-
response.headers['content-encoding'] = name
|
61
|
-
|
62
|
-
body = wrapper.call(body)
|
63
|
-
|
64
|
-
break
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
response.body = body
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
return response
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
data/lib/async/http/headers.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
require 'protocol/http/headers'
|
22
|
-
|
23
|
-
module Async
|
24
|
-
module HTTP
|
25
|
-
Headers = ::Protocol::HTTP::Headers
|
26
|
-
end
|
27
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
module Async
|
22
|
-
module HTTP
|
23
|
-
GET = 'GET'.freeze
|
24
|
-
HEAD = 'HEAD'.freeze
|
25
|
-
POST = 'POST'.freeze
|
26
|
-
PUT = 'PUT'.freeze
|
27
|
-
PATCH = 'PATCH'.freeze
|
28
|
-
DELETE = 'DELETE'.freeze
|
29
|
-
CONNECT = 'CONNECT'.freeze
|
30
|
-
|
31
|
-
VERBS = [GET, HEAD, POST, PUT, PATCH, DELETE, CONNECT].freeze
|
32
|
-
|
33
|
-
module Methods
|
34
|
-
VERBS.each do |verb|
|
35
|
-
define_method(verb.downcase) do |location, headers = [], body = nil|
|
36
|
-
self.call(
|
37
|
-
Request[verb, location.to_str, headers, body]
|
38
|
-
)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
class Middleware
|
44
|
-
def initialize(delegate)
|
45
|
-
@delegate = delegate
|
46
|
-
end
|
47
|
-
|
48
|
-
attr :delegate
|
49
|
-
|
50
|
-
def close
|
51
|
-
@delegate.close
|
52
|
-
end
|
53
|
-
|
54
|
-
include Methods
|
55
|
-
|
56
|
-
def call(request)
|
57
|
-
@delegate.call(request)
|
58
|
-
end
|
59
|
-
|
60
|
-
module Okay
|
61
|
-
def self.close
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.call(request)
|
65
|
-
Response[200, {}, []]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
module HelloWorld
|
70
|
-
def self.close
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.call(request)
|
74
|
-
Response[200, {'content-type' => 'text/plain'}, ["Hello World!"]]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
module Async
|
24
|
-
module HTTP
|
25
|
-
class Middleware
|
26
|
-
module NotFound
|
27
|
-
def self.close
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.call(request)
|
31
|
-
Response[404, {}, []]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class Builder
|
36
|
-
def initialize(default_app = NotFound, &block)
|
37
|
-
@use = []
|
38
|
-
@app = default_app
|
39
|
-
|
40
|
-
instance_eval(&block) if block_given?
|
41
|
-
end
|
42
|
-
|
43
|
-
def use(middleware, *args, &block)
|
44
|
-
@use << proc {|app| middleware.new(app, *args, &block)}
|
45
|
-
end
|
46
|
-
|
47
|
-
def run(app)
|
48
|
-
@app = app
|
49
|
-
end
|
50
|
-
|
51
|
-
def to_app
|
52
|
-
@use.reverse.inject(@app) {|app, use| use.call(app).freeze}
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.build(&block)
|
57
|
-
Builder.new(&block).to_app
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|