Page MenuHomePhabricator

D12070.diff
No OneTemporary

D12070.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -44,7 +44,7 @@
'rsrc/css/application/config/config-welcome.css' => '6abd79be',
'rsrc/css/application/config/setup-issue.css' => '22270af2',
'rsrc/css/application/config/unhandled-exception.css' => '37d4f9a2',
- 'rsrc/css/application/conpherence/durable-column.css' => '1f5c64e8',
+ 'rsrc/css/application/conpherence/durable-column.css' => '8c951609',
'rsrc/css/application/conpherence/menu.css' => 'c6ac5299',
'rsrc/css/application/conpherence/message-pane.css' => '5930260a',
'rsrc/css/application/conpherence/notification.css' => '04a6e10a',
@@ -513,7 +513,7 @@
'changeset-view-manager' => '88be0133',
'config-options-css' => '7fedf08b',
'config-welcome-css' => '6abd79be',
- 'conpherence-durable-column-view' => '1f5c64e8',
+ 'conpherence-durable-column-view' => '8c951609',
'conpherence-menu-css' => 'c6ac5299',
'conpherence-message-pane-css' => '5930260a',
'conpherence-notification-css' => '04a6e10a',
diff --git a/src/applications/files/conduit/FileAllocateConduitAPIMethod.php b/src/applications/files/conduit/FileAllocateConduitAPIMethod.php
--- a/src/applications/files/conduit/FileAllocateConduitAPIMethod.php
+++ b/src/applications/files/conduit/FileAllocateConduitAPIMethod.php
@@ -37,7 +37,7 @@
$hash = $request->getValue('contentHash');
$name = $request->getValue('name');
$view_policy = $request->getValue('viewPolicy');
- $content_length = $request->getValue('contentLength');
+ $length = $request->getValue('contentLength');
$force_chunking = $request->getValue('forceChunking');
@@ -48,18 +48,14 @@
'isExplicitUpload' => true,
);
+ $file = null;
if ($hash) {
$file = PhabricatorFile::newFileFromContentHash(
$hash,
$properties);
+ }
- if ($file) {
- return array(
- 'upload' => false,
- 'filePHID' => $file->getPHID(),
- );
- }
-
+ if ($hash && !$file) {
$chunked_hash = PhabricatorChunkedFileStorageEngine::getChunkedHash(
$viewer,
$hash);
@@ -67,17 +63,34 @@
->setViewer($viewer)
->withContentHashes(array($chunked_hash))
->executeOne();
+ }
- if ($file) {
- return array(
- 'upload' => (bool)$file->getIsPartial(),
- 'filePHID' => $file->getPHID(),
- );
+ if (strlen($name) && !$hash && !$file) {
+ if ($length > PhabricatorFileStorageEngine::getChunkThreshold()) {
+ // If we don't have a hash, but this file is large enough to store in
+ // chunks and thus may be resumable, try to find a partially uploaded
+ // file by the same author with the same name and same length. This
+ // allows us to resume uploads in Javascript where we can't efficiently
+ // compute file hashes.
+ $file = id(new PhabricatorFileQuery())
+ ->setViewer($viewer)
+ ->withAuthorPHIDs(array($viewer->getPHID()))
+ ->withNames(array($name))
+ ->withLengthBetween($length, $length)
+ ->withIsPartial(true)
+ ->setLimit(1)
+ ->executeOne();
}
}
- $engines = PhabricatorFileStorageEngine::loadStorageEngines(
- $content_length);
+ if ($file) {
+ return array(
+ 'upload' => (bool)$file->getIsPartial(),
+ 'filePHID' => $file->getPHID(),
+ );
+ }
+
+ $engines = PhabricatorFileStorageEngine::loadStorageEngines($length);
if ($engines) {
if ($force_chunking) {
@@ -111,7 +124,7 @@
);
}
- $file = $engine->allocateChunks($content_length, $chunk_properties);
+ $file = $engine->allocateChunks($length, $chunk_properties);
return array(
'upload' => true,
diff --git a/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php b/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php
--- a/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php
+++ b/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php
@@ -105,7 +105,16 @@
}
$input = $viewer->getAccountSecret().':'.$hash.':'.$viewer->getPHID();
- return PhabricatorHash::digest($input);
+ return self::getChunkedHashForInput($input);
+ }
+
+ public static function getChunkedHashForInput($input) {
+ $rehash = PhabricatorHash::digest($input);
+
+ // Add a suffix to identify this as a chunk hash.
+ $rehash = substr($rehash, 0, -2).'-C';
+
+ return $rehash;
}
public function allocateChunks($length, array $properties) {
diff --git a/src/applications/files/query/PhabricatorFileQuery.php b/src/applications/files/query/PhabricatorFileQuery.php
--- a/src/applications/files/query/PhabricatorFileQuery.php
+++ b/src/applications/files/query/PhabricatorFileQuery.php
@@ -11,6 +11,10 @@
private $dateCreatedAfter;
private $dateCreatedBefore;
private $contentHashes;
+ private $minLength;
+ private $maxLength;
+ private $names;
+ private $isPartial;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -89,6 +93,22 @@
return $this;
}
+ public function withLengthBetween($min, $max) {
+ $this->minLength = $min;
+ $this->maxLength = $max;
+ return $this;
+ }
+
+ public function withNames(array $names) {
+ $this->names = $names;
+ return $this;
+ }
+
+ public function withIsPartial($partial) {
+ $this->isPartial = $partial;
+ return $this;
+ }
+
public function showOnlyExplicitUploads($explicit_uploads) {
$this->explicitUploads = $explicit_uploads;
return $this;
@@ -213,34 +233,34 @@
$where[] = $this->buildPagingClause($conn_r);
- if ($this->ids) {
+ if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'f.id IN (%Ld)',
$this->ids);
}
- if ($this->phids) {
+ if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'f.phid IN (%Ls)',
$this->phids);
}
- if ($this->authorPHIDs) {
+ if ($this->authorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'f.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
- if ($this->explicitUploads) {
+ if ($this->explicitUploads !== null) {
$where[] = qsprintf(
$conn_r,
'f.isExplicitUpload = true');
}
- if ($this->transforms) {
+ if ($this->transforms !== null) {
$clauses = array();
foreach ($this->transforms as $transform) {
if ($transform['transform'] === true) {
@@ -259,27 +279,55 @@
$where[] = qsprintf($conn_r, '(%Q)', implode(') OR (', $clauses));
}
- if ($this->dateCreatedAfter) {
+ if ($this->dateCreatedAfter !== null) {
$where[] = qsprintf(
$conn_r,
'f.dateCreated >= %d',
$this->dateCreatedAfter);
}
- if ($this->dateCreatedBefore) {
+ if ($this->dateCreatedBefore !== null) {
$where[] = qsprintf(
$conn_r,
'f.dateCreated <= %d',
$this->dateCreatedBefore);
}
- if ($this->contentHashes) {
+ if ($this->contentHashes !== null) {
$where[] = qsprintf(
$conn_r,
'f.contentHash IN (%Ls)',
$this->contentHashes);
}
+ if ($this->minLength !== null) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'byteSize >= %d',
+ $this->minLength);
+ }
+
+ if ($this->maxLength !== null) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'byteSize <= %d',
+ $this->maxLength);
+ }
+
+ if ($this->names !== null) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'name in (%Ls)',
+ $this->names);
+ }
+
+ if ($this->isPartial !== null) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'isPartial = %d',
+ (int)$this->isPartial);
+ }
+
return $this->formatWhereClause($where);
}
diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php
--- a/src/applications/files/storage/PhabricatorFile.php
+++ b/src/applications/files/storage/PhabricatorFile.php
@@ -292,9 +292,10 @@
} else {
// See PhabricatorChunkedFileStorageEngine::getChunkedHash() for some
// discussion of this.
- $file->setContentHash(
- PhabricatorHash::digest(
- Filesystem::readRandomBytes(64)));
+ $seed = Filesystem::readRandomBytes(64);
+ $hash = PhabricatorChunkedFileStorageEngine::getChunkedHashForInput(
+ $seed);
+ $file->setContentHash($hash);
}
$file->setStorageEngine($engine->getEngineIdentifier());

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 22, 12:50 AM (19 h, 7 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6916775
Default Alt Text
D12070.diff (8 KB)

Event Timeline