Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
68.92% covered (warning)
68.92%
51 / 74
70.37% covered (warning)
70.37%
19 / 27
CRAP
0.00% covered (danger)
0.00%
0 / 1
FauxRequest
69.86% covered (warning)
69.86%
51 / 73
70.37% covered (warning)
70.37%
19 / 27
107.46
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
5
 response
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 initHeaders
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getQueryValues
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getQueryValuesOnly
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getMethod
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 wasPosted
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCookie
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 setCookie
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCookies
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 setUploadData
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 setUpload
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
 getUpload
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRequestURL
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 hasRequestURL
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getServerInfo
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setServerInfo
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRequestURL
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getProtocol
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setHeader
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setHeaders
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getSessionArray
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getPostValues
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 getRawQueryString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRawPostString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRawInput
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRawIP
n/a
0 / 0
n/a
0 / 0
1
1<?php
2/**
3 * Deal with importing all those nasty globals and things
4 *
5 * Copyright © 2003 Brooke Vibber <bvibber@wikimedia.org>
6 * https://www.mediawiki.org/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * http://www.gnu.org/copyleft/gpl.html
22 *
23 * @file
24 */
25
26namespace MediaWiki\Request;
27
28use InvalidArgumentException;
29use MediaWiki;
30use MediaWiki\MainConfigNames;
31use MediaWiki\MediaWikiServices;
32use MediaWiki\Session\SessionManager;
33use MWException;
34
35/**
36 * WebRequest clone which takes values from a provided array.
37 *
38 * @newable
39 *
40 * @ingroup HTTP
41 */
42class FauxRequest extends WebRequest {
43    private bool $wasPosted;
44    private ?string $requestUrl = null;
45    private array $serverInfo;
46
47    protected array $cookies = [];
48    private array $uploadData = [];
49
50    /**
51     * @stable to call
52     *
53     * @param array $data Array of *non*-urlencoded key => value pairs, the
54     *   fake GET/POST values
55     * @param bool $wasPosted Whether to treat the data as POST
56     * @param MediaWiki\Session\Session|array|null $session Session, session
57     *  data array, or null
58     * @param string $protocol 'http' or 'https'
59     */
60    public function __construct( array $data = [], $wasPosted = false,
61                                $session = null, $protocol = 'http'
62    ) {
63        $this->requestTime = microtime( true );
64        $this->serverInfo = $_SERVER;
65
66        $this->data = $data;
67        $this->wasPosted = $wasPosted;
68        if ( $session instanceof MediaWiki\Session\Session ) {
69            $this->sessionId = $session->getSessionId();
70        } elseif ( is_array( $session ) ) {
71            $mwsession = SessionManager::singleton()->getEmptySession( $this );
72            $this->sessionId = $mwsession->getSessionId();
73            foreach ( $session as $key => $value ) {
74                $mwsession->set( $key, $value );
75            }
76        } elseif ( $session !== null ) {
77            throw new InvalidArgumentException( "MediaWiki\Request\FauxRequest() got bogus session" );
78        }
79        $this->protocol = $protocol;
80    }
81
82    public function response(): FauxResponse {
83        /* Lazy initialization of response object for this request */
84        if ( !$this->response ) {
85            $this->response = new FauxResponse();
86        }
87        return $this->response;
88    }
89
90    /**
91     * Initialise the header list
92     */
93    protected function initHeaders() {
94        // Nothing to init
95    }
96
97    /**
98     * @param string $name
99     * @param string $default
100     * @return string
101     */
102    public function getText( $name, $default = '' ) {
103        # Override; don't recode since we're using internal data
104        return (string)$this->getVal( $name, $default );
105    }
106
107    /**
108     * @return array
109     */
110    public function getQueryValues() {
111        if ( $this->wasPosted ) {
112            return [];
113        } else {
114            return $this->data;
115        }
116    }
117
118    public function getQueryValuesOnly() {
119        return $this->getQueryValues();
120    }
121
122    public function getMethod() {
123        return $this->wasPosted ? 'POST' : 'GET';
124    }
125
126    /**
127     * @return bool
128     */
129    public function wasPosted() {
130        return $this->wasPosted;
131    }
132
133    public function getCookie( $key, $prefix = null, $default = null ) {
134        if ( $prefix === null ) {
135            $cookiePrefix = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::CookiePrefix );
136            $prefix = $cookiePrefix;
137        }
138        $name = $prefix . $key;
139        return $this->cookies[$name] ?? $default;
140    }
141
142    /**
143     * @param string $key Unprefixed name of the cookie to set
144     * @param string|null $value Value of the cookie to set
145     * @param string|null $prefix Cookie prefix. Defaults to $wgCookiePrefix
146     * @since 1.26
147     */
148    public function setCookie( $key, $value, $prefix = null ) {
149        $this->setCookies( [ $key => $value ], $prefix );
150    }
151
152    /**
153     * @param array $cookies
154     * @param string|null $prefix Cookie prefix. Defaults to $wgCookiePrefix
155     * @since 1.26
156     */
157    public function setCookies( $cookies, $prefix = null ) {
158        if ( $prefix === null ) {
159            $cookiePrefix = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::CookiePrefix );
160            $prefix = $cookiePrefix;
161        }
162        foreach ( $cookies as $key => $value ) {
163            $name = $prefix . $key;
164            $this->cookies[$name] = $value;
165        }
166    }
167
168    /**
169     * Set fake upload data for all files
170     *
171     * @param (array|WebRequestUpload)[] $uploadData
172     * @since 1.37
173     */
174    public function setUploadData( $uploadData ) {
175        foreach ( $uploadData as $key => $data ) {
176            $this->setUpload( $key, $data );
177        }
178    }
179
180    /**
181     * Set fake upload data for one file with specific key
182     *
183     * @param string $key
184     * @param array|WebRequestUpload $data
185     * @since 1.37
186     */
187    public function setUpload( $key, $data ) {
188        if ( $data instanceof WebRequestUpload ) {
189            // cannot reuse MediaWiki\Request\WebRequestUpload, because it contains the original web request object
190            $data = [
191                'name' => $data->getName(),
192                'type' => $data->getType(),
193                'tmp_name' => $data->getTempName(),
194                'size' => $data->getSize(),
195                'error' => $data->getError(),
196            ];
197        }
198        // Check if everything is provided
199        if ( !is_array( $data ) ||
200            array_diff( WebRequestUpload::REQUIRED_FILEINFO_KEYS, array_keys( $data ) ) !== []
201        ) {
202            throw new InvalidArgumentException( __METHOD__ . ' got bogus data' );
203        }
204        $this->uploadData[$key] = $data;
205    }
206
207    /**
208     * Return a MediaWiki\Request\FauxRequestUpload object corresponding to the key
209     *
210     * @param string $key
211     * @return FauxRequestUpload
212     */
213    public function getUpload( $key ) {
214        return new FauxRequestUpload( $this->uploadData, $this, $key );
215    }
216
217    /**
218     * @param string $url
219     *
220     * @since 1.25
221     */
222    public function setRequestURL( string $url ) {
223        $this->requestUrl = $url;
224
225        if ( preg_match( '@^(.*)://@', $url, $m ) ) {
226            $this->protocol = $m[1];
227        }
228    }
229
230    /**
231     * @since 1.42
232     * @return bool
233     */
234    public function hasRequestURL(): bool {
235        return $this->requestUrl !== null;
236    }
237
238    protected function getServerInfo( $name, $default = null ): ?string {
239        return $this->serverInfo[$name] ?? $default;
240    }
241
242    /**
243     * @see $_SERVER
244     * @param array $info
245     */
246    public function setServerInfo( array $info ) {
247        $this->serverInfo = $info;
248    }
249
250    /**
251     * @return string
252     */
253    public function getRequestURL() {
254        if ( $this->requestUrl === null ) {
255            throw new MWException( 'Request URL not set' );
256        }
257        return $this->requestUrl;
258    }
259
260    public function getProtocol() {
261        return $this->protocol;
262    }
263
264    /**
265     * @param string $name
266     * @param string $val
267     */
268    public function setHeader( $name, $val ) {
269        $this->setHeaders( [ $name => $val ] );
270    }
271
272    /**
273     * @param array $headers
274     * @since 1.26
275     */
276    public function setHeaders( $headers ) {
277        foreach ( $headers as $name => $val ) {
278            $name = strtoupper( $name );
279            $this->headers[$name] = $val;
280        }
281    }
282
283    /**
284     * @return array|null
285     */
286    public function getSessionArray() {
287        if ( $this->sessionId !== null ) {
288            return iterator_to_array( $this->getSession() );
289        }
290        return null;
291    }
292
293    public function getPostValues() {
294        return $this->wasPosted ? $this->data : [];
295    }
296
297    /**
298     * FauxRequests shouldn't depend on raw request data (but that could be implemented here)
299     * @return string
300     */
301    public function getRawQueryString() {
302        return '';
303    }
304
305    /**
306     * FauxRequests shouldn't depend on raw request data (but that could be implemented here)
307     * @return string
308     */
309    public function getRawPostString() {
310        return '';
311    }
312
313    /**
314     * FauxRequests shouldn't depend on raw request data (but that could be implemented here)
315     * @return string
316     */
317    public function getRawInput() {
318        return '';
319    }
320
321    /**
322     * @codeCoverageIgnore
323     * @return string
324     */
325    protected function getRawIP() {
326        return '127.0.0.1';
327    }
328}
329
330/** @deprecated class alias since 1.40 */
331class_alias( FauxRequest::class, 'FauxRequest' );