~ballot/wordpress/openstack-objectstorage-breaking-insight

« back to all changes in this revision

Viewing changes to vendor/guzzlehttp/guzzle/src/Message/MessageParser.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
 
 
3
namespace GuzzleHttp\Message;
 
4
 
 
5
/**
 
6
 * Request and response parser used by Guzzle
 
7
 */
 
8
class MessageParser
 
9
{
 
10
    /**
 
11
     * Parse an HTTP request message into an associative array of parts.
 
12
     *
 
13
     * @param string $message HTTP request to parse
 
14
     *
 
15
     * @return array|bool Returns false if the message is invalid
 
16
     */
 
17
    public function parseRequest($message)
 
18
    {
 
19
        if (!($parts = $this->parseMessage($message))) {
 
20
            return false;
 
21
        }
 
22
 
 
23
        // Parse the protocol and protocol version
 
24
        if (isset($parts['start_line'][2])) {
 
25
            $startParts = explode('/', $parts['start_line'][2]);
 
26
            $protocol = strtoupper($startParts[0]);
 
27
            $version = isset($startParts[1]) ? $startParts[1] : '1.1';
 
28
        } else {
 
29
            $protocol = 'HTTP';
 
30
            $version = '1.1';
 
31
        }
 
32
 
 
33
        $parsed = [
 
34
            'method'   => strtoupper($parts['start_line'][0]),
 
35
            'protocol' => $protocol,
 
36
            'protocol_version' => $version,
 
37
            'headers'  => $parts['headers'],
 
38
            'body'     => $parts['body']
 
39
        ];
 
40
 
 
41
        $parsed['request_url'] = $this->getUrlPartsFromMessage(
 
42
            (isset($parts['start_line'][1]) ? $parts['start_line'][1] : ''), $parsed);
 
43
 
 
44
        return $parsed;
 
45
    }
 
46
 
 
47
    /**
 
48
     * Parse an HTTP response message into an associative array of parts.
 
49
     *
 
50
     * @param string $message HTTP response to parse
 
51
     *
 
52
     * @return array|bool Returns false if the message is invalid
 
53
     */
 
54
    public function parseResponse($message)
 
55
    {
 
56
        if (!($parts = $this->parseMessage($message))) {
 
57
            return false;
 
58
        }
 
59
 
 
60
        list($protocol, $version) = explode('/', trim($parts['start_line'][0]));
 
61
 
 
62
        return [
 
63
            'protocol'         => $protocol,
 
64
            'protocol_version' => $version,
 
65
            'code'             => $parts['start_line'][1],
 
66
            'reason_phrase'    => isset($parts['start_line'][2]) ? $parts['start_line'][2] : '',
 
67
            'headers'          => $parts['headers'],
 
68
            'body'             => $parts['body']
 
69
        ];
 
70
    }
 
71
 
 
72
    /**
 
73
     * Parse a message into parts
 
74
     *
 
75
     * @param string $message Message to parse
 
76
     *
 
77
     * @return array|bool
 
78
     */
 
79
    private function parseMessage($message)
 
80
    {
 
81
        if (!$message) {
 
82
            return false;
 
83
        }
 
84
 
 
85
        $startLine = null;
 
86
        $headers = [];
 
87
        $body = '';
 
88
 
 
89
        // Iterate over each line in the message, accounting for line endings
 
90
        $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE);
 
91
        for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) {
 
92
 
 
93
            $line = $lines[$i];
 
94
 
 
95
            // If two line breaks were encountered, then this is the end of body
 
96
            if (empty($line)) {
 
97
                if ($i < $totalLines - 1) {
 
98
                    $body = implode('', array_slice($lines, $i + 2));
 
99
                }
 
100
                break;
 
101
            }
 
102
 
 
103
            // Parse message headers
 
104
            if (!$startLine) {
 
105
                $startLine = explode(' ', $line, 3);
 
106
            } elseif (strpos($line, ':')) {
 
107
                $parts = explode(':', $line, 2);
 
108
                $key = trim($parts[0]);
 
109
                $value = isset($parts[1]) ? trim($parts[1]) : '';
 
110
                if (!isset($headers[$key])) {
 
111
                    $headers[$key] = $value;
 
112
                } elseif (!is_array($headers[$key])) {
 
113
                    $headers[$key] = [$headers[$key], $value];
 
114
                } else {
 
115
                    $headers[$key][] = $value;
 
116
                }
 
117
            }
 
118
        }
 
119
 
 
120
        return [
 
121
            'start_line' => $startLine,
 
122
            'headers'    => $headers,
 
123
            'body'       => $body
 
124
        ];
 
125
    }
 
126
 
 
127
    /**
 
128
     * Create URL parts from HTTP message parts
 
129
     *
 
130
     * @param string $requestUrl Associated URL
 
131
     * @param array  $parts      HTTP message parts
 
132
     *
 
133
     * @return array
 
134
     */
 
135
    private function getUrlPartsFromMessage($requestUrl, array $parts)
 
136
    {
 
137
        // Parse the URL information from the message
 
138
        $urlParts = ['path' => $requestUrl, 'scheme' => 'http'];
 
139
 
 
140
        // Check for the Host header
 
141
        if (isset($parts['headers']['Host'])) {
 
142
            $urlParts['host'] = $parts['headers']['Host'];
 
143
        } elseif (isset($parts['headers']['host'])) {
 
144
            $urlParts['host'] = $parts['headers']['host'];
 
145
        } else {
 
146
            $urlParts['host'] = null;
 
147
        }
 
148
 
 
149
        if (false === strpos($urlParts['host'], ':')) {
 
150
            $urlParts['port'] = '';
 
151
        } else {
 
152
            $hostParts = explode(':', $urlParts['host']);
 
153
            $urlParts['host'] = trim($hostParts[0]);
 
154
            $urlParts['port'] = (int) trim($hostParts[1]);
 
155
            if ($urlParts['port'] == 443) {
 
156
                $urlParts['scheme'] = 'https';
 
157
            }
 
158
        }
 
159
 
 
160
        // Check if a query is present
 
161
        $path = $urlParts['path'];
 
162
        $qpos = strpos($path, '?');
 
163
        if ($qpos) {
 
164
            $urlParts['query'] = substr($path, $qpos + 1);
 
165
            $urlParts['path'] = substr($path, 0, $qpos);
 
166
        } else {
 
167
            $urlParts['query'] = '';
 
168
        }
 
169
 
 
170
        return $urlParts;
 
171
    }
 
172
}