puma 2.2.0 → 8.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +3334 -0
  3. data/LICENSE +23 -20
  4. data/README.md +387 -100
  5. data/bin/puma-wild +25 -0
  6. data/bin/pumactl +1 -1
  7. data/docs/5.0-Upgrade.md +98 -0
  8. data/docs/6.0-Upgrade.md +56 -0
  9. data/docs/7.0-Upgrade.md +52 -0
  10. data/docs/8.0-Upgrade.md +100 -0
  11. data/docs/architecture.md +74 -0
  12. data/docs/compile_options.md +55 -0
  13. data/docs/deployment.md +137 -0
  14. data/docs/fork_worker.md +41 -0
  15. data/docs/grpc.md +62 -0
  16. data/docs/images/favicon.svg +1 -0
  17. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  18. data/docs/images/puma-connection-flow.png +0 -0
  19. data/docs/images/puma-general-arch.png +0 -0
  20. data/docs/images/running-puma.svg +1 -0
  21. data/docs/images/standard-logo.svg +1 -0
  22. data/docs/java_options.md +54 -0
  23. data/docs/jungle/README.md +9 -0
  24. data/docs/jungle/rc.d/README.md +74 -0
  25. data/docs/jungle/rc.d/puma +61 -0
  26. data/docs/jungle/rc.d/puma.conf +10 -0
  27. data/docs/kubernetes.md +73 -0
  28. data/docs/nginx.md +5 -5
  29. data/docs/plugins.md +42 -0
  30. data/docs/rails_dev_mode.md +28 -0
  31. data/docs/restart.md +65 -0
  32. data/docs/signals.md +98 -0
  33. data/docs/stats.md +148 -0
  34. data/docs/systemd.md +253 -0
  35. data/docs/testing_benchmarks_local_files.md +150 -0
  36. data/docs/testing_test_rackup_ci_files.md +36 -0
  37. data/ext/puma_http11/PumaHttp11Service.java +2 -2
  38. data/ext/puma_http11/extconf.rb +59 -2
  39. data/ext/puma_http11/http11_parser.c +319 -487
  40. data/ext/puma_http11/http11_parser.h +15 -13
  41. data/ext/puma_http11/http11_parser.java.rl +64 -94
  42. data/ext/puma_http11/http11_parser.rl +27 -24
  43. data/ext/puma_http11/http11_parser_common.rl +8 -8
  44. data/ext/puma_http11/mini_ssl.c +696 -38
  45. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  46. data/ext/puma_http11/org/jruby/puma/EnvKey.java +241 -0
  47. data/ext/puma_http11/org/jruby/puma/Http11.java +241 -145
  48. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +174 -221
  49. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +413 -193
  50. data/ext/puma_http11/puma_http11.c +183 -175
  51. data/lib/puma/app/status.rb +77 -29
  52. data/lib/puma/binder.rb +349 -119
  53. data/lib/puma/cli.rb +163 -801
  54. data/lib/puma/client.rb +627 -144
  55. data/lib/puma/client_env.rb +171 -0
  56. data/lib/puma/cluster/worker.rb +183 -0
  57. data/lib/puma/cluster/worker_handle.rb +127 -0
  58. data/lib/puma/cluster.rb +634 -0
  59. data/lib/puma/cluster_accept_loop_delay.rb +91 -0
  60. data/lib/puma/commonlogger.rb +115 -0
  61. data/lib/puma/configuration.rb +420 -198
  62. data/lib/puma/const.rb +266 -115
  63. data/lib/puma/control_cli.rb +219 -120
  64. data/lib/puma/detect.rb +56 -2
  65. data/lib/puma/dsl.rb +1562 -0
  66. data/lib/puma/error_logger.rb +115 -0
  67. data/lib/puma/events.rb +44 -60
  68. data/lib/puma/io_buffer.rb +48 -5
  69. data/lib/puma/jruby_restart.rb +2 -51
  70. data/lib/puma/json_serialization.rb +96 -0
  71. data/lib/puma/launcher/bundle_pruner.rb +102 -0
  72. data/lib/puma/launcher.rb +501 -0
  73. data/lib/puma/log_writer.rb +153 -0
  74. data/lib/puma/minissl/context_builder.rb +96 -0
  75. data/lib/puma/minissl.rb +355 -37
  76. data/lib/puma/null_io.rb +79 -12
  77. data/lib/puma/plugin/systemd.rb +90 -0
  78. data/lib/puma/plugin/tmp_restart.rb +36 -0
  79. data/lib/puma/plugin.rb +111 -0
  80. data/lib/puma/rack/builder.rb +297 -0
  81. data/lib/puma/rack/urlmap.rb +93 -0
  82. data/lib/puma/rack_default.rb +21 -4
  83. data/lib/puma/reactor.rb +102 -133
  84. data/lib/puma/response.rb +532 -0
  85. data/lib/puma/runner.rb +211 -0
  86. data/lib/puma/sd_notify.rb +146 -0
  87. data/lib/puma/server.rb +582 -445
  88. data/lib/puma/server_plugin_control.rb +32 -0
  89. data/lib/puma/single.rb +72 -0
  90. data/lib/puma/state_file.rb +69 -0
  91. data/lib/puma/thread_pool.rb +389 -57
  92. data/lib/puma/util.rb +125 -0
  93. data/lib/puma.rb +80 -6
  94. data/lib/rack/handler/puma.rb +125 -47
  95. data/tools/Dockerfile +26 -0
  96. data/tools/trickletest.rb +44 -0
  97. metadata +88 -148
  98. data/COPYING +0 -55
  99. data/Gemfile +0 -10
  100. data/History.txt +0 -302
  101. data/Manifest.txt +0 -60
  102. data/Rakefile +0 -165
  103. data/TODO +0 -5
  104. data/docs/config.md +0 -0
  105. data/ext/puma_http11/ext_help.h +0 -15
  106. data/ext/puma_http11/io_buffer.c +0 -154
  107. data/lib/puma/accept_nonblock.rb +0 -23
  108. data/lib/puma/capistrano.rb +0 -34
  109. data/lib/puma/compat.rb +0 -11
  110. data/lib/puma/daemon_ext.rb +0 -20
  111. data/lib/puma/delegation.rb +0 -11
  112. data/lib/puma/java_io_buffer.rb +0 -45
  113. data/lib/puma/rack_patch.rb +0 -25
  114. data/puma.gemspec +0 -45
  115. data/test/test_app_status.rb +0 -88
  116. data/test/test_cli.rb +0 -171
  117. data/test/test_config.rb +0 -16
  118. data/test/test_http10.rb +0 -27
  119. data/test/test_http11.rb +0 -126
  120. data/test/test_integration.rb +0 -154
  121. data/test/test_iobuffer.rb +0 -38
  122. data/test/test_minissl.rb +0 -25
  123. data/test/test_null_io.rb +0 -31
  124. data/test/test_persistent.rb +0 -238
  125. data/test/test_puma_server.rb +0 -224
  126. data/test/test_rack_handler.rb +0 -10
  127. data/test/test_rack_server.rb +0 -141
  128. data/test/test_thread_pool.rb +0 -146
  129. data/test/test_unix_socket.rb +0 -39
  130. data/test/test_ws.rb +0 -89
  131. data/tools/jungle/init.d/README.md +0 -54
  132. data/tools/jungle/init.d/puma +0 -332
  133. data/tools/jungle/init.d/run-puma +0 -3
  134. data/tools/jungle/upstart/README.md +0 -61
  135. data/tools/jungle/upstart/puma-manager.conf +0 -31
  136. data/tools/jungle/upstart/puma.conf +0 -52
