/www/slight

To get this branch, use:
bzr branch http://bzr.ed.am/www/slight

« back to all changes in this revision

Viewing changes to flight/net/Request.php

  • Committer: Tim Marston
  • Date: 2015-08-05 18:48:29 UTC
  • Revision ID: tim@ed.am-20150805184829-c3qj13d1h89pkb2l
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Flight: An extensible micro-framework.
 
4
 *
 
5
 * @copyright   Copyright (c) 2011, Mike Cao <mike@mikecao.com>
 
6
 * @license     MIT, http://flightphp.com/license
 
7
 */
 
8
 
 
9
namespace flight\net;
 
10
 
 
11
use flight\util\Collection;
 
12
 
 
13
/**
 
14
 * The Request class represents an HTTP request. Data from
 
15
 * all the super globals $_GET, $_POST, $_COOKIE, and $_FILES
 
16
 * are stored and accessible via the Request object.
 
17
 *
 
18
 * The default request properties are:
 
19
 *   url - The URL being requested
 
20
 *   base - The parent subdirectory of the URL
 
21
 *   method - The request method (GET, POST, PUT, DELETE)
 
22
 *   referrer - The referrer URL
 
23
 *   ip - IP address of the client
 
24
 *   ajax - Whether the request is an AJAX request
 
25
 *   scheme - The server protocol (http, https)
 
26
 *   user_agent - Browser information
 
27
 *   type - The content type
 
28
 *   length - The content length
 
29
 *   query - Query string parameters
 
30
 *   data - Post parameters
 
31
 *   cookies - Cookie parameters
 
32
 *   files - Uploaded files
 
33
 *   secure - Connection is secure
 
34
 *   accept - HTTP accept parameters
 
35
 *   proxy_ip - Proxy IP address of the client
 
36
 */
 
