fast_send 1.2.0 → 1.2.1
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 +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
|