r50084 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r50083‎ | r50084 | r50085 >
Date:23:40, 30 April 2009
Author:dale
Status:deferred
Tags:
Comment:
* added background shell task starter.
* added session state updates for downloads
* minor case fix for upload.js
* removed PEAR Http_Request2 class in favor of local version
** too many upstream patches to deal with a async downloads and session state updates
Modified paths:
  • /branches/new-upload/phase3/includes/DefaultSettings.php (modified) (history)
  • /branches/new-upload/phase3/includes/GlobalFunctions.php (modified) (history)
  • /branches/new-upload/phase3/includes/HttpFunctions.php (modified) (history)
  • /branches/new-upload/phase3/includes/PEAR (deleted) (history)
  • /branches/new-upload/phase3/includes/UploadFromUrl.php (modified) (history)
  • /branches/new-upload/phase3/includes/api/ApiUpload.php (modified) (history)
  • /branches/new-upload/phase3/includes/specials/SpecialUpload.php (modified) (history)
  • /branches/new-upload/phase3/maintenance/http_session_download.php (added) (history)
  • /branches/new-upload/phase3/skins/common/upload.js (modified) (history)

Diff [purge]

Index: branches/new-upload/phase3/maintenance/http_session_download.php
@@ -0,0 +1,30 @@
 2+<?php
 3+/*
 4+ * simple entry point to initiate a background download
 5+ *
 6+ * arguments:
 7+ *
 8+ * -sid {$session_id} -usk {$upload_session_key}
 9+ */
 10+
 11+global $optionsWithArgs;
 12+$optionsWithArgs = Array('sid', 'usk');
 13+
 14+require_once( 'commandLine.inc' );
 15+
 16+if(!isset($options['sid']) || !isset($options['usk'])){
 17+ print<<<EOT
 18+ simple entry point to initiate a background download
 19+
 20+ Usage: http_session_download.php [options]
 21+ Options:
 22+ --sid the session id (required)
 23+ --usk the upload session key (also required)
 24+EOT;
 25+
 26+ exit();
 27+}
 28+//run the download:
 29+Http::doSessionIdDownload( $options['sid'], $options['usk'] );
 30+
 31+?>
\ No newline at end of file
Index: branches/new-upload/phase3/skins/common/upload.js
@@ -153,7 +153,7 @@
154154 if( fname.lastIndexOf('.')!=-1 ){
155155 var ext = fname.substr( fname.lastIndexOf('.')+1 );
156156 for(var i=0; i < wgFileExtensions.length; i++){
157 - if( strtolower( wgFileExtensions[i] ) == strtolower( ext ) )
 157+ if( wgFileExtensions[i].toLowerCase() == ext.toLowerCase() )
158158 found = true;
159159 }
160160 }
Index: branches/new-upload/phase3/includes/GlobalFunctions.php
@@ -2170,9 +2170,9 @@
21712171 # This is a hack to work around PHP's flawed invocation of cmd.exe
21722172 # http://news.php.net/php.internals/21796
21732173 $cmd = '"' . $cmd . '"';
2174 - }
 2174+ }
 2175+
21752176 wfDebug( "wfShellExec: $cmd\n" );
2176 -
21772177 $retval = 1; // error by default?
21782178 ob_start();
21792179 passthru( $cmd, $retval );
@@ -2185,6 +2185,15 @@
21862186 return $output;
21872187 }
21882188 /**
 2189+ * Executes a shell command in the background. Passes back the PID of the operation
 2190+ *
 2191+ * @param string $cmd
 2192+ */
 2193+function wfShellBackgroundExec(&$cmd){
 2194+ $pid = shell_exec( "nohup $cmd > /dev/null & echo $!" );
 2195+ return $pid;
 2196+}
 2197+/**
21892198 * Checks if the current instance can execute a shell command
21902199 *
21912200 */
Index: branches/new-upload/phase3/includes/UploadFromUrl.php
@@ -16,16 +16,22 @@
1717 }
1818 /*entry point for Api upload:: ASYNC_DOWNLOAD (if possible) */
1919 function initialize( $name, $url ) {
20 - global $wgTmpDirectory;
 20+ global $wgTmpDirectory, $wgPhpCliPath;
2121
22 - if(!$this->dl_mode)
 22+ if(!$this->dl_mode && $wgPhpCliPath && wfShellExecEnabled() ){
2323 $this->dl_mode = Http::ASYNC_DOWNLOAD;
 24+ }else{
 25+ $this->dl_mode = Http::SYNC_DOWNLOAD;
 26+ }
2427
2528 $local_file = tempnam( $wgTmpDirectory, 'WEBUPLOAD' );
2629 parent::initialize( $name, $local_file, 0, true );
2730
2831 $this->mUrl = trim( $url );
2932 }
 33+ public function isAsync(){
 34+ return $this->dl_mode == Http::ASYNC_DOWNLOAD;
 35+ }
