From 7a0ed924ef35e4a5eca6ca154eaaaa8ed8292396 Mon Sep 17 00:00:00 2001 From: Brian Wolff Date: Thu, 6 Jun 2013 00:55:18 -0300 Subject: [PATCH] Have separate timeouts for upload by url ($wgCopyUpload[Async]Timeout) Add $wgCopyUploadTimeout and $wgCopyUploadAsyncTimeout to control the timeout for the http request used to fetch the file during upload by url. People reasonably may want to make this higher than $wgHTTPTimeout for the case where very large files are being downloaded. Also add the ability for callers of UploadFromUrl::fetchFile to override the timeout as they please (and set any other HTTP opts). This patch was inspired by conversation with dan-nl about gwtoolset. Change-Id: Ia85a97434c14adcdaafc0802cbe0530bfa57a435 --- RELEASE-NOTES-1.22 | 2 ++ includes/DefaultSettings.php | 21 +++++++++++++++++++++ includes/job/jobs/UploadFromUrlJob.php | 7 ++++++- includes/upload/UploadFromUrl.php | 21 +++++++++++++++------ 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22 index 7be25fec2c..c3beec4d64 100644 --- a/RELEASE-NOTES-1.22 +++ b/RELEASE-NOTES-1.22 @@ -41,6 +41,8 @@ production. * (bug 40866) wgOldChangeTagsIndex removed. * $wgNoFollowDomainExceptions now only matches entire domains. For example, an entry for 'bar.com' will still match 'foo.bar.com' but not 'foobar.com'. +* $wgCopyUploadTimeout and $wgCopyUploadAsyncTimeout added to change the timeout times for + fetching the file during upload by url. === New features in 1.22 === * (bug 44525) mediawiki.jqueryMsg can now parse (whitelisted) HTML elements and attributes. diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 8302e6d45a..8e0dff606e 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -585,6 +585,27 @@ $wgCopyUploadsFromSpecialUpload = false; */ $wgCopyUploadProxy = false; +/** + * Different timeout for upload by url + * This could be useful since when fetching large files, you may want a + * timeout longer than the default $wgHTTPTimeout. False means fallback + * to default. + * + * @since 1.22 + */ +$wgCopyUploadTimeout = false; + +/** + * Different timeout for upload by url when run as a background job + * This could be useful since when fetching large files via job queue, + * you may want a different timeout, especially because there is no + * http request being kept alive. + * + * false means fallback to $wgCopyUploadTimeout. + * @since 1.22 + */ +$wgCopyUploadAsyncTimeout = false; + /** * Max size for uploads, in bytes. If not set to an array, applies to all * uploads. If set to an array, per upload type maximums can be set, using the diff --git a/includes/job/jobs/UploadFromUrlJob.php b/includes/job/jobs/UploadFromUrlJob.php index 875491405c..c993cfb476 100644 --- a/includes/job/jobs/UploadFromUrlJob.php +++ b/includes/job/jobs/UploadFromUrlJob.php @@ -48,6 +48,7 @@ class UploadFromUrlJob extends Job { } public function run() { + global $wgCopyUploadAsyncTimeout; # Initialize this object and the upload object $this->upload = new UploadFromUrl(); $this->upload->initialize( @@ -58,7 +59,11 @@ class UploadFromUrlJob extends Job { $this->user = User::newFromName( $this->params['userName'] ); # Fetch the file - $status = $this->upload->fetchFile(); + $opts = array(); + if ( $wgCopyUploadAsyncTimeout ) { + $opts['timeout'] = $wgCopyUploadAsyncTimeout; + } + $status = $this->upload->fetchFile( $opts ); if ( !$status->isOk() ) { $this->leaveMessage( $status ); return true; diff --git a/includes/upload/UploadFromUrl.php b/includes/upload/UploadFromUrl.php index a4374f3f68..0201d5f4e2 100644 --- a/includes/upload/UploadFromUrl.php +++ b/includes/upload/UploadFromUrl.php @@ -182,9 +182,13 @@ class UploadFromUrl extends UploadBase { } /** + * Download the file (if not async) + * + * @param Array $httpOptions Array of options for MWHttpRequest. Ignored if async. + * This could be used to override the timeout on the http request. * @return Status */ - public function fetchFile() { + public function fetchFile( $httpOptions = array() ) { if ( !Http::isValidURI( $this->mUrl ) ) { return Status::newFatal( 'http-invalid-url' ); } @@ -196,7 +200,7 @@ class UploadFromUrl extends UploadBase { return Status::newFatal( 'upload-copy-upload-invalid-url' ); } if ( !$this->mAsync ) { - return $this->reallyFetchFile(); + return $this->reallyFetchFile( $httpOptions ); } return Status::newGood(); } @@ -233,9 +237,12 @@ class UploadFromUrl extends UploadBase { /** * Download the file, save it to the temporary file and update the file * size and set $mRemoveTempFile to true. + * + * @param Array $httpOptions Array of options for MWHttpRequest * @return Status */ - protected function reallyFetchFile() { + protected function reallyFetchFile( $httpOptions = array() ) { + global $wgCopyUploadProxy, $wgCopyUploadTimeout; if ( $this->mTempPath === false ) { return Status::newFatal( 'tmp-create-error' ); } @@ -249,13 +256,15 @@ class UploadFromUrl extends UploadBase { $this->mRemoveTempFile = true; $this->mFileSize = 0; - $options = array( - 'followRedirects' => true + $options = $httpOptions + array( + 'followRedirects' => true, ); - global $wgCopyUploadProxy; if ( $wgCopyUploadProxy !== false ) { $options['proxy'] = $wgCopyUploadProxy; } + if ( $wgCopyUploadTimeout && !isset( $options['timeout'] ) ) { + $options['timeout'] = $wgCopyUploadTimeout; + } $req = MWHttpRequest::factory( $this->mUrl, $options ); $req->setCallback( array( $this, 'saveTempFileChunk' ) ); $status = $req->execute(); -- 2.20.1