Skip to content

Commit

Permalink
check the location header
Browse files Browse the repository at this point in the history
Signed-off-by: nabim777 <[email protected]>
  • Loading branch information
nabim777 committed Dec 24, 2024
1 parent 7058ea3 commit b79bb57
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 178 deletions.
275 changes: 113 additions & 162 deletions tests/acceptance/TestHelpers/TusClientWrapper.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
<?php
<?php declare(strict_types=1);
/**
* ownCloud
*
* @author Nabin Magar <[email protected]>
* @copyright Copyright (c) 2017 Nabin Magar [email protected]
*
* 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 http\Env\Response;
Expand All @@ -11,172 +32,102 @@
use GuzzleHttp\ClientTrait;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\ClientException;
use Psr\Http\Message\ResponseInterface;
use TusPhp\Exception\ConnectionException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\ConnectException;
use Symfony\Component\HttpFoundation\Response as HttpResponse;
use ReflectionException;
use TusPhp\Tus\Client;

class TusClientWrapper extends Client{
public $client;

/**
* Constructor for the TusClientWrapper.
*
* @param string $baseUri Base URI of the TUS server.
* @param array $options Additional client options.
* @throws ReflectionException
*/
public function __construct(string $baseUri, array $options = []) {
parent::__construct($baseUri,$options);
$this->client = new Client($baseUri,$options);
}

public function setKey(string $key): self
{
$this->client->setKey($key);
return $this;
}

public function file(string $file, string $name = null): self
{
$this->client->file($file,$name);
return $this;
}

public function createWithUpload(string $key, int $bytes = -1): array {
$bytes = $bytes < 0 ? $this->fileSize : $bytes;
$headers = $this->headers + [
'Upload-Length' => $this->client->fileSize,
'Upload-Key' => $key,
'Upload-Checksum' => $this->client->getUploadChecksumHeader(),
'Upload-Metadata' => $this->client->getUploadMetadataHeader(),
];

$data = '';
if ($bytes > 0) {
$data = $this->client->getData(0, $bytes);

$headers += [
'Content-Type' => self::HEADER_CONTENT_TYPE,
'Content-Length' => \strlen($data),
];
}

if ($this->isPartial()) {
$headers += ['Upload-Concat' => 'partial'];
}

try {
$response = $this->client->getClient()->post($this->apiPath, [
'body' => $data,
'headers' => $headers,
]);
} catch (ClientException $e) {
$response = $e->getResponse();
}

$statusCode = $response->getStatusCode();
$header = $response->getHeaders();


if (HttpResponse::HTTP_CREATED !== $statusCode) {
throw new FileException('Unable to create resource.');
}

$uploadOffset = $bytes > 0 ? current($response->getHeader('upload-offset')) : 0;
$uploadLocation = current($response->getHeader('location'));

$this->getCache()->set($this->client->getKey(), [
'location' => $uploadLocation,
'expires_at' => Carbon::now()->addSeconds($this->getCache()->getTtl())->format($this->getCache()::RFC_7231),
]);

return [
'location' => $uploadLocation,
'offset' => $uploadOffset,
];
}

// /**
// * Set API path.
// *
// * @param string $path
// *
// * @return self
// */
// public function setApiPath(string $path): self
// {
// $this->client->apiPath = $path;
// return $this;
// }

// public function setApiPath(string $path): self
// {
// $this->client->apiPath = $path;
// return $this;
// }

// public function setKey(string $key): self
// {
// $this->client->setKey($key);
// return $this;
// }

// public function file(string $file, string $name = null): self
// {
// $this->client->file($file,$name);
// return $this;
// }

// public function createWithUpload(string $key, int $bytes = -1): void
// {
// $this->client->createWithUpload($key,$bytes);
// }

// public function setHeaders(array $headers): void {
// $this->client->setHeaders($headers);
// }
//
// public function upload(string $filePath): string {
// $this->client->setFilePath($filePath);
// return $this->client->upload();
// }
//
// public function getOffset(): int {
// return $this->client->getOffset();
// }
//
// public function setChunkSize(int $bytes): void {
// $this->client->setChunkSize($bytes);
// }
//
// public function terminateUpload(string $uploadUrl): void {
// $this->client->terminate($uploadUrl);
// }
//
// public function setKey(string $key): self
// {
// $this->client->key = $key;
//
// return $this;
// }
//
// public function file(string $file, string $name = null): self
// {
// $this->filePath = $file;
//
// if ( ! file_exists($file) || ! is_readable($file)) {
// throw new FileException('Cannot read file: ' . $file);
// }
//
// $this->fileName = $name ?? basename($this->filePath);
// $this->fileSize = filesize($file);
//
// $this->addMetadata('filename', $this->fileName);
//
// return $this;
// }

/**
* A helper class where TUS is wrapped and done API requests
*/

