Fixing Response

This commit is contained in:
Philipp Holzer 2021-11-22 00:07:09 +01:00
parent ae24bf8d54
commit 6a9fff5100
Signed by: nupplaPhil
GPG key ID: 24A7501396EB5432
11 changed files with 41 additions and 12 deletions

View file

@ -704,7 +704,7 @@ class App
// Let the module run it's internal process (init, get, post, ...) // Let the module run it's internal process (init, get, post, ...)
$response = $module->run($_POST, $_REQUEST); $response = $module->run($_POST, $_REQUEST);
if ($response->getHeaderLine('X-RESPONSE-TYPE') === ICanCreateResponses::TYPE_HTML) { if ($response->getHeaderLine(ICanCreateResponses::X_HEADER) === ICanCreateResponses::TYPE_HTML) {
$page->run($this, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig); $page->run($this, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig);
} else { } else {
$page->exit($response); $page->exit($response);

View file

@ -7,6 +7,11 @@ use Psr\Http\Message\ResponseInterface;
interface ICanCreateResponses interface ICanCreateResponses
{ {
/**
* This constant helps to find the specific return type of responses inside the headers array
*/
const X_HEADER = 'X-RESPONSE-TYPE';
const TYPE_HTML = 'html'; const TYPE_HTML = 'html';
const TYPE_XML = 'xml'; const TYPE_XML = 'xml';
const TYPE_JSON = 'json'; const TYPE_JSON = 'json';

View file

@ -199,10 +199,10 @@ class ApiResponse extends Response
switch ($format) { switch ($format) {
case 'xml': case 'xml':
$this->setHeader('Content-Type: text/xml'); $this->setType(static::TYPE_XML);
break; break;
case 'json': case 'json':
$this->setHeader('Content-Type: application/json'); $this->setType(static::TYPE_JSON);
if (!empty($return)) { if (!empty($return)) {
$json = json_encode(end($return)); $json = json_encode(end($return));
if (!empty($_GET['callback'])) { if (!empty($_GET['callback'])) {
@ -212,10 +212,10 @@ class ApiResponse extends Response
} }
break; break;
case 'rss': case 'rss':
$this->setHeader('Content-Type: application/rss+xml'); $this->setType(static::TYPE_RSS);
break; break;
case 'atom': case 'atom':
$this->setHeader('Content-Type: application/atom+xml'); $this->setType(static::TYPE_ATOM);
break; break;
} }

View file

@ -19,7 +19,7 @@ class Response implements ICanCreateResponses
/** /**
* @var string * @var string
*/ */
protected $type = ICanCreateResponses::TYPE_HTML; protected $type = self::TYPE_HTML;
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -68,7 +68,7 @@ class Response implements ICanCreateResponses
*/ */
public function setType(string $type, ?string $content_type = null): void public function setType(string $type, ?string $content_type = null): void
{ {
if (!in_array($type, ICanCreateResponses::ALLOWED_TYPES)) { if (!in_array($type, static::ALLOWED_TYPES)) {
throw new InternalServerErrorException('wrong type'); throw new InternalServerErrorException('wrong type');
} }
@ -79,9 +79,14 @@ class Response implements ICanCreateResponses
case static::TYPE_XML: case static::TYPE_XML:
$content_type = $content_type ?? 'text/xml'; $content_type = $content_type ?? 'text/xml';
break; break;
case static::TYPE_RSS:
$content_type = $content_type ?? 'application/rss+xml';
break;
case static::TYPE_ATOM:
$content_type = $content_type ?? 'application/atom+xml';
break;
} }
$this->setHeader($content_type, 'Content-type'); $this->setHeader($content_type, 'Content-type');
$this->type = $type; $this->type = $type;
@ -101,7 +106,7 @@ class Response implements ICanCreateResponses
public function generate(): ResponseInterface public function generate(): ResponseInterface
{ {
// Setting the response type as an X-header for direct usage // Setting the response type as an X-header for direct usage
$this->headers['X-RESPONSE-TYPE'] = $this->type; $this->headers[static::X_HEADER] = $this->type;
return new \GuzzleHttp\Psr7\Response(200, $this->headers, $this->content); return new \GuzzleHttp\Psr7\Response(200, $this->headers, $this->content);
} }

View file

@ -37,6 +37,7 @@ class ApiResponseTest extends MockedTest
$response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser); $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
$response->error(200, 'OK', 'error_message', 'xml'); $response->error(200, 'OK', 'error_message', 'xml');
self::assertEquals(['Content-type' => 'text/xml', 'HTTP/1.1 200 OK'], $response->getHeaders());
self::assertEquals('<?xml version="1.0"?>' . "\n" . self::assertEquals('<?xml version="1.0"?>' . "\n" .
'<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' . '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
'xmlns:friendica="http://friendi.ca/schema/api/1/" ' . 'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
@ -59,6 +60,7 @@ class ApiResponseTest extends MockedTest
$response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser); $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
$response->error(200, 'OK', 'error_message', 'rss'); $response->error(200, 'OK', 'error_message', 'rss');
self::assertEquals(['Content-type' => 'application/rss+xml', 'HTTP/1.1 200 OK'], $response->getHeaders());
self::assertEquals( self::assertEquals(
'<?xml version="1.0"?>' . "\n" . '<?xml version="1.0"?>' . "\n" .
'<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' . '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
@ -82,6 +84,7 @@ class ApiResponseTest extends MockedTest
$response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser); $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
$response->error(200, 'OK', 'error_message', 'atom'); $response->error(200, 'OK', 'error_message', 'atom');
self::assertEquals(['Content-type' => 'application/atom+xml', 'HTTP/1.1 200 OK'], $response->getHeaders());
self::assertEquals( self::assertEquals(
'<?xml version="1.0"?>' . "\n" . '<?xml version="1.0"?>' . "\n" .
'<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' . '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .

View file

@ -21,6 +21,7 @@
namespace Friendica\Test\src\Module\Api\Friendica; namespace Friendica\Test\src\Module\Api\Friendica;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Api\Friendica\Notification; use Friendica\Module\Api\Friendica\Notification;
use Friendica\Test\src\Module\Api\ApiTest; use Friendica\Test\src\Module\Api\ApiTest;
@ -68,7 +69,10 @@ XML;
$notification = new Notification(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml']); $notification = new Notification(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml']);
$response = $notification->run(); $response = $notification->run();
print_r($response->getHeaders());
self::assertXmlStringEqualsXmlString($assertXml, (string)$response->getBody()); self::assertXmlStringEqualsXmlString($assertXml, (string)$response->getBody());
self::assertEquals(['Content-type' => ['text/xml'], ICanCreateResponses::X_HEADER => ['xml']], $response->getHeaders());
} }
public function testWithJsonResult() public function testWithJsonResult()
@ -77,5 +81,6 @@ XML;
$response = $notification->run(); $response = $notification->run();
self::assertJson($response->getBody()); self::assertJson($response->getBody());
self::assertEquals(['Content-type' => ['application/json'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders());
} }
} }

View file

@ -2,6 +2,7 @@
namespace Friendica\Test\src\Module\Api\GnuSocial\GnuSocial; namespace Friendica\Test\src\Module\Api\GnuSocial\GnuSocial;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Api\GNUSocial\GNUSocial\Version; use Friendica\Module\Api\GNUSocial\GNUSocial\Version;
use Friendica\Test\src\Module\Api\ApiTest; use Friendica\Test\src\Module\Api\ApiTest;
@ -13,6 +14,7 @@ class VersionTest extends ApiTest
$version = new Version(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json']); $version = new Version(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json']);
$response = $version->run(); $response = $version->run();
self::assertEquals(['Content-type' => ['application/json'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders());
self::assertEquals('"0.9.7"', $response->getBody()); self::assertEquals('"0.9.7"', $response->getBody());
} }
} }

View file

@ -2,6 +2,7 @@
namespace Friendica\Test\src\Module\Api\GnuSocial\Help; namespace Friendica\Test\src\Module\Api\GnuSocial\Help;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Api\GNUSocial\Help\Test; use Friendica\Module\Api\GNUSocial\Help\Test;
use Friendica\Test\src\Module\Api\ApiTest; use Friendica\Test\src\Module\Api\ApiTest;
@ -13,6 +14,7 @@ class TestTest extends ApiTest
$test = new Test(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json']); $test = new Test(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'json']);
$response = $test->run(); $response = $test->run();
self::assertEquals(['Content-type' => ['application/json'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders());
self::assertEquals('"ok"', $response->getBody()); self::assertEquals('"ok"', $response->getBody());
} }
@ -21,6 +23,7 @@ class TestTest extends ApiTest
$test = new Test(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml']); $test = new Test(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml']);
$response = $test->run(); $response = $test->run();
self::assertEquals(['Content-type' => ['text/xml'], ICanCreateResponses::X_HEADER => ['xml']], $response->getHeaders());
self::assertxml($response->getBody(), 'ok'); self::assertxml($response->getBody(), 'ok');
} }
} }

