fast_send 1.1.2 → 1.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1df225aaf4d88c9a194879693f2469882fa1acc6
4
- data.tar.gz: 8f5eaa3d4a6d4600f7ae01ed2bae972da10f1c3d
3
+ metadata.gz: ea16771c56f207d5c40555b4981d955e20724177
4
+ data.tar.gz: 691ef28f1a505a95c974c5060fc66eff6147ad22
5
5
  SHA512:
6
- metadata.gz: 03e9b6a4439667c658de6cc7f9e377cadd50f7eed94dc4e085b2e5e8cd55f0944ac3794fdcaab1c68785408224fa6d8054ca1263cffa6d405c460c00ce65d7f2
7
- data.tar.gz: ed25fcedadd280d9400415190b8c34aa1020f95d4caef80e9a5ead3ff3e3b662f6204ea5f18c9619f0b7b80daa963dadfcbba9b7e3bc59a7b1bcd8865e79e9fd
6
+ metadata.gz: a354a9e5b09f1d598147428351f824f39b42c1b29e48633ee334791bc68d3c95edc2bc551f2eb7087c8e29f37b20c9ff33360528f7424422e0de403575cda916
7
+ data.tar.gz: eae00df9f9beb28595c2de2023915245525a27892ed67e2b6ee192446e24822b9f80929051ad6f1bf1a8bb2ede2529bf3ae6364758db3166097ff8466d9ac7e3
data/.gitignore ADDED
@@ -0,0 +1,51 @@
1
+ # rcov generated
2
+ coverage
3
+ coverage.data
4
+
5
+ # rdoc generated
6
+ rdoc
7
+
8
+ # yard generated
9
+ doc
10
+ .yardoc
11
+
12
+ # bundler
13
+ .bundle
14
+ Gemfile.lock
15
+ .ruby-version
16
+
17
+ # jeweler generated
18
+ pkg
19
+
20
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
21
+ #
22
+ # * Create a file at ~/.gitignore
23
+ # * Include files you want ignored
24
+ # * Run: git config --global core.excludesfile ~/.gitignore
25
+ #
26
+ # After doing this, these files will be ignored in all your git projects,
27
+ # saving you from having to 'pollute' every project you touch with them
28
+ #
29
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
30
+ #
31
+ # For MacOS:
32
+ #
33
+ #.DS_Store
34
+
35
+ # For TextMate
36
+ #*.tmproj
37
+ #tmtags
38
+
39
+ # For emacs:
40
+ #*~
41
+ #\#*
42
+ #.\#*
43
+
44
+ # For vim:
45
+ #*.swp
46
+
47
+ # For redcar:
48
+ #.redcar
49
+
50
+ # For rubinius:
51
+ #*.rbc
data/Gemfile CHANGED
@@ -1,9 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gemspec
4
+
3
5
  group :development do
4
- gem 'rake'
5
- gem 'jeweler', '> 2'
6
- gem 'rspec', '~> 3'
7
- gem 'puma'
8
6
  gem 'sendfile', platforms: :mri
9
7
  end
data/Rakefile CHANGED
@@ -1,38 +1,5 @@
1
- # encoding: utf-8
2
-
3
- require 'rubygems'
4
- require 'bundler'
5
- begin
6
- Bundler.setup(:default, :development)
7
- rescue Bundler::BundlerError => e
8
- $stderr.puts e.message
9
- $stderr.puts "Run `bundle install` to install missing gems"
10
- exit e.status_code
11
- end
12
- require 'rake'
13
-
14
- require 'jeweler'
15
- require_relative 'lib/fast_send'
16
- Jeweler::Tasks.new do |gem|
17
- gem.version = FastSend::VERSION
18
- gem.name = "fast_send"
19
- gem.homepage = "https://github.com/WeTransfer/fast_send"
20
- gem.license = "MIT"
21
- gem.description = %Q{Send bursts of large files quickly via Rack}
22
- gem.summary = %Q{and do so bypassing the Ruby VM}
23
- gem.email = "me@julik.nl"
24
- gem.authors = ["Julik Tarkhanov"]
25
- # dependencies defined in Gemfile
26
- end
27
-
28
- Jeweler::RubygemsDotOrgTasks.new
29
-
30
- require 'rspec/core'
1
+ require 'bundler/gem_tasks'
31
2
  require 'rspec/core/rake_task'
