Anomie has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/51066


Change subject: (bug 44923) Fix API upload with only one chunk
......................................................................

(bug 44923) Fix API upload with only one chunk

The API supports chunked uploads to upload a file in multiple pieces.
But it doesn't check if the the entire file is uploaded in the first
chunk, so it winds up waiting for a subsequent chunk that can never
come.

It's actually fairly easy to fix, we just need to move the check for
"did we get the entire file?" outside of the "if we're getting a chunk
after the first" check.

Change-Id: I915c1678dfa3107f1739fed8613ab9452139b946
---
M RELEASE-NOTES-1.21
M includes/api/ApiUpload.php
2 files changed, 50 insertions(+), 50 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/66/51066/1

diff --git a/RELEASE-NOTES-1.21 b/RELEASE-NOTES-1.21
index cbfafa2..30a73b0 100644
--- a/RELEASE-NOTES-1.21
+++ b/RELEASE-NOTES-1.21
@@ -241,6 +241,8 @@
   currently in use on the wiki.
 * (bug 44921) ApiMain::execute() will now return after the CORS check for an
   HTTP OPTIONS request.
+* (bug 44923) action=upload works correctly if the entire file is uploaded in
+  the first chunk.
 
 === API internal changes in 1.21 ===
 * For debugging only, a new global $wgDebugAPI removes many API restrictions 
when true.
diff --git a/includes/api/ApiUpload.php b/includes/api/ApiUpload.php
index a0da765..1e5a5df 100644
--- a/includes/api/ApiUpload.php
+++ b/includes/api/ApiUpload.php
@@ -195,69 +195,67 @@
                $chunkPath = $request->getFileTempname( 'chunk' );
                $chunkSize = $request->getUpload( 'chunk' )->getSize();
                if ( $this->mParams['offset'] == 0 ) {
-                       $result['filekey'] = $this->performStash();
+                       $filekey = $this->performStash();
                } else {
+                       $filekey = $this->mParams['filekey'];
                        $status = $this->mUpload->addChunk(
                                $chunkPath, $chunkSize, 
$this->mParams['offset'] );
                        if ( !$status->isGood() ) {
                                $this->dieUsage( $status->getWikiText(), 
'stashfailed' );
                                return array();
                        }
+               }
 
