FILTER 절
Filter 모듈을 사용할 FILTER 절을 정의하여, NODE 절이나 SERVER 절에서 filter 항목을 설정합니다.
설정 항목
다음은 FILTER 절의 환경 설정 형식입니다.
#"filter": { #"filters": [ { "name": string, "path": string, #"event": [string] } ] }
절과 설정 항목의 구성에 대한 기호나 내용에 대한 자세한 내용은 설정 항목 값의 형식 및 설정 방법을 참고합니다. |
filters/name (필수 항목)
FILTER 설정의 이름입니다. 다른 절에서 FILTER 절의 기능을 사용할 때는 이 'name’을 설정해야 합니다.
구분 | 설명 |
---|---|
자료형 |
string |
범위 |
31자 이내 |
filters/event
Filter 모듈이 동작하는 타이밍을 설정합니다.
구분 | 설명 |
---|---|
자료형 |
array(string) |
범위 |
15개 이내(255자 이내) |
다음은 종류별 필터 이벤트에 대한 설명입니다. 필터 이벤트 종류에 따라 설정하는 위치가 NODE 절 또는 SERVER 절로 구분됩니다.
-
SYSTEM 필터 이벤트
SYSTEM 필터 이벤트를 포함하는 필터는 NODE 절에 설정합니다.
필터 이벤트 설명 ON_STOP
WebtoB 엔진 종료 시점에 동작합니다.
ON_START
WebtoB 엔진 기동 시점에 동작합니다.
-
HTTP 필터 이벤트
HTTP 필터 이벤트를 포함하는 필터는 SERVER 절에 설정합니다.
필터 이벤트 설명 RECEIVE_REQUEST
클라이언트에게 HTTP 요청을 받은 시점에 동작합니다.
BEFORE_SEND_REQUEST
클라이언트에게 받은 HTTP 요청을 내부 서버에 전달하기 전 시점에 동작합니다.
AFTER_SEND_REQUEST
클라이언트에게 받은 HTTP 요청을 내부 서버에 전달한 후 시점에 동작합니다.
RECEIVE_RESPONSE
내부 서버에게 HTTP 응답을 받은 시점에 동작합니다.
BEFORE_SEND_RESPONSE
내부 서버에게 받은 HTTP 응답을 클라이언트에 전달하기 전 시점에 동작합니다.
AFTER_SEND_RESPONSE
내부 서버에게 받은 HTTP 응답을 클라이언트에 전달한 후 점에 동작합니다.
설정 예시
다음은 Filter를 구현하기 위한 설정 예시입니다.
-
Filter 프로젝트 구조
다음은 Filter를 구현하기 위한 프로젝트의 구조 예시입니다. 각 파일은 Filter를 정의하고 구현하는 데 필요한 요소들을 포함하고 있습니다.
. ├── CMakeLists.txt ├── SampleSystemFilter.h ├── SampleSystemFilter.cpp ├── SampleHttpFilter.h └── SampleHttpFilter.cpp
각 파일의 설정 예시는 다음과 같습니다.
-
CMakeLists.txt
cmake_minimum_required(VERSION 3.15) project(sampleFilter) set(CMAKE_VERBOSE_MAKEFILE true) set(CMAKE_CXX_STANDARD 17) message("\t MODULE: ${PROJECT_NAME}") # Webtob Filter Include Directory include_directories(/WEBTOB_BINARY_PATH/include) # Library Add add_library(sampleSystemFilter SHARED SampleSystemFilter.cpp) add_library(sampleHttpFilter SHARED SampleHttpFilter.cpp)
-
SampleSystemFilter.h
/** * @File : SampleFilter.h * @Author : Webtob * @Year : 2024 */ #ifndef WEBTOB6_SAMPLE_SYSTEM_FILTER_H #define WEBTOB6_SAMPLE_SYSTEM_FILTER_H #include <iostream> #include <string> #include <sstream> #include <memory> #include <vector> #include "webtob-filter/filter-api/WebtobFilter.h" namespace webtob { class SampleSystemFilter : public WebtobFilter { public: static std::vector<std::string> calledEvents; FilterResult onStart() override; FilterResult onStop() override; FilterResult onReceiveRequest(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) override; FilterResult onReceiveResponse(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) override; private: static std::string getStaticVector(); void printCalledInfo(const char* calledEvent); std::string filterName = "SampleSystemFilter"; }; } // namespace webtob #endif //WEBTOB6_SAMPLE_SYSTEM_FILTER_H
-
SampleSystemFilter.cpp
#include "SampleSystemFilter.h" using namespace webtob; std::vector<std::string> SampleSystemFilter::calledEvents; // Filter Creator extern "C" [[maybe_unused]] std::shared_ptr<WebtobFilter> createFilter() { return std::make_shared<SampleSystemFilter>(); } std::string SampleSystemFilter::getStaticVector() { std::ostringstream description; description << "Sample SystemFilter Event Called Vector= [\n"; for (const std::string& event : calledEvents) { description << "\t" << event << "\n"; } description << "]"; return description.str(); } void SampleSystemFilter::printCalledInfo(const char* calledEvent) { calledEvents.emplace_back(calledEvent); std::ostringstream message; message << "\n============================================="; message << "\n" << filterName << " : " << calledEvent; message << "\n---------------------------------------------"; message << "\n" << getStaticVector(); message << "\n============================================="; std::cout << message.str() << std::endl; } FilterResult SampleSystemFilter::onStart() { printCalledInfo(__FUNCTION__); return FilterResult::SUCCESS; } FilterResult SampleSystemFilter::onStop() { printCalledInfo(__FUNCTION__); return FilterResult::SUCCESS; } FilterResult SampleSystemFilter::onReceiveRequest(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) { printCalledInfo(__FUNCTION__); return FilterResult::SUCCESS; } FilterResult SampleSystemFilter::onReceiveResponse(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) { printCalledInfo(__FUNCTION__); return FilterResult::SUCCESS; }
-
SampleHttpFilter.h
/** * @File : SampleHttpFilter.h * @Author : Webtob * @Year : 2024 */ #ifndef WEBTOB6_SAMPLE_HTTP_FILTER_H #define WEBTOB6_SAMPLE_HTTP_FILTER_H #include <iostream> #include <sstream> #include "webtob-filter/filter-api/WebtobFilter.h" namespace webtob { class SampleHttpFilter : public WebtobFilter { public: FilterResult onReceiveRequest(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) override; FilterResult onBeforeSendRequest(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) override; FilterResult onAfterSendRequest(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) override; FilterResult onReceiveResponse(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) override; FilterResult onBeforeSendResponse(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) override; FilterResult onAfterSendResponse(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) override; std::string filterName = "SampleHttpFilter"; private: void printCalledInfo(const char* calledEvent); }; } // namespace webtob #endif //WEBTOB6_SAMPLE_HTTP_FILTER_H
-
SampleHttpFilter.cpp
#include "SampleHttpFilter.h" #include <string_view> using namespace webtob; // Filter Creator extern "C" [[maybe_unused]] std::shared_ptr<WebtobFilter> createFilter() { return std::make_shared<SampleHttpFilter>(); } bool startsWith(const std::string_view& str, const std::string_view& prefix) { return str.substr(0, prefix.size()) == prefix; } void SampleHttpFilter::printCalledInfo(const char* calledEvent) { std::ostringstream message; message << "\n============================================="; message << "\n" << filterName << " : " << calledEvent; message << "\n============================================="; std::cout << message.str() << std::endl; } FilterResult SampleHttpFilter::onReceiveRequest(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) { printCalledInfo(__FUNCTION__); std::string path = request->getPath(); if (startsWith(path, "/service/")) { if (startsWith(path, "/service/A")) { response->setStatusCode(200); response->setBody("Filter makes service A response"); } else if (startsWith(path, "/service/B")) { response->setStatusCode(200); response->setBody("Service B response"); } else if (startsWith(path, "/service/C")) { response->setStatusCode(400); response->setBody("BAD Response Makes"); } return FilterResult::TERMINATE; } auto queryString = request->getQueryString(); if (queryString == "test=reject1") { response->setStatusCode(200); response->setBody("I decide to reject"); response->addHeader("ErrorCheck", "Reject1_Detected"); return FilterResult::TERMINATE; } request->addHeader("Filter", "InsertOn"); request->addCookie("FilterCookieKey", "OK_Inserted"); return FilterResult::SUCCESS; } FilterResult SampleHttpFilter::onBeforeSendRequest(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) { printCalledInfo(__FUNCTION__); auto queryString = request->getQueryString(); if (queryString == "test=reject2") { response->setStatusCode(200); response->setBody("I decide to reject onBeforeSendRequest"); response->addHeader("ErrorCheck", "onBeforeSendRequest"); return FilterResult::TERMINATE; } return FilterResult::SUCCESS; } FilterResult SampleHttpFilter::onAfterSendRequest(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) { printCalledInfo(__FUNCTION__); auto queryString = request->getQueryString(); if (queryString == "test=reject3") { response->addHeader("ErrorCheck", "onAfterSendRequest"); return FilterResult::TERMINATE; } return FilterResult::SUCCESS; } FilterResult SampleHttpFilter::onReceiveResponse(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) { printCalledInfo(__FUNCTION__); auto cookieBuilder = response->getCookieBuilder(); auto cookie = cookieBuilder->newCookie().setName("Cookie_ReceiveResponse").setValue("AddFromResponse") .setHttpOnly(true).setPath("/").setSameSite(FilterCookie::SameSite::OFF).build(); response->addCookie(cookie); response->addHeader("Filter_response", "OK_ADDED"); return FilterResult::SUCCESS; } FilterResult SampleHttpFilter::onBeforeSendResponse(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) { printCalledInfo(__FUNCTION__); auto cookieBuilder = response->getCookieBuilder(); auto cookie = cookieBuilder->newCookie().setName("MY_COOKIE").setValue("AddFromResponse") .setHttpOnly(true).setPath("/").setSameSite(FilterCookie::SameSite::OFF).build(); response->addCookie(cookie); return FilterResult::SUCCESS; } FilterResult SampleHttpFilter::onAfterSendResponse(const std::shared_ptr<FilterRequest>& request, const std::shared_ptr<FilterResponse>& response) { printCalledInfo(__FUNCTION__); return FilterResult::SUCCESS; }
-
-
빌드
~/workspace/myTestFilter> cmake . -B build -- The C compiler identification is AppleClang 15.0.0.15000309 -- The CXX compiler identification is AppleClang 15.0.0.15000309 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done MODULE: sampleFilter -- Configuring done (0.5s) -- Generating done (0.0s) -- Build files have been written to: /Users/seungwook/workspace/myTestFilter/build ~/workspace/myTestFilter> ~/workspace/myTestFilter> cd build && make
-
환경 설정
다음 환경 설정 파일에서 FILTER 절을 설정하는 예시입니다.
{ "filter": { "filters": [ { "name": "filter1", "path": "TargetRealPath/myTestFilter/libsampleSystemFilter.so", "event": [ "ON_START", "ON_STOP" ] }, { "name": "filter2", "path": "TargetRealPath/myTestFilter/libsampleHttpFilter.so", "event": [ "RECEIVE_REQUEST", "RECEIVE_RESPONSE" ] }, ] } }