2019-07-28 10:31:56 +08:00
|
|
|
|
#include "stdafx.h"
|
2022-01-18 23:58:40 +08:00
|
|
|
|
#include "tcp_transfer.h"
|
2022-01-24 18:36:08 +08:00
|
|
|
|
#include "http_transfer.h"
|
2019-03-14 15:24:11 +08:00
|
|
|
|
#include "http_servlet.h"
|
|
|
|
|
|
2022-01-24 18:36:08 +08:00
|
|
|
|
http_servlet::http_servlet(acl::socket_stream* stream, acl::session* session,
|
|
|
|
|
int port /* 80 */)
|
2019-03-14 15:24:11 +08:00
|
|
|
|
: acl::HttpServlet(stream, session)
|
2022-01-24 18:36:08 +08:00
|
|
|
|
, port_(port)
|
2019-03-14 15:24:11 +08:00
|
|
|
|
{
|
2022-01-24 18:36:08 +08:00
|
|
|
|
handlers_["/hello"] = &http_servlet::on_hello;
|
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");
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <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");
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <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)
|
|
|
|
|
{
|
2022-01-24 18:36:08 +08:00
|
|
|
|
const char* path = req.getPathInfo();
|
|
|
|
|
handler_t handler = path && *path ? handlers_[path] : NULL;
|
|
|
|
|
return handler ? (this->*handler)(req, res) : transfer_get(req, res);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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-24 18:36:08 +08:00
|
|
|
|
return handler ? (this->*handler)(req, res) : transfer_post(req, res);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-24 18:36:08 +08:00
|
|
|
|
bool http_servlet::on_hello(request_t& req, response_t& res)
|
2019-03-14 15:24:11 +08:00
|
|
|
|
{
|
2019-07-28 10:31:56 +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-24 18:36:08 +08:00
|
|
|
|
bool http_servlet::transfer_get(request_t& req, response_t& res)
|
2022-01-19 23:47:53 +08:00
|
|
|
|
{
|
2022-01-24 18:36:08 +08:00
|
|
|
|
http_transfer fiber_peer(acl::HTTP_METHOD_GET, req, res, port_);
|
|
|
|
|
fiber_peer.start();
|
2022-01-19 23:47:53 +08:00
|
|
|
|
|
2022-01-24 18:36:08 +08:00
|
|
|
|
bool keep_alive;
|
|
|
|
|
fiber_peer.wait(&keep_alive);
|
|
|
|
|
return keep_alive && req.isKeepAlive();
|
|
|
|
|
}
|
2022-01-19 23:47:53 +08:00
|
|
|
|
|
2022-01-24 18:36:08 +08:00
|
|
|
|
bool http_servlet::transfer_post(request_t& req, response_t& res)
|
|
|
|
|
{
|
|
|
|
|
http_transfer fiber_peer(acl::HTTP_METHOD_POST, req, res, port_);
|
|
|
|
|
fiber_peer.start();
|
|
|
|
|
|
|
|
|
|
bool keep_alive;
|
|
|
|
|
fiber_peer.wait(&keep_alive);
|
|
|
|
|
|
|
|
|
|
printf("transfer_post finished\r\n");
|
|
|
|
|
return keep_alive && req.isKeepAlive();
|
2022-01-19 23:47:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-16 12:00:12 +08:00
|
|
|
|
bool http_servlet::doConnect(request_t& req, response_t&)
|
2019-03-14 15:24:11 +08:00
|
|
|
|
{
|
|
|
|
|
// CONNECT 127.0.0.1:22 HTTP/1.0
|
|
|
|
|
// HTTP/1.1 200 Connection Established
|
|
|
|
|
|
2022-02-15 22:34:10 +08:00
|
|
|
|
const char* phost = req.getRemoteHost();
|
|
|
|
|
if (phost == NULL || *phost == 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
|
|
|
|
|
2022-02-15 22:34:10 +08:00
|
|
|
|
acl::string host;
|
|
|
|
|
const char* port = strrchr(phost, ':');
|
|
|
|
|
if (port == NULL) {
|
|
|
|
|
host.format("%s|80", phost);
|
|
|
|
|
} else if (*(port + 1) == 0) {
|
|
|
|
|
host.format("%s80", phost);
|
|
|
|
|
} else {
|
|
|
|
|
host = phost;
|
|
|
|
|
}
|
2022-02-16 18:16:58 +08:00
|
|
|
|
printf("remote host=%s, current fiber=%p\r\n", host.c_str(), acl_fiber_running());
|
2019-03-14 15:24:11 +08:00
|
|
|
|
|
|
|
|
|
acl::socket_stream peer;
|
2022-03-02 18:33:09 +08:00
|
|
|
|
if (!peer.open(host, 5, 5, acl::time_unit_s)) {
|
2022-02-15 22:34:10 +08:00
|
|
|
|
logger_error("connect %s error %s", host.c_str(), acl::last_serror());
|
2019-03-14 15:24:11 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-02-20 11:39:46 +08:00
|
|
|
|
printf("connect %s ok, fd=%d\r\n", host.c_str(), peer.sock_handle());
|
2019-03-14 15:24:11 +08:00
|
|
|
|
|
2022-02-15 22:34:10 +08:00
|
|
|
|
acl::socket_stream& local = req.getSocketStream();
|
|
|
|
|
local.set_rw_timeout(3);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
|
2022-02-15 22:34:10 +08:00
|
|
|
|
#if 0
|
2019-03-14 15:24:11 +08:00
|
|
|
|
const char* ok = "";
|
|
|
|
|
res.setContentLength(0);
|
2022-02-15 22:34:10 +08:00
|
|
|
|
if (!res.write(ok, 1)) {
|
|
|
|
|
logger_error("write connect header error");
|
2019-03-14 15:24:11 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-02-15 22:34:10 +08:00
|
|
|
|
#else
|
|
|
|
|
const char* ok = "HTTP/1.1 200 Connection Established\r\n\r\n";
|
|
|
|
|
size_t n = strlen(ok);
|
|
|
|
|
|
2022-02-16 12:00:12 +08:00
|
|
|
|
if (local.write(ok, n) != (int) n) {
|
2022-02-15 22:34:10 +08:00
|
|
|
|
logger_error("write connect response error");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2019-03-14 15:24:11 +08:00
|
|
|
|
|
2022-01-24 18:36:08 +08:00
|
|
|
|
transfer_tcp(local, peer);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-24 18:36:08 +08:00
|
|
|
|
bool http_servlet::transfer_tcp(acl::socket_stream& local, acl::socket_stream& peer)
|
2019-03-14 15:24:11 +08:00
|
|
|
|
{
|
2022-03-01 19:02:05 +08:00
|
|
|
|
local.set_rw_timeout(5);
|
|
|
|
|
peer.set_rw_timeout(5);
|
2022-02-20 11:39:46 +08:00
|
|
|
|
|
2022-03-02 18:33:09 +08:00
|
|
|
|
tcp_transfer fiber_local(acl_fiber_running(), local, peer, false);
|
|
|
|
|
tcp_transfer fiber_peer(acl_fiber_running(), peer, local, false);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
|
|
|
|
|
fiber_local.set_peer(fiber_peer);
|
|
|
|
|
fiber_peer.set_peer(fiber_local);
|
|
|
|
|
|
|
|
|
|
fiber_peer.start();
|
2022-02-15 22:34:10 +08:00
|
|
|
|
fiber_local.start();
|
|
|
|
|
|
2022-03-01 19:02:05 +08:00
|
|
|
|
//int fd_local = local.sock_handle();
|
|
|
|
|
//int fd_peer = peer.sock_handle();
|
|
|
|
|
|
|
|
|
|
//printf("wait local fiber, local fd=%d, peer fd=%d\r\n", fd_local, fd_peer);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
fiber_local.wait();
|
2022-03-01 19:02:05 +08:00
|
|
|
|
//printf("local fiber done, local fd=%d, peer fd=%d\r\n", fd_local, fd_peer);
|
2022-02-20 11:39:46 +08:00
|
|
|
|
|
2022-03-01 19:02:05 +08:00
|
|
|
|
//printf("wait peer fiber, local fd=%d, peer fd=%d\r\n", fd_local, fd_peer);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
fiber_peer.wait();
|
2022-03-01 19:02:05 +08:00
|
|
|
|
//printf("peer fiber done, local fd=%d, peer fd=%d\r\n", fd_local, fd_peer);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
|
2022-03-01 19:02:05 +08:00
|
|
|
|
//printf("transfer_tcp finished, local fd=%d, %d, peer fd=%d, %d\r\n",
|
|
|
|
|
// fiber_local.get_input().sock_handle(), fd_local,
|
|
|
|
|
// fiber_local.get_output().sock_handle(), fd_peer);
|
2019-03-14 15:24:11 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|