Added the first cdn

This commit is contained in:
Mathias Wagner 2022-07-19 21:10:42 +02:00
parent dd94bf8159
commit 4b9abfd36d
10 changed files with 546 additions and 0 deletions

8
ContentDeliveryV1/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

8
ContentDeliveryV1/.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/sheepstar-api.iml" filepath="$PROJECT_DIR$/.idea/sheepstar-api.iml" />
</modules>
</component>
</project>

4
ContentDeliveryV1/.idea/php.xml generated Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpProjectSharedConfiguration" php_language_level="7.4" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
ContentDeliveryV1/.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,75 @@
<?php
function load($class) { include __DIR__."/../util/".$class.".php"; }
function sendJSON($code, $message) {
header("Content-Type: ".MimeTypes::getType("json"));
echo json_encode(array("code" => $code, "message" => $message));
exit(0);
}
spl_autoload_register('load');
DB::init("localhost", "nutzername", "passwort", "datenbank");
$media_dir = "/mnt/cdn/";
function checkAPIKey(): string {
if (isset($_SERVER['HTTP_API_KEY'])) {
if (DB::get()->query("SELECT null FROM api_keys WHERE apikey=?", $_SERVER['HTTP_API_KEY'])->numRows() != 1)
sendJSON(502, "You need to provide an valid api key.");
} else sendJSON(502, "You need to provide an valid api key.");
return $_SERVER['HTTP_API_KEY'];
}
Router::add("/upload", function () use ($media_dir) {
$key = checkAPIKey();
if(!empty($_FILES['asset'])) {
$fileID = substr(number_format(time() * mt_rand(),0,'',''),0,16);
$path = $media_dir.$fileID;
$asset = $_FILES['asset'];
$fileName = $asset['name'];
if(move_uploaded_file($_FILES['asset']['tmp_name'], $path)) {
$split = explode(".", $fileName);
$fileEnding = substr($split[count($split)-1], -5);
DB::get()->query("INSERT INTO media (assetID, assetEnding, assetOwner, assetName, assetDescription) VALUES (?, ?, ?, ?, ?)",
$fileID, $fileEnding, $key, $fileName, "test");
sendJSON(1, "https://cdn.sheepstar.xyz/".$fileID.".".$fileEnding);
} else {
sendJSON(500, "File upload failed");
}
}
}, "post");
Router::add("/delete", function () use ($media_dir) {
checkAPIKey();
parse_str(file_get_contents("php://input"),$post_vars);
if (isset($post_vars['assetID'])) {
$assetID = $post_vars['assetID'];
$query = DB::get()->query("SELECT null FROM media WHERE assetID=?", $assetID)->numRows();
if ($query) {
unlink($media_dir.$assetID);
DB::get()->query("DELETE FROM media WHERE assetID=?", $assetID);
sendJSON(1, "Resource deleted.");
} else sendJSON(404, "Resource not found.");
} else sendJSON(405, "Please provide an assetID.");
}, "delete");
Router::add("^/[0-9]+\.[a-zA-Z1-9]+$", function () use ($media_dir) {
$parsed_url = parse_url($_SERVER['REQUEST_URI']);
$url = str_replace("/", "", $parsed_url['path']);
$split = explode(".", $url);
$assetID = $split[0];
$assetEnding = $split[count($split)-1];
$query = DB::get()->query("SELECT null FROM media WHERE assetID=? AND assetEnding=?", $assetID, $assetEnding)->numRows();
if ($query == 1) {
header("Content-Type: " . MimeTypes::getFromString($url));
echo file_get_contents($media_dir.$assetID);
} else sendJSON(404, "Resource not found.");
});
Router::add(".+", function () {
sendJSON(402, "Please use the correct URL format");
});
Router::run();

View File

@ -0,0 +1,15 @@
<?php
class DB {
private static MySQL $database;
public static function get(): MySQL {
return self::$database;
}
public static function init($hostname = "localhost", $username = "root", $password, $database) {
self::$database = new MySQL($hostname, $username, $password, $database);
}
}

View File

