User:BDavis (WMF)/Notes/ApiUpload

What happens inside ApiUpload?

edit

Pseudo code walkthrough from rev cd74d6228df8d93565929244c202a5682228ddeb


ApiUpload::execute()

edit

Main body for the API event.

  • die( uploaddisabled ) unless UploadBase::isEnabled()
  • toggle mParams['async'] off if not globally enabled
  • mParams['file'] = $_FILES['file']
  • mParams['chunk'] = $_FILES['chunk']
  • mParams['filekey'] = mParams['sessionkey'] unless mParams['filekey']
  • try :
  • catch UploadStashException && die( stasherror )
  • die( mustbeloggedin | badaccess-groups ) unless mUpload->isAllowed()
  • status = mUpload->fetchFile()
  • die( status->errors[0] ) unless status->isGood()
  • if mParams['chunk'] :
    • die( file-too-large ) if mParams['filesize'] > mUpload->getMaxUploadSize()
    • die( internal-error ) unless mUpload->getTitle()
    • self::verifyUpload() unless ( mParams['async'] && mParams['filekey'] )
  • unless mParams['stash'] :
    • die(filename) unless mUpload->verifyTitlePermissions()
  • try :
  • catch UploadStashException && die( stasherror )
  • getResult()->addValue(cr)
  • mUpload->cleanupTempFile()


ApiUpload::selectUploadModule()

edit

Pick appropriate UploadBase child class to handle consuming this request.

  • die( invalidparammix | missingparam ) unless ( mParams['chunk'] | mParams['filekey'] | mParams['file'] | mParams['url'] | mParams['statuskey'] )
  • if mParams['checkstatus'] : # check stash status
    • add progress message to result
    • return false
  • if mParams['statuskey'] : # check async upload status
    • sessionData = $_SESSION['wsUploadFromUrlJobData'][ mParams['statuskey'] ]
    • die( missingresult ) unless sessionData['result']
    • add sessionData to result
    • return false
  • die( missingparam ) unless mParams['filename']
  • if mParams['chunk'] :
    • mUpload = new UploadFromChunks
    • mParams['filekey'] ? mUpload->continueChunks() : mUpload->initialize()
  • if mParams['filekey'] :
    • die( invalid-file-key ) unless UploadFromStash::isValidKey()
    • mUpload = new UploadFromStash
    • mUpload->initialize()
  • if mParams['file'] :
    • mUpload = new UploadFromFile
    • mUpload->initialize()
  • if mParams['url'] :
    • die( copyuploaddisabled ) unless UploadFromUrl::isEnabled()
    • die( copyuploadbaddomain ) unless UploadFromUrl::isAllowedHost()
    • die( copyuploadbadurl ) unless UploadFromUrl::isAllowedUrl()
    • if mParams['asyncdownload'] :
      • die( asynccopyuploaddisabled ) unless $wgAllowAsyncCopyUploads
      • die( missing-ignorewarnings ) if mParams['leavemessage'] && !mParams['ignorewarnings']
      • mUpload = new UploadFromUrl
      • mUpload->initialize()
  • return true


ApiUpload::verifyUpload()

edit

Verify the sanity of the upload via currently selected UploadBase child class

  • v = mUpload->verifyUpload() # TODO follow this on down
  • return if v === UploadBase::OK
  • die( various ) # based on v['status'] value


ApiUpload::getContextResult()

edit

Get the result of upload request based on request parameters and system status

  • w = self::getApiWarnings()
  • if ( w && !mParams['ignorewarnings']) :
    • return self::getWarningsResult()
  • elif mParams['chunk']
  • elif mParams['stash']
    • self::getStashResult()
  • return self::performUpload()


ApiUpload::getChunkResult()

edit

Get the result of a chunked upload request.

On receipt of final chunk this will queue assemble job of an async request or assemble inline otherwise.

  • result['result'] = 'Continue'
  • result['warnings'] = warnings if warnings
  • if mParams['offset'] == 0 :
    • try :
      • filekey = self::performStash()
    • catch MWException && die( stashfailed ) #<-- Has FIXME from csteipp for differing error handling
  • else :
    • die( stashfailed ) unless mUpload->addChunk()
  • if final chunk added :
    • if mParams['async'] :
      • die( stashfailed ) if UploadBase::getSessionStatus() === 'Poll'
      • die( stashfailed ) unless JobQueue->push( new AssembleUploadChunksJob )
    • else : # not async
      • die( stashfailed ) unless mUpload->concatenateChunks()->isGood()
    • remove filekey from mUpload->stash
    • filekey = FileKey for LocalFile
    • result['result'] = 'Success'
  • result['filekey'] = filekey
  • result['offset'] = mParams['offset'] + chunkSize
  • return result