diff --git a/winixd/core/app.cpp b/winixd/core/app.cpp index 0f53069..7cf7a7c 100644 --- a/winixd/core/app.cpp +++ b/winixd/core/app.cpp @@ -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 { diff --git a/winixd/core/app.h b/winixd/core/app.h index 08bc51e..47e6889 100644 --- a/winixd/core/app.h +++ b/winixd/core/app.h @@ -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(); diff --git a/winixd/core/pluginmsg.h b/winixd/core/pluginmsg.h index 12697bf..04359fd 100644 --- a/winixd/core/pluginmsg.h +++ b/winixd/core/pluginmsg.h @@ -4,8 +4,8 @@ * Author: Tomasz Sowa */ -/* - * 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 diff --git a/winixd/core/postmultiparser.cpp b/winixd/core/postmultiparser.cpp index 3bab06b..20466fa 100644 --- a/winixd/core/postmultiparser.cpp +++ b/winixd/core/postmultiparser.cpp @@ -4,8 +4,8 @@ * Author: Tomasz Sowa */ -/* - * 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(); diff --git a/winixd/core/postmultiparser.h b/winixd/core/postmultiparser.h index da8d584..302ebca 100644 --- a/winixd/core/postmultiparser.h +++ b/winixd/core/postmultiparser.h @@ -4,8 +4,8 @@ * Author: Tomasz Sowa */ -/* - * 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; diff --git a/winixd/core/postparser.cpp b/winixd/core/postparser.cpp index ab2a5ea..d8bc910 100644 --- a/winixd/core/postparser.cpp +++ b/winixd/core/postparser.cpp @@ -4,8 +4,8 @@ * Author: Tomasz Sowa */ -/* - * 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 #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(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 diff --git a/winixd/core/postparser.h b/winixd/core/postparser.h index 92445c0..ed996a5 100644 --- a/winixd/core/postparser.h +++ b/winixd/core/postparser.h @@ -4,8 +4,8 @@ * Author: Tomasz Sowa */ -/* - * 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); diff --git a/winixd/core/request.cpp b/winixd/core/request.cpp index c368d9b..43baf7e 100644 --- a/winixd/core/request.cpp +++ b/winixd/core/request.cpp @@ -264,6 +264,7 @@ void Request::Clear() cookie_id_string.clear(); send_data_buf.clear(); http_header_name.clear(); + raw_post.clear(); } diff --git a/winixd/core/request.h b/winixd/core/request.h index 08d8a99..40e1b39 100644 --- a/winixd/core/request.h +++ b/winixd/core/request.h @@ -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 diff --git a/winixd/functions/functionbase.cpp b/winixd/functions/functionbase.cpp index 6294467..7ca1c87 100644 --- a/winixd/functions/functionbase.cpp +++ b/winixd/functions/functionbase.cpp @@ -4,8 +4,8 @@ * Author: Tomasz Sowa */ -/* - * 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 diff --git a/winixd/functions/functionbase.h b/winixd/functions/functionbase.h index 7750b8a..2998c3e 100644 --- a/winixd/functions/functionbase.h +++ b/winixd/functions/functionbase.h @@ -4,8 +4,8 @@ * Author: Tomasz Sowa */ -/* - * 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: