Set values from query params (bug 12750)
[lhc/web/wiklou.git] / includes / UploadFromUrl.php
1 <?php
2
3
4 class UploadFromUrl extends UploadBase {
5 static function isAllowed( User $user ) {
6 if( !$user->isAllowed( 'upload_by_url' ) )
7 return 'upload_by_url';
8 return parent::isAllowed( $user );
9 }
10 static function isEnabled() {
11 global $wgAllowCopyUploads;
12 return $wgAllowCopyUploads && parent::isEnabled();
13 }
14
15 function initialize( $url ) {
16 global $wgTmpDirectory;
17 $local_file = tempnam( $wgTmpDirectory, 'WEBUPLOAD' );
18
19 $this->mTempPath = $local_file;
20 $this->mFileSize = 0; # Will be set by curlCopy
21 $this->mCurlError = $this->curlCopy( $url, $local_file );
22 $pathParts = explode( '/', $url );
23 $this->mSrcName = array_pop( $pathParts );
24 $this->mSessionKey = false;
25 $this->mStashed = false;
26
27 // PHP won't auto-cleanup the file
28 $this->mRemoveTempFile = file_exists( $local_file );
29 }
30
31
32 /**
33 * Safe copy from URL
34 * Returns true if there was an error, false otherwise
35 */
36 private function curlCopy( $url, $dest ) {
37 global $wgUser, $wgOut;
38
39 // Bad bad bad!
40 if( !$wgUser->isAllowed( 'upload_by_url' ) ) {
41 $wgOut->permissionRequired( 'upload_by_url' );
42 return true;
43 }
44
45 # Maybe remove some pasting blanks :-)
46 $url = trim( $url );
47 if( stripos($url, 'http://') !== 0 && stripos($url, 'ftp://') !== 0 ) {
48 # Only HTTP or FTP URLs
49 $wgOut->showErrorPage( 'upload-proto-error', 'upload-proto-error-text' );
50 return true;
51 }
52
53 # Open temporary file
54 $this->mCurlDestHandle = @fopen( $this->mTempPath, "wb" );
55 if( $this->mCurlDestHandle === false ) {
56 # Could not open temporary file to write in
57 $wgOut->showErrorPage( 'upload-file-error', 'upload-file-error-text');
58 return true;
59 }
60
61 $ch = curl_init();
62 curl_setopt( $ch, CURLOPT_HTTP_VERSION, 1.0); # Probably not needed, but apparently can work around some bug
63 curl_setopt( $ch, CURLOPT_TIMEOUT, 10); # 10 seconds timeout
64 curl_setopt( $ch, CURLOPT_LOW_SPEED_LIMIT, 512); # 0.5KB per second minimum transfer speed
65 curl_setopt( $ch, CURLOPT_URL, $url);
66 curl_setopt( $ch, CURLOPT_WRITEFUNCTION, array( $this, 'uploadCurlCallback' ) );
67 curl_exec( $ch );
68 $error = curl_errno( $ch ) ? true : false;
69 $errornum = curl_errno( $ch );
70 // if ( $error ) print curl_error ( $ch ) ; # Debugging output
71 curl_close( $ch );
72
73 fclose( $this->mCurlDestHandle );
74 unset( $this->mCurlDestHandle );
75 if( $error ) {
76 unlink( $dest );
77 if( wfEmptyMsg( "upload-curl-error$errornum", wfMsg("upload-curl-error$errornum") ) )
78 $wgOut->showErrorPage( 'upload-misc-error', 'upload-misc-error-text' );
79 else
80 $wgOut->showErrorPage( "upload-curl-error$errornum", "upload-curl-error$errornum-text" );
81 }
82
83 return $error;
84 }
85
86 /**
87 * Callback function for CURL-based web transfer
88 * Write data to file unless we've passed the length limit;
89 * if so, abort immediately.
90 * @access private
91 */
92 function uploadCurlCallback( $ch, $data ) {
93 global $wgMaxUploadSize;
94 $length = strlen( $data );
95 $this->mFileSize += $length;
96 if( $this->mFileSize > $wgMaxUploadSize ) {
97 return 0;
98 }
99 fwrite( $this->mCurlDestHandle, $data );
100 return $length;
101 }
102
103 function execute( &$resultDetails ) {
104 /* Check for curl error */
105 if( $this->mCurlError ) {
106 return self::BEFORE_PROCESSING;
107 }
108 return parent::execute( $resultDetails );
109 }
110 }