add a Request::raw_post buffer

This buffer is used when a Function::NeedToCopyRawPost() method returned true.

while here:
- remove WINIX_POST_PARAMS and WINIX_RAW_POST_STRING plugin messages
This commit is contained in:
Tomasz Sowa 2023-11-02 05:14:48 +01:00
parent a08bf9f804
commit 79babc916a
Signed by: tomasz.sowa
GPG Key ID: 662CC1438638588B
11 changed files with 57 additions and 71 deletions

View File

@ -1293,18 +1293,17 @@ void App::ReadInputPostToBuffer()
const int buffer_len = sizeof(buffer) / sizeof(char) - 1;
int read_len;
post_buffer.clear();
post_buffer.reserve(1024 * 1024 * 5); // IMPROVEME add to config?
cur.request->raw_post.clear();
cur.request->raw_post.reserve(1024 * 1024 * 5); // IMPROVEME add to config?
do
{
read_len = FCGX_GetStr(buffer, buffer_len, cur.request->fcgi_request.in);
if( read_len > 0 )
post_buffer.write(buffer, read_len);
cur.request->raw_post.write(buffer, read_len);
}
while( read_len == buffer_len );
}
@ -1317,7 +1316,7 @@ void App::ParsePostJson()
space_parser.set_all_items_limit( (fun && fun->post_max_all_items != 0) ? fun->post_max_all_items : config.post_max_all_items);
space_parser.set_nested_level_limit( (fun && fun->post_max_nested_objects != 0) ? fun->post_max_nested_objects : config.post_max_nested_objects);
pt::SpaceParser::Status parse_status = space_parser.parse_json(post_buffer, cur.request->post_in);
pt::SpaceParser::Status parse_status = space_parser.parse_json(cur.request->raw_post, cur.request->post_in);
if( parse_status == pt::SpaceParser::ok )
{
@ -1362,13 +1361,13 @@ void App::ParsePostJson()
}
void App::ReadPostJson()
void App::ReadPostJson(bool copy_raw_post)
{
ReadInputPostToBuffer();
if( !post_buffer.empty() )
if( !cur.request->raw_post.empty() )
{
if( config.post_json_max == 0 || post_buffer.size() <= config.post_json_max )
if( config.post_json_max == 0 || cur.request->raw_post.size() <= config.post_json_max )
{
ParsePostJson();
}
@ -1378,7 +1377,8 @@ void App::ReadPostJson()
cur.request->http_status = Header::status_400_bad_request;
}
post_buffer.clear();
if( !copy_raw_post )
cur.request->raw_post.clear();
}
else
{
@ -1392,28 +1392,30 @@ void App::ReadPostVars()
if( cur.request->method == Request::post || cur.request->method == Request::put ||
cur.request->method == Request::patch || cur.request->method == Request::delete_ )
{
bool copy_raw_post = (cur.request->function && cur.request->function->NeedToCopyRawPost());
if( pt::is_substr_nc(Header::multipart_form_data, cur.request->env_content_type.c_str()) )
{
log << log3 << "App: content type: " << Header::multipart_form_data << logend;
post_multi_parser.Parse(cur.request->fcgi_request.in, *cur.request); // IMPROVEME add checking for return status
post_multi_parser.Parse(cur.request->fcgi_request.in, *cur.request, copy_raw_post); // IMPROVEME add checking for return status
}
else
if( pt::is_substr_nc(Winix::Header::application_json, cur.request->env_content_type.c_str()) )
{
log << log3 << "App: content type: " << Winix::Header::application_json << ", using json parser" << logend;
ReadPostJson();
ReadPostJson(copy_raw_post);
}
else
if( pt::is_substr_nc(Header::application_x_www_form_urlencoded, cur.request->env_content_type.c_str()) )
{
log << log3 << "App: content type: " << Winix::Header::application_x_www_form_urlencoded << logend;
post_parser.Parse(cur.request->fcgi_request.in, *cur.request); // IMPROVEME add checking for return status
post_parser.Parse(cur.request->fcgi_request.in, *cur.request, copy_raw_post); // IMPROVEME add checking for return status
}
else
if( cur.request->env_content_type.empty() )
{
log << log2 << "App: Content-Type header is not set or is empty, I try to parse as " << Header::application_x_www_form_urlencoded << logend;
post_parser.Parse(cur.request->fcgi_request.in, *cur.request); // IMPROVEME add checking for return status
post_parser.Parse(cur.request->fcgi_request.in, *cur.request, copy_raw_post); // IMPROVEME add checking for return status
}
else
{

View File

@ -128,7 +128,6 @@ private:
PostParser post_parser;
PostMultiParser post_multi_parser;
pt::SpaceParser space_parser;
pt::TextStream post_buffer;
CookieParser cookie_parser;
AcceptBaseParser accept_base_parser;
@ -200,7 +199,7 @@ private:
bool SaveEnvHTTPVariable(const char * env);
void ReadInputPostToBuffer();
void ParsePostJson();
void ReadPostJson();
void ReadPostJson(bool copy_raw_post);
void ReadPostVars();
void CheckIE();
void CheckKonqueror();

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2022, Tomasz Sowa
/*
* Copyright (c) 2008-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -282,20 +282,6 @@ namespace Winix
// the session pointer in info is null
#define WINIX_BASE_URL_REDIRECT 31030
// raw POST parameters
// in p1 there is a pointer to std::wstring meaning a parameter's name
// in p2 there is a pointer to std::wstring value
// this is sent only from PostParser
// PostMultiParser (multipart/form-data html forms) doesn't send this messsage
// there is no a session set (session pointer is null)
// this message is sent for each name value pairs
//
#define WINIX_POST_PARAMS 31040
// this is the raw string sent in POST method
// in p1 there is a pointer to std::string object
#define WINIX_RAW_POST_STRING 31050
// this message is sent before calling MakePost() or MakeGet()
// if you return false (which is default) you can prevent the access
// to the resource

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2021, Tomasz Sowa
/*
* Copyright (c) 2008-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -558,6 +558,9 @@ void PostMultiParser::ReadChar()
in_buffer_len = FCGX_GetStr((char*)in_buffer, WINIX_POSTMULTI_INPUT_BUFFER, in);
in_buffer_ind = 0;
if( copy_raw_post && in_buffer_len > 0 )
request->raw_post.write((char *)in_buffer, in_buffer_len);
}
if( in_buffer_len == 0 )
@ -574,7 +577,7 @@ void PostMultiParser::ReadChar()
Error PostMultiParser::Parse(FCGX_Stream * in_, Request & request)
Error PostMultiParser::Parse(FCGX_Stream * in_, Request & request, bool copy_raw_post)
{
in = in_;
last = 0;
@ -584,6 +587,7 @@ Error PostMultiParser::Parse(FCGX_Stream * in_, Request & request)
in_buffer_ind = WINIX_POSTMULTI_INPUT_BUFFER;
in_buffer_len = WINIX_POSTMULTI_INPUT_BUFFER;
this->request = &request;
this->copy_raw_post = copy_raw_post;
tmp_filename_postfix = 1;
ReadChar();

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2022, Tomasz Sowa
/*
* Copyright (c) 2008-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -66,7 +66,7 @@ public:
~PostMultiParser();
void SetConfig(Config * pconfig);
Error Parse(FCGX_Stream * in_, Request & request);
Error Parse(FCGX_Stream * in_, Request & request, bool copy_raw_post);
private:
@ -80,6 +80,7 @@ private:
int tmp_filename_postfix;
size_t in_buffer_ind;
size_t in_buffer_len;
bool copy_raw_post;
Request * request;

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2022, Tomasz Sowa
/*
* Copyright (c) 2022-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,7 +36,6 @@
#include <string>
#include "postparser.h"
#include "httpsimpleparser.h"
#include "utf8/utf8.h"
#include "convert/text.h"
@ -57,22 +56,15 @@ void PostParser::LogValueSize(size_t s)
}
void PostParser::Parse(FCGX_Stream * in, Request & request)
void PostParser::Parse(FCGX_Stream * in, Request & request, bool copy_raw_post)
{
this->in = in;
this->request = &request;
this->copy_raw_post = copy_raw_post;
var_index = 1;
raw_post.clear();
has_winix_post_params_msg = plugin->HasMessage(WINIX_POST_PARAMS);
has_winix_raw_post_msg = plugin->HasMessage(WINIX_RAW_POST_STRING);
this->request->raw_post.clear();
HttpSimpleParser::Parse();
if( has_winix_raw_post_msg )
plugin->Call(WINIX_RAW_POST_STRING, &raw_post);
raw_post.clear();
}
@ -80,10 +72,10 @@ int PostParser::GetChar()
{
int c = FCGX_GetChar(in);
if( c != -1 && has_winix_raw_post_msg )
raw_post += c;
if( c != -1 && copy_raw_post )
request->raw_post << static_cast<unsigned char>(c);
return c;
return c;
}
@ -110,21 +102,13 @@ void PostParser::CreateLog(bool param_added, const std::wstring & name, const st
}
void PostParser::Parameter(std::wstring & name, std::wstring & value)
{
if( has_winix_post_params_msg )
plugin->Call(WINIX_POST_PARAMS, &name, &value);
bool added = request->AddPostVar(name, value);
CreateLog(added, name, value);
}
} // namespace Winix

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2022, Tomasz Sowa
/*
* Copyright (c) 2008-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -52,7 +52,7 @@ public:
PostParser();
void LogValueSize(size_t s);
void Parse(FCGX_Stream * in, Request & request);
void Parse(FCGX_Stream * in, Request & request, bool copy_raw_post);
protected:
@ -61,9 +61,7 @@ protected:
Request * request;
size_t log_value_size;
int var_index;
bool has_winix_post_params_msg;
bool has_winix_raw_post_msg;
std::string raw_post;
bool copy_raw_post;
virtual int GetChar();
void CreateLog(bool param_added, const std::wstring & name, const std::wstring & value);

View File

@ -264,6 +264,7 @@ void Request::Clear()
cookie_id_string.clear();
send_data_buf.clear();
http_header_name.clear();
raw_post.clear();
}

View File

@ -180,6 +180,11 @@ public:
CookieTab cookie_tab;
pt::Space post_in;
/*
* raw post input used if a Function::NeedToCopyRawPost() returned true
*/
pt::TextStream raw_post;
// input headers (without cookies)
// at the moment we are using FastCGI and HTTP headers are prefixed with 'HTTP_' string
// so we drop the prefix and change all characters to small ones

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2022, Tomasz Sowa
/*
* Copyright (c) 2010-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -524,6 +524,11 @@ void FunctionBase::ContinueMakePatch()
// do nothing by default
}
bool FunctionBase::NeedToCopyRawPost()
{
return false;
}
} // namespace Winix

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2022, Tomasz Sowa
/*
* Copyright (c) 2010-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -167,6 +167,7 @@ public:
//void SetSynchro(Synchro * psynchro);
//void SetSessionManager(SessionManager * pmanager);
virtual bool NeedToCopyRawPost();
protected: