| <?php |
| /** |
| * Copyright 2007 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| namespace google\appengine\runtime; |
| |
| /** |
| * Handles removing (unlink()) uploaded files that are left at tmp_name. |
| * |
| * The shutdown hook is registered in Setup.php if $_FILES is not empty. Users |
| * are expected to use move_uploaded_file() to place wanted files in proper |
| * location. |
| * |
| * If changes are made to the $_FILES array the shutdown hook will have an |
| * unmodified copy which both prevents tampering and allows empty files to be |
| * removed along with others after removeEmptyFiles() cleans the array. |
| * |
| * GCS creates empty files when a POST request is sent with empty file fields. |
| * Typically PHP would ignore the file fields signified using UPLOAD_ERR_NO_FILE |
| * in the $_FILES array entry. Instead rfc1867.c is modified to pass the entries |
| * along with __UNLINK__ as the file name to ensure the tmp_name is filled with |
| * gs:// address and can be unlinked along with any unprocessed uploads. |
| */ |
| final class UnlinkUploads { |
| const NAME_UNLINK = '__UNLINK__'; |
| |
| /** |
| * Remove any left over uploads. |
| * |
| * @param array $files |
| * Associative array of uploaded files ($_FILES). |
| */ |
| public static function shutdownHook(array $files) { |
| foreach ($files as $file) { |
| // Break and allow a response if the timeout has been reached. |
| if ((connection_status() & CONNECTION_TIMEOUT) == CONNECTION_TIMEOUT) { |
| break; |
| } |
| |
| // When files are moved using move_uploaded_file() they are removed from |
| // is_uploaded_file() so this should avoid needless unlink() calls. |
| if (isset($file['tmp_name']) && is_uploaded_file($file['tmp_name'])) { |
| unlink($file['tmp_name']); |
| } |
| } |
| } |
| |
| /** |
| * Remove empty file entries signified by __UNLINK__ from array. |
| * |
| * @param array $files |
| * Associative array of uploaded files ($_FILES). |
| */ |
| public static function removeEmptyFiles(array &$files) { |
| foreach ($files as &$file) { |
| if ($file['name'] == static::NAME_UNLINK) { |
| $file = [ |
| 'name' => '', |
| 'type' => '', |
| 'tmp_name' => '', |
| 'error' => UPLOAD_ERR_NO_FILE, |
| 'size' => 0, |
| ]; |
| } |
| } |
| } |
| } |