Go to the documentation of this file.
30 use Wikimedia\IPUtils;
121 $this->requestTime = $_SERVER[
'REQUEST_TIME_FLOAT'];
125 $this->data = $_POST + $_GET;
127 $this->queryAndPathParams = $this->queryParams = $_GET;
153 if ( isset( $_SERVER[
'REQUEST_URI'] ) ) {
155 $url = $_SERVER[
'REQUEST_URI'];
156 if ( !preg_match(
'!^https?://!', $url ) ) {
157 $url =
'http://unused' . $url;
159 $a = parse_url( $url );
163 $path = $a[
'path'] ??
'';
175 $router->
add(
"$wgScript/$1" );
185 if ( $articlePaths ) {
186 $router->add( $articlePaths, [
'action' =>
'$key' ] );
193 [
'variant' =>
'$2' ],
194 [
'$2' => MediaWikiServices::getInstance()->getContentLanguage()->
206 if ( !empty( $_SERVER[
'ORIG_PATH_INFO'] ) ) {
210 $matches[
'title'] = substr( $_SERVER[
'ORIG_PATH_INFO'], 1 );
211 } elseif ( !empty( $_SERVER[
'PATH_INFO'] ) ) {
213 $matches[
'title'] = substr( $_SERVER[
'PATH_INFO'], 1 );
233 $basePath = rtrim( $basePath,
'/' ) .
'/';
235 $qpos = strpos( $requestUrl,
'?' );
236 if ( $qpos !==
false ) {
237 $requestPath = substr( $requestUrl, 0, $qpos );
239 $requestPath = $requestUrl;
241 if ( substr( $requestPath, 0, strlen( $basePath ) ) !== $basePath ) {
244 return rawurldecode( substr( $requestPath, strlen( $basePath ) ) );
257 $stdPort = $proto ===
'https' ? 443 : 80;
259 $varNames = [
'HTTP_HOST',
'SERVER_NAME',
'HOSTNAME',
'SERVER_ADDR' ];
262 foreach ( $varNames as $varName ) {
263 if ( !isset( $_SERVER[$varName] ) ) {
267 $parts = IPUtils::splitHostAndPort( $_SERVER[$varName] );
279 } elseif ( $parts[1] ===
false ) {
280 if ( isset( $_SERVER[
'SERVER_PORT'] ) ) {
281 $port = $_SERVER[
'SERVER_PORT'];
289 return $proto .
'://' . IPUtils::combineHostAndPort( $host, $port, $stdPort );
300 if ( ( !empty( $_SERVER[
'HTTPS'] ) && $_SERVER[
'HTTPS'] !==
'off' ) ||
301 ( isset( $_SERVER[
'HTTP_X_FORWARDED_PROTO'] ) &&
302 $_SERVER[
'HTTP_X_FORWARDED_PROTO'] ===
'https' ) ) {
331 if ( !self::$reqId ) {
361 if ( $this->protocol ===
null ) {
376 if ( defined(
'MW_API' ) ) {
381 foreach (
$matches as $key => $val ) {
382 $this->data[$key] = $this->queryAndPathParams[$key] = $val;
397 foreach ( (array)$bases as $keyValue =>
$base ) {
400 $baseLen = strlen(
$base );
401 if ( substr(
$path, 0, $baseLen ) ==
$base ) {
402 $raw = substr(
$path, $baseLen );
404 $matches = [
'title' => rawurldecode( $raw ) ];
423 if ( is_array(
$data ) ) {
424 foreach (
$data as $key => $val ) {
428 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
443 # PHP is so nice to not touch input data, except sometimes:
444 # https://www.php.net/variables.external#language.variables.external.dot-in-names
445 # Work around PHP *feature* to avoid *bugs* elsewhere.
446 $name = strtr( $name,
'.',
'_' );
448 if ( !isset( $arr[$name] ) ) {
453 # Optimisation: Skip UTF-8 normalization and legacy transcoding for simple ASCII strings.
454 $isAsciiStr = ( is_string(
$data ) && preg_match(
'/[^\x20-\x7E]/',
$data ) === 0 );
455 if ( !$isAsciiStr ) {
456 if ( isset( $_GET[$name] ) && is_string(
$data ) ) {
457 # Check for alternate/legacy character encoding.
458 $data = MediaWikiServices::getInstance()
459 ->getContentLanguage()
460 ->checkTitleEncoding(
$data );
481 $name = strtr( $name,
'.',
'_' );
482 if ( isset( $this->data[$name] ) && !is_array( $this->data[$name] ) ) {
483 $val = $this->data[$name];
487 if ( $val ===
null ) {
504 public function getVal( $name, $default =
null ) {
505 $val = $this->
getGPCVal( $this->data, $name, $default );
506 if ( is_array( $val ) ) {
509 if ( $val ===
null ) {
524 $ret = $this->data[$key] ??
null;
525 $this->data[$key] = $value;
536 if ( !isset( $this->data[$key] ) ) {
539 $ret = $this->data[$key];
540 unset( $this->data[$key] );
554 public function getArray( $name, $default =
null ) {
555 $val = $this->
getGPCVal( $this->data, $name, $default );
556 if ( $val ===
null ) {
574 $val = $this->
getArray( $name, $default );
575 if ( is_array( $val ) ) {
576 $val = array_map(
'intval', $val );
590 public function getInt( $name, $default = 0 ) {
591 return intval( $this->
getRawVal( $name, $default ) );
604 return is_numeric( $val )
619 public function getFloat( $name, $default = 0.0 ) {
620 return floatval( $this->
getRawVal( $name, $default ) );
632 public function getBool( $name, $default =
false ) {
633 return (
bool)$this->
getRawVal( $name, $default );
646 return $this->
getBool( $name, $default )
647 && strcasecmp( $this->
getRawVal( $name ),
'false' ) !== 0;
659 # Checkboxes and buttons are only present when clicked
660 # Presence connotes truth, absence false
661 return $this->
getRawVal( $name,
null ) !==
null;
674 public function getText( $name, $default =
'' ) {
675 $val = $this->
getVal( $name, $default );
676 return str_replace(
"\r\n",
"\n", $val );
687 $names = func_get_args();
688 if ( count( $names ) == 0 ) {
689 $names = array_keys( $this->data );
693 foreach ( $names as $name ) {
694 $value = $this->
getGPCVal( $this->data, $name,
null );
695 if ( $value !==
null ) {
696 $retVal[$name] = $value;
709 return array_diff( array_keys( $this->
getValues() ), $exclude );
756 return $_SERVER[
'QUERY_STRING'];
780 static $input =
null;
781 if ( $input ===
null ) {
782 $input = file_get_contents(
'php://input' );
793 return $_SERVER[
'REQUEST_METHOD'] ??
'GET';
820 if ( $this->sessionId !==
null ) {
821 $session = SessionManager::singleton()->getSessionById( (
string)$this->sessionId,
true, $this );
827 $session = SessionManager::singleton()->getSessionForRequest( $this );
828 $this->sessionId = $session->getSessionId();
860 public function getCookie( $key, $prefix =
null, $default =
null ) {
861 if ( $prefix ===
null ) {
865 $name = $prefix . $key;
867 $name = strtr( $name,
'.',
'_' );
868 if ( isset( $_COOKIE[$name] ) ) {
869 return $_COOKIE[$name];
885 $name = $prefix . $key;
887 $name = strtr( $name,
'.',
'_' );
888 if ( isset( $_COOKIE[$name] ) ) {
889 return $_COOKIE[$name];
892 $legacyName = $prefix .
"ss0-" . $key;
893 $legacyName = strtr( $legacyName,
'.',
'_' );
894 if ( isset( $_COOKIE[$legacyName] ) ) {
895 return $_COOKIE[$legacyName];
911 if ( isset( $_SERVER[
'REQUEST_URI'] ) && strlen( $_SERVER[
'REQUEST_URI'] ) ) {
912 $base = $_SERVER[
'REQUEST_URI'];
913 } elseif ( isset( $_SERVER[
'HTTP_X_ORIGINAL_URL'] )
914 && strlen( $_SERVER[
'HTTP_X_ORIGINAL_URL'] )
917 $base = $_SERVER[
'HTTP_X_ORIGINAL_URL'];
918 } elseif ( isset( $_SERVER[
'SCRIPT_NAME'] ) ) {
919 $base = $_SERVER[
'SCRIPT_NAME'];
920 if ( isset( $_SERVER[
'QUERY_STRING'] ) && $_SERVER[
'QUERY_STRING'] !=
'' ) {
921 $base .=
'?' . $_SERVER[
'QUERY_STRING'];
925 throw new MWException(
"Web server doesn't provide either " .
926 "REQUEST_URI, HTTP_X_ORIGINAL_URL or SCRIPT_NAME. Report details " .
927 "of your web server configuration to https://phabricator.wikimedia.org/" );
933 $hash = strpos(
$base,
'#' );
934 if ( $hash !==
false ) {
938 if (
$base[0] ==
'/' ) {
940 return preg_replace(
'!^/+!',
'/',
$base );
943 return preg_replace(
'!^[^:]+://[^/]+/+!',
'/',
$base );
996 unset( $newquery[
'title'] );
997 $newquery = array_merge( $newquery, $array );
1013 $limit = $this->
getInt(
'limit', 0 );
1017 if ( ( $limit == 0 ) && ( $optionname !=
'' ) ) {
1020 if ( $limit <= 0 ) {
1023 if ( $limit > 5000 ) {
1024 $limit = 5000; # We have *some* limits...
1027 $offset = $this->
getInt(
'offset', 0 );
1028 if ( $offset < 0 ) {
1032 return [ $limit, $offset ];
1043 return $file->getTempName();
1054 return $file->getError();
1070 return $file->getName();
1091 if ( !is_object( $this->
response ) ) {
1092 $class = ( $this instanceof
FauxRequest ) ? FauxResponse::class : WebResponse::class;
1102 if ( count( $this->headers ) ) {
1106 $this->headers = array_change_key_case( getallheaders(), CASE_UPPER );
1133 $name = strtoupper( $name );
1134 if ( !isset( $this->headers[$name] ) ) {
1137 $value = $this->headers[$name];
1138 if ( $flags & self::GETHEADER_LIST ) {
1139 $value = array_map(
'trim', explode(
',', $value ) );
1194 $acceptLang = $this->
getHeader(
'Accept-Language' );
1195 if ( !$acceptLang ) {
1200 $acceptLang = strtolower( $acceptLang );
1203 if ( !preg_match_all(
1205 # a language code or a star is required
1206 ([a-z]{1,8}(?:-[a-z]{1,8})*|\*)
1207 # from here everything is optional
1210 # this accepts only numbers in the range ;q=0.000 to ;q=1.000
1212 (1(?:\.0{0,3})?|0(?:\.\d{0,3})?)?
1225 $languageCode = $match[1];
1227 $qValue = (float)( $match[2] ?? 1.0 );
1229 $langs[$languageCode] = $qValue;
1234 arsort( $langs, SORT_NUMERIC );
1247 if ( !isset( $_SERVER[
'REMOTE_ADDR'] ) ) {
1251 if ( is_array( $_SERVER[
'REMOTE_ADDR'] ) || strpos( $_SERVER[
'REMOTE_ADDR'],
',' ) !==
false ) {
1253 .
" : Could not determine the remote IP address due to multiple values." );
1255 $ipchain = $_SERVER[
'REMOTE_ADDR'];
1258 return IPUtils::canonicalize( $ipchain );
1273 # Return cached result
1274 if ( $this->ip !==
null ) {
1278 # collect the originating ips
1281 throw new MWException(
'Unable to determine IP.' );
1285 $forwardedFor = $this->
getHeader(
'X-Forwarded-For' );
1286 if ( $forwardedFor !==
false ) {
1287 $proxyLookup = MediaWikiServices::getInstance()->getProxyLookup();
1288 $isConfigured = $proxyLookup->isConfiguredProxy(
$ip );
1289 $ipchain = array_map(
'trim', explode(
',', $forwardedFor ) );
1290 $ipchain = array_reverse( $ipchain );
1291 array_unshift( $ipchain,
$ip );
1293 # Step through XFF list and find the last address in the list which is a
1294 # trusted server. Set $ip to the IP address given by that trusted server,
1295 # unless the address is not sensible (e.g. private). However, prefer private
1296 # IP addresses over proxy servers controlled by this site (more sensible).
1297 # Note that some XFF values might be "unknown" with Squid/Varnish.
1298 foreach ( $ipchain as $i => $curIP ) {
1299 $curIP = IPUtils::sanitizeIP( IPUtils::canonicalize( $curIP ) );
1300 if ( !$curIP || !isset( $ipchain[$i + 1] ) || $ipchain[$i + 1] ===
'unknown'
1301 || !$proxyLookup->isTrustedProxy( $curIP )
1306 IPUtils::isPublic( $ipchain[$i + 1] ) ||
1308 $proxyLookup->isConfiguredProxy( $curIP )
1311 $nextIP = IPUtils::canonicalize( $ipchain[$i + 1] );
1312 if ( !$nextIP && $isConfigured ) {
1315 throw new MWException(
"Invalid IP given in XFF '$forwardedFor'." );
1325 # Allow extensions to improve our guess
1329 throw new MWException(
"Unable to determine IP." );
1358 if ( !isset( $_SERVER[
'REQUEST_METHOD'] ) ) {
1362 return in_array( $_SERVER[
'REQUEST_METHOD'], [
'GET',
'HEAD',
'OPTIONS',
'TRACE' ] );
1384 if ( $this->markedAsSafe && $this->
wasPosted() ) {
1402 $this->markedAsSafe =
true;
add( $path, $params=[], $options=[])
Add a new path pattern to the path router.
initHeaders()
Initialise the header list.
SessionId null $sessionId
Session ID to use for this request.
string[] $headers
Lazy-initialized request headers indexed by upper-case header name.
WebRequest clone which takes values from a provided array.
getSessionData( $key)
Get data from the session.
getValueNames( $exclude=[])
Returns the names of all input values excluding those in $exclude.
array $data
The parameters from $_GET, $_POST and the path router.
static getRequestPathSuffix( $basePath)
If the request URL matches a given base path, extract the path part of the request URL after that bas...
getSessionId()
Get the session id for this request, if any.
$wgScript
The URL path to index.php.
getIntOption( $oname, $defaultOverride=0)
Get the user's current setting for a given option, as an integer value.
appendQueryValue( $key, $value)
interpolateTitle()
Check for title, action, and/or variant data in the URL and interpolate it into the GET variables.
setSessionId(SessionId $sessionId)
Set the session for this request.
getAcceptLang()
Parse the Accept-Language header sent by the client into an array.
getElapsedTime()
Get the number of seconds to have elapsed since request start, in fractional seconds,...
getIntOrNull( $name)
Fetch an integer value from the input or return null if empty.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
getRawPostString()
Return the contents of the POST with no decoding.
static detectProtocol()
Detect the protocol from $_SERVER.
getGPCVal( $arr, $name, $default)
Fetch a value from the given array or return $default if it's not set.
bool $wgUseSameSiteLegacyCookies
If true, when a cross-site cookie with SameSite=None is sent, a legacy cookie with an "ss0" prefix wi...
hasSafeMethod()
Check if this request uses a "safe" HTTP method.
string[] $queryAndPathParams
The parameters from $_GET.
getRawQueryString()
Return the contents of the Query with no decoding.
appendQueryArray( $array)
Appends or replaces value of query variables.
$wgAllowExternalReqID
Whether to respect/honour the request ID provided by the incoming request via the X-Request-Id header...
static getActionPaths(array $actionPaths, $articlePath)
getFileTempname( $key)
Return the path to the temporary file where PHP has stored the upload.
bool $wgAssumeProxiesUseDefaultProtocolPorts
When the wiki is running behind a proxy and this is set to true, assumes that the proxy exposes the w...
isSafeRequest()
Whether this request should be identified as being "safe".
getText( $name, $default='')
Fetch a text string from the given array or return $default if it's not set.
string $protocol
Cached URL protocol.
getMethod()
Get the HTTP method used for this request.
getFileName( $key)
Return the original filename of the uploaded file, as reported by the submitting user agent.
getQueryValuesOnly()
Get the values passed in the query string only, not including the path router parameters.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
setVal( $key, $value)
Set an arbitrary value into our get/post data.
static string $reqId
The unique request ID.
getRawInput()
Return the raw request body, with no processing.
getUpload( $key)
Return a WebRequestUpload object corresponding to the key.
string[] $queryParams
The parameters from $_GET only.
getValues()
Extracts the given named values into an array.
static getPathInfo( $want='all')
Extract relevant query arguments from the http request uri's path to be merged with the normal php pr...
getFullRequestURL()
Return the request URI with the canonical service and hostname, path, and query string.
getArray( $name, $default=null)
Fetch an array from the input or return $default if it's not set.
WebResponse $response
Lazy-init response object.
markAsSafeRequest()
Mark this request as identified as being nullipotent even if it is a POST request.
getAllHeaders()
Get an array containing all request headers.
Object to access the $_FILES array.
normalizeUnicode( $data)
Recursively normalizes UTF-8 strings in the given array.
getRawVal( $name, $default=null)
Fetch a scalar from the input without normalization, or return $default if it's not set.
getCheck( $name)
Return true if the named value is set in the input, whatever that value is (even "0").
getProtocol()
Get the current URL protocol (http or https)
getSession()
Return the session for this request.
response()
Return a handle to WebResponse style object, for setting cookies, headers and other stuff,...
$wgUsePrivateIPs
Should forwarded Private IPs be accepted?
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
getCrossSiteCookie( $key, $prefix='', $default=null)
Get a cookie set with SameSite=None possibly with a legacy fallback cookie.
checkUrlExtension( $extWhitelist=[])
This function formerly did a security check to prevent an XSS vulnerability in IE6,...
getIntArray( $name, $default=null)
Fetch an array of integers, or return $default if it's not set.
float $requestTime
The timestamp of the start of the request, with microsecond precision.
static getMain()
Get the RequestContext object associated with the main request.
bool $markedAsSafe
Whether this HTTP request is "safe" (even if it is an HTTP post)
getCookie( $key, $prefix=null, $default=null)
Get a cookie from the $_COOKIE jar.
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
getIP()
Work out the IP address based on various globals For trusted proxies, use the XFF client IP (first of...
getUploadError( $key)
Return the upload error or 0.
$wgArticlePath
The URL path for primary article page views.
setSessionData( $key, $data)
$wgActionPaths
To set 'pretty' URL paths for actions other than plain page views, add to this array.
const GETHEADER_LIST
Flag to make WebRequest::getHeader return an array of values.
getVal( $name, $default=null)
Fetch a scalar from the input or return $default if it's not set.
getInt( $name, $default=0)
Fetch an integer value from the input or return $default if not set.
static getRequestId()
Get the unique request ID.
getLimitOffsetForUser(User $user, $deflimit=50, $optionname='rclimit')
Check for limit and offset parameters on the input, and return sensible defaults if not given.
getFloat( $name, $default=0.0)
Fetch a floating point value from the input or return $default if not set.
static detectServer()
Work out an appropriate URL prefix containing scheme and host, based on information detected from $_S...
getHeader( $name, $flags=0)
Get a request header, or false if it isn't set.
static getGlobalRequestURL()
Return the path and query string portion of the main request URI.
string $ip
Cached client IP address.
getPostValues()
Get the values passed via POST.
wasPosted()
Returns true if the present request was reached by a POST operation, false otherwise (GET,...
unsetVal( $key)
Unset an arbitrary value from our get/post data.
wfGetServerUrl( $proto)
Get the wiki's "server", i.e.
getRequestURL()
Return the path and query string portion of the request URI.
static overrideRequestId( $id)
Override the unique request ID.
static extractTitle( $path, $bases, $key=false)
URL rewriting function; tries to extract page title and, optionally, one other fixed parameter value ...
Allow programs to request this object from WebRequest::response() and handle all outputting (or lack ...
getRawIP()
Fetch the raw IP from the request.
getQueryValues()
Get the values passed in the query string and the path router parameters.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
getFuzzyBool( $name, $default=false)
Fetch a boolean value from the input or return $default if not set.
$wgVariantArticlePath
Like $wgArticlePath, but on multi-variant wikis, this provides a path format that describes which par...
$wgCookiePrefix
Cookies generated by MediaWiki have names starting with this prefix.
getBool( $name, $default=false)
Fetch a boolean value from the input or return $default if not set.
$wgUsePathInfo
Whether to support URLs like index.php/Page_title These often break when PHP is set up in CGI mode.
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
wfRandomString( $length=32)
Get a random string containing a number of pseudo-random hex characters.