fast_send 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/fast_send/socket_handler.rb +32 -38
- data/lib/fast_send/version.rb +1 -1
- data/spec/fast_send_with_mocks_spec.rb +23 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6e2c4890b5649cc57d8ada06a7d603dce77e5d98f3fed5f08cc8509f36b2f474
|
4
|
+
data.tar.gz: 55bbe6a60c743baf0b587f9d8b9f11141110f6fe8d497a1bc110620487524edf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18f09fb016ffbfec08b34b1e249c618500c72099c247f77673ac974ec2f666c7a9da9fdab605a344f42c1f60760cfd2790d5740db1fdd9e2afe2fea2bf587d97
|
7
|
+
data.tar.gz: 52de47120c17aa8c4fa10d9586c6039d04538517cc6da7be069c5082adc5755f162843183494061ec6947a698f684462b33521849d0fe4464a1aea726ea5a910
|
@@ -30,8 +30,6 @@ class FastSend::SocketHandler < Struct.new(:stream, :logger, :started_proc, :abo
|
|
30
30
|
SENDFILE_CHUNK_SIZE = 2*1024*1024
|
31
31
|
|
32
32
|
def call(socket)
|
33
|
-
return if socket.closed?
|
34
|
-
|
35
33
|
writer_method_name = if socket.respond_to?(:sendfile)
|
36
34
|
:sendfile
|
37
35
|
elsif RUBY_PLATFORM == 'java'
|
@@ -39,44 +37,40 @@ class FastSend::SocketHandler < Struct.new(:stream, :logger, :started_proc, :abo
|
|
39
37
|
else
|
40
38
|
:copy_stream
|
41
39
|
end
|
42
|
-
|
43
|
-
logger.debug { "
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
bytes_written += n_bytes_sent
|
57
|
-
logger.debug { "Written %d bytes" % bytes_written }
|
58
|
-
written_proc.call(n_bytes_sent, bytes_written)
|
59
|
-
end
|
40
|
+
|
41
|
+
logger.debug { "Starting the response, writing via #{writer_method_name}" }
|
42
|
+
bytes_written = 0
|
43
|
+
started_proc.call(bytes_written)
|
44
|
+
|
45
|
+
return if socket.closed? # Only do this now as we need to have bytes_written set
|
46
|
+
|
47
|
+
stream.each_file do | file |
|
48
|
+
logger.debug { "Sending %s" % file.inspect }
|
49
|
+
# Run the sending method, depending on the implementation
|
50
|
+
send(writer_method_name, socket, file) do |n_bytes_sent|
|
51
|
+
bytes_written += n_bytes_sent
|
52
|
+
logger.debug { "Written %d bytes" % bytes_written }
|
53
|
+
written_proc.call(n_bytes_sent, bytes_written)
|
60
54
|
end
|
61
|
-
|
62
|
-
logger.info { "Response written in full - %d bytes" % bytes_written }
|
63
|
-
done_proc.call(bytes_written)
|
64
|
-
rescue *CLIENT_DISCONNECT_EXCEPTIONS => e
|
65
|
-
logger.warn { "Client closed connection: #{e.class}(#{e.message})" }
|
66
|
-
aborted_proc.call(e)
|
67
|
-
rescue Exception => e
|
68
|
-
logger.fatal { "Aborting response due to error: #{e.class}(#{e.message}) and will propagate" }
|
69
|
-
aborted_proc.call(e)
|
70
|
-
error_proc.call(e)
|
71
|
-
raise e unless StandardError === e # Re-raise system errors, signals and other Exceptions
|
72
|
-
ensure
|
73
|
-
# With rack.hijack the consensus seems to be that the hijack
|
74
|
-
# proc is responsible for closing the socket. We also use no-keepalive
|
75
|
-
# so this should not pose any problems.
|
76
|
-
socket.close unless socket.closed?
|
77
|
-
logger.debug { "Performing cleanup" }
|
78
|
-
cleanup_proc.call(bytes_written)
|
79
55
|
end
|
56
|
+
|
57
|
+
logger.info { "Response written in full - %d bytes" % bytes_written }
|
58
|
+
done_proc.call(bytes_written)
|
59
|
+
rescue *CLIENT_DISCONNECT_EXCEPTIONS => e
|
60
|
+
logger.warn { "Client closed connection: #{e.class}(#{e.message})" }
|
61
|
+
aborted_proc.call(e)
|
62
|
+
rescue Exception => e
|
63
|
+
logger.fatal { "Aborting response due to error: #{e.class}(#{e.message}) and will propagate" }
|
64
|
+
aborted_proc.call(e)
|
65
|
+
error_proc.call(e)
|
66
|
+
raise e unless StandardError === e # Re-raise system errors, signals and other Exceptions
|
67
|
+
ensure
|
68
|
+
# With rack.hijack the consensus seems to be that the hijack
|
69
|
+
# proc is responsible for closing the socket. We also use no-keepalive
|
70
|
+
# so this should not pose any problems.
|
71
|
+
socket.close unless socket.closed?
|
72
|
+
logger.debug { "Performing cleanup" }
|
73
|
+
cleanup_proc.call(bytes_written)
|
80
74
|
end
|
81
75
|
|
82
76
|
# This is majorly useful - if the socket is not selectable after a certain
|
data/lib/fast_send/version.rb
CHANGED
@@ -239,7 +239,29 @@ describe 'FastSend when used with a mock Socket' do
|
|
239
239
|
|
240
240
|
expect(output.size).to eq(source_size)
|
241
241
|
end
|
242
|
-
|
242
|
+
|
243
|
+
it 'calls the cleanup proc even if the socket enters the handler in a closed state' do
|
244
|
+
source_size = (64 + 54) * 1024 * 1024
|
245
|
+
cleanup_proc = double('Cleanup')
|
246
|
+
app = ->(env) { [200, {'fast_send.cleanup' => cleanup_proc}, EachFileResponse.new] }
|
247
|
+
|
248
|
+
handler = described_class.new(app)
|
249
|
+
|
250
|
+
status, headers, body = handler.call({'rack.hijack?' => true, 'rack.logger' => logger})
|
251
|
+
expect(status).to eq(200)
|
252
|
+
expect(body).to eq([])
|
253
|
+
|
254
|
+
output = Tempfile.new('response_body')
|
255
|
+
|
256
|
+
already_closed_socket = FakeSocket.new(output)
|
257
|
+
already_closed_socket.close
|
258
|
+
|
259
|
+
hijack = headers.fetch('rack.hijack')
|
260
|
+
|
261
|
+
# The cleanup proc gets called with the number of bytes transferred
|
262
|
+
expect(cleanup_proc).to receive(:call).with(0)
|
263
|
+
hijack.call(already_closed_socket)
|
264
|
+
end
|
243
265
|
|
244
266
|
it 'can execute the hijack proc twice without resending the data' do
|
245
267
|
source_size = (64 + 54) * 1024 * 1024
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fast_send
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julik Tarkhanov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -108,8 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
110
|
requirements: []
|
111
|
-
|
112
|
-
rubygems_version: 2.6.11
|
111
|
+
rubygems_version: 3.0.3
|
113
112
|
signing_key:
|
114
113
|
specification_version: 4
|
115
114
|
summary: and do so bypassing the Ruby VM
|