puma 5.6.9-java → 6.6.0-java
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 +4 -4
- data/History.md +465 -18
- data/README.md +152 -42
- data/bin/puma-wild +1 -1
- data/docs/compile_options.md +34 -0
- data/docs/fork_worker.md +12 -4
- data/docs/java_options.md +54 -0
- data/docs/kubernetes.md +12 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +4 -0
- data/docs/restart.md +1 -0
- data/docs/signals.md +2 -2
- data/docs/stats.md +8 -3
- data/docs/systemd.md +13 -7
- data/docs/testing_benchmarks_local_files.md +150 -0
- data/docs/testing_test_rackup_ci_files.md +36 -0
- data/ext/puma_http11/extconf.rb +27 -17
- data/ext/puma_http11/http11_parser.c +1 -1
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +2 -2
- data/ext/puma_http11/http11_parser.rl +2 -2
- data/ext/puma_http11/http11_parser_common.rl +2 -2
- data/ext/puma_http11/mini_ssl.c +137 -19
- data/ext/puma_http11/org/jruby/puma/Http11.java +31 -10
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +157 -53
- data/ext/puma_http11/puma_http11.c +21 -10
- data/lib/puma/app/status.rb +4 -4
- data/lib/puma/binder.rb +60 -55
- data/lib/puma/cli.rb +22 -20
- data/lib/puma/client.rb +93 -30
- data/lib/puma/cluster/worker.rb +27 -17
- data/lib/puma/cluster/worker_handle.rb +8 -6
- data/lib/puma/cluster.rb +121 -47
- data/lib/puma/commonlogger.rb +21 -14
- data/lib/puma/configuration.rb +101 -65
- data/lib/puma/const.rb +141 -93
- data/lib/puma/control_cli.rb +19 -15
- data/lib/puma/detect.rb +7 -4
- data/lib/puma/dsl.rb +521 -88
- data/lib/puma/error_logger.rb +22 -13
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +39 -4
- data/lib/puma/jruby_restart.rb +0 -15
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +121 -181
- data/lib/puma/log_writer.rb +147 -0
- data/lib/puma/minissl/context_builder.rb +27 -12
- data/lib/puma/minissl.rb +105 -11
- data/lib/puma/null_io.rb +42 -2
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/rack/builder.rb +6 -6
- data/lib/puma/rack/urlmap.rb +1 -1
- data/lib/puma/rack_default.rb +19 -4
- data/lib/puma/reactor.rb +19 -10
- data/lib/puma/request.rb +368 -169
- data/lib/puma/runner.rb +65 -22
- data/lib/puma/sd_notify.rb +146 -0
- data/lib/puma/server.rb +161 -102
- data/lib/puma/single.rb +13 -11
- data/lib/puma/state_file.rb +3 -6
- data/lib/puma/thread_pool.rb +71 -21
- data/lib/puma/util.rb +1 -12
- data/lib/puma.rb +9 -10
- data/lib/rack/handler/puma.rb +116 -86
- data/tools/Dockerfile +2 -2
- metadata +17 -12
- data/lib/puma/queue_close.rb +0 -26
- data/lib/puma/systemd.rb +0 -46
- data/lib/rack/version_restriction.rb +0 -15
@@ -1,6 +1,7 @@
|
|
1
1
|
package org.jruby.puma;
|
2
2
|
|
3
3
|
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyArray;
|
4
5
|
import org.jruby.RubyClass;
|
5
6
|
import org.jruby.RubyModule;
|
6
7
|
import org.jruby.RubyObject;
|
@@ -15,6 +16,7 @@ import org.jruby.runtime.builtin.IRubyObject;
|
|
15
16
|
import org.jruby.util.ByteList;
|
16
17
|
|
17
18
|
import javax.net.ssl.KeyManagerFactory;
|
19
|
+
import javax.net.ssl.TrustManager;
|
18
20
|
import javax.net.ssl.TrustManagerFactory;
|
19
21
|
import javax.net.ssl.SSLContext;
|
20
22
|
import javax.net.ssl.SSLEngine;
|
@@ -22,6 +24,7 @@ import javax.net.ssl.SSLEngineResult;
|
|
22
24
|
import javax.net.ssl.SSLException;
|
23
25
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
24
26
|
import javax.net.ssl.SSLSession;
|
27
|
+
import javax.net.ssl.X509TrustManager;
|
25
28
|
import java.io.FileInputStream;
|
26
29
|
import java.io.InputStream;
|
27
30
|
import java.io.IOException;
|
@@ -32,15 +35,19 @@ import java.security.KeyStore;
|
|
32
35
|
import java.security.KeyStoreException;
|
33
36
|
import java.security.NoSuchAlgorithmException;
|
34
37
|
import java.security.UnrecoverableKeyException;
|
38
|
+
import java.security.cert.Certificate;
|
35
39
|
import java.security.cert.CertificateEncodingException;
|
36
40
|
import java.security.cert.CertificateException;
|
41
|
+
import java.security.cert.X509Certificate;
|
37
42
|
import java.util.concurrent.ConcurrentHashMap;
|
38
43
|
import java.util.Map;
|
44
|
+
import java.util.function.Supplier;
|
39
45
|
|
40
46
|
import static javax.net.ssl.SSLEngineResult.Status;
|
41
47
|
import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
42
48
|
|
43
|
-
public class MiniSSL extends RubyObject {
|
49
|
+
public class MiniSSL extends RubyObject { // MiniSSL::Engine
|
50
|
+
private static final long serialVersionUID = -6903439483039141234L;
|
44
51
|
private static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
45
52
|
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
46
53
|
return new MiniSSL(runtime, klass);
|
@@ -51,11 +58,10 @@ public class MiniSSL extends RubyObject {
|
|
51
58
|
RubyModule mPuma = runtime.defineModule("Puma");
|
52
59
|
RubyModule ssl = mPuma.defineModuleUnder("MiniSSL");
|
53
60
|
|
54
|
-
|
55
|
-
|
56
|
-
runtime.getClass("IOError").getAllocator());
|
61
|
+
// Puma::MiniSSL::SSLError
|
62
|
+
ssl.defineClassUnder("SSLError", runtime.getStandardError(), runtime.getStandardError().getAllocator());
|
57
63
|
|
58
|
-
RubyClass eng = ssl.defineClassUnder("Engine",runtime.getObject(),ALLOCATOR);
|
64
|
+
RubyClass eng = ssl.defineClassUnder("Engine", runtime.getObject(), ALLOCATOR);
|
59
65
|
eng.defineAnnotatedMethods(MiniSSL.class);
|
60
66
|
}
|
61
67
|
|
@@ -137,74 +143,116 @@ public class MiniSSL extends RubyObject {
|
|
137
143
|
private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
|
138
144
|
private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();
|
139
145
|
|
140
|
-
@JRubyMethod(meta = true)
|
146
|
+
@JRubyMethod(meta = true) // Engine.server
|
141
147
|
public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
142
148
|
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
143
149
|
// Create the KeyManagerFactory and TrustManagerFactory for this server
|
144
|
-
String keystoreFile = miniSSLContext.callMethod(context, "keystore")
|
145
|
-
char[]
|
150
|
+
String keystoreFile = asStringValue(miniSSLContext.callMethod(context, "keystore"), null);
|
151
|
+
char[] keystorePass = asStringValue(miniSSLContext.callMethod(context, "keystore_pass"), null).toCharArray();
|
152
|
+
String keystoreType = asStringValue(miniSSLContext.callMethod(context, "keystore_type"), KeyStore::getDefaultType);
|
153
|
+
|
154
|
+
String truststoreFile;
|
155
|
+
char[] truststorePass;
|
156
|
+
String truststoreType;
|
157
|
+
IRubyObject truststore = miniSSLContext.callMethod(context, "truststore");
|
158
|
+
if (truststore.isNil()) {
|
159
|
+
truststoreFile = keystoreFile;
|
160
|
+
truststorePass = keystorePass;
|
161
|
+
truststoreType = keystoreType;
|
162
|
+
} else if (!isDefaultSymbol(context, truststore)) {
|
163
|
+
truststoreFile = truststore.convertToString().asJavaString();
|
164
|
+
IRubyObject pass = miniSSLContext.callMethod(context, "truststore_pass");
|
165
|
+
if (pass.isNil()) {
|
166
|
+
truststorePass = null;
|
167
|
+
} else {
|
168
|
+
truststorePass = asStringValue(pass, null).toCharArray();
|
169
|
+
}
|
170
|
+
truststoreType = asStringValue(miniSSLContext.callMethod(context, "truststore_type"), KeyStore::getDefaultType);
|
171
|
+
} else { // self.truststore = :default
|
172
|
+
truststoreFile = null;
|
173
|
+
truststorePass = null;
|
174
|
+
truststoreType = null;
|
175
|
+
}
|
146
176
|
|
147
|
-
KeyStore ks = KeyStore.getInstance(
|
177
|
+
KeyStore ks = KeyStore.getInstance(keystoreType);
|
148
178
|
InputStream is = new FileInputStream(keystoreFile);
|
149
179
|
try {
|
150
|
-
ks.load(is,
|
180
|
+
ks.load(is, keystorePass);
|
151
181
|
} finally {
|
152
182
|
is.close();
|
153
183
|
}
|
154
184
|
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
155
|
-
kmf.init(ks,
|
185
|
+
kmf.init(ks, keystorePass);
|
156
186
|
keyManagerFactoryMap.put(keystoreFile, kmf);
|
157
187
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
188
|
+
if (truststoreFile != null) {
|
189
|
+
KeyStore ts = KeyStore.getInstance(truststoreType);
|
190
|
+
is = new FileInputStream(truststoreFile);
|
191
|
+
try {
|
192
|
+
ts.load(is, truststorePass);
|
193
|
+
} finally {
|
194
|
+
is.close();
|
195
|
+
}
|
196
|
+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
197
|
+
tmf.init(ts);
|
198
|
+
trustManagerFactoryMap.put(truststoreFile, tmf);
|
164
199
|
}
|
165
|
-
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
166
|
-
tmf.init(ts);
|
167
|
-
trustManagerFactoryMap.put(keystoreFile, tmf);
|
168
200
|
|
169
201
|
RubyClass klass = (RubyClass) recv;
|
170
|
-
return klass.newInstance(context,
|
171
|
-
|
172
|
-
|
202
|
+
return klass.newInstance(context, miniSSLContext, Block.NULL_BLOCK);
|
203
|
+
}
|
204
|
+
|
205
|
+
private static String asStringValue(IRubyObject value, Supplier<String> defaultValue) {
|
206
|
+
if (defaultValue != null && value.isNil()) return defaultValue.get();
|
207
|
+
return value.convertToString().asJavaString();
|
208
|
+
}
|
209
|
+
|
210
|
+
private static boolean isDefaultSymbol(ThreadContext context, IRubyObject truststore) {
|
211
|
+
return context.runtime.newSymbol("default").equals(truststore);
|
173
212
|
}
|
174
213
|
|
175
214
|
@JRubyMethod
|
176
|
-
public IRubyObject initialize(ThreadContext
|
215
|
+
public IRubyObject initialize(ThreadContext context, IRubyObject miniSSLContext)
|
177
216
|
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
178
217
|
|
179
|
-
String keystoreFile = miniSSLContext.callMethod(
|
218
|
+
String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
|
180
219
|
KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
|
181
|
-
|
182
|
-
|
183
|
-
|
220
|
+
IRubyObject truststore = miniSSLContext.callMethod(context, "truststore");
|
221
|
+
String truststoreFile = isDefaultSymbol(context, truststore) ? "" : asStringValue(truststore, () -> keystoreFile);
|
222
|
+
TrustManagerFactory tmf = trustManagerFactoryMap.get(truststoreFile); // null if self.truststore = :default
|
223
|
+
if (kmf == null) {
|
224
|
+
throw new KeyStoreException("Could not find KeyManagerFactory for keystore: " + keystoreFile + " truststore: " + truststoreFile);
|
184
225
|
}
|
185
226
|
|
186
227
|
SSLContext sslCtx = SSLContext.getInstance("TLS");
|
187
228
|
|
188
|
-
sslCtx.init(kmf.getKeyManagers(),
|
229
|
+
sslCtx.init(kmf.getKeyManagers(), getTrustManagers(tmf), null);
|
189
230
|
closed = false;
|
190
231
|
handshake = false;
|
191
232
|
engine = sslCtx.createSSLEngine();
|
192
233
|
|
193
|
-
String[]
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
234
|
+
String[] enabledProtocols;
|
235
|
+
IRubyObject protocols = miniSSLContext.callMethod(context, "protocols");
|
236
|
+
if (protocols.isNil()) {
|
237
|
+
if (miniSSLContext.callMethod(context, "no_tlsv1").isTrue()) {
|
238
|
+
enabledProtocols = new String[] { "TLSv1.1", "TLSv1.2", "TLSv1.3" };
|
239
|
+
} else {
|
240
|
+
enabledProtocols = new String[] { "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" };
|
241
|
+
}
|
199
242
|
|
200
|
-
|
201
|
-
|
243
|
+
if (miniSSLContext.callMethod(context, "no_tlsv1_1").isTrue()) {
|
244
|
+
enabledProtocols = new String[] { "TLSv1.2", "TLSv1.3" };
|
245
|
+
}
|
246
|
+
} else if (protocols instanceof RubyArray) {
|
247
|
+
enabledProtocols = (String[]) ((RubyArray) protocols).toArray(new String[0]);
|
248
|
+
} else {
|
249
|
+
throw context.runtime.newTypeError(protocols, context.runtime.getArray());
|
202
250
|
}
|
251
|
+
engine.setEnabledProtocols(enabledProtocols);
|
203
252
|
|
204
|
-
engine.setEnabledProtocols(protocols);
|
205
253
|
engine.setUseClientMode(false);
|
206
254
|
|
207
|
-
long verify_mode = miniSSLContext.callMethod(
|
255
|
+
long verify_mode = miniSSLContext.callMethod(context, "verify_mode").convertToInteger("to_i").getLongValue();
|
208
256
|
if ((verify_mode & 0x1) != 0) { // 'peer'
|
209
257
|
engine.setWantClientAuth(true);
|
210
258
|
}
|
@@ -212,10 +260,11 @@ public class MiniSSL extends RubyObject {
|
|
212
260
|
engine.setNeedClientAuth(true);
|
213
261
|
}
|
214
262
|
|
215
|
-
IRubyObject
|
216
|
-
if (
|
217
|
-
String[]
|
218
|
-
|
263
|
+
IRubyObject cipher_suites = miniSSLContext.callMethod(context, "cipher_suites");
|
264
|
+
if (cipher_suites instanceof RubyArray) {
|
265
|
+
engine.setEnabledCipherSuites((String[]) ((RubyArray) cipher_suites).toArray(new String[0]));
|
266
|
+
} else if (!cipher_suites.isNil()) {
|
267
|
+
throw context.runtime.newTypeError(cipher_suites, context.runtime.getArray());
|
219
268
|
}
|
220
269
|
|
221
270
|
SSLSession session = engine.getSession();
|
@@ -227,6 +276,48 @@ public class MiniSSL extends RubyObject {
|
|
227
276
|
return this;
|
228
277
|
}
|
229
278
|
|
279
|
+
private TrustManager[] getTrustManagers(TrustManagerFactory factory) {
|
280
|
+
if (factory == null) return null; // use JDK trust defaults
|
281
|
+
final TrustManager[] tms = factory.getTrustManagers();
|
282
|
+
if (tms != null) {
|
283
|
+
for (int i=0; i<tms.length; i++) {
|
284
|
+
final TrustManager tm = tms[i];
|
285
|
+
if (tm instanceof X509TrustManager) {
|
286
|
+
tms[i] = new TrustManagerWrapper((X509TrustManager) tm);
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
return tms;
|
291
|
+
}
|
292
|
+
|
293
|
+
private volatile transient X509Certificate lastCheckedCert0;
|
294
|
+
|
295
|
+
private class TrustManagerWrapper implements X509TrustManager {
|
296
|
+
|
297
|
+
private final X509TrustManager delegate;
|
298
|
+
|
299
|
+
TrustManagerWrapper(X509TrustManager delegate) {
|
300
|
+
this.delegate = delegate;
|
301
|
+
}
|
302
|
+
|
303
|
+
@Override
|
304
|
+
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
305
|
+
lastCheckedCert0 = chain.length > 0 ? chain[0] : null;
|
306
|
+
delegate.checkClientTrusted(chain, authType);
|
307
|
+
}
|
308
|
+
|
309
|
+
@Override
|
310
|
+
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
311
|
+
delegate.checkServerTrusted(chain, authType);
|
312
|
+
}
|
313
|
+
|
314
|
+
@Override
|
315
|
+
public X509Certificate[] getAcceptedIssuers() {
|
316
|
+
return delegate.getAcceptedIssuers();
|
317
|
+
}
|
318
|
+
|
319
|
+
}
|
320
|
+
|
230
321
|
@JRubyMethod
|
231
322
|
public IRubyObject inject(IRubyObject arg) {
|
232
323
|
ByteList bytes = arg.convertToString().getByteList();
|
@@ -251,7 +342,7 @@ public class MiniSSL extends RubyObject {
|
|
251
342
|
res = engine.unwrap(src.getRawBuffer(), dst.getRawBuffer());
|
252
343
|
break;
|
253
344
|
default:
|
254
|
-
throw new
|
345
|
+
throw new AssertionError("Unknown SSLOperation: " + sslOp);
|
255
346
|
}
|
256
347
|
|
257
348
|
switch (res.getStatus()) {
|
@@ -336,9 +427,7 @@ public class MiniSSL extends RubyObject {
|
|
336
427
|
|
337
428
|
return RubyString.newString(getRuntime(), appDataByteList);
|
338
429
|
} catch (SSLException e) {
|
339
|
-
|
340
|
-
re.initCause(e);
|
341
|
-
throw re;
|
430
|
+
throw newSSLError(getRuntime(), e);
|
342
431
|
}
|
343
432
|
}
|
344
433
|
|
@@ -371,19 +460,19 @@ public class MiniSSL extends RubyObject {
|
|
371
460
|
|
372
461
|
return RubyString.newString(context.runtime, dataByteList);
|
373
462
|
} catch (SSLException e) {
|
374
|
-
|
375
|
-
ex.initCause(e);
|
376
|
-
throw ex;
|
463
|
+
throw newSSLError(getRuntime(), e);
|
377
464
|
}
|
378
465
|
}
|
379
466
|
|
380
467
|
@JRubyMethod
|
381
|
-
public IRubyObject peercert() throws CertificateEncodingException {
|
468
|
+
public IRubyObject peercert(ThreadContext context) throws CertificateEncodingException {
|
469
|
+
Certificate peerCert;
|
382
470
|
try {
|
383
|
-
|
471
|
+
peerCert = engine.getSession().getPeerCertificates()[0];
|
384
472
|
} catch (SSLPeerUnverifiedException e) {
|
385
|
-
|
473
|
+
peerCert = lastCheckedCert0; // null if trust check did not happen
|
386
474
|
}
|
475
|
+
return peerCert == null ? context.nil : JavaEmbedUtils.javaToRuby(context.runtime, peerCert.getEncoded());
|
387
476
|
}
|
388
477
|
|
389
478
|
@JRubyMethod(name = "init?")
|
@@ -402,4 +491,19 @@ public class MiniSSL extends RubyObject {
|
|
402
491
|
return getRuntime().getFalse();
|
403
492
|
}
|
404
493
|
}
|
494
|
+
|
495
|
+
private static RubyClass getSSLError(Ruby runtime) {
|
496
|
+
return (RubyClass) ((RubyModule) runtime.getModule("Puma").getConstantAt("MiniSSL")).getConstantAt("SSLError");
|
497
|
+
}
|
498
|
+
|
499
|
+
private static RaiseException newSSLError(Ruby runtime, SSLException cause) {
|
500
|
+
return newError(runtime, getSSLError(runtime), cause.toString(), cause);
|
501
|
+
}
|
502
|
+
|
503
|
+
private static RaiseException newError(Ruby runtime, RubyClass errorClass, String message, Throwable cause) {
|
504
|
+
RaiseException ex = RaiseException.from(runtime, errorClass, message);
|
505
|
+
ex.initCause(cause);
|
506
|
+
return ex;
|
507
|
+
}
|
508
|
+
|
405
509
|
}
|
@@ -36,13 +36,13 @@ static VALUE global_request_method;
|
|
36
36
|
static VALUE global_request_uri;
|
37
37
|
static VALUE global_fragment;
|
38
38
|
static VALUE global_query_string;
|
39
|
-
static VALUE
|
39
|
+
static VALUE global_server_protocol;
|
40
40
|
static VALUE global_request_path;
|
41
41
|
|
42
42
|
/** Defines common length and error messages for input length validation. */
|
43
43
|
#define QUOTE(s) #s
|
44
|
-
#define
|
45
|
-
#define DEF_MAX_LENGTH(N,length) const size_t MAX_##N##_LENGTH = length; const char *MAX_##N##_LENGTH_ERR = "HTTP element " # N " is longer than the "
|
44
|
+
#define EXPAND_MAX_LENGTH_VALUE(s) QUOTE(s)
|
45
|
+
#define DEF_MAX_LENGTH(N,length) const size_t MAX_##N##_LENGTH = length; const char *MAX_##N##_LENGTH_ERR = "HTTP element " # N " is longer than the " EXPAND_MAX_LENGTH_VALUE(length) " allowed length (was %d)"
|
46
46
|
|
47
47
|
/** Validates the max length of given input and throws an HttpParserError exception if over. */
|
48
48
|
#define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR, len); }
|
@@ -52,15 +52,23 @@ static VALUE global_request_path;
|
|
52
52
|
|
53
53
|
|
54
54
|
/* Defines the maximum allowed lengths for various input elements.*/
|
55
|
+
#ifndef PUMA_REQUEST_URI_MAX_LENGTH
|
56
|
+
#define PUMA_REQUEST_URI_MAX_LENGTH (1024 * 12)
|
57
|
+
#endif
|
58
|
+
|
59
|
+
#ifndef PUMA_REQUEST_PATH_MAX_LENGTH
|
60
|
+
#define PUMA_REQUEST_PATH_MAX_LENGTH (8192)
|
61
|
+
#endif
|
62
|
+
|
55
63
|
#ifndef PUMA_QUERY_STRING_MAX_LENGTH
|
56
64
|
#define PUMA_QUERY_STRING_MAX_LENGTH (1024 * 10)
|
57
65
|
#endif
|
58
66
|
|
59
67
|
DEF_MAX_LENGTH(FIELD_NAME, 256);
|
60
68
|
DEF_MAX_LENGTH(FIELD_VALUE, 80 * 1024);
|
61
|
-
DEF_MAX_LENGTH(REQUEST_URI,
|
69
|
+
DEF_MAX_LENGTH(REQUEST_URI, PUMA_REQUEST_URI_MAX_LENGTH);
|
62
70
|
DEF_MAX_LENGTH(FRAGMENT, 1024); /* Don't know if this length is specified somewhere or not */
|
63
|
-
DEF_MAX_LENGTH(REQUEST_PATH,
|
71
|
+
DEF_MAX_LENGTH(REQUEST_PATH, PUMA_REQUEST_PATH_MAX_LENGTH);
|
64
72
|
DEF_MAX_LENGTH(QUERY_STRING, PUMA_QUERY_STRING_MAX_LENGTH);
|
65
73
|
DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
|
66
74
|
|
@@ -236,10 +244,10 @@ void query_string(puma_parser* hp, const char *at, size_t length)
|
|
236
244
|
rb_hash_aset(hp->request, global_query_string, val);
|
237
245
|
}
|
238
246
|
|
239
|
-
void
|
247
|
+
void server_protocol(puma_parser* hp, const char *at, size_t length)
|
240
248
|
{
|
241
249
|
VALUE val = rb_str_new(at, length);
|
242
|
-
rb_hash_aset(hp->request,
|
250
|
+
rb_hash_aset(hp->request, global_server_protocol, val);
|
243
251
|
}
|
244
252
|
|
245
253
|
/** Finalizes the request header to have a bunch of stuff that's
|
@@ -281,7 +289,7 @@ VALUE HttpParser_alloc(VALUE klass)
|
|
281
289
|
hp->fragment = fragment;
|
282
290
|
hp->request_path = request_path;
|
283
291
|
hp->query_string = query_string;
|
284
|
-
hp->
|
292
|
+
hp->server_protocol = server_protocol;
|
285
293
|
hp->header_done = header_done;
|
286
294
|
hp->request = Qnil;
|
287
295
|
|
@@ -453,6 +461,9 @@ void Init_mini_ssl(VALUE mod);
|
|
453
461
|
|
454
462
|
void Init_puma_http11(void)
|
455
463
|
{
|
464
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
465
|
+
rb_ext_ractor_safe(true);
|
466
|
+
#endif
|
456
467
|
|
457
468
|
VALUE mPuma = rb_define_module("Puma");
|
458
469
|
VALUE cHttpParser = rb_define_class_under(mPuma, "HttpParser", rb_cObject);
|
@@ -461,10 +472,10 @@ void Init_puma_http11(void)
|
|
461
472
|
DEF_GLOBAL(request_uri, "REQUEST_URI");
|
462
473
|
DEF_GLOBAL(fragment, "FRAGMENT");
|
463
474
|
DEF_GLOBAL(query_string, "QUERY_STRING");
|
464
|
-
DEF_GLOBAL(
|
475
|
+
DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
|
465
476
|
DEF_GLOBAL(request_path, "REQUEST_PATH");
|
466
477
|
|
467
|
-
eHttpParserError = rb_define_class_under(mPuma, "HttpParserError",
|
478
|
+
eHttpParserError = rb_define_class_under(mPuma, "HttpParserError", rb_eStandardError);
|
468
479
|
rb_global_variable(&eHttpParserError);
|
469
480
|
|
470
481
|
rb_define_alloc_func(cHttpParser, HttpParser_alloc);
|
data/lib/puma/app/status.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
require_relative '../json_serialization'
|
3
3
|
|
4
4
|
module Puma
|
5
5
|
module App
|
@@ -80,13 +80,13 @@ module Puma
|
|
80
80
|
|
81
81
|
def authenticate(env)
|
82
82
|
return true unless @auth_token
|
83
|
-
env['QUERY_STRING'].to_s.split(
|
83
|
+
env['QUERY_STRING'].to_s.split(/[&;]/).include? "token=#{@auth_token}"
|
84
84
|
end
|
85
85
|
|
86
86
|
def rack_response(status, body, content_type='application/json')
|
87
87
|
headers = {
|
88
|
-
'
|
89
|
-
'
|
88
|
+
'content-type' => content_type,
|
89
|
+
'content-length' => body.bytesize.to_s
|
90
90
|
}
|
91
91
|
|
92
92
|
[status, headers, [body]]
|