MediaWiki master
ApiEntryPoint.php
Go to the documentation of this file.
1<?php
28namespace MediaWiki\Api;
29
30use ApiMain;
31use LogicException;
40use Throwable;
41
54
55 public function __construct(
56 RequestContext $context,
58 MediaWikiServices $services
59 ) {
60 parent::__construct(
61 $context,
63 $services
64 );
65 }
66
71 protected function getContext(): RequestContext {
73 $context = parent::getContext();
74
75 // @phan-suppress-next-line PhanTypeMismatchReturnSuperType see $context in the constructor
76 return $context;
77 }
78
87 protected function execute() {
88 global $wgTitle;
89
90 $context = $this->getContext();
91 $request = $this->getRequest();
92 $apiRequestLog = $this->getConfig( MainConfigNames::APIRequestLog );
93
94 $starttime = microtime( true );
95
96 $services = $this->getServiceContainer();
97
98 // PATH_INFO can be used for stupid things. We don't support it for api.php at
99 // all, so error out if it's present. (T128209)
100 $pathInfo = $this->environment->getServerInfo( 'PATH_INFO', '' );
101 if ( $pathInfo != '' ) {
102 $correctUrl = wfAppendQuery(
103 wfScript( 'api' ),
104 $request->getQueryValuesOnly()
105 );
106 $correctUrl = (string)$services->getUrlUtils()->expand(
107 $correctUrl,
109 );
110 $this->header(
111 "Location: $correctUrl",
112 true,
113 301
114 );
115 $this->print(
116 'This endpoint does not support "path info", i.e. extra text ' .
117 'between "api.php" and the "?". Remove any such text and try again.'
118 );
119 $this->exit( 1 );
120 }
121
122 // Set a dummy $wgTitle, because $wgTitle == null breaks various things
123 // In a perfect world this wouldn't be necessary
124 $wgTitle = Title::makeTitle(
126 'Badtitle/dummy title for API calls set in api.php'
127 );
128
129 // RequestContext will read from $wgTitle, but it will also whine about it.
130 // In a perfect world this wouldn't be necessary either.
131 $context->setTitle( $wgTitle );
132
133 try {
134 // Construct an ApiMain with the arguments passed via the URL. What we get back
135 // is some form of an ApiMain, possibly even one that produces an error message,
136 // but we don't care here, as that is handled by the constructor.
137 $processor = new ApiMain(
138 $context,
139 true,
140 false
141 );
142
143 // Last chance hook before executing the API
144 ( new HookRunner( $services->getHookContainer() ) )->onApiBeforeMain( $processor );
145 if ( !$processor instanceof ApiMain ) {
146 throw new LogicException(
147 'ApiBeforeMain hook set $processor to a non-ApiMain class'
148 );
149 }
150 } catch ( Throwable $e ) {
151 // Crap. Try to report the exception in API format to be friendly to clients.
153 $processor = false;
154 }
155
156 // Process data & print results
157 if ( $processor ) {
158 $processor->execute();
159 }
160
161 // Log what the user did, for book-keeping purposes.
162 $endtime = microtime( true );
163
164 // Log the request
165 if ( $apiRequestLog ) {
166 $items = [
167 wfTimestamp( TS_MW ),
168 $endtime - $starttime,
169 $request->getIP(),
170 $request->getHeader( 'User-agent' )
171 ];
172 $items[] = $request->wasPosted() ? 'POST' : 'GET';
173 if ( $processor ) {
174 try {
175 $manager = $processor->getModuleManager();
176 $module = $manager->getModule(
177 $request->getRawVal( 'action' ),
178 'action'
179 );
180 } catch ( Throwable $ex ) {
181 $module = null;
182 }
183 if ( !$module || $module->mustBePosted() ) {
184 $items[] = "action=" . $request->getRawVal( 'action' );
185 } else {
186 $items[] = wfArrayToCgi( $request->getValues() );
187 }
188 } else {
189 $items[] = "failed in ApiBeforeMain";
190 }
192 implode(
193 ',',
194 $items
195 ) . "\n",
196 $apiRequestLog
197 );
198 wfDebug( "Logged API request to $apiRequestLog" );
199 }
200 }
201}
getRequest()
const PROTO_CANONICAL
Definition Defines.php:208
const NS_SPECIAL
Definition Defines.php:53
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
wfScript( $script='index')
Get the URL path to a MediaWiki entry point.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
getContext()
if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli' $wgTitle
Definition Setup.php:536
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:65
static handleApiBeforeMainException(Throwable $e)
Handle a throwable from the ApiBeforeMain hook.
Definition ApiMain.php:1046
Implementation of the API entry point, for web browser navigations, usually via an Action or SpecialP...
execute()
Executes a request to the action API.
getContext()
Overwritten to narrow the return type to RequestContext.
__construct(RequestContext $context, EntryPointEnvironment $environment, MediaWikiServices $services)
Group all the pieces relevant to the context of a request into one instance.
Utility class wrapping PHP runtime state.
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
PSR-3 logger that mimics the historic implementation of MediaWiki's former wfErrorLog logging impleme...
static emit( $text, $file)
Log to a file without getting "file size exceeded" signals.
A class containing constants representing the names of configuration variables.
const APIRequestLog
Name constant for the APIRequestLog setting, for use with Config::get()
Base class for entry point handlers.
Service locator for MediaWiki core services.
Represents a title within MediaWiki.
Definition Title.php:78