tiny-fast-gem 0.0.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.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/puma-8.0.2/History.md +3334 -0
  3. data/puma-8.0.2/LICENSE +29 -0
  4. data/puma-8.0.2/README.md +484 -0
  5. data/puma-8.0.2/bin/puma +10 -0
  6. data/puma-8.0.2/bin/puma-wild +25 -0
  7. data/puma-8.0.2/bin/pumactl +12 -0
  8. data/puma-8.0.2/docs/5.0-Upgrade.md +98 -0
  9. data/puma-8.0.2/docs/6.0-Upgrade.md +56 -0
  10. data/puma-8.0.2/docs/7.0-Upgrade.md +52 -0
  11. data/puma-8.0.2/docs/8.0-Upgrade.md +100 -0
  12. data/puma-8.0.2/docs/architecture.md +74 -0
  13. data/puma-8.0.2/docs/compile_options.md +55 -0
  14. data/puma-8.0.2/docs/deployment.md +137 -0
  15. data/puma-8.0.2/docs/fork_worker.md +41 -0
  16. data/puma-8.0.2/docs/grpc.md +62 -0
  17. data/puma-8.0.2/docs/images/favicon.svg +1 -0
  18. data/puma-8.0.2/docs/images/puma-connection-flow-no-reactor.png +0 -0
  19. data/puma-8.0.2/docs/images/puma-connection-flow.png +0 -0
  20. data/puma-8.0.2/docs/images/puma-general-arch.png +0 -0
  21. data/puma-8.0.2/docs/images/running-puma.svg +1 -0
  22. data/puma-8.0.2/docs/images/standard-logo.svg +1 -0
  23. data/puma-8.0.2/docs/java_options.md +54 -0
  24. data/puma-8.0.2/docs/jungle/README.md +9 -0
  25. data/puma-8.0.2/docs/jungle/rc.d/README.md +74 -0
  26. data/puma-8.0.2/docs/jungle/rc.d/puma +61 -0
  27. data/puma-8.0.2/docs/jungle/rc.d/puma.conf +10 -0
  28. data/puma-8.0.2/docs/kubernetes.md +73 -0
  29. data/puma-8.0.2/docs/nginx.md +80 -0
  30. data/puma-8.0.2/docs/plugins.md +42 -0
  31. data/puma-8.0.2/docs/rails_dev_mode.md +28 -0
  32. data/puma-8.0.2/docs/restart.md +65 -0
  33. data/puma-8.0.2/docs/signals.md +98 -0
  34. data/puma-8.0.2/docs/stats.md +148 -0
  35. data/puma-8.0.2/docs/systemd.md +253 -0
  36. data/puma-8.0.2/docs/testing_benchmarks_local_files.md +150 -0
  37. data/puma-8.0.2/docs/testing_test_rackup_ci_files.md +36 -0
  38. data/puma-8.0.2/ext/puma_http11/PumaHttp11Service.java +17 -0
  39. data/puma-8.0.2/ext/puma_http11/extconf.rb +65 -0
  40. data/puma-8.0.2/ext/puma_http11/http11_parser.c +1057 -0
  41. data/puma-8.0.2/ext/puma_http11/http11_parser.h +65 -0
  42. data/puma-8.0.2/ext/puma_http11/http11_parser.java.rl +131 -0
  43. data/puma-8.0.2/ext/puma_http11/http11_parser.rl +149 -0
  44. data/puma-8.0.2/ext/puma_http11/http11_parser_common.rl +54 -0
  45. data/puma-8.0.2/ext/puma_http11/mini_ssl.c +852 -0
  46. data/puma-8.0.2/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  47. data/puma-8.0.2/ext/puma_http11/org/jruby/puma/EnvKey.java +241 -0
  48. data/puma-8.0.2/ext/puma_http11/org/jruby/puma/Http11.java +321 -0
  49. data/puma-8.0.2/ext/puma_http11/org/jruby/puma/Http11Parser.java +441 -0
  50. data/puma-8.0.2/ext/puma_http11/org/jruby/puma/MiniSSL.java +509 -0
  51. data/puma-8.0.2/ext/puma_http11/puma_http11.c +499 -0
  52. data/puma-8.0.2/lib/puma/app/status.rb +104 -0
  53. data/puma-8.0.2/lib/puma/binder.rb +511 -0
  54. data/puma-8.0.2/lib/puma/cli.rb +245 -0
  55. data/puma-8.0.2/lib/puma/client.rb +756 -0
  56. data/puma-8.0.2/lib/puma/client_env.rb +171 -0
  57. data/puma-8.0.2/lib/puma/cluster/worker.rb +183 -0
  58. data/puma-8.0.2/lib/puma/cluster/worker_handle.rb +127 -0
  59. data/puma-8.0.2/lib/puma/cluster.rb +634 -0
  60. data/puma-8.0.2/lib/puma/cluster_accept_loop_delay.rb +91 -0
  61. data/puma-8.0.2/lib/puma/commonlogger.rb +115 -0
  62. data/puma-8.0.2/lib/puma/configuration.rb +522 -0
  63. data/puma-8.0.2/lib/puma/const.rb +308 -0
  64. data/puma-8.0.2/lib/puma/control_cli.rb +320 -0
  65. data/puma-8.0.2/lib/puma/detect.rb +58 -0
  66. data/puma-8.0.2/lib/puma/dsl.rb +1562 -0
  67. data/puma-8.0.2/lib/puma/error_logger.rb +115 -0
  68. data/puma-8.0.2/lib/puma/events.rb +72 -0
  69. data/puma-8.0.2/lib/puma/io_buffer.rb +50 -0
  70. data/puma-8.0.2/lib/puma/jruby_restart.rb +11 -0
  71. data/puma-8.0.2/lib/puma/json_serialization.rb +96 -0
  72. data/puma-8.0.2/lib/puma/launcher/bundle_pruner.rb +102 -0
  73. data/puma-8.0.2/lib/puma/launcher.rb +501 -0
  74. data/puma-8.0.2/lib/puma/log_writer.rb +153 -0
  75. data/puma-8.0.2/lib/puma/minissl/context_builder.rb +96 -0
  76. data/puma-8.0.2/lib/puma/minissl.rb +458 -0
  77. data/puma-8.0.2/lib/puma/null_io.rb +101 -0
  78. data/puma-8.0.2/lib/puma/plugin/systemd.rb +90 -0
  79. data/puma-8.0.2/lib/puma/plugin/tmp_restart.rb +36 -0
  80. data/puma-8.0.2/lib/puma/plugin.rb +111 -0
  81. data/puma-8.0.2/lib/puma/rack/builder.rb +297 -0
  82. data/puma-8.0.2/lib/puma/rack/urlmap.rb +93 -0
  83. data/puma-8.0.2/lib/puma/rack_default.rb +24 -0
  84. data/puma-8.0.2/lib/puma/reactor.rb +131 -0
  85. data/puma-8.0.2/lib/puma/response.rb +532 -0
  86. data/puma-8.0.2/lib/puma/runner.rb +211 -0
  87. data/puma-8.0.2/lib/puma/sd_notify.rb +146 -0
  88. data/puma-8.0.2/lib/puma/server.rb +773 -0
  89. data/puma-8.0.2/lib/puma/server_plugin_control.rb +32 -0
  90. data/puma-8.0.2/lib/puma/single.rb +72 -0
  91. data/puma-8.0.2/lib/puma/state_file.rb +69 -0
  92. data/puma-8.0.2/lib/puma/thread_pool.rb +517 -0
  93. data/puma-8.0.2/lib/puma/util.rb +134 -0
  94. data/puma-8.0.2/lib/puma.rb +88 -0
  95. data/puma-8.0.2/lib/rack/handler/puma.rb +144 -0
  96. data/puma-8.0.2/tools/Dockerfile +26 -0
  97. data/puma-8.0.2/tools/trickletest.rb +44 -0
  98. data/tiny-fast-gem.gemspec +12 -0
  99. metadata +138 -0
