Initial commit
This commit is contained in:
132
app/Services/FileServersService.php
Normal file
132
app/Services/FileServersService.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\EntryFile;
|
||||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class FileServersService {
|
||||
|
||||
public const FAVORITE_SERVER_TIME = 3600; // In seconds.
|
||||
private const ZEUS_TOKEN_EXPIRATION = 600; // In seconds.
|
||||
|
||||
private string $apiKey;
|
||||
private array $servers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->apiKey = config('fileservers.secret_key');
|
||||
$this->servers = config('fileservers.servers');
|
||||
}
|
||||
|
||||
public function generateZeusToken( int $user_id, string $to, string $action ){
|
||||
|
||||
$info = [
|
||||
'user_id' => $user_id,
|
||||
'to' => $to,
|
||||
'action' => $action,
|
||||
'generated_at' => time(),
|
||||
'expires_at' => time() + self::ZEUS_TOKEN_EXPIRATION,
|
||||
'romhackplaza' => bin2hex(random_bytes(16)),
|
||||
];
|
||||
|
||||
$json = json_encode( $info );
|
||||
$sig = hash_hmac( 'sha256', $json, $this->apiKey );
|
||||
|
||||
$end = base64_encode( $json ) . "|" . $sig;
|
||||
return $end;
|
||||
}
|
||||
|
||||
public function getRandomServerKey(): string
|
||||
{
|
||||
$keys = array_keys($this->servers);
|
||||
return $keys[array_rand($keys)];
|
||||
}
|
||||
|
||||
public function getEntryFileServerKey( EntryFile $file ): string
|
||||
{
|
||||
$serverKey = null;
|
||||
|
||||
if( $file->favorite_server !== null && $file->favorite_at !== null ) {
|
||||
if( time() < $file->favorite_at + static::FAVORITE_SERVER_TIME ) {
|
||||
$serverKey = $file->favorite_server;
|
||||
}
|
||||
}
|
||||
if( $serverKey === null || !isset( $this->servers[$serverKey] ) ) {
|
||||
$serverKey = $this->getRandomServerKey();
|
||||
}
|
||||
|
||||
return $serverKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download URL requires 'filepath' and 'filename'.
|
||||
*
|
||||
* @param EntryFile $file
|
||||
* @return string
|
||||
*/
|
||||
public function getDownloadFileUrl( EntryFile $file ): string
|
||||
{
|
||||
$serverKey = $this->getEntryFileServerKey( $file );
|
||||
$url = $this->servers[$serverKey]['download'] ?? "#";
|
||||
if( $url === "#" )
|
||||
return $url;
|
||||
|
||||
return $url . "&" . http_build_query( [ 'filename' => $file->filename, 'filepath' => $file->filepath ] );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ConnectionException
|
||||
*/
|
||||
public function uploadChunk(
|
||||
UploadedFile $chunk,
|
||||
string $fileUUID,
|
||||
int $currentChunk,
|
||||
int $totalChunks,
|
||||
string $filename,
|
||||
string $type
|
||||
){
|
||||
|
||||
// Define or get favorite server.
|
||||
if( $currentChunk === 0 ){
|
||||
$serverKey = $this->getRandomServerKey();
|
||||
Cache::put("favorite_server_{$fileUUID}", $serverKey, now()->addHours(2) );
|
||||
} else {
|
||||
$serverKey = Cache::get( "favorite_server_{$fileUUID}" );
|
||||
abort_if( !$serverKey, 422, "File upload expired, please retry." );
|
||||
}
|
||||
|
||||
$server = $this->servers[$serverKey];
|
||||
$filepath = $type . '/' . $fileUUID;
|
||||
|
||||
$response = Http::withHeaders([])
|
||||
->attach( 'file', file_get_contents( $chunk->getRealPath() ), $fileUUID )
|
||||
->post( $server['upload_chunk'], [
|
||||
'filepath' => $filepath,
|
||||
'filename' => $filename,
|
||||
'current_chunk' => $currentChunk,
|
||||
'total_chunks' => $totalChunks,
|
||||
// TODO : Must replace User ID
|
||||
'zeus' => $this->generateZeusToken( 0, $server['base_url'], "Uploadchunk" ),
|
||||
]);
|
||||
|
||||
if (!$response->successful()) {
|
||||
throw new \RuntimeException( $response->body() );
|
||||
}
|
||||
|
||||
$data = $response->json();
|
||||
|
||||
if( isset( $data['file'] ) && $data['file'] !== false ){
|
||||
Cache::forget( "favorite_server_{$fileUUID}" );
|
||||
}
|
||||
$data['favorite_server'] = $serverKey;
|
||||
$data['file_uuid'] = $fileUUID;
|
||||
$data['file_path'] = $filepath;
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user