0
0
mirror of https://github.com/OpenVPN/openvpn3.git synced 2024-09-20 20:13:05 +02:00

Refactored web services classes (openvpn/ws) to support HTTP/S servers.

This commit is contained in:
James Yonan 2015-04-19 00:13:20 -06:00 committed by Lev Stipakov
parent a22d7c3d7d
commit 8f535eb76e
No known key found for this signature in database
GPG Key ID: 88670BE258B9C258

View File

@ -50,7 +50,7 @@ namespace openvpn {
rr_content_length = 0;
rr_content_bytes = 0;
rr_chunked.reset();
out_eof = false;
out_state = S_PRE;
}
void reset()
@ -66,7 +66,7 @@ namespace openvpn {
return !halt && ready;
}
const HTTP::Reply& reply() const {
const typename REQUEST_REPLY::State& request_reply() const {
return rr_obj;
}
@ -96,16 +96,27 @@ namespace openvpn {
rr_reset();
}
void http_out_begin()
{
out_state = S_OUT;
}
// Transmit outgoing HTTP, either to SSL object (HTTPS) or TCP socket (HTTP)
void http_out()
{
if (halt)
return;
if ((!outbuf || outbuf->empty()) && !out_eof)
if (out_state == S_PRE)
{
outbuf = http_content_out();
if (ssl_sess)
ssl_down_stack();
return;
}
if ((!outbuf || outbuf->empty()) && out_state == S_OUT)
{
outbuf = parent().base_http_content_out();
if (!outbuf || !outbuf->defined())
out_eof = true;
out_state = S_EOF;
if (content_info.length == CONTENT_INFO::CHUNKED)
outbuf = ChunkedHelper::transmit(outbuf);
}
@ -149,11 +160,16 @@ namespace openvpn {
#if defined(OPENVPN_DEBUG_HTTP)
OPENVPN_LOG(buf_to_string(buf));
#endif
if (parent().link_send(buf))
if (parent().base_link_send(buf))
outbuf->advance(size);
}
}
}
if (out_state == S_EOF && parent().base_send_queue_empty())
{
out_state = S_DONE;
parent().base_http_out_eof();
}
}
void tcp_in(BufferAllocated& b)
@ -165,6 +181,7 @@ namespace openvpn {
buf->swap(b); // take ownership
ssl_sess->write_ciphertext(buf);
ssl_up_stack();
ssl_down_stack();
// In some cases, such as immediately after handshake,
// a write becomes possible after a read has completed.
@ -177,11 +194,13 @@ namespace openvpn {
}
}
// virtual methods
virtual BufferPtr http_content_out() = 0;
virtual void http_headers_received() = 0;
virtual void http_content_in(BufferAllocated& buf) = 0;
// Callback methods in parent:
// BufferPtr base_http_content_out();
// void base_http_headers_received();
// void base_http_content_in(BufferAllocated& buf);
// bool base_link_send(BufferAllocated& buf);
// void base_http_done_handler();
// void base_error_handler(const int errcode, const std::string& err);
// protected member vars
@ -217,10 +236,10 @@ namespace openvpn {
rr_content_bytes += buf.size();
if (config->max_content_bytes && rr_content_bytes > config->max_content_bytes)
{
parent().error_handler(STATUS::E_CONTENT_SIZE, "HTTP content too large");
parent().base_error_handler(STATUS::E_CONTENT_SIZE, "HTTP content too large");
return;
}
http_content_in(buf);
parent().base_http_content_in(buf);
}
}
@ -245,7 +264,7 @@ namespace openvpn {
if ((config->max_header_bytes && rr_header_bytes > config->max_header_bytes)
|| (config->max_headers && rr_obj.headers.size() > config->max_headers))
{
parent().error_handler(STATUS::E_HEADER_SIZE, "HTTP headers too large");
parent().base_error_handler(STATUS::E_HEADER_SIZE, "HTTP headers too large");
return;
}
}
@ -260,12 +279,12 @@ namespace openvpn {
if (rr_content_length == CONTENT_INFO::CHUNKED)
rr_chunked.reset(new ChunkedHelper());
if (!halt)
http_headers_received();
parent().base_http_headers_received();
break;
}
else
{
parent().error_handler(STATUS::E_HTTP, "HTTP headers parse error");
parent().base_error_handler(STATUS::E_HTTP, "HTTP headers parse error");
return;
}
}
@ -292,7 +311,7 @@ namespace openvpn {
done = rr_chunked->receive(*this, buf);
}
if (done)
parent().http_done_handler();
parent().base_http_done_handler();
}
}
@ -302,7 +321,7 @@ namespace openvpn {
while (!halt && ssl_sess->read_ciphertext_ready())
{
BufferPtr buf = ssl_sess->read_ciphertext();
parent().link_send(*buf);
parent().base_link_send(*buf);
}
}
@ -330,7 +349,7 @@ namespace openvpn {
else if (size == SSLConst::SHOULD_RETRY)
break;
else if (size == SSLConst::PEER_CLOSE_NOTIFY)
parent().error_handler(STATUS::E_EOF_SSL, "SSL PEER_CLOSE_NOTIFY");
parent().base_error_handler(STATUS::E_EOF_SSL, "SSL PEER_CLOSE_NOTIFY");
else
throw http_exception("unknown read status from SSL layer");
}
@ -372,7 +391,13 @@ namespace openvpn {
CONTENT_LENGTH_TYPE rr_content_length; // Content-Length in header
ScopedPtr<ChunkedHelper> rr_chunked;
bool out_eof;
enum HTTPOutState {
S_PRE,
S_OUT,
S_EOF,
S_DONE
};
HTTPOutState out_state;
};
}