Skip to content

Commit

Permalink
Return Zotero-Storage-Usage/Zotero-Storage-Quota headers with 413
Browse files Browse the repository at this point in the history
  • Loading branch information
dstillman committed Jun 25, 2019
1 parent fa8a06e commit 8c29e59
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 14 deletions.
14 changes: 8 additions & 6 deletions controllers/ItemsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -901,17 +901,19 @@ private function _handleFileRequest($item) {
// Reject file if it would put account over quota
if ($group) {
$quota = Zotero_Storage::getEffectiveUserQuota($group->ownerUserID);
$usage = Zotero_Storage::getUserUsage($group->ownerUserID);
$usage = Zotero_Storage::getUserUsage($group->ownerUserID, 'b');
}
else {
$quota = Zotero_Storage::getEffectiveUserQuota($this->objectUserID);
$usage = Zotero_Storage::getUserUsage($this->objectUserID);
$usage = Zotero_Storage::getUserUsage($this->objectUserID, 'b');
}
$total = $usage['total'];
$fileSizeMB = round($info->size / 1024 / 1024, 1);
if ($total + $fileSizeMB > $quota) {
$requestedMB = round(($usage['total'] + $info->size) / 1024 / 1024, 1);
if ($requestedMB > $quota) {
StatsD::increment("storage.upload.quota", 1);
$this->e413("File would exceed quota ($total + $fileSizeMB > $quota)");
$usageMB = round($usage['total'] / 1024 / 1024, 1);
header("Zotero-Storage-Usage: $usageMB");
header("Zotero-Storage-Quota: $quota");
$this->e413("File would exceed quota ($requestedMB > $quota)");
}

Zotero_DB::query("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
Expand Down
2 changes: 1 addition & 1 deletion controllers/StorageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public function storageadmin() {
if ($quota == self::UNLIMITED) {
$xml->quota = 'unlimited';
}
$usage = Zotero_Storage::getUserUsage($this->objectUserID);
$usage = Zotero_Storage::getUserUsage($this->objectUserID, 'mb');
$xml->usage->total = $usage['total'];
$xml->usage->library = $usage['library'];

Expand Down
41 changes: 34 additions & 7 deletions model/Storage.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -840,11 +840,17 @@ public static function generateUploadPOSTParams($item, Zotero_StorageFileInfo $i
}


/**
* Get quota and expiration date for a user
*/
public static function getUserValues($userID) {
$sql = "SELECT quota, UNIX_TIMESTAMP(expiration) AS expiration FROM storageAccounts WHERE userID=?";
return Zotero_DB::rowQuery($sql, $userID);
}

/**
* Set quota and expiration date for a user
*/
public static function setUserValues($userID, $quota, $expiration) {
$cacheKey = "userStorageQuota_" . $userID;
Z_Core::$MC->delete($cacheKey);
Expand All @@ -857,7 +863,7 @@ public static function setUserValues($userID, $quota, $expiration) {

// If changing quota, make sure it's not less than current usage
$current = self::getUserValues($userID);
$usage = self::getUserUsage($userID);
$usage = self::getUserUsage($userID, 'mb');
if ($current['quota'] != $quota && $quota < $usage['total']) {
throw new Exception("Cannot set quota below current usage", Z_ERROR_GROUP_QUOTA_SET_BELOW_USAGE);
}
Expand Down Expand Up @@ -943,10 +949,11 @@ public static function getEffectiveUserQuota($userID) {
return $quota;
}

public static function getUserUsage($userID) {
$cacheKey = "userStorageUsage_" . $userID;
public static function getUserUsage($userID, $unit = 'b') {
$cacheKey = "userStorageUsageBytes_" . $userID;
$usage = Z_Core::$MC->get($cacheKey);
if ($usage) {
$usage = self::usageToUnit($usage, $unit);
return $usage;
}

Expand All @@ -956,7 +963,7 @@ public static function getUserUsage($userID) {
$sql = "SELECT SUM(size) AS bytes FROM storageFileItems "
. "JOIN items USING (itemID) WHERE libraryID=?";
$libraryBytes = Zotero_DB::valueQuery($sql, $libraryID, Zotero_Shards::getByLibraryID($libraryID));
$usage['library'] = round($libraryBytes / 1024 / 1024, 1);
$usage['library'] = $libraryBytes;

$groupBytes = 0;
$usage['groups'] = array();
Expand All @@ -977,7 +984,7 @@ public static function getUserUsage($userID) {
if ($library['libraryID']) {
$usage['groups'][] = array(
'id' => Zotero_Groups::getGroupIDFromLibraryID($library['libraryID']),
'usage' => round($library['bytes'] / 1024 / 1024, 1)
'usage' => $library['bytes']
);
}
// ROLLUP row
Expand All @@ -989,16 +996,17 @@ public static function getUserUsage($userID) {
}
}

$usage['total'] = round(($libraryBytes + $groupBytes) / 1024 / 1024, 1);
$usage['total'] = $libraryBytes + $groupBytes;

Z_Core::$MC->set($cacheKey, $usage, 600);

$usage = self::usageToUnit($usage, $unit);
return $usage;
}


public static function clearUserUsage($userID) {
$cacheKey = "userStorageUsage_" . $userID;
$cacheKey = "userStorageUsageBytes_" . $userID;
Z_Core::$MC->delete($cacheKey);
}

Expand All @@ -1009,6 +1017,25 @@ private static function updateLastAdded($storageFileID) {
}


private static function usageToUnit($usage, $unit) {
if ($unit == 'b') {
return $usage;
}
if ($unit == 'mb') {
$divisor = 1024 * 1024;
}
else {
throw new Exception("Invalid unit $unit");
}
$usage['library'] = round($usage['library'] / $divisor, 1);
foreach ($usage['groups'] as &$value) {
$value['usage'] = round($value['usage'] / $divisor, 1);
}
$usage['total'] = round($usage['total'] / $divisor, 1);
return $usage;
}


private static function getHash($stringToSign) {
return base64_encode(hash_hmac('sha1', $stringToSign, Z_CONFIG::$AWS_SECRET_KEY, true));
}
Expand Down

0 comments on commit 8c29e59

Please sign in to comment.