data/lib/puma/const.rb CHANGED
@@ -1,19 +1,91 @@
1
- require 'rack'
1
+ #encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module Puma
4
5
  class UnsupportedOption < RuntimeError
5
6
  end
6
7
 
7
-
8
8
  # Every standard HTTP code mapped to the appropriate message. These are
9
9
  # used so frequently that they are placed directly in Puma for easy
10
10
  # access rather than Puma::Const itself.
11
- HTTP_STATUS_CODES = Rack::Utils::HTTP_STATUS_CODES
11
+
12
+ # Every standard HTTP code mapped to the appropriate message.
13
+ # Generated with:
14
+ # curl -s https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv | \
15
+ # ruby -ne 'm = /^(\d{3}),(?!Unassigned|\(Unused\))([^,]+)/.match($_) and \
16
+ # puts "#{m[1]} => \x27#{m[2].strip}\x27,"'
17
+ HTTP_STATUS_CODES = {
18
+ 100 => 'Continue',
19
+ 101 => 'Switching Protocols',
20
+ 102 => 'Processing',
21
+ 103 => 'Early Hints',
22
+ 200 => 'OK',
23
+ 201 => 'Created',
24
+ 202 => 'Accepted',
25
+ 203 => 'Non-Authoritative Information',
26
+ 204 => 'No Content',
27
+ 205 => 'Reset Content',
28
+ 206 => 'Partial Content',
29
+ 207 => 'Multi-Status',
30
+ 208 => 'Already Reported',
31
+ 226 => 'IM Used',
32
+ 300 => 'Multiple Choices',
33
+ 301 => 'Moved Permanently',
34
+ 302 => 'Found',
35
+ 303 => 'See Other',
36
+ 304 => 'Not Modified',
37
+ 305 => 'Use Proxy',
38
+ 307 => 'Temporary Redirect',
39
+ 308 => 'Permanent Redirect',
40
+ 400 => 'Bad Request',
41
+ 401 => 'Unauthorized',
42
+ 402 => 'Payment Required',
43
+ 403 => 'Forbidden',
44
+ 404 => 'Not Found',
45
+ 405 => 'Method Not Allowed',
46
+ 406 => 'Not Acceptable',
47
+ 407 => 'Proxy Authentication Required',
48
+ 408 => 'Request Timeout',
49
+ 409 => 'Conflict',
50
+ 410 => 'Gone',
51
+ 411 => 'Length Required',
52
+ 412 => 'Precondition Failed',
53
+ 413 => 'Content Too Large',
54
+ 414 => 'URI Too Long',
55
+ 415 => 'Unsupported Media Type',
56
+ 416 => 'Range Not Satisfiable',
57
+ 417 => 'Expectation Failed',
58
+ 421 => 'Misdirected Request',
59
+ 422 => 'Unprocessable Content',
60
+ 423 => 'Locked',
61
+ 424 => 'Failed Dependency',
62
+ 425 => 'Too Early',
63
+ 426 => 'Upgrade Required',
64
+ 428 => 'Precondition Required',
65
+ 429 => 'Too Many Requests',
66
+ 431 => 'Request Header Fields Too Large',
67
+ 451 => 'Unavailable For Legal Reasons',
68
+ 500 => 'Internal Server Error',
69
+ 501 => 'Not Implemented',
70
+ 502 => 'Bad Gateway',
71
+ 503 => 'Service Unavailable',
72
+ 504 => 'Gateway Timeout',
73
+ 505 => 'HTTP Version Not Supported',
74
+ 506 => 'Variant Also Negotiates',
75
+ 507 => 'Insufficient Storage',
76
+ 508 => 'Loop Detected',
77
+ 510 => 'Not Extended (OBSOLETED)',
78
+ 511 => 'Network Authentication Required'
79
+ }.freeze
12
80
 
