Index: trunk/phase3/includes/upload/UploadStash.php |
— | — | @@ -9,7 +9,6 @@ |
10 | 10 | * - enable the uploading user (and *ONLY* the uploading user) to access said files, and thumbnails of said files, via a URL. |
11 | 11 | * We accomplish this by making the session serve as a URL->file mapping, on the assumption that nobody else can access |
12 | 12 | * the session, even the uploading user. See SpecialUploadStash, which implements a web interface to some files stored this way. |
13 | | - * |
14 | 13 | */ |
15 | 14 | class UploadStash { |
16 | 15 | |
— | — | @@ -22,6 +21,12 @@ |
23 | 22 | |
24 | 23 | // array of initialized objects obtained from session (lazily initialized upon getFile()) |
25 | 24 | private $files = array(); |
| 25 | + |
| 26 | + // Session ID |
| 27 | + private $sessionID; |
| 28 | + |
| 29 | + // Cache to store stash metadata in |
| 30 | + private $cache; |
26 | 31 | |
27 | 32 | // TODO: Once UploadBase starts using this, switch to use these constants rather than UploadBase::SESSION* |
28 | 33 | // const SESSION_VERSION = 2; |
— | — | @@ -41,14 +46,13 @@ |
42 | 47 | |
43 | 48 | $this->repo = $repo; |
44 | 49 | |
45 | | - if ( ! isset( $_SESSION ) ) { |
46 | | - throw new UploadStashNotAvailableException( 'no session variable' ); |
| 50 | + if ( session_id() === '' ) { |
| 51 | + // FIXME: Should we just start a session in this case? |
| 52 | + // Anonymous uploading could be allowed |
| 53 | + throw new UploadStashNotAvailableException( 'no session ID' ); |
47 | 54 | } |
48 | | - |
49 | | - if ( !isset( $_SESSION[UploadBase::SESSION_KEYNAME] ) ) { |
50 | | - $_SESSION[UploadBase::SESSION_KEYNAME] = array(); |
51 | | - } |
52 | | - |
| 55 | + $this->sessionID = ''; |
| 56 | + $this->cache = wfGetCache( CACHE_ANYTHING ); |
53 | 57 | } |
54 | 58 | |
55 | 59 | /** |
— | — | @@ -64,32 +68,37 @@ |
65 | 69 | if ( ! preg_match( self::KEY_FORMAT_REGEX, $key ) ) { |
66 | 70 | throw new UploadStashBadPathException( "key '$key' is not in a proper format" ); |
67 | 71 | } |
68 | | - |
| 72 | + |
69 | 73 | if ( !isset( $this->files[$key] ) ) { |
70 | | - if ( !isset( $_SESSION[UploadBase::SESSION_KEYNAME][$key] ) ) { |
| 74 | + $cacheKey = wfMemcKey( 'uploadstash', $this->sessionID, $key ); |
| 75 | + $data = $this->cache->get( $cacheKey ); |
| 76 | + if ( !$data ) { |
71 | 77 | throw new UploadStashFileNotFoundException( "key '$key' not found in stash" ); |
72 | 78 | } |
73 | 79 | |
74 | | - $data = $_SESSION[UploadBase::SESSION_KEYNAME][$key]; |
75 | | - // guards against PHP class changing while session data doesn't |
76 | | - if ($data['version'] !== UploadBase::SESSION_VERSION ) { |
77 | | - throw new UploadStashBadVersionException( $data['version'] . " does not match current version " . UploadBase::SESSION_VERSION ); |
78 | | - } |
79 | | - |
80 | | - // separate the stashData into the path, and then the rest of the data |
81 | | - $path = $data['mTempPath']; |
82 | | - unset( $data['mTempPath'] ); |
| 80 | + $this->files[$key] = $this->getFileFromData( $data ); |
83 | 81 | |
84 | | - $file = new UploadStashFile( $this, $this->repo, $path, $key, $data ); |
85 | | - if ( $file->getSize === 0 ) { |
86 | | - throw new UploadStashZeroLengthFileException( "File is zero length" ); |
87 | | - } |
88 | | - $this->files[$key] = $file; |
89 | | - |
90 | 82 | } |
91 | 83 | return $this->files[$key]; |
92 | 84 | } |
| 85 | + |
| 86 | + protected function getFileFromData( $data ) { |
| 87 | + // guards against PHP class changing while session data doesn't |
| 88 | + if ( $data['version'] !== UploadBase::SESSION_VERSION ) { |
| 89 | + throw new UploadStashBadVersionException( $data['version'] . " does not match current version " . UploadBase::SESSION_VERSION ); |
| 90 | + } |
| 91 | + |
| 92 | + // separate the stashData into the path, and then the rest of the data |
| 93 | + $path = $data['mTempPath']; |
| 94 | + unset( $data['mTempPath'] ); |
93 | 95 | |
| 96 | + $file = new UploadStashFile( $this, $this->repo, $path, $key, $data ); |
| 97 | + if ( $file->getSize() === 0 ) { |
| 98 | + throw new UploadStashZeroLengthFileException( "File is zero length" ); |
| 99 | + } |
| 100 | + return $file; |
| 101 | + } |
| 102 | + |
94 | 103 | /** |
95 | 104 | * Stash a file in a temp directory and record that we did this in the session, along with other metadata. |
96 | 105 | * We store data in a flat key-val namespace because that's how UploadBase did it. This also means we have to |
— | — | @@ -163,10 +172,15 @@ |
164 | 173 | |
165 | 174 | // now, merge required info and extra data into the session. (The extra data changes from application to application. |
166 | 175 | // UploadWizard wants different things than say FirefoggChunkedUpload.) |
| 176 | + $finalData = array_merge( $data, $requiredData ); |
| 177 | + |
| 178 | + global $wgUploadStashExpiry; |
167 | 179 | wfDebug( __METHOD__ . " storing under $key\n" ); |
168 | | - $_SESSION[UploadBase::SESSION_KEYNAME][$key] = array_merge( $data, $requiredData ); |
| 180 | + $cacheKey = wfMemcKey( 'uploadstash', $this->sessionID, $key ); |
| 181 | + $this->cache->set( $cacheKey, array_merge( $data, $requiredData ), $wgUploadStashExpiry ); |
169 | 182 | |
170 | | - return $this->getFile( $key ); |
| 183 | + $this->files[$key] = $this->getFileFromData( $data ); |
| 184 | + return $this->files[$key]; |
171 | 185 | } |
172 | 186 | |
173 | 187 | /** |
Index: trunk/phase3/includes/WebStart.php |
— | — | @@ -126,15 +126,10 @@ |
127 | 127 | |
128 | 128 | wfProfileIn( 'WebStart.php-ob_start' ); |
129 | 129 | # Initialise output buffering |
130 | | - |
131 | 130 | # Check that there is no previous output or previously set up buffers, because |
132 | 131 | # that would cause us to potentially mix gzip and non-gzip output, creating a |
133 | 132 | # big mess. |
134 | | -# In older versions of PHP ob_get_level() returns 0 if there is no buffering or |
135 | | -# previous output, in newer versions the default output buffer is always set up |
136 | | -# and ob_get_level() returns 1. In this case we check that the buffer is empty. |
137 | | -# FIXME: Check that this is the right way to handle this |
138 | | -if ( !defined( 'MW_NO_OUTPUT_BUFFER' ) && ( ob_get_level() == 0 || ( ob_get_level() == 1 && ob_get_contents() === '' ) ) ) { |
| 133 | +if ( !defined( 'MW_NO_OUTPUT_BUFFER' ) && ob_get_level() == 0 ) { |
139 | 134 | require_once( "$IP/includes/OutputHandler.php" ); |
140 | 135 | ob_start( 'wfOutputHandler' ); |
141 | 136 | } |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -959,6 +959,11 @@ |
960 | 960 | */ |
961 | 961 | $wgDjvuOutputExtension = 'jpg'; |
962 | 962 | |
| 963 | +/** |
| 964 | + * How long (in seconds) stashed uploads are kept in cache. |
| 965 | + */ |
| 966 | +$wgUploadStashExpiry = 3600; // 1 hour |
| 967 | + |
963 | 968 | /** @} */ # end of file uploads } |
964 | 969 | |
965 | 970 | /************************************************************************//** |