r50012 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r50011‎ | r50012 | r50013 >
Date:19:07, 28 April 2009
Author:dale
Status:deferred
Tags:
Comment:
basic upload via url in-place (without background task) working... (again)
Modified paths:
  • /branches/new-upload/phase3/includes/HttpFunctions.php (modified) (history)
  • /branches/new-upload/phase3/includes/UploadFromUrl.php (modified) (history)

Diff [purge]

Index: branches/new-upload/phase3/includes/UploadFromUrl.php
@@ -50,7 +50,10 @@
5151 }
5252 //print "fetchFile:: $this->dl_mode";
5353 //now do the actual download to the shared target:
54 - $status = Http::doDownload ( $this->mUrl, $this->mTempPath, $this->dl_mode);
 54+ $status = Http::doDownload ( $this->mUrl, $this->mTempPath, $this->dl_mode);
 55+ //update the local filesize var:
 56+ $this->mFileSize = filesize($this->mTempPath);
 57+
5558 return $status;
5659
5760 /*
@@ -64,39 +67,7 @@
6568
6669 }
6770
68 - /**
69 - * Safe copy from URL
70 - * Returns true if there was an error, false otherwise
7171
72 - private function curlCopy() {
73 - global $wgOut, $wgCopyUploadTimeout;
74 -
75 - # Open temporary file
76 - $this->mCurlDestHandle = @fopen( $this->mTempPath, "wb" );
77 - if( $this->mCurlDestHandle === false ) {
78 - # Could not open temporary file to write in
79 - return 'upload-file-error';
80 - }
81 -
82 - $ch = curl_init();
83 - curl_setopt( $ch, CURLOPT_HTTP_VERSION, 1.0); # Probably not needed, but apparently can work around some bug
84 - curl_setopt( $ch, CURLOPT_TIMEOUT, $wgCopyUploadTimeout); # 1 hour timeout
85 - curl_setopt( $ch, CURLOPT_LOW_SPEED_LIMIT, 512); # 0.5KB per second minimum transfer speed
86 - curl_setopt( $ch, CURLOPT_URL, $this->mUrl);
87 - curl_setopt( $ch, CURLOPT_WRITEFUNCTION, array( $this, 'uploadCurlCallback' ) );
88 - curl_exec( $ch );
89 - $error = curl_errno( $ch );
90 - curl_close( $ch );
91 -
92 - fclose( $this->mCurlDestHandle );
93 - unset( $this->mCurlDestHandle );
94 -
95 - if( $error )
96 - return "upload-curl-error$errornum";
97 -
98 - return true;
99 - }
100 - */
10172 /**
10273 * Callback function for CURL-based web transfer
10374 * Write data to file unless we've passed the length limit;
Index: branches/new-upload/phase3/includes/HttpFunctions.php
@@ -18,17 +18,17 @@
1919 $req = newReq($url, $opts );
2020 return $req->request();
2121 }
22 - //setup a new request
23 - public static function newReq($url, $opts){
24 - $req = new Http();
25 - $req->url = $url;
26 - $req->method = (isset($opt['method']))?$opt['method']:'GET';
27 - $req->target_file = (isset($opt['target_file']))?$opt['target_file']:false;
28 - return $req;
 22+ /**
 23+ * Simple wrapper for Http::request( 'POST' )
 24+ */
 25+ public static function post( $url, $opts = array() ) {
 26+ $opts['method']='POST';
 27+ $req = newReq($url, $opts );
 28+ return $req->request();
2929 }
30 - public static function doDownload( $url, $target_path , $dl_mode = self::SYNC_DOWNLOAD ){
 30+ public static function doDownload( $url, $target_file_path , $dl_mode = self::SYNC_DOWNLOAD ){
3131 global $wgPhpCliPath, $wgMaxUploadSize;
32 -
 32+ print "doDownload:$target_file_path";
3333 //do a quick check to HEAD to insure the file size is not > $wgMaxUploadSize to large no need to download it
3434 $head = get_headers($url, 1);
3535 if(isset($head['Content-Length']) && $head['Content-Length'] > $wgMaxUploadSize){
@@ -36,29 +36,39 @@
3737 }
3838
3939 //check if we can find phpCliPath (for doing a background shell request to php to do the download:
40 - if( $wgPhpCliPath && wfShellExecEnabled() && $dl_mode == self::ASYNC_DOWNLOAD){
41 - //setup session
42 - die('do shell exec');
43 - //do shell exec req
 40+ if( $wgPhpCliPath && wfShellExecEnabled() && $dl_mode == self::ASYNC_DOWNLOAD){
 41+ //setup session and shell call:
 42+ return self::initBackgroundDownload( $url, $target_file_path );
4443
4544 //return success status and download_session_key
4645
4746 //(separate ajax request can now check on the status of the shell exec)... and even kill or cancel it)
4847
4948 }else if( $dl_mode== self::SYNC_DOWNLOAD ){
50 - //else just download as much as we can in the time we have left:
51 - return self::doDownloadtoFile($url, $target_path);
 49+ //else just download as much as we can in the time we have left:
 50+ $opts['method']='GET';
 51+ $opts['target_file_path'] = $target_file_path;
 52+ $req = self::newReq($url, $opts );
 53+ return $req->request();
5254 }
5355 }
 56+ //setup a new request
 57+ public static function newReq($url, $opt){
 58+ $req = new Http();
 59+ $req->url = $url;
 60+ $req->method = (isset($opt['method']))?$opt['method']:'GET';
 61+ $req->target_file_path = (isset($opt['target_file_path']))?$opt['target_file_path']:false;
 62+ return $req;
 63+ }
5464 /**
5565 * a non blocking request (generally an exit point in the application)
5666 * should write to a file location and give updates
5767 *
5868 */
59 - public static function initBackgroundDownload( $url ){
 69+ private function initBackgroundDownload( $url, $target_file_path ){
6070 global $wgMaxUploadSize;
6171 $status = Status::newGood();
62 - //generate a session id with all the details for the download (pid, target_file )
 72+ //generate a session id with all the details for the download (pid, target_file_path )
6373
6474 //later add in (destName & description)
6575 $session_id = session_id();
@@ -67,54 +77,43 @@
6878
6979 //return status
7080 return $status;
71 - }
72 - //called from the command line: :
 81+ }
 82+ /**
 83+ * used to run a session based download. Is initiated via the shell.
 84+ *
 85+ * @param string $dn_session_id // the session id to grab download details from
 86+ */
7387 public static function doSessionIdDownload( $dn_session_id ){
7488 //get all the vars we need from session_id
7589 session_id( $dn_session_id );
7690 $url = $_SESSION[ 'wsDownload' ][ 'url' ];
77 - $target_file_path = $_SESSION[ 'wsDownload' ][ 'target_file_path' ];
78 - self::doDownloadtoFile($url, $target_file_path);
79 - return true;
 91+ $target_file_path_path = $_SESSION[ 'wsDownload' ][ 'target_file_path_path' ];
 92+
 93+ //new req here:
8094 }
81 - public static function doDownloadtoFile($url, $target_file_path){
82 - global $wgCopyUploadTimeout;
83 - $req = self::newReq($url, array(
84 - 'target_file'=> $target_file_path
85 - ) );
86 - $status = $req->request( $url );
87 - print "downloading $url \nto FILE target: $target_file_path \n" . filesize( $target_file_path ) . "\n";
88 - return Status::newGood('upload-ok');
89 - }
9095 /**
91 - * Simple wrapper for Http::request( 'POST' )
92 - */
93 - public static function post( $url, $opts = array() ) {
94 - $opts['method']='POST';
95 - return Http::request( $url, $opts );
96 - }
97 - /**
9896 * Get the contents of a file by HTTP
9997 * @param $url string Full URL to act on
10098 * @param $Opt associative array Optional array of options:
10199 * 'method' => 'GET', 'POST' etc.
102 - * 'target_file' => if curl should output to a target file
 100+ * 'target_file_path' => if curl should output to a target file
103101 * 'adapter' => 'curl', 'soket'
104102 */
105103 private function request() {
106104 global $wgHTTPTimeout, $wgHTTPProxy, $wgTitle;
107105
108 - wfDebug( __METHOD__ . ": $method $url\n" );
 106+ wfDebug( __METHOD__ . ": $method $url\n" );
109107 # Use curl if available
110 - if ( function_exists( 'curl_init' ) ) {
 108+ if ( function_exists( 'curl_init' ) ) {
111109 return $this->doCurlReq();
112 - }else{
 110+ }else{
113111 return $this->doPhpReq();
114112 }
115113 }
116114 private function doCurlReq(){
 115+ $status = Status::newGood();
117116 $c = curl_init( $this->url );
118 -
 117+
119118 //proxy setup:
120119 if ( self::isLocalURL( $this->url ) ) {
121120 curl_setopt( $c, CURLOPT_PROXY, 'localhost:80' );
@@ -144,28 +143,36 @@
145144 }
146145
147146 //set the write back function (if we are writing to a file)
148 - if( $this->target_file ){
149 - $cwrite = new simpleFileWriter( $this->target_file );
 147+ if( $this->target_file_path ){
 148+ $cwrite = new simpleFileWriter( $this->target_file_path );
150149 curl_setopt( $c, CURLOPT_WRITEFUNCTION, array($cwrite, 'callbackWriteBody') );
151150 }
152151
153152 //start output grabber:
154 - if(!$this->target_file)
 153+ if(!$this->target_file_path)
155154 ob_start();
156 -
 155+
 156+ //run the actual curl_exec:
157157 try {
158158 if (false === curl_exec($c)) {
159159 $status = Status::newFatal( 'Error sending request: #' . curl_errno($c) .
160 - ' ' . curl_error($c) );
 160+ ' '. curl_error($c) );
161161 }
162162 } catch (Exception $e) {
163163 //do something with curl exec error?
164164 }
165165 //if direct request output the results to the stats value:
166 - if( !$target_file && $status->isOK() ){
 166+ if( !$this->target_file_path && $status->isOK() ){
167167 $status->value = ob_get_contents();
168168 ob_end_clean();
169 - }
 169+ }
 170+ //if we wrote to a target file close up or return error
 171+ if( $this->target_file_path ){
 172+ $cwrite->close();
 173+ if( ! $cwrite->status->isOK() ){
 174+ return $cwrite->status;
 175+ }
 176+ }
170177
171178 # Don't return the text of error messages, return false on error
172179 $retcode = curl_getinfo( $c, CURLINFO_HTTP_CODE );
@@ -180,10 +187,8 @@
181188 wfDebug( __METHOD__ . ": CURL error code $errno: $errstr\n" );
182189 $status = Status::newFatal( " CURL error code $errno: $errstr\n" );
183190 }
184 - curl_close( $c );
185 -
186 -
187 -
 191+ curl_close( $c );
 192+
188193 //return the result obj
189194 return $status;
190195 }
@@ -255,14 +260,35 @@
256261 * a simpleFileWriter
257262 */
258263 class simpleFileWriter{
259 - var $target_file;
260 - function __constructor($target_file){
261 - $this->target_file = $target_file;
 264+ var $target_file_path;
 265+ var $status = null;
 266+ function simpleFileWriter($target_file_path){
 267+ $this->target_file_path = $target_file_path;
 268+ $this->status = Status::newGood();
 269+ //open the file:
 270+ $this->fp = fopen( $this->target_file_path, 'w');
 271+ if( $this->fp === false ){
 272+ $this->status = Status::newFatal('HTTP::could-not-open-file-for-writing');
 273+ }
262274 }
263 - public function callbackWriteBody($ch, $string){
264 - $wgMaxUploadSize;
265 - //write out to the target file
266 -
267 - //
 275+ public function callbackWriteBody($ch, $data_packet){
 276+ global $wgMaxUploadSize;
 277+ //check file size:
 278+ clearstatcache();
 279+ if( filesize( $this->target_file_path) > $wgMaxUploadSize){
 280+ $this->status = Status::newFatal('HTTP::file-has-grown-beyond-upload-limit-killing: '. filesize( $this->target_file_path) . ' > ' . $wgMaxUploadSize);
 281+ return ;
 282+ }
 283+ //write out the content
 284+ if( fwrite($this->fp, $data_packet) === false){
 285+ $this->status = Status::newFatal('HTTP::could-not-write-to-file');
 286+ return 0;
 287+ }
 288+ return strlen($data_packet);
268289 }
 290+ public function close(){
 291+ if(false === fclose( $this->fp )){
 292+ $this->status = Status::newFatal('HTTP::could-not-close-file');
 293+ }
 294+ }
269295 }
\ No newline at end of file

Status & tagging log