13
81
  # For some HTTP status codes the client only expects headers.
14
- STATUS_WITH_NO_ENTITY_BODY = Hash[Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.map { |s|
15
- [s, true]
16
- }]
82
+ #
83
+
84
+ STATUS_WITH_NO_ENTITY_BODY = {
85
+ 204 => true,
86
+ 205 => true,
87
+ 304 => true
88
+ }.freeze
17
89
 
18
90
  # Frequently used constants when constructing requests or responses. Many times
19
91
  # the constant just refers to a string with the same contents. Using these constants
@@ -28,46 +100,42 @@ module Puma
28
100
  # too taxing on performance.
29
101
  module Const
30
102
 
31
- PUMA_VERSION = VERSION = "2.2.0".freeze
103
+ PUMA_VERSION = VERSION = "8.0.2"
104
+ CODE_NAME = "Into the Arena"
32
105
 
33
- FAST_TRACK_KA_TIMEOUT = 0.2
106
+ PUMA_SERVER_STRING = ["puma", PUMA_VERSION, CODE_NAME].join(" ").freeze
34
107
 
35
- # The default number of seconds for another request within a persistent
36
- # session.
37
- PERSISTENT_TIMEOUT = 20
38
-
39
- # The default number of seconds to wait until we get the first data
40
- # for the request
41
- FIRST_DATA_TIMEOUT = 30
42
-
43
- DATE = "Date".freeze
44
-
45
- SCRIPT_NAME = "SCRIPT_NAME".freeze
108
+ # How long to wait when getting some write blocking on the socket when
109
+ # sending data back
110
+ WRITE_TIMEOUT = 10
46
111
 
