2022-03-29 16:50:26 -04:00
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// 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"
|
2022-04-15 17:24:07 -04:00
|
|
|
#include "wrap-map.hpp"
|
2022-03-29 16:50:26 -04:00
|
|
|
#include "luastack.hpp"
|
2022-04-15 17:24:07 -04:00
|
|
|
#include "streambuffer.hpp"
|
2022-03-29 16:50:26 -04:00
|
|
|
|
2022-04-15 17:24:07 -04:00
|
|
|
class HttpRequest : public eng::nevernew {
|
|
|
|
|
private:
|
|
|
|
|
// If the request contains an error, the error
|
|
|
|
|
// message is stored here.
|
|
|
|
|
eng::string error_;
|
2022-03-29 16:50:26 -04:00
|
|
|
|
2022-04-15 17:24:07 -04:00
|
|
|
// 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.
|
2022-03-29 16:50:26 -04:00
|
|
|
eng::string host_;
|
2022-04-15 17:24:07 -04:00
|
|
|
|
|
|
|
|
// Port number.
|
2022-03-29 16:50:26 -04:00
|
|
|
int port_;
|
|
|
|
|
|
2022-04-15 17:24:07 -04:00
|
|
|
// 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<eng::string, eng::string> params_;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void send_internal(StreamBuffer *target, bool debug_string) const;
|
|
|
|
|
|
2022-03-29 16:50:26 -04:00
|
|
|
public:
|
2022-04-15 17:24:07 -04:00
|
|
|
// 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.
|
2022-03-29 16:50:26 -04:00
|
|
|
eng::string mime_type_;
|
2022-04-15 17:24:07 -04:00
|
|
|
|
|
|
|
|
// The content as string.
|
2022-03-29 16:50:26 -04:00
|
|
|
eng::string content_;
|
2022-04-15 17:24:07 -04:00
|
|
|
|
|
|
|
|
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);
|
2022-03-29 16:50:26 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif // HTTP_HPP
|