View file

@ -2,6 +2,7 @@
namespace Friendica\Test\src\Module\Api\Twitter\Account; namespace Friendica\Test\src\Module\Api\Twitter\Account;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Api\Twitter\Account\RateLimitStatus; use Friendica\Module\Api\Twitter\Account\RateLimitStatus;
use Friendica\Test\src\Module\Api\ApiTest; use Friendica\Test\src\Module\Api\ApiTest;
@ -15,6 +16,7 @@ class RateLimitStatusTest extends ApiTest
$result = json_decode($response->getBody()); $result = json_decode($response->getBody());
self::assertEquals(['Content-type' => ['application/json'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders());
self::assertEquals(150, $result->remaining_hits); self::assertEquals(150, $result->remaining_hits);
self::assertEquals(150, $result->hourly_limit); self::assertEquals(150, $result->hourly_limit);
self::assertIsInt($result->reset_time_in_seconds); self::assertIsInt($result->reset_time_in_seconds);
@ -25,6 +27,7 @@ class RateLimitStatusTest extends ApiTest
$rateLimitStatus = new RateLimitStatus(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml']); $rateLimitStatus = new RateLimitStatus(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), [], ['extension' => 'xml']);
$response = $rateLimitStatus->run(); $response = $rateLimitStatus->run();
self::assertEquals(['Content-type' => ['text/xml'], ICanCreateResponses::X_HEADER => ['xml']], $response->getHeaders());
self::assertXml($response->getBody(), 'hash'); self::assertXml($response->getBody(), 'hash');
} }
} }

