From 52a1e890bad14a4601ad4d862c826271a9c32815 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 30 Apr 2022 16:59:18 +0200 Subject: [PATCH] Implemented simple file upload handling interface for Request. --- web/http/request.cpp | 12 ++++++ web/http/request.h | 5 +++ web_backends/drogon/request.cpp | 67 +++++++++++++++++++++++++++------ web_backends/drogon/request.h | 13 +++++-- 4 files changed, 83 insertions(+), 14 deletions(-) diff --git a/web/http/request.cpp b/web/http/request.cpp index 1c4b83c..2f3ffcf 100644 --- a/web/http/request.cpp +++ b/web/http/request.cpp @@ -95,6 +95,18 @@ HTTPMethod Request::get_method() const { return HTTP_METHOD_GET; } +void Request::parse_files() { +} +int Request::get_file_count() const { + return 0; +} +int Request::get_file_length(const int index) const { + return 0; +} +const uint8_t *Request::get_file_data(const int index) const { + return nullptr; +} + const String Request::get_parameter(const String &key) const { static String str(0); return str; diff --git a/web/http/request.h b/web/http/request.h index 120aa18..890ac51 100644 --- a/web/http/request.h +++ b/web/http/request.h @@ -60,6 +60,11 @@ public: virtual HTTPMethod get_method() const; + virtual void parse_files(); + virtual int get_file_count() const; + virtual int get_file_length(const int index) const; + virtual const uint8_t *get_file_data(const int index) const; + virtual const String get_parameter(const String &key) const; HTTPStatusCode get_status_code() const; diff --git a/web_backends/drogon/request.cpp b/web_backends/drogon/request.cpp index 31ce77d..8fd09ae 100644 --- a/web_backends/drogon/request.cpp +++ b/web_backends/drogon/request.cpp @@ -15,11 +15,49 @@ void DRequest::remove_cookie(const String &key) { } HTTPMethod DRequest::get_method() const { - //the enums are in the same order + // the enums are in the same order return static_cast(static_cast(request->getMethod())); } +void DRequest::parse_files() { + if (_multipart_parser) { + return; + } + + _multipart_parser = new drogon::MultiPartParser(); + if (_multipart_parser->parse(request) != 0) { + RLOG_ERR("asd2"); + delete _multipart_parser; + _multipart_parser = nullptr; + } +} +int DRequest::get_file_count() const { + if (!_multipart_parser) { + return 0; + } + + return _multipart_parser->getFiles().size(); +} +int DRequest::get_file_length(const int index) const { + if (!_multipart_parser) { + return 0; + } + + ERR_FAIL_INDEX_V(index, _multipart_parser->getFiles().size(), 0); + + return static_cast(_multipart_parser->getFiles()[index].fileLength()); +} +const uint8_t *DRequest::get_file_data(const int index) const { + if (!_multipart_parser) { + return nullptr; + } + + ERR_FAIL_INDEX_V(index, _multipart_parser->getFiles().size(), nullptr); + + return reinterpret_cast(_multipart_parser->getFiles()[index].fileData()); +} + const String DRequest::get_parameter(const String &key) const { return request->getParameter(key); } @@ -38,10 +76,10 @@ void DRequest::send_redirect(const String &location, const HTTPStatusCode status } void DRequest::send() { - //if (connection_closed) { + // if (connection_closed) { // DRequestPool::return_request(this); // return; - //} + // } drogon::HttpResponsePtr response = drogon::HttpResponse::newHttpResponse(); @@ -74,7 +112,12 @@ void DRequest::reset() { _added_cookies.clear(); _removed_cookies.clear(); - //response = new HttpResponse(); + if (_multipart_parser) { + delete _multipart_parser; + _multipart_parser = nullptr; + } + + // response = new HttpResponse(); } String DRequest::parser_get_path() { @@ -82,7 +125,7 @@ String DRequest::parser_get_path() { } String DRequest::get_host() const { - //todo + // todo return "/"; } @@ -106,10 +149,12 @@ void DRequest::pool() { DRequest::DRequest() : Request() { - //This value will need benchmarks, 2 MB seems to be just as fast for me as 4 MB, but 1MB is slower - //It is a tradeoff on server memory though, as every active download will consume this amount of memory - //where the file is bigger than this number - file_chunk_size = 1 << 21; //2MB + _multipart_parser = nullptr; + + // This value will need benchmarks, 2 MB seems to be just as fast for me as 4 MB, but 1MB is slower + // It is a tradeoff on server memory though, as every active download will consume this amount of memory + // where the file is bigger than this number + file_chunk_size = 1 << 21; // 2MB reset(); } @@ -175,8 +220,8 @@ void DRequest::_response_additional_setup(const drogon::HttpResponsePtr &req) { ::Cookie &co = _added_cookies[i]; drogon::Cookie c; c.setDomain(co.domain); - //todo - //c.setExpiresDate + // todo + // c.setExpiresDate c.setHttpOnly(co.http_only); c.setKey(co.key); c.setPath(co.path); diff --git a/web_backends/drogon/request.h b/web_backends/drogon/request.h index e4a5755..dc5d66d 100644 --- a/web_backends/drogon/request.h +++ b/web_backends/drogon/request.h @@ -1,8 +1,8 @@ #ifndef DREQUEST_H #define DREQUEST_H -#include "core/string.h" #include "core/containers/vector.h" +#include "core/string.h" #include "web/http/request.h" @@ -10,8 +10,9 @@ #include "http/HttpRequestImpl.h" #include "http/HttpResponse.h" +#include "http/MultiPart.h" -//using namespace drogon; +// using namespace drogon; class DrogonWebServer; @@ -26,6 +27,11 @@ public: HTTPMethod get_method() const; + void parse_files(); + int get_file_count() const; + int get_file_length(const int index) const; + const uint8_t *get_file_data(const int index) const; + const String get_parameter(const String &key) const; void send_redirect(const String &location, const HTTPStatusCode status_code = HTTP_STATUS_CODE_302_FOUND); @@ -49,8 +55,9 @@ protected: void _file_chunk_sent(); void _response_additional_setup(const drogon::HttpResponsePtr &req); - Vector<::Cookie> _added_cookies; + Vector< ::Cookie> _added_cookies; Vector _removed_cookies; + drogon::MultiPartParser *_multipart_parser; private: static RequestPool _request_pool;