Unified output via the "httpExit" function

This commit is contained in:
Michael 2022-04-10 08:31:55 +00:00
parent d15023fe4b
commit 4a22034be6
16 changed files with 69 additions and 70 deletions

View File

@ -35,6 +35,7 @@ use Friendica\Model\Event;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Module\BaseProfile; use Friendica\Module\BaseProfile;
use Friendica\Module\Response;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
@ -289,10 +290,8 @@ function cal_content(App $a)
// If nothing went wrong we can echo the export content // If nothing went wrong we can echo the export content
if ($evexport["success"]) { if ($evexport["success"]) {
header('Content-type: text/calendar');
header('content-disposition: attachment; filename="' . DI::l10n()->t('calendar') . '-' . $nick . '.' . $evexport["extension"] . '"'); header('content-disposition: attachment; filename="' . DI::l10n()->t('calendar') . '-' . $nick . '.' . $evexport["extension"] . '"');
echo $evexport["content"]; System::httpExit($evexport["content"], Response::TYPE_BLANK, 'text/calendar');
exit();
} }
return; return;

View File

@ -25,6 +25,7 @@ use Friendica\Content\Widget;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\Session; use Friendica\Core\Session;
use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Contact; use Friendica\Model\Contact;
@ -32,6 +33,7 @@ use Friendica\Model\Item;
use Friendica\Model\Post; use Friendica\Model\Post;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Module\ActivityPub\Objects; use Friendica\Module\ActivityPub\Objects;
use Friendica\Module\Response;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\DFRN; use Friendica\Protocol\DFRN;
@ -342,7 +344,6 @@ function displayShowFeed(int $uri_id, int $uid, bool $conversation)
if ($xml == '') { if ($xml == '') {
throw new HTTPException\InternalServerErrorException(DI::l10n()->t('The feed for this item is unavailable.')); throw new HTTPException\InternalServerErrorException(DI::l10n()->t('The feed for this item is unavailable.'));
} }
header("Content-type: application/atom+xml");
echo $xml; System::httpExit($xml, Response::TYPE_ATOM);
exit();
} }

View File

@ -28,6 +28,7 @@ use Friendica\Core\Renderer;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Response;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\XML; use Friendica\Util\XML;
@ -229,9 +230,7 @@ function poco_init(App $a) {
Logger::info("End of poco"); Logger::info("End of poco");
if ($format === 'xml') { if ($format === 'xml') {
header('Content-type: text/xml'); System::httpExit(Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayEscape(['$response' => $ret])), Response::TYPE_XML);
echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayEscape(['$response' => $ret]));
exit();
} }
if ($format === 'json') { if ($format === 'json') {
System::jsonExit($ret); System::jsonExit($ret);

View File

@ -31,7 +31,9 @@ use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Core\Theme; use Friendica\Core\Theme;
use Friendica\Module\Response;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -503,11 +505,7 @@ class Page implements ArrayAccess
} }
if ($_GET["mode"] == "raw") { if ($_GET["mode"] == "raw") {
header("Content-type: text/html; charset=utf-8"); System::httpExit(substr($target->saveHTML(), 6, -8), Response::TYPE_HTML);
echo substr($target->saveHTML(), 6, -8);
exit();
} }
} }

View File

