X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FSpecialUpload.php;h=5873dfed0cd41969b3fc6a7b7f173781566f9f7a;hb=a3b490d2c4dfc25d7e0594eae8ee27ba69f6afea;hp=31c4f3c25763f6e10412ea5ab4a202e32ead1b18;hpb=c8f7249f9fc4d2bb1ef719aa006682b688cab3c2;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/SpecialUpload.php b/includes/SpecialUpload.php index 31c4f3c257..5873dfed0c 100644 --- a/includes/SpecialUpload.php +++ b/includes/SpecialUpload.php @@ -5,12 +5,7 @@ * @subpackage SpecialPage */ -/** - * - */ -require_once 'Image.php'; -require_once 'MacBinary.php'; -require_once 'Licenses.php'; + /** * Entry point */ @@ -32,7 +27,7 @@ class UploadForm { var $mUploadFile, $mUploadDescription, $mLicense ,$mIgnoreWarning, $mUploadError; var $mUploadSaveName, $mUploadTempName, $mUploadSize, $mUploadOldVersion; var $mUploadCopyStatus, $mUploadSource, $mReUpload, $mAction, $mUpload; - var $mOname, $mSessionKey, $mStashed, $mDestFile, $mRemoveTempFile; + var $mOname, $mSessionKey, $mStashed, $mDestFile, $mRemoveTempFile, $mSourceType; /**#@-*/ /** @@ -41,6 +36,7 @@ class UploadForm { * @param $request Data posted. */ function UploadForm( &$request ) { + global $wgAllowCopyUploads; $this->mDestFile = $request->getText( 'wpDestFile' ); if( !$request->wasPosted() ) { @@ -48,7 +44,7 @@ class UploadForm { return; } - $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning'); + $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' ); $this->mReUpload = $request->getCheck( 'wpReUpload' ); $this->mUpload = $request->getCheck( 'wpUpload' ); @@ -57,6 +53,7 @@ class UploadForm { $this->mUploadCopyStatus = $request->getText( 'wpUploadCopyStatus' ); $this->mUploadSource = $request->getText( 'wpUploadSource' ); $this->mWatchthis = $request->getBool( 'wpWatchthis' ); + $this->mSourceType = $request->getText( 'wpSourceType' ); wfDebug( "UploadForm: watchthis is: '$this->mWatchthis'\n" ); $this->mAction = $request->getVal( 'action' ); @@ -81,16 +78,112 @@ class UploadForm { /** *Check for a newly uploaded file. */ - $this->mUploadTempName = $request->getFileTempName( 'wpUploadFile' ); - $this->mUploadSize = $request->getFileSize( 'wpUploadFile' ); - $this->mOname = $request->getFileName( 'wpUploadFile' ); - $this->mUploadError = $request->getUploadError( 'wpUploadFile' ); - $this->mSessionKey = false; - $this->mStashed = false; - $this->mRemoveTempFile = false; // PHP will handle this + if( $wgAllowCopyUploads && $this->mSourceType == 'web' ) { + $this->initializeFromUrl( $request ); + } else { + $this->initializeFromUpload( $request ); + } } } + /** + * Initialize the uploaded file from PHP data + * @access private + */ + function initializeFromUpload( $request ) { + $this->mUploadTempName = $request->getFileTempName( 'wpUploadFile' ); + $this->mUploadSize = $request->getFileSize( 'wpUploadFile' ); + $this->mOname = $request->getFileName( 'wpUploadFile' ); + $this->mUploadError = $request->getUploadError( 'wpUploadFile' ); + $this->mSessionKey = false; + $this->mStashed = false; + $this->mRemoveTempFile = false; // PHP will handle this + } + + /** + * Copy a web file to a temporary file + * @access private + */ + function initializeFromUrl( $request ) { + global $wgTmpDirectory, $wgMaxUploadSize; + $url = $request->getText( 'wpUploadFileURL' ); + $local_file = tempnam( $wgTmpDirectory, 'WEBUPLOAD' ); + + $this->mUploadTempName = $local_file; + $this->mUploadError = $this->curlCopy( $url, $local_file ); + $this->mUploadSize = $this->mUploadTempFileSize; + $this->mOname = array_pop( explode( '/', $url ) ); + $this->mSessionKey = false; + $this->mStashed = false; + + // PHP won't auto-cleanup the file + $this->mRemoveTempFile = file_exists( $local_file ); + } + + /** + * Safe copy from URL + * Returns true if there was an error, false otherwise + */ + private function curlCopy( $url, $dest ) { + global $wgMaxUploadSize, $wgUser; + + if( !$wgUser->isAllowed( 'upload_by_url' ) ) { + $wgOut->permissionRequired( 'upload_by_url' ); + return true; + } + + # Maybe remove some pasting blanks :-) + $url = strtolower( trim( $url ) ); + if( substr( $url, 0, 7 ) != 'http://' && substr( $url, 0, 6 ) != 'ftp://' ) { + # Only HTTP or FTP URLs + return true; + } + + # Open temporary file + $this->mUploadTempFileSize = 0; + $this->mUploadTempFile = @fopen( $this->mUploadTempName, "wb" ); + if( $this->mUploadTempFile === false ) { + # Could not open temporary file to write in + return true; + } + + $ch = curl_init(); + curl_setopt( $ch, CURLOPT_HTTP_VERSION, 1.0); # Probably not needed, but apparently can work around some bug + curl_setopt( $ch, CURLOPT_TIMEOUT, 10); # 10 seconds timeout + curl_setopt( $ch, CURLOPT_LOW_SPEED_LIMIT, 512); # 0.5KB per second minimum transfer speed + curl_setopt( $ch, CURLOPT_URL, $url); + curl_setopt( $ch, CURLOPT_WRITEFUNCTION, array( $this, 'uploadCurlCallback' ) ); + curl_exec( $ch ); + $error = curl_errno( $ch ) ? true : false; +# if ( $error ) print curl_error ( $ch ) ; # Debugging output + curl_close( $ch ); + + fclose( $this->mUploadTempFile ); + unset( $this->mUploadTempFile ); + if( $error ) { + unlink( $dest ); + } + + return $error; + } + + /** + * Callback function for CURL-based web transfer + * Write data to file unless we've passed the length limit; + * if so, abort immediately. + * @access private + */ + function uploadCurlCallback( $ch, $data ) { + global $wgMaxUploadSize; + $length = strlen( $data ); + $this->mUploadTempFileSize += $length; + if( $this->mUploadTempFileSize > $wgMaxUploadSize ) { + return 0; + } + fwrite( $this->mUploadTempFile, $data ); + return $length; + } + /** * Start doing stuff * @access public @@ -101,18 +194,17 @@ class UploadForm { # Check uploading enabled if( !$wgEnableUploads ) { - $wgOut->errorPage( 'uploaddisabled', 'uploaddisabledtext' ); + $wgOut->showErrorPage( 'uploaddisabled', 'uploaddisabledtext' ); return; } # Check permissions - if( $wgUser->isLoggedIn() ) { - if( !$wgUser->isAllowed( 'upload' ) ) { + if( !$wgUser->isAllowed( 'upload' ) ) { + if( !$wgUser->isLoggedIn() ) { + $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' ); + } else { $wgOut->permissionRequired( 'upload' ); - return; } - } else { - $wgOut->errorPage( 'uploadnologin', 'uploadnologintext' ); return; } @@ -128,15 +220,17 @@ class UploadForm { } /** Check if the image directory is writeable, this is a common mistake */ - if ( !is_writeable( $wgUploadDirectory ) ) { + if( !is_writeable( $wgUploadDirectory ) ) { $wgOut->addWikiText( wfMsg( 'upload_directory_read_only', $wgUploadDirectory ) ); return; } if( $this->mReUpload ) { - $this->unsaveUploadedFile(); + if( !$this->unsaveUploadedFile() ) { + return; + } $this->mainUploadForm(); - } else if ( 'submit' == $this->mAction || $this->mUpload ) { + } else if( 'submit' == $this->mAction || $this->mUpload ) { $this->processUpload(); } else { $this->mainUploadForm(); @@ -156,7 +250,7 @@ class UploadForm { global $wgUser, $wgOut; /* Check for PHP error if any, requires php 4.2 or newer */ - if ( $this->mUploadError == 1/*UPLOAD_ERR_INI_SIZE*/ ) { + if( $this->mUploadError == 1/*UPLOAD_ERR_INI_SIZE*/ ) { $this->mainUploadForm( wfMsgHtml( 'largefileserver' ) ); return; } @@ -170,7 +264,7 @@ class UploadForm { } # Chop off any directories in the given filename - if ( $this->mDestFile ) { + if( $this->mDestFile ) { $basename = wfBaseName( $this->mDestFile ); } else { $basename = wfBaseName( $this->mOname ); @@ -196,7 +290,7 @@ class UploadForm { $partname .= '.' . $ext[$i]; } - if ( strlen( $partname ) < 3 ) { + if( strlen( $partname ) < 3 ) { $this->mainUploadForm( wfMsgHtml( 'minlength' ) ); return; } @@ -298,6 +392,16 @@ class UploadForm { $sk = $wgUser->getSkin(); $dlink = $sk->makeKnownLinkObj( $nt ); $warning .= '