47
112
  # The original URI requested by the client.
48
- REQUEST_URI= 'REQUEST_URI'.freeze
49
- REQUEST_PATH = 'REQUEST_PATH'.freeze
50
-
51
- PATH_INFO = 'PATH_INFO'.freeze
52
-
53
- PUMA_TMP_BASE = "puma".freeze
54
-
55
- # Indicate that we couldn't parse the request
56
- ERROR_400_RESPONSE = "HTTP/1.1 400 Bad Request\r\n\r\n"
57
-
58
- # The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
59
- ERROR_404_RESPONSE = "HTTP/1.1 404 Not Found\r\nConnection: close\r\nServer: Puma #{PUMA_VERSION}\r\n\r\nNOT FOUND".freeze
60
-
61
- CONTENT_LENGTH = "CONTENT_LENGTH".freeze
62
-
63
- # Indicate that there was an internal error, obviously.
64
- ERROR_500_RESPONSE = "HTTP/1.1 500 Internal Server Error\r\n\r\n"
65
-
66
- # A common header for indicating the server is too busy. Not used yet.
67
- ERROR_503_RESPONSE = "HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
113
+ REQUEST_URI= "REQUEST_URI"
114
+ REQUEST_PATH = "REQUEST_PATH"
115
+ QUERY_STRING = "QUERY_STRING"
116
+ CONTENT_LENGTH = "CONTENT_LENGTH"
117
+
118
+ PATH_INFO = "PATH_INFO"
119
+
120
+ PUMA_TMP_BASE = "puma"
121
+
122
+ ERROR_RESPONSE = {
123
+ # Indicate that we couldn't parse the request
124
+ 400 => "HTTP/1.1 400 Bad Request\r\n\r\n",
125
+ # The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
126
+ 404 => "HTTP/1.1 404 Not Found\r\nconnection: close\r\n\r\n",
127
+ # The standard empty 408 response for requests that timed out.
128
+ 408 => "HTTP/1.1 408 Request Timeout\r\nconnection: close\r\n\r\n",
129
+ # Indicate that there was an internal error, obviously.
130
+ 500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n",
131
+ # Incorrect or invalid header value
132
+ 501 => "HTTP/1.1 501 Not Implemented\r\n\r\n",
133
+ # A common header for indicating the server is too busy. Not used yet.
134
+ 503 => "HTTP/1.1 503 Service Unavailable\r\n\r\n"
135
+ }.freeze
68
136
 
69
137
  # The basic max request size we'll try to read.
70
- CHUNK_SIZE = 16 * 1024
138
+ CHUNK_SIZE = 64 * 1024
71
139
 
