public function run() { $scope = RequestContext::importScopedSession($this->params['session']); $context = RequestContext::getMain(); try { $user = $context->getUser(); if (!$user->isLoggedIn()) { $this->setLastError("Could not load the author user from session."); return false; } if (count($_SESSION) === 0) { // Empty session probably indicates that we didn't associate // with the session correctly. Note that being able to load // the user does not necessarily mean the session was loaded. // Most likely cause by suhosin.session.encrypt = On. $this->setLastError("Error associating with user session. " . "Try setting suhosin.session.encrypt = Off"); return false; } UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood())); $upload = new UploadFromChunks($user); $upload->continueChunks($this->params['filename'], $this->params['filekey'], $context->getRequest()); // Combine all of the chunks into a local file and upload that to a new stash file $status = $upload->concatenateChunks(); if (!$status->isGood()) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => $status)); $this->setLastError($status->getWikiText()); return false; } // We have a new filekey for the fully concatenated file $newFileKey = $upload->getLocalFile()->getFileKey(); // Remove the old stash file row and first chunk file $upload->stash->removeFileNoAuth($this->params['filekey']); // Build the image info array while we have the local reference handy $apiMain = new ApiMain(); // dummy object (XXX) $imageInfo = $upload->getImageInfo($apiMain->getResult()); // Cleanup any temporary local file $upload->cleanupTempFile(); // Cache the info so the user doesn't have to wait forever to get the final info UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => Status::newGood())); } catch (MWException $e) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed'))); $this->setLastError(get_class($e) . ": " . $e->getText()); // To be extra robust. MWExceptionHandler::rollbackMasterChangesAndLog($e); return false; } return true; }
public function run() { $scope = RequestContext::importScopedSession($this->params['session']); $this->addTeardownCallback(function () use(&$scope) { ScopedCallback::consume($scope); // T126450 }); $context = RequestContext::getMain(); $user = $context->getUser(); try { if (!$user->isLoggedIn()) { $this->setLastError("Could not load the author user from session."); return false; } UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood()]); $upload = new UploadFromChunks($user); $upload->continueChunks($this->params['filename'], $this->params['filekey'], new WebRequestUpload($context->getRequest(), 'null')); // Combine all of the chunks into a local file and upload that to a new stash file $status = $upload->concatenateChunks(); if (!$status->isGood()) { UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'assembling', 'status' => $status]); $this->setLastError($status->getWikiText(false, false, 'en')); return false; } // We can only get warnings like 'duplicate' after concatenating the chunks $status = Status::newGood(); $status->value = ['warnings' => $upload->checkWarnings()]; // We have a new filekey for the fully concatenated file $newFileKey = $upload->getStashFile()->getFileKey(); // Remove the old stash file row and first chunk file $upload->stash->removeFileNoAuth($this->params['filekey']); // Build the image info array while we have the local reference handy $apiMain = new ApiMain(); // dummy object (XXX) $imageInfo = $upload->getImageInfo($apiMain->getResult()); // Cleanup any temporary local file $upload->cleanupTempFile(); // Cache the info so the user doesn't have to wait forever to get the final info UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => $status]); } catch (Exception $e) { UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed')]); $this->setLastError(get_class($e) . ": " . $e->getMessage()); // To be extra robust. MWExceptionHandler::rollbackMasterChangesAndLog($e); return false; } return true; }
public function run() { $scope = RequestContext::importScopedSession($this->params['session']); $context = RequestContext::getMain(); try { $user = $context->getUser(); if (!$user->isLoggedIn()) { $this->setLastError("Could not load the author user from session."); return false; } UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood())); $upload = new UploadFromChunks($user); $upload->continueChunks($this->params['filename'], $this->params['filekey'], $context->getRequest()); // Combine all of the chunks into a local file and upload that to a new stash file $status = $upload->concatenateChunks(); if (!$status->isGood()) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => $status)); $this->setLastError($status->getWikiText()); return false; } // We have a new filekey for the fully concatenated file $newFileKey = $upload->getLocalFile()->getFileKey(); // Remove the old stash file row and first chunk file $upload->stash->removeFileNoAuth($this->params['filekey']); // Build the image info array while we have the local reference handy $apiMain = new ApiMain(); // dummy object (XXX) $imageInfo = $upload->getImageInfo($apiMain->getResult()); // Cleanup any temporary local file $upload->cleanupTempFile(); // Cache the info so the user doesn't have to wait forever to get the final info UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => Status::newGood())); } catch (MWException $e) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed'))); $this->setLastError(get_class($e) . ": " . $e->getText()); return false; } return true; }
/** * Select an upload module and set it to mUpload. Dies on failure. If the * request was a status request and not a true upload, returns false; * otherwise true * * @return bool */ protected function selectUploadModule() { $request = $this->getMain()->getRequest(); // chunk or one and only one of the following parameters is needed if (!$this->mParams['chunk']) { $this->requireOnlyOneParameter($this->mParams, 'filekey', 'file', 'url'); } // Status report for "upload to stash"/"upload from stash" if ($this->mParams['filekey'] && $this->mParams['checkstatus']) { $progress = UploadBase::getSessionStatus($this->getUser(), $this->mParams['filekey']); if (!$progress) { $this->dieUsage('No result in status data', 'missingresult'); } elseif (!$progress['status']->isGood()) { $this->dieUsage($progress['status']->getWikiText(false, false, 'en'), 'stashfailed'); } if (isset($progress['status']->value['verification'])) { $this->checkVerification($progress['status']->value['verification']); } unset($progress['status']); // remove Status object $this->getResult()->addValue(null, $this->getModuleName(), $progress); return false; } // The following modules all require the filename parameter to be set if (is_null($this->mParams['filename'])) { $this->dieUsageMsg(['missingparam', 'filename']); } if ($this->mParams['chunk']) { // Chunk upload $this->mUpload = new UploadFromChunks(); if (isset($this->mParams['filekey'])) { if ($this->mParams['offset'] === 0) { $this->dieUsage('Cannot supply a filekey when offset is 0', 'badparams'); } // handle new chunk $this->mUpload->continueChunks($this->mParams['filename'], $this->mParams['filekey'], $request->getUpload('chunk')); } else { if ($this->mParams['offset'] !== 0) { $this->dieUsage('Must supply a filekey when offset is non-zero', 'badparams'); } // handle first chunk $this->mUpload->initialize($this->mParams['filename'], $request->getUpload('chunk')); } } elseif (isset($this->mParams['filekey'])) { // Upload stashed in a previous request if (!UploadFromStash::isValidKey($this->mParams['filekey'])) { $this->dieUsageMsg('invalid-file-key'); } $this->mUpload = new UploadFromStash($this->getUser()); // This will not download the temp file in initialize() in async mode. // We still have enough information to call checkWarnings() and such. $this->mUpload->initialize($this->mParams['filekey'], $this->mParams['filename'], !$this->mParams['async']); } elseif (isset($this->mParams['file'])) { $this->mUpload = new UploadFromFile(); $this->mUpload->initialize($this->mParams['filename'], $request->getUpload('file')); } elseif (isset($this->mParams['url'])) { // Make sure upload by URL is enabled: if (!UploadFromUrl::isEnabled()) { $this->dieUsageMsg('copyuploaddisabled'); } if (!UploadFromUrl::isAllowedHost($this->mParams['url'])) { $this->dieUsageMsg('copyuploadbaddomain'); } if (!UploadFromUrl::isAllowedUrl($this->mParams['url'])) { $this->dieUsageMsg('copyuploadbadurl'); } $this->mUpload = new UploadFromUrl(); $this->mUpload->initialize($this->mParams['filename'], $this->mParams['url']); } return true; }
/** * Select an upload module and set it to mUpload. Dies on failure. If the * request was a status request and not a true upload, returns false; * otherwise true * * @return bool */ protected function selectUploadModule() { $request = $this->getMain()->getRequest(); // chunk or one and only one of the following parameters is needed if (!$this->mParams['chunk']) { $this->requireOnlyOneParameter($this->mParams, 'filekey', 'file', 'url', 'statuskey'); } // Status report for "upload to stash"/"upload from stash" if ($this->mParams['filekey'] && $this->mParams['checkstatus']) { $progress = UploadBase::getSessionStatus($this->mParams['filekey']); if (!$progress) { $this->dieUsage('No result in status data', 'missingresult'); } elseif (!$progress['status']->isGood()) { $this->dieUsage($progress['status']->getWikiText(), 'stashfailed'); } if (isset($progress['status']->value['verification'])) { $this->checkVerification($progress['status']->value['verification']); } unset($progress['status']); // remove Status object $this->getResult()->addValue(null, $this->getModuleName(), $progress); return false; } if ($this->mParams['statuskey']) { $this->checkAsyncDownloadEnabled(); // Status request for an async upload $sessionData = UploadFromUrlJob::getSessionData($this->mParams['statuskey']); if (!isset($sessionData['result'])) { $this->dieUsage('No result in session data', 'missingresult'); } if ($sessionData['result'] == 'Warning') { $sessionData['warnings'] = $this->transformWarnings($sessionData['warnings']); $sessionData['sessionkey'] = $this->mParams['statuskey']; } $this->getResult()->addValue(null, $this->getModuleName(), $sessionData); return false; } // The following modules all require the filename parameter to be set if (is_null($this->mParams['filename'])) { $this->dieUsageMsg(array('missingparam', 'filename')); } if ($this->mParams['chunk']) { // Chunk upload $this->mUpload = new UploadFromChunks(); if (isset($this->mParams['filekey'])) { // handle new chunk $this->mUpload->continueChunks($this->mParams['filename'], $this->mParams['filekey'], $request->getUpload('chunk')); } else { // handle first chunk $this->mUpload->initialize($this->mParams['filename'], $request->getUpload('chunk')); } } elseif (isset($this->mParams['filekey'])) { // Upload stashed in a previous request if (!UploadFromStash::isValidKey($this->mParams['filekey'])) { $this->dieUsageMsg('invalid-file-key'); } $this->mUpload = new UploadFromStash($this->getUser()); // This will not download the temp file in initialize() in async mode. // We still have enough information to call checkWarnings() and such. $this->mUpload->initialize($this->mParams['filekey'], $this->mParams['filename'], !$this->mParams['async']); } elseif (isset($this->mParams['file'])) { $this->mUpload = new UploadFromFile(); $this->mUpload->initialize($this->mParams['filename'], $request->getUpload('file')); } elseif (isset($this->mParams['url'])) { // Make sure upload by URL is enabled: if (!UploadFromUrl::isEnabled()) { $this->dieUsageMsg('copyuploaddisabled'); } if (!UploadFromUrl::isAllowedHost($this->mParams['url'])) { $this->dieUsageMsg('copyuploadbaddomain'); } if (!UploadFromUrl::isAllowedUrl($this->mParams['url'])) { $this->dieUsageMsg('copyuploadbadurl'); } $async = false; if ($this->mParams['asyncdownload']) { $this->checkAsyncDownloadEnabled(); if ($this->mParams['leavemessage'] && !$this->mParams['ignorewarnings']) { $this->dieUsage('Using leavemessage without ignorewarnings is not supported', 'missing-ignorewarnings'); } if ($this->mParams['leavemessage']) { $async = 'async-leavemessage'; } else { $async = 'async'; } } $this->mUpload = new UploadFromUrl(); $this->mUpload->initialize($this->mParams['filename'], $this->mParams['url'], $async); } return true; }