Multipart. Some convenienve API for InMemoryPartReader.

This commit is contained in:
lganzzzo 2019-07-31 01:59:46 +04:00
parent 5cda94383f
commit 5fd3d1dfe2
5 changed files with 96 additions and 17 deletions

View File

@ -136,4 +136,16 @@ async::CoroutineStarter AsyncInMemoryPartReader::onPartDataAsync(const std::shar
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Other functions
std::shared_ptr<PartReader> createInMemoryPartReader(data::v_io_size maxDataSize) {
return std::make_shared<InMemoryPartReader>(maxDataSize);
}
std::shared_ptr<AsyncPartReader> createAsyncInMemoryPartReader(data::v_io_size maxDataSize) {
return std::make_shared<AsyncInMemoryPartReader>(maxDataSize);
}
}}}}

View File

@ -97,6 +97,20 @@ public:
};
/**
* Create in-memory part reader. <br>
* @param maxDataSize - max size of the received data.
* @return - `std::shared_ptr` to &id:oatpp::web::mime::multipart::PartReader;.
*/
std::shared_ptr<PartReader> createInMemoryPartReader(data::v_io_size maxDataSize = 64 * 1024);
/**
* Create in-memory part reader. <br>
* @param maxDataSize - max size of the received data.
* @return - `std::shared_ptr` to &id:oatpp::web::mime::multipart::AsyncPartReader;.
*/
std::shared_ptr<AsyncPartReader> createAsyncInMemoryPartReader(data::v_io_size maxDataSize = 64 * 1024);
}}}}
#endif // oatpp_web_mime_multipart_InMemoryPartReader_hpp

View File

@ -46,7 +46,7 @@ namespace {
void runTests() {
oatpp::base::Environment::printCompilationConfig();
/*
OATPP_RUN_TEST(oatpp::test::base::RegRuleTest);
OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);
@ -76,7 +76,7 @@ void runTests() {
OATPP_RUN_TEST(oatpp::test::web::mime::multipart::StatefulParserTest);
OATPP_RUN_TEST(oatpp::test::web::server::api::ApiControllerTest);
*/
{
oatpp::test::web::FullTest test_virtual(0, 1000);

View File

@ -185,22 +185,48 @@ public:
}
ENDPOINT("POST", "test/multipart/file/{chunk-size}", multipartFileTest,
PATH(Int32, chunkSize, "chunk-size"),
ENDPOINT("POST", "test/multipart-all", multipartFileTest,
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
/* Prepare multipart container. */
auto multipart = std::make_shared<multipart::Multipart>(request->getHeaders());
/* Create multipart reader. */
multipart::Reader multipartReader(multipart.get());
multipartReader.setPartReader("part1", multipart::createFilePartReader("/Users/leonid/Documents/test/my-text-file.tf", -1));
/* Configure to read part with name "part1" into memory */
multipartReader.setPartReader("part1", multipart::createInMemoryPartReader(256 /* max-data-size */));
/* Configure to stream part with name "part2" to file */
multipartReader.setPartReader("part2", multipart::createFilePartReader("/Users/leonid/Documents/test/my-text-file.tf"));
/* Configure to read all other parts into memory */
multipartReader.setDefaultPartReader(multipart::createInMemoryPartReader(16 * 1024 /* max-data-size */));
/* Read multipart body */
request->transferBody(&multipartReader);
auto responseBody = std::make_shared<oatpp::web::protocol::http::outgoing::MultipartBody>(multipart, chunkSize->getValue());
/* Print number of uploaded parts */
OATPP_LOGD("Multipart", "parts_count=%d", multipart->count());
return OutgoingResponse::createShared(Status::CODE_200, responseBody);
/* Print value of "part1" */
auto part1 = multipart->getNamedPart("part1");
OATPP_ASSERT_HTTP(part1, Status::CODE_400, "part1 is empty");
OATPP_LOGD("Multipart", "part1='%s'", part1->getInMemoryData()->c_str());
/* Get part by name "part2"*/
auto filePart = multipart->getNamedPart("part2");
OATPP_ASSERT_HTTP(filePart, Status::CODE_400, "part2 is empty");
auto inputStream = filePart->getInputStream();
// TODO - process file stream.
return createResponse(Status::CODE_200, "OK");
}

View File

@ -205,30 +205,57 @@ public:
};
ENDPOINT_ASYNC("POST", "test/multipart/file/{chunk-size}", MultipartFileTest) {
ENDPOINT_ASYNC("POST", "test/multipart-all", MultipartUpload) {
ENDPOINT_ASYNC_INIT(MultipartFileTest)
ENDPOINT_ASYNC_INIT(MultipartUpload)
v_int32 m_chunkSize;
/* Coroutine State */
std::shared_ptr<multipart::Multipart> m_multipart;
Action act() override {
m_chunkSize = oatpp::utils::conversion::strToInt32(request->getPathVariable("chunk-size")->c_str());
m_multipart = std::make_shared<multipart::Multipart>(request->getHeaders());
auto multipartReader = std::make_shared<multipart::AsyncReader>(m_multipart);
multipartReader->setPartReader("part1", multipart::createAsyncFilePartReader("/Users/leonid/Documents/test/my-text-file-async.tf", 16));
/* Configure to read part with name "part1" into memory */
multipartReader->setPartReader("part1", multipart::createAsyncInMemoryPartReader(256 /* max-data-size */));
return request->transferBodyAsync(multipartReader).next(yieldTo(&MultipartFileTest::respond));
/* Configure to stream part with name "part2" to file */
multipartReader->setPartReader("part2", multipart::createAsyncFilePartReader("/Users/leonid/Documents/test/my-text-file.tf"));
/* Configure to read all other parts into memory */
multipartReader->setDefaultPartReader(multipart::createAsyncInMemoryPartReader(16 * 1024 /* max-data-size */));
/* Read multipart body */
return request->transferBodyAsync(multipartReader).next(yieldTo(&MultipartUpload::onUploaded));
}
Action respond() {
Action onUploaded() {
auto responseBody = std::make_shared<oatpp::web::protocol::http::outgoing::MultipartBody>(m_multipart, m_chunkSize);
return _return(OutgoingResponse::createShared(Status::CODE_200, responseBody));
/* Print number of uploaded parts */
OATPP_LOGD("Multipart", "parts_count=%d", m_multipart->count());
/* Get multipart by name */
auto part1 = m_multipart->getNamedPart("part1");
/* Asser part not-null */
OATPP_ASSERT_HTTP(part1, Status::CODE_400, "part1 is empty");
/* Print value of "part1" */
OATPP_LOGD("Multipart", "part1='%s'", part1->getInMemoryData()->c_str());
/* Get multipart by name */
auto filePart = m_multipart->getNamedPart("part2");
/* Asser part not-null */
OATPP_ASSERT_HTTP(filePart, Status::CODE_400, "part2 is empty");
auto inputStream = filePart->getInputStream();
// TODO - process file stream.
return _return(controller->createResponse(Status::CODE_200, "OK"));
}