72
140
  # This is the maximum header that is allowed before a client is booted. The parser detects
73
141
  # this, but we'd also like to do this as well.
@@ -76,82 +144,165 @@ module Puma
76
144
  # Maximum request body size before it is moved out of memory and into a tempfile for reading.
77
145
  MAX_BODY = MAX_HEADER
78
146
 
79
- # A frozen format for this is about 15% faster
80
- STATUS_FORMAT = "HTTP/1.1 %d %s\r\nConnection: close\r\n".freeze
147
+ REQUEST_METHOD = "REQUEST_METHOD"
148
+ HEAD = "HEAD"
149
+
150
+ # based on https://www.rfc-editor.org/rfc/rfc9110.html#name-overview,
151
+ # with CONNECT removed, and PATCH added
152
+ SUPPORTED_HTTP_METHODS = %w[HEAD GET POST PUT DELETE OPTIONS TRACE PATCH].freeze
153
+
154
+ # list from https://www.iana.org/assignments/http-methods/http-methods.xhtml
155
+ # as of 04-May-23
156
+ IANA_HTTP_METHODS = %w[
157
+ ACL
158
+ BASELINE-CONTROL
159
+ BIND
160
+ CHECKIN
161
+ CHECKOUT
162
+ CONNECT
163
+ COPY
164
+ DELETE
165
+ GET
166
+ HEAD
167
+ LABEL
168
+ LINK
169
+ LOCK
170
+ MERGE
171
+ MKACTIVITY
172
+ MKCALENDAR
173
+ MKCOL
174
+ MKREDIRECTREF
175
+ MKWORKSPACE
176
+ MOVE
177
+ OPTIONS
178
+ ORDERPATCH
179
+ PATCH
180
+ POST
181
+ PRI
182
+ PROPFIND
183
+ PROPPATCH
184
+ PUT
185
+ REBIND
186
+ REPORT
187
+ SEARCH
188
+ TRACE
189
+ UNBIND
190
+ UNCHECKOUT
191
+ UNLINK
192
+ UNLOCK
193
+ UPDATE
194
+ UPDATEREDIRECTREF
195
+ VERSION-CONTROL
196
+ ].freeze
81
197
 
82
- CONTENT_TYPE = "Content-Type".freeze
83
-
84
- LAST_MODIFIED = "Last-Modified".freeze
85
- ETAG = "ETag".freeze
86
- SLASH = "/".freeze
87
- REQUEST_METHOD = "REQUEST_METHOD".freeze
88
- GET = "GET".freeze
89
- HEAD = "HEAD".freeze
90
198
  # ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32)