class TusClientWrapper extends Client {
public $client;

/**
* Constructor for the TusClientWrapper.
*
* @param string $baseUri
* @param array $options
* @throws ReflectionException
*/
public function __construct(string $baseUri, array $options = []) {
parent::__construct($baseUri, $options);
$this->client = new Client($baseUri, $options);
}

public function setKey(string $key): self {
$this->client->setKey($key);
return $this;
}

public function file(string $file, string $name = null): self {
$this->client->file($file, $name);
return $this;
}

/**
* @param string $key
* @param int $bytes
*
* @return ResponseInterface
* @throws GuzzleException
*/
public function createWithUploadResponse(string $key, int $bytes = -1): ResponseInterface {
$bytes = $bytes < 0 ? $this->fileSize : $bytes;
$headers = $this->headers + [
'Upload-Length' => $this->client->fileSize,
'Upload-Key' => $key,
'Upload-Checksum' => $this->client->getUploadChecksumHeader(),
'Upload-Metadata' => $this->client->getUploadMetadataHeader(),
];

$data = '';
if ($bytes > 0) {
$data = $this->client->getData(0, $bytes);

$headers += [
'Content-Type' => self::HEADER_CONTENT_TYPE,
'Content-Length' => \strlen($data),
];
}

if ($this->isPartial()) {
$headers += ['Upload-Concat' => 'partial'];
}

try {
$response = $this->client->getClient()->post(
$this->apiPath,
[
'body' => $data,
'headers' => $headers,
]
);
} catch (ClientException $e) {
$response = $e->getResponse();
}

$statusCode = $response->getStatusCode();
$header = $response->getHeaders();

if ($statusCode !== HttpResponse::HTTP_CREATED) {
throw new FileException('Unable to create resource.');
}

$uploadOffset = $bytes > 0 ? current($response->getHeader('upload-offset')) : 0;
$uploadLocation = current($response->getHeader('location'));

$this->getCache()->set(
$this->client->getKey(),
[
'location' => $uploadLocation,
'expires_at' => Carbon::now()->addSeconds($this->getCache()->getTtl())->format($this->getCache()::RFC_7231),
]
);
return $response;
}
}
5 changes: 3 additions & 2 deletions tests/acceptance/bootstrap/SpacesTUSContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,16 @@ public function userUploadsAFileViaTusInsideOfTheSpaceUsingTheWebdavApi(
* @param string $password
*
* @return void
* @throws Exception
* @throws Exception|GuzzleException
*/
public function thePublicUploadsFileViaTusInsideLastSharedFolderWithPasswordUsingTheWebdavApi(
string $source,
string $destination,
string $password
): void {
$this->tusContext->publicUploadFileUsingTus($source, $destination, $password);
$response = $this->tusContext->publicUploadFileUsingTus($source, $destination, $password);
$this->featureContext->setLastUploadDeleteTime(\time());
$this->featureContext->setResponse($response);
}

/**
Expand Down
29 changes: 16 additions & 13 deletions tests/acceptance/bootstrap/TUSContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,15 @@ public function uploadFileUsingTus(
* @param string $destination
* @param string $password
*
* @return void
* @return ResponseInterface
* @throws GuzzleException
* @throws ReflectionException
*/
public function publicUploadFileUsingTus(
string $source,
string $destination,
string $password,
): void {
): ResponseInterface {
$password = $this->featureContext->getActualPassword($password);
if ($this->featureContext->isUsingSharingNG()) {
$token = $this->featureContext->shareNgGetLastCreatedLinkShareToken();
Expand All @@ -357,17 +359,18 @@ public function publicUploadFileUsingTus(
$sourceFile = $this->featureContext->acceptanceTestsDirLocation() . $source;
$url = WebdavHelper::getDavPath(WebDavHelper::DAV_VERSION_SPACES, $token, "public-files");

$tusWrapper = new TusClientWrapper(
$this->featureContext->getBaseUrl(),
[
'verify' => false,
'headers' => $headers
]
);

$tusWrapper->setApiPath($url);
$tusWrapper->setKey((string)rand())->file($sourceFile, $destination);
$tusWrapper->file($sourceFile, $destination)->createWithUpload("", 0);
$tusWrapper = new TusClientWrapper(
$this->featureContext->getBaseUrl(),
[
'verify' => false,
'headers' => $headers
]
);

$tusWrapper->setApiPath($url);
$tusWrapper->setKey((string)rand())->file($sourceFile, $destination);
$response = $tusWrapper->file($sourceFile, $destination)->createWithUploadResponse("", 0);
return $response;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,11 @@ Feature: upload resources on share using TUS protocol
| permissionsRole | createOnly |
| password | %public% |
When the public uploads file "filesForUpload/zerobyte.txt" to "textfile.txt" via TUS inside last link shared folder with password "%public%" using the WebDAV API
Then for user "Alice" the space "Project" should contain these files:
Then the HTTP status code should be "201"
And the following headers should be set
| header | value |
| Access-Control-Expose-Headers | Tus-Resumable, Upload-Offset, Location |
And for user "Alice" the space "Project" should contain these files:
| textfile.txt |
And for user "Alice" the space "Project" should not contain these files:
| textfile (1).txt |

0 comments on commit b79bb57

Please sign in to comment.