blob: 607e0fbbb995d93fd35413404e260d528c056f2a [file] [log] [blame]
<?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,
];
}
}
}
}