32
- RSpec::Core::RakeTask.new(:spec) do |spec|
33
- spec.rspec_opts = ["-c"]
34
- spec.pattern = FileList['spec/**/*_spec.rb']
35
- end
36
-
37
- task :default => :spec
38
3
 
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
data/fast_send.gemspec CHANGED
@@ -1,13 +1,9 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
1
  # -*- encoding: utf-8 -*-
5
2
  # stub: fast_send 1.1.2 ruby lib
6
-
3
+ require File.dirname(__FILE__) + '/lib/fast_send/version'
7
4
  Gem::Specification.new do |s|
8
5
  s.name = "fast_send"
9
- s.version = "1.1.2"
10
-
6
+ s.version = FastSend::VERSION
11
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
8
  s.require_paths = ["lib"]
13
9
  s.authors = ["Julik Tarkhanov"]
@@ -18,47 +14,14 @@ Gem::Specification.new do |s|
18
14
  "LICENSE.txt",
19
15
  "README.md"
20
16
  ]
21
- s.files = [
22
- "Gemfile",
23
- "LICENSE.txt",
24
- "README.md",
25
- "Rakefile",
26
- "config.ru",
27
- "fast_send.gemspec",
28
- "lib/fast_send.rb",
29
- "lib/fast_send/null_logger.rb",
30
- "lib/fast_send/socket_handler.rb",
31
- "spec/fast_send_with_mocks_spec.rb",
32
- "spec/fast_send_with_puma_spec.rb",
33
- "spec/test_app.ru"
34
- ]
17
+ s.files = `git ls-files -z`.split("\x0")
35
18
  s.homepage = "https://github.com/WeTransfer/fast_send"
36
19
  s.licenses = ["MIT"]
37
20
  s.rubygems_version = "2.4.5.1"
38
21
  s.summary = "and do so bypassing the Ruby VM"
39
22
 
40
- if s.respond_to? :specification_version then
41
- s.specification_version = 4
42
-
43
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
- s.add_development_dependency(%q<rake>, [">= 0"])
45
- s.add_development_dependency(%q<jeweler>, ["> 2"])
46
- s.add_development_dependency(%q<rspec>, ["~> 3"])
47
- s.add_development_dependency(%q<puma>, [">= 0"])
48
- s.add_development_dependency(%q<sendfile>, [">= 0"])
49
- else
50
- s.add_dependency(%q<rake>, [">= 0"])
51
- s.add_dependency(%q<jeweler>, ["> 2"])
52
- s.add_dependency(%q<rspec>, ["~> 3"])
53
- s.add_dependency(%q<puma>, [">= 0"])
54
- s.add_dependency(%q<sendfile>, [">= 0"])
55
- end
56
- else
57
- s.add_dependency(%q<rake>, [">= 0"])
58
- s.add_dependency(%q<jeweler>, ["> 2"])
59
- s.add_dependency(%q<rspec>, ["~> 3"])
60
- s.add_dependency(%q<puma>, [">= 0"])
61
- s.add_dependency(%q<sendfile>, [">= 0"])
62
- end
23
+ s.add_development_dependency("rake", [">= 0"])
24
+ s.add_development_dependency("rspec", ["~> 3"])
25
+ s.add_development_dependency("puma", [">= 0"])
26
+ s.add_development_dependency("sendfile", [">= 0"])
63
27
  end
