Merge "MWException doesn't care about $wgTitle anymore"
[lhc/web/wiklou.git] / includes / upload / UploadFromUrl.php
index c99feef..19b4dfd 100644 (file)
@@ -34,6 +34,8 @@ class UploadFromUrl extends UploadBase {
 
        protected $mTempPath, $mTmpHandle;
 
+       protected static $allowedUrls = array();
+
        /**
         * Checks if the user is allowed to use the upload-by-URL feature. If the
         * user is not allowed, return the name of the user right as a string. If
@@ -104,6 +106,21 @@ class UploadFromUrl extends UploadBase {
                return $valid;
        }
 
+       /**
+        * Checks whether the URL is not allowed.
+        *
+        * @param $url string
+        * @return bool
+        */
+       public static function isAllowedUrl( $url ) {
+               if ( !isset( self::$allowedUrls[$url] ) ) {
+                       $allowed = true;
+                       wfRunHooks( 'IsUploadAllowedFromUrl', array( $url, &$allowed ) );
+                       self::$allowedUrls[$url] = $allowed;
+               }
+               return self::$allowedUrls[$url];
+       }
+
        /**
         * Entry point for API upload
         *
@@ -165,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' );
                }
@@ -175,18 +196,24 @@ class UploadFromUrl extends UploadBase {
                if ( !self::isAllowedHost( $this->mUrl ) ) {
                        return Status::newFatal( 'upload-copy-upload-invalid-domain' );
                }
+               if ( !self::isAllowedUrl( $this->mUrl ) ) {
+                       return Status::newFatal( 'upload-copy-upload-invalid-url' );
+               }
                if ( !$this->mAsync ) {
-                       return $this->reallyFetchFile();
+                       return $this->reallyFetchFile( $httpOptions );
                }
                return Status::newGood();
        }
+
        /**
         * Create a new temporary file in the URL subdirectory of wfTempDir().
         *
         * @return string Path to the file
         */
        protected function makeTemporaryFile() {
-               return tempnam( wfTempDir(), 'URL' );
+               $tmpFile = TempFSFile::factory( 'URL' );
+               $tmpFile->bind( $this );
+               return $tmpFile->getPath();
        }
 
        /**
@@ -213,9 +240,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' );
                }
@@ -229,13 +259,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();