acl/app/wizard_demo/httpd_proxy/http_servlet.cpp

170 lines
4.0 KiB
C++
Raw Normal View History

#include "stdafx.h"
#include "tcp_transfer.h"
2019-03-14 15:24:11 +08:00
#include "http_servlet.h"
http_servlet::http_servlet(acl::socket_stream* stream, acl::session* session)
: acl::HttpServlet(stream, session)
{
2022-01-19 23:47:53 +08:00
handlers_["/hello"] = &http_servlet::onHello;
2019-03-14 15:24:11 +08:00
}
http_servlet::~http_servlet(void)
{
}
bool http_servlet::doError(request_t&, response_t& res)
{
res.setStatus(400);
res.setContentType("text/xml; charset=utf-8");
// <20><><EFBFBD><EFBFBD> http <20><>Ӧ<EFBFBD><D3A6>
2019-03-14 15:24:11 +08:00
acl::string buf;
buf.format("<root error='some error happened!' />\r\n");
res.write(buf);
res.write(NULL, 0);
return false;
}
bool http_servlet::doOther(request_t&, response_t& res, const char* method)
{
res.setStatus(400);
res.setContentType("text/xml; charset=utf-8");
// <20><><EFBFBD><EFBFBD> http <20><>Ӧ<EFBFBD><D3A6>
2019-03-14 15:24:11 +08:00
acl::string buf;
buf.format("<root error='unkown request method %s' />\r\n", method);
res.write(buf);
res.write(NULL, 0);
return false;
}
bool http_servlet::doGet(request_t& req, response_t& res)
{
return doPost(req, res);
}
bool http_servlet::doPost(request_t& req, response_t& res)
{
const char* path = req.getPathInfo();
handler_t handler = path && *path ? handlers_[path] : NULL;
2022-01-19 23:47:53 +08:00
return handler ? (this->*handler)(req, res) : onDefault(req, res);
2019-03-14 15:24:11 +08:00
}
2022-01-19 23:47:53 +08:00
bool http_servlet::onHello(request_t& req, response_t& res)
2019-03-14 15:24:11 +08:00
{
res.setContentType("text/html; charset=utf-8") // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
.setKeepAlive(req.isKeepAlive()) // <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ񱣳ֳ<F1B1A3B3><D6B3><EFBFBD><EFBFBD><EFBFBD>
.setContentEncoding(true) // <20>Զ<EFBFBD>֧<EFBFBD><D6A7>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.setChunkedTransferEncoding(true); // <20><><EFBFBD><EFBFBD> chunk <20><><EFBFBD>ʽ
2019-03-14 15:24:11 +08:00
acl::string buf;
buf.format("<html><body>xxxxxxx<br>\r\n");
if (res.write(buf) == false) {
printf("write error\r\n");
return false;
}
acl::json* json = req.getJson();
if (json == NULL) {
printf("json null\r\n");
} else {
printf("json is [%s]\r\n", json->to_string().c_str());
}
2022-01-19 23:47:53 +08:00
for (size_t i = 0; i < 1; i++) {
2019-03-14 15:24:11 +08:00
buf.format("hello world=%d<br>\r\n", (int) i);
if (res.write(buf) == false) {
printf("write error\r\n");
return false;
}
if (i % 10000 == 0)
{
sleep(1);
printf("i=%d\n", (int) i);
}
}
buf = "</body></html><br>\r\n";
printf("write ok\n");
return res.write(buf) && res.write(NULL, 0);
}
2022-01-19 23:47:53 +08:00
bool http_servlet::onDefault(request_t& req, response_t& res)
{
const char* host = req.getRemoteHost();
if (host == NULL || *host == 0) {
logger_error("no Host in request head");
return false;
}
acl::string buf(host);
char* port = strrchr(buf.c_str(), ':');
if (port == NULL || *(port + 1) == 0) {
port = "80";
} else {
*port++ = 0;
}
acl::string peer_addr;
peer_addr.format("%s|%s", buf.c_str(), port);
acl::socket_stream peer;
if (!peer.open(buf.c_str(), 0, 0)) {
logger_error("connect %s error %s", buf.c_str(), acl::last_serror());
return false;
}
return true;
}
2019-03-14 15:24:11 +08:00
bool http_servlet::doConnect(request_t& req, response_t& res)
{
// CONNECT 127.0.0.1:22 HTTP/1.0
// HTTP/1.1 200 Connection Established
const char* host = req.getRemoteHost();
if (host == NULL || *host == 0) {
2022-01-19 23:47:53 +08:00
logger_error("getRemoteHost null");
2019-03-14 15:24:11 +08:00
return false;
}
2022-01-19 23:47:53 +08:00
2019-03-14 15:24:11 +08:00
printf("remote host=%s\r\n", host);
acl::socket_stream peer;
if (peer.open(host, 0, 0) == false) {
2022-01-19 23:47:53 +08:00
logger_error("connect %s error %s", host, acl::last_serror());
2019-03-14 15:24:11 +08:00
return false;
}
//const char* ok = "HTTP/1.1 200 Connection Established\r\n";
//acl::ostream& out = res.getOutputStream();
const char* ok = "";
res.setContentLength(0);
if (res.write(ok, 1) == false) {
2019-03-14 15:24:11 +08:00
return false;
}
acl::socket_stream& local = req.getSocketStream();
2022-01-19 23:47:53 +08:00
doTcpProxy(local, peer);
2019-03-14 15:24:11 +08:00
return false;
}
2022-01-19 23:47:53 +08:00
bool http_servlet::doTcpProxy(acl::socket_stream& local, acl::socket_stream& peer)
2019-03-14 15:24:11 +08:00
{
tcp_transfer fiber_local(local, peer);
tcp_transfer fiber_peer(peer, local);
2019-03-14 15:24:11 +08:00
fiber_local.set_peer(fiber_peer);
fiber_peer.set_peer(fiber_local);
fiber_local.start();
fiber_peer.start();
fiber_local.wait();
fiber_peer.wait();
printf("doProxy finished, local fd=%d, peer fd=%d\r\n",
fiber_local.get_input().sock_handle(),
fiber_local.get_output().sock_handle());
return true;
}