xref: /plugin/davcal/vendor/sabre/http/lib/Request.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\HTTP;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse InvalidArgumentException;
6*a1a3b679SAndreas Boehleruse Sabre\Uri;
7*a1a3b679SAndreas Boehler
8*a1a3b679SAndreas Boehler/**
9*a1a3b679SAndreas Boehler * The Request class represents a single HTTP request.
10*a1a3b679SAndreas Boehler *
11*a1a3b679SAndreas Boehler * You can either simply construct the object from scratch, or if you need
12*a1a3b679SAndreas Boehler * access to the current HTTP request, use Sapi::getRequest.
13*a1a3b679SAndreas Boehler *
14*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/).
15*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
16*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
17*a1a3b679SAndreas Boehler */
18*a1a3b679SAndreas Boehlerclass Request extends Message implements RequestInterface {
19*a1a3b679SAndreas Boehler
20*a1a3b679SAndreas Boehler    /**
21*a1a3b679SAndreas Boehler     * HTTP Method
22*a1a3b679SAndreas Boehler     *
23*a1a3b679SAndreas Boehler     * @var string
24*a1a3b679SAndreas Boehler     */
25*a1a3b679SAndreas Boehler    protected $method;
26*a1a3b679SAndreas Boehler
27*a1a3b679SAndreas Boehler    /**
28*a1a3b679SAndreas Boehler     * Request Url
29*a1a3b679SAndreas Boehler     *
30*a1a3b679SAndreas Boehler     * @var string
31*a1a3b679SAndreas Boehler     */
32*a1a3b679SAndreas Boehler    protected $url;
33*a1a3b679SAndreas Boehler
34*a1a3b679SAndreas Boehler    /**
35*a1a3b679SAndreas Boehler     * Creates the request object
36*a1a3b679SAndreas Boehler     *
37*a1a3b679SAndreas Boehler     * @param string $method
38*a1a3b679SAndreas Boehler     * @param string $url
39*a1a3b679SAndreas Boehler     * @param array $headers
40*a1a3b679SAndreas Boehler     * @param resource $body
41*a1a3b679SAndreas Boehler     */
42*a1a3b679SAndreas Boehler    function __construct($method = null, $url = null, array $headers = null, $body = null) {
43*a1a3b679SAndreas Boehler
44*a1a3b679SAndreas Boehler        if (is_array($method)) {
45*a1a3b679SAndreas Boehler            throw new InvalidArgumentException('The first argument for this constructor should be a string or null, not an array. Did you upgrade from sabre/http 1.0 to 2.0?');
46*a1a3b679SAndreas Boehler        }
47*a1a3b679SAndreas Boehler        if (!is_null($method))      $this->setMethod($method);
48*a1a3b679SAndreas Boehler        if (!is_null($url))         $this->setUrl($url);
49*a1a3b679SAndreas Boehler        if (!is_null($headers))     $this->setHeaders($headers);
50*a1a3b679SAndreas Boehler        if (!is_null($body))        $this->setBody($body);
51*a1a3b679SAndreas Boehler
52*a1a3b679SAndreas Boehler    }
53*a1a3b679SAndreas Boehler
54*a1a3b679SAndreas Boehler    /**
55*a1a3b679SAndreas Boehler     * Returns the current HTTP method
56*a1a3b679SAndreas Boehler     *
57*a1a3b679SAndreas Boehler     * @return string
58*a1a3b679SAndreas Boehler     */
59*a1a3b679SAndreas Boehler    function getMethod() {
60*a1a3b679SAndreas Boehler
61*a1a3b679SAndreas Boehler        return $this->method;
62*a1a3b679SAndreas Boehler
63*a1a3b679SAndreas Boehler    }
64*a1a3b679SAndreas Boehler
65*a1a3b679SAndreas Boehler    /**
66*a1a3b679SAndreas Boehler     * Sets the HTTP method
67*a1a3b679SAndreas Boehler     *
68*a1a3b679SAndreas Boehler     * @param string $method
69*a1a3b679SAndreas Boehler     * @return void
70*a1a3b679SAndreas Boehler     */
71*a1a3b679SAndreas Boehler    function setMethod($method) {
72*a1a3b679SAndreas Boehler
73*a1a3b679SAndreas Boehler        $this->method = $method;
74*a1a3b679SAndreas Boehler
75*a1a3b679SAndreas Boehler    }
76*a1a3b679SAndreas Boehler
77*a1a3b679SAndreas Boehler    /**
78*a1a3b679SAndreas Boehler     * Returns the request url.
79*a1a3b679SAndreas Boehler     *
80*a1a3b679SAndreas Boehler     * @return string
81*a1a3b679SAndreas Boehler     */
82*a1a3b679SAndreas Boehler    function getUrl() {
83*a1a3b679SAndreas Boehler
84*a1a3b679SAndreas Boehler        return $this->url;
85*a1a3b679SAndreas Boehler
86*a1a3b679SAndreas Boehler    }
87*a1a3b679SAndreas Boehler
88*a1a3b679SAndreas Boehler    /**
89*a1a3b679SAndreas Boehler     * Sets the request url.
90*a1a3b679SAndreas Boehler     *
91*a1a3b679SAndreas Boehler     * @param string $url
92*a1a3b679SAndreas Boehler     * @return void
93*a1a3b679SAndreas Boehler     */
94*a1a3b679SAndreas Boehler    function setUrl($url) {
95*a1a3b679SAndreas Boehler
96*a1a3b679SAndreas Boehler        $this->url = $url;
97*a1a3b679SAndreas Boehler
98*a1a3b679SAndreas Boehler    }
99*a1a3b679SAndreas Boehler
100*a1a3b679SAndreas Boehler    /**
101*a1a3b679SAndreas Boehler     * Returns the list of query parameters.
102*a1a3b679SAndreas Boehler     *
103*a1a3b679SAndreas Boehler     * This is equivalent to PHP's $_GET superglobal.
104*a1a3b679SAndreas Boehler     *
105*a1a3b679SAndreas Boehler     * @return array
106*a1a3b679SAndreas Boehler     */
107*a1a3b679SAndreas Boehler    function getQueryParameters() {
108*a1a3b679SAndreas Boehler
109*a1a3b679SAndreas Boehler        $url = $this->getUrl();
110*a1a3b679SAndreas Boehler        if (($index = strpos($url, '?')) === false) {
111*a1a3b679SAndreas Boehler            return [];
112*a1a3b679SAndreas Boehler        } else {
113*a1a3b679SAndreas Boehler            parse_str(substr($url, $index + 1), $queryParams);
114*a1a3b679SAndreas Boehler            return $queryParams;
115*a1a3b679SAndreas Boehler        }
116*a1a3b679SAndreas Boehler
117*a1a3b679SAndreas Boehler    }
118*a1a3b679SAndreas Boehler
119*a1a3b679SAndreas Boehler    /**
120*a1a3b679SAndreas Boehler     * Sets the absolute url.
121*a1a3b679SAndreas Boehler     *
122*a1a3b679SAndreas Boehler     * @param string $url
123*a1a3b679SAndreas Boehler     * @return void
124*a1a3b679SAndreas Boehler     */
125*a1a3b679SAndreas Boehler    function setAbsoluteUrl($url) {
126*a1a3b679SAndreas Boehler
127*a1a3b679SAndreas Boehler        $this->absoluteUrl = $url;
128*a1a3b679SAndreas Boehler
129*a1a3b679SAndreas Boehler    }
130*a1a3b679SAndreas Boehler
131*a1a3b679SAndreas Boehler    /**
132*a1a3b679SAndreas Boehler     * Returns the absolute url.
133*a1a3b679SAndreas Boehler     *
134*a1a3b679SAndreas Boehler     * @return string
135*a1a3b679SAndreas Boehler     */
136*a1a3b679SAndreas Boehler    function getAbsoluteUrl() {
137*a1a3b679SAndreas Boehler
138*a1a3b679SAndreas Boehler        return $this->absoluteUrl;
139*a1a3b679SAndreas Boehler
140*a1a3b679SAndreas Boehler    }
141*a1a3b679SAndreas Boehler
142*a1a3b679SAndreas Boehler    /**
143*a1a3b679SAndreas Boehler     * Base url
144*a1a3b679SAndreas Boehler     *
145*a1a3b679SAndreas Boehler     * @var string
146*a1a3b679SAndreas Boehler     */
147*a1a3b679SAndreas Boehler    protected $baseUrl = '/';
148*a1a3b679SAndreas Boehler
149*a1a3b679SAndreas Boehler    /**
150*a1a3b679SAndreas Boehler     * Sets a base url.
151*a1a3b679SAndreas Boehler     *
152*a1a3b679SAndreas Boehler     * This url is used for relative path calculations.
153*a1a3b679SAndreas Boehler     *
154*a1a3b679SAndreas Boehler     * @param string $url
155*a1a3b679SAndreas Boehler     * @return void
156*a1a3b679SAndreas Boehler     */
157*a1a3b679SAndreas Boehler    function setBaseUrl($url) {
158*a1a3b679SAndreas Boehler
159*a1a3b679SAndreas Boehler        $this->baseUrl = $url;
160*a1a3b679SAndreas Boehler
161*a1a3b679SAndreas Boehler    }
162*a1a3b679SAndreas Boehler
163*a1a3b679SAndreas Boehler    /**
164*a1a3b679SAndreas Boehler     * Returns the current base url.
165*a1a3b679SAndreas Boehler     *
166*a1a3b679SAndreas Boehler     * @return string
167*a1a3b679SAndreas Boehler     */
168*a1a3b679SAndreas Boehler    function getBaseUrl() {
169*a1a3b679SAndreas Boehler
170*a1a3b679SAndreas Boehler        return $this->baseUrl;
171*a1a3b679SAndreas Boehler
172*a1a3b679SAndreas Boehler    }
173*a1a3b679SAndreas Boehler
174*a1a3b679SAndreas Boehler    /**
175*a1a3b679SAndreas Boehler     * Returns the relative path.
176*a1a3b679SAndreas Boehler     *
177*a1a3b679SAndreas Boehler     * This is being calculated using the base url. This path will not start
178*a1a3b679SAndreas Boehler     * with a slash, so it will always return something like
179*a1a3b679SAndreas Boehler     * 'example/path.html'.
180*a1a3b679SAndreas Boehler     *
181*a1a3b679SAndreas Boehler     * If the full path is equal to the base url, this method will return an
182*a1a3b679SAndreas Boehler     * empty string.
183*a1a3b679SAndreas Boehler     *
184*a1a3b679SAndreas Boehler     * This method will also urldecode the path, and if the url was incoded as
185*a1a3b679SAndreas Boehler     * ISO-8859-1, it will convert it to UTF-8.
186*a1a3b679SAndreas Boehler     *
187*a1a3b679SAndreas Boehler     * If the path is outside of the base url, a LogicException will be thrown.
188*a1a3b679SAndreas Boehler     *
189*a1a3b679SAndreas Boehler     * @return string
190*a1a3b679SAndreas Boehler     */
191*a1a3b679SAndreas Boehler    function getPath() {
192*a1a3b679SAndreas Boehler
193*a1a3b679SAndreas Boehler        // Removing duplicated slashes.
194*a1a3b679SAndreas Boehler        $uri = str_replace('//', '/', $this->getUrl());
195*a1a3b679SAndreas Boehler
196*a1a3b679SAndreas Boehler        $uri = Uri\normalize($uri);
197*a1a3b679SAndreas Boehler        $baseUri = Uri\normalize($this->getBaseUrl());
198*a1a3b679SAndreas Boehler
199*a1a3b679SAndreas Boehler        if (strpos($uri, $baseUri) === 0) {
200*a1a3b679SAndreas Boehler
201*a1a3b679SAndreas Boehler            // We're not interested in the query part (everything after the ?).
202*a1a3b679SAndreas Boehler            list($uri) = explode('?', $uri);
203*a1a3b679SAndreas Boehler            return trim(URLUtil::decodePath(substr($uri, strlen($baseUri))), '/');
204*a1a3b679SAndreas Boehler
205*a1a3b679SAndreas Boehler        }
206*a1a3b679SAndreas Boehler        // A special case, if the baseUri was accessed without a trailing
207*a1a3b679SAndreas Boehler        // slash, we'll accept it as well.
208*a1a3b679SAndreas Boehler        elseif ($uri . '/' === $baseUri) {
209*a1a3b679SAndreas Boehler
210*a1a3b679SAndreas Boehler            return '';
211*a1a3b679SAndreas Boehler
212*a1a3b679SAndreas Boehler        }
213*a1a3b679SAndreas Boehler
214*a1a3b679SAndreas Boehler        throw new \LogicException('Requested uri (' . $this->getUrl() . ') is out of base uri (' . $this->getBaseUrl() . ')');
215*a1a3b679SAndreas Boehler    }
216*a1a3b679SAndreas Boehler
217*a1a3b679SAndreas Boehler    /**
218*a1a3b679SAndreas Boehler     * Equivalent of PHP's $_POST.
219*a1a3b679SAndreas Boehler     *
220*a1a3b679SAndreas Boehler     * @var array
221*a1a3b679SAndreas Boehler     */
222*a1a3b679SAndreas Boehler    protected $postData = [];
223*a1a3b679SAndreas Boehler
224*a1a3b679SAndreas Boehler    /**
225*a1a3b679SAndreas Boehler     * Sets the post data.
226*a1a3b679SAndreas Boehler     *
227*a1a3b679SAndreas Boehler     * This is equivalent to PHP's $_POST superglobal.
228*a1a3b679SAndreas Boehler     *
229*a1a3b679SAndreas Boehler     * This would not have been needed, if POST data was accessible as
230*a1a3b679SAndreas Boehler     * php://input, but unfortunately we need to special case it.
231*a1a3b679SAndreas Boehler     *
232*a1a3b679SAndreas Boehler     * @param array $postData
233*a1a3b679SAndreas Boehler     * @return void
234*a1a3b679SAndreas Boehler     */
235*a1a3b679SAndreas Boehler    function setPostData(array $postData) {
236*a1a3b679SAndreas Boehler
237*a1a3b679SAndreas Boehler        $this->postData = $postData;
238*a1a3b679SAndreas Boehler
239*a1a3b679SAndreas Boehler    }
240*a1a3b679SAndreas Boehler
241*a1a3b679SAndreas Boehler    /**
242*a1a3b679SAndreas Boehler     * Returns the POST data.
243*a1a3b679SAndreas Boehler     *
244*a1a3b679SAndreas Boehler     * This is equivalent to PHP's $_POST superglobal.
245*a1a3b679SAndreas Boehler     *
246*a1a3b679SAndreas Boehler     * @return array
247*a1a3b679SAndreas Boehler     */
248*a1a3b679SAndreas Boehler    function getPostData() {
249*a1a3b679SAndreas Boehler
250*a1a3b679SAndreas Boehler        return $this->postData;
251*a1a3b679SAndreas Boehler
252*a1a3b679SAndreas Boehler    }
253*a1a3b679SAndreas Boehler
254*a1a3b679SAndreas Boehler    /**
255*a1a3b679SAndreas Boehler     * An array containing the raw _SERVER array.
256*a1a3b679SAndreas Boehler     *
257*a1a3b679SAndreas Boehler     * @var array
258*a1a3b679SAndreas Boehler     */
259*a1a3b679SAndreas Boehler    protected $rawServerData;
260*a1a3b679SAndreas Boehler
261*a1a3b679SAndreas Boehler    /**
262*a1a3b679SAndreas Boehler     * Returns an item from the _SERVER array.
263*a1a3b679SAndreas Boehler     *
264*a1a3b679SAndreas Boehler     * If the value does not exist in the array, null is returned.
265*a1a3b679SAndreas Boehler     *
266*a1a3b679SAndreas Boehler     * @param string $valueName
267*a1a3b679SAndreas Boehler     * @return string|null
268*a1a3b679SAndreas Boehler     */
269*a1a3b679SAndreas Boehler    function getRawServerValue($valueName) {
270*a1a3b679SAndreas Boehler
271*a1a3b679SAndreas Boehler        if (isset($this->rawServerData[$valueName])) {
272*a1a3b679SAndreas Boehler            return $this->rawServerData[$valueName];
273*a1a3b679SAndreas Boehler        }
274*a1a3b679SAndreas Boehler
275*a1a3b679SAndreas Boehler    }
276*a1a3b679SAndreas Boehler
277*a1a3b679SAndreas Boehler    /**
278*a1a3b679SAndreas Boehler     * Sets the _SERVER array.
279*a1a3b679SAndreas Boehler     *
280*a1a3b679SAndreas Boehler     * @param array $data
281*a1a3b679SAndreas Boehler     * @return void
282*a1a3b679SAndreas Boehler     */
283*a1a3b679SAndreas Boehler    function setRawServerData(array $data) {
284*a1a3b679SAndreas Boehler
285*a1a3b679SAndreas Boehler        $this->rawServerData = $data;
286*a1a3b679SAndreas Boehler
287*a1a3b679SAndreas Boehler    }
288*a1a3b679SAndreas Boehler
289*a1a3b679SAndreas Boehler    /**
290*a1a3b679SAndreas Boehler     * Serializes the request object as a string.
291*a1a3b679SAndreas Boehler     *
292*a1a3b679SAndreas Boehler     * This is useful for debugging purposes.
293*a1a3b679SAndreas Boehler     *
294*a1a3b679SAndreas Boehler     * @return string
295*a1a3b679SAndreas Boehler     */
296*a1a3b679SAndreas Boehler    function __toString() {
297*a1a3b679SAndreas Boehler
298*a1a3b679SAndreas Boehler        $out = $this->getMethod() . ' ' . $this->getUrl() . ' HTTP/' . $this->getHTTPVersion() . "\r\n";
299*a1a3b679SAndreas Boehler
300*a1a3b679SAndreas Boehler        foreach ($this->getHeaders() as $key => $value) {
301*a1a3b679SAndreas Boehler            foreach ($value as $v) {
302*a1a3b679SAndreas Boehler                if ($key === 'Authorization') {
303*a1a3b679SAndreas Boehler                    list($v) = explode(' ', $v, 2);
304*a1a3b679SAndreas Boehler                    $v  .= ' REDACTED';
305*a1a3b679SAndreas Boehler                }
306*a1a3b679SAndreas Boehler                $out .= $key . ": " . $v . "\r\n";
307*a1a3b679SAndreas Boehler            }
308*a1a3b679SAndreas Boehler        }
309*a1a3b679SAndreas Boehler        $out .= "\r\n";
310*a1a3b679SAndreas Boehler        $out .= $this->getBodyAsString();
311*a1a3b679SAndreas Boehler
312*a1a3b679SAndreas Boehler        return $out;
313*a1a3b679SAndreas Boehler
314*a1a3b679SAndreas Boehler    }
315*a1a3b679SAndreas Boehler
316*a1a3b679SAndreas Boehler}
317