mirror of
https://github.com/oatpp/oatpp.git
synced 2025-04-06 18:40:24 +08:00
Update changelog. Request/Response: use ObjectHandle for stream transfers.
This commit is contained in:
parent
70a643a571
commit
446ad6710d
@ -14,6 +14,7 @@ Contents:
|
||||
- [ConnectionProviderSwitch](#connectionproviderswitch)
|
||||
- [Proper Server Stoppage](#proper-server-stoppage)
|
||||
- [TemporaryFile](#temporaryfile)
|
||||
- [Better Multipart](#better-multipart)
|
||||
- [Response::getBody()](#responsegetbody)
|
||||
- [data::stream::FIFOStream](#datastreamfifostream)
|
||||
- [data::stream::BufferedInputStream](#datastreambufferedinputstream)
|
||||
@ -243,7 +244,7 @@ Now call to `HttpConnectionHandler::stop()`, `AsyncHttpConnectionHandler::stop()
|
||||
|
||||
## TemporaryFile
|
||||
|
||||
Introduce `oatpp::data::share::TemporaryFile`.
|
||||
Introduce `oatpp::data::resource::TemporaryFile`.
|
||||
|
||||
Use-case:
|
||||
|
||||
@ -251,20 +252,72 @@ Temporary file resolves concurrency issues during file uploads.
|
||||
Also, a temporary file ensures that partially uploaded (due to errors/exceptions) resources will be automatically deleted at the end of the block.
|
||||
|
||||
```cpp
|
||||
#include "oatpp/core/data/resource/TemporaryFile.hpp"
|
||||
|
||||
...
|
||||
|
||||
ENDPOINT("POST", "/upload", upload,
|
||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||
{
|
||||
oatpp::data::share::TemporaryFile tmp("/tmp"); // create random file in '/tmp' folder
|
||||
|
||||
auto stream = tmp.openOutputStream();
|
||||
request->transferBody(&stream); // transfer body to temporary file
|
||||
|
||||
tmp.moveFile("/path/to/permanent/storage/avatar.png"); // move file to permanent storage
|
||||
|
||||
/* create random file in '/tmp' folder */
|
||||
oatpp::data::resource::TemporaryFile tmp("/tmp");
|
||||
|
||||
/* transfer body to temporary file */
|
||||
request->transferBody(tmp.openOutputStream());
|
||||
|
||||
/* move file to permanent storage */
|
||||
OATPP_ASSERT_HTTP(tmp.moveFile("/path/to/permanent/storage/avatar.png"), Status::CODE_500, "Failed to save file")
|
||||
|
||||
/* return 200 */
|
||||
return createResponse(Status::CODE_200, "OK");
|
||||
}
|
||||
```
|
||||
|
||||
## Better Multipart
|
||||
|
||||
Multipart API has been changed and improved.
|
||||
Now it's possible to upload multiple files using `TemporaryFile` and keep track of
|
||||
all parts and their corresponding data resources.
|
||||
|
||||
```cpp
|
||||
#include "oatpp/web/mime/multipart/TemporaryFileProvider.hpp"
|
||||
#include "oatpp/web/mime/multipart/Reader.hpp"
|
||||
#include "oatpp/web/mime/multipart/PartList.hpp"
|
||||
|
||||
...
|
||||
|
||||
namespace multipart = oatpp::web::mime::multipart;
|
||||
|
||||
...
|
||||
|
||||
ENDPOINT("POST", "upload", upload,
|
||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||
{
|
||||
|
||||
/* create multipart object */
|
||||
multipart::PartList multipart(request->getHeaders());
|
||||
|
||||
/* create multipart reader */
|
||||
multipart::Reader multipartReader(&multipart);
|
||||
|
||||
/* setup reader to stream parts to a temporary files by default */
|
||||
multipartReader.setDefaultPartReader(multipart::createTemporaryFilePartReader("/Users/leonid/Documents/tmp"));
|
||||
|
||||
/* upload multipart data */
|
||||
request->transferBody(&multipartReader);
|
||||
|
||||
/* list all parts and locations to corresponding temporary files */
|
||||
auto parts = multipart.getAllParts();
|
||||
for(auto& p : parts) {
|
||||
OATPP_LOGD("part", "name=%s, location=%s", p->getName()->c_str(), p->getPayload()->getLocation()->c_str());
|
||||
}
|
||||
|
||||
/* return 200 */
|
||||
return createResponse(Status::CODE_200, "OK");
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Response::getBody()
|
||||
|
||||
`oatpp::web::protocol::http::outgoing::Response` has a new method `getBody()` to retreive the body of the response.
|
||||
|
@ -138,12 +138,12 @@ const data::Bundle& Request::getBundle() const {
|
||||
return m_bundle;
|
||||
}
|
||||
|
||||
void Request::transferBody(data::stream::WriteCallback* writeCallback) const {
|
||||
m_bodyDecoder->decode(m_headers, m_bodyStream.get(), writeCallback, m_connection.get());
|
||||
void Request::transferBody(const base::ObjectHandle<data::stream::WriteCallback>& writeCallback) const {
|
||||
m_bodyDecoder->decode(m_headers, m_bodyStream.get(), writeCallback.get(), m_connection.get());
|
||||
}
|
||||
|
||||
void Request::transferBodyToStream(oatpp::data::stream::OutputStream* toStream) const {
|
||||
m_bodyDecoder->decode(m_headers, m_bodyStream.get(), toStream, m_connection.get());
|
||||
void Request::transferBodyToStream(const base::ObjectHandle<oatpp::data::stream::OutputStream>& toStream) const {
|
||||
m_bodyDecoder->decode(m_headers, m_bodyStream.get(), toStream.get(), m_connection.get());
|
||||
}
|
||||
|
||||
oatpp::String Request::readBodyToString() const {
|
||||
|
@ -240,13 +240,13 @@ public:
|
||||
* Read body chunk by chunk and pass chunks to the `writeCallback`.
|
||||
* @param writeCallback - &id:oatpp::data::stream::WriteCallback;.
|
||||
*/
|
||||
void transferBody(data::stream::WriteCallback* writeCallback) const;
|
||||
void transferBody(const base::ObjectHandle<data::stream::WriteCallback>& writeCallback) const;
|
||||
|
||||
/**
|
||||
* Stream content of the body-stream to toStream
|
||||
* @param toStream
|
||||
*/
|
||||
void transferBodyToStream(oatpp::data::stream::OutputStream* toStream) const;
|
||||
void transferBodyToStream(const base::ObjectHandle<data::stream::OutputStream>& toStream) const;
|
||||
|
||||
/**
|
||||
* Transfer body stream to string
|
||||
@ -261,7 +261,7 @@ public:
|
||||
* @return DTO
|
||||
*/
|
||||
template<class Wrapper>
|
||||
Wrapper readBodyToDto(data::mapping::ObjectMapper* objectMapper) const {
|
||||
Wrapper readBodyToDto(const base::ObjectHandle<data::mapping::ObjectMapper>& objectMapper) const {
|
||||
return objectMapper->readFromString<Wrapper>(m_bodyDecoder->decodeToString(m_headers, m_bodyStream.get(), m_connection.get()));
|
||||
}
|
||||
|
||||
|
@ -103,12 +103,12 @@ std::shared_ptr<const http::incoming::BodyDecoder> Response::getBodyDecoder() co
|
||||
return m_bodyDecoder;
|
||||
}
|
||||
|
||||
void Response::transferBody(data::stream::WriteCallback* writeCallback) const {
|
||||
m_bodyDecoder->decode(m_headers, m_bodyStream.get(), writeCallback, m_connection.get());
|
||||
void Response::transferBody(const base::ObjectHandle<data::stream::WriteCallback>& writeCallback) const {
|
||||
m_bodyDecoder->decode(m_headers, m_bodyStream.get(), writeCallback.get(), m_connection.get());
|
||||
}
|
||||
|
||||
void Response::transferBodyToStream(oatpp::data::stream::OutputStream* toStream) const {
|
||||
m_bodyDecoder->decode(m_headers, m_bodyStream.get(), toStream, m_connection.get());
|
||||
void Response::transferBodyToStream(const base::ObjectHandle<oatpp::data::stream::OutputStream>& toStream) const {
|
||||
m_bodyDecoder->decode(m_headers, m_bodyStream.get(), toStream.get(), m_connection.get());
|
||||
}
|
||||
|
||||
oatpp::String Response::readBodyToString() const {
|
||||
|
@ -185,7 +185,7 @@ public:
|
||||
* Get raw body stream.
|
||||
* @return - raw body stream as &id:oatpp::data::stream::InputStream;.
|
||||
*/
|
||||
std::shared_ptr<oatpp::data::stream::InputStream> getBodyStream() const;
|
||||
std::shared_ptr<data::stream::InputStream> getBodyStream() const;
|
||||
|
||||
/**
|
||||
* Get body decoder configured for this response.
|
||||
@ -198,14 +198,14 @@ public:
|
||||
* Read body chunk by chunk and pass chunks to the `writeCallback`.
|
||||
* @param writeCallback - &id:oatpp::data::stream::WriteCallback;.
|
||||
*/
|
||||
void transferBody(data::stream::WriteCallback* writeCallback) const;
|
||||
void transferBody(const base::ObjectHandle<data::stream::WriteCallback>& writeCallback) const;
|
||||
|
||||
/**
|
||||
* Decode and transfer body to toStream.
|
||||
* Use case example - stream huge body directly to file using relatively small buffer.
|
||||
* @param toStream - pointer to &id:oatpp::data::stream::OutputStream;.
|
||||
*/
|
||||
void transferBodyToStream(oatpp::data::stream::OutputStream* toStream) const;
|
||||
void transferBodyToStream(const base::ObjectHandle<data::stream::OutputStream>& toStream) const;
|
||||
|
||||
/**
|
||||
* Decode and read body to &id:oatpp::String;.
|
||||
@ -220,8 +220,8 @@ public:
|
||||
* @return - deserialized DTO object.
|
||||
*/
|
||||
template<class Wrapper>
|
||||
Wrapper readBodyToDto(oatpp::data::mapping::ObjectMapper* objectMapper) const {
|
||||
return m_bodyDecoder->decodeToDto<Wrapper>(m_headers, m_bodyStream.get(), m_connection.get(), objectMapper);
|
||||
Wrapper readBodyToDto(const base::ObjectHandle<data::mapping::ObjectMapper>& objectMapper) const {
|
||||
return m_bodyDecoder->decodeToDto<Wrapper>(m_headers, m_bodyStream.get(), m_connection.get(), objectMapper.get());
|
||||
}
|
||||
|
||||
// Async
|
||||
@ -240,7 +240,7 @@ public:
|
||||
* @param toStream - `std::shared_ptr` to &id:oatpp::data::stream::OutputStream;.
|
||||
* @return - &id:oatpp::async::CoroutineStarter;.
|
||||
*/
|
||||
oatpp::async::CoroutineStarter transferBodyToStreamAsync(const std::shared_ptr<oatpp::data::stream::OutputStream>& toStream) const;
|
||||
oatpp::async::CoroutineStarter transferBodyToStreamAsync(const std::shared_ptr<data::stream::OutputStream>& toStream) const;
|
||||
|
||||
/**
|
||||
* Same as &l:Response::readBodyToString (); but Async.
|
||||
@ -258,7 +258,7 @@ public:
|
||||
*/
|
||||
template<class Wrapper>
|
||||
oatpp::async::CoroutineStarterForResult<const Wrapper&>
|
||||
readBodyToDtoAsync(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper) const {
|
||||
readBodyToDtoAsync(const std::shared_ptr<data::mapping::ObjectMapper>& objectMapper) const {
|
||||
return m_bodyDecoder->decodeToDtoAsync<Wrapper>(m_headers, m_bodyStream, m_connection, objectMapper);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user