diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php index d3dc5208d2..2b8624b9c0 100644 --- a/src/applications/files/storage/PhabricatorFile.php +++ b/src/applications/files/storage/PhabricatorFile.php @@ -272,8 +272,12 @@ final class PhabricatorFile extends PhabricatorFileDAO $file->setByteSize($length); // NOTE: Once we receive the first chunk, we'll detect its MIME type and - // update the parent file. This matters for large media files like video. - $file->setMimeType('application/octet-stream'); + // update the parent file if a MIME type hasn't been provided. This matters + // for large media files like video. + $mime_type = idx($params, 'mime-type'); + if (!strlen($mime_type)) { + $file->setMimeType('application/octet-stream'); + } $chunked_hash = idx($params, 'chunkedHash'); diff --git a/src/applications/files/uploadsource/PhabricatorFileUploadSource.php b/src/applications/files/uploadsource/PhabricatorFileUploadSource.php index bf213a417e..87a4486869 100644 --- a/src/applications/files/uploadsource/PhabricatorFileUploadSource.php +++ b/src/applications/files/uploadsource/PhabricatorFileUploadSource.php @@ -6,6 +6,8 @@ abstract class PhabricatorFileUploadSource private $name; private $relativeTTL; private $viewPolicy; + private $mimeType; + private $authorPHID; private $rope; private $data; @@ -51,6 +53,24 @@ abstract class PhabricatorFileUploadSource return $this->byteLimit; } + public function setMIMEType($mime_type) { + $this->mimeType = $mime_type; + return $this; + } + + public function getMIMEType() { + return $this->mimeType; + } + + public function setAuthorPHID($author_phid) { + $this->authorPHID = $author_phid; + return $this; + } + + public function getAuthorPHID() { + return $this->authorPHID; + } + public function uploadFile() { if (!$this->shouldChunkFile()) { return $this->writeSingleFile(); @@ -245,6 +265,16 @@ abstract class PhabricatorFileUploadSource $parameters['ttl.relative'] = $ttl; } + $mime_type = $this->getMimeType(); + if ($mime_type !== null) { + $parameters['mime-type'] = $mime_type; + } + + $author_phid = $this->getAuthorPHID(); + if ($author_phid !== null) { + $parameters['authorPHID'] = $author_phid; + } + return $parameters; } diff --git a/src/applications/search/controller/PhabricatorApplicationSearchController.php b/src/applications/search/controller/PhabricatorApplicationSearchController.php index 0402102e2b..e980498c42 100644 --- a/src/applications/search/controller/PhabricatorApplicationSearchController.php +++ b/src/applications/search/controller/PhabricatorApplicationSearchController.php @@ -461,15 +461,20 @@ final class PhabricatorApplicationSearchController $export_result = $format->newFileData(); - $file = PhabricatorFile::newFromFileData( - $export_result, - array( - 'name' => $filename, - 'authorPHID' => $viewer->getPHID(), - 'ttl.relative' => phutil_units('15 minutes in seconds'), - 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE, - 'mime-type' => $mime_type, - )); + // We have all the data in one big string and aren't actually + // streaming it, but pretending that we are allows us to actviate + // the chunk engine and store large files. + $iterator = new ArrayIterator(array($export_result)); + + $source = id(new PhabricatorIteratorFileUploadSource()) + ->setName($filename) + ->setViewPolicy(PhabricatorPolicies::POLICY_NOONE) + ->setMIMEType($mime_type) + ->setRelativeTTL(phutil_units('60 minutes in seconds')) + ->setAuthorPHID($viewer->getPHID()) + ->setIterator($iterator); + + $file = $source->uploadFile(); return $this->newDialog() ->setTitle(pht('Download Results'))