2020-12-21 08:46:01 +08:00
|
|
|
# Oat++ 1.2.5
|
2020-11-29 23:32:07 +08:00
|
|
|
|
2020-12-21 08:46:01 +08:00
|
|
|
Previous release - [1.2.0](1.2.0.md)
|
2020-11-29 23:32:07 +08:00
|
|
|
|
2020-12-21 08:46:01 +08:00
|
|
|
Feel free to ask questions - [Chat on Gitter!](https://gitter.im/oatpp-framework/Lobby)
|
|
|
|
|
|
|
|
Contents:
|
|
|
|
|
|
|
|
- [Introduce ResponseInterceptor](#introduce-responseinterceptor)
|
|
|
|
- [Enable Global CORS](#enable-global-cors)
|
|
|
|
- [Headers Multimap](#headers-multimap)
|
|
|
|
- [Better Router API](#better-router-api)
|
|
|
|
|
|
|
|
## Introduce ResponseInterceptor
|
|
|
|
|
|
|
|
### Declare Response Interceptor
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
#include "oatpp/web/server/interceptor/ResponseInterceptor.hpp"
|
|
|
|
|
|
|
|
class MyResponseInterceptor : public ResponseInterceptor {
|
|
|
|
public:
|
|
|
|
|
|
|
|
std::shared_ptr<OutgoingResponse> intercept(const std::shared_ptr<IncomingRequest>& request,
|
|
|
|
const std::shared_ptr<OutgoingResponse>& response) override
|
|
|
|
{
|
|
|
|
// TODO modify response or create a new one
|
|
|
|
return response; // return modified response
|
|
|
|
// returning nullptr will result in an error
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
### Register global request interceptor
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
|
|
|
|
|
|
|
|
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
|
|
|
|
|
|
|
|
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
|
|
|
|
|
|
|
|
/* Add MyResponseInterceptor */
|
|
|
|
connectionHandler->addResponseInterceptor(std::make_shared<MyResponseInterceptor>());
|
|
|
|
|
|
|
|
return connectionHandler;
|
|
|
|
|
|
|
|
}());
|
|
|
|
```
|
|
|
|
|
|
|
|
## Enable Global CORS
|
|
|
|
|
|
|
|
To enable global CORS for all endpoints:
|
|
|
|
|
|
|
|
- Add **Request** Interceptor - `oatpp::web::server::interceptor::AllowOptionsGlobal` to `ConnectionHandler`.
|
|
|
|
- Add **Response** Interceptor - `atpp::web::server::interceptor::AllowCorsGlobal` to `ConnectionHandler`.
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
#include "oatpp/web/server/interceptor/AllowCorsGlobal.hpp"
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
|
|
|
|
|
|
|
|
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router); // get Router component
|
|
|
|
|
|
|
|
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
|
|
|
|
|
|
|
|
/* Add CORS-enabling interceptors */
|
|
|
|
connectionHandler->addRequestInterceptor(std::make_shared<oatpp::web::server::interceptor::AllowOptionsGlobal>());
|
|
|
|
connectionHandler->addResponseInterceptor(std::make_shared<oatpp::web::server::interceptor::AllowCorsGlobal>());
|
|
|
|
|
|
|
|
return connectionHandler;
|
|
|
|
|
|
|
|
}());
|
|
|
|
```
|
|
|
|
|
|
|
|
## Headers Multimap
|
|
|
|
|
|
|
|
Now headers are stored using [std::multimap](https://en.cppreference.com/w/cpp/container/multimap) and can store multiple entries with the same key.
|
|
|
|
|
|
|
|
Put multiple headers:
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
auto response = createResponse(Status::CODE_200, "");
|
|
|
|
response->putHeader("Set-Cookie", "...");
|
|
|
|
response->putHeader("Set-Cookie", "...");
|
|
|
|
return response;
|
|
|
|
```
|
|
|
|
|
|
|
|
Log all "Set-Cookie" headers:
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
const auto& map = headers.getAll();
|
|
|
|
auto itlow = map.lower_bound("Set-Cookie");
|
|
|
|
auto itup = map.upper_bound("Set-Cookie");
|
|
|
|
|
|
|
|
for(auto it = itlow; it != itup; it ++) {
|
|
|
|
oatpp::String value = it->second.toString();
|
|
|
|
OATPP_LOGD("Header", "Set-Cookie: %s", value->c_str());
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Better Router API
|
|
|
|
|
|
|
|
Now Router class is a template and can store any value-types and not only `RequestHandler`s.
|
|
|
|
|
|
|
|
Example use-case - check if endpoint should require authorization:
|
|
|
|
|
|
|
|
**Add Routs**
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
oatpp::web::server::HttpRouterTemplate<bool> authEndpoints;
|
|
|
|
|
|
|
|
authEndpoint.route("POST", "login", false); // DO NOT require auth for /login path
|
|
|
|
authEndpoint.route("POST", "auth", false); // DO NOT require auth for /auth path
|
|
|
|
|
|
|
|
authEndpoint.route("GET", "*", true); // require auth for all GET
|
|
|
|
authEndpoint.route("POST", "*", true); // require auth for all POST
|
|
|
|
|
|
|
|
authEndpoint.route("OPTIONS", "*", false); // DO NOT require auth for OPTIONS
|
|
|
|
```
|
|
|
|
|
|
|
|
**Check Auth**
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
auto r = authEndpoints.getRoute(request->getStartingLine().method, request->getStartingLine().path);
|
|
|
|
if(r && r.getEndpoint() == true) {
|
|
|
|
// check auth
|
|
|
|
}
|
|
|
|
```
|