piesync-puma 3.12.6

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 (82) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +1429 -0
  3. data/LICENSE +26 -0
  4. data/README.md +280 -0
  5. data/bin/puma +10 -0
  6. data/bin/puma-wild +31 -0
  7. data/bin/pumactl +12 -0
  8. data/docs/architecture.md +36 -0
  9. data/docs/deployment.md +91 -0
  10. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  11. data/docs/images/puma-connection-flow.png +0 -0
  12. data/docs/images/puma-general-arch.png +0 -0
  13. data/docs/nginx.md +80 -0
  14. data/docs/plugins.md +28 -0
  15. data/docs/restart.md +39 -0
  16. data/docs/signals.md +96 -0
  17. data/docs/systemd.md +272 -0
  18. data/ext/puma_http11/PumaHttp11Service.java +17 -0
  19. data/ext/puma_http11/ext_help.h +15 -0
  20. data/ext/puma_http11/extconf.rb +15 -0
  21. data/ext/puma_http11/http11_parser.c +1071 -0
  22. data/ext/puma_http11/http11_parser.h +65 -0
  23. data/ext/puma_http11/http11_parser.java.rl +161 -0
  24. data/ext/puma_http11/http11_parser.rl +149 -0
  25. data/ext/puma_http11/http11_parser_common.rl +54 -0
  26. data/ext/puma_http11/io_buffer.c +155 -0
  27. data/ext/puma_http11/mini_ssl.c +494 -0
  28. data/ext/puma_http11/org/jruby/puma/Http11.java +234 -0
  29. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +470 -0
  30. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +352 -0
  31. data/ext/puma_http11/puma_http11.c +500 -0
  32. data/lib/puma.rb +23 -0
  33. data/lib/puma/accept_nonblock.rb +23 -0
  34. data/lib/puma/app/status.rb +74 -0
  35. data/lib/puma/binder.rb +413 -0
  36. data/lib/puma/cli.rb +235 -0
  37. data/lib/puma/client.rb +480 -0
  38. data/lib/puma/cluster.rb +531 -0
  39. data/lib/puma/commonlogger.rb +108 -0
  40. data/lib/puma/compat.rb +14 -0
  41. data/lib/puma/configuration.rb +361 -0
  42. data/lib/puma/const.rb +239 -0
  43. data/lib/puma/control_cli.rb +264 -0
  44. data/lib/puma/convenient.rb +25 -0
  45. data/lib/puma/daemon_ext.rb +33 -0
  46. data/lib/puma/delegation.rb +13 -0
  47. data/lib/puma/detect.rb +15 -0
  48. data/lib/puma/dsl.rb +518 -0
  49. data/lib/puma/events.rb +153 -0
  50. data/lib/puma/io_buffer.rb +9 -0
  51. data/lib/puma/java_io_buffer.rb +47 -0
  52. data/lib/puma/jruby_restart.rb +84 -0
  53. data/lib/puma/launcher.rb +433 -0
  54. data/lib/puma/minissl.rb +285 -0
  55. data/lib/puma/null_io.rb +44 -0
  56. data/lib/puma/plugin.rb +117 -0
  57. data/lib/puma/plugin/tmp_restart.rb +34 -0
  58. data/lib/puma/rack/backports/uri/common_193.rb +33 -0
  59. data/lib/puma/rack/builder.rb +299 -0
  60. data/lib/puma/rack/urlmap.rb +91 -0
  61. data/lib/puma/rack_default.rb +7 -0
  62. data/lib/puma/reactor.rb +347 -0
  63. data/lib/puma/runner.rb +184 -0
  64. data/lib/puma/server.rb +1072 -0
  65. data/lib/puma/single.rb +123 -0
  66. data/lib/puma/state_file.rb +31 -0
  67. data/lib/puma/tcp_logger.rb +41 -0
  68. data/lib/puma/thread_pool.rb +346 -0
  69. data/lib/puma/util.rb +129 -0
  70. data/lib/rack/handler/puma.rb +115 -0
  71. data/tools/jungle/README.md +19 -0
  72. data/tools/jungle/init.d/README.md +61 -0
  73. data/tools/jungle/init.d/puma +421 -0
  74. data/tools/jungle/init.d/run-puma +18 -0
  75. data/tools/jungle/rc.d/README.md +74 -0
  76. data/tools/jungle/rc.d/puma +61 -0
  77. data/tools/jungle/rc.d/puma.conf +10 -0
  78. data/tools/jungle/upstart/README.md +61 -0
  79. data/tools/jungle/upstart/puma-manager.conf +31 -0
  80. data/tools/jungle/upstart/puma.conf +69 -0
  81. data/tools/trickletest.rb +45 -0
  82. metadata +131 -0
