HTTP server functionality is in there.

This commit is contained in:
2022-05-20 17:12:58 -04:00
parent cd3064eb05
commit ca271b8db1
9 changed files with 932 additions and 208 deletions

View File

@@ -31,9 +31,9 @@ private:
int64_t place_id_;
int64_t thread_id_;
// If the request contains an error, the error
// message is stored here.
eng::string error_;
// When we detect that we generated an invalid
// outgoing request, the error is stored here.
eng::string check_fail_;
// If true, verify the server's certificate.
// True is the default.
@@ -59,9 +59,10 @@ private:
// The content as a string, only for POST requests.
eng::string content_;
bool content_assigned_;
private:
void fail(std::string_view error);
void check_fail(std::string_view error);
void send_internal(StreamBuffer *target, bool debug_string) const;
public:
@@ -69,17 +70,6 @@ public:
// All of the fields have empty values.
HttpClientRequest();
// Get request-related fields.
//
const eng::string &error() const { return error_; }
bool verify_certificate() const { return verify_certificate_; }
const eng::string &method() const { return method_; }
const eng::string &host() const { return host_; }
int port() const { return port_; }
const eng::string &path() const { return path_; }
const eng::string &mime_type() const { return mime_type_; }
const eng::string &content() const { return content_; }
// Populate an request-related fields one piece at a time.
// If you pass an invalid value, or if the field is
// already set, the routine will generate an error message
@@ -116,7 +106,10 @@ public:
void set_config(LuaStack &LS0, LuaSlot tab);
// Get or Set the request IDs.
// This class does just stores these.
//
// This class does not use these fields, it just stores
// them as a convenience.
//
int64_t request_id() const { return request_id_; }
int64_t place_id() const { return place_id_; }
int64_t thread_id() const { return thread_id_; }
@@ -125,25 +118,123 @@ public:
void set_thread_id(int64_t thread_id) { thread_id_ = thread_id; }
// Get the network target, eg, "cert:host:port"
//
eng::string target() const;
// Verify that the request is error free and that
// defaults have been set.
//
eng::string check() const;
// Put the request into the stream, assuming HTTP/1.1
//
void send(StreamBuffer *target) const { send_internal(target, false); }
// Serialize and deserialize.
//
void serialize(StreamBuffer *sb) const;
void deserialize(StreamBuffer *sb);
// Get the request as a debug string.
eng::string DebugString();
//
eng::string debug_string();
};
class HttpServerResponse {
private:
// When we detect that our own response is
// invalid, the error is stored here.
//
eng::string check_fail_;
// The status code to send back to the client
// as part of the response status line.
//
int status_;
// Maximum age for the cache-control directive.
//
int max_age_;
// Mime type of the content.
//
eng::string mime_type_;
// Content to send to the client.
//
eng::string content_;
bool content_assigned_;
// If the keep-alive flag is set, then a connection: keep-alive
// header is sent. Otherwise, a connection: close is sent.
// The keep-alive flag cannot be controlled from Lua. It is
// designed to be handled automatically by the server code.
//
bool keep_alive_;
// The protocol is taken from the request.
//
bool http11_;
private:
void check_fail(std::string_view error);
void send_internal(StreamBuffer *target, bool debug_string) const;
public:
// Construct an empty response.
// All of the fields have empty values.
//
HttpServerResponse();
void set_status(int status);
void set_max_age(int max_age);
void set_mime_type(const eng::string &mime_type);
void set_content(const eng::string &content);
void set_status(LuaStack &LS, LuaSlot val);
void set_max_age(LuaStack &LS, LuaSlot val);
void set_mime_type(LuaStack &LS, LuaSlot val);
void set_content(LuaStack &LS, LuaSlot val);
// Set default values.
//
void set_defaults();
// Populate request-related fields from a Lua table.
//
void set_config(LuaStack &LS0, LuaSlot tab);
// Set the keep_alive flag.
//
void set_keep_alive(bool k) { keep_alive_ = k; };
// Set the protocol.
//
void set_http11(bool k) { http11_= k; }
// Store a fail response.
//
void fail(int status, const eng::string &message);
// Verify that the response is error free.
//
eng::string check() const;
// Get the status of the response.
//
int status() const { return status_; }
bool errstatus() const { return (status_ >= 400)&&(status_ <= 599); }
// Put the response into the stream, assuming HTTP/1.1
//
void send(StreamBuffer *target) const { send_internal(target, false); }
// Get the response as a debug string.
//
eng::string debug_string();
};
// HttpParser is used for parsing both requests and responses.
// Stores a status code, an error message, headers, and content.
//
class HttpParser : public eng::nevernew {
protected:
@@ -181,7 +272,10 @@ protected:
// Charset of the content before the content was translated to utf-8.
eng::string charset_;
// The method, GET, HEAD, or POST. (only when parsing requests)
// The protocol: true for HTTP/1.1, false for HTTP/1.0
bool http11_;
// The method: always "GET". (only when parsing requests)
eng::string method_;
// The URL path, not url-encoded. (only when parsing requests)
@@ -216,10 +310,6 @@ protected:
//
void oversized();
// If the status is not in the range 200-299 (OK),
// then discard the content.
void clear_content_on_error();
// Parse a response status line, such as "HTTP/1.1 200 OK"
// returns false if we couldn't parse the whole line.
//
@@ -269,9 +359,23 @@ public:
//
HttpParser();
// Get the parsed status.
// Get the parsed status or error message.
//
int status() const { return status_; }
bool errstatus() const { return (status_ >= 400) && (status_ <= 599); }
eng::string error() const { return error_; }
// Return true if the communication was complete.
//
bool complete() const { return status_ != 0; }
// Get the first component of the path.
// If the path is empty, return defval.
eng::string first_path_component(std::string_view defval) const;
// Get the parsed protocol.
//
bool http11() const { return http11_; }
// Store the parsed fields into a lua table.
//
@@ -301,10 +405,6 @@ public:
int64_t request_id() const { return request_id_; }
void set_request_id(int64_t v) { request_id_ = v; }
// Return true if the communication was complete.
//
bool complete() const { return status_ != 0; }
// Return a debug string.
//
eng::string debug_string() const;