我正在尝试通过修改Boost ASIO 示例来编写一个简单的 HTTPS 服务器。它可以工作,但问题是它为来自客户端的每个请求建立了一个安全连接,这极大地减慢了通信速度。
我知道 HTTPS 服务器应该使用 Keep-Alive 连接。但我不知道如何扩展上述示例来做到这一点。就我而言,情况非常简单,因为我总是有 1:1 连接,所以不需要会话管理,总是只有一个有效会话。
我使用两种 HTTP 响应:
std::string HTTPS::createResponse(status_type status)
{
std::stringstream response;
response<<statusCodeToString(status);
response<<"Content-Length: "<<statusToContentString(status).size()<<"\r\n";
response<<"Content-Type: text/html\r\n\r\n";
response<<statusToContentString(status);
return response.str();
}
std::string HTTPS::createResponse(status_type status, const std::string &data)
{
std::stringstream response;
response<<"HTTP/1.1 200 OK\r\n";
response<<"Content-Length: "<<data.size()<<"\r\n";
response<<"Content-Type: text/plain\r\n\r\n";
response<<data;
return response.str();
}
std::string HLSProxyServerSSL::statusCodeToString(status_type status)
{
static const char ok_s[] =
"HTTP/1.1 200 OK\r\n";
static const char created_s[] =
"HTTP/1.1 201 Created\r\n";
static const char accepted_s[] =
"HTTP/1.1 202 Accepted\r\n";
static const char no_content_s[] =
"HTTP/1.1 204 No Content\r\n";
static const char multiple_choices_s[] =
"HTTP/1.1 300 Multiple Choices\r\n";
static const char moved_permanently_s[] =
"HTTP/1.1 301 Moved Permanently\r\n";
static const char moved_temporarily_s[] =
"HTTP/1.1 302 Moved Temporarily\r\n";
static const char not_modified_s[] =
"HTTP/1.1 304 Not Modified\r\n";
static const char bad_request_s[] =
"HTTP/1.1 400 Bad Request\r\n";
static const char unauthorized_s[] =
"HTTP/1.1 401 Unauthorized\r\n";
static const char forbidden_s[] =
"HTTP/1.1 403 Forbidden\r\n";
static const char not_found_s[] =
"HTTP/1.1 404 Not Found\r\n";
static const char not_supported_s[] =
"HTTP/1.1 405 Method Not Supported\r\n";
static const char not_acceptable_s[] =
"HTTP/1.1 406 Method Not Acceptable\r\n";
static const char internal_server_error_s[] =
"HTTP/1.1 500 Internal Server Error\r\n";
static const char not_implemented_s[] =
"HTTP/1.1 501 Not Implemented\r\n";
static const char bad_gateway_s[] =
"HTTP/1.1 502 Bad Gateway\r\n";
static const char service_unavailable_s[] =
"HTTP/1.1 503 Service Unavailable\r\n";
switch (status)
{
case ok:
return ok_s;
case created:
return created_s;
case accepted:
return accepted_s;
case no_content:
return no_content_s;
case multiple_choices:
return multiple_choices_s;
case moved_permanently:
return moved_permanently_s;
case moved_temporarily:
return moved_temporarily_s;
case not_modified:
return not_modified_s;
case bad_request:
return bad_request_s;
case unauthorized:
return unauthorized_s;
case forbidden:
return forbidden_s;
case not_found:
return not_found_s;
case not_supported:
return not_supported_s;
case not_acceptable:
return not_acceptable_s;
case internal_server_error:
return internal_server_error_s;
case not_implemented:
return not_implemented_s;
case bad_gateway:
return bad_gateway_s;
case service_unavailable:
return service_unavailable_s;
default:
return internal_server_error_s;
}
}
std::string HLSProxyServerSSL::statusToContentString(status_type status)
{
static const char ok_s[] = "";
static const char created_s[] =
"<html>"
"<head><title>Created</title></head>"
"<body><h1>201 Created</h1></body>"
"</html>";
static const char accepted_s[] =
"<html>"
"<head><title>Accepted</title></head>"
"<body><h1>202 Accepted</h1></body>"
"</html>";
static const char no_content_s[] =
"<html>"
"<head><title>No Content</title></head>"
"<body><h1>204 Content</h1></body>"
"</html>";
static const char multiple_choices_s[] =
"<html>"
"<head><title>Multiple Choices</title></head>"
"<body><h1>300 Multiple Choices</h1></body>"
"</html>";
static const char moved_permanently_s[] =
"<html>"
"<head><title>Moved Permanently</title></head>"
"<body><h1>301 Moved Permanently</h1></body>"
"</html>";
static const char moved_temporarily_s[] =
"<html>"
"<head><title>Moved Temporarily</title></head>"
"<body><h1>302 Moved Temporarily</h1></body>"
"</html>";
static const char not_modified_s[] =
"<html>"
"<head><title>Not Modified</title></head>"
"<body><h1>304 Not Modified</h1></body>"
"</html>";
static const char bad_request_s[] =
"<html>"
"<head><title>Bad Request</title></head>"
"<body><h1>400 Bad Request</h1></body>"
"</html>";
static const char unauthorized_s[] =
"<html>"
"<head><title>Unauthorized</title></head>"
"<body><h1>401 Unauthorized</h1></body>"
"</html>";
static const char forbidden_s[] =
"<html>"
"<head><title>Forbidden</title></head>"
"<body><h1>403 Forbidden</h1></body>"
"</html>";
static const char not_found_s[] =
"<html>"
"<head><title>Not Found</title></head>"
"<body><h1>404 Not Found</h1></body>"
"</html>";
static const char not_supported_s[] =
"<html>"
"<head><title>Method Not Supported</title></head>"
"<body><h1>Method Not Supported</h1></body>"
"</html>";
static const char not_acceptable_s[] =
"<html>"
"<head><title>Request Not Acceptable</title></head>"
"<body><h1>Request Not Acceptable</h1></body>"
"</html>";
static const char internal_server_error_s[] =
"<html>"
"<head><title>Internal Server Error</title></head>"
"<body><h1>500 Internal Server Error</h1></body>"
"</html>";
static const char not_implemented_s[] =
"<html>"
"<head><title>Not Implemented</title></head>"
"<body><h1>501 Not Implemented</h1></body>"
"</html>";
static const char bad_gateway_s[] =
"<html>"
"<head><title>Bad Gateway</title></head>"
"<body><h1>502 Bad Gateway</h1></body>"
"</html>";
static const char service_unavailable_s[] =
"<html>"
"<head><title>Service Unavailable</title></head>"
"<body><h1>503 Service Unavailable</h1></body>"
"</html>";
switch (status)
{
case ok:
return ok_s;
case created:
return created_s;
case accepted:
return accepted_s;
case no_content:
return no_content_s;
case multiple_choices:
return multiple_choices_s;
case moved_permanently:
return moved_permanently_s;
case moved_temporarily:
return moved_temporarily_s;
case not_modified:
return not_modified_s;
case bad_request:
return bad_request_s;
case unauthorized:
return unauthorized_s;
case forbidden:
return forbidden_s;
case not_found:
return not_found_s;
case not_supported:
return not_supported_s;
case not_acceptable:
return not_acceptable_s;
case internal_server_error:
return internal_server_error_s;
case not_implemented:
return not_implemented_s;
case bad_gateway:
return bad_gateway_s;
case service_unavailable:
return service_unavailable_s;
default:
return internal_server_error_s;
}
}
我相信回复是可以的,但请检查一下——这不是我的专业领域。
现在的通信流程如下:
1、服务器开始接受一个新的连接——创建一个会话,绑定等待传入握手请求的异步接受器。
2,如果发生传入握手,则服务器在第 1 点创建的会话上开始握手。
3、一旦握手完成,就处理传入的消息
会话握手句柄如下。它读取一个 HTTP 命令并对其进行处理。我故意不关心标头的其余部分,因为从服务器端来看,只有 GET 命令是有效的——服务器就像一个简单的重新发送者一样工作。
void SSLSession::handleHandshake(const boost::system::error_code& error)
{
__log_print(LOG_INFO, "SSLSession", "handleHandshake");
if (!error)
{
boost::asio::async_read_until(_socket, _data, "\r\n", boost::bind(&SSLSession::handleHttpRequestLine, this, _1));
}
else
{
delete this;
}
}
void SSLSession::handleHttpRequestLine(boost::system::error_code ec)
{
std::string method, uri, version;
if (!ec)
{
char sp1, sp2, cr, lf;
std::istream is(&_data);
is.unsetf(std::ios_base::skipws);
is >> method >> sp1 >> uri >> sp2 >> version >> cr >> lf;
}
handleHttpRequest(method, uri);
}
所以我的问题是,我该如何修改方法:
void SSLSession::handleHandshake(const boost::system::error_code& error)
不仅要开始收听一个命令,还要继续收听对该会话有效的 GET 命令?我尝试添加另一个
boost::asio::async_read_until(_socket, _data, "\r\n", boost::bind(&SSLSession::handleHttpRequestLine, this, _1));
调用handleHttpRequest(method, uri);
方法结束,但我遇到了死锁......我相信它一定是微不足道的,但我迷失在所有这些异步接受器和处理程序中......