puma 4.3.12 → 5.6.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +1526 -524
  3. data/LICENSE +23 -20
  4. data/README.md +120 -36
  5. data/bin/puma-wild +3 -9
  6. data/docs/architecture.md +63 -26
  7. data/docs/compile_options.md +21 -0
  8. data/docs/deployment.md +60 -69
  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 +15 -15
  20. data/docs/rails_dev_mode.md +28 -0
  21. data/docs/restart.md +46 -23
  22. data/docs/signals.md +13 -11
  23. data/docs/stats.md +142 -0
  24. data/docs/systemd.md +85 -128
  25. data/ext/puma_http11/PumaHttp11Service.java +2 -4
  26. data/ext/puma_http11/ext_help.h +1 -1
  27. data/ext/puma_http11/extconf.rb +44 -10
  28. data/ext/puma_http11/http11_parser.c +45 -47
  29. data/ext/puma_http11/http11_parser.h +1 -1
  30. data/ext/puma_http11/http11_parser.java.rl +1 -1
  31. data/ext/puma_http11/http11_parser.rl +1 -1
  32. data/ext/puma_http11/http11_parser_common.rl +0 -0
  33. data/ext/puma_http11/mini_ssl.c +225 -89
  34. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  35. data/ext/puma_http11/org/jruby/puma/Http11.java +5 -3
  36. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +3 -5
  37. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +109 -67
  38. data/ext/puma_http11/puma_http11.c +32 -51
  39. data/lib/puma/app/status.rb +50 -36
  40. data/lib/puma/binder.rb +225 -106
  41. data/lib/puma/cli.rb +24 -18
  42. data/lib/puma/client.rb +146 -84
  43. data/lib/puma/cluster/worker.rb +173 -0
  44. data/lib/puma/cluster/worker_handle.rb +94 -0
  45. data/lib/puma/cluster.rb +212 -220
  46. data/lib/puma/commonlogger.rb +2 -2
  47. data/lib/puma/configuration.rb +58 -49
  48. data/lib/puma/const.rb +22 -7
  49. data/lib/puma/control_cli.rb +99 -76
  50. data/lib/puma/detect.rb +29 -2
  51. data/lib/puma/dsl.rb +368 -96
  52. data/lib/puma/error_logger.rb +104 -0
  53. data/lib/puma/events.rb +55 -34
  54. data/lib/puma/io_buffer.rb +9 -2
  55. data/lib/puma/jruby_restart.rb +0 -58
  56. data/lib/puma/json_serialization.rb +96 -0
  57. data/lib/puma/launcher.rb +128 -46
  58. data/lib/puma/minissl/context_builder.rb +14 -9
  59. data/lib/puma/minissl.rb +137 -50
  60. data/lib/puma/null_io.rb +18 -1
  61. data/lib/puma/plugin/tmp_restart.rb +0 -0
  62. data/lib/puma/plugin.rb +3 -12
  63. data/lib/puma/queue_close.rb +26 -0
  64. data/lib/puma/rack/builder.rb +1 -5
  65. data/lib/puma/rack/urlmap.rb +0 -0
  66. data/lib/puma/rack_default.rb +0 -0
  67. data/lib/puma/reactor.rb +85 -369
  68. data/lib/puma/request.rb +489 -0
  69. data/lib/puma/runner.rb +46 -61
  70. data/lib/puma/server.rb +292 -763
  71. data/lib/puma/single.rb +9 -65
  72. data/lib/puma/state_file.rb +48 -8
  73. data/lib/puma/systemd.rb +46 -0
  74. data/lib/puma/thread_pool.rb +125 -57
  75. data/lib/puma/util.rb +32 -4
  76. data/lib/puma.rb +48 -0
  77. data/lib/rack/handler/puma.rb +2 -3
  78. data/lib/rack/version_restriction.rb +15 -0
  79. data/tools/{docker/Dockerfile → Dockerfile} +1 -1
  80. data/tools/trickletest.rb +0 -0
  81. metadata +29 -24
  82. data/docs/tcp_mode.md +0 -96
  83. data/ext/puma_http11/io_buffer.c +0 -155
  84. data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
  85. data/lib/puma/accept_nonblock.rb +0 -29
  86. data/lib/puma/tcp_logger.rb +0 -41
  87. data/tools/jungle/README.md +0 -19
  88. data/tools/jungle/init.d/README.md +0 -61
  89. data/tools/jungle/init.d/puma +0 -421
  90. data/tools/jungle/init.d/run-puma +0 -18
  91. data/tools/jungle/upstart/README.md +0 -61
  92. data/tools/jungle/upstart/puma-manager.conf +0 -31
  93. data/tools/jungle/upstart/puma.conf +0 -69
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 runs in single mode, these stats are available at the top level. When Puma runs in cluster mode, these stats are available within the `worker_status` array in a hash labeled `last_status`, in an array of hashes where one hash represents 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 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 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
@@ -1,21 +1,18 @@
1
1
  # systemd
