From b49d52e78bd361d4f6442b2b8ab0354ca171fa9a Mon Sep 17 00:00:00 2001 From: The-EDev Date: Sun, 18 Oct 2020 01:34:58 +0300 Subject: [PATCH 1/7] Added basic multipart data structure Including methods to generate multipart message from request --- include/crow.h | 2 + include/crow/multipart.h | 195 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 include/crow/multipart.h diff --git a/include/crow.h b/include/crow.h index 9a0c22e11..98df4b64f 100644 --- a/include/crow.h +++ b/include/crow.h @@ -11,10 +11,12 @@ #include "crow/dumb_timer_queue.h" #include "crow/utility.h" #include "crow/common.h" +#include "crow/mime_types.h" #include "crow/http_request.h" #include "crow/websocket.h" #include "crow/parser.h" #include "crow/http_response.h" +#include "crow/multipart.h" #include "crow/middleware.h" #include "crow/routing.h" #include "crow/middleware_context.h" diff --git a/include/crow/multipart.h b/include/crow/multipart.h new file mode 100644 index 000000000..3cc4a586b --- /dev/null +++ b/include/crow/multipart.h @@ -0,0 +1,195 @@ +#pragma once +#include +#include +#include +#include "crow/http_request.h" +#include "crow/http_response.h" + +namespace crow +{ + ///Encapsulates anything related to processing and organizing `multipart/xyz` messages + namespace multipart + { + const std::string dd = "--"; + const std::string crlf = "\r\n"; + + ///The first part in a section, contains metadata about the part + struct header + { + std::pair value; ///< The first part of the header, usually `Content-Type` or `Content-Disposition` + std::unordered_map params; ///< The parameters of the header, come after the `value` + }; + + ///One part of the multipart message + + ///It is usually separated from other sections by a `boundary` + /// + struct part + { + std::vector
headers; ///< (optional) The first part before the data, Contains information regarding the type of data and encoding + std::string body; ///< The actual data in the part + }; + + ///The parsed multipart request/response + struct message + { + ci_map headers; + std::string boundary; ///< The text boundary that separates different `parts` + std::vector parts; ///< The individual parts of the message + + const std::string& get_header_value(const std::string& key) const + { + return crow::get_header_value(headers, key); + } + + ///Represent all parts as a string (**does not include message headers**) + const std::string dump() + { + std::stringstream str; + std::string delimiter = "--" + boundary; + + for (uint8_t i=0 ; i(header.substr(0, header_split), header.substr(header_split+2)); + } + + //add the parameters + while (line != "") + { + size_t found = line.find("; "); + std::string param = line.substr(0, found); + if (found != std::string::npos) + line.erase(0, found+2); + else + line = std::string(); + + size_t param_split = param.find('='); + + std::string value = param.substr(param_split+1); + + to_add.params.emplace(param.substr(0, param_split), trim(value)); + } + part.headers.emplace_back(to_add); + } + } + + inline std::string trim (std::string& string, char excess = '"') + { + if (string.length() > 1 && string[0] == excess && string[string.length()-1] == excess) + return string.substr(1, string.length()-2); + return string; + } + + inline std::string pad (std::string& string, char padding = '"') + { + return (padding + string + padding); + } + + }; + } +} From d20bc7051a860463371a42a0f4cbada67b171952 Mon Sep 17 00:00:00 2001 From: The-EDev Date: Sun, 18 Oct 2020 01:56:07 +0300 Subject: [PATCH 2/7] removed include for mime type header --- include/crow.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/crow.h b/include/crow.h index 98df4b64f..b57bb6632 100644 --- a/include/crow.h +++ b/include/crow.h @@ -11,7 +11,6 @@ #include "crow/dumb_timer_queue.h" #include "crow/utility.h" #include "crow/common.h" -#include "crow/mime_types.h" #include "crow/http_request.h" #include "crow/websocket.h" #include "crow/parser.h" From e06942dfc420d315e2230e532de78e38c7e35492 Mon Sep 17 00:00:00 2001 From: The-EDev Date: Sun, 18 Oct 2020 02:36:39 +0300 Subject: [PATCH 3/7] added test funny enough, the test pointed out a mistake i made in the code XD --- include/crow/multipart.h | 10 +++++----- tests/unittest.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/include/crow/multipart.h b/include/crow/multipart.h index 3cc4a586b..eb79e1f4b 100644 --- a/include/crow/multipart.h +++ b/include/crow/multipart.h @@ -50,10 +50,10 @@ namespace crow for (uint8_t i=0 ; i 1 && string[0] == excess && string[string.length()-1] == excess) return string.substr(1, string.length()-2); return string; } - inline std::string pad (std::string& string, char padding = '"') + inline std::string pad (std::string& string, const char& padding = '"') { return (padding + string + padding); } From 6a760ca09f65ecaafa54b0c362a1d5301f702ccd Mon Sep 17 00:00:00 2001 From: The-EDev Date: Sun, 18 Oct 2020 03:20:19 +0300 Subject: [PATCH 5/7] added simple example --- examples/example.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/example.cpp b/examples/example.cpp index 1355b03ec..58bbb12d6 100644 --- a/examples/example.cpp +++ b/examples/example.cpp @@ -163,6 +163,13 @@ int main() return std::string(512*1024, ' '); }); + // Take a multipart/form-data request and print out its body + CROW_ROUTE(app,"/multipart") + ([](const crow::request& req){ + crow::multipart::message msg(req); + CROW_LOG_INFO << "body of the first part " << msg.parts[0]; + }); + // enables all log app.loglevel(crow::LogLevel::DEBUG); //crow::logger::setHandler(std::make_shared()); From 8da6919617eb37d9cd379a269c54d52be1d803b7 Mon Sep 17 00:00:00 2001 From: The-EDev Date: Sun, 18 Oct 2020 03:38:50 +0300 Subject: [PATCH 6/7] fixed issue in example --- examples/example.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/example.cpp b/examples/example.cpp index 58bbb12d6..a2739a827 100644 --- a/examples/example.cpp +++ b/examples/example.cpp @@ -167,7 +167,8 @@ int main() CROW_ROUTE(app,"/multipart") ([](const crow::request& req){ crow::multipart::message msg(req); - CROW_LOG_INFO << "body of the first part " << msg.parts[0]; + CROW_LOG_INFO << "body of the first part " << msg.parts[0].body; + return "it works!"; }); // enables all log From 7fa73907f82b26ae337d85fff168a3e69d68909b Mon Sep 17 00:00:00 2001 From: Farook Al-Sammarraie Date: Tue, 20 Oct 2020 10:21:29 +0300 Subject: [PATCH 7/7] removed main function --- tests/unittest.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/unittest.cpp b/tests/unittest.cpp index 07475518a..022398b1e 100644 --- a/tests/unittest.cpp +++ b/tests/unittest.cpp @@ -1277,8 +1277,3 @@ TEST_CASE("multipart") REQUIRE(test_string == res.body); } } - -int main() -{ - return testmain(); -}