goliath-rack_proxy 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8a7a0e1b05033aa36859754d967e1dc35a9521d1
4
- data.tar.gz: 57213aee848373ccbc1cd57431cf68af0ece721b
2
+ SHA256:
3
+ metadata.gz: '0389e88c7db998d12b5550d7dbd3a3bc323184e3bd1b8d080a1c5d81e0ed1123'
4
+ data.tar.gz: ee1fdf5d915de32cc4f15d05dcf3d53ca9fe1b5b5daeeb32eb404da02fb1c8eb
5
5
  SHA512:
6
- metadata.gz: c6ca9cca21727aa34afe651b55b8b7a198d52b16916710fa494f3d1b524af520273925c514f9388d4340db74ffd32f04f99d94af0a1678899626b0797a6edfa8
7
- data.tar.gz: 4f08b4ecb2e2e06932b2f135d4ccbe4d288ee0b537667f6044f58611977ca8c0087d9d81de80a6f2ff1b10d3101dec712189b153a1b29ab64bcee0174eb2d259
6
+ metadata.gz: 399119828686d758a0bc438c62b42467b41bc4ddd5189a0751dc9b64631bf107ef1c65c39a02ef8e89aaec3d05c6006aaa17dae758834f68bd318c5fde7d2ad3
7
+ data.tar.gz: 0a854cac90c5eab049b4e575e7efa230a16871ed446a195635880d84e265b8ab906861cd44c8552f3cdc0090c06f53db88d5ae18b433deb8775c393e1f0258e7
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = "goliath-rack_proxy"
3
- gem.version = "1.0.2"
3
+ gem.version = "1.1.0"
4
4
 
5
5
  gem.required_ruby_version = ">= 2.1"
6
6
 
@@ -19,6 +19,6 @@ Gem::Specification.new do |gem|
19
19
  gem.add_development_dependency "rake", "~> 11.1"
20
20
  gem.add_development_dependency "minitest", "~> 5.8"
21
21
  gem.add_development_dependency "minitest-hooks"
22
- gem.add_development_dependency "http"
22
+ gem.add_development_dependency "http", "~> 3.0"
23
23
  gem.add_development_dependency "rack", "~> 2.0"
24
24
  end
@@ -27,12 +27,12 @@ module Goliath
27
27
  rewindable_input = self.class.rack_proxy_options.fetch(:rewindable_input, true)
28
28
 
29
29
  env["rack_proxy.call"] = RackCall.new(rack_app, env, rewindable_input: rewindable_input)
30
- env["rack_proxy.call"].resume
30
+ env["rack_proxy.call"].resume(on_response: -> (response) { send_response(response, env) })
31
31
  end
32
32
 
33
33
  # Resumes the Rack request with the received request body data.
34
34
  def on_body(env, data)
35
- env["rack_proxy.call"].resume(data)
35
+ env["rack_proxy.call"].resume(data, on_response: -> (response) { send_response(response, env) })
36
36
  end
37
37
 
38
38
  # Resumes the Rack request with no more data.
@@ -42,11 +42,30 @@ module Goliath
42
42
 
43
43
  # Resumes the Rack request with no more data.
44
44
  def response(env)
45
- env["rack_proxy.call"].resume
45
+ env["rack_proxy.call"].resume(on_response: -> (response) { send_response(response, env) })
46
+ nil
46
47
  end
47
48
 
48
49
  private
49
50
 
51
+ # The env[ASYNC_CALLBACK] proc wraps sending response data in a
52
+ # Goliath::Request#callback, which gets executed after the whole request
53
+ # body has been received.
54
+ #
55
+ # This is not ideal for apps that receive large uploads, as when they
56
+ # validate request headers, they likely want to return error responses
57
+ # immediately. It's not good user experience to require the user to upload
58
+ # a large file, only to have the request fail with a validation error.
59
+ #
60
+ # To work around that, we mark the request as succeeded before sending the
61
+ # response, so that the response is sent immediately.
62
+ def send_response(response, env)
63
+ request = env[STREAM_SEND].binding.receiver # hack to get the Goliath::Request object
64
+ request.succeed # makes it so that response is sent immediately
65
+
66
+ env[ASYNC_CALLBACK].call(response)
67
+ end
68
+
50
69
  # Allows "curry-calling" the Rack application, resuming the call as we're
51
70
  # receiving more request body data.
52
71
  class RackCall
@@ -56,9 +75,11 @@ module Goliath
56
75
  @rewindable_input = rewindable_input
57
76
  end
58
77
 
59
- def resume(data = nil)
60
- @result = fiber.resume(data) if fiber.alive?
61
- @result
78
+ def resume(data = nil, on_response: nil)
79
+ if fiber.alive?
80
+ response = fiber.resume(data)
81
+ on_response.call(response) if response && on_response
82
+ end
62
83
  end
63
84
 
64
85
  private
@@ -71,14 +92,14 @@ module Goliath
71
92
  @fiber ||= Fiber.new do
72
93
  rack_input = RackInput.new(rewindable: @rewindable_input) { Fiber.yield }
73
94
 
74
- result = @app.call @env.merge(
95
+ response = @app.call @env.merge(
75
96
  "rack.input" => rack_input,
76
97
  "async.callback" => nil, # prevent Roda/Sinatra from calling EventMachine while streaming the response
77
98
  )
78
99
 
79
100
  rack_input.close
80
101
 
81
- result
102
+ response
82
103
  end
83
104
  end
84
105
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goliath-rack_proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-26 00:00:00.000000000 Z
11
+ date: 2018-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: goliath
@@ -76,16 +76,16 @@ dependencies:
76
76
  name: http
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ">="
79
+ - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '0'
81
+ version: '3.0'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - ">="
86
+ - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '0'
88
+ version: '3.0'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: rack
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
133
  version: '0'
134
134
  requirements: []
135
135
  rubyforge_project:
136
- rubygems_version: 2.6.11
136
+ rubygems_version: 2.7.6
137
137
  signing_key:
138
138
  specification_version: 4
139
139
  summary: Allows you to use Goliath as a web server for your Rack app, giving you streaming