multipart: better API.

This commit is contained in:
lganzzzo 2021-10-28 12:58:52 +03:00
parent 9a44c1f463
commit 6455e14399
19 changed files with 376 additions and 427 deletions

View File

@ -216,22 +216,24 @@ add_library(oatpp
oatpp/web/client/RequestExecutor.hpp
oatpp/web/client/RetryPolicy.cpp
oatpp/web/client/RetryPolicy.hpp
oatpp/web/mime/multipart/FileResourceProvider.cpp
oatpp/web/mime/multipart/FileResourceProvider.hpp
oatpp/web/mime/multipart/InMemoryPartReader.cpp
oatpp/web/mime/multipart/InMemoryPartReader.hpp
oatpp/web/mime/multipart/FileProvider.cpp
oatpp/web/mime/multipart/FileProvider.hpp
oatpp/web/mime/multipart/InMemoryDataProvider.cpp
oatpp/web/mime/multipart/InMemoryDataProvider.hpp
oatpp/web/mime/multipart/Multipart.cpp
oatpp/web/mime/multipart/Multipart.hpp
oatpp/web/mime/multipart/Part.cpp
oatpp/web/mime/multipart/Part.hpp
oatpp/web/mime/multipart/PartList.cpp
oatpp/web/mime/multipart/PartList.hpp
oatpp/web/mime/multipart/PartReader.cpp
oatpp/web/mime/multipart/PartReader.hpp
oatpp/web/mime/multipart/Reader.cpp
oatpp/web/mime/multipart/Reader.hpp
oatpp/web/mime/multipart/StatefulParser.cpp
oatpp/web/mime/multipart/StatefulParser.hpp
oatpp/web/mime/multipart/StreamPartReader.cpp
oatpp/web/mime/multipart/StreamPartReader.hpp
oatpp/web/mime/multipart/TemporaryFileProvider.cpp
oatpp/web/mime/multipart/TemporaryFileProvider.hpp
oatpp/web/protocol/CommunicationError.cpp
oatpp/web/protocol/CommunicationError.hpp
oatpp/web/protocol/http/Http.cpp

View File

@ -27,11 +27,7 @@
namespace oatpp { namespace data { namespace resource {
InMemoryData::OutputDataHandle::~OutputDataHandle() {
if(data != nullptr) {
dataHandle->data = data + stream->toString();
} else {
dataHandle->data = stream->toString();
}
dataHandle->data = data + stream->toString();
}
InMemoryData::InMemoryData(const oatpp::String& data)
@ -41,7 +37,10 @@ InMemoryData::InMemoryData(const oatpp::String& data)
std::shared_ptr<data::stream::OutputStream> InMemoryData::openOutputStream() {
auto outputDataHandle = std::make_shared<OutputDataHandle>();
if(!m_handle) {
m_handle = std::make_shared<DataHandle>(nullptr);
m_handle = std::make_shared<DataHandle>("");
}
if(!m_handle->data){
m_handle->data = "";
}
outputDataHandle->dataHandle = m_handle;
outputDataHandle->data = m_handle->data;
@ -52,6 +51,12 @@ std::shared_ptr<data::stream::OutputStream> InMemoryData::openOutputStream() {
}
std::shared_ptr<data::stream::InputStream> InMemoryData::openInputStream() {
if(!m_handle) {
m_handle = std::make_shared<DataHandle>("");
}
if(!m_handle->data){
m_handle->data = "";
}
return std::make_shared<data::stream::BufferInputStream>(m_handle->data, m_handle);
}

View File

@ -22,27 +22,23 @@
*
***************************************************************************/
#include "FileResourceProvider.hpp"
#include "FileProvider.hpp"
#include "oatpp/core/data/resource/File.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
FileResourceProvider::FileResourceProvider(const oatpp::String& filename)
FileProvider::FileProvider(const oatpp::String& filename)
: m_filename(filename)
{}
std::shared_ptr<data::resource::Resource> FileResourceProvider::getResource(const std::shared_ptr<Part>& part) {
std::shared_ptr<data::resource::Resource> FileProvider::getResource(const std::shared_ptr<Part>& part) {
(void)part;
return std::make_shared<data::resource::File>(m_filename->c_str());
}
AsyncFileResourceProvider::AsyncFileResourceProvider(const oatpp::String& filename)
: m_filename(filename)
{}
async::CoroutineStarter AsyncFileResourceProvider::getResourceAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::resource::Resource>& stream)
async::CoroutineStarter FileProvider::getResourceAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::resource::Resource>& stream)
{
(void)part;
stream = std::make_shared<data::resource::File>(m_filename->c_str());
@ -53,13 +49,13 @@ async::CoroutineStarter AsyncFileResourceProvider::getResourceAsync(const std::s
// Other functions
std::shared_ptr<PartReader> createFilePartReader(const oatpp::String& filename, v_io_size maxDataSize) {
auto provider = std::make_shared<FileResourceProvider>(filename);
auto provider = std::make_shared<FileProvider>(filename);
auto reader = std::make_shared<StreamPartReader>(provider, maxDataSize);
return reader;
}
std::shared_ptr<AsyncPartReader> createAsyncFilePartReader(const oatpp::String& filename, v_io_size maxDataSize) {
auto provider = std::make_shared<AsyncFileResourceProvider>(filename);
auto provider = std::make_shared<FileProvider>(filename);
auto reader = std::make_shared<AsyncStreamPartReader>(provider, maxDataSize);
return reader;
}

View File

@ -22,57 +22,23 @@
*
***************************************************************************/
#ifndef oatpp_web_mime_multipart_FileStreamProvider_hpp
#define oatpp_web_mime_multipart_FileStreamProvider_hpp
#ifndef oatpp_web_mime_multipart_FileProvider_hpp
#define oatpp_web_mime_multipart_FileProvider_hpp
#include "StreamPartReader.hpp"
#include "PartReader.hpp"
#include "Reader.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
/**
* Stream provider for `StreamPartReader`.
*/
class FileResourceProvider : public PartReaderResourceProvider {
class FileProvider : public PartReaderResourceProvider {
private:
oatpp::String m_filename;
public:
/**
* Constructor.
* @param filename
*/
FileResourceProvider(const oatpp::String& filename);
FileProvider(const oatpp::String& filename);
/**
* Get resource to write (save) part data in.
* @param part
* @return
*/
std::shared_ptr<data::resource::Resource> getResource(const std::shared_ptr<Part>& part) override;
};
/**
* Async stream provider for `AsyncStreamPartReader`.
*/
class AsyncFileResourceProvider : public AsyncPartReaderResourceProvider {
private:
oatpp::String m_filename;
public:
/**
* Constructor.
* @param filename
*/
AsyncFileResourceProvider(const oatpp::String& filename);
/**
* Get stream to write (save) part data to.
* @param part
* @param resource - put here pointer to obtained resource.
* @return
*/
async::CoroutineStarter getResourceAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::resource::Resource>& resource) override;
@ -98,4 +64,4 @@ std::shared_ptr<AsyncPartReader> createAsyncFilePartReader(const oatpp::String&
}}}}
#endif // oatpp_web_mime_multipart_FileStreamProvider_hpp
#endif //oatpp_web_mime_multipart_FileProvider_hpp

View File

@ -0,0 +1,59 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "InMemoryDataProvider.hpp"
#include "oatpp/core/data/resource/InMemoryData.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
std::shared_ptr<data::resource::Resource> InMemoryDataProvider::getResource(const std::shared_ptr<Part>& part) {
(void)part;
return std::make_shared<data::resource::InMemoryData>();
}
async::CoroutineStarter InMemoryDataProvider::getResourceAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::resource::Resource>& resource)
{
(void)part;
resource = std::make_shared<data::resource::InMemoryData>();
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Other functions
std::shared_ptr<PartReader> createInMemoryPartReader(v_io_size maxDataSize) {
auto provider = std::make_shared<InMemoryDataProvider>();
auto reader = std::make_shared<StreamPartReader>(provider, maxDataSize);
return reader;
}
std::shared_ptr<AsyncPartReader> createAsyncInMemoryPartReader(v_io_size maxDataSize) {
auto provider = std::make_shared<InMemoryDataProvider>();
auto reader = std::make_shared<AsyncStreamPartReader>(provider, maxDataSize);
return reader;
}
}}}}