@ -0,0 +1,201 @@
<?php
class MimeTypes {
private static string $plain = "text/plain";
private static array $mimeTypes = array(
'jar' => 'application/java-archive',
'hqx' => 'application/mac-binhex40',
'cpt' => 'application/mac-compactpro',
'doc' => 'application/msword',
'dat' => 'application/octet-stream',
'oda' => 'application/oda',
'ogg' => 'application/ogg',
'pdf' => 'application/pdf',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'rdf' => 'application/rdf+xml',
'rss' => 'application/rss+xml',
'smi' => 'application/smil',
'smil' => 'application/smil',
'gram' => 'application/srgs',
'grxml' => 'application/srgs+xml',
'kml' => 'application/vnd.google-earth.kml+xml',
'kmz' => 'application/vnd.google-earth.kmz',
'mif' => 'application/vnd.mif',
'xul' => 'application/vnd.mozilla.xul+xml',
'xls' => 'application/vnd.ms-excel',
'xlb' => 'application/vnd.ms-excel',
'xlt' => 'application/vnd.ms-excel',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
'ppt' => 'application/vnd.ms-powerpoint',
'pps' => 'application/vnd.ms-powerpoint',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'otg' => 'application/vnd.oasis.opendocument.graphics-template',
'odi' => 'application/vnd.oasis.opendocument.image',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'otp' => 'application/vnd.oasis.opendocument.presentation-template',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
'odt' => 'application/vnd.oasis.opendocument.text',
'odm' => 'application/vnd.oasis.opendocument.text-master',
'ott' => 'application/vnd.oasis.opendocument.text-template',
'oth' => 'application/vnd.oasis.opendocument.text-web',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'vsd' => 'application/vnd.visio',
'wbxml' => 'application/vnd.wap.wbxml',
'wmlc' => 'application/vnd.wap.wmlc',
'wmlsc' => 'application/vnd.wap.wmlscriptc',
'vxml' => 'application/voicexml+xml',
'bcpio' => 'application/x-bcpio',
'vcd' => 'application/x-cdlink',
'pgn' => 'application/x-chess-pgn',
'cpio' => 'application/x-cpio',
'csh' => 'application/x-csh',
'dcr' => 'application/x-director',
'dir' => 'application/x-director',
'dxr' => 'application/x-director',
'dvi' => 'application/x-dvi',
'spl' => 'application/x-futuresplash',
'tgz' => 'application/x-gtar',
'gtar' => 'application/x-gtar',
'latex' => 'application/x-latex',
'nc' => 'application/x-netcdf',
'cdf' => 'application/x-netcdf',
'sh' => 'application/x-sh',
'shar' => 'application/x-shar',
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'sv4cpio' => 'application/x-sv4cpio',
'sv4crc' => 'application/x-sv4crc',
'tar' => 'application/x-tar',
'tcl' => 'application/x-tcl',
'tex' => 'application/x-tex',
'texinfo' => 'application/x-texinfo',
'texi' => 'application/x-texinfo',
't' => 'application/x-troff',
'tr' => 'application/x-troff',
'roff' => 'application/x-troff',
'man' => 'application/x-troff-man',
'me' => 'application/x-troff-me',
'ms' => 'application/x-troff-ms',
'ustar' => 'application/x-ustar',
'src' => 'application/x-wais-source',
'xml' => 'application/xml',
'xsl' => 'application/xml',
'dtd' => 'application/xml-dtd',
'zip' => 'application/zip',
'au' => 'audio/basic',
'snd' => 'audio/basic',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'kar' => 'audio/midi',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
'mp3' => 'audio/mpeg',
'mp4' => 'video/mp4',
'aif' => 'audio/x-aiff',
'aiff' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
'm3u' => 'audio/x-mpegurl',
'wma' => 'audio/x-ms-wma',
'wax' => 'audio/x-ms-wax',
'ram' => 'audio/x-pn-realaudio',
'ra' => 'audio/x-pn-realaudio',
'rm' => 'application/vnd.rn-realmedia',
'wav' => 'audio/x-wav',
'pdb' => 'chemical/x-pdb',
'xyz' => 'chemical/x-xyz',
'bmp' => 'image/bmp',
'cgm' => 'image/cgm',
'gif' => 'image/gif',
'ief' => 'image/ief',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'png' => 'image/png',
'svg' => 'image/svg+xml',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'djvu' => 'image/vnd.djvu',
'djv' => 'image/vnd.djvu',
'wbmp' => 'image/vnd.wap.wbmp',
'ras' => 'image/x-cmu-raster',
'ico' => 'image/x-icon',
'pnm' => 'image/x-portable-anymap',
'pbm' => 'image/x-portable-bitmap',
'pgm' => 'image/x-portable-graymap',
'ppm' => 'image/x-portable-pixmap',
'rgb' => 'image/x-rgb',
'xbm' => 'image/x-xbitmap',
'psd' => 'image/x-photoshop',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'eml' => 'message/rfc822',
'igs' => 'model/iges',
'iges' => 'model/iges',
'msh' => 'model/mesh',
'mesh' => 'model/mesh',
'silo' => 'model/mesh',
'wrl' => 'model/vrml',
'vrml' => 'model/vrml',
'ics' => 'text/calendar',
'ifb' => 'text/calendar',
'csv' => 'text/csv',
'rtx' => 'text/richtext',
'rtf' => 'text/rtf',
'sgml' => 'text/sgml',
'sgm' => 'text/sgml',
'tsv' => 'text/tab-separated-values',
'wml' => 'text/vnd.wap.wml',
'wmls' => 'text/vnd.wap.wmlscript',
'etx' => 'text/x-setext',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpe' => 'video/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'mxu' => 'video/vnd.mpegurl',
'm4u' => 'video/vnd.mpegurl',
'flv' => 'video/x-flv',
'json' => 'application/json',
'py' => 'text/x-python',
'avi' => 'video/x-msvideo',
'ogv' => 'video/ogg',
'movie' => 'video/x-sgi-movie',
);
public static function getType(string $ending): string {
if (isset(self::$mimeTypes[strtolower($ending)])) {
return self::$mimeTypes[strtolower($ending)];
} else return self::$plain;
}
public static function getFromString(string $string): string {
if ($string) {
$splitted = explode(".", $string);
return self::getType($splitted[sizeof($splitted)-1]);
} else return self::$plain;
}
}

