puma 3.12.6 → 5.3.2

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.

Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +1400 -451
  3. data/LICENSE +23 -20
  4. data/README.md +131 -60
  5. data/bin/puma-wild +3 -9
  6. data/docs/architecture.md +24 -19
  7. data/docs/compile_options.md +19 -0
  8. data/docs/deployment.md +38 -13
  9. data/docs/fork_worker.md +33 -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/jungle/README.md +9 -0
  14. data/{tools → docs}/jungle/rc.d/README.md +1 -1
  15. data/{tools → docs}/jungle/rc.d/puma +2 -2
  16. data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
  17. data/docs/kubernetes.md +66 -0
  18. data/docs/nginx.md +1 -1
  19. data/docs/plugins.md +20 -10
  20. data/docs/rails_dev_mode.md +29 -0
  21. data/docs/restart.md +47 -22
  22. data/docs/signals.md +7 -6
  23. data/docs/stats.md +142 -0
  24. data/docs/systemd.md +48 -70
  25. data/ext/puma_http11/PumaHttp11Service.java +2 -2
  26. data/ext/puma_http11/ext_help.h +1 -1
  27. data/ext/puma_http11/extconf.rb +27 -0
  28. data/ext/puma_http11/http11_parser.c +81 -108
  29. data/ext/puma_http11/http11_parser.h +1 -1
  30. data/ext/puma_http11/http11_parser.java.rl +22 -38
  31. data/ext/puma_http11/http11_parser.rl +1 -1
  32. data/ext/puma_http11/http11_parser_common.rl +3 -3
  33. data/ext/puma_http11/mini_ssl.c +254 -91
  34. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  35. data/ext/puma_http11/org/jruby/puma/Http11.java +108 -116
  36. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +89 -106
  37. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +92 -22
  38. data/ext/puma_http11/puma_http11.c +34 -50
  39. data/lib/puma.rb +54 -0
  40. data/lib/puma/app/status.rb +68 -49
  41. data/lib/puma/binder.rb +191 -139
  42. data/lib/puma/cli.rb +15 -15
  43. data/lib/puma/client.rb +247 -226
  44. data/lib/puma/cluster.rb +221 -212
  45. data/lib/puma/cluster/worker.rb +183 -0
  46. data/lib/puma/cluster/worker_handle.rb +90 -0
  47. data/lib/puma/commonlogger.rb +2 -2
  48. data/lib/puma/configuration.rb +58 -51
  49. data/lib/puma/const.rb +32 -20
  50. data/lib/puma/control_cli.rb +109 -67
  51. data/lib/puma/detect.rb +24 -3
  52. data/lib/puma/dsl.rb +519 -121
  53. data/lib/puma/error_logger.rb +104 -0
  54. data/lib/puma/events.rb +55 -31
  55. data/lib/puma/io_buffer.rb +7 -5
  56. data/lib/puma/jruby_restart.rb +0 -58
  57. data/lib/puma/json.rb +96 -0
  58. data/lib/puma/launcher.rb +178 -68
  59. data/lib/puma/minissl.rb +147 -48
  60. data/lib/puma/minissl/context_builder.rb +79 -0
  61. data/lib/puma/null_io.rb +13 -1
  62. data/lib/puma/plugin.rb +6 -12
  63. data/lib/puma/plugin/tmp_restart.rb +2 -0
  64. data/lib/puma/queue_close.rb +26 -0
  65. data/lib/puma/rack/builder.rb +2 -4
  66. data/lib/puma/rack/urlmap.rb +2 -0
  67. data/lib/puma/rack_default.rb +2 -0
  68. data/lib/puma/reactor.rb +85 -316
  69. data/lib/puma/request.rb +467 -0
  70. data/lib/puma/runner.rb +31 -52
  71. data/lib/puma/server.rb +275 -726
  72. data/lib/puma/single.rb +11 -67
  73. data/lib/puma/state_file.rb +8 -3
  74. data/lib/puma/systemd.rb +46 -0
  75. data/lib/puma/thread_pool.rb +129 -81
  76. data/lib/puma/util.rb +13 -6
  77. data/lib/rack/handler/puma.rb +5 -6
  78. data/tools/Dockerfile +16 -0
  79. data/tools/trickletest.rb +0 -1
  80. metadata +45 -28
  81. data/ext/puma_http11/io_buffer.c +0 -155
  82. data/lib/puma/accept_nonblock.rb +0 -23
  83. data/lib/puma/compat.rb +0 -14
  84. data/lib/puma/convenient.rb +0 -25
  85. data/lib/puma/daemon_ext.rb +0 -33
  86. data/lib/puma/delegation.rb +0 -13
  87. data/lib/puma/java_io_buffer.rb +0 -47
  88. data/lib/puma/rack/backports/uri/common_193.rb +0 -33
  89. data/lib/puma/tcp_logger.rb +0 -41
  90. data/tools/jungle/README.md +0 -19
  91. data/tools/jungle/init.d/README.md +0 -61
  92. data/tools/jungle/init.d/puma +0 -421
  93. data/tools/jungle/init.d/run-puma +0 -18
  94. data/tools/jungle/upstart/README.md +0 -61
  95. data/tools/jungle/upstart/puma-manager.conf +0 -31
  96. data/tools/jungle/upstart/puma.conf +0 -69
