Implemented simple file upload handling interface for Request.

This commit is contained in:
Relintai 2022-04-30 16:59:18 +02:00
parent 1d3dcaf806
commit 52a1e890ba
4 changed files with 83 additions and 14 deletions

View File

@ -95,6 +95,18 @@ HTTPMethod Request::get_method() const {
return HTTP_METHOD_GET; 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 { const String Request::get_parameter(const String &key) const {
static String str(0); static String str(0);
return str; return str;

View File

@ -60,6 +60,11 @@ public:
virtual HTTPMethod get_method() const; 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; virtual const String get_parameter(const String &key) const;
HTTPStatusCode get_status_code() const; HTTPStatusCode get_status_code() const;

View File

@ -15,11 +15,49 @@ void DRequest::remove_cookie(const String &key) {
} }
HTTPMethod DRequest::get_method() const { HTTPMethod DRequest::get_method() const {
//the enums are in the same order // the enums are in the same order
return static_cast<HTTPMethod>(static_cast<int>(request->getMethod())); return static_cast<HTTPMethod>(static_cast<int>(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<int>(_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<const uint8_t*>(_multipart_parser->getFiles()[index].fileData());
}
const String DRequest::get_parameter(const String &key) const { const String DRequest::get_parameter(const String &key) const {
return request->getParameter(key); return request->getParameter(key);
} }
@ -38,10 +76,10 @@ void DRequest::send_redirect(const String &location, const HTTPStatusCode status
} }
void DRequest::send() { void DRequest::send() {
//if (connection_closed) { // if (connection_closed) {
// DRequestPool::return_request(this); // DRequestPool::return_request(this);
// return; // return;
//} // }
drogon::HttpResponsePtr response = drogon::HttpResponse::newHttpResponse(); drogon::HttpResponsePtr response = drogon::HttpResponse::newHttpResponse();
@ -74,7 +112,12 @@ void DRequest::reset() {
_added_cookies.clear(); _added_cookies.clear();
_removed_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() { String DRequest::parser_get_path() {
@ -82,7 +125,7 @@ String DRequest::parser_get_path() {
} }
String DRequest::get_host() const { String DRequest::get_host() const {
//todo // todo
return "/"; return "/";
} }
@ -106,10 +149,12 @@ void DRequest::pool() {
DRequest::DRequest() : DRequest::DRequest() :
Request() { Request() {
//This value will need benchmarks, 2 MB seems to be just as fast for me as 4 MB, but 1MB is slower _multipart_parser = nullptr;
//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 // This value will need benchmarks, 2 MB seems to be just as fast for me as 4 MB, but 1MB is slower
file_chunk_size = 1 << 21; //2MB // 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(); reset();
} }
@ -175,8 +220,8 @@ void DRequest::_response_additional_setup(const drogon::HttpResponsePtr &req) {
::Cookie &co = _added_cookies[i]; ::Cookie &co = _added_cookies[i];
drogon::Cookie c; drogon::Cookie c;
c.setDomain(co.domain); c.setDomain(co.domain);
//todo // todo
//c.setExpiresDate // c.setExpiresDate
c.setHttpOnly(co.http_only); c.setHttpOnly(co.http_only);
c.setKey(co.key); c.setKey(co.key);
c.setPath(co.path); c.setPath(co.path);

View File

@ -1,8 +1,8 @@
#ifndef DREQUEST_H #ifndef DREQUEST_H
#define DREQUEST_H #define DREQUEST_H
#include "core/string.h"
#include "core/containers/vector.h" #include "core/containers/vector.h"
#include "core/string.h"
#include "web/http/request.h" #include "web/http/request.h"
@ -10,8 +10,9 @@
#include "http/HttpRequestImpl.h" #include "http/HttpRequestImpl.h"
#include "http/HttpResponse.h" #include "http/HttpResponse.h"
#include "http/MultiPart.h"
//using namespace drogon; // using namespace drogon;
class DrogonWebServer; class DrogonWebServer;
@ -26,6 +27,11 @@ public:
HTTPMethod get_method() const; 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; const String get_parameter(const String &key) const;
void send_redirect(const String &location, const HTTPStatusCode status_code = HTTP_STATUS_CODE_302_FOUND); 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 _file_chunk_sent();
void _response_additional_setup(const drogon::HttpResponsePtr &req); void _response_additional_setup(const drogon::HttpResponsePtr &req);
Vector<::Cookie> _added_cookies; Vector< ::Cookie> _added_cookies;
Vector<String> _removed_cookies; Vector<String> _removed_cookies;
drogon::MultiPartParser *_multipart_parser;
private: private:
static RequestPool<DRequest> _request_pool; static RequestPool<DRequest> _request_pool;