View File

@ -0,0 +1,59 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_web_mime_multipart_InMemoryDataProvider_hpp
#define oatpp_web_mime_multipart_InMemoryDataProvider_hpp
#include "PartReader.hpp"
#include "Reader.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
class InMemoryDataProvider : public PartReaderResourceProvider {
public:
std::shared_ptr<data::resource::Resource> getResource(const std::shared_ptr<Part>& part) override;
async::CoroutineStarter getResourceAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::resource::Resource>& resource) override;
};
/**
* Create in-memory part reader.
* @param maxDataSize - max-allowed size of the data. Use `-1` for infinity.
* @return
*/
std::shared_ptr<PartReader> createInMemoryPartReader(v_io_size maxDataSize);
/**
* Create Async in-memory part reader.
* @param maxDataSize - max-allowed size of the data. Use `-1` for infinity.
* @return
*/
std::shared_ptr<AsyncPartReader> createAsyncInMemoryPartReader(v_io_size maxDataSize);
}}}}
#endif //oatpp_web_mime_multipart_InMemoryDataProvider_hpp

View File

@ -1,150 +0,0 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "InMemoryPartReader.hpp"
#include "oatpp/core/data/resource/InMemoryData.hpp"
#include "oatpp/core/data/stream/BufferStream.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
const char* const InMemoryPartReader::TAG_NAME = "[oatpp::web::mime::multipart::InMemoryPartReader::TAG]";
InMemoryPartReader::InMemoryPartReader(v_io_size maxDataSize)
: m_maxDataSize(maxDataSize)
{}
void InMemoryPartReader::onNewPart(const std::shared_ptr<Part>& part) {
auto tag = part->getTagObject();
if(tag) {
throw std::runtime_error("[oatpp::web::mime::multipart::InMemoryPartReader::onNewPart()]: Error. "
"Part tag object is not nullptr. Seems like this part is already being processed by another reader.");
}
auto buffer = oatpp::data::stream::ChunkedBuffer::createShared();
part->setTag(TAG_NAME, buffer);
}
void InMemoryPartReader::onPartData(const std::shared_ptr<Part>& part, const char* data, oatpp::v_io_size size) {
auto tag = part->getTagObject();
if(!tag) {
throw std::runtime_error("[oatpp::web::mime::multipart::InMemoryPartReader::onPartData()]: Error. "
"Part tag object is nullptr.");
}
if(part->getTagName() != TAG_NAME) {
throw std::runtime_error("[oatpp::web::mime::multipart::InMemoryPartReader::onPartData()]: Error. "
"Wrong tag name. Seems like this part is already being processed by another part reader.");
}
auto buffer = std::static_pointer_cast<oatpp::data::stream::ChunkedBuffer>(tag);
if(size > 0) {
if(buffer->getSize() + size > m_maxDataSize) {
OATPP_LOGE("[oatpp::web::mime::multipart::InMemoryPartReader::onPartData()]", "Error. Part size exceeds specified maxDataSize=%d", m_maxDataSize);
throw std::runtime_error("[oatpp::web::mime::multipart::InMemoryPartReader::onPartData()]: Error. Part size exceeds specified maxDataSize");
}
buffer->writeSimple(data, size);
} else {
auto fullData = buffer->toString();
buffer->clear();
part->clearTag();
part->setPayload(std::make_shared<data::resource::InMemoryData>(fullData));
}
}
const char* const AsyncInMemoryPartReader::TAG_NAME = "[oatpp::web::mime::multipart::AsyncInMemoryPartReader::TAG]";
AsyncInMemoryPartReader::AsyncInMemoryPartReader(v_io_size maxDataSize)
: m_maxDataSize(maxDataSize)
{}
async::CoroutineStarter AsyncInMemoryPartReader::onNewPartAsync(const std::shared_ptr<Part>& part) {
auto tag = part->getTagObject();
if(tag) {
throw std::runtime_error("[oatpp::web::mime::multipart::AsyncInMemoryPartReader::onNewPartAsync()]: Error. "
"Part tag object is not nullptr. Seems like this part is already being processed by another part reader.");
}
auto buffer = oatpp::data::stream::ChunkedBuffer::createShared();
part->setTag(TAG_NAME, buffer);
return nullptr;
}
async::CoroutineStarter AsyncInMemoryPartReader::onPartDataAsync(const std::shared_ptr<Part>& part, const char* data, oatpp::v_io_size size) {
auto tag = part->getTagObject();
if(!tag) {
throw std::runtime_error("[oatpp::web::mime::multipart::AsyncInMemoryPartReader::onPartDataAsync()]: Error. "
"Part tag object is nullptr.");
}
if(part->getTagName() != TAG_NAME) {
throw std::runtime_error("[oatpp::web::mime::multipart::AsyncInMemoryPartReader::onNewPartAsync()]: Error. "
"Wrong tag name. Seems like this part is already being processed by another part reader.");
}
auto buffer = std::static_pointer_cast<oatpp::data::stream::ChunkedBuffer>(tag);
if(size > 0) {
if(buffer->getSize() + size > m_maxDataSize) {
OATPP_LOGE("[oatpp::web::mime::multipart::AsyncInMemoryPartReader::onPartDataAsync()]", "Error. Part size exceeds specified maxDataSize=%d", m_maxDataSize);
throw std::runtime_error("[oatpp::web::mime::multipart::AsyncInMemoryPartReader::onPartDataAsync()]: Error. Part size exceeds specified maxDataSize");
}
buffer->writeSimple(data, size);
} else {
auto fullData = buffer->toString();
buffer->clear();
part->clearTag();
part->setPayload(std::make_shared<data::resource::InMemoryData>(fullData));
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Other functions
std::shared_ptr<PartReader> createInMemoryPartReader(v_io_size maxDataSize) {
return std::make_shared<InMemoryPartReader>(maxDataSize);
}
std::shared_ptr<AsyncPartReader> createAsyncInMemoryPartReader(v_io_size maxDataSize) {
return std::make_shared<AsyncInMemoryPartReader>(maxDataSize);
}
}}}}

