puma 5.0.0.beta2-java → 5.0.4-java
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +1194 -570
- data/README.md +12 -5
- data/bin/puma-wild +3 -9
- data/docs/deployment.md +5 -6
- data/docs/jungle/README.md +0 -4
- data/docs/jungle/rc.d/puma +2 -2
- data/docs/nginx.md +1 -1
- data/docs/restart.md +46 -23
- data/docs/signals.md +3 -3
- data/docs/systemd.md +1 -1
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/mini_ssl.c +42 -37
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +40 -12
- data/ext/puma_http11/puma_http11.c +21 -10
- data/lib/puma.rb +15 -0
- data/lib/puma/app/status.rb +44 -43
- data/lib/puma/binder.rb +35 -8
- data/lib/puma/client.rb +32 -73
- data/lib/puma/cluster.rb +32 -191
- data/lib/puma/cluster/worker.rb +170 -0
- data/lib/puma/cluster/worker_handle.rb +83 -0
- data/lib/puma/configuration.rb +9 -7
- data/lib/puma/const.rb +2 -1
- data/lib/puma/control_cli.rb +2 -0
- data/lib/puma/detect.rb +9 -0
- data/lib/puma/dsl.rb +74 -36
- data/lib/puma/error_logger.rb +3 -2
- data/lib/puma/events.rb +7 -3
- data/lib/puma/launcher.rb +15 -8
- data/lib/puma/minissl.rb +28 -15
- data/lib/puma/minissl/context_builder.rb +0 -3
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/queue_close.rb +26 -0
- data/lib/puma/reactor.rb +77 -373
- data/lib/puma/request.rb +438 -0
- data/lib/puma/runner.rb +6 -18
- data/lib/puma/server.rb +192 -509
- data/lib/puma/single.rb +3 -2
- data/lib/puma/thread_pool.rb +27 -3
- data/lib/puma/util.rb +12 -0
- metadata +9 -8
- data/docs/jungle/upstart/README.md +0 -61
- data/docs/jungle/upstart/puma-manager.conf +0 -31
- data/docs/jungle/upstart/puma.conf +0 -69
- data/lib/puma/accept_nonblock.rb +0 -29
@@ -0,0 +1,15 @@
|
|
1
|
+
package puma;
|
2
|
+
|
3
|
+
import java.io.IOException;
|
4
|
+
|
5
|
+
import org.jruby.Ruby;
|
6
|
+
import org.jruby.runtime.load.BasicLibraryService;
|
7
|
+
|
8
|
+
import org.jruby.puma.Http11;
|
9
|
+
|
10
|
+
public class PumaHttp11Service implements BasicLibraryService {
|
11
|
+
public boolean basicLoad(final Ruby runtime) throws IOException {
|
12
|
+
Http11.createHttp11(runtime);
|
13
|
+
return true;
|
14
|
+
}
|
15
|
+
}
|
@@ -22,6 +22,7 @@ import javax.net.ssl.SSLException;
|
|
22
22
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
23
23
|
import javax.net.ssl.SSLSession;
|
24
24
|
import java.io.FileInputStream;
|
25
|
+
import java.io.InputStream;
|
25
26
|
import java.io.IOException;
|
26
27
|
import java.nio.Buffer;
|
27
28
|
import java.nio.ByteBuffer;
|
@@ -32,6 +33,8 @@ import java.security.NoSuchAlgorithmException;
|
|
32
33
|
import java.security.UnrecoverableKeyException;
|
33
34
|
import java.security.cert.CertificateEncodingException;
|
34
35
|
import java.security.cert.CertificateException;
|
36
|
+
import java.util.concurrent.ConcurrentHashMap;
|
37
|
+
import java.util.Map;
|
35
38
|
|
36
39
|
import static javax.net.ssl.SSLEngineResult.Status;
|
37
40
|
import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
@@ -130,10 +133,39 @@ public class MiniSSL extends RubyObject {
|
|
130
133
|
super(runtime, klass);
|
131
134
|
}
|
132
135
|
|
136
|
+
private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
|
137
|
+
private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();
|
138
|
+
|
133
139
|
@JRubyMethod(meta = true)
|
134
|
-
public static IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
135
|
-
|
140
|
+
public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
141
|
+
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
142
|
+
// Create the KeyManagerFactory and TrustManagerFactory for this server
|
143
|
+
String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
|
144
|
+
char[] password = miniSSLContext.callMethod(context, "keystore_pass").convertToString().asJavaString().toCharArray();
|
145
|
+
|
146
|
+
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
147
|
+
InputStream is = new FileInputStream(keystoreFile);
|
148
|
+
try {
|
149
|
+
ks.load(is, password);
|
150
|
+
} finally {
|
151
|
+
is.close();
|
152
|
+
}
|
153
|
+
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
154
|
+
kmf.init(ks, password);
|
155
|
+
keyManagerFactoryMap.put(keystoreFile, kmf);
|
156
|
+
|
157
|
+
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
158
|
+
is = new FileInputStream(keystoreFile);
|
159
|
+
try {
|
160
|
+
ts.load(is, password);
|
161
|
+
} finally {
|
162
|
+
is.close();
|
163
|
+
}
|
164
|
+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
165
|
+
tmf.init(ts);
|
166
|
+
trustManagerFactoryMap.put(keystoreFile, tmf);
|
136
167
|
|
168
|
+
RubyClass klass = (RubyClass) recv;
|
137
169
|
return klass.newInstance(context,
|
138
170
|
new IRubyObject[] { miniSSLContext },
|
139
171
|
Block.NULL_BLOCK);
|
@@ -141,20 +173,16 @@ public class MiniSSL extends RubyObject {
|
|
141
173
|
|
142
174
|
@JRubyMethod
|
143
175
|
public IRubyObject initialize(ThreadContext threadContext, IRubyObject miniSSLContext)
|
144
|
-
throws KeyStoreException,
|
176
|
+
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
145
177
|
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
146
178
|
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
147
179
|
|
148
|
-
char[] password = miniSSLContext.callMethod(threadContext, "keystore_pass").convertToString().asJavaString().toCharArray();
|
149
180
|
String keystoreFile = miniSSLContext.callMethod(threadContext, "keystore").convertToString().asJavaString();
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
157
|
-
tmf.init(ts);
|
181
|
+
KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
|
182
|
+
TrustManagerFactory tmf = trustManagerFactoryMap.get(keystoreFile);
|
183
|
+
if(kmf == null || tmf == null) {
|
184
|
+
throw new KeyStoreException("Could not find KeyManagerFactory/TrustManagerFactory for keystore: " + keystoreFile);
|
185
|
+
}
|
158
186
|
|
159
187
|
SSLContext sslCtx = SSLContext.getInstance("TLS");
|
160
188
|
|
@@ -253,11 +253,18 @@ void HttpParser_free(void *data) {
|
|
253
253
|
}
|
254
254
|
}
|
255
255
|
|
256
|
-
void HttpParser_mark(
|
256
|
+
void HttpParser_mark(void *ptr) {
|
257
|
+
puma_parser *hp = ptr;
|
257
258
|
if(hp->request) rb_gc_mark(hp->request);
|
258
259
|
if(hp->body) rb_gc_mark(hp->body);
|
259
260
|
}
|
260
261
|
|
262
|
+
const rb_data_type_t HttpParser_data_type = {
|
263
|
+
"HttpParser",
|
264
|
+
{ HttpParser_mark, HttpParser_free, 0 },
|
265
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
266
|
+
};
|
267
|
+
|
261
268
|
VALUE HttpParser_alloc(VALUE klass)
|
262
269
|
{
|
263
270
|
puma_parser *hp = ALLOC_N(puma_parser, 1);
|
@@ -274,7 +281,7 @@ VALUE HttpParser_alloc(VALUE klass)
|
|
274
281
|
|
275
282
|
puma_parser_init(hp);
|
276
283
|
|
277
|
-
return
|
284
|
+
return TypedData_Wrap_Struct(klass, &HttpParser_data_type, hp);
|
278
285
|
}
|
279
286
|
|
280
287
|
/**
|
@@ -286,7 +293,7 @@ VALUE HttpParser_alloc(VALUE klass)
|
|
286
293
|
VALUE HttpParser_init(VALUE self)
|
287
294
|
{
|
288
295
|
puma_parser *http = NULL;
|
289
|
-
DATA_GET(self, puma_parser, http);
|
296
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
290
297
|
puma_parser_init(http);
|
291
298
|
|
292
299
|
return self;
|
@@ -303,7 +310,7 @@ VALUE HttpParser_init(VALUE self)
|
|
303
310
|
VALUE HttpParser_reset(VALUE self)
|
304
311
|
{
|
305
312
|
puma_parser *http = NULL;
|
306
|
-
DATA_GET(self, puma_parser, http);
|
313
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
307
314
|
puma_parser_init(http);
|
308
315
|
|
309
316
|
return Qnil;
|
@@ -320,7 +327,7 @@ VALUE HttpParser_reset(VALUE self)
|
|
320
327
|
VALUE HttpParser_finish(VALUE self)
|
321
328
|
{
|
322
329
|
puma_parser *http = NULL;
|
323
|
-
DATA_GET(self, puma_parser, http);
|
330
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
324
331
|
puma_parser_finish(http);
|
325
332
|
|
326
333
|
return puma_parser_is_finished(http) ? Qtrue : Qfalse;
|
@@ -351,7 +358,7 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
|
|
351
358
|
char *dptr = NULL;
|
352
359
|
long dlen = 0;
|
353
360
|
|
354
|
-
DATA_GET(self, puma_parser, http);
|
361
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
355
362
|
|
356
363
|
from = FIX2INT(start);
|
357
364
|
dptr = rb_extract_chars(data, &dlen);
|
@@ -385,7 +392,7 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
|
|
385
392
|
VALUE HttpParser_has_error(VALUE self)
|
386
393
|
{
|
387
394
|
puma_parser *http = NULL;
|
388
|
-
DATA_GET(self, puma_parser, http);
|
395
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
389
396
|
|
390
397
|
return puma_parser_has_error(http) ? Qtrue : Qfalse;
|
391
398
|
}
|
@@ -400,7 +407,7 @@ VALUE HttpParser_has_error(VALUE self)
|
|
400
407
|
VALUE HttpParser_is_finished(VALUE self)
|
401
408
|
{
|
402
409
|
puma_parser *http = NULL;
|
403
|
-
DATA_GET(self, puma_parser, http);
|
410
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
404
411
|
|
405
412
|
return puma_parser_is_finished(http) ? Qtrue : Qfalse;
|
406
413
|
}
|
@@ -416,7 +423,7 @@ VALUE HttpParser_is_finished(VALUE self)
|
|
416
423
|
VALUE HttpParser_nread(VALUE self)
|
417
424
|
{
|
418
425
|
puma_parser *http = NULL;
|
419
|
-
DATA_GET(self, puma_parser, http);
|
426
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
420
427
|
|
421
428
|
return INT2FIX(http->nread);
|
422
429
|
}
|
@@ -429,12 +436,14 @@ VALUE HttpParser_nread(VALUE self)
|
|
429
436
|
*/
|
430
437
|
VALUE HttpParser_body(VALUE self) {
|
431
438
|
puma_parser *http = NULL;
|
432
|
-
DATA_GET(self, puma_parser, http);
|
439
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
433
440
|
|
434
441
|
return http->body;
|
435
442
|
}
|
436
443
|
|
444
|
+
#ifdef HAVE_OPENSSL_BIO_H
|
437
445
|
void Init_mini_ssl(VALUE mod);
|
446
|
+
#endif
|
438
447
|
|
439
448
|
void Init_puma_http11()
|
440
449
|
{
|
@@ -463,5 +472,7 @@ void Init_puma_http11()
|
|
463
472
|
rb_define_method(cHttpParser, "body", HttpParser_body, 0);
|
464
473
|
init_common_fields();
|
465
474
|
|
475
|
+
#ifdef HAVE_OPENSSL_BIO_H
|
466
476
|
Init_mini_ssl(mPuma);
|
477
|
+
#endif
|
467
478
|
}
|
data/lib/puma.rb
CHANGED
@@ -10,20 +10,27 @@ require 'stringio'
|
|
10
10
|
|
11
11
|
require 'thread'
|
12
12
|
|
13
|
+
require 'puma/puma_http11'
|
14
|
+
require 'puma/detect'
|
15
|
+
|
13
16
|
module Puma
|
14
17
|
autoload :Const, 'puma/const'
|
15
18
|
autoload :Server, 'puma/server'
|
16
19
|
autoload :Launcher, 'puma/launcher'
|
17
20
|
|
21
|
+
# @!attribute [rw] stats_object=
|
18
22
|
def self.stats_object=(val)
|
19
23
|
@get_stats = val
|
20
24
|
end
|
21
25
|
|
26
|
+
# @!attribute [rw] stats_object
|
22
27
|
def self.stats
|
23
28
|
require 'json'
|
24
29
|
@get_stats.stats.to_json
|
25
30
|
end
|
26
31
|
|
32
|
+
# @!attribute [r] stats_hash
|
33
|
+
# @version 5.0.0
|
27
34
|
def self.stats_hash
|
28
35
|
@get_stats.stats
|
29
36
|
end
|
@@ -33,4 +40,12 @@ module Puma
|
|
33
40
|
return unless Thread.current.respond_to?(:name=)
|
34
41
|
Thread.current.name = "puma #{name}"
|
35
42
|
end
|
43
|
+
|
44
|
+
unless HAS_SSL
|
45
|
+
module MiniSSL
|
46
|
+
# this class is defined so that it exists when Puma is compiled
|
47
|
+
# without ssl support, as Server and Reactor use it in rescue statements.
|
48
|
+
class SSLError < StandardError ; end
|
49
|
+
end
|
50
|
+
end
|
36
51
|
end
|
data/lib/puma/app/status.rb
CHANGED
@@ -7,11 +7,16 @@ module Puma
|
|
7
7
|
class Status
|
8
8
|
OK_STATUS = '{ "status": "ok" }'.freeze
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
# @param launcher [::Puma::Launcher]
|
11
|
+
# @param token [String, nil] the token used for authentication
|
12
|
+
#
|
13
|
+
def initialize(launcher, token = nil)
|
14
|
+
@launcher = launcher
|
12
15
|
@auth_token = token
|
13
16
|
end
|
14
17
|
|
18
|
+
# most commands call methods in `::Puma::Launcher` based on command in
|
19
|
+
# `env['PATH_INFO']`
|
15
20
|
def call(env)
|
16
21
|
unless authenticate(env)
|
17
22
|
return rack_response(403, 'Invalid auth token', 'text/plain')
|
@@ -21,57 +26,53 @@ module Puma
|
|
21
26
|
require 'json'
|
22
27
|
end
|
23
28
|
|
24
|
-
case
|
25
|
-
|
26
|
-
|
27
|
-
|
29
|
+
# resp_type is processed by following case statement, return
|
30
|
+
# is a number (status) or a string used as the body of a 200 response
|
31
|
+
resp_type =
|
32
|
+
case env['PATH_INFO'][/\/([^\/]+)$/, 1]
|
33
|
+
when 'stop'
|
34
|
+
@launcher.stop ; 200
|
28
35
|
|
29
|
-
|
30
|
-
|
31
|
-
rack_response(200, OK_STATUS)
|
36
|
+
when 'halt'
|
37
|
+
@launcher.halt ; 200
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
rack_response(200, OK_STATUS)
|
39
|
+
when 'restart'
|
40
|
+
@launcher.restart ; 200
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
rack_response(404, '{ "error": "phased restart not available" }')
|
40
|
-
else
|
41
|
-
rack_response(200, OK_STATUS)
|
42
|
-
end
|
43
|
-
|
44
|
-
when /\/reload-worker-directory$/
|
45
|
-
if !@cli.send(:reload_worker_directory)
|
46
|
-
rack_response(404, '{ "error": "reload_worker_directory not available" }')
|
47
|
-
else
|
48
|
-
rack_response(200, OK_STATUS)
|
49
|
-
end
|
42
|
+
when 'phased-restart'
|
43
|
+
@launcher.phased_restart ? 200 : 404
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
rack_response(200, OK_STATUS)
|
45
|
+
when 'reload-worker-directory'
|
46
|
+
@launcher.send(:reload_worker_directory) ? 200 : 404
|
54
47
|
|
55
|
-
|
56
|
-
|
48
|
+
when 'gc'
|
49
|
+
GC.start ; 200
|
57
50
|
|
58
|
-
|
59
|
-
|
51
|
+
when 'gc-stats'
|
52
|
+
GC.stat.to_json
|
60
53
|
|
61
|
-
|
62
|
-
|
63
|
-
@cli.thread_status do |name, backtrace|
|
64
|
-
backtraces << { name: name, backtrace: backtrace }
|
65
|
-
end
|
54
|
+
when 'stats'
|
55
|
+
@launcher.stats.to_json
|
66
56
|
|
67
|
-
|
57
|
+
when 'thread-backtraces'
|
58
|
+
backtraces = []
|
59
|
+
@launcher.thread_status do |name, backtrace|
|
60
|
+
backtraces << { name: name, backtrace: backtrace }
|
61
|
+
end
|
62
|
+
backtraces.to_json
|
68
63
|
|
69
|
-
|
70
|
-
|
71
|
-
|
64
|
+
else
|
65
|
+
return rack_response(404, "Unsupported action", 'text/plain')
|
66
|
+
end
|
72
67
|
|
73
|
-
|
74
|
-
|
68
|
+
case resp_type
|
69
|
+
when String
|
70
|
+
rack_response 200, resp_type
|
71
|
+
when 200
|
72
|
+
rack_response 200, OK_STATUS
|
73
|
+
when 404
|
74
|
+
str = env['PATH_INFO'][/\/(\S+)/, 1].tr '-', '_'
|
75
|
+
rack_response 404, "{ \"error\": \"#{str} not available\" }"
|
75
76
|
end
|
76
77
|
end
|
77
78
|
|
data/lib/puma/binder.rb
CHANGED
@@ -5,10 +5,24 @@ require 'socket'
|
|
5
5
|
|
6
6
|
require 'puma/const'
|
7
7
|
require 'puma/util'
|
8
|
-
require 'puma/minissl/context_builder'
|
9
8
|
require 'puma/configuration'
|
10
9
|
|
11
10
|
module Puma
|
11
|
+
|
12
|
+
if HAS_SSL
|
13
|
+
require 'puma/minissl'
|
14
|
+
require 'puma/minissl/context_builder'
|
15
|
+
|
16
|
+
# Odd bug in 'pure Ruby' nio4r verion 2.5.2, which installs with Ruby 2.3.
|
17
|
+
# NIO doesn't create any OpenSSL objects, but it rescues an OpenSSL error.
|
18
|
+
# The bug was that it did not require openssl.
|
19
|
+
# @todo remove when Ruby 2.3 support is dropped
|
20
|
+
#
|
21
|
+
if windows? && RbConfig::CONFIG['ruby_version'] == '2.3.0'
|
22
|
+
require 'openssl'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
12
26
|
class Binder
|
13
27
|
include Puma::Const
|
14
28
|
|
@@ -44,7 +58,12 @@ module Puma
|
|
44
58
|
@ios = []
|
45
59
|
end
|
46
60
|
|
47
|
-
attr_reader :ios
|
61
|
+
attr_reader :ios
|
62
|
+
|
63
|
+
# @version 5.0.0
|
64
|
+
attr_reader :activated_sockets, :envs, :inherited_fds, :listeners, :proto_env, :unix_paths
|
65
|
+
|
66
|
+
# @version 5.0.0
|
48
67
|
attr_writer :ios, :listeners
|
49
68
|
|
50
69
|
def env(sock)
|
@@ -55,10 +74,13 @@ module Puma
|
|
55
74
|
@ios.each { |i| i.close }
|
56
75
|
end
|
57
76
|
|
77
|
+
# @!attribute [r] connected_ports
|
78
|
+
# @version 5.0.0
|
58
79
|
def connected_ports
|
59
80
|
ios.map { |io| io.addr[1] }.uniq
|
60
81
|
end
|
61
82
|
|
83
|
+
# @version 5.0.0
|
62
84
|
def create_inherited_fds(env_hash)
|
63
85
|
env_hash.select {|k,v| k =~ /PUMA_INHERIT_\d+/}.each do |_k, v|
|
64
86
|
fd, url = v.split(":", 2)
|
@@ -69,7 +91,9 @@ module Puma
|
|
69
91
|
# systemd socket activation.
|
70
92
|
# LISTEN_FDS = number of listening sockets. e.g. 2 means accept on 2 sockets w/descriptors 3 and 4.
|
71
93
|
# LISTEN_PID = PID of the service process, aka us
|
72
|
-
# see https://www.freedesktop.org/software/systemd/man/systemd-socket-activate.html
|
94
|
+
# @see https://www.freedesktop.org/software/systemd/man/systemd-socket-activate.html
|
95
|
+
# @version 5.0.0
|
96
|
+
#
|
73
97
|
def create_activated_fds(env_hash)
|
74
98
|
return [] unless env_hash['LISTEN_FDS'] && env_hash['LISTEN_PID'].to_i == $$
|
75
99
|
env_hash['LISTEN_FDS'].to_i.times do |index|
|
@@ -155,6 +179,9 @@ module Puma
|
|
155
179
|
|
156
180
|
@listeners << [str, io]
|
157
181
|
when "ssl"
|
182
|
+
|
183
|
+
raise "Puma compiled without SSL support" unless HAS_SSL
|
184
|
+
|
158
185
|
params = Util.parse_query uri.query
|
159
186
|
ctx = MiniSSL::ContextBuilder.new(params, @events).context
|
160
187
|
|
@@ -245,9 +272,8 @@ module Puma
|
|
245
272
|
|
246
273
|
def add_ssl_listener(host, port, ctx,
|
247
274
|
optimize_for_latency=true, backlog=1024)
|
248
|
-
require 'puma/minissl'
|
249
275
|
|
250
|
-
|
276
|
+
raise "Puma compiled without SSL support" unless HAS_SSL
|
251
277
|
|
252
278
|
if host == "localhost"
|
253
279
|
loopback_addresses.each do |addr|
|
@@ -264,7 +290,6 @@ module Puma
|
|
264
290
|
s.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
265
291
|
s.listen backlog
|
266
292
|
|
267
|
-
|
268
293
|
ssl = MiniSSL::Server.new s, ctx
|
269
294
|
env = @proto_env.dup
|
270
295
|
env[HTTPS_KEY] = HTTPS
|
@@ -275,8 +300,7 @@ module Puma
|
|
275
300
|
end
|
276
301
|
|
277
302
|
def inherit_ssl_listener(fd, ctx)
|
278
|
-
|
279
|
-
MiniSSL.check
|
303
|
+
raise "Puma compiled without SSL support" unless HAS_SSL
|
280
304
|
|
281
305
|
if fd.kind_of? TCPServer
|
282
306
|
s = fd
|
@@ -367,6 +391,7 @@ module Puma
|
|
367
391
|
redirects
|
368
392
|
end
|
369
393
|
|
394
|
+
# @version 5.0.0
|
370
395
|
def redirects_for_restart_env
|
371
396
|
listeners.each_with_object({}).with_index do |(listen, memo), i|
|
372
397
|
memo["PUMA_INHERIT_#{i}"] = "#{listen[1].to_i}:#{listen[0]}"
|
@@ -375,12 +400,14 @@ module Puma
|
|
375
400
|
|
376
401
|
private
|
377
402
|
|
403
|
+
# @!attribute [r] loopback_addresses
|
378
404
|
def loopback_addresses
|
379
405
|
Socket.ip_address_list.select do |addrinfo|
|
380
406
|
addrinfo.ipv6_loopback? || addrinfo.ipv4_loopback?
|
381
407
|
end.map { |addrinfo| addrinfo.ip_address }.uniq
|
382
408
|
end
|
383
409
|
|
410
|
+
# @version 5.0.0
|
384
411
|
def socket_activation_fd(int)
|
385
412
|
int + 3 # 3 is the magic number you add to follow the SA protocol
|
386
413
|
end
|