17#define HTTPD_MAX_HEADER 8192
22#define HTTP_ERR_WRITE -1
23#define HTTP_ERR_FOPEN -2
24#define HTTP_ERR_FREAD -3
25#define HTTP_NO_HANDLER -4
33struct ci_less :
public std::function<bool (std::string, std::string)>
35 bool operator() (
const std::string& lhs,
const std::string& rhs)
const
37 return _stricmp (lhs.c_str (), rhs.c_str ()) < 0;
43typedef std::map<std::string, std::string, ci_less>
str_pairs;
56 const std::string&
get_path ()
const;
65 const std::string&
get_body ()
const;
67 void add_ohdr (
const std::string& hdr,
const std::string& value);
70 bool has_ihdr (
const std::string& hdr)
const;
73 const std::string&
get_ihdr (
const std::string& hdr)
const;
79 bool has_ohdr (
const std::string& hdr)
const;
82 const std::string&
get_ohdr (
const std::string& hdr)
const;
88 const std::string&
get_qparam (
const std::string& key);
94 const std::string&
get_bparam (
const std::string& key);
100 void respond (
unsigned int code,
const std::string& reason = std::string());
101 void redirect (
const std::string& uri,
unsigned int code = 303);
102 void serve404 (
const char* text = 0);
103 int serve_file (
const std::filesystem::path& file);
104 int serve_shtml (
const std::filesystem::path& file);
112 void run ()
override;
113 void term ()
override;
119 bool parse_request (
const std::string& req);
120 bool parse_headers (
const std::string& hdrs);
123 void process_valid_request ();
124 void process_ssi (
const char* request);
126 void serve401 (
const char* realm);
127 bool should_close ();
132 std::string http_version;
135 std::string part_boundary;
141 bool query_parsed, body_parsed;
148 std::multimap<std::string, user> auth;
156 explicit server (
unsigned short port = 0,
unsigned int maxconn = 0);
159 void add_ohdr (
const std::string& hdr,
const std::string& value);
165 bool add_user (
const char* realm,
const char* username,
const char* pwd);
166 bool remove_user (
const char* realm,
const char* username);
167 void add_realm (
const char* realm,
const char* uri);
169 template <
typename T>
170 void add_var (
const std::string&
name,
const T* addr,
const char* fmt =
nullptr)
173 : std::is_same_v<T, char> ?
VT_CHAR
174 : std::is_same_v<T, std::string> ?
VT_STRING
175 : std::is_same_v<T, short> ?
VT_SHORT
176 : std::is_same_v<T, unsigned short> ?
VT_USHORT
177 : std::is_same_v<T, int> ?
VT_INT
178 : std::is_same_v<T, unsigned int> ?
VT_UINT
179 : std::is_same_v<T, long> ?
VT_LONG
180 : std::is_same_v<T, unsigned long> ?
VT_ULONG
183 add_var (
name, t, addr, fmt);
186 template <
typename T>
187 std::enable_if_t<std::is_floating_point_v<T>> add_var (
const std::string&
name,
const T* addr,
188 const char* fmt =
nullptr,
189 double multiplier = 1.)
195 add_var (
name, t, addr, fmt, multiplier);
198 const std::string
get_var (
const std::string&
name);
203 void name (
const char* nam);
204 void docroot (
const std::string& path);
205 const std::filesystem::path&
docroot ()
const;
206 void add_alias (
const std::string& uri,
const std::string& path);
208 void default_uri (
const std::string&
name)
212 const std::string& default_uri ()
217 static void add_mime_type (
const std::string& ext,
const std::string& type,
bool shtml =
false);
220 bool is_protected (
const std::string& uri, std::string& realm);
221 bool authenticate (
const std::string& realm,
const std::string& user,
const std::string& pwd);
223 friend class connection;
245 bool find_alias (
const std::string& res, std::filesystem::path& path);
246 const std::string&
guess_mimetype (
const std::filesystem::path& fn,
bool& shtml);
248 void add_var (
const std::string&
name,
vtype t,
const void* addr,
const char* fmt =
nullptr,
249 double multiplier = 1.);
262 std::shared_ptr<mlib::criticalsection> in_use;
264 std::map<std::string, handle_info> handlers;
265 std::map<std::string, handle_info> post_handlers;
267 std::map<std::string, std::string> aliases;
276 std::map<std::string, var_info> variables;
284 std::multimap<std::string, user> credentials;
286 std::filesystem::path root;
364 oheaders[hdr] = value;
371 return iheaders.find (hdr) != iheaders.end();
384 return iheaders.at(hdr);
394 lock l (parent.hdr_lock);
395 return parent.out_headers.find (hdr) != parent.out_headers.end()
396 || (oheaders.find(hdr) != oheaders.end());
411 lock l (parent.hdr_lock);
412 auto idx = parent.out_headers.find (hdr);
413 if (idx != parent.out_headers.end ())
416 return oheaders.at (hdr);
429 return qparams.find (key) != qparams.end ();
447 return qparams.at (key);
460 return bparams.find (key) != bparams.end ();
475 static const std::string empty;
479 return bparams.at (key);
535 return varlock.try_enter ();
539server::handle_info::handle_info (
uri_handler h_,
void* info_)
551inline std::ostream& operator<< (std::ostream& os,
const str_pairs& hdrs)
553 for (
auto& hdr : hdrs)
555 os << hdr.first <<
": " << hdr.second <<
"\r\n";
Lightweight inter-thread synchronization.
Definition critsect.h:25
Representation of a HTTP client connection request.
const std::string & get_query() const
Return request query string (everything after '?' and before '#')
Definition httpd.h:338
bool has_ohdr(const std::string &hdr) const
Check if response has a header.
Definition httpd.h:392
void term() override
Finalization function called after run.
Definition httpd.cpp:308
const std::string & get_qparam(const std::string &key)
Return the value of a query parameter.
Definition httpd.h:443
sockstream & out()
Return socket object associated with this connection.
Definition httpd.h:494
const std::string & get_method() const
Return HTTP method (GET, POST, etc.) of the request.
Definition httpd.h:319
int serve_buffer(const BYTE *buffer, size_t sz)
Send the content of a buffer.
Definition httpd.cpp:726
const std::string & get_bparam(const std::string &key)
Return the value of a body parameter.
Definition httpd.h:473
const std::string & get_path() const
Return request target of this connection.
Definition httpd.h:305
int serve_file(const std::filesystem::path &file)
Send the content of a file.
Definition httpd.cpp:784
bool has_ihdr(const std::string &hdr) const
Check if request has a header.
Definition httpd.h:369
void respond(unsigned int code, const std::string &reason=std::string())
Send the beginning of HTTP response.
Definition httpd.cpp:934
bool has_qparam(const std::string &key)
Check if query has a parameter.
Definition httpd.h:425
const std::string & get_ihdr(const std::string &hdr) const
Return the value of a request header.
Definition httpd.h:382
int get_content_length() const
Return size of request body.
Definition httpd.h:487
const std::string & get_body() const
Return request body.
Definition httpd.h:347
bool has_bparam(const std::string &key)
Return true if request contains the given parameter in the request body.
Definition httpd.h:456
void serve404(const char *text=0)
Sends a 404 (page not found) response.
Definition httpd.cpp:442
const str_pairs & get_request_headers() const
Return all request headers.
Definition httpd.h:500
void add_ohdr(const std::string &hdr, const std::string &value)
Add or modify a response header.
Definition httpd.h:362
int serve_shtml(const std::filesystem::path &file)
Send the content of a file, processing any SSI directives.
Definition httpd.cpp:580
const std::string & get_ohdr(const std::string &hdr) const
Return the value of a response header.
Definition httpd.h:409
void redirect(const std::string &uri, unsigned int code=303)
Generate a HTTP redirect response to a new resource.
Definition httpd.cpp:900
connection(sock &socket, server &server)
Protected constructor used by mlib::http::server class to create a new connection thread.
Definition httpd.cpp:94
void run() override
The thread run loop.
Definition httpd.cpp:115
Small multi-threaded HTTP server.
Definition httpd.h:154
void release_varlock()
Release lock on server's variables.
Definition httpd.h:523
bool authenticate(const std::string &realm, const std::string &user, const std::string &pwd)
Verify user credentials for a realm.
Definition httpd.cpp:1268
void aquire_varlock()
Acquire lock on server's variables.
Definition httpd.h:516
int invoke_post_handler(connection &client)
Invoke a user defined handler in response to a POST or PUT request.
Definition httpd.cpp:1316
void add_realm(const char *realm, const char *uri)
Add a new access realm.
Definition httpd.cpp:1173
bool find_alias(const std::string &res, std::filesystem::path &path)
Retrieve the local file path mapped to a resource.
Definition httpd.cpp:1363
int invoke_handler(connection &client)
Invoke a user defined URI handler.
Definition httpd.cpp:1290
connection * make_thread(sock &connection)
Create an new mlib::http::connection object in response to a new client connection request.
Definition httpd.cpp:1065
void name(const char *nam)
Change server name.
Definition httpd.cpp:1049
bool add_user(const char *realm, const char *username, const char *pwd)
Add a new user to a relm or modifies password for an existing user.
Definition httpd.cpp:1186
void remove_ohdr(const std::string &hdr)
Remove a server response header.
Definition httpd.cpp:1088
static void delete_mime_type(const std::string &ext)
Remove a file type from the MIME type table.
Definition httpd.cpp:1160
static void add_mime_type(const std::string &ext, const std::string &type, bool shtml=false)
Add/change content of table matching MIME types to file extensions.
Definition httpd.cpp:1150
~server()
Destructor.
Definition httpd.cpp:1040
server(unsigned short port=0, unsigned int maxconn=0)
Constructor.
Definition httpd.cpp:1030
const std::string get_var(const std::string &name)
Return the current string representation of a variable.
Definition httpd.cpp:1417
const std::string & guess_mimetype(const std::filesystem::path &fn, bool &shtml)
Guess MIME type of a file and if SSI replacement should be enabled based on file extension.
Definition httpd.cpp:1486
void add_post_handler(const std::string &uri, uri_handler func, void *info=0)
Add or modify an POST handler function.
Definition httpd.cpp:1138
void add_handler(const std::string &uri, uri_handler func, void *info=0)
Add or modify an URI handler function.
Definition httpd.cpp:1123
vtype
SSI variables type.
Definition httpd.h:228
@ VT_UINT
unsigned int*
Definition httpd.h:236
@ VT_BOOL
bool*
Definition httpd.h:230
@ VT_FLOAT
float*
Definition httpd.h:239
@ VT_DOUBLE
double*
Definition httpd.h:240
@ VT_USHORT
unsigned short*
Definition httpd.h:234
@ VT_INT
int*
Definition httpd.h:235
@ VT_CHAR
char*
Definition httpd.h:231
@ VT_SHORT
short int*
Definition httpd.h:233
@ VT_UNKNOWN
illegal
Definition httpd.h:229
@ VT_ULONG
unsigned long*
Definition httpd.h:238
@ VT_LONG
long*
Definition httpd.h:237
@ VT_STRING
std::string*
Definition httpd.h:232
void add_ohdr(const std::string &hdr, const std::string &value)
Add or modify a server response header.
Definition httpd.cpp:1078
bool is_protected(const std::string &uri, std::string &realm)
Find the realm with longest matching path that covers an URI.
Definition httpd.cpp:1244
bool try_varlock()
Try to acquire lock on server's variables.
Definition httpd.h:533
const std::filesystem::path & docroot() const
Return current file origin.
Definition httpd.h:509
void add_alias(const std::string &uri, const std::string &path)
Maps a local file path to an URI resource path.
Definition httpd.cpp:1338
Automatic wrapper for critical sections.
Definition critsect.h:69
Encapsulation of a Windows socket.
Definition wsockstream.h:27
tcpserver(unsigned short port, const std::string &name=std::string(), unsigned int max_conn=0)
Opens the socket and initializes the connections table.
Definition tcpserver.cpp:70
void maxconn(unsigned int new_max)
Set maximum number of connections accepted.
Definition tcpserver.cpp:377
Wrapper for a Windows thread.
Definition thread.h:15
virtual const std::string & name() const
Return object's name.
Definition syncbase.h:60
std::function< int(connection &client, void *info)> uri_handler
User defined URL handler function.
Definition httpd.h:46
std::map< std::string, std::string, ci_less > str_pairs
Definition httpd.h:43
Case insensitive comparison function.
Definition httpd.h:34
Definition of tcpserver class.
generic_sockstream< std::iostream > sockstream
Bidirectional socket stream.
Definition wsockstream.h:262