From 374da3948e1d21f2c7d4dc8e4e6eedf105001f84 Mon Sep 17 00:00:00 2001 From: Kevin Robatel Date: Wed, 29 Jul 2015 17:30:02 +0200 Subject: [PATCH] Better parsing with RFC respect --- src/KeyValueHttpHeader.php | 27 +++++++++++++++++---------- tests/KeyValueHttpHeaderTest.php | 2 +- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/KeyValueHttpHeader.php b/src/KeyValueHttpHeader.php index 23f02429..c7238a54 100644 --- a/src/KeyValueHttpHeader.php +++ b/src/KeyValueHttpHeader.php @@ -5,7 +5,12 @@ class KeyValueHttpHeader { - const REGEX_SPLIT = '/^([^=]*)=(.*)$/'; + + /** + * Take from https://github.com/hapijs/wreck + * and modified for accepting space before and after the "=". + */ + const REGEX_SPLIT = '/(?:^|(?:\s*\,\s*))([^\x00-\x20\(\)<>@\,;\:\\\\"\/\[\]\?\=\{\}\x7F]+)(?:\s*\=\s*(?:([^\x00-\x20\(\)<>@\,;\:\\\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\\\]|\\\\.)*)\")))?/'; /** * @var string[] @@ -19,15 +24,17 @@ class KeyValueHttpHeader public function __construct(array $values) { foreach ($values as $value) { - // FIXME make it better with the RFC ABNF rule - $exploded = explode(',', $value); - - foreach ($exploded as $fragment) { - $matches = []; - if (preg_match(self::REGEX_SPLIT, $fragment, $matches)) { - $this->values[trim($matches[1])] = trim($matches[2]); - } else { - $this->values[trim($fragment)] = true; + $matches = []; + if (preg_match_all(self::REGEX_SPLIT, $value, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $val = ''; + if (count($match) == 3) { + $val = $match[2]; + } else if (count($match) > 3) { + $val = $match[3]; + } + + $this->values[$match[1]] = $val; } } } diff --git a/tests/KeyValueHttpHeaderTest.php b/tests/KeyValueHttpHeaderTest.php index f692c350..92a34a00 100644 --- a/tests/KeyValueHttpHeaderTest.php +++ b/tests/KeyValueHttpHeaderTest.php @@ -24,7 +24,7 @@ public function testBase() 'zero=0', 'nothing = ', 'false = false', - 'with-comma=1,yeah=2' + 'with-comma=1,yeah="2"' ] ]);