~tcuthbert/wordpress/openstack-objectstorage

« back to all changes in this revision

Viewing changes to vendor/guzzlehttp/guzzle/src/Message/AbstractMessage.php

  • Committer: Jacek Nykis
  • Date: 2015-02-11 15:35:31 UTC
  • Revision ID: jacek.nykis@canonical.com-20150211153531-hmy6zi0ov2qfkl0b
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
namespace GuzzleHttp\Message;
 
3
 
 
4
use GuzzleHttp\Stream\StreamInterface;
 
5
 
 
6
abstract class AbstractMessage implements MessageInterface
 
7
{
 
8
    /** @var array HTTP header collection */
 
9
    private $headers = [];
 
10
 
 
11
    /** @var array mapping a lowercase header name to its name over the wire */
 
12
    private $headerNames = [];
 
13
 
 
14
    /** @var StreamInterface Message body */
 
15
    private $body;
 
16
 
 
17
    /** @var string HTTP protocol version of the message */
 
18
    private $protocolVersion = '1.1';
 
19
 
 
20
    public function __toString()
 
21
    {
 
22
        return static::getStartLineAndHeaders($this)
 
23
            . "\r\n\r\n" . $this->getBody();
 
24
    }
 
25
 
 
26
    public function getProtocolVersion()
 
27
    {
 
28
        return $this->protocolVersion;
 
29
    }
 
30
 
 
31
    public function getBody()
 
32
    {
 
33
        return $this->body;
 
34
    }
 
35
 
 
36
    public function setBody(StreamInterface $body = null)
 
37
    {
 
38
        if ($body === null) {
 
39
            // Setting a null body will remove the body of the request
 
40
            $this->removeHeader('Content-Length')
 
41
                ->removeHeader('Transfer-Encoding');
 
42
        }
 
43
 
 
44
        $this->body = $body;
 
45
 
 
46
        return $this;
 
47
    }
 
48
 
 
49
    public function addHeader($header, $value)
 
50
    {
 
51
        static $valid = ['string' => true, 'integer' => true,
 
52
            'double' => true, 'array' => true];
 
53
 
 
54
        $type = gettype($value);
 
55
        if (!isset($valid[$type])) {
 
56
            throw new \InvalidArgumentException('Invalid header value');
 
57
        }
 
58
 
 
59
        if ($type == 'array') {
 
60
            $current = array_merge($this->getHeader($header, true), $value);
 
61
        } else {
 
62
            $current = $this->getHeader($header, true);
 
63
            $current[] = $value;
 
64
        }
 
65
 
 
66
        return $this->setHeader($header, $current);
 
67
    }
 
68
 
 
69
    public function addHeaders(array $headers)
 
70
    {
 
71
        foreach ($headers as $name => $header) {
 
72
            $this->addHeader($name, $header);
 
73
        }
 
74
    }
 
75
 
 
76
    public function getHeader($header, $asArray = false)
 
77
    {
 
78
        $name = strtolower($header);
 
79
 
 
80
        if (!isset($this->headers[$name])) {
 
81
            return $asArray ? [] : '';
 
82
        }
 
83
 
 
84
        return $asArray
 
85
            ? $this->headers[$name]
 
86
            : implode(', ', $this->headers[$name]);
 
87
    }
 
88
 
 
89
    public function getHeaders()
 
90
    {
 
91
        $headers = [];
 
92
        foreach ($this->headers as $name => $values) {
 
93
            $headers[$this->headerNames[$name]] = $values;
 
94
        }
 
95
 
 
96
        return $headers;
 
97
    }
 
98
 
 
99
    public function setHeader($header, $value)
 
100
    {
 
101
        $header = trim($header);
 
102
        $name = strtolower($header);
 
103
        $this->headerNames[$name] = $header;
 
104
 
 
105
        switch (gettype($value)) {
 
106
            case 'string':
 
107
                $this->headers[$name] = [trim($value)];
 
108
                break;
 
109
            case 'integer':
 
110
            case 'double':
 
111
                $this->headers[$name] = [(string) $value];
 
112
                break;
 
113
            case 'array':
 
114
                foreach ($value as &$v) {
 
115
                    $v = trim($v);
 
116
                }
 
117
                $this->headers[$name] = $value;
 
118
                break;
 
119
            default:
 
120
                throw new \InvalidArgumentException('Invalid header value '
 
121
                    . 'provided: ' . var_export($value, true));
 
122
        }
 
123
 
 
124
        return $this;
 
125
    }
 
126
 
 
127
    public function setHeaders(array $headers)
 
128
    {
 
129
        $this->headers = $this->headerNames = [];
 
130
        foreach ($headers as $key => $value) {
 
131
            $this->setHeader($key, $value);
 
132
        }
 
133
 
 
134
        return $this;
 
135
    }
 
136
 
 
137
    public function hasHeader($header)
 
138
    {
 
139
        return isset($this->headers[strtolower($header)]);
 
140
    }
 
141
 
 
142
    public function removeHeader($header)
 
143
    {
 
144
        $name = strtolower($header);
 
145
        unset($this->headers[$name], $this->headerNames[$name]);
 
146
 
 
147
        return $this;
 
148
    }
 
149
 
 
150
    /**
 
151
     * Parse an array of header values containing ";" separated data into an
 
152
     * array of associative arrays representing the header key value pair
 
153
     * data of the header. When a parameter does not contain a value, but just
 
154
     * contains a key, this function will inject a key with a '' string value.
 
155
     *
 
156
     * @param MessageInterface $message That contains the header
 
157
     * @param string           $header  Header to retrieve from the message
 
158
     *
 
159
     * @return array Returns the parsed header values.
 
160
     */
 
161
    public static function parseHeader(MessageInterface $message, $header)
 
162
    {
 
163
        static $trimmed = "\"'  \n\t\r";
 
164
        $params = $matches = [];
 
165
 
 
166
        foreach (self::normalizeHeader($message, $header) as $val) {
 
167
            $part = [];
 
168
            foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
 
169
                if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
 
170
                    $m = $matches[0];
 
171
                    if (isset($m[1])) {
 
172
                        $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
 
173
                    } else {
 
174
                        $part[] = trim($m[0], $trimmed);
 
175
                    }
 
176
                }
 
177
            }
 
178
            if ($part) {
 
179
                $params[] = $part;
 
180
            }
 
181
        }
 
