* Case-insensitive dictionary, suitable for HTTP headers
namespace WpOrg\Requests\Response;
use WpOrg\Requests\Exception;
use WpOrg\Requests\Exception\InvalidArgument;
use WpOrg\Requests\Utility\CaseInsensitiveDictionary;
use WpOrg\Requests\Utility\FilteredIterator;
* Case-insensitive dictionary, suitable for HTTP headers
class Headers extends CaseInsensitiveDictionary {
* Unlike {@see \WpOrg\Requests\Response\Headers::getValues()}, this returns a string. If there are
* multiple values, it concatenates them with a comma as per RFC2616.
* Avoid using this where commas may be used unquoted in values, such as
* @param string $offset Name of the header to retrieve.
* @return string|null Header value
public function offsetGet($offset) {
if (is_string($offset)) {
$offset = strtolower($offset);
if (!isset($this->data[$offset])) {
return $this->flatten($this->data[$offset]);
* @param string $offset Item name
* @param string $value Item value
* @throws \WpOrg\Requests\Exception On attempting to use dictionary as list (`invalidset`)
public function offsetSet($offset, $value) {
throw new Exception('Object is a dictionary, not a list', 'invalidset');
if (is_string($offset)) {
$offset = strtolower($offset);
if (!isset($this->data[$offset])) {
$this->data[$offset] = [];
$this->data[$offset][] = $value;
* Get all values for a given header
* @param string $offset Name of the header to retrieve.
* @return array|null Header values
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not valid as an array key.
public function getValues($offset) {
if (!is_string($offset) && !is_int($offset)) {
throw InvalidArgument::create(1, '$offset', 'string|int', gettype($offset));
if (is_string($offset)) {
$offset = strtolower($offset);
if (!isset($this->data[$offset])) {
return $this->data[$offset];
* Flattens a value into a string
* Converts an array into a string by imploding values with a comma, as per
* RFC2616's rules for folding headers.
* @param string|array $value Value to flatten
* @return string Flattened value
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or an array.
public function flatten($value) {
return implode(',', $value);
throw InvalidArgument::create(1, '$value', 'string|array', gettype($value));
* Get an iterator for the data
* Converts the internally stored values to a comma-separated string if there is more
* than one value for a key.
public function getIterator() {
return new FilteredIterator($this->data, [$this, 'flatten']);