3036 /*entry point for SpecialUpload no ASYNC_DOWNLOAD possible: */
3137 function initializeFromRequest( &$request ) {
3238 //set dl mode if not set:
@@ -43,18 +49,20 @@
4450 /**
4551 * Do the real fetching stuff
4652 */
47 - function fetchFile( ) {
 53+ function fetchFile( ) {
4854 //entry point for SpecialUplaod
4955 if( stripos($this->mUrl, 'http://') !== 0 && stripos($this->mUrl, 'ftp://') !== 0 ) {
5056 return Status::newFatal('upload-proto-error');
5157 }
5258 //print "fetchFile:: $this->dl_mode";
53 - //now do the actual download to the shared target:
54 - $status = Http::doDownload ( $this->mUrl, $this->mTempPath, $this->dl_mode);
 59+
 60+ //now do the actual download to the target file:
 61+ $status = Http::doDownload ( $this->mUrl, $this->mTempPath, $this->dl_mode );
 62+
5563 //update the local filesize var:
56 - $this->mFileSize = filesize( $this->mTempPath );
57 - return $status;
58 -
 64+ $this->mFileSize = filesize( $this->mTempPath );
 65+
 66+ return $status;
5967 }
6068
6169 static function isValidRequest( $request ){
Index: branches/new-upload/phase3/includes/api/ApiUpload.php
@@ -38,7 +38,7 @@
3939 }
4040
4141 public function execute() {
42 - global $wgUser;
 42+ global $wgUser;
4343
4444 $this->getMain()->requestWriteMode();
4545 $this->mParams = $this->extractRequestParams();
@@ -46,7 +46,7 @@
4747
4848 // Add the uploaded file to the params array
4949 $this->mParams['file'] = $request->getFileName( 'file' );
50 -
 50+
5151 // Check whether upload is enabled
5252 if( !UploadBase::isEnabled() )
5353 $this->dieUsageMsg( array( 'uploaddisabled' ) );
@@ -81,9 +81,33 @@
8282 $request->getFileTempName( 'file' ),
8383 $request->getFileSize( 'file' )
8484 );
85 - } elseif( isset( $this->mParams['url'] ) ) {
 85+ } elseif( isset( $this->mParams['url'] ) ) {
 86+
8687 $this->mUpload = new UploadFromUrl();
87 - $this->mUpload->initialize( $this->mParams['filename'], $this->mParams['url']);
 88+ $this->mUpload->initialize( $this->mParams['filename'], $this->mParams['url']);
 89+
 90+ $status = $this->mUpload->fetchFile();
 91+ if( !$status->isOK() ){
 92+ $this->dieUsage( 'fetchfilerror', $status->getWikiText());
 93+ }
 94+ //check if we doing a async request (return session info)
 95+ if( $this->mUpload->isAsync() ){
 96+ $upload_session_key = $status->value;
 97+ //update the session with anything with the params we will need to finish up the upload later on:
 98+ if(!isset($_SESSION['wsDownload'][$upload_session_key]))
 99+ $_SESSION['wsDownload'][$upload_session_key] = array();
 100+
 101+ $sd =& $_SESSION['wsDownload'][$upload_session_key];
 102+
 103+ //do a wholesale copy of mParams
 104+ $sd['mParams'] = $this->mParams;
 105+
 106+
 107+ return $this->getResult()->addValue( null, $this->getModuleName(),
 108+ array( 'upload_session_key' => $upload_session_key
 109+ ));
 110+ }
 111+ //else the file downloaded in place continue with validation:
88112 }
89113 }
90114
@@ -216,12 +240,12 @@
217241 'file' => null,
218242 'chunk' => null,
219243 'url' => null,
 244+ 'enablechunks' => null,
