Have separate timeouts for upload by url ($wgCopyUpload[Async]Timeout)
authorBrian Wolff <bawolff+wn@gmail.com>
Thu, 6 Jun 2013 03:55:18 +0000 (00:55 -0300)
committerRelease notes rebase bot <matma.rex+releasenotesrebasebot@gmail.com>
Wed, 7 Aug 2013 19:05:07 +0000 (21:05 +0200)
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
includes/DefaultSettings.php
includes/job/jobs/UploadFromUrlJob.php
includes/upload/UploadFromUrl.php

index 7be25fe..c3beec4 100644 (file)
@@ -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.
index 8302e6d..8e0dff6 100644 (file)
@@ -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
index 8754914..c993cfb 100644 (file)
@@ -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;
index a4374f3..0201d5f 100644 (file)
@@ -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();