91
- ETAG_FORMAT = "\"%x-%x-%x\"".freeze
92
- LINE_END = "\r\n".freeze
93
- REMOTE_ADDR = "REMOTE_ADDR".freeze
94
- HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR".freeze
95
- HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE".freeze
96
- HTTP_IF_NONE_MATCH = "HTTP_IF_NONE_MATCH".freeze
97
- REDIRECT = "HTTP/1.1 302 Found\r\nLocation: %s\r\nConnection: close\r\n\r\n".freeze
98
- HOST = "HOST".freeze
99
-
100
- SERVER_NAME = "SERVER_NAME".freeze
101
- SERVER_PORT = "SERVER_PORT".freeze
102
- HTTP_HOST = "HTTP_HOST".freeze
103
- PORT_80 = "80".freeze
104
- PORT_443 = "443".freeze
105
- LOCALHOST = "localhost".freeze
106
-
107
- SERVER_PROTOCOL = "SERVER_PROTOCOL".freeze
108
- HTTP_11 = "HTTP/1.1".freeze
109
- HTTP_10 = "HTTP/1.0".freeze
110
-
111
- SERVER_SOFTWARE = "SERVER_SOFTWARE".freeze
112
- GATEWAY_INTERFACE = "GATEWAY_INTERFACE".freeze
113
- CGI_VER = "CGI/1.2".freeze
114
-
115
- STOP_COMMAND = "?".freeze
116
- HALT_COMMAND = "!".freeze
117
- RESTART_COMMAND = "R".freeze
118
-
119
- RACK_INPUT = "rack.input".freeze
120
- RACK_URL_SCHEME = "rack.url_scheme".freeze
121
- RACK_AFTER_REPLY = "rack.after_reply".freeze
122
- PUMA_SOCKET = "puma.socket".freeze
123
- PUMA_CONFIG = "puma.config".freeze
124
-
125
- HTTP = "http".freeze
126
- HTTPS = "https".freeze
127
-
128
- HTTPS_KEY = "HTTPS".freeze
129
-
130
- HTTP_VERSION = "HTTP_VERSION".freeze
131
- HTTP_CONNECTION = "HTTP_CONNECTION".freeze
132
-
133
- HTTP_11_200 = "HTTP/1.1 200 OK\r\n".freeze
134
- HTTP_10_200 = "HTTP/1.0 200 OK\r\n".freeze
135
-
136
- CLOSE = "close".freeze
137
- KEEP_ALIVE = "Keep-Alive".freeze
138
-
139
- CONTENT_LENGTH2 = "Content-Length".freeze
140
- CONTENT_LENGTH_S = "Content-Length: ".freeze
141
- TRANSFER_ENCODING = "Transfer-Encoding".freeze
142
-
143
- CONNECTION_CLOSE = "Connection: close\r\n".freeze
144
- CONNECTION_KEEP_ALIVE = "Connection: Keep-Alive\r\n".freeze
145
-
146
- TRANSFER_ENCODING_CHUNKED = "Transfer-Encoding: chunked\r\n".freeze
147
- CLOSE_CHUNKED = "0\r\n\r\n".freeze
148
-
149
- COLON = ": ".freeze
150
-
151
- NEWLINE = "\n".freeze
152
-
153
- HIJACK_P = "rack.hijack?".freeze
154
- HIJACK = "rack.hijack".freeze
155
- HIJACK_IO = "rack.hijack_io".freeze
199
+ LINE_END = "\r\n"
200
+ REMOTE_ADDR = "REMOTE_ADDR"
201
+ HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR"
202
+ HTTP_X_FORWARDED_SSL = "HTTP_X_FORWARDED_SSL"
203
+ HTTP_X_FORWARDED_SCHEME = "HTTP_X_FORWARDED_SCHEME"
204
+ HTTP_X_FORWARDED_PROTO = "HTTP_X_FORWARDED_PROTO"
205
+
206
+ SERVER_NAME = "SERVER_NAME"
207
+ SERVER_PORT = "SERVER_PORT"
208
+ HTTP_HOST = "HTTP_HOST"
209
+ PORT_80 = "80"
210
+ PORT_443 = "443"
211
+ LOCALHOST = "localhost"
212
+ LOCALHOST_IPV4 = "127.0.0.1"
213
+ LOCALHOST_IPV6 = "::1"
214
+ UNSPECIFIED_IPV4 = "0.0.0.0"
215
+ UNSPECIFIED_IPV6 = "::"
216
+
217
+ SERVER_PROTOCOL = "SERVER_PROTOCOL"
218
+ HTTP_11 = "HTTP/1.1"
219
+
220
+ SERVER_SOFTWARE = "SERVER_SOFTWARE"
221
+ GATEWAY_INTERFACE = "GATEWAY_INTERFACE"
222
+ CGI_VER = "CGI/1.2"
223
+
224
+ STOP_COMMAND = "?"
225
+ HALT_COMMAND = "!"
226
+ RESTART_COMMAND = "R"
227
+
228
+ RACK_INPUT = "rack.input"
229
+ RACK_URL_SCHEME = "rack.url_scheme"
230
+ RACK_AFTER_REPLY = "rack.after_reply"
231
+ RACK_RESPONSE_FINISHED = "rack.response_finished"
232
+ PUMA_SOCKET = "puma.socket"
233
+ PUMA_CONFIG = "puma.config"
234
+ PUMA_PEERCERT = "puma.peercert"
235
+
236
+ HTTP = "http"
237
+ HTTPS = "https"
238
+
239
+ HTTPS_KEY = "HTTPS"
240
+
241
+ HTTP_VERSION = "HTTP_VERSION"
242
+ HTTP_CONNECTION = "HTTP_CONNECTION"
243
+ HTTP_EXPECT = "HTTP_EXPECT"
244
+ CONTINUE = "100-continue"
245
+
246
+ HTTP_11_100 = "HTTP/1.1 100 Continue\r\n\r\n"
247
+ HTTP_11_200 = "HTTP/1.1 200 OK\r\n"
248
+ HTTP_10_200 = "HTTP/1.0 200 OK\r\n"
249
+
250
+ CLOSE = "close"
251
+ KEEP_ALIVE = "keep-alive"
252
+
253
+ CONTENT_LENGTH2 = "content-length"
254
+ CONTENT_LENGTH_S = "content-length: "
255
+ TRANSFER_ENCODING = "transfer-encoding"
256
+ TRANSFER_ENCODING2 = "HTTP_TRANSFER_ENCODING"
257
+
258
+ CONNECTION_CLOSE = "connection: close\r\n"
259
+ CONNECTION_KEEP_ALIVE = "connection: keep-alive\r\n"
260
+
261
+ TRANSFER_ENCODING_CHUNKED = "transfer-encoding: chunked\r\n"
262
+ CLOSE_CHUNKED = "0\r\n\r\n"
263
+
264
+ CHUNKED = "chunked"
265
+
266
+ COLON = ": "
267
+
268
+ NEWLINE = "\n"
269
+
270
+ HIJACK_P = "rack.hijack?"
271
+ HIJACK = "rack.hijack"
272
+ HIJACK_IO = "rack.hijack_io"
273
+
274
+ EARLY_HINTS = "rack.early_hints"
275
+
276
+ # Illegal character in the key or value of response header
277
+ DQUOTE = "\""
278
+ HTTP_HEADER_DELIMITER = Regexp.escape("(),/:;<=>?@[]{}\\").freeze
279
+ ILLEGAL_HEADER_KEY_REGEX = /[\x00-\x20#{DQUOTE}#{HTTP_HEADER_DELIMITER}]/.freeze
280
+ # header values can contain HTAB?
281
+ ILLEGAL_HEADER_VALUE_REGEX = /[\x00-\x08\x0A-\x1F]/.freeze
282
+
283
+ # The keys of headers that should not be convert to underscore
284
+ # normalized versions. These headers are ignored at the request reading layer,
285
+ # but if we normalize them after reading, it's just confusing for the application.
286
+ UNMASKABLE_HEADERS = {
287
+ "HTTP_TRANSFER,ENCODING" => true,
288
+ "HTTP_CONTENT,LENGTH" => true,
289
+ }
290
+
291
+ # Banned keys of response header
292
+ BANNED_HEADER_KEY = /\A(rack\.|status\z)/.freeze
293
+
294
+ PROXY_PROTOCOL_V1_REGEX = /\APROXY (?:TCP4|TCP6|UNKNOWN) ([^\r]+)\r\n/.freeze
295
+ PROXY_PROTOCOL_V1_MAX_LENGTH = 107
296
+
297
+ # All constants are prefixed with `PIPE_` to avoid name collisions.
298
+ module PipeRequest
299
+ PIPE_WAKEUP = "!"
300
+ PIPE_BOOT = "b"
301
+ PIPE_FORK = "f"
302
+ PIPE_EXTERNAL_TERM = "e"
303
+ PIPE_TERM = "t"
304
+ PIPE_PING = "p"
305
+ PIPE_IDLE = "i"
306
+ end
156
307
  end
157
308
  end