]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/upload/UploadFromUrl.php
MediaWiki 1.16.5-scripts
[autoinstalls/mediawiki.git] / includes / upload / UploadFromUrl.php
1 <?php
2 /**
3  * @file
4  * @ingroup upload
5  *
6  * Implements uploading from a HTTP resource.
7  *
8  * @author Bryan Tong Minh
9  * @author Michael Dale
10  */
11 class UploadFromUrl extends UploadBase {
12         protected $mTempDownloadPath;
13
14         /**
15          * Checks if the user is allowed to use the upload-by-URL feature. If the
16          * user is allowed, pass on permissions checking to the parent.
17          */
18         public static function isAllowed( $user ) {
19                 if( !$user->isAllowed( 'upload_by_url' ) )
20                         return 'upload_by_url';
21                 return parent::isAllowed( $user );
22         }
23
24         /**
25          * Checks if the upload from URL feature is enabled
26          */
27         public static function isEnabled() {
28                 global $wgAllowCopyUploads;
29                 return $wgAllowCopyUploads && parent::isEnabled();
30         }
31
32         /**
33          * Entry point for API upload
34          */
35         public function initialize( $name, $url, $na, $nb = false ) {
36                 global $wgTmpDirectory;
37
38                 $localFile = tempnam( $wgTmpDirectory, 'WEBUPLOAD' );
39                 $this->initializePathInfo( $name, $localFile, 0, true );
40
41                 $this->mUrl = trim( $url );
42         }
43
44         /**
45          * Entry point for SpecialUpload
46          * @param $request Object: WebRequest object
47          */
48         public function initializeFromRequest( &$request ) {
49                 $desiredDestName = $request->getText( 'wpDestFile' );
50                 if( !$desiredDestName )
51                         $desiredDestName = $request->getText( 'wpUploadFileURL' );
52                 return $this->initialize(
53                         $desiredDestName,
54                         $request->getVal( 'wpUploadFileURL' ),
55                         false
56                 );
57         }
58
59         /**
60          * @param $request Object: WebRequest object
61          */
62         public static function isValidRequest( $request ){
63                 if( !$request->getVal( 'wpUploadFileURL' ) )
64                         return false;
65                 // check that is a valid url:
66                 return self::isValidUrl( $request->getVal( 'wpUploadFileURL' ) );
67         }
68
69         public static function isValidUrl( $url ) {
70                 // Only allow HTTP or FTP for now
71                 return (bool)preg_match( '!^(http://|ftp://)!', $url );
72         }
73
74         /**
75          * Do the real fetching stuff
76          */
77         function fetchFile() {
78                 if( !self::isValidUrl( $this->mUrl ) ) {
79                         return Status::newFatal( 'upload-proto-error' );
80                 }
81                 $res = $this->curlCopy();
82                 if( $res !== true ) {
83                         return Status::newFatal( $res );
84                 }
85                 return Status::newGood();
86         }
87
88         /**
89          * Safe copy from URL
90          * Returns true if there was an error, false otherwise
91          */
92         private function curlCopy() {
93                 global $wgOut;
94
95                 # Open temporary file
96                 $this->mCurlDestHandle = @fopen( $this->mTempPath, "wb" );
97                 if( $this->mCurlDestHandle === false ) {
98                         # Could not open temporary file to write in
99                         return 'upload-file-error';
100                 }
101
102                 $ch = curl_init();
103                 curl_setopt( $ch, CURLOPT_HTTP_VERSION, 1.0); # Probably not needed, but apparently can work around some bug
104                 curl_setopt( $ch, CURLOPT_TIMEOUT, 10); # 10 seconds timeout
105                 curl_setopt( $ch, CURLOPT_LOW_SPEED_LIMIT, 512); # 0.5KB per second minimum transfer speed
106                 curl_setopt( $ch, CURLOPT_URL, $this->mUrl);
107                 curl_setopt( $ch, CURLOPT_WRITEFUNCTION, array( $this, 'uploadCurlCallback' ) );
108                 curl_exec( $ch );
109                 $error =  curl_errno( $ch );
110                 curl_close( $ch );
111
112                 fclose( $this->mCurlDestHandle );
113                 unset( $this->mCurlDestHandle );
114
115                 if( $error )
116                         return "upload-curl-error$errornum";
117
118                 return true;
119         }
120
121         /**
122          * Callback function for CURL-based web transfer
123          * Write data to file unless we've passed the length limit;
124          * if so, abort immediately.
125          * @access private
126          */
127         function uploadCurlCallback( $ch, $data ) {
128                 global $wgMaxUploadSize;
129                 $length = strlen( $data );
130                 $this->mFileSize += $length;
131                 if( $this->mFileSize > $wgMaxUploadSize ) {
132                         return 0;
133                 }
134                 fwrite( $this->mCurlDestHandle, $data );
135                 return $length;
136         }
137 }