View File

@ -1,116 +0,0 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_web_mime_multipart_InMemoryPartReader_hpp
#define oatpp_web_mime_multipart_InMemoryPartReader_hpp
#include "Reader.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
/**
* In memory part reader.
*/
class InMemoryPartReader : public PartReader {
private:
static const char* const TAG_NAME;
private:
oatpp::v_io_size m_maxDataSize;
public:
/**
* Constructor.
* @param maxDataSize
*/
InMemoryPartReader(v_io_size maxDataSize = 64 * 1024);
/**
* Called when new part headers are parsed and part object is created.
* @param part
*/
void onNewPart(const std::shared_ptr<Part>& part) override;
/**
* Called on each new chunk of data is parsed for the multipart-part. <br>
* When all data is read, called again with `data == nullptr && size == 0` to indicate end of the part.
* @param part
* @param data - pointer to buffer containing chunk data.
* @param size - size of the buffer.
*/
void onPartData(const std::shared_ptr<Part>& part, const char* data, oatpp::v_io_size size) override;
};
/**
* Async in memory part reader.
*/
class AsyncInMemoryPartReader : public AsyncPartReader {
private:
static const char* const TAG_NAME;
private:
oatpp::v_io_size m_maxDataSize;
public:
/**
* Constructor.
* @param maxDataSize
*/
AsyncInMemoryPartReader(v_io_size maxDataSize = 64 * 1024);
/**
* Called when new part headers are parsed and part object is created.
* @param part
* @return - &id:oatpp::async::CoroutineStarter;.
*/
async::CoroutineStarter onNewPartAsync(const std::shared_ptr<Part>& part) override;
/**
* Called on each new chunk of data is parsed for the multipart-part. <br>
* When all data is read, called again with `data == nullptr && size == 0` to indicate end of the part.
* @param part
* @param data - pointer to buffer containing chunk data.
* @param size - size of the buffer.
* @return - &id:oatpp::async::CoroutineStarter;.
*/
async::CoroutineStarter onPartDataAsync(const std::shared_ptr<Part>& part, const char* data, oatpp::v_io_size size) override;
};
/**
* 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(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(v_io_size maxDataSize = 64 * 1024);
}}}}
#endif // oatpp_web_mime_multipart_InMemoryPartReader_hpp

View File

@ -22,7 +22,7 @@
*
***************************************************************************/
#include "StreamPartReader.hpp"
#include "PartReader.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
@ -92,7 +92,7 @@ void StreamPartReader::onPartData(const std::shared_ptr<Part>& part, const char*
const char* const AsyncStreamPartReader::TAG_NAME = "[oatpp::web::mime::multipart::AsyncStreamPartReader::TAG]";
AsyncStreamPartReader::AsyncStreamPartReader(const std::shared_ptr<AsyncPartReaderResourceProvider>& resourceProvider,
AsyncStreamPartReader::AsyncStreamPartReader(const std::shared_ptr<PartReaderResourceProvider>& resourceProvider,
v_io_size maxDataSize)
: m_resourceProvider(resourceProvider)
, m_maxDataSize(maxDataSize)
@ -103,12 +103,12 @@ async::CoroutineStarter AsyncStreamPartReader::onNewPartAsync(const std::shared_
class OnNewPartCoroutine : public async::Coroutine<OnNewPartCoroutine> {
private:
std::shared_ptr<Part> m_part;
std::shared_ptr<AsyncPartReaderResourceProvider> m_resourceProvider;
std::shared_ptr<PartReaderResourceProvider> m_resourceProvider;
std::shared_ptr<data::resource::Resource> m_obtainedResource;
public:
OnNewPartCoroutine(const std::shared_ptr<Part>& part,
const std::shared_ptr<AsyncPartReaderResourceProvider>& resourceProvider)
const std::shared_ptr<PartReaderResourceProvider>& resourceProvider)
: m_part(part)
, m_resourceProvider(resourceProvider)
{}
@ -169,6 +169,7 @@ async::CoroutineStarter AsyncStreamPartReader::onPartDataAsync(const std::shared
return tagObject->outputStream->writeExactSizeDataAsync(data, size);
} else {
part->setPayload(tagObject->resource);
part->clearTag();
return nullptr;
}

View File

@ -22,15 +22,72 @@
*
***************************************************************************/
#ifndef oatpp_web_mime_multipart_StreamPartReader_hpp
#define oatpp_web_mime_multipart_StreamPartReader_hpp
#include "Reader.hpp"
#ifndef oatpp_web_mime_multipart_PartReader_hpp
#define oatpp_web_mime_multipart_PartReader_hpp
#include "./Multipart.hpp"
#include "oatpp/core/data/stream/Stream.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
/**
* Abstract read handler of multipart parts.
*/
class PartReader {
public:
/**
* Default virtual destructor.
*/
virtual ~PartReader() = default;
/**
* Called when new part headers are parsed and part object is created.
* @param part
*/
virtual void onNewPart(const std::shared_ptr<Part>& part) = 0;
/**
* Called on each new chunk of data is parsed for the multipart-part. <br>
* When all data is read, called again with `data == nullptr && size == 0` to indicate end of the part.
* @param part
* @param data - pointer to buffer containing chunk data.
* @param size - size of the buffer.
*/
virtual void onPartData(const std::shared_ptr<Part>& part, const char* data, oatpp::v_io_size size) = 0;
};
/**
* Abstract Async read handler of multipart parts.
*/
class AsyncPartReader {
public:
/**
* Default virtual destructor.
*/
virtual ~AsyncPartReader() = default;
/**
* Called when new part headers are parsed and part object is created.
* @param part
* @return - &id:oatpp::async::CoroutineStarter;.
*/
virtual async::CoroutineStarter onNewPartAsync(const std::shared_ptr<Part>& part) = 0;
/**
* Called on each new chunk of data is parsed for the multipart-part. <br>
* When all data is read, called again with `data == nullptr && size == 0` to indicate end of the part.
* @param part
* @param data - pointer to buffer containing chunk data.
* @param size - size of the buffer.
* @return - &id:oatpp::async::CoroutineStarter;.
*/
virtual async::CoroutineStarter onPartDataAsync(const std::shared_ptr<Part>& part, const char* data, oatpp::v_io_size size) = 0;
};
/**
* Resource provider for `StreamPartReader`.
*/
@ -49,19 +106,6 @@ public:
*/
virtual std::shared_ptr<data::resource::Resource> getResource(const std::shared_ptr<Part>& part) = 0;
};
/**
* Async resource provider for `AsyncStreamPartReader`.
*/
class AsyncPartReaderResourceProvider {
public:
/**
* Default virtual destructor.
*/
virtual ~AsyncPartReaderResourceProvider() = default;
/**
* Get data resource to write (save) part data in.
* @param part
@ -71,7 +115,6 @@ public:
virtual async::CoroutineStarter getResourceAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::resource::Resource>& resource) = 0;
};
/**
@ -134,7 +177,7 @@ private:
};
private:
std::shared_ptr<AsyncPartReaderResourceProvider> m_resourceProvider;
std::shared_ptr<PartReaderResourceProvider> m_resourceProvider;
v_io_size m_maxDataSize;
public:
@ -143,7 +186,7 @@ public:
* @param resourceProvider
* @param maxDataSize - use `-1` for no limit.
*/
AsyncStreamPartReader(const std::shared_ptr<AsyncPartReaderResourceProvider>& resourceProvider, v_io_size maxDataSize = -1);
AsyncStreamPartReader(const std::shared_ptr<PartReaderResourceProvider>& resourceProvider, v_io_size maxDataSize = -1);
/**
* Called when new part headers are parsed and part object is created.
@ -166,5 +209,4 @@ public:
}}}}
#endif // oatpp_web_mime_multipart_StreamPartReader_hpp
#endif //oatpp_web_mime_multipart_PartReader_hpp

View File

@ -25,6 +25,7 @@
#ifndef oatpp_web_mime_multipart_Reader_hpp
#define oatpp_web_mime_multipart_Reader_hpp
#include "PartReader.hpp"
#include "Multipart.hpp"
#include "StatefulParser.hpp"
@ -32,64 +33,6 @@
namespace oatpp { namespace web { namespace mime { namespace multipart {
/**
* Abstract read handler of multipart parts.
*/
class PartReader {
public:
/**
* Default virtual destructor.
*/
virtual ~PartReader() = default;
/**
* Called when new part headers are parsed and part object is created.
* @param part
*/
virtual void onNewPart(const std::shared_ptr<Part>& part) = 0;
/**
* Called on each new chunk of data is parsed for the multipart-part. <br>
* When all data is read, called again with `data == nullptr && size == 0` to indicate end of the part.
* @param part
* @param data - pointer to buffer containing chunk data.
* @param size - size of the buffer.
*/
virtual void onPartData(const std::shared_ptr<Part>& part, const char* data, oatpp::v_io_size size) = 0;
};
/**
* Abstract Async read handler of multipart parts.
*/
class AsyncPartReader {
public:
/**
* Default virtual destructor.
*/
virtual ~AsyncPartReader() = default;
/**
* Called when new part headers are parsed and part object is created.
* @param part
* @return - &id:oatpp::async::CoroutineStarter;.
*/
virtual async::CoroutineStarter onNewPartAsync(const std::shared_ptr<Part>& part) = 0;
/**
* Called on each new chunk of data is parsed for the multipart-part. <br>
* When all data is read, called again with `data == nullptr && size == 0` to indicate end of the part.
* @param part
* @param data - pointer to buffer containing chunk data.
* @param size - size of the buffer.
* @return - &id:oatpp::async::CoroutineStarter;.
*/
virtual async::CoroutineStarter onPartDataAsync(const std::shared_ptr<Part>& part, const char* data, oatpp::v_io_size size) = 0;
};
class Reader; // FWD
/**

View File

@ -0,0 +1,70 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "TemporaryFileProvider.hpp"
#include "oatpp/core/data/resource/TemporaryFile.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
TemporaryFileProvider::TemporaryFileProvider(const oatpp::String& tmpDirectory, v_int32 randomWordSizeBytes)
: m_tmpDirectory(tmpDirectory)
, m_randomWordSizeBytes(randomWordSizeBytes)
{}
std::shared_ptr<data::resource::Resource> TemporaryFileProvider::getResource(const std::shared_ptr<Part>& part) {
(void)part;
return std::make_shared<data::resource::TemporaryFile>(m_tmpDirectory, m_randomWordSizeBytes);
}
async::CoroutineStarter TemporaryFileProvider::getResourceAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::resource::Resource>& stream)
{
(void)part;
stream = std::make_shared<data::resource::TemporaryFile>(m_tmpDirectory, m_randomWordSizeBytes);
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Other functions
std::shared_ptr<PartReader> createTemporaryFilePartReader(const oatpp::String& tmpDirectory,
v_int32 randomWordSizeBytes,
v_io_size maxDataSize)
{
auto provider = std::make_shared<TemporaryFileProvider>(tmpDirectory, randomWordSizeBytes);
auto reader = std::make_shared<StreamPartReader>(provider, maxDataSize);
return reader;
}
std::shared_ptr<AsyncPartReader> createAsyncTemporaryFilePartReader(const oatpp::String& tmpDirectory,
v_int32 randomWordSizeBytes,
v_io_size maxDataSize)
{
auto provider = std::make_shared<TemporaryFileProvider>(tmpDirectory, randomWordSizeBytes);
auto reader = std::make_shared<AsyncStreamPartReader>(provider, maxDataSize);
return reader;
}
}}}}

View File

@ -0,0 +1,72 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_web_mime_multipart_TemporaryFileProvider_hpp
#define oatpp_web_mime_multipart_TemporaryFileProvider_hpp
#include "PartReader.hpp"
#include "Reader.hpp"
namespace oatpp { namespace web { namespace mime { namespace multipart {
class TemporaryFileProvider : public PartReaderResourceProvider {
private:
oatpp::String m_tmpDirectory;
v_int32 m_randomWordSizeBytes;
public:
TemporaryFileProvider(const oatpp::String& tmpDirectory, v_int32 randomWordSizeBytes = 8);
std::shared_ptr<data::resource::Resource> getResource(const std::shared_ptr<Part>& part) override;
async::CoroutineStarter getResourceAsync(const std::shared_ptr<Part>& part,
std::shared_ptr<data::resource::Resource>& resource) override;
};
/**
* Create part reader to a temporary file.
* @param tmpDirectory - directory for temporary files.
* @param randomWordSizeBytes - number of random bytes to generate file name.
* @param maxDataSize - max size of the received data. put `-1` for no-limit.
* @return - `std::shared_ptr` to &id:oatpp::web::mime::multipart::PartReader;.
*/
std::shared_ptr<PartReader> createTemporaryFilePartReader(const oatpp::String& tmpDirectory,
v_int32 randomWordSizeBytes,
v_io_size maxDataSize = -1);
/**
* Create async part reader to a temporary file.
* @param tmpDirectory - directory for temporary files.
* @param randomWordSizeBytes - number of random bytes to generate file name.
* @param maxDataSize - max size of the received data. put `-1` for no-limit.
* @return - `std::shared_ptr` to &id:oatpp::web::mime::multipart::AsyncPartReader;.
*/
std::shared_ptr<AsyncPartReader> createAsyncTemporaryFilePartReader(const oatpp::String& tmpDirectory,
v_int32 randomWordSizeBytes,
v_io_size maxDataSize = -1);
}}}}
#endif //oatpp_web_mime_multipart_TemporaryFileProvider_hpp

