///////////////////////////////////////////////////////// // // HTTP Implementation. // // This is a fairly limited implementation of HTTP. // // It only supports HTTP 1.1 // // It only supports GET, POST, and HEAD. // ///////////////////////////////////////////////////////// #ifndef HTTP_HPP #define HTTP_HPP #include "eng-malloc.hpp" #include "wrap-string.hpp" #include "wrap-vector.hpp" #include "wrap-map.hpp" #include "luastack.hpp" #include "streambuffer.hpp" class HttpRequest : public eng::nevernew { private: // If the request contains an error, the error // message is stored here. eng::string error_; // If true, verify the server's certificate. // True is the default. bool verify_certificate_; // Method: GET, HEAD, POST, etc. eng::string method_; // The hostname. This is used both for DNS lookup, // and to create an HTTP Host header. eng::string host_; // Port number. int port_; // The path is always UTF-8. This field should not be urlencoded. // Instead, urlencoding is done automatically when the request // is sent. Should not include protocol, host, port, or parameters. eng::string path_; // If params is nonempty, then we will add URL parameters // to the URL. The contents of the params field should not be // urlencoded, the urlencoding is done automatically when the // request is sent. eng::map params_; private: void send_internal(StreamBuffer *target, bool debug_string) const; public: // Construct an empty HTTP request. // All of the fields have empty values. HttpRequest(); // Get 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_; } // Get the network target, eg, "cert:host:port" eng::string target() const; // Populate an HTTP request a piece at a time. // If you pass an invalid value, or if the field is // already set, the routine will generate an error message // and store it in the error field. In that case, the set // will not happen. If there's already an error in the error // field, it will not be overwritten. void set_verify_certificate(bool flag); void set_method(const eng::string &method); void set_host(const eng::string &host); void set_port(int port); void set_url(const eng::string &url); void set_param(const eng::string &key, const eng::string &value); // Same as above, but using Lua values. void set_verify_certificate(LuaStack &LS, LuaSlot val); void set_method(LuaStack &LS, LuaSlot val); void set_host(LuaStack &LS, LuaSlot val); void set_port(LuaStack &LS, LuaSlot val); void set_url(LuaStack &LS, LuaSlot val); void set_param(LuaStack &LS, LuaSlot key, LuaSlot val); void set_params(LuaStack &LS, LuaSlot tab); // Set default values for any fields that should have // defaults. This must be done after setting regular // values. void set_defaults(); // Verify that the request is error free and that // defaults have been set. eng::string check() const; // Populate an HTTP request from a Lua table. void set_config(LuaStack &LS0, LuaSlot tab); // Put the request into the stream, assuming HTTP/1.1 void send(StreamBuffer *target) const { send_internal(target, false); } // Get the request as a debug string. eng::string DebugString(); }; class HttpResponse { private: // The HTTP response code. int response_code_; // If the HTTP response contains an error, the // error message is stored here. If the HTTP response // is a success such as "200 OK" or "201 Created", this // is the empty string, not "OK" or "Created". eng::string error_; // The length in bytes of the entire response. // May be zero, which means that the response // was so garbled that we couldn't determine the length. bool response_length_; // MIME type of the content. eng::string mime_type_; // The content as string. eng::string content_; private: public: // Construct a blank response. HttpResponse(); // Store an error message. This is used when the client detects an error, // such as a DNS lookup fail, a connection failed, an SSL negotiation // failed, or the like. Clears the content, leaving only the error // and response code. void fail(int response_code, const eng::string &error); // Parse the HTTP response. Note that the response is not // removed from the StreamBuffer, which is always unmodified. // If you want to remove the response from the StreamBuffer, see // response_length. void parse(const StreamBuffer *sb); // Convert the HTTP response to a lua table. void store(LuaStack &LS, LuaSlot tab); }; #endif // HTTP_HPP