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; const int buffer_len = sizeof(buffer) / sizeof(char) - 1;
int read_len; int read_len;
post_buffer.clear(); cur.request->raw_post.clear();
post_buffer.reserve(1024 * 1024 * 5); // IMPROVEME add to config? cur.request->raw_post.reserve(1024 * 1024 * 5); // IMPROVEME add to config?
do do
{ {
read_len = FCGX_GetStr(buffer, buffer_len, cur.request->fcgi_request.in); read_len = FCGX_GetStr(buffer, buffer_len, cur.request->fcgi_request.in);
if( read_len > 0 ) if( read_len > 0 )
post_buffer.write(buffer, read_len); cur.request->raw_post.write(buffer, read_len);
} }
while( read_len == buffer_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_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); 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 ) if( parse_status == pt::SpaceParser::ok )
{ {
@ -1362,13 +1361,13 @@ void App::ParsePostJson()
} }
void App::ReadPostJson() void App::ReadPostJson(bool copy_raw_post)
{ {
ReadInputPostToBuffer(); 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(); ParsePostJson();
} }
@ -1378,7 +1377,8 @@ void App::ReadPostJson()
cur.request->http_status = Header::status_400_bad_request; cur.request->http_status = Header::status_400_bad_request;
} }
post_buffer.clear(); if( !copy_raw_post )
cur.request->raw_post.clear();
} }
else else
{ {
@ -1392,28 +1392,30 @@ void App::ReadPostVars()
if( cur.request->method == Request::post || cur.request->method == Request::put || if( cur.request->method == Request::post || cur.request->method == Request::put ||
cur.request->method == Request::patch || cur.request->method == Request::delete_ ) 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()) ) 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; 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 else
if( pt::is_substr_nc(Winix::Header::application_json, cur.request->env_content_type.c_str()) ) 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; log << log3 << "App: content type: " << Winix::Header::application_json << ", using json parser" << logend;
ReadPostJson(); ReadPostJson(copy_raw_post);
} }
else else
if( pt::is_substr_nc(Header::application_x_www_form_urlencoded, cur.request->env_content_type.c_str()) ) 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; 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 else
if( cur.request->env_content_type.empty() ) 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; 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 else
{ {

View File

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

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org> * Author: Tomasz Sowa <t.sowa@ttmath.org>
*/ */
/* /*
* Copyright (c) 2008-2022, Tomasz Sowa * Copyright (c) 2008-2023, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -282,20 +282,6 @@ namespace Winix
// the session pointer in info is null // the session pointer in info is null
#define WINIX_BASE_URL_REDIRECT 31030 #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() // this message is sent before calling MakePost() or MakeGet()
// if you return false (which is default) you can prevent the access // if you return false (which is default) you can prevent the access
// to the resource // to the resource

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org> * Author: Tomasz Sowa <t.sowa@ttmath.org>
*/ */
/* /*
* Copyright (c) 2008-2021, Tomasz Sowa * Copyright (c) 2008-2023, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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_len = FCGX_GetStr((char*)in_buffer, WINIX_POSTMULTI_INPUT_BUFFER, in);
in_buffer_ind = 0; 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 ) 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_; in = in_;
last = 0; last = 0;
@ -584,6 +587,7 @@ Error PostMultiParser::Parse(FCGX_Stream * in_, Request & request)
in_buffer_ind = WINIX_POSTMULTI_INPUT_BUFFER; in_buffer_ind = WINIX_POSTMULTI_INPUT_BUFFER;
in_buffer_len = WINIX_POSTMULTI_INPUT_BUFFER; in_buffer_len = WINIX_POSTMULTI_INPUT_BUFFER;
this->request = &request; this->request = &request;
this->copy_raw_post = copy_raw_post;
tmp_filename_postfix = 1; tmp_filename_postfix = 1;
ReadChar(); ReadChar();

View File

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

View File

@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org> * Author: Tomasz Sowa <t.sowa@ttmath.org>
*/ */
/* /*
* Copyright (c) 2022, Tomasz Sowa * Copyright (c) 2022-2023, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,7 +36,6 @@
#include <string> #include <string>
#include "postparser.h" #include "postparser.h"
#include "httpsimpleparser.h" #include "httpsimpleparser.h"
#include "utf8/utf8.h"
#include "convert/text.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->in = in;
this->request = &request; this->request = &request;
this->copy_raw_post = copy_raw_post;
var_index = 1; var_index = 1;
raw_post.clear(); this->request->raw_post.clear();
has_winix_post_params_msg = plugin->HasMessage(WINIX_POST_PARAMS);
has_winix_raw_post_msg = plugin->HasMessage(WINIX_RAW_POST_STRING);
HttpSimpleParser::Parse(); 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); int c = FCGX_GetChar(in);
if( c != -1 && has_winix_raw_post_msg ) if( c != -1 && copy_raw_post )
raw_post += c; 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) 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); bool added = request->AddPostVar(name, value);
CreateLog(added, name, value); CreateLog(added, name, value);
} }
} // namespace Winix } // namespace Winix

View File

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

View File

@ -180,6 +180,11 @@ public:
CookieTab cookie_tab; CookieTab cookie_tab;
pt::Space post_in; pt::Space post_in;
/*
* raw post input used if a Function::NeedToCopyRawPost() returned true
*/
pt::TextStream raw_post;
// input headers (without cookies) // input headers (without cookies)
// at the moment we are using FastCGI and HTTP headers are prefixed with 'HTTP_' string // 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 // 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> * Author: Tomasz Sowa <t.sowa@ttmath.org>
*/ */
/* /*
* Copyright (c) 2010-2022, Tomasz Sowa * Copyright (c) 2010-2023, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -524,6 +524,11 @@ void FunctionBase::ContinueMakePatch()
// do nothing by default // do nothing by default
} }
bool FunctionBase::NeedToCopyRawPost()
{
return false;
}
} // namespace Winix } // namespace Winix

View File

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