220245 'comment' => array(
221246 ApiBase :: PARAM_DFLT => ''
222247 ),
223248 'watch' => false,
224 - 'ignorewarnings' => false,
225 - 'enablechunks' => false,
 249+ 'ignorewarnings' => false,
226250 'done' => false,
227251 'sessionkey' => null,
228252 'chunksessionkey'=> null,
@@ -234,10 +258,10 @@
235259 'file' => 'File contents',
236260 'chunk'=> 'Chunk File Contents',
237261 'url' => 'Url to upload from',
 262+ 'enablechunks' => 'Boolean If we are in chunk mode; accepts many small file POSTs',
238263 'comment' => 'Upload comment or initial page text',
239264 'watch' => 'Watch the page',
240 - 'ignorewarnings' => 'Ignore any warnings',
241 - 'enablechunks' => 'Boolean If we are in chunk mode; accepts many small file POSTs',
 265+ 'ignorewarnings' => 'Ignore any warnings',
242266 'done' => 'When used with "chunks", Is sent to notify the api The last chunk is being uploaded.',
243267 'sessionkey' => 'Session key in case there were any warnings.',
244268 'chunksessionkey'=> 'Used to sync uploading of chunks',
Index: branches/new-upload/phase3/includes/DefaultSettings.php
@@ -3354,11 +3354,17 @@
33553355 $wgAllowSpecialInclusion = true;
33563356
33573357 /**
3358 - * Timeout for HTTP requests done via CURL
 3358+ * Timeout for HTTP requests done via CURL
 3359+ *
33593360 */
3360 -$wgHTTPTimeout = 3;
 3361+$wgHTTPTimeout = 3;
33613362
33623363 /**
 3364+ * Timeout for large http file copy over http (default 2 hours)
 3365+ */
 3366+$wgHTTPFileTimeout = 60*60*2;
 3367+
 3368+/**
33633369 * Proxy to use for CURL requests.
33643370 */
33653371 $wgHTTPProxy = false;
Index: branches/new-upload/phase3/includes/HttpFunctions.php
@@ -10,87 +10,169 @@
1111 const ASYNC_DOWNLOAD = 2; //asynchronous upload we should spawn out another process and monitor progress if possible)
1212
1313 var $body = '';
 14+
