| @@ 658-715 (lines=58) @@ | ||
| 655 | * @throws \PHPDaemon\Request\RequestHeadersAlreadySent |
|
| 656 | * @return boolean Success |
|
| 657 | */ |
|
| 658 | public function header($s, $replace = true, $code = false) |
|
| 659 | { |
|
| 660 | if (!$code) { |
|
| 661 | $this->status($code); |
|
| 662 | } |
|
| 663 | ||
| 664 | if ($this->headers_sent) { |
|
| 665 | throw new RequestHeadersAlreadySent; |
|
| 666 | } |
|
| 667 | $s = strtr($s, "\r\n", ' '); |
|
| 668 | ||
| 669 | $e = explode(':', $s, 2); |
|
| 670 | ||
| 671 | if (!isset($e[1])) { |
|
| 672 | $e[0] = 'STATUS'; |
|
| 673 | ||
| 674 | if (strncmp($s, 'HTTP/', 5) === 0) { |
|
| 675 | $s = substr($s, 9); |
|
| 676 | } |
|
| 677 | } |
|
| 678 | ||
| 679 | $k = strtr(strtoupper($e[0]), Generic::$htr); |
|
| 680 | ||
| 681 | if ($k === 'CONTENT_TYPE') { |
|
| 682 | self::parse_str(strtolower($e[1]), $ctype, true); |
|
| 683 | if (!isset($ctype['charset'])) { |
|
| 684 | $ctype['charset'] = $this->upstream->pool->config->defaultcharset->value; |
|
| 685 | ||
| 686 | $s = $e[0] . ': '; |
|
| 687 | $i = 0; |
|
| 688 | foreach ($ctype as $k => $v) { |
|
| 689 | $s .= ($i > 0 ? '; ' : '') . $k . ($v !== '' ? '=' . $v : ''); |
|
| 690 | ++$i; |
|
| 691 | } |
|
| 692 | } |
|
| 693 | } |
|
| 694 | ||
| 695 | if ($k === 'SET_COOKIE') { |
|
| 696 | $k .= '_' . ++$this->cookieNum; |
|
| 697 | } elseif (!$replace && isset($this->headers[$k])) { |
|
| 698 | return false; |
|
| 699 | } |
|
| 700 | ||
| 701 | $this->headers[$k] = $s; |
|
| 702 | ||
| 703 | if ($k === 'CONTENT_LENGTH') { |
|
| 704 | $this->contentLength = (int)$e[1]; |
|
| 705 | } elseif ($k === 'LOCATION') { |
|
| 706 | $this->status(301); |
|
| 707 | } |
|
| 708 | ||
| 709 | if (Daemon::$compatMode) { |
|
| 710 | is_callable('header_native') ? header_native($s) : header($s); |
|
| 711 | } |
|
| 712 | ||
| 713 | return true; |
|
| 714 | } |
|
| 715 | ||
| 716 | /** |
|
| 717 | * Removes a header |
|
| 718 | * @param string $s Header name. Example: 'Location' |
|
| @@ 490-546 (lines=57) @@ | ||
| 487 | * @throws \PHPDaemon\Request\RequestHeadersAlreadySent |
|
| 488 | * @return boolean Success |
|
| 489 | */ |
|
| 490 | public function header($s, $replace = true, $code = false) |
|
| 491 | { |
|
| 492 | if ($code) { |
|
| 493 | $this->status($code); |
|
| 494 | } |
|
| 495 | ||
| 496 | if ($this->headers_sent) { |
|
| 497 | throw new RequestHeadersAlreadySent; |
|
| 498 | } |
|
| 499 | $s = strtr($s, "\r\n", ' '); |
|
| 500 | ||
| 501 | $e = explode(':', $s, 2); |
|
| 502 | ||
| 503 | if (!isset($e[1])) { |
|
| 504 | $e[0] = 'STATUS'; |
|
| 505 | ||
| 506 | if (strncmp($s, 'HTTP/', 5) === 0) { |
|
| 507 | $s = substr($s, 9); |
|
| 508 | } |
|
| 509 | } |
|
| 510 | ||
| 511 | $k = strtr(strtoupper($e[0]), Generic::$htr); |
|
| 512 | ||
| 513 | if ($k === 'CONTENT_TYPE') { |
|
| 514 | self::parse_str(strtolower($e[1]), $ctype, true); |
|
| 515 | if (!isset($ctype['charset'])) { |
|
| 516 | $ctype['charset'] = $this->upstream->pool->config->defaultcharset->value; |
|
| 517 | ||
| 518 | $s = $e[0] . ': '; |
|
| 519 | $i = 0; |
|
| 520 | foreach ($ctype as $k => $v) { |
|
| 521 | $s .= ($i > 0 ? '; ' : '') . $k . ($v !== '' ? '=' . $v : ''); |
|
| 522 | ++$i; |
|
| 523 | } |
|
| 524 | } |
|
| 525 | } |
|
| 526 | if ($k === 'SET_COOKIE') { |
|
| 527 | $k .= '_' . ++$this->cookieNum; |
|
| 528 | } elseif (!$replace && isset($this->headers[$k])) { |
|
| 529 | return false; |
|
| 530 | } |
|
| 531 | ||
| 532 | $this->headers[$k] = $s; |
|
| 533 | ||
| 534 | if ($k === 'CONTENT_LENGTH') { |
|
| 535 | $this->contentLength = (int)$e[1]; |
|
| 536 | } elseif ($k === 'LOCATION') { |
|
| 537 | $this->status(301); |
|
| 538 | } |
|
| 539 | ||
| 540 | if (Daemon::$compatMode) { |
|
| 541 | is_callable('header_native') ? header_native($s) : header($s); |
|
| 542 | } |
|
| 543 | ||
| 544 | return true; |
|
| 545 | } |
|
| 546 | } |
|
| 547 | ||