merge PageCompiler changes from poco-1.9.3

This commit is contained in:
Günter Obiltschnig
2019-08-20 22:04:18 +02:00
parent aec24aa4f7
commit 8f96473bde
3 changed files with 43 additions and 34 deletions

View File

@@ -16,8 +16,8 @@ current date and time.
#include "Poco/DateTime.h" #include "Poco/DateTime.h"
#include "Poco/DateTimeFormatter.h" #include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h" #include "Poco/DateTimeFormat.h"
using Poco::DateTime; using Poco::DateTime;
using Poco::DateTimeFormatter; using Poco::DateTimeFormatter;
using Poco::DateTimeFormat; using Poco::DateTimeFormat;
@@ -244,6 +244,10 @@ Allows to specify a language tag (e.g., "en") that will be sent in the
response Content-Language header if the client sends an Accept-Language response Content-Language header if the client sends an Accept-Language
header in the request. header in the request.
!contentSecurityPolicy
Allows to specify the value of the HTTP Content-Security-Policy header.
!chunked !chunked
Allows you to specify whether the response is sent using chunked transfer encoding. Allows you to specify whether the response is sent using chunked transfer encoding.

View File

@@ -36,13 +36,13 @@ void CodeWriter::writeHeader(std::ostream& ostr, const std::string& headerFileNa
beginGuard(ostr, headerFileName); beginGuard(ostr, headerFileName);
writeHeaderIncludes(ostr); writeHeaderIncludes(ostr);
ostr << "\n\n"; ostr << "\n\n";
std::string decls(_page.headerDecls().str()); std::string decls(_page.headerDecls().str());
if (!decls.empty()) if (!decls.empty())
{ {
ostr << decls << "\n\n"; ostr << decls << "\n\n";
} }
beginNamespace(ostr); beginNamespace(ostr);
writeHandlerClass(ostr); writeHandlerClass(ostr);
writeFactoryClass(ostr); writeFactoryClass(ostr);
@@ -73,13 +73,13 @@ void CodeWriter::writeImpl(std::ostream& ostr, const std::string& headerFileName
} }
beginNamespace(ostr); beginNamespace(ostr);
std::string path = _page.get("page.path", ""); std::string path = _page.get("page.path", "");
if (!path.empty()) if (!path.empty())
{ {
ostr << "\tconst std::string " << _class << "::PATH(\"" << path << "\");\n\n\n"; ostr << "\tconst std::string " << _class << "::PATH(\"" << path << "\");\n\n\n";
} }
writeConstructor(ostr); writeConstructor(ostr);
writeHandler(ostr); writeHandler(ostr);
writeFactory(ostr); writeFactory(ostr);
@@ -124,7 +124,7 @@ void CodeWriter::beginGuard(std::ostream& ostr, const std::string& headerFileNam
std::string guard(p.getBaseName()); std::string guard(p.getBaseName());
Poco::translateInPlace(guard, ".-", "__"); Poco::translateInPlace(guard, ".-", "__");
guard += "_INCLUDED"; guard += "_INCLUDED";
ostr << "#ifndef " << guard << "\n"; ostr << "#ifndef " << guard << "\n";
ostr << "#define " << guard << "\n"; ostr << "#define " << guard << "\n";
ostr << "\n\n"; ostr << "\n\n";
@@ -157,13 +157,13 @@ void CodeWriter::handlerClass(std::ostream& ostr, const std::string& base, const
} }
ostr << "\tvoid handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);\n"; ostr << "\tvoid handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);\n";
writeHandlerMembers(ostr); writeHandlerMembers(ostr);
std::string path = _page.get("page.path", ""); std::string path = _page.get("page.path", "");
if (!path.empty()) if (!path.empty())
{ {
ostr << "\n\tstatic const std::string PATH;\n"; ostr << "\n\tstatic const std::string PATH;\n";
} }
ostr << "};\n"; ostr << "};\n";
} }
@@ -311,13 +311,14 @@ void CodeWriter::writeResponse(std::ostream& ostr)
{ {
std::string contentType(_page.get("page.contentType", "text/html")); std::string contentType(_page.get("page.contentType", "text/html"));
std::string contentLang(_page.get("page.contentLanguage", "")); std::string contentLang(_page.get("page.contentLanguage", ""));
std::string contentSecurityPolicy(_page.get("page.contentSecurityPolicy", ""));
std::string cacheControl(_page.get("page.cacheControl", "")); std::string cacheControl(_page.get("page.cacheControl", ""));
bool buffered(_page.getBool("page.buffered", false)); bool buffered(_page.getBool("page.buffered", false));
bool chunked(_page.getBool("page.chunked", !buffered)); bool chunked(_page.getBool("page.chunked", !buffered));
bool compressed(_page.getBool("page.compressed", false)); bool compressed(_page.getBool("page.compressed", false));
if (buffered) compressed = false; if (buffered) compressed = false;
if (compressed) chunked = true; if (compressed) chunked = true;
if (chunked) if (chunked)
{ {
ostr << "\tresponse.setChunkedTransferEncoding(true);\n"; ostr << "\tresponse.setChunkedTransferEncoding(true);\n";
@@ -329,6 +330,10 @@ void CodeWriter::writeResponse(std::ostream& ostr)
ostr << "\tif (request.has(\"Accept-Language\"))\n" ostr << "\tif (request.has(\"Accept-Language\"))\n"
<< "\t\tresponse.set(\"Content-Language\", \"" << contentLang << "\");\n"; << "\t\tresponse.set(\"Content-Language\", \"" << contentLang << "\");\n";
} }
if (!contentSecurityPolicy.empty())
{
ostr << "\tresponse.set(\"Content-Secure-Policy\", \"" << contentSecurityPolicy << "\");\n";
}
if (compressed) if (compressed)
{ {
ostr << "\tbool _compressResponse(request.hasToken(\"Accept-Encoding\", \"gzip\"));\n" ostr << "\tbool _compressResponse(request.hasToken(\"Accept-Encoding\", \"gzip\"));\n"
@@ -350,7 +355,7 @@ void CodeWriter::writeContent(std::ostream& ostr)
int compressionLevel(_page.getInt("page.compressionLevel", 1)); int compressionLevel(_page.getInt("page.compressionLevel", 1));
if (buffered) compressed = false; if (buffered) compressed = false;
if (compressed) chunked = true; if (compressed) chunked = true;
if (buffered) if (buffered)
{ {
ostr << "\tstd::stringstream responseStream;\n"; ostr << "\tstd::stringstream responseStream;\n";
@@ -359,7 +364,7 @@ void CodeWriter::writeContent(std::ostream& ostr)
{ {
ostr << "\tresponse.setContentLength(static_cast<int>(responseStream.tellp()));\n"; ostr << "\tresponse.setContentLength(static_cast<int>(responseStream.tellp()));\n";
} }
ostr << "\tPoco::StreamCopier::copyStream(responseStream, response.send());\n"; ostr << "\tPoco::StreamCopier::copyStream(responseStream, response.send());\n";
} }
else if (compressed) else if (compressed)
{ {
@@ -383,7 +388,7 @@ std::string CodeWriter::cleanupHandler(std::string handler)
static const std::string NEWLINE_WRITE("\tresponseStream << \"\\n\";\n"); static const std::string NEWLINE_WRITE("\tresponseStream << \"\\n\";\n");
static const std::string DOUBLE_NEWLINE_WRITE("\tresponseStream << \"\\n\";\n\tresponseStream << \"\\n\";\n"); static const std::string DOUBLE_NEWLINE_WRITE("\tresponseStream << \"\\n\";\n\tresponseStream << \"\\n\";\n");
static const std::string EMPTY; static const std::string EMPTY;
// remove empty writes // remove empty writes
Poco::replaceInPlace(handler, EMPTY_WRITE, EMPTY); Poco::replaceInPlace(handler, EMPTY_WRITE, EMPTY);
// remove consecutive newlines // remove consecutive newlines

View File

@@ -54,7 +54,7 @@ using Poco::OutputLineEndingConverter;
class CompilerApp: public Application class CompilerApp: public Application
{ {
public: public:
CompilerApp(): CompilerApp():
_helpRequested(false), _helpRequested(false),
_generateOSPCode(false), _generateOSPCode(false),
_generateApacheCode(false), _generateApacheCode(false),
@@ -62,13 +62,13 @@ public:
{ {
} }
protected: protected:
void initialize(Application& self) void initialize(Application& self)
{ {
loadConfiguration(); // load default configuration files, if present loadConfiguration(); // load default configuration files, if present
Application::initialize(self); Application::initialize(self);
} }
void defineOptions(OptionSet& options) void defineOptions(OptionSet& options)
{ {
Application::defineOptions(options); Application::defineOptions(options);
@@ -80,7 +80,7 @@ protected:
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleHelp))); .callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleHelp)));
options.addOption( options.addOption(
Option("define", "D", Option("define", "D",
"Define a configuration property. A configuration property " "Define a configuration property. A configuration property "
"defined with this option can be referenced in the input " "defined with this option can be referenced in the input "
"page file, using the following syntax: ${<name>}.") "page file, using the following syntax: ${<name>}.")
@@ -88,7 +88,7 @@ protected:
.repeatable(true) .repeatable(true)
.argument("<name>=<value>") .argument("<name>=<value>")
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleDefine))); .callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleDefine)));
options.addOption( options.addOption(
Option("config-file", "f", "Load configuration data from the given file.") Option("config-file", "f", "Load configuration data from the given file.")
.required(false) .required(false)
@@ -142,18 +142,18 @@ protected:
.repeatable(false) .repeatable(false)
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleNoLine))); .callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleNoLine)));
} }
void handleHelp(const std::string& name, const std::string& value) void handleHelp(const std::string& name, const std::string& value)
{ {
_helpRequested = true; _helpRequested = true;
stopOptionsProcessing(); stopOptionsProcessing();
} }
void handleDefine(const std::string& name, const std::string& value) void handleDefine(const std::string& name, const std::string& value)
{ {
defineProperty(value); defineProperty(value);
} }
void handleConfig(const std::string& name, const std::string& value) void handleConfig(const std::string& name, const std::string& value)
{ {
loadConfiguration(value); loadConfiguration(value);
@@ -183,19 +183,19 @@ protected:
void handleOSP(const std::string& name, const std::string& value) void handleOSP(const std::string& name, const std::string& value)
{ {
_generateOSPCode = true; _generateOSPCode = true;
} }
void handleApache(const std::string& name, const std::string& value) void handleApache(const std::string& name, const std::string& value)
{ {
_generateApacheCode = true; _generateApacheCode = true;
} }
void handleNoLine(const std::string& name, const std::string& value) void handleNoLine(const std::string& name, const std::string& value)
{ {
_emitLineDirectives = false; _emitLineDirectives = false;
} }
void displayHelp() void displayHelp()
{ {
HelpFormatter helpFormatter(options()); HelpFormatter helpFormatter(options());
@@ -204,7 +204,7 @@ protected:
helpFormatter.setHeader( helpFormatter.setHeader(
"\n" "\n"
"The POCO C++ Server Page Compiler.\n" "The POCO C++ Server Page Compiler.\n"
"Copyright (c) 2008-2018 by Applied Informatics Software Engineering GmbH.\n" "Copyright (c) 2008-2019 by Applied Informatics Software Engineering GmbH.\n"
"All rights reserved.\n\n" "All rights reserved.\n\n"
"This program compiles web pages containing embedded C++ code " "This program compiles web pages containing embedded C++ code "
"into a C++ class that can be used with the HTTP server " "into a C++ class that can be used with the HTTP server "
@@ -218,7 +218,7 @@ protected:
helpFormatter.setIndent(8); helpFormatter.setIndent(8);
helpFormatter.format(std::cout); helpFormatter.format(std::cout);
} }
void defineProperty(const std::string& def) void defineProperty(const std::string& def)
{ {
std::string name; std::string name;
@@ -245,7 +245,7 @@ protected:
{ {
compile(*it); compile(*it);
} }
return Application::EXIT_OK; return Application::EXIT_OK;
} }
@@ -257,7 +257,7 @@ protected:
pageReader.parse(srcStream); pageReader.parse(srcStream);
Path p(path); Path p(path);
if (page.has("page.class")) if (page.has("page.class"))
{ {
clazz = page.get("page.class"); clazz = page.get("page.class");
@@ -266,15 +266,15 @@ protected:
{ {
clazz = p.getBaseName() + "Handler"; clazz = p.getBaseName() + "Handler";
clazz[0] = Poco::Ascii::toUpper(clazz[0]); clazz[0] = Poco::Ascii::toUpper(clazz[0]);
} }
} }
void write(const std::string& path, const Page& page, const std::string& clazz) void write(const std::string& path, const Page& page, const std::string& clazz)
{ {
Path p(path); Path p(path);
config().setString("inputFileName", p.getFileName()); config().setString("inputFileName", p.getFileName());
config().setString("inputFilePath", p.toString()); config().setString("inputFilePath", p.toString());
DateTime now; DateTime now;
config().setString("dateTime", DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT)); config().setString("dateTime", DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));
@@ -293,12 +293,12 @@ protected:
{ {
p = Path(_outputDir, p.getBaseName()); p = Path(_outputDir, p.getBaseName());
} }
if (!_base.empty()) if (!_base.empty())
{ {
p.setBaseName(_base); p.setBaseName(_base);
} }
p.setExtension("cpp"); p.setExtension("cpp");
std::string implPath = p.toString(); std::string implPath = p.toString();
std::string implFileName = p.getFileName(); std::string implFileName = p.getFileName();
@@ -325,7 +325,7 @@ protected:
writeFileHeader(headerLEC); writeFileHeader(headerLEC);
pCodeWriter->writeHeader(headerLEC, headerFileName); pCodeWriter->writeHeader(headerLEC, headerFileName);
} }
void compile(const std::string& path) void compile(const std::string& path)
{ {
Page page; Page page;