commit d8e3bf753c21a2fe18d25612fb600deb8fc242e1
parent 7a6c79051c8d0fa6f3f8d14f8de54101c21b2090
Author: dankert <openrat@jandankert.de>
Date: Sat, 19 Mar 2022 00:09:47 +0100
Refactoring: Outputs are setting their content-type themself.
Diffstat:
16 files changed, 72 insertions(+), 33 deletions(-)
diff --git a/index.php b/index.php
@@ -15,14 +15,15 @@ try {
Startup::initialize();
} catch (ErrorException $e) {
+ // Switching to text/plain here because so there is no way to inject any HTML to the page.
header('Content-Type: text/plain');
error_log( $e->getMessage() );
- echo "Startup failed";
+ echo "Sorry, startup failed";
+ exit;
}
// Creates the output driver
// Dependent on which data format is requested by the client.
$output = OutputFactory::createOutput();
-header('Content-Type: ' . $output->getContentType() . '; charset=' . Startup::CHARSET);
$output->execute(); // Outputs the data.
\ No newline at end of file
diff --git a/modules/cms/action/Action.class.php b/modules/cms/action/Action.class.php
@@ -112,6 +112,26 @@ abstract class Action
$this->response->addHeader( $name, $value );
}
+
+ /**
+ * Sets the content security policy.
+ *
+ * @param $csp string content security policy as array
+ */
+ protected function setContentSecurityPolicy( $csp ) {
+ $this->response->setContentSecurityPolicy( $csp );
+ }
+
+
+ /**
+ * Sets the content type.
+ *
+ * @param $type
+ */
+ protected function setContentType( $type ) {
+ $this->response->setContentType( $type );
+ }
+
/**
* F�gt einen Validierungsfehler hinzu.
*
@@ -290,7 +310,7 @@ abstract class Action
return;
// Der entfernte Browser bzw. Proxy holt die Seite nun aus seinem Cache
- $this->addHeader('HTTP/1.0 304 Not Modified');
+ header('HTTP/1.0 304 Not Modified');
exit; // Sofortiges Skript-Ende
}
diff --git a/modules/cms/action/ObjectAction.class.php b/modules/cms/action/ObjectAction.class.php
@@ -58,6 +58,7 @@ class ObjectAction extends BaseAction
$this->setBaseObject( $baseObject );
+ $this->addHeader('X-CMS-OID',$baseObject->objectid );
}
diff --git a/modules/cms/action/Response.class.php b/modules/cms/action/Response.class.php
@@ -32,6 +32,24 @@ class Response
}
+ public function setContentSecurityPolicy( $csp ) {
+
+ // Content Security Policy
+ $this->header['Content-Security-Policy'] = implode(';', array_map( function($value,$key) {
+ return $key.' '.$value;
+ },$csp,array_keys($csp) ));
+ }
+
+
+ /**
+ * Sets the content type.
+ * @param $type string
+ * @param $charset string Default: UTF-8
+ */
+ public function setContentType( $type, $charset = Startup::CHARSET) {
+ $this->header['Content-Type'] = $type.'; charset=' . $charset;
+ }
+
/**
* Getting the response data as an array.
*
@@ -72,6 +90,8 @@ class Response
}
+
+
/**
* F�gt ein Meldung hinzu.
*
diff --git a/modules/cms/action/file/FileShowAction.class.php b/modules/cms/action/file/FileShowAction.class.php
@@ -47,18 +47,15 @@ class FileShowAction extends FileAction implements Method {
$mime_type = File::$MIME_TYPES[$ext];
- $this->addHeader('Content-Type',$mime_type );
+ $this->setContentType( $mime_type );
$this->addHeader('Content-Encoding','gzip' );
}
else
{
// Angabe Content-Type
- $this->addHeader('Content-Type',$generator->getMimeType() );
+ $this->setContentType($generator->getMimeType() );
}
- $this->addHeader('X-File-Id',$this->file->fileid );
- $this->addHeader('X-Id' ,$this->file->objectid );
-
// Image should be displayed inline.
// Filename is used if the user agent is saving the file.
$this->addHeader('Content-Disposition' ,'inline; filename='.$this->file->filename() );
diff --git a/modules/cms/action/folder/FolderShowAction.class.php b/modules/cms/action/folder/FolderShowAction.class.php
@@ -18,7 +18,7 @@ class FolderShowAction extends FolderAction implements Method {
public function view() {
// Angabe Content-Type
- $this->addHeader('Content-Type','text/html' );
+ $this->setContentType('text/html' );
$this->addHeader('X-Folder-Id' ,$this->folder->folderid );
$this->addHeader('X-Id' ,$this->folder->objectid );
diff --git a/modules/cms/action/link/LinkShowAction.class.php b/modules/cms/action/link/LinkShowAction.class.php
@@ -9,11 +9,8 @@ use util\Html;
class LinkShowAction extends LinkAction implements Method {
public function view() {
- $this->addHeader('Content-Type','text/html' );
+ $this->setContentType('text/html' );
- $this->addHeader('X-Link-Id' ,$this->link->linkid );
- $this->addHeader('X-Id' ,$this->link->objectid );
- $this->addHeader('Content-Description',$this->link->filename() );
echo '<html><body>';
echo '<h1>'.$this->link->filename.'</h1>';
diff --git a/modules/cms/action/page/PageShowAction.class.php b/modules/cms/action/page/PageShowAction.class.php
@@ -16,7 +16,7 @@ class PageShowAction extends PageAction implements Method {
// The output is only shown in an iframe, so there is no security impact to the CMS.
// But if the template is using inline JS or CSS, we would break this with a CSP-header.
$pageSettingsConfig = new Config( $this->page->getTotalSettings() );
- $this->addHeader('Content-Security-Policy',$pageSettingsConfig->get('content-security-policy','') );
+ $this->setContentSecurityPolicy($pageSettingsConfig->get('content-security-policy',[]) );
$this->page->load();
@@ -32,7 +32,7 @@ class PageShowAction extends PageAction implements Method {
$generator = new PageGenerator( $pageContext );
- $this->addHeader('Content-Type',$generator->getMimeType().'; charset=UTF-8' );
+ $this->setContentType( $generator->getMimeType() );
$template = new Template( $this->page->templateid );
diff --git a/modules/cms/action/template/TemplateShowAction.class.php b/modules/cms/action/template/TemplateShowAction.class.php
@@ -16,7 +16,7 @@ class TemplateShowAction extends TemplateAction implements Method {
$tplGenerator = new TemplateGenerator( $this->template->templateid, $this->request->getModelId(), Producer::SCHEME_PREVIEW );
- $this->addHeader('Content-Type',$tplGenerator->getMimeType().'; charset=UTF-8' );
+ $this->setContentType($tplGenerator->getMimeType() );
// Template should have access to the page properties.
// Template should have access to the settings of this node object.
diff --git a/modules/cms/action/url/UrlShowAction.class.php b/modules/cms/action/url/UrlShowAction.class.php
@@ -9,11 +9,7 @@ class UrlShowAction extends UrlAction implements Method {
public function view() {
// Angabe Content-Type
- $this->addHeader('Content-Type','text/html' );
-
- $this->addHeader('X-Url-Id' ,$this->url->urlid );
- $this->addHeader('X-Id' ,$this->url->objectid );
- $this->addHeader('Content-Description',$this->url->filename() );
+ $this->setContentType('text/html' );
echo '<html><body>';
echo '<h1>'.$this->url->filename.'</h1>';
diff --git a/modules/cms/output/BaseOutput.class.php b/modules/cms/output/BaseOutput.class.php
@@ -6,6 +6,7 @@ use BadMethodCallException;
use cms\action\RequestParams;
use cms\action\Response;
use cms\base\Language as L;
+use cms\base\Startup;
use cms\Dispatcher;
use Exception;
use util\Http;
@@ -48,6 +49,10 @@ abstract class BaseOutput implements Output
$dispatcher->setRequestAndResponse( $request,$response );
$dispatcher->doAction(); // calling the action ...
+
+ if ( $contentType = $this->getContentType() )
+ header('Content-Type: '.$contentType.'; charset='.Startup::CHARSET);
+
$response->setHTTPHeader();
$this->outputData( $request,$response->getOutputData() ); // ... and output the data
diff --git a/modules/cms/output/PreviewOutput.class.php b/modules/cms/output/PreviewOutput.class.php
@@ -12,15 +12,22 @@ use util\YAML;
class PreviewOutput extends APIOutput
{
/**
- * Renders the output directy from the action output.
+ * Renders the output directly from the action output.
*/
protected function renderOutput( $data )
{
+ // HTTP Spec:
+ // "Applications SHOULD use this field to indicate the transfer-length of the
+ // message-body, unless this is prohibited by the rules in section 4.4."
+ //
+ // And the overhead of 'Transfer-Encoding: chunked' is eliminated...
+ header('Content-Length: ' . strlen($data['output']['value']));
+
return $data['output']['value'];
}
public function getContentType()
{
- return 'text/css';
+ return null; // 'null' because the actions are setting their Content-Type.
}
}
diff --git a/modules/cms/ui/action/IndexAction.class.php b/modules/cms/ui/action/IndexAction.class.php
@@ -48,7 +48,7 @@ class IndexAction extends Action
*/
protected function getUserStyle($user )
{
- // Theme für den angemeldeten Benuter ermitteln
+ // Theme für den angemeldeten Benutzer ermitteln
if ( $user && C::subset('style')->has($user->style) )
$style = $user->style;
else
@@ -62,16 +62,14 @@ class IndexAction extends Action
/**
* Content-Security-Policy.
*/
- protected function setContentSecurityPolicy()
+ protected function addContentSecurityPolicy()
{
$csp = Configuration::subset('security' )->get('csp', [
'default-src' =>'\'self\'', // Default for all is 'self' (CSS, styles, etc)
'frame-src' => '*' // For preview of urls we need to show every url in an iframe.
] );
- header('Content-Security-Policy: ' . implode(';', array_map( function($value,$key) {
- return $key.' '.$value;
- },$csp,array_keys($csp) )));
+ $this->setContentSecurityPolicy( $csp );
}
diff --git a/modules/cms/ui/action/index/IndexShowAction.class.php b/modules/cms/ui/action/index/IndexShowAction.class.php
@@ -27,7 +27,7 @@ class IndexShowAction extends IndexAction implements Method {
public function view() {
- $this->setContentSecurityPolicy();
+ $this->addContentSecurityPolicy();
$user = Session::getUser();
@@ -58,7 +58,7 @@ class IndexShowAction extends IndexAction implements Method {
$this->setTemplateVar('styleLink' , $this->getStyleLink() );
$this->setTemplateVar('themeStyleLink', Html::url('index','themestyle',0,['style'=>$style]) );
- $this->setTemplateVar('manifestLink' , Html::url('index','manifest' ) );
+ $this->setTemplateVar('manifestLink' , Html::url('index','manifest',0,['output'=>'json'] ) );
$themeStyle = new ThemeStyle( Configuration::subset('style')->get($style,[]) ); // user style config
diff --git a/modules/cms/ui/themes/default/html/views/index/manifest.php b/modules/cms/ui/themes/default/html/views/index/manifest.php
@@ -1 +0,0 @@
-<?php /* THIS FILE IS GENERATED from manifest.tpl.src.xml - DO NOT CHANGE */ defined('APP_STARTED') || die('Forbidden'); use \template_engine\Output as O; ?><?php echo ''.@$manifest.'' ?>
-\ No newline at end of file
diff --git a/modules/cms/ui/themes/default/html/views/index/manifest.tpl.src.xml b/modules/cms/ui/themes/default/html/views/index/manifest.tpl.src.xml
@@ -1 +0,0 @@
-<text xmlns="http://www.openrat.de/template" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openrat.de/template ../../../../../../../template_engine/components/template.xsd" value="${manifest}" escape="false" type="none"/>