13#ifndef UNUSED_PARAMETER
14#define UNUSED_PARAMETER(x) (void)(x)
17#ifndef MAX_PARAM_BODY_LENGTH
19#define MAX_PARAM_BODY_LENGTH (1024 * 1024 * 2)
23CivetHandler::handleGet(CivetServer *server,
struct mg_connection *conn)
31CivetHandler::handleGet(CivetServer *server,
44CivetHandler::handlePost(CivetServer *server,
struct mg_connection *conn)
52CivetHandler::handlePost(CivetServer *server,
65CivetHandler::handleHead(CivetServer *server,
struct mg_connection *conn)
73CivetHandler::handleHead(CivetServer *server,
86CivetHandler::handlePut(CivetServer *server,
struct mg_connection *conn)
94CivetHandler::handlePut(CivetServer *server,
107CivetHandler::handlePatch(CivetServer *server,
struct mg_connection *conn)
115CivetHandler::handlePatch(CivetServer *server,
128CivetHandler::handleDelete(CivetServer *server,
struct mg_connection *conn)
136CivetHandler::handleDelete(CivetServer *server,
149CivetHandler::handleOptions(CivetServer *server,
struct mg_connection *conn)
157CivetHandler::handleOptions(CivetServer *server,
170CivetWebSocketHandler::handleConnection(CivetServer *server,
179CivetWebSocketHandler::handleReadyState(CivetServer *server,
188CivetWebSocketHandler::handleData(CivetServer *server,
203CivetWebSocketHandler::handleClose(CivetServer *server,
212CivetServer::requestHandler(
struct mg_connection *conn,
void *cbdata)
215 assert(request_info !=
NULL);
216 CivetServer *me = (CivetServer *)(request_info->
user_data);
218 int http_status_code = -1;
219 bool status_ok =
false;
222 if (me->context ==
NULL)
226 me->connections[conn] = CivetConnection();
229 CivetHandler *handler = (CivetHandler *)cbdata;
233 status_ok = handler->handleGet(me, conn, &http_status_code);
234 if (http_status_code < 0) {
235 status_ok = handler->handleGet(me, conn);
238 status_ok = handler->handlePost(me, conn, &http_status_code);
239 if (http_status_code < 0) {
240 status_ok = handler->handlePost(me, conn);
243 status_ok = handler->handleHead(me, conn, &http_status_code);
244 if (http_status_code < 0) {
245 status_ok = handler->handleHead(me, conn);
248 status_ok = handler->handlePut(me, conn, &http_status_code);
249 if (http_status_code < 0) {
250 status_ok = handler->handlePut(me, conn);
253 status_ok = handler->handleDelete(me, conn, &http_status_code);
254 if (http_status_code < 0) {
255 status_ok = handler->handleDelete(me, conn);
257 }
else if (strcmp(request_info->
request_method,
"OPTIONS") == 0) {
258 status_ok = handler->handleOptions(me, conn, &http_status_code);
259 if (http_status_code < 0) {
260 status_ok = handler->handleOptions(me, conn);
263 status_ok = handler->handlePatch(me, conn, &http_status_code);
264 if (http_status_code < 0) {
265 status_ok = handler->handlePatch(me, conn);
270 if (http_status_code < 0) {
271 http_status_code = status_ok ? 1 : 0;
274 return http_status_code;
278CivetServer::authHandler(
struct mg_connection *conn,
void *cbdata)
281 assert(request_info !=
NULL);
282 CivetServer *me = (CivetServer *)(request_info->
user_data);
286 if (me->context ==
NULL)
290 me->connections[conn] = CivetConnection();
293 CivetAuthHandler *handler = (CivetAuthHandler *)cbdata;
296 return handler->authorize(me, conn) ? 1 : 0;
303CivetServer::webSocketConnectionHandler(
const struct mg_connection *conn,
307 assert(request_info !=
NULL);
308 CivetServer *me = (CivetServer *)(request_info->
user_data);
312 if (me->context ==
NULL)
315 CivetWebSocketHandler *handler = (CivetWebSocketHandler *)cbdata;
318 return handler->handleConnection(me, conn) ? 0 : 1;
325CivetServer::webSocketReadyHandler(
struct mg_connection *conn,
void *cbdata)
328 assert(request_info !=
NULL);
329 CivetServer *me = (CivetServer *)(request_info->
user_data);
333 if (me->context ==
NULL)
336 CivetWebSocketHandler *handler = (CivetWebSocketHandler *)cbdata;
339 handler->handleReadyState(me, conn);
351 assert(request_info !=
NULL);
352 CivetServer *me = (CivetServer *)(request_info->
user_data);
356 if (me->context ==
NULL)
359 CivetWebSocketHandler *handler = (CivetWebSocketHandler *)cbdata;
362 return handler->handleData(me, conn, bits, data, data_len) ? 1 : 0;
369CivetServer::webSocketCloseHandler(
const struct mg_connection *conn,
373 assert(request_info !=
NULL);
374 CivetServer *me = (CivetServer *)(request_info->
user_data);
378 if (me->context ==
NULL)
381 CivetWebSocketHandler *handler = (CivetWebSocketHandler *)cbdata;
384 handler->handleClose(me, conn);
388CivetCallbacks::CivetCallbacks()
390 memset(
this, 0,
sizeof(*
this));
393CivetServer::CivetServer(
const char **options,
394 const struct CivetCallbacks *_callbacks,
395 const void *UserContextIn)
398 struct CivetCallbacks callbacks;
400 UserContext = UserContextIn;
403 callbacks = *_callbacks;
404 userCloseHandler = _callbacks->connection_close;
406 userCloseHandler =
NULL;
408 callbacks.connection_close = closeHandler;
415 char errtxtbuf[256] = {0};
416 mg_start_error_data.
text = errtxtbuf;
419 context =
mg_start2(&mg_start_init_data, &mg_start_error_data);
421 if (context ==
NULL) {
422 std::string exceptionMsg =
423 "null context when constructing CivetServer. "
424 "Possible problem binding to port. Error: ";
425 exceptionMsg += errtxtbuf;
426 throw CivetException(exceptionMsg);
430CivetServer::CivetServer(
const std::vector<std::string> &options,
431 const struct CivetCallbacks *_callbacks,
432 const void *UserContextIn)
435 struct CivetCallbacks callbacks;
437 UserContext = UserContextIn;
440 callbacks = *_callbacks;
441 userCloseHandler = _callbacks->connection_close;
443 userCloseHandler =
NULL;
445 callbacks.connection_close = closeHandler;
447 std::vector<const char *> pointers(options.size() + 1);
448 for (
size_t i = 0; i < options.size(); i++) {
449 pointers[i] = (options[i].c_str());
451 pointers.back() =
NULL;
459 char errtxtbuf[256] = {0};
460 mg_start_error_data.
text = errtxtbuf;
463 context =
mg_start2(&mg_start_init_data, &mg_start_error_data);
465 if (context ==
NULL) {
466 std::string exceptionMsg =
467 "null context when constructing CivetServer. "
468 "Possible problem binding to port. Error: ";
469 exceptionMsg += errtxtbuf;
470 throw CivetException(exceptionMsg);
474CivetServer::~CivetServer()
486 if (me->context ==
NULL)
489 if (me->userCloseHandler) {
490 me->userCloseHandler(conn);
493 me->connections.erase(conn);
498CivetServer::addHandler(
const std::string &uri, CivetHandler *handler)
504CivetServer::addWebSocketHandler(
const std::string &uri,
505 CivetWebSocketHandler *handler)
509 webSocketConnectionHandler,
510 webSocketReadyHandler,
511 webSocketDataHandler,
512 webSocketCloseHandler,
517CivetServer::addAuthHandler(
const std::string &uri, CivetAuthHandler *handler)
523CivetServer::removeHandler(
const std::string &uri)
529CivetServer::removeWebSocketHandler(
const std::string &uri)
536CivetServer::removeAuthHandler(
const std::string &uri)
552 const std::string &cookieName,
553 std::string &cookieValue)
557 char _cookieValue[4096];
562 sizeof(_cookieValue));
565 cookieValue.append(_cookieValue);
572 const std::string &headerName)
581 assert(request_info !=
NULL);
586CivetServer::urlDecode(
const char *src,
588 bool is_form_url_encoded)
590 urlDecode(src, strlen(src), dst, is_form_url_encoded);
594CivetServer::urlDecode(
const char *src,
597 bool is_form_url_encoded)
600 std::vector<char> buf(src_len + 1);
602 static_cast<int>(src_len),
604 static_cast<int>(buf.size()),
605 is_form_url_encoded);
608 throw std::out_of_range(
"");
611 dst.assign(buf.begin(), buf.begin() + r);
620 const char *formParams =
NULL;
621 const char *queryString =
NULL;
624 CivetServer *me = (CivetServer *)(ri->
user_data);
627 CivetConnection &conobj = me->connections[conn];
631 if (conobj.postData.empty()) {
635 int r =
mg_read(conn, buf,
sizeof(buf));
638 conobj.postData.push_back(
'\0');
641 || ((conobj.postData.size() + r)
643 conobj.postData.assign(1,
'\0');
646 conobj.postData.insert(conobj.postData.end(), buf, buf + r);
648 conobj.postData.clear();
653 if (!conobj.postData.empty()) {
655 formParams = &conobj.postData[0];
666 bool get_param_success =
false;
667 if (formParams !=
NULL) {
669 getParam(formParams, strlen(formParams),
name, dst, occurrence);
671 if (!get_param_success && queryString !=
NULL) {
673 getParam(queryString, strlen(queryString),
name, dst, occurrence);
676 return get_param_success;
680CivetServer::getParam(
const char *data,
687 int r =
mg_get_var2(data, data_len,
name, buf,
sizeof(buf), occurrence);
692 }
else if (r == -2) {
694 std::vector<char> vbuf(
sizeof(buf) * 2);
697 data, data_len,
name, &vbuf[0], vbuf.size(), occurrence);
699 dst.assign(vbuf.begin(), vbuf.begin() + r);
701 }
else if (r != -2) {
705 vbuf.resize(vbuf.size() * 2);
716 std::string postdata;
718 int r =
mg_read(conn, buf,
sizeof(buf));
720 postdata.append(buf, r);
721 r =
mg_read(conn, buf,
sizeof(buf));
728CivetServer::urlEncode(
const char *src, std::string &dst,
bool append)
730 urlEncode(src, strlen(src), dst,
append);
734CivetServer::urlEncode(
const char *src,
742 for (; src_len > 0; src++, src_len--) {
747 char buf[2] = {*src,
'\0'};
751 throw std::out_of_range(
"");
759CivetServer::getListeningPorts()
761 std::vector<struct mg_server_port> server_ports = getListeningPortsFull();
763 std::vector<int> ports(server_ports.size());
764 for (
size_t i = 0; i < server_ports.size(); i++) {
765 ports[i] = server_ports[i].port;
771std::vector<struct mg_server_port>
772CivetServer::getListeningPortsFull()
774 std::vector<struct mg_server_port> server_ports(8);
777 static_cast<int>(server_ports.size()),
779 if (size <
static_cast<int>(server_ports.size())) {
780 server_ports.resize(size < 0 ? 0 : size);
783 server_ports.resize(server_ports.size() * 2);
#define UNUSED_PARAMETER(x)
#define MAX_PARAM_BODY_LENGTH
CIVETWEB_API void mg_lock_context(struct mg_context *ctx)
CIVETWEB_API void mg_lock_connection(struct mg_connection *conn)
CIVETWEB_API void * mg_get_user_data(const struct mg_context *ctx)
CIVETWEB_API struct mg_context * mg_start2(struct mg_init_data *init, struct mg_error_data *error)
CIVETWEB_API void mg_unlock_connection(struct mg_connection *conn)
CIVETWEB_API const char * mg_get_header(const struct mg_connection *conn, const char *name)
CIVETWEB_API void mg_set_websocket_handler(struct mg_context *ctx, const char *uri, mg_websocket_connect_handler connect_handler, mg_websocket_ready_handler ready_handler, mg_websocket_data_handler data_handler, mg_websocket_close_handler close_handler, void *cbdata)
CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
CIVETWEB_API int mg_get_var2(const char *data, size_t data_len, const char *name, char *dst, size_t dst_len, size_t occurrence)
CIVETWEB_API void mg_unlock_context(struct mg_context *ctx)
CIVETWEB_API void mg_stop(struct mg_context *ctx)
CIVETWEB_API int mg_get_cookie(const char *cookie_header, const char *var_name, char *dst, size_t dst_size)
CIVETWEB_API int mg_get_server_ports(const struct mg_context *ctx, int size, struct mg_server_port *ports)
CIVETWEB_API struct mg_context * mg_get_context(const struct mg_connection *conn)
CIVETWEB_API const struct mg_request_info * mg_get_request_info(const struct mg_connection *conn)
CIVETWEB_API void mg_set_auth_handler(struct mg_context *ctx, const char *uri, mg_authorization_handler handler, void *cbdata)
CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata)
CIVETWEB_API int mg_read(struct mg_connection *conn, void *buf, size_t len)
CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len)
CURL_EXTERN int void curl_formget_callback append
const struct mg_callbacks * callbacks
const char ** configuration_options
const char * request_method
const char * query_string