$value) { if($key === 'driver' || $key === 'username' || $key === 'password') continue; if($key === 'database') $key = 'dbname'; $dsn .= $key . '=' . $value . ';'; } try { $mszPdo = new \PDO($dsn, $config['username'], $config['password'], DB::FLAGS); } catch(\PDOException $ex) { throw new \Exception('Unable to connect to Misuzu database.'); } return $mszPdo; } function checkSockChatAuth(string $token): int { if(strpos($token, '_') === false) return -1; $mszPdo = connectMszDatabase(); $tokenParts = explode('_', $token, 2); $userId = intval($tokenParts[0] ?? 0); $chatToken = strval($tokenParts[1] ?? ''); $getUserId = $mszPdo->prepare(' SELECT `user_id` FROM `msz_user_chat_tokens` WHERE `user_id` = :user AND `token_string` = :token AND `token_created` > NOW() - INTERVAL 1 WEEK '); $getUserId->bindValue('user', $userId); $getUserId->bindValue('token', $chatToken); $getUserId->execute(); return (int)$getUserId->fetchColumn(); } function checkMszAuth(string $token): int { $packed = Base64::decode($token, true); $packed = str_pad($packed, 37, "\x00"); $unpacked = unpack('Cversion/Nuser/H64token', $packed); if($unpacked['version'] !== 1) return -1; $getUserId = connectMszDatabase()->prepare(' SELECT `user_id` FROM `msz_sessions` WHERE `user_id` = :user AND `session_key` = :token AND `session_expires` > NOW() '); $getUserId->bindValue('user', $unpacked['user']); $getUserId->bindValue('token', $unpacked['token']); $getUserId->execute(); return (int)$getUserId->fetchColumn(); } if(!isset($isShortDomain) && !empty($_SERVER['HTTP_AUTHORIZATION'])) { $authParts = explode(' ', $_SERVER['HTTP_AUTHORIZATION'], 2); $authMethod = strval($authParts[0] ?? ''); $authToken = strval($authParts[1] ?? ''); switch($authMethod) { case 'SockChat': $authUserId = checkSockChatAuth($authToken); break; case 'Misuzu': $authUserId = checkMszAuth($authToken); break; } if(isset($authUserId) && $authUserId > 0) User::byId($authUserId)->setActive(); } if(preg_match('#^/uploads/([a-zA-Z0-9-_]{32})(\.t)?/?$#', $reqPath, $matches)) { $getNormal = empty($matches[2]); $getThumbnail = isset($matches[2]) && $matches[2] === '.t'; try { $uploadInfo = Upload::byId($matches[1]); } catch(UploadNotFoundException $ex) { http_response_code(404); echo 'File not found.'; return; } if($uploadInfo->isDMCA()) { http_response_code(451); echo 'File is unavailable for copyright reasons.'; return; } if($uploadInfo->isDeleted() || $uploadInfo->hasExpired()) { http_response_code(404); echo 'File not found.'; return; } if($reqMethod === 'DELETE') { if(!User::hasActive()) { http_response_code(401); return; } if(User::active()->isRestricted() || User::active()->getId() !== $uploadInfo->getUserId()) { http_response_code(403); return; } http_response_code(204); $uploadInfo->delete(false); return; } if(!is_file($uploadInfo->getPath())) { http_response_code(404); echo 'Data is missing.'; return; } if($getNormal) { $uploadInfo->bumpAccess(); $uploadInfo->bumpExpiry(); } $contentType = $uploadInfo->getType(); if($contentType === 'application/octet-stream' || substr($contentType, 0, 5) === 'text/') $contentType = 'text/plain'; $sourceDir = basename($getThumbnail ? PRM_THUMBS : PRM_UPLOADS); if($getThumbnail) { if(substr($contentType, 0, 6) !== 'image/') { http_response_code(404); echo 'Thumbnails are not supported for this filetype.'; return; } try { $imagick = new \Imagick($uploadInfo->getPath()); $imagick->setImageFormat('jpg'); $imagick->setImageCompressionQuality(40); $thumbRes = 100; $width = $imagick->getImageWidth(); $height = $imagick->getImageHeight(); if ($width > $height) { $resizeWidth = $width * $thumbRes / $height; $resizeHeight = $thumbRes; } else { $resizeWidth = $thumbRes; $resizeHeight = $height * $thumbRes / $width; } $imagick->resizeImage( $resizeWidth, $resizeHeight, \Imagick::FILTER_GAUSSIAN, 0.7 ); $imagick->cropImage( $thumbRes, $thumbRes, ($resizeWidth - $thumbRes) / 2, ($resizeHeight - $thumbRes) / 2 ); $imagick->writeImage($uploadInfo->getThumbPath()); } catch(\Exception $ex) {} } header(sprintf('X-Accel-Redirect: /%s/%s', $sourceDir, $uploadInfo->getId())); header(sprintf('Content-Type: %s', $contentType)); header(sprintf('Content-Disposition: inline; filename="%s"', addslashes($uploadInfo->getName()))); return; } if(preg_match('#^/uploads/([a-zA-Z0-9-_]{32})\.json/?$#', $reqPath, $matches)) { if(isset($isShortDomain)) { http_response_code(404); return; } try { $uploadInfo = Upload::byId($matches[1]); } catch(UploadNotFoundException $ex) { http_response_code(404); return; } header('Content-Type: application/json; charset=utf-8'); echo json_encode($uploadInfo); return; } if($reqPath === '/eeprom.js' && is_file(PRM_ROOT . '/eeprom.js')) { header('Content-Type: application/javascript; charset=utf-8'); echo file_get_contents(PRM_ROOT . '/eeprom.js'); return; } header('Content-Type: text/plain; charset=us-ascii'); if($reqPath === '/' || $reqPath === '/stats' || $reqPath === '/html') { $fileCount = 0; $userCount = 0; $totalSize = 0; $uniqueTypes = 0; $getUploadStats = DB::prepare(' SELECT COUNT(`upload_id`) AS `amount`, SUM(`upload_size`) AS `size`, COUNT(DISTINCT `upload_type`) AS `types` FROM `prm_uploads` WHERE `upload_deleted` IS NULL AND `upload_dmca` IS NULL '); $getUploadStats->execute(); $uploadStats = $getUploadStats->execute() ? $getUploadStats->fetchObject() : null; if(!empty($uploadStats)) { $fileCount = intval($uploadStats->amount); $totalSize = intval($uploadStats->size ?? 0); $uniqueTypes = intval($uploadStats->types ?? 0); } $getUserStats = DB::prepare(' SELECT COUNT(`user_id`) AS `amount` FROM `prm_users` WHERE `user_restricted` IS NULL '); $getUserStats->execute(); $userStats = $getUserStats->execute() ? $getUserStats->fetchObject() : null; if(!empty($userStats)) { $userCount = intval($userStats->amount); } if($reqPath === '/stats') { header('Content-Type: application/json; charset=utf-8'); echo json_encode([ 'files_size' => $totalSize, 'files_count' => $fileCount, 'files_types' => $uniqueTypes, 'users_count' => $userCount, ]); return; } $totalSizeFmt = eepromByteSymbol($totalSize); if($reqPath === '/html') { header('Content-Type: text/html; charset=utf-8'); echo <<
________________ ____ ____ __ ___ / ____/ ____/ __ \/ __ \/ __ \/ |/ / / __/ / __/ / /_/ / /_/ / / / / /|_/ / / /___/ /___/ ____/ _, _/ /_/ / / / / /_____/_____/_/ /_/ |_|\____/_/ /_/ Currently serving {$totalSizeFmt} ({$totalSize} bytes) of {$fileCount} files in {$uniqueTypes} unique file types from {$userCount} users.HTML; return; } echo <<