๐๐ป ๋ฆฌ๋ฒ์ค ํ๋ก์๋ ์น์๋ฒ์ ๋ค์ด์จ ์์ฒญ์ ๋ค๋ฅธ ์๋ฒ๋ก ์์ฒญ์ ์ ๋ฌํ๊ธฐ ์ํด์ ์ฌ์ฉํฉ๋๋ค.
A reverse proxy is used to forward requests received by a web server to another server.
๐๐ป ๋ฆฌ๋ฒ์ค ํ๋ก์๊ฐ ์
ํ
๋ ์๋ฒhttp,https,5080)์ ์ค์ ๋ก ์คํ๋ ์๋ฒ(http,3000)๋ฅผ ์คํํฉ๋๋ค.
Run the server with the reverse proxy set up (http,https,5080) and the server to be actually executed (http,3000).
๐๐ป ๋ธ๋ผ์ฐ์ ์์ ๋ค์์ฒ๋ผ 5080ํฌํธ๋ก ์คํํ๋ฉด ํฌํธ3000๋ฒ์ธ ์๋ฒ์ ๋ณด๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
If you run it on port 5080 in a browser as follows, you can view the server information on port 3000.
โ๏ธLinux : https://host.domain.org:5080/api
โ๏ธmacOS : http://localhost:5080/api
๐๐ป macOS์์๋ http์๋ฒ๋ฅผ ํ
์คํธํ๊ณ Linux์๋ฒ์์๋ https์๋ฒ๋ฅผ ํ
์คํธํฉ๋๋ค.
Test the HTTP server on macOS and the HTTPS server on Linux.
๐๐ป ๋ฐฉํ๋ฒฝ์์ 3000๋ฒ ํฌํธ๋ฅผ ์ถ๊ฐ๋ก ์คํ ํฉ๋๋ค.(iptables)
Open port 3000 additionally in the firewall (iptables).
$ sudo iptables -I INPUT -p tcp --dport 3000 -j ACCEPT
$ sudo netfilter-persistent save
๐๐ป ๋๋จธ์ง ๋ฐฉํ๋ฒฝ ์ค์ ๋ถ๋ถ ์ค๋ช
์ ์ด์ ๊ฒ์๋ฌผ์ ์ฐธ์กฐํ์ธ์
Please refer to the previous post for the explanation of the remaining firewall settings.
โ๏ธ httplib.h(0.42.0)
curl -L https://raw.githubusercontent.com/yhirose/cpp-httplib/master/httplib.h -o httplib.h
๐๐ปHttp server(http_server.cpp)-Reverse proxy setting
โ๏ธ ์ฝ๋ / Code
#include "httplib.h"
#include <iostream>
static void copy_response(const httplib::Result& r, httplib::Response& res) {
if (!r) {
res.status = 502;
res.set_content("Backend server is unreachable.", "text/plain; charset=utf-8");
return;
}
res.status = r->status;
for (const auto& h : r->headers) {
if (h.first == "Connection" || h.first == "Keep-Alive" ||
h.first == "Proxy-Authenticate" || h.first == "Proxy-Authorization" ||
h.first == "TE" || h.first == "Trailers" ||
h.first == "Transfer-Encoding" || h.first == "Upgrade") {
continue;
}
res.set_header(h.first.c_str(), h.second.c_str());
}
res.body = r->body;
}
int main() {
httplib::Server svr;
// /api ์ /api/... ๋ชจ๋ ์ฒ๋ฆฌ
svr.Get(R"(/api.*)", [](const httplib::Request& req, httplib::Response& res) {
std::cout << "Proxying: " << req.method << " " << req.path << "\n";
httplib::Client cli("localhost", 3000);
if (auto backend_res = cli.Get(req.path.c_str())) {
copy_response(backend_res, res);
} else {
res.status = 502;
res.set_content("Backend server is unreachable.", "text/plain; charset=utf-8");
}
});
std::cout << "Proxy server listening on http://0.0.0.0:5080\n";
svr.listen("0.0.0.0", 5080);
return 0;
}
โ๏ธ ์ปดํ์ผ / Compiling
g++ -o http_server http_server.cpp -std=c++17 -pthread
โ๏ธ ์คํ / Run
./http_server
๐๐ปHttps server(https_server.cpp)-Reverse proxy setting
โ๏ธ ์ธ์ฆ์ ๋ณต์ฌ / Copy certificate
— ์ด์ ์ ๋ฐ๊ธ๋ฐ์ Let’s Encrypt์ธ์ฆ์์
๋๋ค.(์ด์ ๊ฒ์๋ฌผ ์ฐธ์กฐ)
Please refer to the previous post for the explanation of the remaining firewall settings.
$ sudo cp /etc/letsencrypt/live/host.domain.org/fullchain.pem ./
$ sudo cp /etc/letsencrypt/live/host.domain.org/privkey.pem ./
# ๋ด ๊ณ์ ์ผ๋ก ์์ ๊ถ ๋ณ๊ฒฝ / Change ownership to my account
$ sudo chown username:username *.pem
โ๏ธ ์ฝ๋ / Code
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
#include <iostream>
static void copy_response(const httplib::Result& r, httplib::Response& res) {
if (!r) {
res.status = 502;
res.set_content("Backend server is unreachable.", "text/plain; charset=utf-8");
return;
}
res.status = r->status;
for (const auto& h : r->headers) {
if (h.first == "Connection" || h.first == "Keep-Alive" ||
h.first == "Proxy-Authenticate" || h.first == "Proxy-Authorization" ||
h.first == "TE" || h.first == "Trailers" ||
h.first == "Transfer-Encoding" || h.first == "Upgrade") {
continue;
}
res.set_header(h.first.c_str(), h.second.c_str());
}
res.body = r->body;
}
int main() {
httplib::SSLServer svr("./fullchain.pem", "./privkey.pem");
if (!svr.is_valid()) {
std::cerr << "SSL server setup failed\n";
return 1;
}
// ๋ชจ๋ /api/... ์์ฒญ์ ํ๋ก์ ์ฒ๋ฆฌ
svr.Get(R"(/api.*)", [](const httplib::Request& req, httplib::Response& res) {
httplib::Client cli("localhost", 3000);
if (auto backend_res = cli.Get(req.path.c_str())) {
copy_response(backend_res, res);
} else {
res.status = 502;
res.set_content("Backend server is unreachable.", "text/plain; charset=utf-8");
}
});
std::cout << "Proxy server listening on https://0.0.0.0:5080\n";
svr.listen("0.0.0.0", 5080);
return 0;
}
โ๏ธ ์ปดํ์ผ / Compiling
g++ -o https_server https_server.cpp -std=c++17 -pthread -lssl -lcrypto
โ๏ธ ์คํ / Run
./https_server
๐๐ป http server(httplib_server.cpp)
โ๏ธ ์ฝ๋ / Code
#include "httplib.h"
#include <iostream>
int main()
{
httplib::Server svr;
svr.Get("/",[](const httplib::Request &req, httplib::Response &res){
res.set_content("<h1>Hi! silver hand!!!๐</h1>", "text/html; charset=utf-8");
});
svr.Get("/api",[](const httplib::Request &req, httplib::Response &res){
//res.set_content("Hello Red Dead Redemption!","text/plain");
res.set_content("<h1>๐๐ปHello Red Dead Redemption-reverse proxy ok!!</h1>", "text/html; charset=utf-8");
});
std::cout << "cpp-httplib server listening on http://localhost:3000" << std::endl;
svr.listen("0.0.0.0", 3000);
return 0;
}
โ๏ธ ์ปดํ์ผ / Compiling
g++ -o https_server https_server.cpp -std=c++17
โ๏ธ ์คํ / Run
./httplib_server
๐๐ป ์๋ฒ ์คํ ๋ฐฉ๋ฒ / How to run the server
โ๏ธ ์์์ ์์ฑ๋ ์ฝ๋๋ฅผ ์๋์ฒ๋ผ ํ
์คํธ ํ ์ ์์ต๋๋ค.
You can test the code written above as follows.
โ๏ธ macOS
— 5080์๋ฒ์ 3000๋ฒ ์๋ฒ๋ฅผ ์คํํฉ๋๋ค.
Run server 5080 and server 3000.

— ๋ธ๋ผ์ฐ์ ์์ 5080ํฌํธ์๋ฒ๋ก ์ ์ํฉ๋๋ค. / Connect to the server on port 5080 in your browser.
(http://localhost:5080/api)

โ๏ธ Linux
— 5080์๋ฒ์ 3000๋ฒ ์๋ฒ๋ฅผ ์คํํฉ๋๋ค.
Run server 5080 and server 3000.

— ๋ธ๋ผ์ฐ์ ์์ 5080ํฌํธ์๋ฒ๋ก ์ ์ํฉ๋๋ค. / Connect to the server on port 5080 in your browser.
(https://host.domain.org:5080/api)