@ -306,25 +306,41 @@ class System
* @param string $content Response body. Optional. * @param string $content Response body. Optional.
* @throws \Exception * @throws \Exception
*/ */
public static function httpExit($val, $message = '', $content = '') public static function httpError($httpCode, $message = '', $content = '')
{ {
if ($val >= 400) { if ($httpCode >= 400) {
Logger::debug('Exit with error', ['code' => $val, 'message' => $message, 'callstack' => System::callstack(20), 'method' => DI::args()->getMethod(), 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '']); 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::apiResponse()->addContent($content);
DI::page()->exit(DI::apiResponse()->generate()); DI::page()->exit(DI::apiResponse()->generate());
exit(); 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) { 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'] ?? '']); 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); 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. * and adds an application/json HTTP header to the output.
* After finishing the process is getting killed. * 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 string $content_type Type of the input (Default: 'application/json')
* @param integer $options JSON options * @param integer $options JSON options
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @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()->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()); DI::page()->exit(DI::apiResponse()->generate());
exit(); exit();
} }

View File

@ -22,6 +22,8 @@
namespace Friendica\Module\DFRN; namespace Friendica\Module\DFRN;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\System;
use Friendica\Module\Response;
use Friendica\Protocol\OStatus; use Friendica\Protocol\OStatus;
/** /**
@ -31,9 +33,7 @@ class Poll extends BaseModule
{ {
protected function rawContent(array $request = []) protected function rawContent(array $request = [])
{ {
header("Content-type: application/atom+xml"); $last_update = $request['last_update'] ?? '';
$last_update = $_GET['last_update'] ?? ''; System::httpExit(OStatus::feed($this->parameters['nickname'], $last_update, 10), Response::TYPE_ATOM);
echo OStatus::feed($this->parameters['nickname'], $last_update, 10);
exit();
} }
} }

View File

@ -28,6 +28,7 @@ use Friendica\DI;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Model\Post; use Friendica\Model\Post;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Module\Response;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Protocol\Diaspora; use Friendica\Protocol\Diaspora;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -84,9 +85,6 @@ class Fetch extends BaseModule
$xml = Diaspora::buildPostXml($status["type"], $status["message"]); $xml = Diaspora::buildPostXml($status["type"], $status["message"]);
// Send the envelope // Send the envelope
header("Content-Type: application/magic-envelope+xml; charset=utf-8"); System::httpExit(Diaspora::buildMagicEnvelope($xml, $user), Response::TYPE_XML, 'application/magic-envelope+xml');
echo Diaspora::buildMagicEnvelope($xml, $user);
exit();
} }
} }

View File

@ -22,6 +22,7 @@
namespace Friendica\Module; namespace Friendica\Module;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
use Friendica\Protocol\Feed as ProtocolFeed; use Friendica\Protocol\Feed as ProtocolFeed;
@ -43,10 +44,8 @@ class Feed extends BaseModule
{ {
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
$a = DI::app(); $last_update = $request['last_update'] ?? '';
$nocache = !empty($request['nocache']) && local_user();
$last_update = $_GET['last_update'] ?? '';
$nocache = !empty($_GET['nocache']) && local_user();
$type = null; $type = null;
// @TODO: Replace with parameter from router // @TODO: Replace with parameter from router
@ -67,8 +66,6 @@ class Feed extends BaseModule
$type = 'posts'; $type = 'posts';
} }
header("Content-type: application/atom+xml; charset=utf-8"); System::httpExit(ProtocolFeed::atom($this->parameters['nickname'], $last_update, 10, $type, $nocache, true), Response::TYPE_ATOM);
echo ProtocolFeed::atom($this->parameters['nickname'], $last_update, 10, $type, $nocache, true);
exit();
} }
} }

View File

@ -291,9 +291,7 @@ class Ping extends BaseModule
if (isset($_GET['callback'])) { if (isset($_GET['callback'])) {
// JSONP support // JSONP support
header("Content-type: application/javascript"); System::httpExit($_GET['callback'] . '(' . json_encode(['result' => $data]) . ')', Response::TYPE_BLANK, 'application/javascript');
echo $_GET['callback'] . '(' . json_encode(['result' => $data]) . ')';
exit;
} else { } else {
System::jsonExit(['result' => $data]); System::jsonExit(['result' => $data]);
} }

View File

@ -24,6 +24,7 @@ namespace Friendica\Module;
use DOMDocument; use DOMDocument;
use DOMElement; use DOMElement;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
use Friendica\Util\XML; use Friendica\Util\XML;
@ -38,8 +39,6 @@ class OpenSearch extends BaseModule
*/ */
protected function rawContent(array $request = []) protected function rawContent(array $request = [])
{ {
header('Content-type: application/opensearchdescription+xml');
$hostname = DI::baseUrl()->getHostname(); $hostname = DI::baseUrl()->getHostname();
$baseUrl = DI::baseUrl()->get(); $baseUrl = DI::baseUrl()->get();
@ -85,8 +84,6 @@ class OpenSearch extends BaseModule
'template' => "$baseUrl/opensearch", 'template' => "$baseUrl/opensearch",
]); ]);
echo $xml->saveXML(); System::httpExit($xml->saveXML(), Response::TYPE_XML, 'application/opensearchdescription+xml');
exit();
} }
} }

View File

@ -22,6 +22,7 @@
namespace Friendica\Module; namespace Friendica\Module;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException\BadRequestException; use Friendica\Network\HTTPException\BadRequestException;
@ -48,9 +49,7 @@ class PublicRSAKey extends BaseModule
Crypto::pemToMe($user['spubkey'], $modulus, $exponent); Crypto::pemToMe($user['spubkey'], $modulus, $exponent);
header('Content-type: application/magic-public-key'); $content = 'RSA' . '.' . Strings::base64UrlEncode($modulus, true) . '.' . Strings::base64UrlEncode($exponent, true);
echo 'RSA' . '.' . Strings::base64UrlEncode($modulus, true) . '.' . Strings::base64UrlEncode($exponent, true); System::httpExit($content, Response::TYPE_BLANK, 'application/magic-public-key');
exit();
} }
} }

View File

@ -22,6 +22,7 @@
namespace Friendica\Module; namespace Friendica\Module;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
use Friendica\Util\XML; use Friendica\Util\XML;
@ -33,10 +34,8 @@ class ReallySimpleDiscovery extends BaseModule
{ {
protected function rawContent(array $request = []) protected function rawContent(array $request = [])
{ {
header('Content-Type: text/xml');
$xml = null; $xml = null;
echo XML::fromArray([ $content = XML::fromArray([
'rsd' => [ 'rsd' => [
'@attributes' => [ '@attributes' => [
'version' => '1.0', 'version' => '1.0',
@ -69,6 +68,6 @@ class ReallySimpleDiscovery extends BaseModule
], ],
], ],
], $xml); ], $xml);
exit(); System::httpExit($content, Response::TYPE_XML);
} }
} }