View File

@ -0,0 +1,131 @@
<?php
class MySQL {
protected $connection;
protected $query;
protected $show_errors = TRUE;
protected $query_closed = TRUE;
public $query_count = 0;
public function __construct($dbhost, $dbuser, $dbpass = '', $dbname = '', $charset = 'utf8') {
$this->connection = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($this->connection->connect_error) {
$this->error('Failed to connect to MySQL - ' . $this->connection->connect_error);
}
$this->connection->set_charset($charset);
}
public function query($query) {
if (!$this->query_closed) {
$this->query->close();
}
if ($this->query = $this->connection->prepare($query)) {
if (func_num_args() > 1) {
$x = func_get_args();
$args = array_slice($x, 1);
$types = '';
$args_ref = array();
foreach ($args as $k => &$arg) {
if (is_array($args[$k])) {
foreach ($args[$k] as $j => &$a) {
$types .= $this->_gettype($args[$k][$j]);
$args_ref[] = &$a;
}
} else {
$types .= $this->_gettype($args[$k]);
$args_ref[] = &$arg;
}
}
array_unshift($args_ref, $types);
call_user_func_array(array($this->query, 'bind_param'), $args_ref);
}
$this->query->execute();
if ($this->query->errno) {
$this->error('Unable to process MySQL query (check your params) - ' . $this->query->error);
}
$this->query_closed = FALSE;
$this->query_count++;
} else {
$this->error('Unable to prepare MySQL statement (check your syntax) - ' . $this->connection->error);
}
return $this;
}
public function fetchAll($callback = null) {
$params = array();
$row = array();
$meta = $this->query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($this->query, 'bind_result'), $params);
$result = array();
while ($this->query->fetch()) {
$r = array();
foreach ($row as $key => $val) {
$r[$key] = $val;
}
if ($callback != null && is_callable($callback)) {
$value = call_user_func($callback, $r);
if ($value == 'break') break;
} else {
$result[] = $r;
}
}
$this->query->close();
$this->query_closed = TRUE;
return $result;
}
public function fetchArray() {
$params = array();
$row = array();
$meta = $this->query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($this->query, 'bind_result'), $params);
$result = array();
while ($this->query->fetch()) {
foreach ($row as $key => $val) {
$result[$key] = $val;
}
}
$this->query->close();
$this->query_closed = TRUE;
return $result;
}
public function close() {
return $this->connection->close();
}
public function numRows() {
$this->query->store_result();
return $this->query->num_rows;
}
public function affectedRows() {
return $this->query->affected_rows;
}
public function lastInsertID() {
return $this->connection->insert_id;
}
public function error($error) {
if ($this->show_errors) {
exit($error);
}
}
private function _gettype($var) {
if (is_string($var)) return 's';
if (is_float($var)) return 'd';
if (is_int($var)) return 'i';
return 'b';
}
}

View File

@ -0,0 +1,90 @@
<?php
class Router {
private static $routes = Array();
private static $pathNotFound = null;
private static $methodNotAllowed = null;
public static function add($expression, $function, $method = 'get'){
array_push(self::$routes,Array(
'expression' => $expression,
'function' => $function,
'method' => $method
));
}
public static function pathNotFound($function){
self::$pathNotFound = $function;
}
public static function methodNotAllowed($function){
self::$methodNotAllowed = $function;
}
public static function run($basepath = '/'){
$parsed_url = parse_url($_SERVER['REQUEST_URI']);
if(isset($parsed_url['path'])){
$path = $parsed_url['path'];
}else{
$path = '/';
}
$method = $_SERVER['REQUEST_METHOD'];
$path_match_found = false;
$route_match_found = false;
foreach(self::$routes as $route){
if($basepath!=''&&$basepath!='/'){
$route['expression'] = '('.$basepath.')'.$route['expression'];
}
$route['expression'] = '^'.$route['expression'];
$route['expression'] = $route['expression'].'$';
if(preg_match('#'.$route['expression'].'#',$path,$matches)){
$path_match_found = true;
if(strtolower($method) == strtolower($route['method'])){
array_shift($matches);
if($basepath!=''&&$basepath!='/'){
array_shift($matches);
}
call_user_func_array($route['function'], $matches);
$route_match_found = true;
break;
}
}
}
if(!$route_match_found){
if($path_match_found){
header("HTTP/1.0 405 Method Not Allowed");
if(self::$methodNotAllowed){
call_user_func_array(self::$methodNotAllowed, Array($path,$method));
}
}else{
header("HTTP/1.0 404 Not Found");
if(self::$pathNotFound){
call_user_func_array(self::$pathNotFound, Array($path));
}
}
}
}
}