1415 /**
1516 * Simple wrapper for Http::request( 'GET' )
1617 */
1718 public static function get( $url, $opts = array() ) {
1819 $opt['method'] = 'GET';
19 - $req = newReq($url, $opts );
20 - return $req->request();
 20+ $req = new HttpRequest($url, $opts );
 21+ return $req->doRequest();
2122 }
2223 /**
2324 * Simple wrapper for Http::request( 'POST' )
2425 */
2526 public static function post( $url, $opts = array() ) {
2627 $opts['method']='POST';
27 - $req = newReq($url, $opts );
28 - return $req->request();
 28+ $req = new HttpRequest( $url, $opts );
 29+ return $req->doRequest();
2930 }
3031 public static function doDownload( $url, $target_file_path , $dl_mode = self::SYNC_DOWNLOAD ){
31 - global $wgPhpCliPath, $wgMaxUploadSize;
 32+ global $wgPhpCliPath, $wgMaxUploadSize;
3233 //do a quick check to HEAD to insure the file size is not > $wgMaxUploadSize to large no need to download it
3334 $head = get_headers($url, 1);
3435 if(isset($head['Content-Length']) && $head['Content-Length'] > $wgMaxUploadSize){
35 - return Status::newFatal('requested file length ' .$head['Content-Length'] . ' is greater than $wgMaxUploadSize: ' . $wgMaxUploadSize);
 36+ return Status::newFatal('requested file length ' . $head['Content-Length'] . ' is greater than $wgMaxUploadSize: ' . $wgMaxUploadSize);
3637 }
3738
3839 //check if we can find phpCliPath (for doing a background shell request to php to do the download:
3940 if( $wgPhpCliPath && wfShellExecEnabled() && $dl_mode == self::ASYNC_DOWNLOAD){
4041 //setup session and shell call:
41 - return self::initBackgroundDownload( $url, $target_file_path );
42 -
43 - //return success status and download_session_key
44 -
45 - //(separate ajax request can now check on the status of the shell exec)... and even kill or cancel it)
46 -
 42+ return self::initBackgroundDownload( $url, $target_file_path );
4743 }else if( $dl_mode== self::SYNC_DOWNLOAD ){
4844 //else just download as much as we can in the time we have left:
4945 $opts['method']='GET';
5046 $opts['target_file_path'] = $target_file_path;
51 - $req = self::newReq($url, $opts );
52 - return $req->request();
 47+ $req = new HttpRequest($url, $opts );
 48+ return $req->doRequest();
5349 }
5450 }
55 - //setup a new request
56 - public static function newReq($url, $opt){
57 - $req = new Http();
58 - $req->url = $url;
59 - $req->method = (isset($opt['method']))?$opt['method']:'GET';
60 - $req->target_file_path = (isset($opt['target_file_path']))?$opt['target_file_path']:false;
61 - return $req;
62 - }
6351 /**
6452 * a non blocking request (generally an exit point in the application)
6553 * should write to a file location and give updates
6654 *
6755 */
6856 private function initBackgroundDownload( $url, $target_file_path ){
69 - global $wgMaxUploadSize;
 57+ global $wgMaxUploadSize, $IP, $wgPhpCliPath;
7058 $status = Status::newGood();
 59+
7160 //generate a session id with all the details for the download (pid, target_file_path )
72 -
73 - //later add in (destName & description)
 61+ $upload_session_key = self::getUploadSessionKey();
7462 $session_id = session_id();
75 - print "should spin out a process with id: $session_id\n";
76 - //maintenance/http_download.php passing it a upload session_id
 63+
 64+ //store the url and target path:
 65+ $_SESSION[ 'wsDownload' ][$upload_session_key]['url'] = $url;
 66+ $_SESSION[ 'wsDownload' ][$upload_session_key]['target_file_path'] = $target_file_path;
 67+
 68+ //run the background download request:
 69+ $cmd = $wgPhpCliPath . ' ' . $IP . "/maintenance/http_session_download.php --sid {$session_id} --usk {$upload_session_key}";
 70+ $pid = wfShellBackgroundExec($cmd , $retval);
 71+ wfDebug('GOT PID: '. $pid . " running cmd: $cmd\n" );
 72+ //the pid is not of much use since we won't be visiting this same apache any-time soon.
 73+ if(!$pid)
 74+ return Status::newFatal('could not run background shell exec');
7775
78 - //return status
 76+ //update the status value with the $upload_session_key (for the user to check on the status of the upload)
 77+ $status->value = $upload_session_key;
 78+
 79+ //return good status with
7980 return $status;
80 - }
 81+ }
 82+ function getUploadSessionKey(){
 83+ $key = mt_rand( 0, 0x7fffffff );
 84+ $_SESSION['wsUploadData'][$key] = array();
 85+ return $key;
 86+ }
