comparison vendor/symfony/http-foundation/Response.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents c2387f117808
children af1871eacc83
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
62 const HTTP_I_AM_A_TEAPOT = 418; // RFC2324 62 const HTTP_I_AM_A_TEAPOT = 418; // RFC2324
63 const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540 63 const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540
64 const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918 64 const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918
65 const HTTP_LOCKED = 423; // RFC4918 65 const HTTP_LOCKED = 423; // RFC4918
66 const HTTP_FAILED_DEPENDENCY = 424; // RFC4918 66 const HTTP_FAILED_DEPENDENCY = 424; // RFC4918
67
68 /**
69 * @deprecated
70 */
67 const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817 71 const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817
72 const HTTP_TOO_EARLY = 425; // RFC-ietf-httpbis-replay-04
68 const HTTP_UPGRADE_REQUIRED = 426; // RFC2817 73 const HTTP_UPGRADE_REQUIRED = 426; // RFC2817
69 const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585 74 const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585
70 const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585 75 const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585
71 const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585 76 const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585
72 const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; 77 const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
121 * 126 *
122 * Unless otherwise noted, the status code is defined in RFC2616. 127 * Unless otherwise noted, the status code is defined in RFC2616.
123 * 128 *
124 * @var array 129 * @var array
125 */ 130 */
126 public static $statusTexts = array( 131 public static $statusTexts = [
127 100 => 'Continue', 132 100 => 'Continue',
128 101 => 'Switching Protocols', 133 101 => 'Switching Protocols',
129 102 => 'Processing', // RFC2518 134 102 => 'Processing', // RFC2518
130 103 => 'Early Hints', 135 103 => 'Early Hints',
131 200 => 'OK', 136 200 => 'OK',
167 418 => 'I\'m a teapot', // RFC2324 172 418 => 'I\'m a teapot', // RFC2324
168 421 => 'Misdirected Request', // RFC7540 173 421 => 'Misdirected Request', // RFC7540
169 422 => 'Unprocessable Entity', // RFC4918 174 422 => 'Unprocessable Entity', // RFC4918
170 423 => 'Locked', // RFC4918 175 423 => 'Locked', // RFC4918
171 424 => 'Failed Dependency', // RFC4918 176 424 => 'Failed Dependency', // RFC4918
172 425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817 177 425 => 'Too Early', // RFC-ietf-httpbis-replay-04
173 426 => 'Upgrade Required', // RFC2817 178 426 => 'Upgrade Required', // RFC2817
174 428 => 'Precondition Required', // RFC6585 179 428 => 'Precondition Required', // RFC6585
175 429 => 'Too Many Requests', // RFC6585 180 429 => 'Too Many Requests', // RFC6585
176 431 => 'Request Header Fields Too Large', // RFC6585 181 431 => 'Request Header Fields Too Large', // RFC6585
177 451 => 'Unavailable For Legal Reasons', // RFC7725 182 451 => 'Unavailable For Legal Reasons', // RFC7725
184 506 => 'Variant Also Negotiates', // RFC2295 189 506 => 'Variant Also Negotiates', // RFC2295
185 507 => 'Insufficient Storage', // RFC4918 190 507 => 'Insufficient Storage', // RFC4918
186 508 => 'Loop Detected', // RFC5842 191 508 => 'Loop Detected', // RFC5842
187 510 => 'Not Extended', // RFC2774 192 510 => 'Not Extended', // RFC2774
188 511 => 'Network Authentication Required', // RFC6585 193 511 => 'Network Authentication Required', // RFC6585
189 ); 194 ];
190 195
191 /** 196 /**
192 * @param mixed $content The response content, see setContent() 197 * @param mixed $content The response content, see setContent()
193 * @param int $status The response status code 198 * @param int $status The response status code
194 * @param array $headers An array of response headers 199 * @param array $headers An array of response headers
195 * 200 *
196 * @throws \InvalidArgumentException When the HTTP status code is not valid 201 * @throws \InvalidArgumentException When the HTTP status code is not valid
197 */ 202 */
198 public function __construct($content = '', $status = 200, $headers = array()) 203 public function __construct($content = '', $status = 200, $headers = [])
199 { 204 {
200 $this->headers = new ResponseHeaderBag($headers); 205 $this->headers = new ResponseHeaderBag($headers);
201 $this->setContent($content); 206 $this->setContent($content);
202 $this->setStatusCode($status); 207 $this->setStatusCode($status);
203 $this->setProtocolVersion('1.0'); 208 $this->setProtocolVersion('1.0');
215 * @param int $status The response status code 220 * @param int $status The response status code
216 * @param array $headers An array of response headers 221 * @param array $headers An array of response headers
217 * 222 *
218 * @return static 223 * @return static
219 */ 224 */
220 public static function create($content = '', $status = 200, $headers = array()) 225 public static function create($content = '', $status = 200, $headers = [])
221 { 226 {
222 return new static($content, $status, $headers); 227 return new static($content, $status, $headers);
223 } 228 }
224 229
225 /** 230 /**
326 if (headers_sent()) { 331 if (headers_sent()) {
327 return $this; 332 return $this;
328 } 333 }
329 334
330 // headers 335 // headers
331 foreach ($this->headers->allPreserveCase() as $name => $values) { 336 foreach ($this->headers->allPreserveCaseWithoutCookies() as $name => $values) {
337 $replace = 0 === strcasecmp($name, 'Content-Type');
332 foreach ($values as $value) { 338 foreach ($values as $value) {
333 header($name.': '.$value, false, $this->statusCode); 339 header($name.': '.$value, $replace, $this->statusCode);
334 } 340 }
341 }
342
343 // cookies
344 foreach ($this->headers->getCookies() as $cookie) {
345 header('Set-Cookie: '.$cookie->getName().strstr($cookie, '='), false, $this->statusCode);
335 } 346 }
336 347
337 // status 348 // status
338 header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode); 349 header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode);
339 350
360 public function send() 371 public function send()
361 { 372 {
362 $this->sendHeaders(); 373 $this->sendHeaders();
363 $this->sendContent(); 374 $this->sendContent();
364 375
365 if (function_exists('fastcgi_finish_request')) { 376 if (\function_exists('fastcgi_finish_request')) {
366 fastcgi_finish_request(); 377 fastcgi_finish_request();
367 } elseif (!\in_array(PHP_SAPI, array('cli', 'phpdbg'), true)) { 378 } elseif (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
368 static::closeOutputBuffers(0, true); 379 static::closeOutputBuffers(0, true);
369 } 380 }
370 381
371 return $this; 382 return $this;
372 } 383 }
382 * 393 *
383 * @throws \UnexpectedValueException 394 * @throws \UnexpectedValueException
384 */ 395 */
385 public function setContent($content) 396 public function setContent($content)
386 { 397 {
387 if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) { 398 if (null !== $content && !\is_string($content) && !is_numeric($content) && !\is_callable([$content, '__toString'])) {
388 throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content))); 399 throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', \gettype($content)));
389 } 400 }
390 401
391 $this->content = (string) $content; 402 $this->content = (string) $content;
392 403
393 return $this; 404 return $this;
529 * 540 *
530 * @final since version 3.3 541 * @final since version 3.3
531 */ 542 */
532 public function isCacheable() 543 public function isCacheable()
533 { 544 {
534 if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) { 545 if (!\in_array($this->statusCode, [200, 203, 300, 301, 302, 404, 410])) {
535 return false; 546 return false;
536 } 547 }
537 548
538 if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) { 549 if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
539 return false; 550 return false;
706 */ 717 */
707 public function expire() 718 public function expire()
708 { 719 {
709 if ($this->isFresh()) { 720 if ($this->isFresh()) {
710 $this->headers->set('Age', $this->getMaxAge()); 721 $this->headers->set('Age', $this->getMaxAge());
722 $this->headers->remove('Expires');
711 } 723 }
712 724
713 return $this; 725 return $this;
714 } 726 }
715 727
960 * 972 *
961 * @final since version 3.3 973 * @final since version 3.3
962 */ 974 */
963 public function setCache(array $options) 975 public function setCache(array $options)
964 { 976 {
965 if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'))) { 977 if ($diff = array_diff(array_keys($options), ['etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'])) {
966 throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff)))); 978 throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', $diff)));
967 } 979 }
968 980
969 if (isset($options['etag'])) { 981 if (isset($options['etag'])) {
970 $this->setEtag($options['etag']); 982 $this->setEtag($options['etag']);
971 } 983 }
1021 { 1033 {
1022 $this->setStatusCode(304); 1034 $this->setStatusCode(304);
1023 $this->setContent(null); 1035 $this->setContent(null);
1024 1036
1025 // remove headers that MUST NOT be included with 304 Not Modified responses 1037 // remove headers that MUST NOT be included with 304 Not Modified responses
1026 foreach (array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified') as $header) { 1038 foreach (['Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified'] as $header) {
1027 $this->headers->remove($header); 1039 $this->headers->remove($header);
1028 } 1040 }
1029 1041
1030 return $this; 1042 return $this;
1031 } 1043 }
1050 * @final since version 3.2 1062 * @final since version 3.2
1051 */ 1063 */
1052 public function getVary() 1064 public function getVary()
1053 { 1065 {
1054 if (!$vary = $this->headers->get('Vary', null, false)) { 1066 if (!$vary = $this->headers->get('Vary', null, false)) {
1055 return array(); 1067 return [];
1056 } 1068 }
1057 1069
1058 $ret = array(); 1070 $ret = [];
1059 foreach ($vary as $item) { 1071 foreach ($vary as $item) {
1060 $ret = array_merge($ret, preg_split('/[\s,]+/', $item)); 1072 $ret = array_merge($ret, preg_split('/[\s,]+/', $item));
1061 } 1073 }
1062 1074
1063 return $ret; 1075 return $ret;
1100 $notModified = false; 1112 $notModified = false;
1101 $lastModified = $this->headers->get('Last-Modified'); 1113 $lastModified = $this->headers->get('Last-Modified');
1102 $modifiedSince = $request->headers->get('If-Modified-Since'); 1114 $modifiedSince = $request->headers->get('If-Modified-Since');
1103 1115
1104 if ($etags = $request->getETags()) { 1116 if ($etags = $request->getETags()) {
1105 $notModified = in_array($this->getEtag(), $etags) || in_array('*', $etags); 1117 $notModified = \in_array($this->getEtag(), $etags) || \in_array('*', $etags);
1106 } 1118 }
1107 1119
1108 if ($modifiedSince && $lastModified) { 1120 if ($modifiedSince && $lastModified) {
1109 $notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified); 1121 $notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified);
1110 } 1122 }
1235 * 1247 *
1236 * @final since version 3.2 1248 * @final since version 3.2
1237 */ 1249 */
1238 public function isRedirect($location = null) 1250 public function isRedirect($location = null)
1239 { 1251 {
1240 return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location')); 1252 return \in_array($this->statusCode, [201, 301, 302, 303, 307, 308]) && (null === $location ?: $location == $this->headers->get('Location'));
1241 } 1253 }
1242 1254
1243 /** 1255 /**
1244 * Is the response empty? 1256 * Is the response empty?
1245 * 1257 *
1247 * 1259 *
1248 * @final since version 3.2 1260 * @final since version 3.2
1249 */ 1261 */
1250 public function isEmpty() 1262 public function isEmpty()
1251 { 1263 {
1252 return in_array($this->statusCode, array(204, 304)); 1264 return \in_array($this->statusCode, [204, 304]);
1253 } 1265 }
1254 1266
1255 /** 1267 /**
1256 * Cleans or flushes output buffers up to target level. 1268 * Cleans or flushes output buffers up to target level.
1257 * 1269 *
1263 * @final since version 3.3 1275 * @final since version 3.3
1264 */ 1276 */
1265 public static function closeOutputBuffers($targetLevel, $flush) 1277 public static function closeOutputBuffers($targetLevel, $flush)
1266 { 1278 {
1267 $status = ob_get_status(true); 1279 $status = ob_get_status(true);
1268 $level = count($status); 1280 $level = \count($status);
1269 // PHP_OUTPUT_HANDLER_* are not defined on HHVM 3.3 1281 // PHP_OUTPUT_HANDLER_* are not defined on HHVM 3.3
1270 $flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1; 1282 $flags = \defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1;
1271 1283
1272 while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || ($s['flags'] & $flags) === $flags : $s['del'])) { 1284 while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || ($s['flags'] & $flags) === $flags : $s['del'])) {
1273 if ($flush) { 1285 if ($flush) {
1274 ob_end_flush(); 1286 ob_end_flush();
1275 } else { 1287 } else {