@@ -0,0 +1,285 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'io/wait'
5
+ rescue LoadError
6
+ end
7
+
8
+ module Puma
9
+ module MiniSSL
10
+ class Socket
11
+ def initialize(socket, engine)
12
+ @socket = socket
13
+ @engine = engine
14
+ @peercert = nil
15
+ end
16
+
17
+ def to_io
18
+ @socket
19
+ end
20
+
21
+ def closed?
22
+ @socket.closed?
23
+ end
24
+
25
+ def readpartial(size)
26
+ while true
27
+ output = @engine.read
28
+ return output if output
29
+
30
+ data = @socket.readpartial(size)
31
+ @engine.inject(data)
32
+ output = @engine.read
33
+
34
+ return output if output
35
+
36
+ while neg_data = @engine.extract
37
+ @socket.write neg_data
38
+ end
39
+ end
40
+ end
41
+
42
+ def engine_read_all
43
+ output = @engine.read
44
+ while output and additional_output = @engine.read
45
+ output << additional_output
46
+ end
47
+ output
48
+ end
49
+
50
+ def read_nonblock(size, *_)
51
+ # *_ is to deal with keyword args that were added
52
+ # at some point (and being used in the wild)
53
+ while true
54
+ output = engine_read_all
55
+ return output if output
56
+
57
+ begin
58
+ data = @socket.read_nonblock(size, exception: false)
59
+ if data == :wait_readable || data == :wait_writable
60
+ if @socket.to_io.respond_to?(data)
61
+ @socket.to_io.__send__(data)
62
+ elsif data == :wait_readable
63
+ IO.select([@socket.to_io])
64
+ else
65
+ IO.select(nil, [@socket.to_io])
66
+ end
67
+ elsif !data
68
+ return nil
69
+ else
70
+ break
71
+ end
72
+ end while true
73
+
74
+ @engine.inject(data)
75
+ output = engine_read_all
76
+
77
+ return output if output
78
+
79
+ while neg_data = @engine.extract
80
+ @socket.write neg_data
81
+ end
82
+ end
83
+ end
84
+
85
+ def write(data)
86
+ return 0 if data.empty?
87
+
88
+ need = data.bytesize
89
+
90
+ while true
91
+ wrote = @engine.write data
92
+ enc = @engine.extract
93
+
94
+ while enc
95
+ @socket.write enc
96
+ enc = @engine.extract
97
+ end
98
+
99
+ need -= wrote
100
+
101
+ return data.bytesize if need == 0
102
+
103
+ data = data[wrote..-1]
104
+ end
105
+ end
106
+
107
+ alias_method :syswrite, :write
108
+ alias_method :<<, :write
109
+
110
+ # This is a temporary fix to deal with websockets code using
111
+ # write_nonblock. The problem with implementing it properly
112
+ # is that it means we'd have to have the ability to rewind
113
+ # an engine because after we write+extract, the socket
114
+ # write_nonblock call might raise an exception and later
115
+ # code would pass the same data in, but the engine would think
116
+ # it had already written the data in. So for the time being
117
+ # (and since write blocking is quite rare), go ahead and actually
118
+ # block in write_nonblock.
119
+ def write_nonblock(data, *_)
120
+ write data
121
+ end
122
+
123
+ def flush
124
+ @socket.flush
125
+ end
126
+
127
+ def read_and_drop(timeout = 1)
128
+ return :timeout unless IO.select([@socket], nil, nil, timeout)
129
+ return :eof unless read_nonblock(1024)
130
+ :drop
131
+ rescue Errno::EAGAIN
132
+ # do nothing
133
+ :eagain
134
+ end
135
+
136
+ def should_drop_bytes?
137
+ @engine.init? || !@engine.shutdown
138
+ end
139
+
140
+ def close
141
+ begin
142
+ # Read any drop any partially initialized sockets and any received bytes during shutdown.
143
+ # Don't let this socket hold this loop forever.
144
+ # If it can't send more packets within 1s, then give up.
145
+ while should_drop_bytes?
146
+ return if [:timeout, :eof].include?(read_and_drop(1))
147
+ end
148
+ rescue IOError, SystemCallError
149
+ Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
150
+ # nothing
151
+ ensure
152
+ @socket.close
153
+ end
154
+ end
155
+
156
+ def peeraddr
157
+ @socket.peeraddr
158
+ end
159
+
160
+ def peercert
161
+ return @peercert if @peercert
162
+
163
+ raw = @engine.peercert
164
+ return nil unless raw
165
+
166
+ @peercert = OpenSSL::X509::Certificate.new raw
167
+ end
168
+ end
169
+
170
+ if defined?(JRUBY_VERSION)
171
+ class SSLError < StandardError
172
+ # Define this for jruby even though it isn't used.
173
+ end
174
+
175
+ def self.check; end
176
+ end
177
+
178
+ class Context
179
+ attr_accessor :verify_mode
180
+
181
+ if defined?(JRUBY_VERSION)
182
+ # jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair
183
+ attr_reader :keystore
184
+ attr_accessor :keystore_pass
185
+ attr_accessor :ssl_cipher_list
186
+
187
+ def keystore=(keystore)
188
+ raise ArgumentError, "No such keystore file '#{keystore}'" unless File.exist? keystore
189
+ @keystore = keystore
190
+ end
191
+
192
+ def check
193
+ raise "Keystore not configured" unless @keystore
194
+ end
195
+
196
+ else
197
+ # non-jruby Context properties
198
+ attr_reader :key
199
+ attr_reader :cert
200
+ attr_reader :ca
201
+ attr_accessor :ssl_cipher_filter
202
+ attr_accessor :verification_flags
203
+
204
+ def key=(key)
205
+ raise ArgumentError, "No such key file '#{key}'" unless File.exist? key
206
+ @key = key
207
+ end
208
+
209
+ def cert=(cert)
210
+ raise ArgumentError, "No such cert file '#{cert}'" unless File.exist? cert
211
+ @cert = cert
212
+ end
213
+
214
+ def ca=(ca)
215
+ raise ArgumentError, "No such ca file '#{ca}'" unless File.exist? ca
216
+ @ca = ca
217
+ end
218
+
219
+ def check
220
+ raise "Key not configured" unless @key
221
+ raise "Cert not configured" unless @cert
222
+ end
223
+ end
224
+ end
225
+
226
+ VERIFY_NONE = 0
227
+ VERIFY_PEER = 1
228
+ VERIFY_FAIL_IF_NO_PEER_CERT = 2
229
+
230
+ VERIFICATION_FLAGS = {
231
+ "USE_CHECK_TIME" => 0x2,
232
+ "CRL_CHECK" => 0x4,
233
+ "CRL_CHECK_ALL" => 0x8,
234
+ "IGNORE_CRITICAL" => 0x10,
235
+ "X509_STRICT" => 0x20,
236
+ "ALLOW_PROXY_CERTS" => 0x40,
237
+ "POLICY_CHECK" => 0x80,
238
+ "EXPLICIT_POLICY" => 0x100,
239
+ "INHIBIT_ANY" => 0x200,
240
+ "INHIBIT_MAP" => 0x400,
241
+ "NOTIFY_POLICY" => 0x800,
242
+ "EXTENDED_CRL_SUPPORT" => 0x1000,
243
+ "USE_DELTAS" => 0x2000,
244
+ "CHECK_SS_SIGNATURE" => 0x4000,
245
+ "TRUSTED_FIRST" => 0x8000,
246
+ "SUITEB_128_LOS_ONLY" => 0x10000,
247
+ "SUITEB_192_LOS" => 0x20000,
248
+ "SUITEB_128_LOS" => 0x30000,
249
+ "PARTIAL_CHAIN" => 0x80000,
250
+ "NO_ALT_CHAINS" => 0x100000,
251
+ "NO_CHECK_TIME" => 0x200000
252
+ }.freeze
253
+
254
+ class Server
255
+ def initialize(socket, ctx)
256
+ @socket = socket
257
+ @ctx = ctx
258
+ end
259
+
260
+ def to_io
261
+ @socket
262
+ end
263
+
264
+ def accept
265
+ @ctx.check
266
+ io = @socket.accept
267
+ engine = Engine.server @ctx
268
+
269
+ Socket.new io, engine
270
+ end
271
+
272
+ def accept_nonblock
273
+ @ctx.check
274
+ io = @socket.accept_nonblock
275
+ engine = Engine.server @ctx
276
+
277
+ Socket.new io, engine
278
+ end
279
+
280
+ def close
281
+ @socket.close unless @socket.closed? # closed? call is for Windows
282
+ end
283
+ end
284
+ end
285
+ end
@@ -0,0 +1,44 @@
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 each
13
+ end
14
+
15
+ # Mimics IO#read with no data.
16
+ #
17
+ def read(count = nil, _buffer = nil)
18
+ (count && count > 0) ? nil : ""
19
+ end
20
+
21
+ def rewind
22
+ end
23
+
24
+ def close
25
+ end
26
+
27
+ def size
28
+ 0
29
+ end
30
+
31
+ def eof?
32
+ true
33
+ end
34
+
35
+ def sync=(v)
36
+ end
37
+
38
+ def puts(*ary)
39
+ end
40
+
41
+ def write(*ary)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Puma
4
+ class UnknownPlugin < RuntimeError; end
5
+
6
+ class PluginLoader
7
+ def initialize
8
+ @instances = []
9
+ end
10
+
11
+ def create(name)
12
+ if cls = Plugins.find(name)
13
+ plugin = cls.new(Plugin)
14
+ @instances << plugin
15
+ return plugin
16
+ end
17
+
18
+ raise UnknownPlugin, "File failed to register properly named plugin"
19
+ end
20
+
21
+ def fire_starts(launcher)
22
+ @instances.each do |i|
23
+ if i.respond_to? :start
24
+ i.start(launcher)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ class PluginRegistry
31
+ def initialize
32
+ @plugins = {}
33
+ @background = []
34
+ end
35
+
36
+ def register(name, cls)
37
+ @plugins[name] = cls
38
+ end
39
+
40
+ def find(name)
41
+ name = name.to_s
42
+
43
+ if cls = @plugins[name]
44
+ return cls
45
+ end
46
+
47
+ begin
48
+ require "puma/plugin/#{name}"
49
+ rescue LoadError
50
+ raise UnknownPlugin, "Unable to find plugin: #{name}"
51
+ end
52
+
53
+ if cls = @plugins[name]
54
+ return cls
55
+ end
56
+
57
+ raise UnknownPlugin, "file failed to register a plugin"
58
+ end
59
+
60
+ def add_background(blk)
61
+ @background << blk
62
+ end
63
+
64
+ def fire_background
65
+ @background.each do |b|
66
+ Thread.new(&b)
67
+ end
68
+ end
69
+ end
70
+
71
+ Plugins = PluginRegistry.new
72
+
73
+ class Plugin
74
+ # Matches
75
+ # "C:/Ruby22/lib/ruby/gems/2.2.0/gems/puma-3.0.1/lib/puma/plugin/tmp_restart.rb:3:in `<top (required)>'"
76
+ # AS
77
+ # C:/Ruby22/lib/ruby/gems/2.2.0/gems/puma-3.0.1/lib/puma/plugin/tmp_restart.rb
78
+ CALLER_FILE = /
79
+ \A # start of string
80
+ .+ # file path (one or more characters)
81
+ (?= # stop previous match when
82
+ :\d+ # a colon is followed by one or more digits
83
+ :in # followed by a colon followed by in
84
+ )
85
+ /x
86
+
87
+ def self.extract_name(ary)
88
+ path = ary.first[CALLER_FILE]
89
+
90
+ m = %r!puma/plugin/([^/]*)\.rb$!.match(path)
91
+ return m[1]
92
+ end
93
+
94
+ def self.create(&blk)
95
+ name = extract_name(caller)
96
+
97
+ cls = Class.new(self)
98
+
99
+ cls.class_eval(&blk)
100
+
101
+ Plugins.register name, cls
102
+ end
103
+
104
+ def initialize(loader)
105
+ @loader = loader
106
+ end
107
+
108
+ def in_background(&blk)
109
+ Plugins.add_background blk
110
+ end
111
+
112
+ def workers_supported?
113
+ return false if Puma.jruby? || Puma.windows?
114
+ true
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,34 @@
1
+ require 'puma/plugin'
2
+
3
+ Puma::Plugin.create do
4
+ def start(launcher)
5
+ path = File.join("tmp", "restart.txt")
6
+
7
+ orig = nil
8
+
9
+ # If we can't write to the path, then just don't bother with this plugin
10
+ begin
11
+ File.write(path, "") unless File.exist?(path)
12
+ orig = File.stat(path).mtime
13
+ rescue SystemCallError
14
+ return
15
+ end
16
+
17
+ in_background do
18
+ while true
19
+ sleep 2
20
+
21
+ begin
22
+ mtime = File.stat(path).mtime
23
+ rescue SystemCallError
24
+ # If the file has disappeared, assume that means don't restart
25
+ else
26
+ if mtime > orig
27
+ launcher.restart
28
+ break
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end