@@ -0,0 +1,96 @@
1
+ module Puma
2
+ module MiniSSL
3
+ class ContextBuilder
4
+ def initialize(params, log_writer)
5
+ @params = params
6
+ @log_writer = log_writer
7
+ end
8
+
9
+ def context
10
+ ctx = MiniSSL::Context.new
11
+
12
+ if defined?(JRUBY_VERSION)
13
+ unless params['keystore']
14
+ log_writer.error "Please specify the Java keystore via 'keystore='"
15
+ end
16
+
17
+ ctx.keystore = params['keystore']
18
+
19
+ unless params['keystore-pass']
20
+ log_writer.error "Please specify the Java keystore password via 'keystore-pass='"
21
+ end
22
+
23
+ ctx.keystore_pass = params['keystore-pass']
24
+ ctx.keystore_type = params['keystore-type']
25
+
26
+ if truststore = params['truststore']
27
+ ctx.truststore = truststore.eql?('default') ? :default : truststore
28
+ ctx.truststore_pass = params['truststore-pass']
29
+ ctx.truststore_type = params['truststore-type']
30
+ end
31
+
32
+ ctx.cipher_suites = params['cipher_suites'] || params['ssl_cipher_list']
33
+ ctx.protocols = params['protocols'] if params['protocols']
34
+ else
35
+ if params['key'].nil? && params['key_pem'].nil?
36
+ log_writer.error "Please specify the SSL key via 'key=' or 'key_pem='"
37
+ end
38
+
39
+ ctx.key = params['key'] if params['key']
40
+ ctx.key_pem = params['key_pem'] if params['key_pem']
41
+ ctx.key_password_command = params['key_password_command'] if params['key_password_command']
42
+
43
+ if params['cert'].nil? && params['cert_pem'].nil?
44
+ log_writer.error "Please specify the SSL cert via 'cert=' or 'cert_pem='"
45
+ end
46
+
47
+ ctx.cert = params['cert'] if params['cert']
48
+ ctx.cert_pem = params['cert_pem'] if params['cert_pem']
49
+
50
+ if ['peer', 'force_peer'].include?(params['verify_mode'])
51
+ unless params['ca']
52
+ log_writer.error "Please specify the SSL ca via 'ca='"
53
+ end
54
+ # needed for Puma::MiniSSL::Socket#peercert, env['puma.peercert']
55
+ require 'openssl'
56
+ end
57
+
58
+ ctx.ca = params['ca'] if params['ca']
59
+ ctx.ssl_cipher_filter = params['ssl_cipher_filter'] if params['ssl_cipher_filter']
60
+ ctx.ssl_ciphersuites = params['ssl_ciphersuites'] if params['ssl_ciphersuites'] && HAS_TLS1_3
61
+
62
+ ctx.reuse = params['reuse'] if params['reuse']
63
+ end
64
+
65
+ ctx.no_tlsv1 = params['no_tlsv1'] == 'true'
66
+ ctx.no_tlsv1_1 = params['no_tlsv1_1'] == 'true'
67
+
68
+ if params['verify_mode']
69
+ ctx.verify_mode = case params['verify_mode']
70
+ when "peer"
71
+ MiniSSL::VERIFY_PEER
72
+ when "force_peer"
73
+ MiniSSL::VERIFY_PEER | MiniSSL::VERIFY_FAIL_IF_NO_PEER_CERT
74
+ when "none"
75
+ MiniSSL::VERIFY_NONE
76
+ else
77
+ log_writer.error "Please specify a valid verify_mode="
78
+ MiniSSL::VERIFY_NONE
79
+ end
80
+ end
81
+
82
+ if params['verification_flags']
83
+ ctx.verification_flags = params['verification_flags'].split(',').
84
+ map { |flag| MiniSSL::VERIFICATION_FLAGS.fetch(flag) }.
85
+ inject { |sum, flag| sum ? sum | flag : flag }
86
+ end
87
+
88
+ ctx
89
+ end
90
+
91
+ private
92
+
93
+ attr_reader :params, :log_writer
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,458 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
5
+ rescue LoadError
6
+ end
7
+
8
+ require 'open3'
9
+ # need for Puma::MiniSSL::OPENSSL constants used in `HAS_TLS1_3`
10
+ # use require, see https://github.com/puma/puma/pull/2381
11
+ require 'puma/puma_http11'
12
+
13
+ module Puma
14
+ module MiniSSL
15
+ # Define constant at runtime, as it's easy to determine at built time,
16
+ # but Puma could (it shouldn't) be loaded with an older OpenSSL version
17
+ # @version 5.0.0
18
+ HAS_TLS1_3 = IS_JRUBY ||
19
+ ((OPENSSL_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) != -1 &&
20
+ (OPENSSL_LIBRARY_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) !=-1)
21
+
22
+ class Socket
23
+ def initialize(socket, engine)
24
+ @socket = socket
25
+ @engine = engine
26
+ @peercert = nil
27
+ @reuse = nil
28
+ end
29
+
30
+ # @!attribute [r] to_io
31
+ def to_io
32
+ @socket
33
+ end
34
+
35
+ def closed?
36
+ @socket.closed?
37
+ end
38
+
39
+ # Returns a two element array,
40
+ # first is protocol version (SSL_get_version),
41
+ # second is 'handshake' state (SSL_state_string)
42
+ #
43
+ # Used for dropping tcp connections to ssl.
44
+ # See OpenSSL ssl/ssl_stat.c SSL_state_string for info
45
+ # @!attribute [r] ssl_version_state
46
+ # @version 5.0.0
47
+ #
48
+ def ssl_version_state
49
+ IS_JRUBY ? [nil, nil] : @engine.ssl_vers_st
50
+ end
51
+
52
+ # Used to check the handshake status, in particular when a TCP connection
53
+ # is made with TLSv1.3 as an available protocol
54
+ # @version 5.0.0
55
+ def bad_tlsv1_3?
56
+ HAS_TLS1_3 && ssl_version_state == ['TLSv1.3', 'SSLERR']
57
+ end
58
+ private :bad_tlsv1_3?
59
+
60
+ def readpartial(size)
61
+ while true
62
+ output = @engine.read
63
+ return output if output
64
+
65
+ data = @socket.readpartial(size)
66
+ @engine.inject(data)
67
+ output = @engine.read
68
+
69
+ return output if output
70
+
71
+ while neg_data = @engine.extract
72
+ @socket.write neg_data
73
+ end
74
+ end
75
+ end
76
+
77
+ def engine_read_all
78
+ output = @engine.read
79
+ while output and additional_output = @engine.read
80
+ output << additional_output
81
+ end
82
+ output
83
+ end
84
+
85
+ def read_nonblock(size, *_)
86
+ # *_ is to deal with keyword args that were added
87
+ # at some point (and being used in the wild)
88
+ while true
89
+ output = engine_read_all
90
+ return output if output
91
+
92
+ data = @socket.read_nonblock(size, exception: false)
93
+ if data == :wait_readable || data == :wait_writable
94
+ # It would make more sense to let @socket.read_nonblock raise
95
+ # EAGAIN if necessary but it seems like it'll misbehave on Windows.
96
+ # I don't have a Windows machine to debug this so I can't explain
97
+ # exactly whats happening in that OS. Please let me know if you
98
+ # find out!
99
+ #
100
+ # In the meantime, we can emulate the correct behavior by
101
+ # capturing :wait_readable & :wait_writable and raising EAGAIN
102
+ # ourselves.
103
+ raise IO::EAGAINWaitReadable
104
+ elsif data.nil?
105
+ raise SSLError.exception "HTTP connection?" if bad_tlsv1_3?
106
+ return nil
107
+ end
108
+
109
+ @engine.inject(data)
110
+ output = engine_read_all
111
+
112
+ return output if output
113
+
114
+ while neg_data = @engine.extract
115
+ @socket.write neg_data
116
+ end
117
+ end
118
+ end
119
+
120
+ def write(data)
121
+ return 0 if data.empty?
122
+
123
+ data_size = data.bytesize
124
+ need = data_size
125
+
126
+ while true
127
+ wrote = @engine.write data
128
+
129
+ enc_wr = +''
130
+ while (enc = @engine.extract)
131
+ enc_wr << enc
132
+ end
133
+ @socket.write enc_wr unless enc_wr.empty?
134
+
135
+ need -= wrote
136
+
137
+ return data_size if need == 0
138
+
139
+ data = data.byteslice(wrote..-1)
140
+ end
141
+ end
142
+
143
+ alias_method :syswrite, :write
144
+ alias_method :<<, :write
145
+
146
+ # This is a temporary fix to deal with websockets code using
147
+ # write_nonblock.
148
+
149
+ # The problem with implementing it properly
150
+ # is that it means we'd have to have the ability to rewind
151
+ # an engine because after we write+extract, the socket
152
+ # write_nonblock call might raise an exception and later
153
+ # code would pass the same data in, but the engine would think
154
+ # it had already written the data in.
155
+ #
156
+ # So for the time being (and since write blocking is quite rare),
157
+ # go ahead and actually block in write_nonblock.
158
+ #
159
+ def write_nonblock(data, *_)
160
+ write data
161
+ end
162
+
163
+ def flush
164
+ @socket.flush
165
+ end
166
+
167
+ def close
168
+ begin
169
+ unless @engine.shutdown
170
+ while alert_data = @engine.extract
171
+ @socket.write alert_data
172
+ end
173
+ end
174
+ rescue IOError, SystemCallError
175
+ # nothing
176
+ ensure
177
+ @socket.close
178
+ end
179
+ end
180
+
181
+ # @!attribute [r] peeraddr
182
+ def peeraddr
183
+ @socket.peeraddr
184
+ end
185
+
186
+ # OpenSSL is loaded in `MiniSSL::ContextBuilder` when
187
+ # `MiniSSL::Context#verify_mode` is not `VERIFY_NONE`.
188
+ # When `VERIFY_NONE`, `MiniSSL::Engine#peercert` is nil, regardless of
189
+ # whether the client sends a cert.
190
+ # @return [OpenSSL::X509::Certificate, nil]
191
+ # @!attribute [r] peercert
192
+ def peercert
193
+ return @peercert if @peercert
194
+
195
+ raw = @engine.peercert
196
+ return nil unless raw
197
+
198
+ @peercert = OpenSSL::X509::Certificate.new raw
199
+ end
200
+ end
201
+
202
+ if IS_JRUBY
203
+ OPENSSL_NO_SSL3 = false
204
+ OPENSSL_NO_TLS1 = false
205
+ end
206
+
207
+ class Context
208
+ attr_accessor :verify_mode
209
+ attr_reader :no_tlsv1, :no_tlsv1_1
210
+
211
+ def initialize
212
+ @no_tlsv1 = false
213
+ @no_tlsv1_1 = false
214
+ @key = nil
215
+ @cert = nil
216
+ @key_pem = nil
217
+ @cert_pem = nil
218
+ @reuse = nil
219
+ @reuse_cache_size = nil
220
+ @reuse_timeout = nil
221
+ end
222
+
223
+ def check_file(file, desc)
224
+ raise ArgumentError, "#{desc} file '#{file}' does not exist" unless File.exist? file
225
+ raise ArgumentError, "#{desc} file '#{file}' is not readable" unless File.readable? file
226
+ end
227
+
228
+ if IS_JRUBY
229
+ # jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair
230
+ attr_reader :keystore
231
+ attr_reader :keystore_type
232
+ attr_accessor :keystore_pass
233
+ attr_reader :truststore
234
+ attr_reader :truststore_type
235
+ attr_accessor :truststore_pass
236
+ attr_reader :cipher_suites
237
+ attr_reader :protocols
238
+
239
+ def keystore=(keystore)
240
+ check_file keystore, 'Keystore'
241
+ @keystore = keystore
242
+ end
243
+
244
+ def truststore=(truststore)
245
+ # NOTE: historically truststore was assumed the same as keystore, this is kept for backwards
246
+ # compatibility, to rely on JVM's trust defaults we allow setting `truststore = :default`
247
+ unless truststore.eql?(:default)
248
+ raise ArgumentError, "No such truststore file '#{truststore}'" unless File.exist?(truststore)
249
+ end
250
+ @truststore = truststore
251
+ end
252
+
253
+ def keystore_type=(type)
254
+ raise ArgumentError, "Invalid keystore type: #{type.inspect}" unless ['pkcs12', 'jks', nil].include?(type)
255
+ @keystore_type = type
256
+ end
257
+
258
+ def truststore_type=(type)
259
+ raise ArgumentError, "Invalid truststore type: #{type.inspect}" unless ['pkcs12', 'jks', nil].include?(type)
260
+ @truststore_type = type
261
+ end
262
+
263
+ def cipher_suites=(list)
264
+ list = list.split(',').map(&:strip) if list.is_a?(String)
265
+ @cipher_suites = list
266
+ end
267
+
268
+ # aliases for backwards compatibility
269
+ alias_method :ssl_cipher_list, :cipher_suites
270
+ alias_method :ssl_cipher_list=, :cipher_suites=
271
+
272
+ def protocols=(list)
273
+ list = list.split(',').map(&:strip) if list.is_a?(String)
274
+ @protocols = list
275
+ end
276
+
277
+ def check
278
+ raise "Keystore not configured" unless @keystore
279
+ # @truststore defaults to @keystore due backwards compatibility
280
+ end
281
+
282
+ else
283
+ # non-jruby Context properties
284
+ attr_reader :key
285
+ attr_reader :key_password_command
286
+ attr_reader :cert
287
+ attr_reader :ca
288
+ attr_reader :cert_pem
289
+ attr_reader :key_pem
290
+ attr_accessor :ssl_cipher_filter
291
+ attr_accessor :ssl_ciphersuites
292
+ attr_accessor :verification_flags
293
+
294
+ attr_reader :reuse, :reuse_cache_size, :reuse_timeout
295
+
296
+ def key=(key)
297
+ check_file key, 'Key'
298
+ @key = key
299
+ end
300
+
301
+ def key_password_command=(key_password_command)
302
+ @key_password_command = key_password_command
303
+ end
304
+
305
+ def cert=(cert)
306
+ check_file cert, 'Cert'
307
+ @cert = cert
308
+ end
309
+
310
+ def ca=(ca)
311
+ check_file ca, 'ca'
312
+ @ca = ca
313
+ end
314
+
315
+ def cert_pem=(cert_pem)
316
+ raise ArgumentError, "'cert_pem' is not a String" unless cert_pem.is_a? String
317
+ @cert_pem = cert_pem
318
+ end
319
+
320
+ def key_pem=(key_pem)
321
+ raise ArgumentError, "'key_pem' is not a String" unless key_pem.is_a? String
322
+ @key_pem = key_pem
323
+ end
324
+
325
+ def check
326
+ raise "Key not configured" if @key.nil? && @key_pem.nil?
327
+ raise "Cert not configured" if @cert.nil? && @cert_pem.nil?
328
+ end
329
+
330
+ # Executes the command to return the password needed to decrypt the key.
331
+ def key_password
332
+ raise "Key password command not configured" if @key_password_command.nil?
333
+
334
+ stdout_str, stderr_str, status = Open3.capture3(@key_password_command)
335
+
336
+ return stdout_str.chomp if status.success?
337
+
338
+ raise "Key password failed with code #{status.exitstatus}: #{stderr_str}"
339
+ end
340
+
341
+ # Controls session reuse. Allowed values are as follows:
342
+ # * 'off' - matches the behavior of Puma 5.6 and earlier. This is included
343
+ # in case reuse 'on' is made the default in future Puma versions.
344
+ # * 'dflt' - sets session reuse on, with OpenSSL default cache size of
345
+ # 20k and default timeout of 300 seconds.
346
+ # * 's,t' - where s and t are integer strings, for size and timeout.
347
+ # * 's' - where s is an integer strings for size.
348
+ # * ',t' - where t is an integer strings for timeout.
349
+ #
350
+ def reuse=(reuse_str)
351
+ case reuse_str
352
+ when 'off'
353
+ @reuse = nil
354
+ when 'dflt'
355
+ @reuse = true
356
+ when /\A\d+\z/
357
+ @reuse = true
358
+ @reuse_cache_size = reuse_str.to_i
359
+ when /\A\d+,\d+\z/
360
+ @reuse = true
361
+ size, time = reuse_str.split ','
362
+ @reuse_cache_size = size.to_i
363
+ @reuse_timeout = time.to_i
364
+ when /\A,\d+\z/
365
+ @reuse = true
366
+ @reuse_timeout = reuse_str.delete(',').to_i
367
+ end
368
+ end
369
+ end
370
+
371
+ # disables TLSv1
372
+ # @!attribute [w] no_tlsv1=
373
+ def no_tlsv1=(tlsv1)
374
+ raise ArgumentError, "Invalid value of no_tlsv1=" unless ['true', 'false', true, false].include?(tlsv1)
375
+ @no_tlsv1 = tlsv1
376
+ end
377
+
378
+ # disables TLSv1 and TLSv1.1. Overrides `#no_tlsv1=`
379
+ # @!attribute [w] no_tlsv1_1=
380
+ def no_tlsv1_1=(tlsv1_1)
381
+ raise ArgumentError, "Invalid value of no_tlsv1_1=" unless ['true', 'false', true, false].include?(tlsv1_1)
382
+ @no_tlsv1_1 = tlsv1_1
383
+ end
384
+
385
+ end
386
+
387
+ VERIFY_NONE = 0
388
+ VERIFY_PEER = 1
389
+ VERIFY_FAIL_IF_NO_PEER_CERT = 2
390
+
391
+ # https://github.com/openssl/openssl/blob/master/include/openssl/x509_vfy.h.in
392
+ # /* Certificate verify flags */
393
+ VERIFICATION_FLAGS = {
394
+ "USE_CHECK_TIME" => 0x2,
395
+ "CRL_CHECK" => 0x4,
396
+ "CRL_CHECK_ALL" => 0x8,
397
+ "IGNORE_CRITICAL" => 0x10,
398
+ "X509_STRICT" => 0x20,
399
+ "ALLOW_PROXY_CERTS" => 0x40,
400
+ "POLICY_CHECK" => 0x80,
401
+ "EXPLICIT_POLICY" => 0x100,
402
+ "INHIBIT_ANY" => 0x200,
403
+ "INHIBIT_MAP" => 0x400,
404
+ "NOTIFY_POLICY" => 0x800,
405
+ "EXTENDED_CRL_SUPPORT" => 0x1000,
406
+ "USE_DELTAS" => 0x2000,
407
+ "CHECK_SS_SIGNATURE" => 0x4000,
408
+ "TRUSTED_FIRST" => 0x8000,
409
+ "SUITEB_128_LOS_ONLY" => 0x10000,
410
+ "SUITEB_192_LOS" => 0x20000,
411
+ "SUITEB_128_LOS" => 0x30000,
412
+ "PARTIAL_CHAIN" => 0x80000,
413
+ "NO_ALT_CHAINS" => 0x100000,
414
+ "NO_CHECK_TIME" => 0x200000
415
+ }.freeze
416
+
417
+ class Server
418
+ def initialize(socket, ctx)
419
+ @socket = socket
420
+ @ctx = ctx
421
+ @eng_ctx = IS_JRUBY ? @ctx : SSLContext.new(ctx)
422
+ end
423
+
424
+ def accept
425
+ @ctx.check
426
+ io = @socket.accept
427
+ engine = Engine.server @eng_ctx
428
+ Socket.new io, engine
429
+ end
430
+
431
+ def accept_nonblock
432
+ @ctx.check
433
+ io = @socket.accept_nonblock
434
+ engine = Engine.server @eng_ctx
435
+ Socket.new io, engine
436
+ end
437
+
438
+ # @!attribute [r] to_io
439
+ def to_io
440
+ @socket
441
+ end
442
+
443
+ # @!attribute [r] addr
444
+ # @version 5.0.0
445
+ def addr
446
+ @socket.addr
447
+ end
448
+
449
+ def close
450
+ @socket.close unless @socket.closed? # closed? call is for Windows
451
+ end
452
+
453
+ def closed?
454
+ @socket.closed?
455
+ end
456
+ end
457
+ end
458
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Puma
4
+ # Provides an IO-like object that always appears to contain no data.
5
+ # Used as the value for rack.input when the request has no body.
6
+ #
7
+ class NullIO
8
+ def gets
9
+ nil
10
+ end
11
+
12
+ def string
13
+ ""
14
+ end
15
+
16
+ def each
17
+ end
18
+
19
+ def pos
20
+ 0
21
+ end
22
+
23
+ # Mimics IO#read with no data.
24
+ #
25
+ def read(length = nil, buffer = nil)
26
+ if length.to_i < 0
27
+ raise ArgumentError, "(negative length #{length} given)"
28
+ end
29
+
30
+ buffer = if buffer.nil?
31
+ "".b
32
+ else
33
+ String.try_convert(buffer) or raise TypeError, "no implicit conversion of #{buffer.class} into String"
34
+ end
35
+ buffer.clear
36
+ if length.to_i > 0
37
+ nil
38
+ else
39
+ buffer
40
+ end
41
+ end
42
+
43
+ def rewind
44
+ end
45
+
46
+ def seek(pos, whence = 0)
47
+ raise ArgumentError, "negative length #{pos} given" if pos.negative?
48
+ 0
49
+ end
50
+
51
+ def close
52
+ end
53
+
54
+ def size
55
+ 0
56
+ end
57
+
58
+ def eof?
59
+ true
60
+ end
61
+
62
+ def sync
63
+ true
64
+ end
65
+
66
+ def sync=(v)
67
+ end
68
+
69
+ def puts(*ary)
70
+ end
71
+
72
+ def write(*ary)
73
+ end
74
+
75
+ def flush
76
+ self
77
+ end
78
+
79
+ # This is used as singleton class, so can't have state.
80
+ def closed?
81
+ false
82
+ end
83
+
84
+ def set_encoding(enc)
85
+ self
86
+ end
87
+
88
+ # per rack spec
89
+ def external_encoding
90
+ Encoding::ASCII_8BIT
91
+ end
92
+
93
+ def binmode
94
+ self
95
+ end
96
+
97
+ def binmode?
98
+ true
99
+ end
100
+ end
101
+ end