Changeset View
Changeset View
Standalone View
Standalone View
src/aphront/headerparser/AphrontHTTPHeaderParser.php
- This file was added.
| <?php | |||||
| final class AphrontHTTPHeaderParser extends Phobject { | |||||
| private $name; | |||||
| private $content; | |||||
| private $pairs; | |||||
| public function parseRawHeader($raw_header) { | |||||
| $this->name = null; | |||||
| $this->content = null; | |||||
| $parts = explode(':', $raw_header, 2); | |||||
| $this->name = trim($parts[0]); | |||||
| if (count($parts) > 1) { | |||||
| $this->content = trim($parts[1]); | |||||
| } | |||||
| $this->pairs = null; | |||||
| return $this; | |||||
| } | |||||
| public function getHeaderName() { | |||||
| $this->requireParse(); | |||||
| return $this->name; | |||||
| } | |||||
| public function getHeaderContent() { | |||||
| $this->requireParse(); | |||||
| return $this->content; | |||||
| } | |||||
| public function getHeaderContentAsPairs() { | |||||
| $content = $this->getHeaderContent(); | |||||
| $state = 'prekey'; | |||||
| $length = strlen($content); | |||||
| $pair_name = null; | |||||
| $pair_value = null; | |||||
| $pairs = array(); | |||||
| $ii = 0; | |||||
| while ($ii < $length) { | |||||
| $c = $content[$ii]; | |||||
| switch ($state) { | |||||
| case 'prekey'; | |||||
| // We're eating space in front of a key. | |||||
| if ($c == ' ') { | |||||
| $ii++; | |||||
| break; | |||||
| } | |||||
| $pair_name = ''; | |||||
| $state = 'key'; | |||||
| break; | |||||
| case 'key'; | |||||
| // We're parsing a key name until we find "=" or ";". | |||||
| if ($c == ';') { | |||||
| $state = 'done'; | |||||
| break; | |||||
| } | |||||
| if ($c == '=') { | |||||
| $ii++; | |||||
| $state = 'value'; | |||||
| break; | |||||
| } | |||||
| $ii++; | |||||
| $pair_name .= $c; | |||||
| break; | |||||
| case 'value': | |||||
| // We found an "=", so now figure out if the value is quoted | |||||
| // or not. | |||||
| if ($c == '"') { | |||||
| $ii++; | |||||
| $state = 'quoted'; | |||||
| break; | |||||
| } | |||||
| $state = 'unquoted'; | |||||
| break; | |||||
| case 'quoted': | |||||
| // We're in a quoted string, parse until we find the closing quote. | |||||
| if ($c == '"') { | |||||
| $ii++; | |||||
| $state = 'done'; | |||||
| break; | |||||
| } | |||||
| $ii++; | |||||
| $pair_value .= $c; | |||||
| break; | |||||
| case 'unquoted': | |||||
| // We're in an unquoted string, parse until we find a space or a | |||||
| // semicolon. | |||||
| if ($c == ' ' || $c == ';') { | |||||
| $state = 'done'; | |||||
| break; | |||||
| } | |||||
| $ii++; | |||||
| $pair_value .= $c; | |||||
| break; | |||||
| case 'done': | |||||
| // We parsed something, so eat any trailing whitespace and semicolons | |||||
| // and look for a new value. | |||||
| if ($c == ' ' || $c == ';') { | |||||
| $ii++; | |||||
| break; | |||||
| } | |||||
| $pairs[] = array( | |||||
| $pair_name, | |||||
| $pair_value, | |||||
| ); | |||||
| $pair_name = null; | |||||
| $pair_value = null; | |||||
| $state = 'prekey'; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if ($state == 'quoted') { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Header has unterminated double quote for key "%s".', | |||||
| $pair_name)); | |||||
| } | |||||
| if ($pair_name !== null) { | |||||
| $pairs[] = array( | |||||
| $pair_name, | |||||
| $pair_value, | |||||
| ); | |||||
| } | |||||
| return $pairs; | |||||
| } | |||||
| private function requireParse() { | |||||
| if ($this->name === null) { | |||||
| throw new PhutilInvalidStateException('parseRawHeader'); | |||||
| } | |||||
| } | |||||
| } | |||||