25 use Wikimedia\RequestTimeout\TimeoutException;
70 parent::__construct(
'UploadStash',
'upload' );
89 $this->stash = $this->localRepo->getUploadStash( $this->
getUser() );
92 if ( $subPage ===
null || $subPage ===
'' ) {
112 if ( $params[
'type'] ===
'thumb' ) {
120 $message = $e->getMessage();
121 }
catch ( Exception $e ) {
123 $message = $e->getMessage();
140 $type = strtok( $key,
'/' );
142 if (
$type !==
'file' &&
$type !==
'thumb' ) {
144 $this->
msg(
'uploadstash-bad-path-unknown-type',
$type )
147 $fileName = strtok(
'/' );
148 $thumbPart = strtok(
'/' );
149 $file = $this->stash->getFile( $fileName );
150 if (
$type ===
'thumb' ) {
151 $srcNamePos = strrpos( $thumbPart, $fileName );
152 if ( $srcNamePos ===
false || $srcNamePos < 1 ) {
154 $this->
msg(
'uploadstash-bad-path-unrecognized-thumb-name' )
157 $paramString = substr( $thumbPart, 0, $srcNamePos - 1 );
159 $handler =
$file->getHandler();
161 $params = $handler->parseParamString( $paramString );
163 return [
'file' =>
$file,
'type' =>
$type,
'params' => $params ];
166 $this->
msg(
'uploadstash-bad-path-no-handler',
$file->getMimeType(),
$file->getPath() )
187 if (
$file->getRepo()->getThumbProxyUrl()
188 || $this->getConfig()->get( MainConfigNames::UploadStashScalerBaseUrl )
210 $thumbnailImage =
$file->transform( $params, $flags );
211 if ( !$thumbnailImage ) {
213 $this->
msg(
'uploadstash-file-not-found-no-thumb' )
218 if ( !$thumbnailImage->getStoragePath() ) {
220 $this->
msg(
'uploadstash-file-not-found-no-local-path' )
227 $this->stash->repo, $thumbnailImage->getStoragePath(),
false );
254 $scalerThumbName =
$file->generateThumbName(
$file->getName(), $params );
258 $thumbProxyUrl =
$file->getRepo()->getThumbProxyUrl();
259 if ( strlen( $thumbProxyUrl ) ) {
260 $scalerThumbUrl = $thumbProxyUrl .
'temp/' .
$file->getUrlRel() .
261 '/' . rawurlencode( $scalerThumbName );
262 $secret =
$file->getRepo()->getThumbProxySecret();
267 $scalerBaseUrl = $this->
getConfig()->get( MainConfigNames::UploadStashScalerBaseUrl );
269 if ( preg_match(
'/^\/\//', $scalerBaseUrl ) ) {
276 $scalerThumbUrl = $scalerBaseUrl .
'/' .
$file->getUrlRel() .
277 '/' . rawurlencode( $scalerThumbName );
287 $req = $this->httpRequestFactory->create( $scalerThumbUrl, $httpOptions, __METHOD__ );
290 if ( strlen( $secret ) ) {
291 $req->setHeader(
'X-Swift-Secret', $secret );
294 $status = $req->execute();
295 if ( !$status->isOK() ) {
296 $errors = $status->getErrorsArray();
299 'uploadstash-file-not-found-no-remote-thumb',
300 print_r( $errors, 1 ),
305 $contentType = $req->getResponseHeader(
"content-type" );
306 if ( !$contentType ) {
308 $this->
msg(
'uploadstash-file-not-found-missing-content-type' )
324 if (
$file->getSize() > self::MAX_SERVE_BYTES ) {
326 $this->
msg(
'uploadstash-file-too-large', self::MAX_SERVE_BYTES )
330 $file->getRepo()->streamFileWithStatus(
$file->getPath(),
331 [
'Content-Transfer-Encoding: binary',
332 'Expires: Sun, 17-Jan-2038 19:14:07 GMT' ]
345 if ( $size > self::MAX_SERVE_BYTES ) {
347 $this->
msg(
'uploadstash-file-too-large', self::MAX_SERVE_BYTES )
366 header(
"Content-Type: $contentType",
true );
367 header(
'Content-Transfer-Encoding: binary',
true );
368 header(
'Expires: Sun, 17-Jan-2038 19:14:07 GMT',
true );
370 header(
'Cache-Control: private' );
371 header(
"Content-Length: $size",
true );
392 ], $this->
getContext(),
'clearStashedUploads' );
394 $form->setSubmitDestructive();
395 $form->setSubmitCallback(
function ( $formData, $form ) {
396 if ( isset( $formData[
'Clear'] ) ) {
397 wfDebug(
'stash has: ' . print_r( $this->stash->listFiles(),
true ) );
399 if ( !$this->stash->clear() ) {
406 $form->setSubmitTextMsg(
'uploadstash-clear' );
408 $form->prepareForm();
409 $formResult = $form->tryAuthorizedSubmit();
415 $this->
msg(
'uploadstash-refresh' )->text()
417 $files = $this->stash->listFiles();
418 if ( $files && count( $files ) ) {
420 $fileListItemsHtml =
'';
421 foreach ( $files as
$file ) {
427 $fileObj = $this->stash->getFile(
$file );
428 $thumb = $fileObj->generateThumbName(
$file, [
'width' => 220 ] );
430 $this->
msg(
'word-separator' )->escaped() .
431 $this->
msg(
'parentheses' )->rawParams(
433 $this->getPageTitle(
"thumb/$file/$thumb" ),
434 $this->msg(
'uploadstash-thumbnail' )->text()
437 }
catch ( TimeoutException $e ) {
439 }
catch ( Exception $e ) {
445 $form->displayForm( $formResult );
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfResetOutputBuffers( $resetGzipEncoding=true)
Clear away any user-level output buffers, discarding contents.
Implements some public methods and some protected utility functions which are required by multiple ch...
const RENDER_NOW
Force rendering in the current process.
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Show an error that looks like an HTTP server error.
static logException(Throwable $e, $catcher=self::CAUGHT_BY_OTHER, $extraData=[])
Log a throwable to the exception log (if enabled).
A class containing constants representing the names of configuration variables.
Prioritized list of file repositories.
getLocalRepo()
Get the local repository, i.e.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getUser()
Shortcut to get the User executing this instance.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
getContext()
Gets the context this SpecialPage is executed in.
LinkRenderer null $linkRenderer
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getPageTitle( $subpage=false)
Get a self-referential title object.
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Web access for files temporarily stored by UploadStash.
static outputFileHeaders( $contentType, $size)
Output headers for streaming.
outputLocalFile(File $file)
Output HTTP response for file Side effect: writes HTTP response to STDOUT.
outputThumbFromStash( $file, $params)
Get a thumbnail for file, either generated locally or remotely, and stream it out.
__construct(RepoGroup $repoGroup, HttpRequestFactory $httpRequestFactory)
showUploads()
Default action when we don't have a subpage – just show links to the uploads we have,...
parseKey( $key)
Parse the key passed to the SpecialPage.
showUpload( $key)
If file available in stash, cats it out to the client as a simple HTTP response.
outputRemoteScaledThumb( $file, $params, $flags)
Scale a file with a remote "scaler", as exists on the Wikimedia Foundation cluster,...
const MAX_SERVE_BYTES
Since we are directly writing the file to STDOUT, we should not be reading in really big files and se...
execute( $subPage)
Execute page – can output a file directly or show a listing of them.
doesWrites()
Indicates whether this special page may perform database writes.
outputLocallyScaledThumb( $file, $params, $flags)
Scale a file (probably with a locally installed imagemagick, or similar) and output it to STDOUT.
HttpRequestFactory $httpRequestFactory
outputContents( $content, $contentType)
Output HTTP response of raw content Side effect: writes HTTP response to STDOUT.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
static newGood( $value=null)
Factory function for good results.
Shortcut to construct a special page which is unlisted by default.
File without associated database record.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.