View File

@ -97,7 +97,7 @@ class Response implements ICanCreateResponses
switch ($type) { switch ($type) {
case static::TYPE_HTML: case static::TYPE_HTML:
$content_type = $content_type ?? 'text/html'; $content_type = $content_type ?? 'text/html; charset=utf-8';
break; break;
case static::TYPE_JSON: case static::TYPE_JSON:
$content_type = $content_type ?? 'application/json'; $content_type = $content_type ?? 'application/json';

View File

@ -74,7 +74,7 @@ class HTTPException
$content = Renderer::replaceMacros($tpl, self::getVars($e)); $content = Renderer::replaceMacros($tpl, self::getVars($e));
} }
System::httpExit($e->getCode(), $e->getDescription(), $content); System::httpError($e->getCode(), $e->getDescription(), $content);
} }
/** /**

View File

@ -23,7 +23,9 @@ namespace Friendica\Module\WellKnown;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Response;
use Friendica\Protocol\Salmon; use Friendica\Protocol\Salmon;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
@ -37,8 +39,6 @@ class HostMeta extends BaseModule
{ {
$config = DI::config(); $config = DI::config();
header('Content-type: text/xml');
if (!$config->get('system', 'site_pubkey', false)) { if (!$config->get('system', 'site_pubkey', false)) {
$res = Crypto::newKeypair(1024); $res = Crypto::newKeypair(1024);
@ -47,13 +47,13 @@ class HostMeta extends BaseModule
} }
$tpl = Renderer::getMarkupTemplate('xrd_host.tpl'); $tpl = Renderer::getMarkupTemplate('xrd_host.tpl');
echo Renderer::replaceMacros($tpl, [ $content = Renderer::replaceMacros($tpl, [
'$zhost' => DI::baseUrl()->getHostname(), '$zhost' => DI::baseUrl()->getHostname(),
'$zroot' => DI::baseUrl()->get(), '$zroot' => DI::baseUrl()->get(),
'$domain' => DI::baseUrl()->get(), '$domain' => DI::baseUrl()->get(),
'$bigkey' => Salmon::salmonKey($config->get('system', 'site_pubkey')) '$bigkey' => Salmon::salmonKey($config->get('system', 'site_pubkey'))
]); ]);
exit(); System::httpExit($content, Response::TYPE_XML);
} }
} }

View File

@ -46,9 +46,9 @@ class Xrd extends BaseModule
$uri = urldecode(trim($_GET['uri'])); $uri = urldecode(trim($_GET['uri']));
if (strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/jrd+json') !== false) { if (strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/jrd+json') !== false) {
$mode = 'json'; $mode = Response::TYPE_JSON;
} else { } else {
$mode = 'xml'; $mode = Response::TYPE_XML;
} }
} else { } else {
if (empty($_GET['resource'])) { if (empty($_GET['resource'])) {
@ -57,9 +57,9 @@ class Xrd extends BaseModule
$uri = urldecode(trim($_GET['resource'])); $uri = urldecode(trim($_GET['resource']));
if (strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/xrd+xml') !== false) { if (strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/xrd+xml') !== false) {
$mode = 'xml'; $mode = Response::TYPE_XML;
} else { } else {
$mode = 'json'; $mode = Response::TYPE_JSON;
} }
} }
@ -101,7 +101,7 @@ class Xrd extends BaseModule
$avatar = ['type' => 'image/jpeg']; $avatar = ['type' => 'image/jpeg'];
} }
if ($mode == 'xml') { if ($mode == Response::TYPE_JSON) {
self::printXML($alias, DI::baseUrl()->get(), $user, $owner, $avatar); self::printXML($alias, DI::baseUrl()->get(), $user, $owner, $avatar);
} else { } else {
self::printJSON($alias, DI::baseUrl()->get(), $owner, $avatar); self::printJSON($alias, DI::baseUrl()->get(), $owner, $avatar);
@ -238,9 +238,6 @@ class Xrd extends BaseModule
{ {
$salmon_key = Salmon::salmonKey($owner['spubkey']); $salmon_key = Salmon::salmonKey($owner['spubkey']);
header('Access-Control-Allow-Origin: *');
header('Content-type: text/xml');
$tpl = Renderer::getMarkupTemplate('xrd_person.tpl'); $tpl = Renderer::getMarkupTemplate('xrd_person.tpl');
$o = Renderer::replaceMacros($tpl, [ $o = Renderer::replaceMacros($tpl, [
@ -263,7 +260,8 @@ class Xrd extends BaseModule
$arr = ['user' => $user, 'xml' => $o]; $arr = ['user' => $user, 'xml' => $o];
Hook::callAll('personal_xrd', $arr); Hook::callAll('personal_xrd', $arr);
echo $arr['xml']; header('Access-Control-Allow-Origin: *');
exit();
System::httpExit($arr['xml'], Response::TYPE_XML);
} }
} }