View file

@ -2,6 +2,7 @@
namespace Friendica\Test\src\Module\Api\Twitter; namespace Friendica\Test\src\Module\Api\Twitter;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Api\Twitter\SavedSearches; use Friendica\Module\Api\Twitter\SavedSearches;
use Friendica\Test\src\Module\Api\ApiTest; use Friendica\Test\src\Module\Api\ApiTest;
@ -15,6 +16,7 @@ class SavedSearchesTest extends ApiTest
$result = json_decode($response->getBody()); $result = json_decode($response->getBody());
self::assertEquals(['Content-type' => ['application/json'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders());
self::assertEquals(1, $result[0]->id); self::assertEquals(1, $result[0]->id);
self::assertEquals(1, $result[0]->id_str); self::assertEquals(1, $result[0]->id_str);
self::assertEquals('Saved search', $result[0]->name); self::assertEquals('Saved search', $result[0]->name);

View file

@ -2,6 +2,7 @@
namespace Friendica\Test\src\Module; namespace Friendica\Test\src\Module;
use Friendica\Capabilities\ICanCreateResponses;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\NodeInfo110; use Friendica\Module\NodeInfo110;
use Friendica\Module\NodeInfo120; use Friendica\Module\NodeInfo120;
@ -19,7 +20,7 @@ class NodeInfoTest extends FixtureTest
$response = $nodeinfo->run(); $response = $nodeinfo->run();
self::assertJson($response->getBody()); self::assertJson($response->getBody());
self::assertEquals(['Content-type' => ['application/json']], $response->getHeaders()); self::assertEquals(['Content-type' => ['application/json'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders());
$json = json_decode($response->getBody()); $json = json_decode($response->getBody());
@ -42,7 +43,7 @@ class NodeInfoTest extends FixtureTest
$response = $nodeinfo->run(); $response = $nodeinfo->run();
self::assertJson($response->getBody()); self::assertJson($response->getBody());
self::assertEquals(['Content-type' => ['application/json; charset=utf-8']], $response->getHeaders()); self::assertEquals(['Content-type' => ['application/json; charset=utf-8'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders());
$json = json_decode($response->getBody()); $json = json_decode($response->getBody());
@ -64,7 +65,7 @@ class NodeInfoTest extends FixtureTest
$response = $nodeinfo->run(); $response = $nodeinfo->run();
self::assertJson($response->getBody()); self::assertJson($response->getBody());
self::assertEquals(['Content-type' => ['application/json; charset=utf-8']], $response->getHeaders()); self::assertEquals(['Content-type' => ['application/json; charset=utf-8'], ICanCreateResponses::X_HEADER => ['json']], $response->getHeaders());
$json = json_decode($response->getBody()); $json = json_decode($response->getBody());