Go to the documentation of this file.
91 $this->requestTime = $_SERVER[
'REQUEST_TIME_FLOAT'];
95 $this->
data = $_POST + $_GET;
119 if ( !empty( $_SERVER[
'REQUEST_URI'] ) ) {
121 $url = $_SERVER[
'REQUEST_URI'];
122 if ( !preg_match(
'!^https?://!', $url ) ) {
123 $url =
'http://unused' . $url;
125 Wikimedia\suppressWarnings();
126 $a = parse_url( $url );
127 Wikimedia\restoreWarnings();
129 $path = isset( $a[
'path'] ) ? $a[
'path'] :
'';
141 $router->
add(
"$wgScript/$1" );
143 if ( isset( $_SERVER[
'SCRIPT_NAME'] )
144 && preg_match(
'/\.php/', $_SERVER[
'SCRIPT_NAME'] )
146 # Check for SCRIPT_NAME, we handle index.php explicitly
147 # But we do have some other .php files such as img_auth.php
148 # Don't let root article paths clober the parsing for them
149 $router->add( $_SERVER[
'SCRIPT_NAME'] .
"/$1" );
165 [
'variant' =>
'$2' ],
170 Hooks::run(
'WebRequestPathInfoRouter', [ $router ] );
175 if ( isset( $_SERVER[
'ORIG_PATH_INFO'] ) && $_SERVER[
'ORIG_PATH_INFO'] !=
'' ) {
179 $matches[
'title'] = substr( $_SERVER[
'ORIG_PATH_INFO'], 1 );
181 } elseif ( isset( $_SERVER[
'PATH_INFO'] ) && $_SERVER[
'PATH_INFO'] !=
'' ) {
183 $matches[
'title'] = substr( $_SERVER[
'PATH_INFO'], 1 );
200 $stdPort = $proto ===
'https' ? 443 : 80;
202 $varNames = [
'HTTP_HOST',
'SERVER_NAME',
'HOSTNAME',
'SERVER_ADDR' ];
205 foreach ( $varNames
as $varName ) {
206 if ( !isset( $_SERVER[$varName] ) ) {
222 } elseif ( $parts[1] ===
false ) {
223 if ( isset( $_SERVER[
'SERVER_PORT'] ) ) {
224 $port = $_SERVER[
'SERVER_PORT'];
243 if ( ( !empty( $_SERVER[
'HTTPS'] ) && $_SERVER[
'HTTPS'] !==
'off' ) ||
244 ( isset( $_SERVER[
'HTTP_X_FORWARDED_PROTO'] ) &&
245 $_SERVER[
'HTTP_X_FORWARDED_PROTO'] ===
'https' ) ) {
274 if ( !self::$reqId ) {
275 self::$reqId = isset( $_SERVER[
'UNIQUE_ID'] )
298 if ( $this->protocol ===
null ) {
313 if ( defined(
'MW_API' ) ) {
319 $this->
data[$key] = $_GET[$key] = $_REQUEST[$key] = $val;
337 $baseLen = strlen(
$base );
338 if ( substr(
$path, 0, $baseLen ) ==
$base ) {
339 $raw = substr(
$path, $baseLen );
341 $matches = [
'title' => rawurldecode( $raw ) ];
360 if ( is_array(
$data ) ) {
361 foreach (
$data as $key => $val ) {
368 UtfNormal\Validator::cleanUp(
$data );
382 # PHP is so nice to not touch input data, except sometimes:
383 # https://secure.php.net/variables.external#language.variables.external.dot-in-names
384 # Work around PHP *feature* to avoid *bugs* elsewhere.
386 if ( isset( $arr[
$name] ) ) {
389 if ( isset( $_GET[
$name] ) && !is_array(
$data ) ) {
390 # Check for alternate/legacy character encoding.
416 if ( isset( $this->
data[
$name] ) && !is_array( $this->
data[$name] ) ) {
421 if ( is_null( $val ) ) {
440 if ( is_array( $val ) ) {
443 if ( is_null( $val ) ) {
458 $ret = isset( $this->
data[$key] ) ? $this->
data[$key] :
null;
470 if ( !isset( $this->
data[$key] ) ) {
474 unset( $this->
data[$key] );
490 if ( is_null( $val ) ) {
509 if ( is_array( $val ) ) {
510 $val = array_map(
'intval', $val );
538 return is_numeric( $val )
593 # Checkboxes and buttons are only present when clicked
594 # Presence connotes truth, absence false
610 return str_replace(
"\r\n",
"\n", $val );
621 $names = func_get_args();
622 if (
count( $names ) == 0 ) {
623 $names = array_keys( $this->
data );
629 if ( !is_null(
$value ) ) {
643 return array_diff( array_keys( $this->
getValues() ), $exclude );
665 return $_SERVER[
'QUERY_STRING'];
691 $input = file_get_contents(
'php://input' );
702 return isset( $_SERVER[
'REQUEST_METHOD'] ) ? $_SERVER[
'REQUEST_METHOD'] :
'GET';
729 if ( $this->sessionId !==
null ) {
730 $session = SessionManager::singleton()->getSessionById( (
string)$this->sessionId,
true, $this );
736 $session = SessionManager::singleton()->getSessionForRequest( $this );
737 $this->sessionId = $session->getSessionId();
769 public function getCookie( $key, $prefix =
null, $default =
null ) {
770 if ( $prefix ===
null ) {
774 return $this->
getGPCVal( $_COOKIE, $prefix . $key, $default );
787 if ( isset( $_SERVER[
'REQUEST_URI'] ) && strlen( $_SERVER[
'REQUEST_URI'] ) ) {
788 $base = $_SERVER[
'REQUEST_URI'];
789 } elseif ( isset( $_SERVER[
'HTTP_X_ORIGINAL_URL'] )
790 && strlen( $_SERVER[
'HTTP_X_ORIGINAL_URL'] )
793 $base = $_SERVER[
'HTTP_X_ORIGINAL_URL'];
794 } elseif ( isset( $_SERVER[
'SCRIPT_NAME'] ) ) {
795 $base = $_SERVER[
'SCRIPT_NAME'];
796 if ( isset( $_SERVER[
'QUERY_STRING'] ) && $_SERVER[
'QUERY_STRING'] !=
'' ) {
797 $base .=
'?' . $_SERVER[
'QUERY_STRING'];
801 throw new MWException(
"Web server doesn't provide either " .
802 "REQUEST_URI, HTTP_X_ORIGINAL_URL or SCRIPT_NAME. Report details " .
803 "of your web server configuration to https://phabricator.wikimedia.org/" );
809 $hash = strpos(
$base,
'#' );
810 if ( $hash !==
false ) {
814 if (
$base[0] ==
'/' ) {
816 return preg_replace(
'!^/+!',
'/',
$base );
819 return preg_replace(
'!^[^:]+://[^/]+/+!',
'/',
$base );
865 unset( $newquery[
'title'] );
866 $newquery = array_merge( $newquery, $array );
883 $limit = $this->
getInt(
'limit', 0 );
887 if ( ( $limit == 0 ) && ( $optionname !=
'' ) ) {
888 $limit =
$wgUser->getIntOption( $optionname );
893 if ( $limit > 5000 ) {
894 $limit = 5000; # We have *
some* limits...
897 $offset = $this->
getInt(
'offset', 0 );
902 return [ $limit, $offset ];
913 return $file->getTempName();
924 return $file->getError();
940 return $file->getName();
961 if ( !is_object( $this->
response ) ) {
976 $apacheHeaders = function_exists(
'apache_request_headers' ) ? apache_request_headers() :
false;
977 if ( $apacheHeaders ) {
978 foreach ( $apacheHeaders
as $tempName => $tempValue ) {
979 $this->
headers[strtoupper( $tempName )] = $tempValue;
983 if ( substr(
$name, 0, 5 ) ===
'HTTP_' ) {
984 $name = str_replace(
'_',
'-', substr(
$name, 5 ) );
986 } elseif (
$name ===
'CONTENT_LENGTH' ) {
1022 if ( $flags & self::GETHEADER_LIST ) {
1061 $extWhitelist[] =
'php';
1066 if ( $newUrl !==
false ) {
1072 'Invalid file extension found in the path info or query string.' );
1085 header(
'Location: ' . $url );
1086 header(
'Content-Type: text/html' );
1087 $encUrl = htmlspecialchars( $url );
1097 We can
't serve non-HTML content from the URL you have requested, because
1098 Internet Explorer would interpret it as an incorrect and potentially dangerous
1100 <p>Instead, please use <a href="$encUrl">this URL</a>, which is the same as the
1101 URL you have requested, except that "&*" is appended. This prevents Internet
1102 Explorer from seeing a bogus file extension.
1120 public function getAcceptLang() {
1121 // Modified version of code found at
1122 // http://www.thefutureoftheweb.com/blog/use-accept-language-header
1123 $acceptLang = $this->getHeader( 'Accept-
Language' );
1124 if ( !$acceptLang ) {
1128 // Return the language codes in lower case
1129 $acceptLang = strtolower( $acceptLang );
1131 // Break up string into pieces (languages and q factors)
1134 '/([
a-z]{1,8}(-[
a-z]{1,8})*|\*)\s*(;\s*q\s*=\s*(1(\.0{0,3})?|0(\.[0-9]{0,3})?)?)?/
',
1139 if ( !count( $lang_parse[1] ) ) {
1143 $langcodes = $lang_parse[1];
1144 $qvalues = $lang_parse[4];
1145 $indices = range( 0, count( $lang_parse[1] ) - 1 );
1147 // Set default q factor to 1
1148 foreach ( $indices as $index ) {
1149 if ( $qvalues[$index] === '' ) {
1150 $qvalues[$index] = 1;
1151 } elseif ( $qvalues[$index] == 0 ) {
1152 unset( $langcodes[$index], $qvalues[$index], $indices[$index] );
1156 // Sort list. First by $qvalues, then by order. Reorder $langcodes the same way
1157 array_multisort( $qvalues, SORT_DESC, SORT_NUMERIC, $indices, $langcodes );
1159 // Create a list like "en" => 0.8
1160 $langs = array_combine( $langcodes, $qvalues );
1173 protected function getRawIP() {
1174 if ( !isset( $_SERVER['REMOTE_ADDR
'] ) ) {
1178 if ( is_array( $_SERVER['REMOTE_ADDR
'] ) || strpos( $_SERVER['REMOTE_ADDR
'], ',
' ) !== false ) {
1179 throw new MWException( __METHOD__
1180 . " : Could not determine the remote IP address due to multiple values." );
1182 $ipchain = $_SERVER['REMOTE_ADDR
'];
1185 return IP::canonicalize( $ipchain );
1197 public function getIP() {
1198 global $wgUsePrivateIPs;
1200 # Return cached result
1201 if ( $this->ip !== null ) {
1205 # collect the originating ips
1206 $ip = $this->getRawIP();
1208 throw new MWException( 'Unable to determine
IP.
' );
1212 $forwardedFor = $this->getHeader( 'X-Forwarded-For
' );
1213 if ( $forwardedFor !== false ) {
1214 $proxyLookup = MediaWikiServices::getInstance()->getProxyLookup();
1215 $isConfigured = $proxyLookup->isConfiguredProxy( $ip );
1216 $ipchain = array_map( 'trim
', explode( ',
', $forwardedFor ) );
1217 $ipchain = array_reverse( $ipchain );
1218 array_unshift( $ipchain, $ip );
1220 # Step through XFF list and find the last address in the list which is a
1221 # trusted server. Set $ip to the IP address given by that trusted server,
1222 # unless the address is not sensible (e.g. private). However, prefer private
1223 # IP addresses over proxy servers controlled by this site (more sensible).
1224 # Note that some XFF values might be "unknown" with Squid/Varnish.
1225 foreach ( $ipchain as $i => $curIP ) {
1226 $curIP = IP::sanitizeIP( IP::canonicalize( $curIP ) );
1227 if ( !$curIP || !isset( $ipchain[$i + 1] ) || $ipchain[$i + 1] === 'unknown
'
1228 || !$proxyLookup->isTrustedProxy( $curIP )
1230 break; // IP is not valid/trusted or does not point to anything
1233 IP::isPublic( $ipchain[$i + 1] ) ||
1235 $proxyLookup->isConfiguredProxy( $curIP ) // T50919; treat IP as sane
1237 // Follow the next IP according to the proxy
1238 $nextIP = IP::canonicalize( $ipchain[$i + 1] );
1239 if ( !$nextIP && $isConfigured ) {
1240 // We have not yet made it past CDN/proxy servers of this site,
1241 // so either they are misconfigured or there is some IP spoofing.
1242 throw new MWException( "Invalid IP given in XFF '$forwardedFor
'." );
1245 // keep traversing the chain
1252 # Allow extensions to improve our guess
1253 Hooks::run( 'GetIP
', [ &$ip ] );
1256 throw new MWException( "Unable to determine IP." );
1259 wfDebug( "IP: $ip\n" );
1269 public function setIP( $ip ) {
1285 public function hasSafeMethod() {
1286 if ( !isset( $_SERVER['REQUEST_METHOD
'] ) ) {
1287 return false; // CLI mode
1290 return in_array( $_SERVER['REQUEST_METHOD
'], [ 'GET
', 'HEAD
', 'OPTIONS
', 'TRACE
' ] );
1311 public function isSafeRequest() {
1312 if ( $this->markedAsSafe && $this->wasPosted() ) {
1313 return true; // marked as a "safe" POST
1316 return $this->hasSafeMethod();
1329 public function markAsSafeRequest() {
1330 $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.
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.
static combineHostAndPort( $host, $port, $defaultPort=false)
Given a host name and a port, combine them into host/port string like you might find in a URL.
getSessionId()
Get the session id for this request, if any.
$wgScript
The URL path to index.php.
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.
getElapsedTime()
Get the number of seconds to have elapsed since request start, in fractional seconds,...
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
getIntOrNull( $name)
Fetch an integer value from the input or return null if empty.
A collection of public static functions to play with IP address and IP ranges.
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.
</source > ! result< div class="mw-highlight mw-content-ltr" dir="ltr">< pre >< span ></span >< span class="kd"> var</span >< span class="nx"> a</span >< span class="p"></span ></pre ></div > ! end ! test Multiline< source/> in lists !input *< source > a b</source > *foo< source > a b</source > ! html< ul >< li >< div class="mw-highlight mw-content-ltr" dir="ltr">< pre > a b</pre ></div ></li ></ul >< ul >< li > foo< div class="mw-highlight mw-content-ltr" dir="ltr">< pre > a b</pre ></div ></li ></ul > ! html tidy< ul >< li >< div class="mw-highlight mw-content-ltr" dir="ltr">< pre > a b</pre ></div ></li ></ul >< ul >< li > foo< div class="mw-highlight mw-content-ltr" dir="ltr">< pre > a b</pre ></div ></li ></ul > ! end ! test Custom attributes !input< source lang="javascript" id="foo" class="bar" dir="rtl" style="font-size: larger;"> var a
Allows to change the fields on the form that will be generated $name
Show an error that looks like an HTTP server error.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
getRawQueryString()
Return the contents of the Query with no decoding.
appendQueryArray( $array)
Appends or replaces value of query variables.
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...
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.
setVal( $key, $value)
Set an arbitrary value into our get/post data.
if(is_array( $mode)) switch( $mode) $input
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.
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.
getAllHeaders()
Get an array containing all request headers.
when a variable name is used in a it is silently declared as a new masking the global
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.
static areServerVarsBad( $vars, $extWhitelist=[])
Check a subset of $_SERVER (or the whole of $_SERVER if you like) to see if it indicates that the req...
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,...
static splitHostAndPort( $both)
Given a host/port string, like one might find in the host part of a URL per RFC 2732,...
I won t presume to tell you how to I m just describing the methods I chose to use for myself If you do choose to follow these it will probably be easier for you to collaborate with others on the but if you want to contribute without by all means do which work well I also use K &R brace matching style I know that s a religious issue for some
getLimitOffset( $deflimit=50, $optionname='rclimit')
Check for limit and offset parameters on the input, and return sensible defaults if not given.
checkUrlExtension( $extWhitelist=[])
Check if Internet Explorer will detect an incorrect cache extension in PATH_INFO or QUERY_STRING.
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.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
static fixUrlForIE6( $url, $extWhitelist=[])
Returns a variant of $url which will pass isUrlExtensionBad() but has the same GET parameters,...
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...
getUploadError( $key)
Return the upload error or 0.
setSessionData( $key, $data)
Set session data.
doSecurityRedirect( $url)
Attempt to redirect to a URL with a QUERY_STRING that's not dangerous in IE 6.
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.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
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.
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
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.
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 ...
getQueryValues()
Get the values passed in the query string.
getFuzzyBool( $name, $default=false)
Fetch a boolean value from the input or return $default if not set.
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
$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.
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add headers
This list may contain false positives That usually means there is additional text with links below the first Each row contains links to the first and second redirect
Internationalisation code.
and how to run hooks for an and one after Each event has a preferably in CamelCase For ArticleDelete hook A clump of code and data that should be run when an event happens This can be either a function and a chunk of data
getBool( $name, $default=false)
Fetch a boolean value from the input or return $default if not set.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
the array() calling protocol came about after MediaWiki 1.4rc1.
$wgUsePathInfo
Whether to support URLs like index.php/Page_title These often break when PHP is set up in CGI mode.
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
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.