Files
ocis/tests/acceptance/TestHelpers/TusClient.php
2025-06-19 15:34:02 +05:45

138 lines
3.8 KiB
PHP

<?php declare(strict_types=1);
/**
* ownCloud
*
* @author Nabin Magar <nabin@jankaritech.com>
* @copyright Copyright (c) 2025 Nabin Magar nabin@jankaritech.com
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License,
* as published by the Free Software Foundation;
* either version 3 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace TestHelpers;
use Carbon\Carbon;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\GuzzleException;
use TusPhp\Exception\ConnectionException;
use TusPhp\Exception\FileException;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Response as HttpResponse;
use TusPhp\Exception\TusException;
use TusPhp\Tus\Client;
/**
* A TUS client based on TusPhp\Tus\Client
*/
class TusClient extends Client {
/**
* creates a resource with a post request and returns response.
*
* @param string $key
* @param int $bytes
*
* @return ResponseInterface
* @throws GuzzleException
*/
public function createWithUploadRR(string $key, int $bytes = -1): ResponseInterface {
$bytes = $bytes < 0 ? $this->fileSize : $bytes;
$headers = $this->headers + [
'Upload-Length' => $this->fileSize,
'Upload-Key' => $key,
'Upload-Checksum' => $this->getUploadChecksumHeader(),
'Upload-Metadata' => $this->getUploadMetadataHeader(),
];
$data = '';
if ($bytes > 0) {
$data = $this->getData(0, $bytes);
$headers += [
'Content-Type' => self::HEADER_CONTENT_TYPE,
'Content-Length' => \strlen($data),
];
}
if ($this->isPartial()) {
$headers += ['Upload-Concat' => 'partial'];
}
try {
$response = $this->getClient()->post(
$this->apiPath,
[
'body' => $data,
'headers' => $headers,
],
);
} catch (ClientException $e) {
$response = $e->getResponse();
}
if ($response->getStatusCode() === HttpResponse::HTTP_CREATED) {
$uploadLocation = current($response->getHeader('location'));
$this->getCache()->set(
$this->getKey(),
[
'location' => $uploadLocation,
'expires_at' => Carbon::now()->addSeconds(
$this->getCache()->getTtl(),
)->format($this->getCache()::RFC_7231),
],
);
}
return $response;
}
/**
* upload file and returns response.
*
* @param int $bytes
*
* @return ResponseInterface
* @throws GuzzleException
* @throws TusException | ConnectionException
*/
public function uploadRR(int $bytes = -1): ResponseInterface {
$bytes = $bytes < 0 ? $this->getFileSize() : $bytes;
$offset = $this->partialOffset < 0 ? 0 : $this->partialOffset;
try {
// Check if this upload exists with HEAD request.
$offset = $this->sendHeadRequest();
} catch (FileException | ClientException $e) {
// Create a new upload.
$response = $this->createWithUploadRR($this->getKey(), 0);
if ($response->getStatusCode() !== HttpResponse::HTTP_CREATED) {
return $response;
}
}
$data = $this->getData($offset, $bytes);
$headers = $this->headers + [
'Content-Type' => self::HEADER_CONTENT_TYPE,
'Content-Length' => \strlen($data),
'Upload-Checksum' => $this->getUploadChecksumHeader(),
];
if ($this->isPartial()) {
$headers += ['Upload-Concat' => self::UPLOAD_TYPE_PARTIAL];
} else {
$headers += ['Upload-Offset' => $offset];
}
$response = $this->getClient()->patch(
$this->getUrl(),
[
'body' => $data,
'headers' => $headers,
],
);
return $response;
}
}