8187 /**
8288 * used to run a session based download. Is initiated via the shell.
8389 *
84 - * @param string $dn_session_id // the session id to grab download details from
 90+ * @param string $session_id // the session id to grab download details from
 91+ * @param string $upload_session_key //the key of the given upload session
 92+ * (a given client could have started a few http uploads at once)
8593 */
86 - public static function doSessionIdDownload( $dn_session_id ){
87 - //get all the vars we need from session_id
88 - session_id( $dn_session_id );
89 - $url = $_SESSION[ 'wsDownload' ][ 'url' ];
90 - $target_file_path_path = $_SESSION[ 'wsDownload' ][ 'target_file_path_path' ];
 94+ public static function doSessionIdDownload( $session_id, $upload_session_key ){
 95+
 96+ //set session to the provided key:
 97+ session_id($session_id);
 98+ //start the session
 99+ if( session_start() === false){
 100+ wfDebug( __METHOD__ . ' could not start session');
 101+ }
 102+ //get all the vars we need from session_id
 103+ $sessionData = $_SESSION[ 'wsDownload' ][$upload_session_key];
 104+ //close down the session so we can other http queries can get session updates:
 105+ session_write_close();
 106+
 107+ $req = new HttpRequest( $sessionData['url'], array(
 108+ 'target_file_path' => $sessionData['target_file_path'],
 109+ 'upload_session_key' => $upload_session_key
 110+ ) );
 111+ $status = $req->doRequest();
 112+ if( $status->isOK() ){
 113+ //regrab the updated session data:
 114+ $sessionData = $_SESSION[ 'wsDownload' ][$upload_session_key];
 115+ //done with 'download' now to inject and display warnings
 116+ wfDebug("\nDONE with session download now to inject:\n");
 117+ wfDebug( print_r($_SESSION, true));
 118+
 119+
 120+ //$faxReq = new FauxRequest($sessionData['mParam'], true);
 121+ //print_r($faxReq);
 122+ }
 123+ }
 124+
 125+ /**
 126+ * Check if the URL can be served by localhost
 127+ * @param $url string Full url to check
 128+ * @return bool
 129+ */
 130+ public static function isLocalURL( $url ) {
 131+ global $wgCommandLineMode, $wgConf;
 132+ if ( $wgCommandLineMode ) {
 133+ return false;
 134+ }
91135
92 - //new req here:
 136+ // Extract host part
 137+ $matches = array();
 138+ if ( preg_match( '!^http://([\w.-]+)[/:].*$!', $url, $matches ) ) {
 139+ $host = $matches[1];
 140+ // Split up dotwise
 141+ $domainParts = explode( '.', $host );
 142+ // Check if this domain or any superdomain is listed in $wgConf as a local virtual host
 143+ $domainParts = array_reverse( $domainParts );
 144+ for ( $i = 0; $i < count( $domainParts ); $i++ ) {
 145+ $domainPart = $domainParts[$i];
 146+ if ( $i == 0 ) {
 147+ $domain = $domainPart;
 148+ } else {
 149+ $domain = $domainPart . '.' . $domain;
 150+ }
 151+ if ( $wgConf->isLocalVHost( $domain ) ) {
 152+ return true;
 153+ }
 154+ }
 155+ }
 156+ return false;
93157 }
 158+
94159 /**
 160+ * Return a standard user-agent we can use for external requests.
 161+ */
 162+ public static function userAgent() {
 163+ global $wgVersion;
 164+ return "MediaWiki/$wgVersion";
 165+ }
 166+}
 167+class HttpRequest{
 168+ var $target_file_path;
 169+ var $upload_session_key;
 170+ function __construct($url, $opt){
 171+ $this->url = $url;
 172+ $this->method = (isset($opt['method']))?$opt['method']:'GET';
 173+ $this->target_file_path = (isset($opt['target_file_path']))?$opt['target_file_path']:false;
 174+ $this->upload_session_key = (isset($opt['upload_session_key']))?$opt['upload_session_key']:false;
 175+ }
 176+/**
95177 * Get the contents of a file by HTTP
96178 * @param $url string Full URL to act on
97179 * @param $Opt associative array Optional array of options:
@@ -98,10 +180,7 @@
99181 * 'target_file_path' => if curl should output to a target file
100182 * 'adapter' => 'curl', 'soket'
101183 */
102 - private function request() {
103 - global $wgHTTPTimeout, $wgHTTPProxy, $wgTitle;
104 -
105 - wfDebug( __METHOD__ . ": $method $url\n" );
 184+ public function doRequest() {
106185 # Use curl if available
107186 if ( function_exists( 'curl_init' ) ) {
108187 return $this->doCurlReq();
@@ -110,20 +189,22 @@
111190 }
112191 }
113192 private function doCurlReq(){
114 - $status = Status::newGood();
115 - $c = curl_init( $this->url );
116 -
 193+ global $wgHTTPFileTimeout, $wgHTTPProxy, $wgTitle;
 194+
 195+ $status = Status::newGood();
 196+ $c = curl_init( $this->url );
 197+
117198 //proxy setup:
118 - if ( self::isLocalURL( $this->url ) ) {
 199+ if ( Http::isLocalURL( $this->url ) ) {
119200 curl_setopt( $c, CURLOPT_PROXY, 'localhost:80' );
120201 } else if ($wgHTTPProxy) {
121202 curl_setopt($c, CURLOPT_PROXY, $wgHTTPProxy);
122203 }
123 -
124 - curl_setopt( $c, CURLOPT_TIMEOUT, $wgHTTPTimeout );
 204+
 205+ curl_setopt( $c, CURLOPT_TIMEOUT, $wgHTTPFileTimeout );
125206
126207
127 - curl_setopt( $c, CURLOPT_USERAGENT, self :: userAgent() );
 208+ curl_setopt( $c, CURLOPT_USERAGENT, Http::userAgent() );
128209
129210 if ( $this->method == 'POST' ) {
130211 curl_setopt( $c, CURLOPT_POST, true );
@@ -143,7 +224,7 @@
144225
145226 //set the write back function (if we are writing to a file)
146227 if( $this->target_file_path ){
147 - $cwrite = new simpleFileWriter( $this->target_file_path );
 228+ $cwrite = new simpleFileWriter( $this->target_file_path, $this->upload_session_key );
148229 curl_setopt( $c, CURLOPT_WRITEFUNCTION, array($cwrite, 'callbackWriteBody') );
149230 }
150231
@@ -213,55 +294,18 @@
214295 }
215296 return $status;
216297 }
217 - /**
218 - * Check if the URL can be served by localhost
219 - * @param $url string Full url to check
220 - * @return bool
221 - */
222 - public static function isLocalURL( $url ) {
223 - global $wgCommandLineMode, $wgConf;
224 - if ( $wgCommandLineMode ) {
225 - return false;
226 - }
227 -
228 - // Extract host part
229 - $matches = array();
230 - if ( preg_match( '!^http://([\w.-]+)[/:].*$!', $url, $matches ) ) {
231 - $host = $matches[1];
232 - // Split up dotwise
233 - $domainParts = explode( '.', $host );
234 - // Check if this domain or any superdomain is listed in $wgConf as a local virtual host
235 - $domainParts = array_reverse( $domainParts );
236 - for ( $i = 0; $i < count( $domainParts ); $i++ ) {
237 - $domainPart = $domainParts[$i];
238 - if ( $i == 0 ) {
239 - $domain = $domainPart;
240 - } else {
241 - $domain = $domainPart . '.' . $domain;
242 - }
243 - if ( $wgConf->isLocalVHost( $domain ) ) {
244 - return true;
245 - }
246 - }
247 - }
248 - return false;
249 - }
250 -
251 - /**
252 - * Return a standard user-agent we can use for external requests.
253 - */
254 - public static function userAgent() {
255 - global $wgVersion;
256 - return "MediaWiki/$wgVersion";
257 - }
258298 }
259299 /**
260 - * a simpleFileWriter
 300+ * a simpleFileWriter with session id updates
 301+ *
261302 */
262303 class simpleFileWriter{
263304 var $target_file_path;
264 - var $status = null;
265 - function simpleFileWriter($target_file_path){
 305+ var $status = null;
 306+ var $session_id = null;
 307+ static $session_update_interval = 2; //how offten to update the session while downloading
 308+
 309+ function simpleFileWriter($target_file_path, $session_id=false){
266310 $this->target_file_path = $target_file_path;
267311 $this->status = Status::newGood();
268312 //open the file:
@@ -269,22 +313,60 @@
270314 if( $this->fp === false ){
271315 $this->status = Status::newFatal('HTTP::could-not-open-file-for-writing');
272316 }
 317+ //true start time
 318+ $this->prevTime = time();
273319 }
274320 public function callbackWriteBody($ch, $data_packet){
275321 global $wgMaxUploadSize;
276322 //check file size:
277323 clearstatcache();
278 - if( filesize( $this->target_file_path) > $wgMaxUploadSize){
279 - $this->status = Status::newFatal('HTTP::file-has-grown-beyond-upload-limit-killing: '. filesize( $this->target_file_path) . ' > ' . $wgMaxUploadSize);
280 - return ;
281 - }
 324+ $this->current_fsize = filesize( $this->target_file_path);
 325+
 326+ if( $this->current_fsize > $wgMaxUploadSize){
 327+ wfDebug( __METHOD__ . ' http download too large');
 328+ $this->status = Status::newFatal('HTTP::file-has-grown-beyond-upload-limit-killing: downloaded more than ' .
 329+ Language::formatSize($wgMaxUploadSize) . ' ');
 330+ return 0;
 331+ }
 332+
282333 //write out the content
283334 if( fwrite($this->fp, $data_packet) === false){
284335 $this->status = Status::newFatal('HTTP::could-not-write-to-file');
285336 return 0;
286 - }
 337+ }
 338+
 339+ //if more than 2 second have passed update_session_progress
 340+ if($this->upload_session_key && (time() - $this->prevTime) > self::session_update_interval) {
 341+ $this->prevTime = time();
 342+ $session_status = $this->update_session_progress();
 343+ if( !$session_status->isOK() ){
 344+ $this->status = $session_status;
 345+ wfDebug( __METHOD__ . ' update session failed or was canceled');
 346+ return 0;
 347+ }
 348+ }
287349 return strlen($data_packet);
288350 }
 351+ public function update_session_progress(){
 352+ $status = Status::newGood();
 353+ //start the session
 354+ if( session_start() === false){
 355+ wfDebug( __METHOD__ . ' could not start session');
 356+ exit(0);
 357+ }
 358+ $sd =& $_SESSION[ 'wsDownload' ][$this->upload_session_key];
 359+ //check if the user canceled the request:
 360+ if( $sd['user_cancel'] == true ){
 361+ //kill the download
 362+ return Status::newFatal('user-canceled-request');
 363+ }
 364+ //update the progress bytes download so far:
 365+ $sd['loaded'] = $this->current_fsize;
 366+ wfDebug('set session loaded amount to: ' . $sd['loaded']);
 367+ //close down the session so we can other http queries can get session updates:
 368+ session_write_close();
 369+ return $status;
 370+ }
289371 public function close(){
290372 if(false === fclose( $this->fp )){
291373 $this->status = Status::newFatal('HTTP::could-not-close-file');
Index: branches/new-upload/phase3/includes/specials/SpecialUpload.php
@@ -82,15 +82,15 @@
8383 * @access public
8484 */
8585 function execute() {
86 - global $wgUser, $wgOut;
87 -
 86+ global $wgUser, $wgOut;
 87+
8888 # Check uploading enabled
8989 if( !UploadBase::isEnabled() ) {
9090 $wgOut->showErrorPage( 'uploaddisabled', 'uploaddisabledtext' );
9191 return;
9292 }
9393
94 - # Check permissions
 94+ # Check permissions
9595 if( $this->mUpload ) {
9696 $permission = $this->mUpload->isAllowed( $wgUser );
9797 } else {
@@ -114,7 +114,7 @@
115115 if( wfReadOnly() ) {
116116 $wgOut->readOnlyPage();
117117 return;
118 - }
 118+ }
119119 if( $this->mReUpload ) {
120120 // User choose to cancel upload
121121 if( !$this->mUpload->unsaveUploadedFile() ) {

Status & tagging log