-                       // Check we added the last chunk:
-                       if( $this->mParams['offset'] + $chunkSize == 
$this->mParams['filesize'] ) {
-                               if ( $this->mParams['async'] && !wfIsWindows() 
) {
-                                       $progress = 
UploadBase::getSessionStatus( $this->mParams['filekey'] );
-                                       if ( $progress && $progress['result'] 
=== 'Poll' ) {
-                                               $this->dieUsage( "Chunk 
assembly already in progress.", 'stashfailed' );
-                                       }
-                                       UploadBase::setSessionStatus(
-                                               $this->mParams['filekey'],
-                                               array( 'result' => 'Poll',
-                                                       'stage' => 'queued', 
'status' => Status::newGood() )
-                                       );
-                                       $retVal = 1;
-                                       $cmd = wfShellWikiCmd(
-                                               
"$IP/includes/upload/AssembleUploadChunks.php",
-                                               array(
-                                                       '--wiki', wfWikiID(),
-                                                       '--filename', 
$this->mParams['filename'],
-                                                       '--filekey', 
$this->mParams['filekey'],
-                                                       '--userid', 
$this->getUser()->getId(),
-                                                       '--sessionid', 
session_id(),
-                                                       '--quiet'
-                                               )
-                                       ) . " < " . wfGetNull() . " > " . 
wfGetNull() . " 2>&1 &";
-                                       // Start a process in the background. 
Enforce the time limits via PHP
-                                       // since ulimit4.sh seems to often not 
work for this particular usage.
-                                       wfShellExec( $cmd, $retVal, array(), 
array( 'time' => 0, 'memory' => 0 ) );
-                                       if ( $retVal == 0 ) {
-                                               $result['result'] = 'Poll';
-                                       } else {
-                                               UploadBase::setSessionStatus( 
$this->mParams['filekey'], false );
-                                               $this->dieUsage(
-                                                       "Failed to start 
AssembleUploadChunks.php", 'stashfailed' );
-                                       }
+               // Check we added the last chunk:
+               if( $this->mParams['offset'] + $chunkSize == 
$this->mParams['filesize'] ) {
+                       if ( $this->mParams['async'] && !wfIsWindows() ) {
+                               $progress = UploadBase::getSessionStatus( 
$this->mParams['filekey'] );
+                               if ( $progress && $progress['result'] === 
'Poll' ) {
+                                       $this->dieUsage( "Chunk assembly 
already in progress.", 'stashfailed' );
+                               }
+                               UploadBase::setSessionStatus(
+                                       $this->mParams['filekey'],
+                                       array( 'result' => 'Poll',
+                                               'stage' => 'queued', 'status' 
=> Status::newGood() )
+                               );
+                               $retVal = 1;
+                               $cmd = wfShellWikiCmd(
+                                       
"$IP/includes/upload/AssembleUploadChunks.php",
+                                       array(
+                                               '--wiki', wfWikiID(),
+                                               '--filename', 
$this->mParams['filename'],
+                                               '--filekey', 
$this->mParams['filekey'],
+                                               '--userid', 
$this->getUser()->getId(),
+                                               '--sessionid', session_id(),
+                                               '--quiet'
+                                       )
+                               ) . " < " . wfGetNull() . " > " . wfGetNull() . 
" 2>&1 &";
+                               // Start a process in the background. Enforce 
the time limits via PHP
+                               // since ulimit4.sh seems to often not work for 
this particular usage.
+                               wfShellExec( $cmd, $retVal, array(), array( 
'time' => 0, 'memory' => 0 ) );
+                               if ( $retVal == 0 ) {
+                                       $result['result'] = 'Poll';
                                } else {
-                                       $status = 
$this->mUpload->concatenateChunks();
-                                       if ( !$status->isGood() ) {
-                                               $this->dieUsage( 
$status->getWikiText(), 'stashfailed' );
-                                               return array();
-                                       }
-
-                                       // We have a new filekey for the fully 
concatenated file.
-                                       $result['filekey'] = 
$this->mUpload->getLocalFile()->getFileKey();
-
-                                       // Remove chunk from stash. (Checks 
against user ownership of chunks.)
-                                       $this->mUpload->stash->removeFile( 
$this->mParams['filekey'] );
-
-                                       $result['result'] = 'Success';
+                                       UploadBase::setSessionStatus( 
$this->mParams['filekey'], false );
+                                       $this->dieUsage(
+                                               "Failed to start 
AssembleUploadChunks.php", 'stashfailed' );
                                }
                        } else {
-                               // Continue passing through the filekey for 
adding further chunks.
-                               $result['filekey'] = $this->mParams['filekey'];
+                               $status = $this->mUpload->concatenateChunks();
+                               if ( !$status->isGood() ) {
+                                       $this->dieUsage( 
$status->getWikiText(), 'stashfailed' );
+                                       return array();
+                               }
+
+                               // The the fully concatenated file has a new 
filekey. So remove
+                               // the old filekey and fetch the new one.
+                               $this->mUpload->stash->removeFile( $filekey );
+                               $filekey = 
$this->mUpload->getLocalFile()->getFileKey();
+
+                               $result['result'] = 'Success';
                        }
                }
+               $result['filekey'] = $filekey;
                $result['offset'] = $this->mParams['offset'] + $chunkSize;
                return $result;
        }

-- 
To view, visit https://gerrit.wikimedia.org/r/51066
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I915c1678dfa3107f1739fed8613ab9452139b946
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Anomie <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to