View File

@ -78,7 +78,7 @@ void runTests() {
OATPP_LOGD("Tests", "coroutine size=%d", sizeof(oatpp::async::AbstractCoroutine));
OATPP_LOGD("Tests", "action size=%d", sizeof(oatpp::async::Action));
OATPP_LOGD("Tests", "class count=%d", oatpp::data::mapping::type::ClassId::getClassCount());
/*
OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);
OATPP_RUN_TEST(oatpp::test::base::LoggerTest);
@ -175,7 +175,7 @@ void runTests() {
test_port.run();
}
*/
{
oatpp::test::web::FullTest test_virtual(0, 1000);

View File

@ -242,8 +242,8 @@ void FullAsyncTest::onRun() {
multipart = std::make_shared<oatpp::web::mime::multipart::PartList>(response->getHeaders());
oatpp::web::mime::multipart::Reader multipartReader(multipart.get());
multipartReader.setPartReader("value1", std::make_shared<oatpp::web::mime::multipart::InMemoryPartReader>(10));
multipartReader.setPartReader("value2", std::make_shared<oatpp::web::mime::multipart::InMemoryPartReader>(10));
multipartReader.setPartReader("value1", oatpp::web::mime::multipart::createInMemoryPartReader(10));
multipartReader.setPartReader("value2", oatpp::web::mime::multipart::createInMemoryPartReader(10));
response->transferBody(&multipartReader);

View File

@ -460,8 +460,8 @@ void FullTest::onRun() {
multipart = std::make_shared<oatpp::web::mime::multipart::PartList>(response->getHeaders());
oatpp::web::mime::multipart::Reader multipartReader(multipart.get());
multipartReader.setPartReader("value1", std::make_shared<oatpp::web::mime::multipart::InMemoryPartReader>(10));
multipartReader.setPartReader("value2", std::make_shared<oatpp::web::mime::multipart::InMemoryPartReader>(10));
multipartReader.setPartReader("value1", oatpp::web::mime::multipart::createInMemoryPartReader(10));
multipartReader.setPartReader("value2", oatpp::web::mime::multipart::createInMemoryPartReader(10));
response->transferBody(&multipartReader);

View File

@ -27,8 +27,8 @@
#include "./DTOs.hpp"
#include "oatpp/web/mime/multipart/FileResourceProvider.hpp"
#include "oatpp/web/mime/multipart/InMemoryPartReader.hpp"
#include "oatpp/web/mime/multipart/FileProvider.hpp"
#include "oatpp/web/mime/multipart/InMemoryDataProvider.hpp"
#include "oatpp/web/mime/multipart/Reader.hpp"
#include "oatpp/web/mime/multipart/PartList.hpp"
@ -240,7 +240,7 @@ public:
auto multipart = std::make_shared<oatpp::web::mime::multipart::PartList>(request->getHeaders());
oatpp::web::mime::multipart::Reader multipartReader(multipart.get());
multipartReader.setDefaultPartReader(std::make_shared<oatpp::web::mime::multipart::InMemoryPartReader>(10));
multipartReader.setDefaultPartReader(oatpp::web::mime::multipart::createInMemoryPartReader(10));
request->transferBody(&multipartReader);

View File

@ -27,8 +27,8 @@
#include "./DTOs.hpp"
#include "oatpp/web/mime/multipart/FileResourceProvider.hpp"
#include "oatpp/web/mime/multipart/InMemoryPartReader.hpp"
#include "oatpp/web/mime/multipart/FileProvider.hpp"
#include "oatpp/web/mime/multipart/InMemoryDataProvider.hpp"
#include "oatpp/web/mime/multipart/Reader.hpp"
#include "oatpp/web/mime/multipart/PartList.hpp"
@ -214,7 +214,7 @@ public:
m_multipart = std::make_shared<oatpp::web::mime::multipart::PartList>(request->getHeaders());
auto multipartReader = std::make_shared<oatpp::web::mime::multipart::AsyncReader>(m_multipart);
multipartReader->setDefaultPartReader(std::make_shared<oatpp::web::mime::multipart::AsyncInMemoryPartReader>(10));
multipartReader->setDefaultPartReader(oatpp::web::mime::multipart::createAsyncInMemoryPartReader(10));
return request->transferBodyAsync(multipartReader).next(yieldTo(&MultipartTest::respond));

View File

@ -25,7 +25,7 @@
#include "StatefulParserTest.hpp"
#include "oatpp/web/mime/multipart/PartList.hpp"
#include "oatpp/web/mime/multipart/InMemoryPartReader.hpp"
#include "oatpp/web/mime/multipart/InMemoryDataProvider.hpp"
#include "oatpp/web/mime/multipart/Reader.hpp"
#include "oatpp/core/data/stream/BufferStream.hpp"
@ -108,7 +108,7 @@ void StatefulParserTest::onRun() {
oatpp::web::mime::multipart::PartList multipart("12345");
auto listener = std::make_shared<oatpp::web::mime::multipart::PartsParser>(&multipart);
listener->setDefaultPartReader(std::make_shared<oatpp::web::mime::multipart::InMemoryPartReader>(128));
listener->setDefaultPartReader(oatpp::web::mime::multipart::createInMemoryPartReader(128));
parseStepByStep(text, "12345", listener, i);