diff --git a/mod/cal.php b/mod/cal.php index 070cadf3d5..dea1c2b9ea 100644 --- a/mod/cal.php +++ b/mod/cal.php @@ -35,6 +35,7 @@ use Friendica\Model\Event; use Friendica\Model\Item; use Friendica\Model\User; use Friendica\Module\BaseProfile; +use Friendica\Module\Response; use Friendica\Network\HTTPException; use Friendica\Util\DateTimeFormat; use Friendica\Util\Temporal; @@ -289,10 +290,8 @@ function cal_content(App $a) // If nothing went wrong we can echo the export content if ($evexport["success"]) { - header('Content-type: text/calendar'); header('content-disposition: attachment; filename="' . DI::l10n()->t('calendar') . '-' . $nick . '.' . $evexport["extension"] . '"'); - echo $evexport["content"]; - exit(); + System::httpExit($evexport["content"], Response::TYPE_BLANK, 'text/calendar'); } return; diff --git a/mod/display.php b/mod/display.php index da41c8656e..880cfd44b8 100644 --- a/mod/display.php +++ b/mod/display.php @@ -25,6 +25,7 @@ use Friendica\Content\Widget; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\Session; +use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; @@ -32,6 +33,7 @@ use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\User; use Friendica\Module\ActivityPub\Objects; +use Friendica\Module\Response; use Friendica\Network\HTTPException; use Friendica\Protocol\ActivityPub; use Friendica\Protocol\DFRN; @@ -342,7 +344,6 @@ function displayShowFeed(int $uri_id, int $uid, bool $conversation) if ($xml == '') { throw new HTTPException\InternalServerErrorException(DI::l10n()->t('The feed for this item is unavailable.')); } - header("Content-type: application/atom+xml"); - echo $xml; - exit(); + + System::httpExit($xml, Response::TYPE_ATOM); } diff --git a/mod/poco.php b/mod/poco.php index 09ee25a1ff..73179a33f2 100644 --- a/mod/poco.php +++ b/mod/poco.php @@ -28,6 +28,7 @@ use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\DI; +use Friendica\Module\Response; use Friendica\Util\DateTimeFormat; use Friendica\Util\XML; @@ -229,9 +230,7 @@ function poco_init(App $a) { Logger::info("End of poco"); if ($format === 'xml') { - header('Content-type: text/xml'); - echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayEscape(['$response' => $ret])); - exit(); + System::httpExit(Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayEscape(['$response' => $ret])), Response::TYPE_XML); } if ($format === 'json') { System::jsonExit($ret); diff --git a/src/App/Page.php b/src/App/Page.php index 0d7b164363..41d50da055 100644 --- a/src/App/Page.php +++ b/src/App/Page.php @@ -31,7 +31,9 @@ use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues; use Friendica\Core\Hook; use Friendica\Core\L10n; use Friendica\Core\Renderer; +use Friendica\Core\System; use Friendica\Core\Theme; +use Friendica\Module\Response; use Friendica\Network\HTTPException; use Friendica\Util\Network; use Friendica\Util\Strings; @@ -503,11 +505,7 @@ class Page implements ArrayAccess } if ($_GET["mode"] == "raw") { - header("Content-type: text/html; charset=utf-8"); - - echo substr($target->saveHTML(), 6, -8); - - exit(); + System::httpExit(substr($target->saveHTML(), 6, -8), Response::TYPE_HTML); } } diff --git a/src/Core/System.php b/src/Core/System.php index 3ef94a74c5..66b6b25a50 100644 --- a/src/Core/System.php +++ b/src/Core/System.php @@ -306,25 +306,41 @@ class System * @param string $content Response body. Optional. * @throws \Exception */ - public static function httpExit($val, $message = '', $content = '') + public static function httpError($httpCode, $message = '', $content = '') { - if ($val >= 400) { - Logger::debug('Exit with error', ['code' => $val, 'message' => $message, 'callstack' => System::callstack(20), 'method' => DI::args()->getMethod(), 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']); + if ($httpCode >= 400) { + Logger::debug('Exit with error', ['code' => $httpCode, 'message' => $message, 'callstack' => System::callstack(20), 'method' => DI::args()->getMethod(), 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']); } - DI::apiResponse()->setStatus($val, $message); + DI::apiResponse()->setStatus($httpCode, $message); DI::apiResponse()->addContent($content); DI::page()->exit(DI::apiResponse()->generate()); exit(); } - public static function jsonError($httpCode, $data, $content_type = 'application/json') + /** + * This function adds the content and a content-teype HTTP header to the output. + * After finishing the process is getting killed. + * + * @param string $content + * @param [type] $responce + * @param string|null $content_type + * @return void + */ + public static function httpExit(string $content, string $responce = Response::TYPE_HTML, ?string $content_type = null) { + DI::apiResponse()->setType($responce, $content_type); + DI::apiResponse()->addContent($content); + DI::page()->exit(DI::apiResponse()->generate()); + exit(); + } + + public static function jsonError($httpCode, $content, $content_type = 'application/json') { if ($httpCode >= 400) { Logger::debug('Exit with error', ['code' => $httpCode, 'content_type' => $content_type, 'callstack' => System::callstack(20), 'method' => DI::args()->getMethod(), 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']); } DI::apiResponse()->setStatus($httpCode); - self::jsonExit($data, $content_type); + self::jsonExit($content, $content_type); } /** @@ -334,14 +350,14 @@ class System * and adds an application/json HTTP header to the output. * After finishing the process is getting killed. * - * @param mixed $x The input content + * @param mixed $content The input content * @param string $content_type Type of the input (Default: 'application/json') * @param integer $options JSON options * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function jsonExit($x, $content_type = 'application/json', int $options = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) { + public static function jsonExit($content, $content_type = 'application/json', int $options = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) { DI::apiResponse()->setType(Response::TYPE_JSON, $content_type); - DI::apiResponse()->addContent(json_encode($x, $options)); + DI::apiResponse()->addContent(json_encode($content, $options)); DI::page()->exit(DI::apiResponse()->generate()); exit(); } diff --git a/src/Module/DFRN/Poll.php b/src/Module/DFRN/Poll.php index 65a3448fb4..516f863845 100644 --- a/src/Module/DFRN/Poll.php +++ b/src/Module/DFRN/Poll.php @@ -22,6 +22,8 @@ namespace Friendica\Module\DFRN; use Friendica\BaseModule; +use Friendica\Core\System; +use Friendica\Module\Response; use Friendica\Protocol\OStatus; /** @@ -31,9 +33,7 @@ class Poll extends BaseModule { protected function rawContent(array $request = []) { - header("Content-type: application/atom+xml"); - $last_update = $_GET['last_update'] ?? ''; - echo OStatus::feed($this->parameters['nickname'], $last_update, 10); - exit(); + $last_update = $request['last_update'] ?? ''; + System::httpExit(OStatus::feed($this->parameters['nickname'], $last_update, 10), Response::TYPE_ATOM); } } diff --git a/src/Module/Diaspora/Fetch.php b/src/Module/Diaspora/Fetch.php index 97cbb5878f..bcb6ba0cae 100644 --- a/src/Module/Diaspora/Fetch.php +++ b/src/Module/Diaspora/Fetch.php @@ -28,6 +28,7 @@ use Friendica\DI; use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\User; +use Friendica\Module\Response; use Friendica\Network\HTTPException; use Friendica\Protocol\Diaspora; use Friendica\Util\Strings; @@ -84,9 +85,6 @@ class Fetch extends BaseModule $xml = Diaspora::buildPostXml($status["type"], $status["message"]); // Send the envelope - header("Content-Type: application/magic-envelope+xml; charset=utf-8"); - echo Diaspora::buildMagicEnvelope($xml, $user); - - exit(); + System::httpExit(Diaspora::buildMagicEnvelope($xml, $user), Response::TYPE_XML, 'application/magic-envelope+xml'); } } diff --git a/src/Module/Feed.php b/src/Module/Feed.php index 3a1246028b..8db92c275a 100644 --- a/src/Module/Feed.php +++ b/src/Module/Feed.php @@ -22,6 +22,7 @@ namespace Friendica\Module; use Friendica\BaseModule; +use Friendica\Core\System; use Friendica\DI; use Friendica\Protocol\Feed as ProtocolFeed; @@ -43,10 +44,8 @@ class Feed extends BaseModule { protected function content(array $request = []): string { - $a = DI::app(); - - $last_update = $_GET['last_update'] ?? ''; - $nocache = !empty($_GET['nocache']) && local_user(); + $last_update = $request['last_update'] ?? ''; + $nocache = !empty($request['nocache']) && local_user(); $type = null; // @TODO: Replace with parameter from router @@ -67,8 +66,6 @@ class Feed extends BaseModule $type = 'posts'; } - header("Content-type: application/atom+xml; charset=utf-8"); - echo ProtocolFeed::atom($this->parameters['nickname'], $last_update, 10, $type, $nocache, true); - exit(); + System::httpExit(ProtocolFeed::atom($this->parameters['nickname'], $last_update, 10, $type, $nocache, true), Response::TYPE_ATOM); } } diff --git a/src/Module/Notifications/Ping.php b/src/Module/Notifications/Ping.php index 1501c4277e..b0412b5dcb 100644 --- a/src/Module/Notifications/Ping.php +++ b/src/Module/Notifications/Ping.php @@ -291,9 +291,7 @@ class Ping extends BaseModule if (isset($_GET['callback'])) { // JSONP support - header("Content-type: application/javascript"); - echo $_GET['callback'] . '(' . json_encode(['result' => $data]) . ')'; - exit; + System::httpExit($_GET['callback'] . '(' . json_encode(['result' => $data]) . ')', Response::TYPE_BLANK, 'application/javascript'); } else { System::jsonExit(['result' => $data]); } diff --git a/src/Module/OpenSearch.php b/src/Module/OpenSearch.php index 94215aaa7a..35d6890ec6 100644 --- a/src/Module/OpenSearch.php +++ b/src/Module/OpenSearch.php @@ -24,6 +24,7 @@ namespace Friendica\Module; use DOMDocument; use DOMElement; use Friendica\BaseModule; +use Friendica\Core\System; use Friendica\DI; use Friendica\Util\XML; @@ -38,8 +39,6 @@ class OpenSearch extends BaseModule */ protected function rawContent(array $request = []) { - header('Content-type: application/opensearchdescription+xml'); - $hostname = DI::baseUrl()->getHostname(); $baseUrl = DI::baseUrl()->get(); @@ -85,8 +84,6 @@ class OpenSearch extends BaseModule 'template' => "$baseUrl/opensearch", ]); - echo $xml->saveXML(); - - exit(); + System::httpExit($xml->saveXML(), Response::TYPE_XML, 'application/opensearchdescription+xml'); } } diff --git a/src/Module/PublicRSAKey.php b/src/Module/PublicRSAKey.php index d803de754e..523ab174fb 100644 --- a/src/Module/PublicRSAKey.php +++ b/src/Module/PublicRSAKey.php @@ -22,6 +22,7 @@ namespace Friendica\Module; use Friendica\BaseModule; +use Friendica\Core\System; use Friendica\DI; use Friendica\Model\User; use Friendica\Network\HTTPException\BadRequestException; @@ -48,9 +49,7 @@ class PublicRSAKey extends BaseModule Crypto::pemToMe($user['spubkey'], $modulus, $exponent); - header('Content-type: application/magic-public-key'); - echo 'RSA' . '.' . Strings::base64UrlEncode($modulus, true) . '.' . Strings::base64UrlEncode($exponent, true); - - exit(); + $content = 'RSA' . '.' . Strings::base64UrlEncode($modulus, true) . '.' . Strings::base64UrlEncode($exponent, true); + System::httpExit($content, Response::TYPE_BLANK, 'application/magic-public-key'); } } diff --git a/src/Module/ReallySimpleDiscovery.php b/src/Module/ReallySimpleDiscovery.php index d699455f47..9b8cb31a57 100644 --- a/src/Module/ReallySimpleDiscovery.php +++ b/src/Module/ReallySimpleDiscovery.php @@ -22,6 +22,7 @@ namespace Friendica\Module; use Friendica\BaseModule; +use Friendica\Core\System; use Friendica\DI; use Friendica\Util\XML; @@ -33,10 +34,8 @@ class ReallySimpleDiscovery extends BaseModule { protected function rawContent(array $request = []) { - header('Content-Type: text/xml'); - $xml = null; - echo XML::fromArray([ + $content = XML::fromArray([ 'rsd' => [ '@attributes' => [ 'version' => '1.0', @@ -69,6 +68,6 @@ class ReallySimpleDiscovery extends BaseModule ], ], ], $xml); - exit(); + System::httpExit($content, Response::TYPE_XML); } } diff --git a/src/Module/Response.php b/src/Module/Response.php index f9d46da83b..ba7d432027 100644 --- a/src/Module/Response.php +++ b/src/Module/Response.php @@ -97,7 +97,7 @@ class Response implements ICanCreateResponses switch ($type) { case static::TYPE_HTML: - $content_type = $content_type ?? 'text/html'; + $content_type = $content_type ?? 'text/html; charset=utf-8'; break; case static::TYPE_JSON: $content_type = $content_type ?? 'application/json'; diff --git a/src/Module/Special/HTTPException.php b/src/Module/Special/HTTPException.php index 95448606e5..8b520f6b5a 100644 --- a/src/Module/Special/HTTPException.php +++ b/src/Module/Special/HTTPException.php @@ -74,7 +74,7 @@ class HTTPException $content = Renderer::replaceMacros($tpl, self::getVars($e)); } - System::httpExit($e->getCode(), $e->getDescription(), $content); + System::httpError($e->getCode(), $e->getDescription(), $content); } /** diff --git a/src/Module/WellKnown/HostMeta.php b/src/Module/WellKnown/HostMeta.php index c5553272e6..8f44754530 100644 --- a/src/Module/WellKnown/HostMeta.php +++ b/src/Module/WellKnown/HostMeta.php @@ -23,7 +23,9 @@ namespace Friendica\Module\WellKnown; use Friendica\BaseModule; use Friendica\Core\Renderer; +use Friendica\Core\System; use Friendica\DI; +use Friendica\Module\Response; use Friendica\Protocol\Salmon; use Friendica\Util\Crypto; @@ -37,8 +39,6 @@ class HostMeta extends BaseModule { $config = DI::config(); - header('Content-type: text/xml'); - if (!$config->get('system', 'site_pubkey', false)) { $res = Crypto::newKeypair(1024); @@ -47,13 +47,13 @@ class HostMeta extends BaseModule } $tpl = Renderer::getMarkupTemplate('xrd_host.tpl'); - echo Renderer::replaceMacros($tpl, [ + $content = Renderer::replaceMacros($tpl, [ '$zhost' => DI::baseUrl()->getHostname(), '$zroot' => DI::baseUrl()->get(), '$domain' => DI::baseUrl()->get(), '$bigkey' => Salmon::salmonKey($config->get('system', 'site_pubkey')) ]); - exit(); + System::httpExit($content, Response::TYPE_XML); } } diff --git a/src/Module/Xrd.php b/src/Module/Xrd.php index d24628ce65..6043ae4ddc 100644 --- a/src/Module/Xrd.php +++ b/src/Module/Xrd.php @@ -46,9 +46,9 @@ class Xrd extends BaseModule $uri = urldecode(trim($_GET['uri'])); if (strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/jrd+json') !== false) { - $mode = 'json'; + $mode = Response::TYPE_JSON; } else { - $mode = 'xml'; + $mode = Response::TYPE_XML; } } else { if (empty($_GET['resource'])) { @@ -57,9 +57,9 @@ class Xrd extends BaseModule $uri = urldecode(trim($_GET['resource'])); if (strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/xrd+xml') !== false) { - $mode = 'xml'; + $mode = Response::TYPE_XML; } else { - $mode = 'json'; + $mode = Response::TYPE_JSON; } } @@ -101,7 +101,7 @@ class Xrd extends BaseModule $avatar = ['type' => 'image/jpeg']; } - if ($mode == 'xml') { + if ($mode == Response::TYPE_JSON) { self::printXML($alias, DI::baseUrl()->get(), $user, $owner, $avatar); } else { self::printJSON($alias, DI::baseUrl()->get(), $owner, $avatar); @@ -238,9 +238,6 @@ class Xrd extends BaseModule { $salmon_key = Salmon::salmonKey($owner['spubkey']); - header('Access-Control-Allow-Origin: *'); - header('Content-type: text/xml'); - $tpl = Renderer::getMarkupTemplate('xrd_person.tpl'); $o = Renderer::replaceMacros($tpl, [ @@ -263,7 +260,8 @@ class Xrd extends BaseModule $arr = ['user' => $user, 'xml' => $o]; Hook::callAll('personal_xrd', $arr); - echo $arr['xml']; - exit(); + header('Access-Control-Allow-Origin: *'); + + System::httpExit($arr['xml'], Response::TYPE_XML); } }