1
1
Fork 0

Improved http error handling

This commit is contained in:
Michael 2021-10-29 23:21:07 +00:00
parent b2165cdf22
commit 4236a9a105
55 changed files with 282 additions and 135 deletions

View file

@ -51,9 +51,10 @@
* *
*/ */
use Friendica\Network\HTTPException\ForbiddenException;
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden'); throw new ForbiddenException();
exit();
} }
use Dice\Dice; use Dice\Dice;

View file

@ -20,9 +20,10 @@
* *
*/ */
use Friendica\Network\HTTPException\ForbiddenException;
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden'); throw new ForbiddenException();
exit();
} }
use Dice\Dice; use Dice\Dice;

View file

@ -23,9 +23,10 @@
* This script was taken from http://php.net/manual/en/function.pcntl-fork.php * This script was taken from http://php.net/manual/en/function.pcntl-fork.php
*/ */
use Friendica\Network\HTTPException\ForbiddenException;
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden'); throw new ForbiddenException();
exit();
} }
use Dice\Dice; use Dice\Dice;

View file

@ -26,9 +26,10 @@
* *
*/ */
use Friendica\Network\HTTPException\ForbiddenException;
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden'); throw new ForbiddenException();
exit();
} }
if (($_SERVER["argc"] > 1) && isset($_SERVER["argv"][1])) { if (($_SERVER["argc"] > 1) && isset($_SERVER["argv"][1])) {

View file

@ -24,9 +24,10 @@
* Usage: php bin/wait-for-connection {HOST} {PORT} [{TIMEOUT}] * Usage: php bin/wait-for-connection {HOST} {PORT} [{TIMEOUT}]
*/ */
use Friendica\Network\HTTPException\ForbiddenException;
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden'); throw new ForbiddenException();
exit();
} }
$timeout = 60; $timeout = 60;

View file

@ -21,9 +21,10 @@
* Starts the background processing * Starts the background processing
*/ */
use Friendica\Network\HTTPException\ForbiddenException;
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden'); throw new ForbiddenException();
exit();
} }
use Dice\Dice; use Dice\Dice;

View file

@ -246,8 +246,6 @@ function api_login(App $a)
if (!DBA::isResult($record)) { if (!DBA::isResult($record)) {
Logger::debug(API_LOG_PREFIX . 'failed', ['module' => 'api', 'action' => 'login', 'parameters' => $_SERVER]); Logger::debug(API_LOG_PREFIX . 'failed', ['module' => 'api', 'action' => 'login', 'parameters' => $_SERVER]);
header('WWW-Authenticate: Basic realm="Friendica"'); header('WWW-Authenticate: Basic realm="Friendica"');
//header('HTTP/1.0 401 Unauthorized');
//die('This api requires login');
throw new UnauthorizedException("This API requires login"); throw new UnauthorizedException("This API requires login");
} }

View file

@ -29,6 +29,7 @@ use Friendica\Module\Home;
use Friendica\Module\HTTPException\MethodNotAllowed; use Friendica\Module\HTTPException\MethodNotAllowed;
use Friendica\Module\HTTPException\PageNotFound; use Friendica\Module\HTTPException\PageNotFound;
use Friendica\Network\HTTPException\MethodNotAllowedException; use Friendica\Network\HTTPException\MethodNotAllowedException;
use Friendica\Network\HTTPException\NoContentException;
use Friendica\Network\HTTPException\NotFoundException; use Friendica\Network\HTTPException\NotFoundException;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -291,9 +292,8 @@ class Module
// @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
// @todo Check allowed methods per requested path // @todo Check allowed methods per requested path
if ($server['REQUEST_METHOD'] === Router::OPTIONS) { if ($server['REQUEST_METHOD'] === Router::OPTIONS) {
header('HTTP/1.1 204 No Content');
header('Allow: ' . implode(',', Router::ALLOWED_METHODS)); header('Allow: ' . implode(',', Router::ALLOWED_METHODS));
exit(); throw new NoContentException();
} }
$placeholder = ''; $placeholder = '';

View file

