# Oat++ 1.2.5 Previous release - [1.2.0](1.2.0.md) 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 intercept(const std::shared_ptr& request, const std::shared_ptr& 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, serverConnectionHandler)([] { OATPP_COMPONENT(std::shared_ptr, router); auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router); /* Add MyResponseInterceptor */ connectionHandler->addResponseInterceptor(std::make_shared()); 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, serverConnectionHandler)([] { OATPP_COMPONENT(std::shared_ptr, router); // get Router component auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router); /* Add CORS-enabling interceptors */ connectionHandler->addRequestInterceptor(std::make_shared()); connectionHandler->addResponseInterceptor(std::make_shared()); 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 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 } ```