37
class Request {
 
38
    /**
 
39
     * @var string URL being requested
 
40
     */
 
41
    public $url;
 
42
 
 
43
    /**
 
44
     * @var string Parent subdirectory of the URL
 
45
     */
 
46
    public $base;
 
47
 
 
48
    /**
 
49
     * @var string Request method (GET, POST, PUT, DELETE)
 
50
     */
 
51
    public $method;
 
52
 
 
53
    /**
 
54
     * @var string Referrer URL
 
55
     */
 
56
    public $referrer;
 
57
 
 
58
    /**
 
59
     * @var string IP address of the client
 
60
     */
 
61
    public $ip;
 
62
 
 
63
    /**
 
64
     * @var bool Whether the request is an AJAX request
 
65
     */
 
66
    public $ajax;
 
67
 
 
68
    /**
 
69
     * @var string Server protocol (http, https)
 
70
     */
 
71
    public $scheme;
 
72
 
 
73
    /**
 
74
     * @var string Browser information
 
75
     */
 
76
    public $user_agent;
 
77
 
 
78
    /**
 
79
     * @var string Content type
 
80
     */
 
81
    public $type;
 
82
 
 
83
    /**
 
84
     * @var int Content length
 
85
     */
 
86
    public $length;
 
87
 
 
88
    /**
 
89
     * @var \flight\util\Collection Query string parameters
 
90
     */
 
91
    public $query;
 
92
 
 
93
    /**
 
94
     * @var \flight\util\Collection Post parameters
 
95
     */
 
96
    public $data;
 
97
 
 
98
    /**
 
99
     * @var \flight\util\Collection Cookie parameters
 
100
     */
 
101
    public $cookies;
 
102
 
 
103
    /**
 
104
     * @var \flight\util\Collection Uploaded files
 
105
     */
 
106
    public $files;
 
107
 
 
108
    /**
 
109
     * @var bool Whether the connection is secure
 
110
     */
 
111
    public $secure;
 
112
 
 
113
    /**
 
114
     * @var string HTTP accept parameters
 
115
     */
 
116
    public $accept;
 
117
 
 
118
    /**
 
119
     * @var string Proxy IP address of the client
 
120
     */
 
121
    public $proxy_ip;
 
122
 
 
123
    /**
 
124
     * Constructor.
 
125
     *
 
126
     * @param array $config Request configuration
 
127
     */
 
128
    public function __construct($config = array()) {
 
129
        // Default properties
 
130
        if (empty($config)) {
 
131
            $config = array(
 
132
                'url' => self::getVar('REQUEST_URI', '/'),
 
133
                'base' => str_replace(array('\\',' '), array('/','%20'), dirname(self::getVar('SCRIPT_NAME'))),
 
134
                'method' => self::getMethod(),
 
135
                'referrer' => self::getVar('HTTP_REFERER'),
 
136
                'ip' => self::getVar('REMOTE_ADDR'),
 
137
                'ajax' => self::getVar('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest',
 
138
                'scheme' => self::getVar('SERVER_PROTOCOL', 'HTTP/1.1'),
 
139
                'user_agent' => self::getVar('HTTP_USER_AGENT'),
 
140
                'type' => self::getVar('CONTENT_TYPE'),
 
141
                'length' => self::getVar('CONTENT_LENGTH', 0),
 
142
                'query' => new Collection($_GET),
 
143
                'data' => new Collection($_POST),
 
144
                'cookies' => new Collection($_COOKIE),
 
145
                'files' => new Collection($_FILES),
 
146
                'secure' => self::getVar('HTTPS', 'off') != 'off',
 
147
                'accept' => self::getVar('HTTP_ACCEPT'),
 
148
                'proxy_ip' => self::getProxyIpAddress()
 
149
            );
 
150
        }
 
151
 
 
152
        $this->init($config);
 
153
    }
 
154
 
 
155
    /**
 
156
     * Initialize request properties.
 
157
     *
 
158
     * @param array $properties Array of request properties
 
159
     */
 
160
    public function init($properties = array()) {
 
161
        // Set all the defined properties
 
162
        foreach ($properties as $name => $value) {
 
163
            $this->$name = $value;
 
164
        }
 
165
 
 
166
        // Get the requested URL without the base directory
 
167
        if ($this->base != '/' && strlen($this->base) > 0 && strpos($this->url, $this->base) === 0) {
 
168
            $this->url = substr($this->url, strlen($this->base));
 
169
        }
 
170
 
 
171
        // Default url
 
172
        if (empty($this->url)) {
 
173
            $this->url = '/';
 
174
        }
 
175
        // Merge URL query parameters with $_GET
 
176
        else {
 
177
            $_GET += self::parseQuery($this->url);
 
178
 
 
179
            $this->query->setData($_GET);
 
180
        }
 
181
 
 
182
        // Check for JSON input
 
183
        if (strpos($this->type, 'application/json') === 0) {
 
184
            $body = $this->getBody();
 
185
            if ($body != '') {
 
186
                $data = json_decode($body, true);
 
187
                if ($data != null) {
 
188
                    $this->data->setData($data);
 
189
                }
 
190
            }
 
191
        }
 
192
    }
 
193
 
 
194
    /**
 
195
     * Gets the body of the request.
 
196
     *
 
197
     * @return string Raw HTTP request body
 
198
     */
 
199
    public static function getBody() {
 
200
        static $body;
 
201
 
 
202
        if (!is_null($body)) {
 
203
            return $body;
 
204
        }
 
205
 
 
206
        $method = self::getMethod();
 
207
 
 
208
        if ($method == 'POST' || $method == 'PUT' || $method == 'PATCH') {
 
209
            $body = file_get_contents('php://input');
 
210
        }
 
211
 
 
212
        return $body;
 
213
    }
 
214
 
 
215
    /**
 
216
     * Gets the request method.
 
217
     *
 
218
     * @return string
 
219
     */
 
220
    public static function getMethod() {
 
221
        $method = self::getVar('REQUEST_METHOD', 'GET');
 
222
 
 
223
        if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
 
224
            $method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'];
 
225
        }
 
226
        elseif (isset($_REQUEST['_method'])) {
 
227
            $method = $_REQUEST['_method'];
 
228
        }
 
229
 
 
230
        return strtoupper($method);
 
231
    }
 
232
 
 
233
    /**
 
234
     * Gets the real remote IP address.
 
235
     *
 
236
     * @return string IP address
 
237
     */
 
238
    public static function getProxyIpAddress() {
 
239
        static $forwarded = array(
 
240
            'HTTP_CLIENT_IP',
 
241
            'HTTP_X_FORWARDED_FOR',
 
242
            'HTTP_X_FORWARDED',
 
243
            'HTTP_X_CLUSTER_CLIENT_IP',
 
244
            'HTTP_FORWARDED_FOR',
 
245
            'HTTP_FORWARDED'
 
246
        );
 
247
 
 
248
        $flags = \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE;
 
249
 
 
250
        foreach ($forwarded as $key) {
 
251
            if (array_key_exists($key, $_SERVER)) {
 
252
                sscanf($_SERVER[$key], '%[^,]', $ip);
 
253
                if (filter_var($ip, \FILTER_VALIDATE_IP, $flags) !== false) {
 
254
                    return $ip;
 
255
                }
 
256
            }
 
257
        }
 
258
 
 
259
        return '';
 
260
    }
 
261
 
 
262
    /**
 
263
     * Gets a variable from $_SERVER using $default if not provided.
 
264
     *
 
265
     * @param string $var Variable name
 
266
     * @param string $default Default value to substitute
 
267
     * @return string Server variable value
 
268
     */
 
269
    public static function getVar($var, $default = '') {
 
270
        return isset($_SERVER[$var]) ? $_SERVER[$var] : $default;
 
271
    }
 
272
 
 
273
    /**
 
274
     * Parse query parameters from a URL.
 
275
     *
 
276
     * @param string $url URL string
 
277
     * @return array Query parameters
 
278
     */
 
279
    public static function parseQuery($url) {
 
280
        $params = array();
 
281
 
 
282
        $args = parse_url($url);
 
283
        if (isset($args['query'])) {
 
284
            parse_str($args['query'], $params);
 
285
        }
 
286
 
 
287
        return $params;
 
288
    }
 
289
}