00001 <?php
00011 class UploadFromUrl extends UploadBase {
00012 protected $mTempDownloadPath;
00013
00018 public static function isAllowed( $user ) {
00019 if( !$user->isAllowed( 'upload_by_url' ) )
00020 return 'upload_by_url';
00021 return parent::isAllowed( $user );
00022 }
00023
00027 public static function isEnabled() {
00028 global $wgAllowCopyUploads;
00029 return $wgAllowCopyUploads && parent::isEnabled();
00030 }
00031
00035 public function initialize( $name, $url, $na, $nb = false ) {
00036 global $wgTmpDirectory;
00037
00038 $localFile = tempnam( $wgTmpDirectory, 'WEBUPLOAD' );
00039 $this->initializePathInfo( $name, $localFile, 0, true );
00040
00041 $this->mUrl = trim( $url );
00042 }
00043
00048 public function initializeFromRequest( &$request ) {
00049 $desiredDestName = $request->getText( 'wpDestFile' );
00050 if( !$desiredDestName )
00051 $desiredDestName = $request->getText( 'wpUploadFileURL' );
00052 return $this->initialize(
00053 $desiredDestName,
00054 $request->getVal( 'wpUploadFileURL' ),
00055 false
00056 );
00057 }
00058
00062 public static function isValidRequest( $request ){
00063 if( !$request->getVal( 'wpUploadFileURL' ) )
00064 return false;
00065
00066 return self::isValidUrl( $request->getVal( 'wpUploadFileURL' ) );
00067 }
00068
00069 public static function isValidUrl( $url ) {
00070
00071 return (bool)preg_match( '!^(http://|ftp://)!', $url );
00072 }
00073
00077 function fetchFile() {
00078 if( !self::isValidUrl( $this->mUrl ) ) {
00079 return Status::newFatal( 'upload-proto-error' );
00080 }
00081 $res = $this->curlCopy();
00082 if( $res !== true ) {
00083 return Status::newFatal( $res );
00084 }
00085 return Status::newGood();
00086 }
00087
00092 private function curlCopy() {
00093 global $wgOut;
00094
00095 # Open temporary file
00096 $this->mCurlDestHandle = @fopen( $this->mTempPath, "wb" );
00097 if( $this->mCurlDestHandle === false ) {
00098 # Could not open temporary file to write in
00099 return 'upload-file-error';
00100 }
00101
00102 $ch = curl_init();
00103 curl_setopt( $ch, CURLOPT_HTTP_VERSION, 1.0); # Probably not needed, but apparently can work around some bug
00104 curl_setopt( $ch, CURLOPT_TIMEOUT, 10); # 10 seconds timeout
00105 curl_setopt( $ch, CURLOPT_LOW_SPEED_LIMIT, 512); # 0.5KB per second minimum transfer speed
00106 curl_setopt( $ch, CURLOPT_URL, $this->mUrl);
00107 curl_setopt( $ch, CURLOPT_WRITEFUNCTION, array( $this, 'uploadCurlCallback' ) );
00108 curl_exec( $ch );
00109 $error = curl_errno( $ch );
00110 curl_close( $ch );
00111
00112 fclose( $this->mCurlDestHandle );
00113 unset( $this->mCurlDestHandle );
00114
00115 if( $error )
00116 return "upload-curl-error$errornum";
00117
00118 return true;
00119 }
00120
00127 function uploadCurlCallback( $ch, $data ) {
00128 global $wgMaxUploadSize;
00129 $length = strlen( $data );
00130 $this->mFileSize += $length;
00131 if( $this->mFileSize > $wgMaxUploadSize ) {
00132 return 0;
00133 }
00134 fwrite( $this->mCurlDestHandle, $data );
00135 return $length;
00136 }
00137 }