@ -21,7 +21,7 @@
namespace Friendica\Core\Cache; namespace Friendica\Core\Cache;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\ServiceUnavailableException;
/** /**
* Trait for Memcache to add a custom version of the * Trait for Memcache to add a custom version of the
@ -52,7 +52,7 @@ trait TraitMemcacheCommand
* *
* @return array All keys of the memcache instance * @return array All keys of the memcache instance
* *
* @throws InternalServerErrorException * @throws ServiceUnavailableException
*/ */
protected function getMemcacheKeys() protected function getMemcacheKeys()
{ {
@ -88,13 +88,13 @@ trait TraitMemcacheCommand
* *
* @return string The returned buffer result * @return string The returned buffer result
* *
* @throws InternalServerErrorException In case the memcache server isn't available (anymore) * @throws ServiceUnavailableException In case the memcache server isn't available (anymore)
*/ */
protected function sendMemcacheCommand(string $command) protected function sendMemcacheCommand(string $command)
{ {
$s = @fsockopen($this->server, $this->port); $s = @fsockopen($this->server, $this->port);
if (!$s) { if (!$s) {
throw new InternalServerErrorException("Cant connect to:" . $this->server . ':' . $this->port); throw new ServiceUnavailableException("Cant connect to:" . $this->server . ':' . $this->port);
} }
fwrite($s, $command . "\r\n"); fwrite($s, $command . "\r\n");

View file

@ -23,7 +23,7 @@ namespace Friendica\Core;
use Exception; use Exception;
use Friendica\DI; use Friendica\DI;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\ServiceUnavailableException;
use Friendica\Render\TemplateEngine; use Friendica\Render\TemplateEngine;
/** /**
@ -69,7 +69,7 @@ class Renderer
* @param string $template * @param string $template
* @param array $vars * @param array $vars
* @return string * @return string
* @throws InternalServerErrorException * @throws ServiceUnavailableException
*/ */
public static function replaceMacros(string $template, array $vars = []) public static function replaceMacros(string $template, array $vars = [])
{ {
@ -87,7 +87,7 @@ class Renderer
$message = is_site_admin() ? $message = is_site_admin() ?
$e->getMessage() : $e->getMessage() :
DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.'); DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.');
throw new InternalServerErrorException($message); throw new ServiceUnavailableException($message);
} }
DI::profiler()->stopRecording(); DI::profiler()->stopRecording();
@ -102,7 +102,7 @@ class Renderer
* @param string $subDir Subdirectory (Optional) * @param string $subDir Subdirectory (Optional)
* *
* @return string template. * @return string template.
* @throws InternalServerErrorException * @throws ServiceUnavailableException
*/ */
public static function getMarkupTemplate($file, $subDir = '') public static function getMarkupTemplate($file, $subDir = '')
{ {
@ -116,7 +116,7 @@ class Renderer
$message = is_site_admin() ? $message = is_site_admin() ?
$e->getMessage() : $e->getMessage() :
DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.'); DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.');
throw new InternalServerErrorException($message); throw new ServiceUnavailableException($message);
} }
DI::profiler()->stopRecording(); DI::profiler()->stopRecording();
@ -128,7 +128,7 @@ class Renderer
* Register template engine class * Register template engine class
* *
* @param string $class * @param string $class
* @throws InternalServerErrorException * @throws ServiceUnavailableException
*/ */
public static function registerTemplateEngine($class) public static function registerTemplateEngine($class)
{ {
@ -143,7 +143,7 @@ class Renderer
$message = is_site_admin() ? $message = is_site_admin() ?
$admin_message : $admin_message :
DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.'); DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.');
throw new InternalServerErrorException($message); throw new ServiceUnavailableException($message);
} }
} }
@ -154,7 +154,7 @@ class Renderer
* or default * or default
* *
* @return TemplateEngine Template Engine instance * @return TemplateEngine Template Engine instance
* @throws InternalServerErrorException * @throws ServiceUnavailableException
*/ */
public static function getTemplateEngine() public static function getTemplateEngine()
{ {
@ -177,7 +177,7 @@ class Renderer
$message = is_site_admin() ? $message = is_site_admin() ?
$admin_message : $admin_message :
DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.'); DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.');
throw new InternalServerErrorException($message); throw new ServiceUnavailableException($message);
} }
/** /**

View file

@ -22,7 +22,10 @@
namespace Friendica\Core; namespace Friendica\Core;
use Friendica\DI; use Friendica\DI;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\BadRequestException;
use Friendica\Network\HTTPException\FoundException;
use Friendica\Network\HTTPException\MovedPermanentlyException;
use Friendica\Network\HTTPException\TemporaryRedirectException;
use Friendica\Util\XML; use Friendica\Util\XML;
/** /**
@ -122,7 +125,9 @@ class System
*/ */
public static function httpExit($val, $message = '', $content = '') public static function httpExit($val, $message = '', $content = '')
{ {
Logger::log('http_status_exit ' . $val); if ($val >= 400) {
Logger::debug('Exit with error', ['code' => $val, 'message' => $message, 'callstack' => System::callstack(20), 'method' => $_SERVER['REQUEST_METHOD'], 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']);
}
header($_SERVER["SERVER_PROTOCOL"] . ' ' . $val . ' ' . $message); header($_SERVER["SERVER_PROTOCOL"] . ' ' . $val . ' ' . $message);
echo $content; echo $content;
@ -132,6 +137,9 @@ class System
public static function jsonError($httpCode, $data, $content_type = 'application/json') public static function jsonError($httpCode, $data, $content_type = 'application/json')
{ {
if ($httpCode >= 400) {
Logger::debug('Exit with error', ['code' => $httpCode, 'content_type' => $content_type, 'callstack' => System::callstack(20), 'method' => $_SERVER['REQUEST_METHOD'], 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']);
}
header($_SERVER["SERVER_PROTOCOL"] . ' ' . $httpCode); header($_SERVER["SERVER_PROTOCOL"] . ' ' . $httpCode);
self::jsonExit($data, $content_type); self::jsonExit($data, $content_type);
} }
@ -222,28 +230,25 @@ class System
* @param string $url The new Location to redirect * @param string $url The new Location to redirect
* @param int $code The redirection code, which is used (Default is 302) * @param int $code The redirection code, which is used (Default is 302)
* *
* @throws InternalServerErrorException If the URL is not fully qualified * @throws BadRequestException If the URL is not fully qualified
*/ */
public static function externalRedirect($url, $code = 302) public static function externalRedirect($url, $code = 302)
{ {
if (empty(parse_url($url, PHP_URL_SCHEME))) { if (empty(parse_url($url, PHP_URL_SCHEME))) {
throw new InternalServerErrorException("'$url' is not a fully qualified URL, please use App->internalRedirect() instead"); throw new BadRequestException("'$url' is not a fully qualified URL, please use App->internalRedirect() instead");
}
switch ($code) {
case 302:
// this is the default code for a REDIRECT
// We don't need a extra header here
break;
case 301:
header('HTTP/1.1 301 Moved Permanently');
break;
case 307:
header('HTTP/1.1 307 Temporary Redirect');
break;
} }
header("Location: $url"); header("Location: $url");
switch ($code) {
case 302:
throw new FoundException();
case 301:
throw new MovedPermanentlyException();
case 307:
throw new TemporaryRedirectException();
}
exit(); exit();
} }

View file

@ -23,7 +23,7 @@ namespace Friendica\Database;
use Friendica\Core\Config\Cache; use Friendica\Core\Config\Cache;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\ServiceUnavailableException;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use mysqli; use mysqli;
@ -520,7 +520,7 @@ class Database
$called_from_e = ($called_from['function'] == 'e'); $called_from_e = ($called_from['function'] == 'e');
if (!isset($this->connection)) { if (!isset($this->connection)) {
throw new InternalServerErrorException('The Connection is empty, although connected is set true.'); throw new ServiceUnavailableException('The Connection is empty, although connected is set true.');
} }
switch ($this->driver) { switch ($this->driver) {

View file

@ -23,7 +23,7 @@ namespace Friendica\Factory\Api\Mastodon;
use Friendica\BaseFactory; use Friendica\BaseFactory;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\UnprocessableEntityException;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
class Application extends BaseFactory class Application extends BaseFactory
@ -42,13 +42,13 @@ class Application extends BaseFactory
* *
* @return \Friendica\Object\Api\Mastodon\Application * @return \Friendica\Object\Api\Mastodon\Application
* *
* @throws InternalServerErrorException * @throws UnprocessableEntityException
*/ */
public function createFromApplicationId(int $id): \Friendica\Object\Api\Mastodon\Application public function createFromApplicationId(int $id): \Friendica\Object\Api\Mastodon\Application
{ {
$application = $this->dba->selectFirst('application', ['client_id', 'client_secret', 'id', 'name', 'redirect_uri', 'website'], ['id' => $id]); $application = $this->dba->selectFirst('application', ['client_id', 'client_secret', 'id', 'name', 'redirect_uri', 'website'], ['id' => $id]);
if (!$this->dba->isResult($application)) { if (!$this->dba->isResult($application)) {
throw new InternalServerErrorException(sprintf("ID '%s' not found", $id)); throw new UnprocessableEntityException(sprintf("ID '%s' not found", $id));
} }
return new \Friendica\Object\Api\Mastodon\Application( return new \Friendica\Object\Api\Mastodon\Application(

View file

@ -32,8 +32,7 @@ use Friendica\DI;
use Friendica\Factory\ConfigFactory; use Friendica\Factory\ConfigFactory;
use Friendica\Model\Register; use Friendica\Model\Register;
use Friendica\Module\BaseAdmin; use Friendica\Module\BaseAdmin;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\ServiceUnavailableException;
use Friendica\Util\ConfigFileLoader;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
class Summary extends BaseAdmin class Summary extends BaseAdmin
@ -129,7 +128,7 @@ class Summary extends BaseAdmin
$stream = $fileSystem->createStream($file); $stream = $fileSystem->createStream($file);
if (!isset($stream)) { if (!isset($stream)) {
throw new InternalServerErrorException('Stream is null.'); throw new ServiceUnavailableException('Stream is null.');
} }
} catch (\Throwable $exception) { } catch (\Throwable $exception) {
@ -143,7 +142,7 @@ class Summary extends BaseAdmin
$stream = $fileSystem->createStream($file); $stream = $fileSystem->createStream($file);
if (!isset($stream)) { if (!isset($stream)) {
throw new InternalServerErrorException('Stream is null.'); throw new ServiceUnavailableException('Stream is null.');
} }
} }
} catch (\Throwable $exception) { } catch (\Throwable $exception) {

View file

@ -96,7 +96,9 @@ class Receive extends BaseModule
if (Diaspora::dispatch($importer, $msg)) { if (Diaspora::dispatch($importer, $msg)) {
throw new HTTPException\OKException(); throw new HTTPException\OKException();
} else { } else {
throw new HTTPException\InternalServerErrorException(); // We couldn't process the content.
// To avoid the remote system trying again we send the message that we accepted the content.
throw new HTTPException\AcceptedException();
} }
} }

View file

@ -30,6 +30,7 @@ use Friendica\Database\PostUpdate;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Network\HTTPException\ImATeapotException;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
/** /**

View file

@ -33,6 +33,7 @@ use Friendica\Model\Storage\ExternalResource;
use Friendica\Model\Storage\SystemResource; use Friendica\Model\Storage\SystemResource;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Network\HTTPException\NotModifiedException;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Util\Images; use Friendica\Util\Images;
use Friendica\Util\Network; use Friendica\Util\Network;
@ -55,7 +56,6 @@ class Photo extends BaseModule
$totalstamp = microtime(true); $totalstamp = microtime(true);
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) { if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
header("HTTP/1.1 304 Not Modified");
header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT");
if (!empty($_SERVER["HTTP_IF_NONE_MATCH"])) { if (!empty($_SERVER["HTTP_IF_NONE_MATCH"])) {
header("Etag: " . $_SERVER["HTTP_IF_NONE_MATCH"]); header("Etag: " . $_SERVER["HTTP_IF_NONE_MATCH"]);
@ -67,7 +67,7 @@ class Photo extends BaseModule
header_remove("Expires"); header_remove("Expires");
header_remove("Cache-Control"); header_remove("Cache-Control");
} }
exit; throw new NotModifiedException();
} }
Profile::addVisitorCookieForHTTPSigner(); Profile::addVisitorCookieForHTTPSigner();

View file

@ -25,6 +25,7 @@ use Friendica\BaseModule;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
use Friendica\Network\HTTPException\NotModifiedException;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Util\HTTPSignature; use Friendica\Util\HTTPSignature;
use Friendica\Util\Images; use Friendica\Util\Images;
@ -53,7 +54,6 @@ class Proxy extends BaseModule
} }
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) { if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
header("HTTP/1.1 304 Not Modified");
header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT");
if (!empty($_SERVER["HTTP_IF_NONE_MATCH"])) { if (!empty($_SERVER["HTTP_IF_NONE_MATCH"])) {
header("Etag: " . $_SERVER["HTTP_IF_NONE_MATCH"]); header("Etag: " . $_SERVER["HTTP_IF_NONE_MATCH"]);
@ -65,7 +65,7 @@ class Proxy extends BaseModule
header_remove("Expires"); header_remove("Expires");
header_remove("Cache-Control"); header_remove("Cache-Control");
} }
exit; throw new NotModifiedException();
} }
if (empty($request['url'])) { if (empty($request['url'])) {

View file

@ -21,6 +21,7 @@
namespace Friendica\Module\Special; namespace Friendica\Module\Special;
use Friendica\Core\Logger;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
@ -42,36 +43,10 @@ class HTTPException
*/ */
private static function getVars(\Friendica\Network\HTTPException $e) private static function getVars(\Friendica\Network\HTTPException $e)
{ {
$message = $e->getMessage(); // Explanations are mostly taken from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
$titles = [
200 => 'OK',
400 => DI::l10n()->t('Bad Request'),
401 => DI::l10n()->t('Unauthorized'),
403 => DI::l10n()->t('Forbidden'),
404 => DI::l10n()->t('Not Found'),
500 => DI::l10n()->t('Internal Server Error'),
503 => DI::l10n()->t('Service Unavailable'),
];
$title = ($titles[$e->getCode()] ?? '') ?: 'Error ' . $e->getCode();
if (empty($message)) {
// Explanations are taken from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
$explanation = [
400 => DI::l10n()->t('The server cannot or will not process the request due to an apparent client error.'),
401 => DI::l10n()->t('Authentication is required and has failed or has not yet been provided.'),
403 => DI::l10n()->t('The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource, or may need an account.'),
404 => DI::l10n()->t('The requested resource could not be found but may be available in the future.'),
500 => DI::l10n()->t('An unexpected condition was encountered and no more specific message is suitable.'),
503 => DI::l10n()->t('The server is currently unavailable (because it is overloaded or down for maintenance). Please try again later.'),
];
$message = $explanation[$e->getCode()] ?? '';
}
$vars = [ $vars = [
'$title' => $title, '$title' => $e->httpdesc ?: 'Error ' . $e->getCode(),
'$message' => $message, '$message' => $e->getMessage() ?: $e->explanation,
'$back' => DI::l10n()->t('Go back'), '$back' => DI::l10n()->t('Go back'),
'$stack_trace' => DI::l10n()->t('Stack trace:'), '$stack_trace' => DI::l10n()->t('Stack trace:'),
]; ];
@ -113,6 +88,10 @@ class HTTPException
{ {
header($_SERVER["SERVER_PROTOCOL"] . ' ' . $e->getCode() . ' ' . $e->httpdesc); header($_SERVER["SERVER_PROTOCOL"] . ' ' . $e->getCode() . ' ' . $e->httpdesc);
if ($e->getCode() >= 400) {
Logger::debug('Exit with error', ['code' => $e->getCode(), 'description' => $e->httpdesc, 'query' => DI::args()->getQueryString(), 'callstack' => System::callstack(20), 'method' => $_SERVER['REQUEST_METHOD'], 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']);
}
$tpl = Renderer::getMarkupTemplate('exception.tpl'); $tpl = Renderer::getMarkupTemplate('exception.tpl');
return Renderer::replaceMacros($tpl, self::getVars($e)); return Renderer::replaceMacros($tpl, self::getVars($e));

View file

@ -22,8 +22,7 @@
namespace Friendica\Network; namespace Friendica\Network;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\System; use Friendica\Network\HTTPException\UnprocessableEntityException;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Util\Network; use Friendica\Util\Network;
/** /**
@ -102,7 +101,7 @@ class CurlResult implements IHTTPResult
* @param string $url optional URL * @param string $url optional URL
* *
* @return IHTTPResult a CURL with error response * @return IHTTPResult a CURL with error response
* @throws InternalServerErrorException * @throws UnprocessableEntityException
*/ */
public static function createErrorCurl($url = '') public static function createErrorCurl($url = '')
{ {
@ -117,12 +116,12 @@ class CurlResult implements IHTTPResult
* @param int $errorNumber the error number or 0 (zero) if no error * @param int $errorNumber the error number or 0 (zero) if no error
* @param string $error the error message or '' (the empty string) if no * @param string $error the error message or '' (the empty string) if no
* *
* @throws InternalServerErrorException when HTTP code of the CURL response is missing * @throws UnprocessableEntityException when HTTP code of the CURL response is missing
*/ */
public function __construct($url, $result, $info, $errorNumber = 0, $error = '') public function __construct($url, $result, $info, $errorNumber = 0, $error = '')
{ {
if (!array_key_exists('http_code', $info)) { if (!array_key_exists('http_code', $info)) {
throw new InternalServerErrorException('CURL response doesn\'t contains a response HTTP code'); throw new UnprocessableEntityException('CURL response doesn\'t contains a response HTTP code');
} }
$this->returnCode = $info['http_code']; $this->returnCode = $info['http_code'];

View file

@ -32,14 +32,10 @@ use Exception;
abstract class HTTPException extends Exception abstract class HTTPException extends Exception
{ {
public $httpdesc = ''; public $httpdesc = '';
public $explanation = '';
public function __construct($message = '', Exception $previous = null) public function __construct($message = '', Exception $previous = null)
{ {
parent::__construct($message, $this->code, $previous); parent::__construct($message, $this->code, $previous);
if (empty($this->httpdesc)) {
$classname = str_replace('Exception', '', str_replace('Friendica\Network\HTTPException\\', '', get_class($this)));
$this->httpdesc = preg_replace("|([a-z])([A-Z])|",'$1 $2', $classname);
}
} }
} }

View file

@ -26,4 +26,5 @@ use Friendica\Network\HTTPException;
class AcceptedException extends HTTPException class AcceptedException extends HTTPException
{ {
protected $code = 202; protected $code = 202;
var $httpdesc = 'Accepted';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class BadGatewayException extends HTTPException class BadGatewayException extends HTTPException
{ {
protected $code = 502; protected $code = 502;
var $httpdesc = 'Bad Gateway';
var $explanation = 'The server was acting as a gateway or proxy and received an invalid response from the upstream server.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class BadRequestException extends HTTPException class BadRequestException extends HTTPException
{ {
protected $code = 400; protected $code = 400;
var $httpdesc = 'Bad Request';
var $explanation = 'The server cannot or will not process the request due to an apparent client error.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class ConflictException extends HTTPException class ConflictException extends HTTPException
{ {
protected $code = 409; protected $code = 409;
var $httpdesc = 'Conflict ';
var $explanation = 'Indicates that the request could not be processed because of conflict in the current state of the resource, such as an edit conflict between multiple simultaneous updates.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class ExpectationFailedException extends HTTPException class ExpectationFailedException extends HTTPException
{ {
protected $code = 417; protected $code = 417;
var $httpdesc = 'Expectation Failed';
var $explanation = 'The server cannot meet the requirements of the Expect request-header field.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class ForbiddenException extends HTTPException class ForbiddenException extends HTTPException
{ {
protected $code = 403; protected $code = 403;
var $httpdesc = 'Forbidden';
var $explanation = 'The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource, or may need an account.';
} }

View file

@ -0,0 +1,30 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program 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 (at your option) 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Network\HTTPException;
use Friendica\Network\HTTPException;
class FoundException extends HTTPException
{
protected $code = 302;
var $httpdesc = 'Found (Moved Temporarily)';
}

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class GatewayTimeoutException extends HTTPException class GatewayTimeoutException extends HTTPException
{ {
protected $code = 504; protected $code = 504;
var $httpdesc = 'Gateway Timeout';
var $explanation = 'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class GoneException extends HTTPException class GoneException extends HTTPException
{ {
protected $code = 410; protected $code = 410;
var $httpdesc = 'Gone';
var $explanation = 'Indicates that the resource requested is no longer available and will not be available again.';
} }

View file

@ -27,4 +27,5 @@ class ImATeapotException extends HTTPException
{ {
protected $code = 418; protected $code = 418;
var $httpdesc = "I'm A Teapot"; var $httpdesc = "I'm A Teapot";
var $explanation = 'This is a teapot that is requested to brew coffee.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class InternalServerErrorException extends HTTPException class InternalServerErrorException extends HTTPException
{ {
protected $code = 500; protected $code = 500;
var $httpdesc = 'Internal Server Error';
var $explanation = 'An unexpected condition was encountered and no more specific message is suitable.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class LenghtRequiredException extends HTTPException class LenghtRequiredException extends HTTPException
{ {
protected $code = 411; protected $code = 411;
var $httpdesc = 'Length Required';
var $explanation = 'The request did not specify the length of its content, which is required by the requested resource.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class MethodNotAllowedException extends HTTPException class MethodNotAllowedException extends HTTPException
{ {
protected $code = 405; protected $code = 405;
var $httpdesc = 'Method Not Allowed';
var $explanation = 'A request method is not supported for the requested resource; for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.';
} }

View file

@ -0,0 +1,30 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program 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 (at your option) 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Network\HTTPException;
use Friendica\Network\HTTPException;
class MovedPermanentlyException extends HTTPException
{
protected $code = 301;
var $httpdesc = 'Moved Permanently';
}

View file

@ -26,4 +26,5 @@ use Friendica\Network\HTTPException;
class NoContentException extends HTTPException class NoContentException extends HTTPException
{ {
protected $code = 204; protected $code = 204;
var $httpdesc = 'No Content';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class NonAcceptableException extends HTTPException class NonAcceptableException extends HTTPException
{ {
protected $code = 406; protected $code = 406;
var $httpdesc = 'Not Acceptable';
var $explanation = 'The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class NotFoundException extends HTTPException class NotFoundException extends HTTPException
{ {
protected $code = 404; protected $code = 404;
var $httpdesc = 'Not Found';
var $explanation = 'The requested resource could not be found but may be available in the future.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class NotImplementedException extends HTTPException class NotImplementedException extends HTTPException
{ {
protected $code = 501; protected $code = 501;
var $httpdesc = 'Not Implemented';
var $explanation = 'The server either does not recognize the request method, or it lacks the ability to fulfil the request. Usually this implies future availability (e.g., a new feature of a web-service API).';
} }

View file

@ -0,0 +1,30 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program 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 (at your option) 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Network\HTTPException;
use Friendica\Network\HTTPException;
class NotModifiedException extends HTTPException
{
protected $code = 304;
var $httpdesc = 'Not Modified';
}

View file

@ -26,4 +26,5 @@ use Friendica\Network\HTTPException;
class OKException extends HTTPException class OKException extends HTTPException
{ {
protected $code = 200; protected $code = 200;
var $httpdesc = 'OK';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class PreconditionFailedException extends HTTPException class PreconditionFailedException extends HTTPException
{ {
protected $code = 412; protected $code = 412;
var $httpdesc = 'Precondition Failed';
var $explanation = 'The server does not meet one of the preconditions that the requester put on the request header fields.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class ServiceUnavailableException extends HTTPException class ServiceUnavailableException extends HTTPException
{ {
protected $code = 503; protected $code = 503;
var $httpdesc = 'Service Unavailable';
var $explanation = 'The server is currently unavailable (because it is overloaded or down for maintenance). Please try again later.';
} }

View file

@ -0,0 +1,30 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* This program 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 (at your option) 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Network\HTTPException;
use Friendica\Network\HTTPException;
class TemporaryRedirectException extends HTTPException
{
protected $code = 307;
var $httpdesc = 'Temporary Redirect';
}

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class TooManyRequestsException extends HTTPException class TooManyRequestsException extends HTTPException
{ {
protected $code = 429; protected $code = 429;
var $httpdesc = 'Too Many Requests';
var $explanation = 'The user has sent too many requests in a given amount of time.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class UnauthorizedException extends HTTPException class UnauthorizedException extends HTTPException
{ {
protected $code = 401; protected $code = 401;
var $httpdesc = 'Unauthorized';
var $explanation = 'Authentication is required and has failed or has not yet been provided.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class UnprocessableEntityException extends HTTPException class UnprocessableEntityException extends HTTPException
{ {
protected $code = 422; protected $code = 422;
var $httpdesc = 'Unprocessable Entity';
var $explanation = 'The request was well-formed but was unable to be followed due to semantic errors.';
} }

View file

@ -26,4 +26,6 @@ use Friendica\Network\HTTPException;
class UnsupportedMediaTypeException extends HTTPException class UnsupportedMediaTypeException extends HTTPException
{ {
protected $code = 415; protected $code = 415;
var $httpdesc = 'Unsupported Media Type';
var $explanation = 'The request entity has a media type which the server or resource does not support. For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.';
} }

View file

@ -23,7 +23,7 @@ namespace Friendica\Render;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\DI; use Friendica\DI;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\ServiceUnavailableException;
use Friendica\Util\Strings; use Friendica\Util\Strings;
/** /**
@ -54,7 +54,7 @@ final class FriendicaSmartyEngine extends TemplateEngine
$message = is_site_admin() ? $message = is_site_admin() ?
$admin_message : $admin_message :
DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.'); DI::l10n()->t('Friendica can\'t display this page at the moment, please contact the administrator.');
throw new InternalServerErrorException($message); throw new ServiceUnavailableException($message);
} }
} }

View file

@ -27,7 +27,7 @@ use Friendica\Core\Config\IConfig;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException\InternalServerErrorException; use Friendica\Network\HTTPException\UnprocessableEntityException;
use Friendica\Object\Email; use Friendica\Object\Email;
use Friendica\Object\EMail\IEmail; use Friendica\Object\EMail\IEmail;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -226,7 +226,7 @@ abstract class MailBuilder
* *
* @return IEmail A new generated email * @return IEmail A new generated email
* *
* @throws InternalServerErrorException * @throws UnprocessableEntityException
* @throws Exception * @throws Exception
*/ */
public function build(bool $raw = false) public function build(bool $raw = false)
@ -241,11 +241,11 @@ abstract class MailBuilder
} }
if (empty($this->recipientAddress)) { if (empty($this->recipientAddress)) {
throw new InternalServerErrorException('Recipient address is missing.'); throw new UnprocessableEntityException('Recipient address is missing.');
} }
if (empty($this->senderAddress) || empty($this->senderName)) { if (empty($this->senderAddress) || empty($this->senderName)) {
throw new InternalServerErrorException('Sender address or name is missing.'); throw new UnprocessableEntityException('Sender address or name is missing.');
} }
$this->senderNoReply = $this->senderNoReply ?? $this->senderAddress; $this->senderNoReply = $this->senderNoReply ?? $this->senderAddress;

View file

@ -476,7 +476,7 @@ class HTTPSignature
public static function getSigner($content, $http_headers) public static function getSigner($content, $http_headers)
{ {
if (empty($http_headers['HTTP_SIGNATURE'])) { if (empty($http_headers['HTTP_SIGNATURE'])) {
Logger::info('No HTTP_SIGNATURE header'); Logger::debug('No HTTP_SIGNATURE header');
return false; return false;
} }

View file

@ -25,6 +25,7 @@ use Friendica\Core\Hook;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Network\HTTPException\NotModifiedException;
class Network class Network
{ {
@ -544,8 +545,7 @@ class Network
header('Last-Modified: ' . $last_modified); header('Last-Modified: ' . $last_modified);
if ($flag_not_modified) { if ($flag_not_modified) {
header("HTTP/1.1 304 Not Modified"); throw new NotModifiedException();
exit;
} }
} }

View file

@ -693,7 +693,7 @@ class Notifier
private static function notifySelfRemoval($self_user_id, $priority, $created) private static function notifySelfRemoval($self_user_id, $priority, $created)
{ {
$owner = User::getOwnerDataById($self_user_id); $owner = User::getOwnerDataById($self_user_id);
if (!$owner) { if (empty($self_user_id) || empty($owner)) {
return false; return false;
} }

View file

@ -20,6 +20,7 @@
*/ */
use Friendica\DI; use Friendica\DI;
use Friendica\Network\HTTPException\NotModifiedException;
use Friendica\Util\Strings; use Friendica\Util\Strings;
require_once 'view/theme/frio/theme.php'; require_once 'view/theme/frio/theme.php';
@ -225,8 +226,7 @@ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && isset($_SERVER['HTTP_IF_NONE_MA
stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])); stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
if (($cached_modified == $modified) && ($cached_etag == $etag)) { if (($cached_modified == $modified) && ($cached_etag == $etag)) {
header('HTTP/1.1 304 Not Modified'); throw new NotModifiedException();
exit();
} }
} }

View file

@ -21,6 +21,7 @@
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\DI; use Friendica\DI;
use Friendica\Network\HTTPException\NotModifiedException;
$uid = $_REQUEST['puid'] ?? 0; $uid = $_REQUEST['puid'] ?? 0;
@ -67,8 +68,7 @@ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && isset($_SERVER['HTTP_IF_NONE_MA
stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])); stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
if (($cached_modified == $modified) && ($cached_etag == $etag)) { if (($cached_modified == $modified) && ($cached_etag == $etag)) {
header('HTTP/1.1 304 Not Modified'); throw new NotModifiedException();
exit();
} }
} }
echo $stylecss; echo $stylecss;