data/docs/signals.md CHANGED
@@ -1,8 +1,8 @@
1
- The [unix signal](http://en.wikipedia.org/wiki/Unix_signal) is a method of sending messages between [processes](http://en.wikipedia.org/wiki/Process_(computing)). When a signal is sent, the operating system interrupts the target process's normal flow of execution. There are standard signals that are used to stop a process but there are also custom signals that can be used for other purposes. This document is an attempt to list all supported signals that Puma will respond to. In general, signals need only be sent to the master process of a cluster.
1
+ The [unix signal](https://en.wikipedia.org/wiki/Unix_signal) is a method of sending messages between [processes](https://en.wikipedia.org/wiki/Process_(computing)). When a signal is sent, the operating system interrupts the target process's normal flow of execution. There are standard signals that are used to stop a process but there are also custom signals that can be used for other purposes. This document is an attempt to list all supported signals that Puma will respond to. In general, signals need only be sent to the master process of a cluster.
2
2
 
3
3
  ## Sending Signals
4
4
 
5
- If you are new to signals it can be useful to see how they can be used. When a process is created in a *nix like operating system it will have a [PID - or process identifier](http://en.wikipedia.org/wiki/Process_identifier) that can be used to send signals to the process. For demonstration we will create an infinitely running process by tailing a file:
5
+ If you are new to signals it can be useful to see how they can be used. When a process is created in a *nix like operating system it will have a [PID - or process identifier](https://en.wikipedia.org/wiki/Process_identifier) that can be used to send signals to the process. For demonstration we will create an infinitely running process by tailing a file:
6
6
 
7
7
  ```sh
8
8
  $ echo "foo" >> my.log
@@ -17,13 +17,13 @@ $ ps aux | grep tail
17
17
  schneems 87152 0.0 0.0 2432772 492 s032 S+ 12:46PM 0:00.00 tail -f my.log
18
18
  ```
19
19
 
20
- You can send a signal in Ruby using the [Process module](http://www.ruby-doc.org/core-2.1.1/Process.html#kill-method):
20
+ You can send a signal in Ruby using the [Process module](https://www.ruby-doc.org/core-2.1.1/Process.html#kill-method):
21
21
 
22
22
  ```
23
23
  $ irb
24
24
  > puts pid
25
25
  => 87152
26
- Process.detach(pid) # http://ruby-doc.org/core-2.1.1/Process.html#method-c-detach
26
+ Process.detach(pid) # https://ruby-doc.org/core-2.1.1/Process.html#method-c-detach
27
27
  Process.kill("TERM", pid)
28
28
  ```
29
29
 
@@ -38,9 +38,10 @@ Puma cluster responds to these signals:
38
38
  - `TERM` send `TERM` to worker. Worker will attempt to finish then exit.
39
39
  - `USR2` restart workers. This also reloads puma configuration file, if there is one.
40
40
  - `USR1` restart workers in phases, a rolling restart. This will not reload configuration file.
41
- - `HUP` reopen log files defined in stdout_redirect configuration parameter. If there is no stdout_redirect option provided it will behave like `INT`
42
- - `INT` equivalent of sending Ctrl-C to cluster. Will attempt to finish then exit.
41
+ - `HUP ` reopen log files defined in stdout_redirect configuration parameter. If there is no stdout_redirect option provided it will behave like `INT`
42
+ - `INT ` equivalent of sending Ctrl-C to cluster. Will attempt to finish then exit.
43
43
  - `CHLD`
44
+ - `URG ` refork workers in phases from worker 0, if `fork_workers` option is enabled.
44
45
 
45
46
  ## Callbacks order in case of different signals
46
47
 
data/docs/stats.md ADDED
@@ -0,0 +1,142 @@
1
+ ## accessing stats
2
+
3
+ Stats can be accessed in two ways:
4
+
5
+ ### control server
6
+
7
+ `$ pumactl stats` or `GET /stats`
8
+
9
+ [Read more about `pumactl` and the control server in the README.](https://github.com/puma/puma#controlstatus-server).
10
+
11
+ ### Puma.stats
12
+
13
+ `Puma.stats` produces a JSON string. `Puma.stats_hash` produces a ruby hash.
14
+
15
+ #### in single mode
16
+
17
+ Invoke `Puma.stats` anywhere in runtime, e.g. in a rails initializer:
18
+
19
+ ```ruby
20
+ # config/initializers/puma_stats.rb
21
+
22
+ Thread.new do
23
+ loop do
24
+ sleep 30
25
+ puts Puma.stats
26
+ end
27
+ end
28
+ ```
29
+
30
+ #### in cluster mode
31
+
32
+ Invoke `Puma.stats` from the master process
33
+
34
+ ```ruby
35
+ # config/puma.rb
36
+
37
+ before_fork do
38
+ Thread.new do
39
+ loop do
40
+ puts Puma.stats
41
+ sleep 30
42
+ end
43
+ end
44
+ end
45
+ ```
46
+
47
+
48
+ ## Explanation of stats
49
+
50
+ `Puma.stats` returns different information and a different structure depending on if Puma is in single vs cluster mode. There is one top-level attribute that is common to both modes:
51
+
52
+ * started_at: when puma was started
53
+
54
+ ### single mode and individual workers in cluster mode
55
+
56
+ When Puma is run in single mode, these stats are available at the top level. When Puma is run in cluster mode, these stats are available within the `worker_status` array in a hash labeled `last_status`, in an array of hashes, one hash for each worker.
57
+
58
+ * backlog: requests that are waiting for an available thread to be available. if this is above 0, you need more capacity [always true?]
59
+ * running: how many threads are running
60
+ * pool_capacity: the number of requests that the server is capable of taking right now. For example if the number is 5 then it means there are 5 threads sitting idle ready to take a request. If one request comes in, then the value would be 4 until it finishes processing. If the minimum threads allowed is zero, this number will still have a maximum value of the maximum threads allowed.
61
+ * max_threads: the maximum number of threads puma is configured to spool up per worker
62
+ * requests_count: the number of requests this worker has served since starting
63
+
64
+
65
+ ### cluster mode
66
+
67
+ * phase: which phase of restart the process is in, during [phased restart](https://github.com/puma/puma/blob/master/docs/restart.md)
68
+ * workers: ??
69
+ * booted_workers: how many workers currently running?
70
+ * old_workers: ??
71
+ * worker_status: array of hashes of info for each worker (see below)
72
+
73
+ ### worker status
74
+
75
+ * started_at: when the worker was started
76
+ * pid: the process id of the worker process
77
+ * index: each worker gets a number. if puma is configured to have 3 workers, then this will be 0, 1, or 2
78
+ * booted: if it's done booting [?]
79
+ * last_checkin: Last time the worker responded to the master process' heartbeat check.
80
+ * last_status: a hash of info about the worker's state handling requests. See the explanation for this in "single mode and individual workers in cluster mode" section above.
81
+
82
+
83
+ ## Examples
84
+
85
+ Here are two example stats hashes produced by `Puma.stats`:
86
+
87
+ ### single
88
+
89
+ ```json
90
+ {
91
+ "started_at": "2021-01-14T07:12:35Z",
92
+ "backlog": 0,
93
+ "running": 5,
94
+ "pool_capacity": 5,
95
+ "max_threads": 5,
96
+ "requests_count": 3
97
+ }
98
+ ```
99
+
100
+ ### cluster
101
+
102
+ ```json
103
+ {
104
+ "started_at": "2021-01-14T07:09:17Z",
105
+ "workers": 2,
106
+ "phase": 0,
107
+ "booted_workers": 2,
108
+ "old_workers": 0,
109
+ "worker_status": [
110
+ {
111
+ "started_at": "2021-01-14T07:09:24Z",
112
+ "pid": 64136,
113
+ "index": 0,
114
+ "phase": 0,
115
+ "booted": true,
116
+ "last_checkin": "2021-01-14T07:11:09Z",
117
+ "last_status": {
118
+ "backlog": 0,
119
+ "running": 5,
120
+ "pool_capacity": 5,
121
+ "max_threads": 5,
122
+ "requests_count": 2
123
+ }
124
+ },
125
+ {
126
+ "started_at": "2021-01-14T07:09:24Z",
127
+ "pid": 64137,
128
+ "index": 1,
129
+ "phase": 0,
130
+ "booted": true,
131
+ "last_checkin": "2021-01-14T07:11:09Z",
132
+ "last_status": {
133
+ "backlog": 0,
134
+ "running": 5,
135
+ "pool_capacity": 5,
136
+ "max_threads": 5,
137
+ "requests_count": 1
138
+ }
139
+ }
140
+ ]
141
+ }
142
+ ```
data/docs/systemd.md CHANGED
@@ -8,14 +8,12 @@ useful features for running Puma in production.
8
8
  ## Service Configuration
9
9
 
10
10
  Below is a sample puma.service configuration file for systemd, which
11
- can be copied or symlinked to /etc/systemd/system/puma.service, or if
11
+ can be copied or symlinked to `/etc/systemd/system/puma.service`, or if
12
12
  desired, using an application or instance specific name.
13
13
 
14
14
  Note that this uses the systemd preferred "simple" type where the
15
15
  start command remains running in the foreground (does not fork and
16
- exit). See also, the
17
- [Alternative Forking Configuration](#alternative-forking-configuration)
18
- below.
16
+ exit).
19
17
 
20
18
  ~~~~ ini
21
19
  [Unit]
@@ -26,27 +24,39 @@ After=network.target
26
24
  # Requires=puma.socket
27
25
 
28
26
  [Service]
29
- # Foreground process (do not use --daemon in ExecStart or config.rb)
30
- Type=simple
27
+ # Puma supports systemd's `Type=notify` and watchdog service
28
+ # monitoring, if the [sd_notify](https://github.com/agis/ruby-sdnotify) gem is installed,
29
+ # as of Puma 5.1 or later.
30
+ # On earlier versions of Puma or JRuby, change this to `Type=simple` and remove
31
+ # the `WatchdogSec` line.
32
+ Type=notify
33
+
34
+ # If your Puma process locks up, systemd's watchdog will restart it within seconds.
35
+ WatchdogSec=10
31
36
 
32
37
  # Preferably configure a non-privileged user
33
38
  # User=
34
39
 
35
- # The path to the puma application root
36
- # Also replace the "<WD>" place holders below with this path.
37
- WorkingDirectory=
40
+ # The path to the your application code root directory.
41
+ # Also replace the "<YOUR_APP_PATH>" place holders below with this path.
42
+ # Example /home/username/myapp
43
+ WorkingDirectory=<YOUR_APP_PATH>
38
44
 
39
45
  # Helpful for debugging socket activation, etc.
40
46
  # Environment=PUMA_DEBUG=1
41
47
 
42
- # The command to start Puma. This variant uses a binstub generated via
43
- # `bundle binstubs puma --path ./sbin` in the WorkingDirectory
44
- # (replace "<WD>" below)
45
- ExecStart=<WD>/sbin/puma -b tcp://0.0.0.0:9292 -b ssl://0.0.0.0:9293?key=key.pem&cert=cert.pem
48
+ # SystemD will not run puma even if it is in your path. You must specify
49
+ # an absolute URL to puma. For example /usr/local/bin/puma
50
+ # Alternatively, create a binstub with `bundle binstubs puma --path ./sbin` in the WorkingDirectory
51
+ ExecStart=/<FULLPATH>/bin/puma -C <YOUR_APP_PATH>/puma.rb
52
+
53
+ # Variant: Rails start.
54
+ # ExecStart=/<FULLPATH>/bin/puma -C <YOUR_APP_PATH>/config/puma.rb ../config.ru
46
55
 
47
- # Variant: Use config file with `bind` directives instead:
48
- # ExecStart=<WD>/sbin/puma -C config.rb
49
56
  # Variant: Use `bundle exec --keep-file-descriptors puma` instead of binstub
57
+ # Variant: Specify directives inline.
58
+ # ExecStart=/<FULLPATH>/puma -b tcp://0.0.0.0:9292 -b ssl://0.0.0.0:9293?key=key.pem&cert=cert.pem
59
+
50
60
 
51
61
  Restart=always
52
62
 
@@ -66,7 +76,14 @@ listening sockets open across puma restarts and achieves graceful
66
76
  restarts, including when upgraded puma, and is compatible with both
67
77
  clustered mode and application preload.
68
78
 
69
- **Note:** Socket activation doesn't currently work on jruby. This is
79
+ **Note:** Any wrapper scripts which `exec`, or other indirections in
80
+ `ExecStart`, may result in activated socket file descriptors being closed
81
+ before they reach the puma master process. For example, if using `bundle exec`,
82
+ pass the `--keep-file-descriptors` flag. `bundle exec` can be avoided by using a
83
+ `puma` executable generated by `bundle binstubs puma`. This is tracked in
84
+ [#1499].
85
+
86
+ **Note:** Socket activation doesn't currently work on JRuby. This is
70
87
  tracked in [#1367].
71
88
 
72
89
  To use socket activation, configure one or more `ListenStream` sockets
@@ -112,6 +129,21 @@ Puma will detect the release path socket as different than the one provided by
112
129
  systemd and attempt to bind it again, resulting in the exception
113
130
  `There is already a server bound to:`.
114
131
 
132
+ ### Binding
133
+
134
+ By default you need to configure puma to have binds matching with all
135
+ ListenStream statements. Any mismatched systemd ListenStreams will be closed by
136
+ puma.
137
+
138
+ To automatically bind to all activated sockets, the option
139
+ `--bind-to-activated-sockets` can be used. This matches the config DSL
140
+ `bind_to_activated_sockets` statement. This will cause puma to create a bind
141
+ automatically for any activated socket. When systemd socket activation is not
142
+ enabled, this option does nothing.
143
+
144
+ This also accepts an optional argument `only` (DSL: `'only'`) to discard any
145
+ binds that's not socket activated.
146
+
115
147
  ## Usage
116
148
 
117
149
  Without socket activation, use `systemctl` as root (e.g. via `sudo`) as
@@ -197,60 +229,6 @@ Apr 07 08:40:19 hx puma[28320]: * Activated ssl://0.0.0.0:9234?key=key.pem&cert=
197
229
  Apr 07 08:40:19 hx puma[28320]: Use Ctrl-C to stop
198
230
  ~~~~
199
231
 
200
- ## Alternative Forking Configuration
201
-
202
- Other systems/tools might expect or need puma to be run as a
203
- "traditional" forking server, for example so that the `pumactl`
204
- command can be used directly and outside of systemd for
205
- stop/start/restart. This use case is incompatible with systemd socket
206
- activation, so it should not be configured. Below is an alternative
207
- puma.service config sample, using `Type=forking` and the `--daemon`
208
- flag in `ExecStart`. Here systemd is playing a role more equivalent to
209
- SysV init.d, where it is responsible for starting Puma on boot
210
- (multi-user.target) and stopping it on shutdown, but is not performing
211
- continuous restarts. Therefore running Puma in cluster mode, where the
212
- master can restart workers, is highly recommended. See the systemd
213
- [Restart] directive for details.
214
-
215
- ~~~~ ini
216
- [Unit]
217
- Description=Puma HTTP Forking Server
218
- After=network.target
219
-
220
- [Service]
221
- # Background process configuration (use with --daemon in ExecStart)
222
- Type=forking
223
-
224
- # Preferably configure a non-privileged user
225
- # User=
226
-
227
- # The path to the puma application root
228
- # Also replace the "<WD>" place holders below with this path.
229
- WorkingDirectory=
230
-
231
- # The command to start Puma
232
- # (replace "<WD>" below)
233
- ExecStart=bundle exec puma -C <WD>/shared/puma.rb --daemon
234
-
235
- # The command to stop Puma
236
- # (replace "<WD>" below)
237
- ExecStop=bundle exec pumactl -S <WD>/shared/tmp/pids/puma.state stop
238
-
239
- # Path to PID file so that systemd knows which is the master process
240
- PIDFile=<WD>/shared/tmp/pids/puma.pid
241
-
242
- # Should systemd restart puma?
243
- # Use "no" (the default) to ensure no interference when using
244
- # stop/start/restart via `pumactl`. The "on-failure" setting might
245
- # work better for this purpose, but you must test it.
246
- # Use "always" if only `systemctl` is used for start/stop/restart, and
247
- # reconsider if you actually need the forking config.
248
- Restart=no
249
-
250
- [Install]
251
- WantedBy=multi-user.target
252
- ~~~~
253
-
254
232
  ### capistrano3-puma
255
233
 
256
234
  By default,
@@ -1,14 +1,14 @@
1
1
  package puma;
2
2
 
3
3
  import java.io.IOException;
4
-
4
+
5
5
  import org.jruby.Ruby;
6
6
  import org.jruby.runtime.load.BasicLibraryService;
7
7
 
8
8
  import org.jruby.puma.Http11;
9
9
  import org.jruby.puma.MiniSSL;
10
10
 
11
- public class PumaHttp11Service implements BasicLibraryService {
11
+ public class PumaHttp11Service implements BasicLibraryService {
12
12
  public boolean basicLoad(final Ruby runtime) throws IOException {
13
13
  Http11.createHttp11(runtime);
14
14
  MiniSSL.createMiniSSL(runtime);
@@ -2,7 +2,7 @@
2
2
  #define ext_help_h
3
3
 
4
4
  #define RAISE_NOT_NULL(T) if(T == NULL) rb_raise(rb_eArgError, "%s", "NULL found for " # T " when shouldn't be.");
5
- #define DATA_GET(from,type,name) Data_Get_Struct(from,type,name); RAISE_NOT_NULL(name);
5
+ #define DATA_GET(from,type,data_type,name) TypedData_Get_Struct(from,type,data_type,name); RAISE_NOT_NULL(name);
6
6
  #define REQUIRE_TYPE(V, T) if(TYPE(V) != T) rb_raise(rb_eTypeError, "%s", "Wrong argument type for " # V " required " # T);
7
7
  #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
8
8
 
@@ -2,6 +2,12 @@ require 'mkmf'
2
2
 
3
3
  dir_config("puma_http11")
4
4
 
5
+ if $mingw && RUBY_VERSION >= '2.4'
6
+ append_cflags '-fstack-protector-strong -D_FORTIFY_SOURCE=2'
7
+ append_ldflags '-fstack-protector-strong -l:libssp.a'
8
+ have_library 'ssp'
9
+ end
10
+
5
11
  unless ENV["DISABLE_SSL"]
6
12
  dir_config("openssl")
7
13
 
@@ -9,6 +15,27 @@ unless ENV["DISABLE_SSL"]
9
15
  %w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')}
10
16
 
11
17
  have_header "openssl/bio.h"
18
+
19
+ # below is yes for 1.0.2 & later
20
+ have_func "DTLS_method" , "openssl/ssl.h"
21
+
22
+ # below are yes for 1.1.0 & later
23
+ have_func "TLS_server_method" , "openssl/ssl.h"
24
+ have_func "SSL_CTX_set_min_proto_version(NULL, 0)", "openssl/ssl.h"
25
+
26
+ have_func "X509_STORE_up_ref"
27
+ have_func("SSL_CTX_set_ecdh_auto(NULL, 0)", "openssl/ssl.h")
28
+ end
29
+ end
30
+
31
+ if ENV["MAKE_WARNINGS_INTO_ERRORS"]
32
+ # Make all warnings into errors
33
+ # Except `implicit-fallthrough` since most failures comes from ragel state machine generated code
34
+ if respond_to? :append_cflags
35
+ append_cflags config_string 'WERRORFLAG'
36
+ append_cflags '-Wno-implicit-fallthrough'
37
+ else
38
+ $CFLAGS += ' ' << (config_string 'WERRORFLAG') << ' -Wno-implicit-fallthrough'
12
39
  end
13
40
  end
14
41
 
@@ -33,20 +33,18 @@ static void snake_upcase_char(char *c)
33
33
  /** Machine **/
34
34
 
35
35
 
36
- #line 79 "ext/puma_http11/http11_parser.rl"
36
+ #line 81 "ext/puma_http11/http11_parser.rl"
37
37
 
38
38
 
39
39
  /** Data **/
40
40
 
41
- #line 40 "ext/puma_http11/http11_parser.c"
41
+ #line 42 "ext/puma_http11/http11_parser.c"
42
42
  static const int puma_parser_start = 1;
43
- static const int puma_parser_first_final = 47;
43
+ static const int puma_parser_first_final = 46;
44
44
  static const int puma_parser_error = 0;
45
45
 
46
- static const int puma_parser_en_main = 1;
47
46
 
48
-
49
- #line 83 "ext/puma_http11/http11_parser.rl"
47
+ #line 85 "ext/puma_http11/http11_parser.rl"
50
48
 
51
49
  int puma_parser_init(puma_parser *parser) {
52
50
  int cs = 0;
@@ -56,7 +54,7 @@ int puma_parser_init(puma_parser *parser) {
56
54
  cs = puma_parser_start;
57
55
  }
58
56
 
59
- #line 87 "ext/puma_http11/http11_parser.rl"
57
+ #line 89 "ext/puma_http11/http11_parser.rl"
60
58
  parser->cs = cs;
61
59
  parser->body_start = 0;
62
60
  parser->content_len = 0;
@@ -109,7 +107,7 @@ st0:
109
107
  cs = 0;
110
108
  goto _out;
111
109
  tr0:
112
- #line 35 "ext/puma_http11/http11_parser.rl"
110
+ #line 37 "ext/puma_http11/http11_parser.rl"
113
111
  { MARK(mark, p); }
114
112
  goto st2;
115
113
  st2:
@@ -119,20 +117,20 @@ case 2:
119
117
  #line 118 "ext/puma_http11/http11_parser.c"
120
118
  switch( (*p) ) {
121
119
  case 32: goto tr2;
122
- case 36: goto st28;
123
- case 95: goto st28;
120
+ case 36: goto st27;
121
+ case 95: goto st27;
124
122
  }
125
123
  if ( (*p) < 48 ) {
126
124
  if ( 45 <= (*p) && (*p) <= 46 )
127
- goto st28;
125
+ goto st27;
128
126
  } else if ( (*p) > 57 ) {
129
127
  if ( 65 <= (*p) && (*p) <= 90 )
130
- goto st28;
128
+ goto st27;
131
129
  } else
132
- goto st28;
130
+ goto st27;
133
131
  goto st0;
134
132
  tr2:
135
- #line 48 "ext/puma_http11/http11_parser.rl"
133
+ #line 50 "ext/puma_http11/http11_parser.rl"
136
134
  {
137
135
  parser->request_method(parser, PTR_TO(mark), LEN(mark, p));
138
136
  }
@@ -158,7 +156,7 @@ case 3:
158
156
  goto tr5;
159
157
  goto st0;
160
158
  tr4:
161
- #line 35 "ext/puma_http11/http11_parser.rl"
159
+ #line 37 "ext/puma_http11/http11_parser.rl"
162
160
  { MARK(mark, p); }
163
161
  goto st4;
164
162
  st4:
@@ -172,53 +170,53 @@ case 4:
172
170
  }
173
171
  goto st0;
174
172
  tr8:
175
- #line 51 "ext/puma_http11/http11_parser.rl"
173
+ #line 53 "ext/puma_http11/http11_parser.rl"
176
174
  {
177
175
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
178
176
  }
179
177
  goto st5;
180
178
  tr31:
181
- #line 35 "ext/puma_http11/http11_parser.rl"
179
+ #line 37 "ext/puma_http11/http11_parser.rl"
182
180
  { MARK(mark, p); }
183
- #line 54 "ext/puma_http11/http11_parser.rl"
181
+ #line 56 "ext/puma_http11/http11_parser.rl"
184
182
  {
185
183
  parser->fragment(parser, PTR_TO(mark), LEN(mark, p));
186
184
  }
187
185
  goto st5;
188
186
  tr33:
189
- #line 54 "ext/puma_http11/http11_parser.rl"
187
+ #line 56 "ext/puma_http11/http11_parser.rl"
190
188
  {
191
189
  parser->fragment(parser, PTR_TO(mark), LEN(mark, p));
192
190
  }
193
191
  goto st5;
194
192
  tr37:
195
- #line 67 "ext/puma_http11/http11_parser.rl"
193
+ #line 69 "ext/puma_http11/http11_parser.rl"
196
194
  {
197
195
  parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
198
196
  }
199
- #line 51 "ext/puma_http11/http11_parser.rl"
197
+ #line 53 "ext/puma_http11/http11_parser.rl"
200
198
  {
201
199
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
202
200
  }
203
201
  goto st5;
204
- tr44:
205
- #line 58 "ext/puma_http11/http11_parser.rl"
202
+ tr41:
203
+ #line 60 "ext/puma_http11/http11_parser.rl"
206
204
  { MARK(query_start, p); }
207
- #line 59 "ext/puma_http11/http11_parser.rl"
205
+ #line 61 "ext/puma_http11/http11_parser.rl"
208
206
  {
209
207
  parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
210
208
  }
211
- #line 51 "ext/puma_http11/http11_parser.rl"
209
+ #line 53 "ext/puma_http11/http11_parser.rl"
212
210
  {
213
211
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
214
212
  }
215
213
  goto st5;
216
- tr47:
217
- #line 59 "ext/puma_http11/http11_parser.rl"
214
+ tr44:
215
+ #line 61 "ext/puma_http11/http11_parser.rl"
218
216
  {
219
217
  parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
220
218
  }
221
- #line 51 "ext/puma_http11/http11_parser.rl"
219
+ #line 53 "ext/puma_http11/http11_parser.rl"
222
220
  {
223
221
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
224
222
  }
@@ -232,7 +230,7 @@ case 5:
232
230
  goto tr10;
233
231
  goto st0;
234
232
  tr10:
235
- #line 35 "ext/puma_http11/http11_parser.rl"
233
+ #line 37 "ext/puma_http11/http11_parser.rl"
236
234
  { MARK(mark, p); }
237
235
  goto st6;
238
236
  st6:
@@ -297,21 +295,21 @@ case 13:
297
295
  goto st13;
298
296
  goto st0;
299
297
  tr18:
300
- #line 63 "ext/puma_http11/http11_parser.rl"
298
+ #line 65 "ext/puma_http11/http11_parser.rl"
301
299
  {
302
300
  parser->http_version(parser, PTR_TO(mark), LEN(mark, p));
303
301
  }
304
302
  goto st14;
305
303
  tr26:
306
- #line 44 "ext/puma_http11/http11_parser.rl"
304
+ #line 46 "ext/puma_http11/http11_parser.rl"
307
305
  { MARK(mark, p); }
308
- #line 45 "ext/puma_http11/http11_parser.rl"
306
+ #line 47 "ext/puma_http11/http11_parser.rl"
309
307
  {
310
308
  parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
311
309
  }
312
310
  goto st14;
313
311
  tr29:
314
- #line 45 "ext/puma_http11/http11_parser.rl"
312
+ #line 47 "ext/puma_http11/http11_parser.rl"
315
313
  {
316
314
  parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p));
317
315
  }
@@ -360,27 +358,27 @@ case 16:
360
358
  goto tr22;
361
359
  goto st0;
362
360
  tr22:
363
- #line 71 "ext/puma_http11/http11_parser.rl"
361
+ #line 73 "ext/puma_http11/http11_parser.rl"
364
362
  {
365
363
  parser->body_start = p - buffer + 1;
366
364
  parser->header_done(parser, p + 1, pe - p - 1);
367
- {p++; cs = 47; goto _out;}
365
+ {p++; cs = 46; goto _out;}
368
366
  }
369
- goto st47;
370
- st47:
367
+ goto st46;
368
+ st46:
371
369
  if ( ++p == pe )
372
- goto _test_eof47;
373
- case 47:
370
+ goto _test_eof46;
371
+ case 46:
374
372
  #line 373 "ext/puma_http11/http11_parser.c"
375
373
  goto st0;
376
374
  tr21:
377
- #line 38 "ext/puma_http11/http11_parser.rl"
375
+ #line 40 "ext/puma_http11/http11_parser.rl"
378
376
  { MARK(field_start, p); }
379
- #line 39 "ext/puma_http11/http11_parser.rl"
377
+ #line 41 "ext/puma_http11/http11_parser.rl"
380
378
  { snake_upcase_char((char *)p); }
381
379
  goto st17;
382
380
  tr23:
383
- #line 39 "ext/puma_http11/http11_parser.rl"
381
+ #line 41 "ext/puma_http11/http11_parser.rl"
384
382
  { snake_upcase_char((char *)p); }
385
383
  goto st17;
386
384
  st17:
@@ -413,13 +411,13 @@ case 17:
413
411
  goto tr23;
414
412
  goto st0;
415
413
  tr24:
416
- #line 40 "ext/puma_http11/http11_parser.rl"
414
+ #line 42 "ext/puma_http11/http11_parser.rl"
417
415
  {
418
416
  parser->field_len = LEN(field_start, p);
419
417
  }
420
418
  goto st18;
421
419
  tr27:
422
- #line 44 "ext/puma_http11/http11_parser.rl"
420
+ #line 46 "ext/puma_http11/http11_parser.rl"
423
421
  { MARK(mark, p); }
424
422
  goto st18;
425
423
  st18:
@@ -433,7 +431,7 @@ case 18:
433
431
  }
434
432
  goto tr25;
435
433
  tr25:
436
- #line 44 "ext/puma_http11/http11_parser.rl"
434
+ #line 46 "ext/puma_http11/http11_parser.rl"
437
435
  { MARK(mark, p); }
438
436
  goto st19;
439
437
  st19:
@@ -445,39 +443,39 @@ case 19:
445
443
  goto tr29;
446
444
  goto st19;
447
445
  tr9:
448
- #line 51 "ext/puma_http11/http11_parser.rl"
446
+ #line 53 "ext/puma_http11/http11_parser.rl"
449
447
  {
450
448
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
451
449
  }
452
450
  goto st20;
453
451
  tr38:
454
- #line 67 "ext/puma_http11/http11_parser.rl"
452
+ #line 69 "ext/puma_http11/http11_parser.rl"
455
453
  {
456
454
  parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
457
455
  }
458
- #line 51 "ext/puma_http11/http11_parser.rl"
456
+ #line 53 "ext/puma_http11/http11_parser.rl"
459
457
  {
460
458
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
461
459
  }
462
460
  goto st20;
463
- tr45:
464
- #line 58 "ext/puma_http11/http11_parser.rl"
461
+ tr42:
462
+ #line 60 "ext/puma_http11/http11_parser.rl"
465
463
  { MARK(query_start, p); }
466
- #line 59 "ext/puma_http11/http11_parser.rl"
464
+ #line 61 "ext/puma_http11/http11_parser.rl"
467
465
  {
468
466
  parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
469
467
  }
470
- #line 51 "ext/puma_http11/http11_parser.rl"
468
+ #line 53 "ext/puma_http11/http11_parser.rl"
471
469
  {
472
470
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
473
471
  }
474
472
  goto st20;
475
- tr48:
476
- #line 59 "ext/puma_http11/http11_parser.rl"
473
+ tr45:
474
+ #line 61 "ext/puma_http11/http11_parser.rl"
477
475
  {
478
476
  parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p));
479
477
  }
480
- #line 51 "ext/puma_http11/http11_parser.rl"
478
+ #line 53 "ext/puma_http11/http11_parser.rl"
481
479
  {
482
480
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, p));
483
481
  }
@@ -500,7 +498,7 @@ case 20:
500
498
  goto st0;
501
499
  goto tr30;
502
500
  tr30:
503
- #line 35 "ext/puma_http11/http11_parser.rl"
501
+ #line 37 "ext/puma_http11/http11_parser.rl"
504
502
  { MARK(mark, p); }
505
503
  goto st21;
506
504
  st21:
@@ -521,7 +519,7 @@ case 21:
521
519
  goto st0;
522
520
  goto st21;
523
521
  tr5:
524
- #line 35 "ext/puma_http11/http11_parser.rl"
522
+ #line 37 "ext/puma_http11/http11_parser.rl"
525
523
  { MARK(mark, p); }
526
524
  goto st22;
527
525
  st22:
@@ -546,7 +544,7 @@ case 22:
546
544
  goto st22;
547
545
  goto st0;
548
546
  tr7:
549
- #line 35 "ext/puma_http11/http11_parser.rl"
547
+ #line 37 "ext/puma_http11/http11_parser.rl"
550
548
  { MARK(mark, p); }
551
549
  goto st23;
552
550
  st23:
@@ -566,7 +564,7 @@ case 23:
566
564
  goto st0;
567
565
  goto st23;
568
566
  tr6:
569
- #line 35 "ext/puma_http11/http11_parser.rl"
567
+ #line 37 "ext/puma_http11/http11_parser.rl"
570
568
  { MARK(mark, p); }
571
569
  goto st24;
572
570
  st24:
@@ -578,17 +576,16 @@ case 24:
578
576
  case 32: goto tr37;
579
577
  case 34: goto st0;
580
578
  case 35: goto tr38;
581
- case 59: goto tr39;
582
579
  case 60: goto st0;
583
580
  case 62: goto st0;
584
- case 63: goto tr40;
581
+ case 63: goto tr39;
585
582
  case 127: goto st0;
586
583
  }
587
584
  if ( 0 <= (*p) && (*p) <= 31 )
588
585
  goto st0;
589
586
  goto st24;
590
587
  tr39:
591
- #line 67 "ext/puma_http11/http11_parser.rl"
588
+ #line 69 "ext/puma_http11/http11_parser.rl"
592
589
  {
593
590
  parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
594
591
  }
@@ -597,30 +594,27 @@ st25:
597
594
  if ( ++p == pe )
598
595
  goto _test_eof25;
599
596
  case 25:
600
- #line 599 "ext/puma_http11/http11_parser.c"
597
+ #line 598 "ext/puma_http11/http11_parser.c"
601
598
  switch( (*p) ) {
602
- case 32: goto tr8;
599
+ case 32: goto tr41;
603
600
  case 34: goto st0;
604
- case 35: goto tr9;
601
+ case 35: goto tr42;
605
602
  case 60: goto st0;
606
603
  case 62: goto st0;
607
- case 63: goto st26;
608
604
  case 127: goto st0;
609
605
  }
610
606
  if ( 0 <= (*p) && (*p) <= 31 )
611
607
  goto st0;
612
- goto st25;
608
+ goto tr40;
613
609
  tr40:
614
- #line 67 "ext/puma_http11/http11_parser.rl"
615
- {
616
- parser->request_path(parser, PTR_TO(mark), LEN(mark,p));
617
- }
610
+ #line 60 "ext/puma_http11/http11_parser.rl"
611
+ { MARK(query_start, p); }
618
612
  goto st26;
619
613
  st26:
620
614
  if ( ++p == pe )
621
615
  goto _test_eof26;
622
616
  case 26:
623
- #line 622 "ext/puma_http11/http11_parser.c"
617
+ #line 618 "ext/puma_http11/http11_parser.c"
624
618
  switch( (*p) ) {
625
619
  case 32: goto tr44;
626
620
  case 34: goto st0;
@@ -631,27 +625,25 @@ case 26:
631
625
  }
632
626
  if ( 0 <= (*p) && (*p) <= 31 )
633
627
  goto st0;
634
- goto tr43;
635
- tr43:
636
- #line 58 "ext/puma_http11/http11_parser.rl"
637
- { MARK(query_start, p); }
638
- goto st27;
628
+ goto st26;
639
629
  st27:
640
630
  if ( ++p == pe )
641
631
  goto _test_eof27;
642
632
  case 27:
643
- #line 642 "ext/puma_http11/http11_parser.c"
644
633
  switch( (*p) ) {
645
- case 32: goto tr47;
646
- case 34: goto st0;
647
- case 35: goto tr48;
648
- case 60: goto st0;
649
- case 62: goto st0;
650
- case 127: goto st0;
634
+ case 32: goto tr2;
635
+ case 36: goto st28;
636
+ case 95: goto st28;
651
637
  }
652
- if ( 0 <= (*p) && (*p) <= 31 )
653
- goto st0;
654
- goto st27;
638
+ if ( (*p) < 48 ) {
639
+ if ( 45 <= (*p) && (*p) <= 46 )
640
+ goto st28;
641
+ } else if ( (*p) > 57 ) {
642
+ if ( 65 <= (*p) && (*p) <= 90 )
643
+ goto st28;
644
+ } else
645
+ goto st28;
646
+ goto st0;
655
647
  st28:
656
648
  if ( ++p == pe )
657
649
  goto _test_eof28;
@@ -962,24 +954,6 @@ st45:
962
954
  if ( ++p == pe )
963
955
  goto _test_eof45;
964
956
  case 45:
965
- switch( (*p) ) {
966
- case 32: goto tr2;
967
- case 36: goto st46;
968
- case 95: goto st46;
969
- }
970
- if ( (*p) < 48 ) {
971
- if ( 45 <= (*p) && (*p) <= 46 )
972
- goto st46;
973
- } else if ( (*p) > 57 ) {
974
- if ( 65 <= (*p) && (*p) <= 90 )
975
- goto st46;
976
- } else
977
- goto st46;
978
- goto st0;
979
- st46:
980
- if ( ++p == pe )
981
- goto _test_eof46;
982
- case 46:
983
957
  if ( (*p) == 32 )
984
958
  goto tr2;
985
959
  goto st0;
@@ -999,7 +973,7 @@ case 46:
999
973
  _test_eof14: cs = 14; goto _test_eof;
1000
974
  _test_eof15: cs = 15; goto _test_eof;
1001
975
  _test_eof16: cs = 16; goto _test_eof;
1002
- _test_eof47: cs = 47; goto _test_eof;
976
+ _test_eof46: cs = 46; goto _test_eof;
1003
977
  _test_eof17: cs = 17; goto _test_eof;
1004
978
  _test_eof18: cs = 18; goto _test_eof;
1005
979
  _test_eof19: cs = 19; goto _test_eof;
@@ -1029,13 +1003,12 @@ case 46:
1029
1003
  _test_eof43: cs = 43; goto _test_eof;
1030
1004
  _test_eof44: cs = 44; goto _test_eof;
1031
1005
  _test_eof45: cs = 45; goto _test_eof;
1032
- _test_eof46: cs = 46; goto _test_eof;
1033
1006
 
1034
1007
  _test_eof: {}
1035
1008
  _out: {}
1036
1009
  }
1037
1010
 
1038
- #line 115 "ext/puma_http11/http11_parser.rl"
1011
+ #line 117 "ext/puma_http11/http11_parser.rl"
1039
1012
 
1040
1013
  if (!puma_parser_has_error(parser))
1041
1014
  parser->cs = cs;