12     private $headers = [];
 
   15     private $headerNames  = [];
 
   18     private $protocol = 
'1.1';
 
   25         return $this->protocol;
 
   30         if ($this->protocol === $version) {
 
   35         $new->protocol = $version;
 
   41         return $this->headers;
 
   46         return isset($this->headerNames[strtolower($header)]);
 
   51         $header = strtolower($header);
 
   53         if (!isset($this->headerNames[$header])) {
 
   57         $header = $this->headerNames[$header];
 
   59         return $this->headers[$header];
 
   64         return implode(
', ', $this->
getHeader($header));
 
   69         $this->assertHeader($header);
 
   70         $value = $this->normalizeHeaderValue($value);
 
   71         $normalized = strtolower($header);
 
   74         if (isset($new->headerNames[$normalized])) {
 
   75             unset($new->headers[$new->headerNames[$normalized]]);
 
   77         $new->headerNames[$normalized] = $header;
 
   78         $new->headers[$header] = $value;
 
   85         $this->assertHeader($header);
 
   86         $value = $this->normalizeHeaderValue($value);
 
   87         $normalized = strtolower($header);
 
   90         if (isset($new->headerNames[$normalized])) {
 
   91             $header = $this->headerNames[$normalized];
 
   92             $new->headers[$header] = array_merge($this->headers[$header], $value);
 
   94             $new->headerNames[$normalized] = $header;
 
   95             $new->headers[$header] = $value;
 
  103         $normalized = strtolower($header);
 
  105         if (!isset($this->headerNames[$normalized])) {
 
  109         $header = $this->headerNames[$normalized];
 
  112         unset($new->headers[$header], $new->headerNames[$normalized]);
 
  119         if (!$this->stream) {
 
  123         return $this->stream;
 
  126     public function withBody(StreamInterface $body)
 
  128         if ($body === $this->stream) {
 
  133         $new->stream = $body;
 
  137     private function setHeaders(array $headers)
 
  139         $this->headerNames = $this->headers = [];
 
  140         foreach ($headers as $header => $value) {
 
  141             if (is_int($header)) {
 
  144                 $header = (string) $header;
 
  146             $this->assertHeader($header);
 
  147             $value = $this->normalizeHeaderValue($value);
 
  148             $normalized = strtolower($header);
 
  149             if (isset($this->headerNames[$normalized])) {
 
  150                 $header = $this->headerNames[$normalized];
 
  151                 $this->headers[$header] = array_merge($this->headers[$header], $value);
 
  153                 $this->headerNames[$normalized] = $header;
 
  154                 $this->headers[$header] = $value;
 
  159     private function normalizeHeaderValue($value)
 
  161         if (!is_array($value)) {
 
  162             return $this->trimHeaderValues([$value]);
 
  165         if (count($value) === 0) {
 
  166             throw new \InvalidArgumentException(
'Header value can not be an empty array.');
 
  169         return $this->trimHeaderValues($value);
 
  186     private function trimHeaderValues(array $values)
 
  188         return array_map(
function ($value) {
 
  189             if (!is_scalar($value) && 
null !== $value) {
 
  190                 throw new \InvalidArgumentException(sprintf(
 
  191                     'Header value must be scalar or null but %s provided.',
 
  192                     is_object($value) ? get_class($value) : gettype($value)
 
  196             return trim((
string) $value, 
" \t");
 
  200     private function assertHeader($header)
 
  202         if (!is_string($header)) {
 
  203             throw new \InvalidArgumentException(sprintf(
 
  204                 'Header name must be a string but %s provided.',
 
  205                 is_object($header) ? get_class($header) : gettype($header)
 
  209         if ($header === 
'') {
 
  210             throw new \InvalidArgumentException(
'Header name can not be empty.');