2
2
 
3
- [systemd](https://www.freedesktop.org/wiki/Software/systemd/) is a
4
- commonly available init system (PID 1) on many Linux distributions. It
5
- offers process monitoring (including automatic restarts) and other
6
- useful features for running Puma in production.
3
+ [systemd](https://www.freedesktop.org/wiki/Software/systemd/) is a commonly
4
+ available init system (PID 1) on many Linux distributions. It offers process
5
+ monitoring (including automatic restarts) and other useful features for running
6
+ Puma in production.
7
7
 
8
8
  ## Service Configuration
9
9
 
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
12
- desired, using an application or instance specific name.
10
+ Below is a sample puma.service configuration file for systemd, which can be
11
+ copied or symlinked to `/etc/systemd/system/puma.service`, or if desired, using
12
+ an application or instance-specific name.
13
13
 
14
- Note that this uses the systemd preferred "simple" type where the
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.
14
+ Note that this uses the systemd preferred "simple" type where the start command
15
+ remains running in the foreground (does not fork and exit).
19
16
 
20
17
  ~~~~ ini
21
18
  [Unit]
@@ -26,14 +23,21 @@ After=network.target
26
23
  # Requires=puma.socket
27
24
 
28
25
  [Service]
29
- # Foreground process (do not use --daemon in ExecStart or config.rb)
30
- Type=simple
26
+ # Puma supports systemd's `Type=notify` and watchdog service
27
+ # monitoring, if the [sd_notify](https://github.com/agis/ruby-sdnotify) gem is installed,
28
+ # as of Puma 5.1 or later.
29
+ # On earlier versions of Puma or JRuby, change this to `Type=simple` and remove
30
+ # the `WatchdogSec` line.
31
+ Type=notify
32
+
33
+ # If your Puma process locks up, systemd's watchdog will restart it within seconds.
34
+ WatchdogSec=10
31
35
 
32
36
  # Preferably configure a non-privileged user
33
37
  # User=
34
38
 
35
- # The path to the your application code root directory.
36
- # Also replace the "<YOUR_APP_PATH>" place holders below with this path.
39
+ # The path to your application code root directory.
40
+ # Also replace the "<YOUR_APP_PATH>" placeholders below with this path.
37
41
  # Example /home/username/myapp
38
42
  WorkingDirectory=<YOUR_APP_PATH>
39
43
 
@@ -59,33 +63,31 @@ Restart=always
59
63
  WantedBy=multi-user.target
60
64
  ~~~~
61
65
 
62
- See [systemd.exec](https://www.freedesktop.org/software/systemd/man/systemd.exec.html)
66
+ See
67
+ [systemd.exec](https://www.freedesktop.org/software/systemd/man/systemd.exec.html)
63
68
  for additional details.
64
69
 
65
70
  ## Socket Activation
66
71
 
67
- systemd and puma also support socket activation, where systemd opens
68
- the listening socket(s) in advance and provides them to the puma
69
- master process on startup. Among other advantages, this keeps
70
- listening sockets open across puma restarts and achieves graceful
71
- restarts, including when upgraded puma, and is compatible with both
72
- clustered mode and application preload.
73
-
74
- **Note:** Any wrapper scripts which `exec`, or other indirections in
75
- `ExecStart`, may result in activated socket file descriptors being closed
76
- before they reach the puma master process. For example, if using `bundle exec`,
77
- pass the `--keep-file-descriptors` flag. `bundle exec` can be avoided by using a
78
- `puma` executable generated by `bundle binstubs puma`. This is tracked in
79
- [#1499].
80
-
81
- **Note:** Socket activation doesn't currently work on jruby. This is
82
- tracked in [#1367].
83
-
84
- To use socket activation, configure one or more `ListenStream` sockets
85
- in a companion `*.socket` unit file. Also uncomment the associated
86
- `Requires` directive for the socket unit in the service file (see
87
- above.) Here is a sample puma.socket, matching the ports used in the
88
- above puma.service:
72
+ systemd and Puma also support socket activation, where systemd opens the
73
+ listening socket(s) in advance and provides them to the Puma master process on
74
+ startup. Among other advantages, this keeps listening sockets open across puma
75
+ restarts and achieves graceful restarts, including when upgraded Puma, and is
76
+ compatible with both clustered mode and application preload.
77
+
78
+ **Note:** Any wrapper scripts which `exec`, or other indirections in `ExecStart`
79
+ may result in activated socket file descriptors being closed before reaching the
80
+ puma master process. For example, if using `bundle exec`, pass the
81
+ `--keep-file-descriptors` flag. `bundle exec` can be avoided by using a `puma`
82
+ executable generated by `bundle binstubs puma`. This is tracked in [#1499].
83
+
84
+ **Note:** Socket activation doesn't currently work on JRuby. This is tracked in
85
+ [#1367].
86
+
87
+ Configure one or more `ListenStream` sockets in a companion `*.socket` unit file
88
+ to use socket activation. Also, uncomment the associated `Requires` directive
89
+ for the socket unit in the service file (see above.) Here is a sample
90
+ puma.socket, matching the ports used in the above puma.service:
89
91
 
90
92
  ~~~~ ini
91
93
  [Unit]
@@ -108,26 +110,42 @@ Backlog=1024
108
110
  WantedBy=sockets.target
109
111
  ~~~~
110
112
 
111
- See [systemd.socket](https://www.freedesktop.org/software/systemd/man/systemd.socket.html)
113
+ See
114
+ [systemd.socket](https://www.freedesktop.org/software/systemd/man/systemd.socket.html)
112
115
  for additional configuration details.
113
116
 
114
- Note that the above configurations will work with Puma in either
115
- single process or cluster mode.
117
+ Note that the above configurations will work with Puma in either single process
118
+ or cluster mode.
116
119
 
117
120
  ### Sockets and symlinks
118
121
 
119
- When using releases folders, you should set the socket path using the
120
- shared folder path (ex. `/srv/projet/shared/tmp/puma.sock`), not the
121
- release folder path (`/srv/projet/releases/1234/tmp/puma.sock`).
122
+ When using releases folders, you should set the socket path using the shared
123
+ folder path (ex. `/srv/projet/shared/tmp/puma.sock`), not the release folder
124
+ path (`/srv/projet/releases/1234/tmp/puma.sock`).
122
125
 
123
126
  Puma will detect the release path socket as different than the one provided by
124
- systemd and attempt to bind it again, resulting in the exception
125
- `There is already a server bound to:`.
127
+ systemd and attempt to bind it again, resulting in the exception `There is
128
+ already a server bound to:`.
129
+
130
+ ### Binding
131
+
132
+ By default, you need to configure Puma to have binds matching with all
133
+ ListenStream statements. Any mismatched systemd ListenStreams will be closed by
134
+ Puma.
135
+
136
+ To automatically bind to all activated sockets, the option
137
+ `--bind-to-activated-sockets` can be used. This matches the config DSL
138
+ `bind_to_activated_sockets` statement. This will cause Puma to create a bind
139
+ automatically for any activated socket. When systemd socket activation is not
140
+ enabled, this option does nothing.
141
+
142
+ This also accepts an optional argument `only` (DSL: `'only'`) to discard any
143
+ binds that's not socket activated.
126
144
 
127
145
  ## Usage
128
146
 
129
- Without socket activation, use `systemctl` as root (e.g. via `sudo`) as
130
- with other system services:
147
+ Without socket activation, use `systemctl` as root (i.e., via `sudo`) as with
148
+ other system services:
131
149
 
132
150
  ~~~~ sh
133
151
  # After installing or making changes to puma.service
@@ -136,35 +154,35 @@ systemctl daemon-reload
136
154
  # Enable so it starts on boot
137
155
  systemctl enable puma.service
138
156
 
139
- # Initial start up.
157
+ # Initial startup.
140
158
  systemctl start puma.service
141
159
 
142
160
  # Check status
143
161
  systemctl status puma.service
144
162
 
145
- # A normal restart. Warning: listeners sockets will be closed
163
+ # A normal restart. Warning: listener's sockets will be closed
146
164
  # while a new puma process initializes.
147
165
  systemctl restart puma.service
148
166
  ~~~~
149
167
 
150
- With socket activation, several but not all of these commands should
151
- be run for both socket and service:
168
+ With socket activation, several but not all of these commands should be run for
169
+ both socket and service:
152
170
 
153
171
  ~~~~ sh
154
172
  # After installing or making changes to either puma.socket or
155
173
  # puma.service.
156
174
  systemctl daemon-reload
157
175
 
158
- # Enable both socket and service so they start on boot. Alternatively
159
- # you could leave puma.service disabled and systemd will start it on
160
- # first use (with startup lag on first request)
176
+ # Enable both socket and service, so they start on boot. Alternatively
177
+ # you could leave puma.service disabled, and systemd will start it on
178
+ # the first use (with startup lag on the first request)
161
179
  systemctl enable puma.socket puma.service
162
180
 
163
- # Initial start up. The Requires directive (see above) ensures the
181
+ # Initial startup. The Requires directive (see above) ensures the
164
182
  # socket is started before the service.
165
183
  systemctl start puma.socket puma.service
166
184
 
167
- # Check status of both socket and service.
185
+ # Check the status of both socket and service.
168
186
  systemctl status puma.socket puma.service
169
187
 
170
188
  # A "hot" restart, with systemd keeping puma.socket listening and
@@ -177,8 +195,8 @@ systemctl restart puma.service
177
195
  systemctl restart puma.socket puma.service
178
196
  ~~~~
179
197
 
180
- Here is sample output from `systemctl status` with both service and
181
- socket running:
198
+ Here is sample output from `systemctl status` with both service and socket
199
+ running:
182
200
 
183
201
  ~~~~
184
202
  ● puma.socket - Puma HTTP Server Accept Sockets
@@ -209,76 +227,14 @@ Apr 07 08:40:19 hx puma[28320]: * Activated ssl://0.0.0.0:9234?key=key.pem&cert=
209
227
  Apr 07 08:40:19 hx puma[28320]: Use Ctrl-C to stop
210
228
  ~~~~
211
229
 
212
- ## Alternative Forking Configuration
213
-
214
- Other systems/tools might expect or need puma to be run as a
215
- "traditional" forking server, for example so that the `pumactl`
216
- command can be used directly and outside of systemd for
217
- stop/start/restart. This use case is incompatible with systemd socket
218
- activation, so it should not be configured. Below is an alternative
219
- puma.service config sample, using `Type=forking` and the `--daemon`
220
- flag in `ExecStart`. Here systemd is playing a role more equivalent to
221
- SysV init.d, where it is responsible for starting Puma on boot
222
- (multi-user.target) and stopping it on shutdown, but is not performing
223
- continuous restarts. Therefore running Puma in cluster mode, where the
224
- master can restart workers, is highly recommended. See the systemd
225
- [Restart] directive for details.
226
-
227
- ~~~~ ini
228
- [Unit]
229
- Description=Puma HTTP Forking Server
230
- After=network.target
231
-
232
- [Service]
233
- # Background process configuration (use with --daemon in ExecStart)
234
- Type=forking
235
-
236
- # Preferably configure a non-privileged user
237
- # User=
238
-
239
- # The path to the puma application root
240
- # Also replace the "<WD>" place holders below with this path.
241
- WorkingDirectory=
242
-
243
- # The command to start Puma
244
- # (replace "<WD>" below)
245
- ExecStart=bundle exec puma -C <WD>/shared/puma.rb --daemon
246
-
247
- # The command to stop Puma
248
- # (replace "<WD>" below)
249
- ExecStop=bundle exec pumactl -S <WD>/shared/tmp/pids/puma.state stop
250
-
251
- # Path to PID file so that systemd knows which is the master process
252
- PIDFile=<WD>/shared/tmp/pids/puma.pid
253
-
254
- # Should systemd restart puma?
255
- # Use "no" (the default) to ensure no interference when using
256
- # stop/start/restart via `pumactl`. The "on-failure" setting might
257
- # work better for this purpose, but you must test it.
258
- # Use "always" if only `systemctl` is used for start/stop/restart, and
259
- # reconsider if you actually need the forking config.
260
- Restart=no
261
-
262
- # `puma_ctl restart` wouldn't work without this. It's because `pumactl`
263
- # changes PID on restart and systemd stops the service afterwards
264
- # because of the PID change. This option prevents stopping after PID
265
- # change.
266
- RemainAfterExit=yes
267
-
268
- [Install]
269
- WantedBy=multi-user.target
270
- ~~~~
271
-
272
230
  ### capistrano3-puma
273
231
 
274
- By default,
275
- [capistrano3-puma](https://github.com/seuros/capistrano-puma) uses
276
- `pumactl` for deployment restarts, outside of systemd. To learn the
277
- exact commands that this tool would use for `ExecStart` and
278
- `ExecStop`, use the following `cap` commands in dry-run mode, and
279
- update from the above forking service configuration accordingly. Note
280
- also that the configured `User` should likely be the same as the
281
- capistrano3-puma `:puma_user` option.
232
+ By default, [capistrano3-puma](https://github.com/seuros/capistrano-puma) uses
233
+ `pumactl` for deployment restarts outside of systemd. To learn the exact
234
+ commands that this tool would use for `ExecStart` and `ExecStop`, use the
235
+ following `cap` commands in dry-run mode, and update from the above forking
236
+ service configuration accordingly. Note also that the configured `User` should
237
+ likely be the same as the capistrano3-puma `:puma_user` option.
282
238
 
283
239
  ~~~~ sh
284
240
  stage=production # or different stage, as needed
@@ -288,3 +244,4 @@ cap $stage puma:stop --dry-run
288
244
 
289
245
  [Restart]: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=
290
246
  [#1367]: https://github.com/puma/puma/issues/1367
247
+ [#1499]: https://github.com/puma/puma/issues/1499
@@ -1,18 +1,16 @@
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
- import org.jruby.puma.IOBuffer;
10
9
  import org.jruby.puma.MiniSSL;
11
10
 
12
- public class PumaHttp11Service implements BasicLibraryService {
11
+ public class PumaHttp11Service implements BasicLibraryService {
13
12
  public boolean basicLoad(final Ruby runtime) throws IOException {
14
13
  Http11.createHttp11(runtime);
15
- IOBuffer.createIOBuffer(runtime);
16
14
  MiniSSL.createMiniSSL(runtime);
17
15
  return true;
18
16
  }
@@ -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
 
@@ -1,31 +1,51 @@
1
1
  require 'mkmf'
2
2
 
3
3
  dir_config("puma_http11")
4
+
4
5
  if $mingw && RUBY_VERSION >= '2.4'
5
- append_cflags '-D_FORTIFY_SOURCE=2'
6
- append_ldflags '-fstack-protector'
6
+ append_cflags '-fstack-protector-strong -D_FORTIFY_SOURCE=2'
7
+ append_ldflags '-fstack-protector-strong -l:libssp.a'
7
8
  have_library 'ssp'
8
9
  end
9
10
 
10
11
  unless ENV["DISABLE_SSL"]
11
- dir_config("openssl")
12
+ # don't use pkg_config('openssl') if '--with-openssl-dir' is used
13
+ has_openssl_dir = dir_config('openssl').any?
14
+ found_pkg_config = !has_openssl_dir && pkg_config('openssl')
12
15
 
13
- if %w'crypto libeay32'.find {|crypto| have_library(crypto, 'BIO_read')} and
16
+ found_ssl = if (!$mingw || RUBY_VERSION >= '2.4') && found_pkg_config
17
+ puts 'using OpenSSL pkgconfig (openssl.pc)'
18
+ true
19
+ elsif %w'crypto libeay32'.find {|crypto| have_library(crypto, 'BIO_read')} &&
14
20
  %w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')}
21
+ true
22
+ else
23
+ puts '** Puma will be compiled without SSL support'
24
+ false
25
+ end
15
26
 
27
+ if found_ssl
16
28
  have_header "openssl/bio.h"
17
29
 
18
30
  # below is yes for 1.0.2 & later
19
- have_func "DTLS_method" , "openssl/ssl.h"
31
+ have_func "DTLS_method" , "openssl/ssl.h"
32
+
33
+ # below are yes for 1.1.0 & later
34
+ have_func "TLS_server_method" , "openssl/ssl.h"
35
+ have_func "SSL_CTX_set_min_proto_version(NULL, 0)", "openssl/ssl.h"
36
+
37
+ have_func "X509_STORE_up_ref"
38
+ have_func "SSL_CTX_set_ecdh_auto(NULL, 0)" , "openssl/ssl.h"
20
39
 
21
- # below are yes for 1.1.0 & later, may need to check func rather than macro
22
- # with versions after 1.1.1
23
- have_func "TLS_server_method" , "openssl/ssl.h"
24
- have_macro "SSL_CTX_set_min_proto_version", "openssl/ssl.h"
40
+ # below exists in 1.1.0 and later, but isn't documented until 3.0.0
41
+ have_func "SSL_CTX_set_dh_auto(NULL, 0)" , "openssl/ssl.h"
42
+
43
+ # below is yes for 3.0.0 & later
44
+ have_func "SSL_get1_peer_certificate" , "openssl/ssl.h"
25
45
 
26
46
  # Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
27
47
  if Random.respond_to?(:bytes)
28
- $defs.push("-DHAVE_RANDOM_BYTES")
48
+ $defs.push "-DHAVE_RANDOM_BYTES"
29
49
  puts "checking for Random.bytes... yes"
30
50
  else
31
51
  puts "checking for Random.bytes... no"
@@ -33,4 +53,18 @@ unless ENV["DISABLE_SSL"]
33
53
  end
34
54
  end
35
55
 
56
+ if ENV["MAKE_WARNINGS_INTO_ERRORS"]
57
+ # Make all warnings into errors
58
+ # Except `implicit-fallthrough` since most failures comes from ragel state machine generated code
59
+ if respond_to?(:append_cflags, true) # Ruby 2.5 and later
60
+ append_cflags(config_string('WERRORFLAG') || '-Werror')
61
+ append_cflags '-Wno-implicit-fallthrough'
62
+ else
63
+ # flag may not exist on some platforms, -Werror may not be defined on some platforms, but
64
+ # works with all in current CI
65
+ $CFLAGS << " #{config_string('WERRORFLAG') || '-Werror'}"
66
+ $CFLAGS << ' -Wno-implicit-fallthrough'
67
+ end
68
+ end
69
+
36
70
  create_makefile("puma/puma_http11")