64
-
@@ -12,6 +12,10 @@ class FastSend::SocketHandler < Struct.new(:stream, :logger, :started_proc, :abo
12
12
  # Is raised when it is not possible to send a chunk of data
13
13
  # to the client using non-blocking sends for longer than the preset timeout
14
14
  SlowLoris = Class.new(StandardError)
15
+
16
+ # Exceptions that indicate a client being too slow or dropping out
17
+ # due to failing reads/writes
18
+ CLIENT_DISCONNECT_EXCEPTIONS = [SlowLoris] + ::FastSend::CLIENT_DISCONNECTS
15
19
 
16
20
  # Whether we are forced to use blocking IO for sendfile()
17
21
  USE_BLOCKING_SENDFILE = !!(RUBY_PLATFORM =~ /darwin/)
@@ -55,13 +59,14 @@ class FastSend::SocketHandler < Struct.new(:stream, :logger, :started_proc, :abo
55
59
 
56
60
  logger.info { "Response written in full - %d bytes" % bytes_written }
57
61
  done_proc.call(bytes_written)
58
- rescue *client_disconnect_exeptions => e
62
+ rescue *CLIENT_DISCONNECT_EXCEPTIONS => e
59
63
  logger.warn { "Client closed connection: #{e.class}(#{e.message})" }
60
64
  aborted_proc.call(e)
61
65
  rescue Exception => e
62
- logger.fatal { "Aborting response due to error: #{e.class}(#{e.message})" }
66
+ logger.fatal { "Aborting response due to error: #{e.class}(#{e.message}) and will propagate" }
63
67
  aborted_proc.call(e)
64
68
  error_proc.call(e)
69
+ raise e unless StandardError === e # Re-raise system errors, signals and other Exceptions
65
70
  ensure
66
71
  # With rack.hijack the consensus seems to be that the hijack
67
72
  # proc is responsible for closing the socket. We also use no-keepalive
@@ -71,14 +76,6 @@ class FastSend::SocketHandler < Struct.new(:stream, :logger, :started_proc, :abo
71
76
  cleanup_proc.call(bytes_written)
72
77
  end
73
78
  end
74
-
75
- # Returns an array of Exception classes we can rescue from (using a splat)
76
- #
77
- # @return [Array<Class>] the classes
78
- def client_disconnect_exeptions
79
- [SlowLoris] + ::FastSend::CLIENT_DISCONNECTS
80
- end
81
-
82
79
 
83
80
  # This is majorly useful - if the socket is not selectable after a certain
84
81
  # timeout, it might be a slow loris or a connection that hung up on us. So if
@@ -110,7 +107,7 @@ class FastSend::SocketHandler < Struct.new(:stream, :logger, :started_proc, :abo
110
107
  #
111
108
  # @param socket[Socket] the socket to write to
112
109
  # @param file[File] the IO you can read from
113
- # @yields num_bytes_written[Fixnum] the number of bytes written on each `IO.copy_stream() call`
110
+ # @yields num_bytes_written[Integer] the number of bytes written on each `IO.copy_stream() call`
114
111
  # @return [void]
115
112
  def sendfile(socket, file)
116
113
  chunk = SENDFILE_CHUNK_SIZE
@@ -152,7 +149,7 @@ class FastSend::SocketHandler < Struct.new(:stream, :logger, :started_proc, :abo
152
149
  #
153
150
  # @param socket[Socket] the socket to write to
154
151
  # @param file[File] the IO you can read from
155
- # @yields num_bytes_written[Fixnum] the number of bytes written on each `IO.copy_stream() call`
152
+ # @yields num_bytes_written[Integer] the number of bytes written on each `IO.copy_stream() call`
156
153
  # @return [void]
157
154
  def copy_stream(socket, file)
158
155
  chunk = SENDFILE_CHUNK_SIZE
@@ -177,7 +174,7 @@ class FastSend::SocketHandler < Struct.new(:stream, :logger, :started_proc, :abo
177
174
  #
178
175
  # @param socket[Socket] the socket to write to
179
176
  # @param file[File] the IO you can read from
180
- # @yields num_bytes_written[Fixnum] the number of bytes written on each `IO.copy_stream() call`
177
+ # @yields num_bytes_written[Integer] the number of bytes written on each `IO.copy_stream() call`
181
178
  # @return [void]
182
179
  def copy_nio(socket, file)
183
180
  chunk = SENDFILE_CHUNK_SIZE
@@ -0,0 +1,3 @@
1
+ class FastSend
2
+ VERSION = "1.1.3"
3
+ end
data/lib/fast_send.rb CHANGED
@@ -31,11 +31,6 @@
31
31
  # `fast_send.error' => ->(exception) { } # the response is not sent completely due to an error in the application
32
32
  # `fast_send.cleanup' => ->(sent_total) { } # Called at the end of the response, in an ensure block
33
33
  class FastSend
34
- require_relative 'fast_send/socket_handler'
35
- require_relative 'fast_send/null_logger'
36
-
37
- VERSION = '1.1.2'
38
-
39
34
  # All exceptions that get raised when the client closes a connection before receiving the entire response
40
35
  CLIENT_DISCONNECTS = [Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN, Errno::EPROTOTYPE]
41
36
 
@@ -43,8 +38,11 @@ class FastSend
43
38
  require 'java'
44
39
  CLIENT_DISCONNECTS << Java::JavaIo::IOException
45
40
  end
46
-
47
-
41
+
42
+ require_relative 'fast_send/version'
43
+ require_relative 'fast_send/socket_handler'
44
+ require_relative 'fast_send/null_logger'
45
+
48
46
  # Gets raised if a fast_send.something is mentioned in
49
47
  # the response headers but is not supported as a callback
50
48
  # (the dangers of hashmaps as datastructures is that you
@@ -1,5 +1,7 @@
1
1
  require_relative '../lib/fast_send'
2
2
  require 'logger'
3
+ require 'tempfile'
4
+
3
5
  describe 'FastSend when used with a mock Socket' do
4
6
  let(:logger) {
5
7
  Logger.new(nil).tap{|l| l.level = Logger::DEBUG }
@@ -327,8 +329,8 @@ describe 'FastSend when used with a mock Socket' do
327
329
 
328
330
  bytes_sent_cbs = callbacks[1..-3]
329
331
  bytes_sent_cbs.each_with_index do | c, i |
330
- expect(c[1]).to be_kind_of(Fixnum)
331
- expect(c[2]).to be_kind_of(Fixnum)
332
+ expect(c[1]).to be_kind_of(Integer)
333
+ expect(c[2]).to be_kind_of(Integer)
332
334
  end
333
335
  end
334
336
 
@@ -1,5 +1,6 @@
1
1
  require_relative '../lib/fast_send'
2
2
  require 'net/http'
3
+ require 'tempfile'
3
4
 
4
5
  describe 'FastSend when used in combination with Puma' do
5
6
  before :all do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast_send
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: jeweler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">"
32
- - !ruby/object:Gem::Version
33
- version: '2'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">"
39
- - !ruby/object:Gem::Version
40
- version: '2'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rspec
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -88,6 +74,7 @@ extra_rdoc_files:
88
74
  - LICENSE.txt
89
75
  - README.md
90
76
  files:
77
+ - ".gitignore"
91
78
  - Gemfile
92
79
  - LICENSE.txt
93
80
  - README.md
@@ -97,6 +84,7 @@ files:
97
84
  - lib/fast_send.rb
98
85
  - lib/fast_send/null_logger.rb
99
86
  - lib/fast_send/socket_handler.rb
87
+ - lib/fast_send/version.rb
100
88
  - spec/fast_send_with_mocks_spec.rb
101
89
  - spec/fast_send_with_puma_spec.rb
102
90
  - spec/test_app.ru
@@ -120,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
108
  version: '0'
121
109
  requirements: []
122
110
  rubyforge_project:
123
- rubygems_version: 2.4.5.1
111
+ rubygems_version: 2.6.11
124
112
  signing_key:
125
113
  specification_version: 4
126
114
  summary: and do so bypassing the Ruby VM