182
 
 
183
        return $params;
 
184
    }
 
185
 
 
186
    /**
 
187
     * Converts an array of header values that may contain comma separated
 
188
     * headers into an array of headers with no comma separated values.
 
189
     *
 
190
     * @param MessageInterface $message That contains the header
 
191
     * @param string              $header  Header to retrieve from the message
 
192
     *
 
193
     * @return array Returns the normalized header field values.
 
194
     */
 
195
    public static function normalizeHeader(MessageInterface $message, $header)
 
196
    {
 
197
        $h = $message->getHeader($header, true);
 
198
        for ($i = 0, $total = count($h); $i < $total; $i++) {
 
199
            if (strpos($h[$i], ',') === false) {
 
200
                continue;
 
201
            }
 
202
            foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $h[$i]) as $v) {
 
203
                $h[] = trim($v);
 
204
            }
 
205
            unset($h[$i]);
 
206
        }
 
207
 
 
208
        return $h;
 
209
    }
 
210
 
 
211
    /**
 
212
     * Gets the start-line and headers of a message as a string
 
213
     *
 
214
     * @param MessageInterface $message
 
215
     *
 
216
     * @return string
 
217
     */
 
218
    public static function getStartLineAndHeaders(MessageInterface $message)
 
219
    {
 
220
        return static::getStartLine($message)
 
221
            . self::getHeadersAsString($message);
 
222
    }
 
223
 
 
224
    /**
 
225
     * Gets the headers of a message as a string
 
226
     *
 
227
     * @param MessageInterface $message
 
228
     *
 
229
     * @return string
 
230
     */
 
231
    public static function getHeadersAsString(MessageInterface $message)
 
232
    {
 
233
        $result  = '';
 
234
        foreach ($message->getHeaders() as $name => $values) {
 
235
            $result .= "\r\n{$name}: " . implode(', ', $values);
 
236
        }
 
237
 
 
238
        return $result;
 
239
    }
 
240
 
 
241
    /**
 
242
     * Gets the start line of a message
 
243
     *
 
244
     * @param MessageInterface $message
 
245
     *
 
246
     * @return string
 
247
     * @throws \InvalidArgumentException
 
248
     */
 
249
    public static function getStartLine(MessageInterface $message)
 
250
    {
 
251
        if ($message instanceof RequestInterface) {
 
252
            return trim($message->getMethod() . ' '
 
253
                . $message->getResource())
 
254
                . ' HTTP/' . $message->getProtocolVersion();
 
255
        } elseif ($message instanceof ResponseInterface) {
 
256
            return 'HTTP/' . $message->getProtocolVersion() . ' '
 
257
                . $message->getStatusCode() . ' '
 
258
                . $message->getReasonPhrase();
 
259
        } else {
 
260
            throw new \InvalidArgumentException('Unknown message type');
 
261
        }
 
262
    }
 
263
 
 
264
    /**
 
265
     * Accepts and modifies the options provided to the message in the
 
266
     * constructor.
 
267
     *
 
268
     * Can be overridden in subclasses as necessary.
 
269
     *
 
270
     * @param array $options Options array passed by reference.
 
271
     */
 
272
    protected function handleOptions(array &$options)
 
273
    {
 
274
        if (isset($options['protocol_version'])) {
 
275
            $this->protocolVersion = $options['protocol_version'];
 
276
        }
 
277
    }
 
278
}