HtmlTextStream has now pt::Stream as a based class and uses pt::WTextStream as a buffer

This commit is contained in:
2021-07-16 18:17:57 +02:00
parent ba6159964b
commit c5c02d7f44
14 changed files with 764 additions and 375 deletions

View File

@@ -696,7 +696,7 @@ void App::ClearAfterRequest()
try
{
// simple operations which should not throw an exception
json_out_stream.Clear();
json_out_stream.clear();
templates.ClearAfterRequest();
cur.request->Clear();
cur.session->ClearAfterRequest();
@@ -767,7 +767,7 @@ void App::SaveSessionsIfNeeded()
const std::wstring * App::CreateFrameAnswer()
pt::WTextStream * App::CreateFrameAnswer()
{
Request & req = *cur.request;
auto i = req.out_streams.streams_map.begin();
@@ -777,8 +777,7 @@ const std::wstring * App::CreateFrameAnswer()
{
if( (frame && i->first == *frame) || (!frame && i->first == L"content") )
{
return &i->second->Str();
break;
return &i->second->get_buffer();
}
}
@@ -786,10 +785,10 @@ const std::wstring * App::CreateFrameAnswer()
}
void App::CreateJSONAnswer()
pt::WTextStream * App::CreateJSONAnswer()
{
Request & req = *cur.request;
json_out_stream.Clear();
json_out_stream.clear();
if( !req.return_info_only )
{
@@ -806,9 +805,9 @@ void App::CreateJSONAnswer()
}
json_out_stream << L"\"";
JSONescape(json_out_stream, i->first);
JSONescape(i->first, json_out_stream);
json_out_stream << L"\": \"";
JSONescape(json_out_stream, i->second->Str());
JSONescapeStream(i->second->get_buffer(), json_out_stream);
json_out_stream << L"\"";
is_first = false;
}
@@ -825,6 +824,8 @@ void App::CreateJSONAnswer()
log << " (Request::info only)";
log << logend;
return &json_out_stream;
}
@@ -1736,9 +1737,16 @@ void App::FilterContent()
if( filter_main_stream )
{
// !! IMPROVE ME may some kind of html_filtered.reserve() here? (optimization)
TemplatesFunctions::html_filter.Filter(req.out_main_stream.Str(), html_filtered);
req.out_main_stream.Str(std::move(html_filtered)); // !! IMPROVE ME we do not have Str(&&) method
std::wstring tmp_out_main_stream;
req.out_main_stream.to_str(tmp_out_main_stream, false);
TemplatesFunctions::html_filter.Filter(tmp_out_main_stream, html_filtered); // IMPROVEME let Filter take pt::WTextStream
/*
* it would be better to just return a pointer from this method
*
*/
req.out_main_stream.clear();
req.out_main_stream.PutText(html_filtered);
log << log3 << "App: html in the main stream has been filtered" << logend;
}
@@ -1747,9 +1755,14 @@ void App::FilterContent()
for(auto i = req.out_streams.streams_map.begin() ; i != req.out_streams.streams_map.end() ; ++i)
{
HtmlTextStream & stream = *i->second;
// !! IMPROVE ME may some kind of html_filtered.reserve() here? (optimization)
TemplatesFunctions::html_filter.Filter(stream.Str(), html_filtered);
stream.Str(std::move(html_filtered));
std::wstring tmp_stream;
stream.to_str(tmp_stream, false);
TemplatesFunctions::html_filter.Filter(tmp_stream, html_filtered);
stream.clear();
stream.PutText(html_filtered);
}
log << log3 << "App: html in json out streams have been filtered" << logend;
@@ -1878,22 +1891,25 @@ return header;
void App::SendTextAnswer()
{
const std::wstring * source = nullptr;
const pt::WTextStream * source = nullptr;
bool compressing = false;
int compress_encoding = 0;
size_t output_size = 0;
Header header = GetHTTPStatusCode();
if( CanSendContent() )
{
/*
* FIXME frames are not filtered (when is_htmx_request is true)
*
* FilterContent() should be combined with CreateJSONAnswer() and CreateFrameAnswer() somehow
*/
FilterContent();
if( cur.request->return_json )
{
CreateJSONAnswer();
source = &json_out_stream.Str(); // json_out_stream was prepared by CreateJSONAnswer()
source = CreateJSONAnswer();
}
else
if( cur.request->is_htmx_request )
@@ -1908,12 +1924,12 @@ size_t output_size = 0;
}
else
{
source = &cur.request->out_main_stream.Str();
source = &cur.request->out_main_stream.get_buffer();
}
SelectCompression(source->length(), compressing, compress_encoding);
SelectCompression(source->size(), compressing, compress_encoding);
pt::wide_to_utf8(*source, output_8bit);
pt::wide_stream_to_utf8(*source, output_8bit);
// !! IMPROVE ME add to log the binary stream as well
if( config.log_server_answer )

View File

@@ -147,7 +147,7 @@ private:
pthread_t signal_thread;
std::string socket_to_send_on_exit;
std::string send_data_buf;
TextStream<std::wstring> json_out_stream;
pt::WTextStream json_out_stream;
std::string aheader_name, aheader_value;
std::wstring html_filtered;
std::string output_8bit;
@@ -156,7 +156,7 @@ private:
std::wstring http_header_name;
std::wstring http_header_value;
std::string http_header_8bit;
std::wstring empty_response;
pt::WTextStream empty_response;
WinixModelConnector model_connector; // main thread model connector, each thread has its own connector
morm::JSONConnector json_connector;
@@ -200,8 +200,8 @@ private:
void SaveSessionsIfNeeded(); // !! IMPROVE ME wywalic do menagera sesji??
void LogAccess();
void SendData(const BinaryPage & page, FCGX_Stream * out);
const std::wstring * CreateFrameAnswer();
void CreateJSONAnswer();
pt::WTextStream * CreateFrameAnswer();
pt::WTextStream * CreateJSONAnswer();
void ReadRequest();
void SendTextAnswer();

View File

@@ -1450,6 +1450,17 @@ void RemovePostFileTmp(PostFileTab & post_file_tab)
}
void JSONescapeStream(const pt::WTextStream & in, pt::WTextStream & out)
{
pt::WTextStream::const_iterator i = in.begin();
for( ; i != in.end() ; ++i)
{
JSONescape(*i, out);
}
}
bool wide_to_utf8(const wchar_t * wide_string, char * utf8, size_t utf8_size)
{
bool res = pt::wide_to_utf8(wide_string, utf8, utf8_size);

View File

@@ -946,20 +946,11 @@ void SetMinMax(IntType & val, IntType min_val, IntType max_val)
}
template<class Stream, class StringType>
void JSONescape(Stream & out, const StringType & str)
template<class Stream>
void JSONescape(wchar_t c, Stream & out)
{
// !! IMPROVE ME (optimizing)
// it is better to not write one by one character
// but use write method insted
for(size_t i=0 ; i<str.size() ; ++i)
switch( c )
{
switch(str[i])
{
case 0: out << '\\'; out << '0'; break;
case '\r': out << '\\'; out << 'r'; break;
case '\n': out << '\\'; out << 'n'; break;
@@ -970,12 +961,31 @@ void JSONescape(Stream & out, const StringType & str)
//case '/': out << '\\'; out << '/'; break; // slash doesn't have to be escaped
case '"': out << '\\'; out << '\"'; break;
default:
out << str[i];
out << c;
}
}
template<class StringType, class Stream>
void JSONescape(const StringType & str, Stream & out)
{
for(size_t i=0 ; i < str.size() ; ++i)
{
if constexpr(sizeof(char) == sizeof(typename StringType::value_type))
{
JSONescape(static_cast<wchar_t>(static_cast<unsigned char>(str[i])), out);
}
else
{
JSONescape(str[i], out);
}
}
}
void JSONescapeStream(const pt::WTextStream & in, pt::WTextStream & out);
/*
* converting from a wide string to an UTF-8 string

View File

@@ -75,7 +75,7 @@ void Request::ClearOutputStreams()
{
size_t len = 0;
out_main_stream.Clear();
out_main_stream.clear();
if( config )
len = config->ezc_out_streams_size;