mirror of
https://github.com/appwrite/appwrite
synced 2026-05-24 09:28:40 +00:00
Add download build endpoint to sites
This commit is contained in:
parent
765d8241f2
commit
bbd589f6a8
3 changed files with 122 additions and 0 deletions
|
|
@ -76,6 +76,7 @@ services:
|
|||
- appwrite-config:/storage/config:rw
|
||||
- appwrite-certificates:/storage/certificates:rw
|
||||
- appwrite-functions:/storage/functions:rw
|
||||
- appwrite-builds:/storage/builds:rw
|
||||
- ./phpunit.xml:/usr/src/code/phpunit.xml
|
||||
- ./tests:/usr/src/code/tests
|
||||
- ./app:/usr/src/code/app
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Sites\Http\Deployments;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\Swoole\Request;
|
||||
|
||||
class DownloadBuild extends Action
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'downloadBuild';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/sites/:siteId/deployments/:deploymentId/build/download')
|
||||
->desc('Download build')
|
||||
->groups(['api', 'sites'])
|
||||
->label('scope', 'functions.read') //TODO: Update the scope to sites later
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'sites')
|
||||
->label('sdk.method', 'getBuildDownload')
|
||||
->label('sdk.description', '/docs/references/sites/get-build-download.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', '*/*')
|
||||
->label('sdk.methodType', 'location')
|
||||
->param('siteId', '', new UID(), 'Site ID.')
|
||||
->param('deploymentId', '', new UID(), 'Deployment ID.')
|
||||
->inject('response')
|
||||
->inject('request')
|
||||
->inject('dbForProject')
|
||||
->inject('deviceForBuilds')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
public function action(string $siteId, string $deploymentId, Response $response, Request $request, Database $dbForProject, Device $deviceForBuilds)
|
||||
{
|
||||
$site = $dbForProject->getDocument('sites', $siteId);
|
||||
if ($site->isEmpty()) {
|
||||
throw new Exception(Exception::SITE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
|
||||
if ($deployment->isEmpty()) {
|
||||
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($deployment->getAttribute('resourceId') !== $site->getId()) {
|
||||
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId'));
|
||||
if ($build->isEmpty()) {
|
||||
throw new Exception(Exception::BUILD_NOT_FOUND);
|
||||
}
|
||||
|
||||
$path = $build->getAttribute('path', '');
|
||||
if (!$deviceForBuilds->exists($path)) {
|
||||
throw new Exception(Exception::BUILD_NOT_FOUND);
|
||||
}
|
||||
|
||||
$response
|
||||
->setContentType('application/gzip')
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache
|
||||
->addHeader('X-Peak', \memory_get_peak_usage())
|
||||
->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"');
|
||||
|
||||
$size = $deviceForBuilds->getFileSize($path);
|
||||
$rangeHeader = $request->getHeader('range');
|
||||
|
||||
if (!empty($rangeHeader)) {
|
||||
$start = $request->getRangeStart();
|
||||
$end = $request->getRangeEnd();
|
||||
$unit = $request->getRangeUnit();
|
||||
|
||||
if ($end === null) {
|
||||
$end = min(($start + MAX_OUTPUT_CHUNK_SIZE - 1), ($size - 1));
|
||||
}
|
||||
|
||||
if ($unit !== 'bytes' || $start >= $end || $end >= $size) {
|
||||
throw new Exception(Exception::STORAGE_INVALID_RANGE);
|
||||
}
|
||||
|
||||
$response
|
||||
->addHeader('Accept-Ranges', 'bytes')
|
||||
->addHeader('Content-Range', 'bytes ' . $start . '-' . $end . '/' . $size)
|
||||
->addHeader('Content-Length', $end - $start + 1)
|
||||
->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT);
|
||||
|
||||
$response->send($deviceForBuilds->read($path, $start, ($end - $start + 1)));
|
||||
}
|
||||
|
||||
if ($size > APP_STORAGE_READ_BUFFER) {
|
||||
for ($i = 0; $i < ceil($size / MAX_OUTPUT_CHUNK_SIZE); $i++) {
|
||||
$response->chunk(
|
||||
$deviceForBuilds->read(
|
||||
$path,
|
||||
($i * MAX_OUTPUT_CHUNK_SIZE),
|
||||
min(MAX_OUTPUT_CHUNK_SIZE, $size - ($i * MAX_OUTPUT_CHUNK_SIZE))
|
||||
),
|
||||
(($i + 1) * MAX_OUTPUT_CHUNK_SIZE) >= $size
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$response->send($deviceForBuilds->read($path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Sites\Services;
|
|||
use Appwrite\Platform\Modules\Sites\Http\Deployments\CancelDeployment;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Deployments\CreateDeployment;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Deployments\DeleteDeployment;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Deployments\DownloadBuild;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Deployments\DownloadDeployment;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Deployments\GetDeployment;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Deployments\ListDeployments;
|
||||
|
|
@ -43,6 +44,7 @@ class Http extends Service
|
|||
$this->addAction(UpdateDeployment::getName(), new UpdateDeployment());
|
||||
$this->addAction(DeleteDeployment::getName(), new DeleteDeployment());
|
||||
$this->addAction(DownloadDeployment::getName(), new DownloadDeployment());
|
||||
$this->addAction(DownloadBuild::getName(), new DownloadBuild());
|
||||
$this->addAction(RebuildDeployment::getName(), new RebuildDeployment());
|
||||
$this->addAction(CancelDeployment::getName(), new CancelDeployment());
|
||||
$this->addAction(CreateVariable::getName(), new CreateVariable());
|
||||
|
|
|
|||
Loading…
Reference in a new issue