Logo ROOT   6.18/05
Reference Guide
TCivetweb.cxx
Go to the documentation of this file.
1// $Id$
2// Author: Sergey Linev 21/12/2013
3
4/*************************************************************************
5 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TCivetweb.h"
13
14#include "../civetweb/civetweb.h"
15
16#include <stdlib.h>
17#include <string.h>
18
19#ifdef _MSC_VER
20#include <windows.h>
21#include <tchar.h>
22#endif
23
24#include "THttpServer.h"
25#include "THttpWSEngine.h"
26#include "TUrl.h"
27
28
29
30//////////////////////////////////////////////////////////////////////////
31// //
32// TCivetwebWSEngine //
33// //
34// Implementation of THttpWSEngine for Civetweb //
35// //
36//////////////////////////////////////////////////////////////////////////
37
38class TCivetwebWSEngine : public THttpWSEngine {
39protected:
40 struct mg_connection *fWSconn;
41
42 /// True websocket requires extra thread to parallelize sending
43 Bool_t SupportSendThrd() const override { return kTRUE; }
44
45public:
46 TCivetwebWSEngine(struct mg_connection *conn) : THttpWSEngine(), fWSconn(conn) {}
47
48 virtual ~TCivetwebWSEngine() = default;
49
50 UInt_t GetId() const override { return TString::Hash((void *)&fWSconn, sizeof(void *)); }
51
52 void ClearHandle(Bool_t terminate) override
53 {
54 if (fWSconn && terminate)
56 fWSconn = nullptr;
57 }
58
59 void Send(const void *buf, int len) override
60 {
61 if (fWSconn)
62 mg_websocket_write(fWSconn, MG_WEBSOCKET_OPCODE_BINARY, (const char *)buf, len);
63 }
64
65 /////////////////////////////////////////////////////////
66 /// Special method to send binary data with text header
67 /// For normal websocket it is two separated operation, for other engines could be combined together,
68 /// but emulates as two messages on client side
69 void SendHeader(const char *hdr, const void *buf, int len) override
70 {
71 if (fWSconn) {
72 mg_websocket_write(fWSconn, MG_WEBSOCKET_OPCODE_TEXT, hdr, strlen(hdr));
73 mg_websocket_write(fWSconn, MG_WEBSOCKET_OPCODE_BINARY, (const char *)buf, len);
74 }
75 }
76
77 void SendCharStar(const char *str) override
78 {
79 if (fWSconn)
80 mg_websocket_write(fWSconn, MG_WEBSOCKET_OPCODE_TEXT, str, strlen(str));
81 }
82};
83
84//////////////////////////////////////////////////////////////////////////
85
86int websocket_connect_handler(const struct mg_connection *conn, void *)
87{
88 const struct mg_request_info *request_info = mg_get_request_info(conn);
89 if (!request_info)
90 return 1;
91
92 TCivetweb *engine = (TCivetweb *)request_info->user_data;
93 if (!engine || engine->IsTerminating())
94 return 1;
95 THttpServer *serv = engine->GetServer();
96 if (!serv)
97 return 1;
98
99 auto arg = std::make_shared<THttpCallArg>();
100 arg->SetPathAndFileName(request_info->local_uri); // path and file name
101 arg->SetQuery(request_info->query_string); // query arguments
102 arg->SetWSId(TString::Hash((void *)&conn, sizeof(void *)));
103 arg->SetMethod("WS_CONNECT");
104
105 Bool_t execres = serv->ExecuteWS(arg, kTRUE, kTRUE);
106
107 return execres && !arg->Is404() ? 0 : 1;
108}
109
110//////////////////////////////////////////////////////////////////////////
111
112void websocket_ready_handler(struct mg_connection *conn, void *)
113{
114 const struct mg_request_info *request_info = mg_get_request_info(conn);
115
116 TCivetweb *engine = (TCivetweb *)request_info->user_data;
117 if (!engine || engine->IsTerminating())
118 return;
119 THttpServer *serv = engine->GetServer();
120 if (!serv)
121 return;
122
123 auto arg = std::make_shared<THttpCallArg>();
124 arg->SetPathAndFileName(request_info->local_uri); // path and file name
125 arg->SetQuery(request_info->query_string); // query arguments
126 arg->SetMethod("WS_READY");
127
128 // delegate ownership to the arg, id will be automatically set
129 arg->CreateWSEngine<TCivetwebWSEngine>(conn);
130
131 serv->ExecuteWS(arg, kTRUE, kTRUE);
132}
133
134//////////////////////////////////////////////////////////////////////////
135
136int websocket_data_handler(struct mg_connection *conn, int code, char *data, size_t len, void *)
137{
138 const struct mg_request_info *request_info = mg_get_request_info(conn);
139
140 // do not handle empty data
141 if (len == 0)
142 return 1;
143
144 TCivetweb *engine = (TCivetweb *)request_info->user_data;
145 if (!engine || engine->IsTerminating())
146 return 1;
147 THttpServer *serv = engine->GetServer();
148 if (!serv)
149 return 1;
150
151 std::string *conn_data = (std::string *) mg_get_user_connection_data(conn);
152
153 // this is continuation of the request
154 if (!(code & 0x80)) {
155 if (!conn_data) {
156 conn_data = new std::string(data,len);
158 } else {
159 conn_data->append(data,len);
160 }
161 return 1;
162 }
163
164 auto arg = std::make_shared<THttpCallArg>();
165 arg->SetPathAndFileName(request_info->local_uri); // path and file name
166 arg->SetQuery(request_info->query_string); // query arguments
167 arg->SetWSId(TString::Hash((void *)&conn, sizeof(void *)));
168 arg->SetMethod("WS_DATA");
169
170 if (conn_data) {
171 mg_set_user_connection_data(conn, nullptr);
172 conn_data->append(data,len);
173 arg->SetPostData(std::move(*conn_data));
174 delete conn_data;
175 } else {
176 arg->SetPostData(std::string(data,len));
177 }
178
179 serv->ExecuteWS(arg, kTRUE, kTRUE);
180
181 return 1;
182}
183
184//////////////////////////////////////////////////////////////////////////
185
186void websocket_close_handler(const struct mg_connection *conn, void *)
187{
188 const struct mg_request_info *request_info = mg_get_request_info(conn);
189
190 TCivetweb *engine = (TCivetweb *)request_info->user_data;
191 if (!engine || engine->IsTerminating())
192 return;
193 THttpServer *serv = engine->GetServer();
194 if (!serv)
195 return;
196
197 auto arg = std::make_shared<THttpCallArg>();
198 arg->SetPathAndFileName(request_info->local_uri); // path and file name
199 arg->SetQuery(request_info->query_string); // query arguments
200 arg->SetWSId(TString::Hash((void *)&conn, sizeof(void *)));
201 arg->SetMethod("WS_CLOSE");
202
203 serv->ExecuteWS(arg, kTRUE, kFALSE); // do not wait for result of execution
204}
205
206//////////////////////////////////////////////////////////////////////////
207
208static int log_message_handler(const struct mg_connection *conn, const char *message)
209{
210 const struct mg_context *ctx = mg_get_context(conn);
211
212 TCivetweb *engine = (TCivetweb *)mg_get_user_data(ctx);
213
214 if (engine)
215 return engine->ProcessLog(message);
216
217 // provide debug output
218 if ((gDebug > 0) || (strstr(message, "cannot bind to") != 0))
219 fprintf(stderr, "Error in <TCivetweb::Log> %s\n", message);
220
221 return 0;
222}
223
224//////////////////////////////////////////////////////////////////////////
225
226static int begin_request_handler(struct mg_connection *conn, void *)
227{
228 const struct mg_request_info *request_info = mg_get_request_info(conn);
229
230 TCivetweb *engine = (TCivetweb *)request_info->user_data;
231 if (!engine || engine->IsTerminating())
232 return 0;
233 THttpServer *serv = engine->GetServer();
234 if (!serv)
235 return 0;
236
237 auto arg = std::make_shared<THttpCallArg>();
238
239 TString filename;
240
241 Bool_t execres = kTRUE, debug = engine->IsDebugMode();
242
243 if (!debug && serv->IsFileRequested(request_info->local_uri, filename)) {
244 if ((filename.Length() > 3) && ((filename.Index(".js") != kNPOS) || (filename.Index(".css") != kNPOS))) {
245 std::string buf = THttpServer::ReadFileContent(filename.Data());
246 if (buf.empty()) {
247 arg->Set404();
248 } else {
249 arg->SetContentType(THttpServer::GetMimeType(filename.Data()));
250 arg->SetContent(std::move(buf));
251 if (engine->GetMaxAge() > 0)
252 arg->AddHeader("Cache-Control", TString::Format("max-age=%d", engine->GetMaxAge()));
253 else
254 arg->AddNoCacheHeader();
255 arg->SetZipping();
256 }
257 } else {
258 arg->SetFile(filename.Data());
259 }
260 } else {
261 arg->SetPathAndFileName(request_info->local_uri); // path and file name
262 arg->SetQuery(request_info->query_string); // query arguments
263 arg->SetTopName(engine->GetTopName());
264 arg->SetMethod(request_info->request_method); // method like GET or POST
265 if (request_info->remote_user)
266 arg->SetUserName(request_info->remote_user);
267
268 TString header;
269 for (int n = 0; n < request_info->num_headers; n++)
270 header.Append(
271 TString::Format("%s: %s\r\n", request_info->http_headers[n].name, request_info->http_headers[n].value));
272 arg->SetRequestHeader(header);
273
274 const char *len = mg_get_header(conn, "Content-Length");
275 Int_t ilen = len ? TString(len).Atoi() : 0;
276
277 if (ilen > 0) {
278 std::string buf;
279 buf.resize(ilen);
280 Int_t iread = mg_read(conn, (void *) buf.data(), ilen);
281 if (iread == ilen)
282 arg->SetPostData(std::move(buf));
283 }
284
285 if (debug) {
286 TString cont;
287 cont.Append("<title>Civetweb echo</title>");
288 cont.Append("<h1>Civetweb echo</h1>\n");
289
290 static int count = 0;
291
292 cont.Append(TString::Format("Request %d:<br/>\n<pre>\n", ++count));
293 cont.Append(TString::Format(" Method : %s\n", arg->GetMethod()));
294 cont.Append(TString::Format(" PathName : %s\n", arg->GetPathName()));
295 cont.Append(TString::Format(" FileName : %s\n", arg->GetFileName()));
296 cont.Append(TString::Format(" Query : %s\n", arg->GetQuery()));
297 cont.Append(TString::Format(" PostData : %ld\n", arg->GetPostDataLength()));
298 if (arg->GetUserName())
299 cont.Append(TString::Format(" User : %s\n", arg->GetUserName()));
300
301 cont.Append("</pre><p>\n");
302
303 cont.Append("Environment:<br/>\n<pre>\n");
304 for (int n = 0; n < request_info->num_headers; n++)
305 cont.Append(
306 TString::Format(" %s = %s\n", request_info->http_headers[n].name, request_info->http_headers[n].value));
307 cont.Append("</pre><p>\n");
308
309 arg->SetContentType("text/html");
310
311 arg->SetContent(cont);
312
313 } else {
314 execres = serv->ExecuteHttp(arg);
315 }
316 }
317
318 if (!execres || arg->Is404()) {
319 std::string hdr = arg->FillHttpHeader("HTTP/1.1");
320 mg_printf(conn, "%s", hdr.c_str());
321 } else if (arg->IsFile()) {
322 filename = (const char *)arg->GetContent();
323#ifdef _MSC_VER
324 // resolve Windows links which are not supported by civetweb
325 const int BUFSIZE = 2048;
326 TCHAR Path[BUFSIZE];
327
328 auto hFile = CreateFile(filename.Data(), // file to open
329 GENERIC_READ, // open for reading
330 FILE_SHARE_READ, // share for reading
331 NULL, // default security
332 OPEN_EXISTING, // existing file only
333 FILE_ATTRIBUTE_NORMAL, // normal file
334 NULL); // no attr. template
335
336 if( hFile != INVALID_HANDLE_VALUE) {
337 auto dwRet = GetFinalPathNameByHandle( hFile, Path, BUFSIZE, VOLUME_NAME_DOS );
338 // produced file name may include \\? symbols, which are indicating long file name
339 if(dwRet < BUFSIZE)
340 filename = Path;
341 CloseHandle(hFile);
342 }
343#endif
344 mg_send_file(conn, filename.Data());
345 } else {
346
347 Bool_t dozip = kFALSE;
348 switch (arg->GetZipping()) {
349 case THttpCallArg::kNoZip: dozip = kFALSE; break;
351 if (arg->GetContentLength() < 10000) break;
353 // check if request header has Accept-Encoding
354 for (int n = 0; n < request_info->num_headers; n++) {
355 TString name = request_info->http_headers[n].name;
356 if (name.Index("Accept-Encoding", 0, TString::kIgnoreCase) != 0)
357 continue;
358 TString value = request_info->http_headers[n].value;
359 dozip = (value.Index("gzip", 0, TString::kIgnoreCase) != kNPOS);
360 break;
361 }
362
363 break;
364 case THttpCallArg::kZipAlways: dozip = kTRUE; break;
365 }
366
367 if (dozip)
368 arg->CompressWithGzip();
369
370 std::string hdr = arg->FillHttpHeader("HTTP/1.1");
371 mg_printf(conn, "%s", hdr.c_str());
372
373 if (arg->GetContentLength() > 0)
374 mg_write(conn, arg->GetContent(), (size_t)arg->GetContentLength());
375 }
376
377 // Returning non-zero tells civetweb that our function has replied to
378 // the client, and civetweb should not send client any more data.
379 return 1;
380}
381
382//////////////////////////////////////////////////////////////////////////
383// //
384// TCivetweb //
385// //
386// http server implementation, based on civetweb embedded server //
387// It is default kind of engine, created for THttpServer //
388// Currently v1.8 from https://github.com/civetweb/civetweb is used //
389// //
390// Following additional options can be specified: //
391// top=foldername - name of top folder, seen in the browser //
392// thrds=N - use N threads to run civetweb server (default 5) //
393// auth_file - global authentication file //
394// auth_domain - domain name, used for authentication //
395// //
396// Example: //
397// new THttpServer("http:8080?top=MyApp&thrds=3"); //
398// //
399// Authentication: //
400// When auth_file and auth_domain parameters are specified, access //
401// to running http server will be possible only after user //
402// authentication, using so-call digest method. To generate //
403// authentication file, htdigest routine should be used: //
404// //
405// [shell] htdigest -c .htdigest domain_name user //
406// //
407// When creating server, parameters should be: //
408// //
409// new THttpServer("http:8080?auth_file=.htdigets&auth_domain=domain_name"); //
410// //
411//////////////////////////////////////////////////////////////////////////
412
413////////////////////////////////////////////////////////////////////////////////
414/// constructor
415
417 : THttpEngine("civetweb", "compact embedded http server"), fCtx(nullptr), fCallbacks(nullptr), fTopName(),
418 fDebug(kFALSE), fTerminating(kFALSE), fOnlySecured(only_secured)
419{
420}
421
422////////////////////////////////////////////////////////////////////////////////
423/// destructor
424
426{
427 if (fCtx && !fTerminating)
428 mg_stop((struct mg_context *)fCtx);
429 if (fCallbacks)
431}
432
433////////////////////////////////////////////////////////////////////////////////
434/// process civetweb log message, can be used to detect critical errors
435
436Int_t TCivetweb::ProcessLog(const char *message)
437{
438 if ((gDebug > 0) || (strstr(message, "cannot bind to") != 0))
439 Error("Log", "%s", message);
440
441 return 0;
442}
443
444////////////////////////////////////////////////////////////////////////////////
445/// Creates embedded civetweb server
446/// As main argument, http port should be specified like "8090".
447/// Or one can provide combination of ipaddress and portnumber like 127.0.0.1:8090
448/// Extra parameters like in URL string could be specified after '?' mark:
449/// thrds=N - there N is number of threads used by the civetweb (default is 10)
450/// top=name - configure top name, visible in the web browser
451/// ssl_certificate=filename - SSL certificate, see docs/OpenSSL.md from civetweb
452/// auth_file=filename - authentication file name, created with htdigets utility
453/// auth_domain=domain - authentication domain
454/// websocket_timeout=tm - set web sockets timeout in seconds (default 300)
455/// websocket_disable - disable web sockets handling (default enabled)
456/// bind - ip address to bind server socket
457/// loopback - bind specified port to loopback 127.0.0.1 address
458/// debug - enable debug mode, server always returns html page with request info
459/// log=filename - configure civetweb log file
460/// max_age=value - configures "Cache-Control: max_age=value" http header for all file-related requests, default 3600
461/// nocache - try to fully disable cache control for file requests
462/// Examples:
463/// http:8080?websocket_disable
464/// http:7546?thrds=30&websocket_timeout=20
465
466Bool_t TCivetweb::Create(const char *args)
467{
468 fCallbacks = malloc(sizeof(struct mg_callbacks));
469 memset(fCallbacks, 0, sizeof(struct mg_callbacks));
470 //((struct mg_callbacks *) fCallbacks)->begin_request = begin_request_handler;
471 ((struct mg_callbacks *)fCallbacks)->log_message = log_message_handler;
472 TString sport = IsSecured() ? "8480s" : "8080", num_threads = "10", websocket_timeout = "300000";
473 TString auth_file, auth_domain, log_file, ssl_cert, max_age;
474 Bool_t use_ws = kTRUE;
475
476 // extract arguments
477 if (args && (strlen(args) > 0)) {
478
479 // first extract port number
480 sport = "";
481 while ((*args != 0) && (*args != '?') && (*args != '/'))
482 sport.Append(*args++);
483 if (IsSecured() && (sport.Index("s")==kNPOS)) sport.Append("s");
484
485 // than search for extra parameters
486 while ((*args != 0) && (*args != '?'))
487 args++;
488
489 if (*args == '?') {
490 TUrl url(TString::Format("http://localhost/folder%s", args));
491
492 if (url.IsValid()) {
493 url.ParseOptions();
494
495 const char *top = url.GetValueFromOptions("top");
496 if (top)
497 fTopName = top;
498
499 const char *log = url.GetValueFromOptions("log");
500 if (log)
501 log_file = log;
502
503 Int_t thrds = url.GetIntValueFromOptions("thrds");
504 if (thrds > 0)
505 num_threads.Form("%d", thrds);
506
507 const char *afile = url.GetValueFromOptions("auth_file");
508 if (afile)
509 auth_file = afile;
510
511 const char *adomain = url.GetValueFromOptions("auth_domain");
512 if (adomain)
513 auth_domain = adomain;
514
515 const char *sslc = url.GetValueFromOptions("ssl_cert");
516 if (sslc)
517 ssl_cert = sslc;
518
519 Int_t wtmout = url.GetIntValueFromOptions("websocket_timeout");
520 if (wtmout > 0) {
521 websocket_timeout.Format("%d", wtmout * 1000);
522 use_ws = kTRUE;
523 }
524
525 if (url.HasOption("websocket_disable"))
526 use_ws = kFALSE;
527
528 if (url.HasOption("debug"))
529 fDebug = kTRUE;
530
531 if (url.HasOption("loopback") && (sport.Index(":") == kNPOS))
532 sport = TString("127.0.0.1:") + sport;
533
534 if (url.HasOption("bind") && (sport.Index(":") == kNPOS)) {
535 const char *addr = url.GetValueFromOptions("bind");
536 if (addr && strlen(addr))
537 sport = TString(addr) + ":" + sport;
538 }
539
540 if (GetServer() && url.HasOption("cors")) {
541 const char *cors = url.GetValueFromOptions("cors");
542 GetServer()->SetCors(cors && *cors ? cors : "*");
543 }
544
545 if (url.HasOption("nocache"))
546 fMaxAge = 0;
547
548 if (url.HasOption("max_age"))
549 fMaxAge = url.GetIntValueFromOptions("max_age");
550
551 max_age.Form("%d", fMaxAge);
552 }
553 }
554 }
555
556 const char *options[20];
557 int op(0);
558
559 Info("Create", "Starting HTTP server on port %s", sport.Data());
560
561 options[op++] = "listening_ports";
562 options[op++] = sport.Data();
563 options[op++] = "num_threads";
564 options[op++] = num_threads.Data();
565
566 if (use_ws) {
567 options[op++] = "websocket_timeout_ms";
568 options[op++] = websocket_timeout.Data();
569 }
570
571 if ((auth_file.Length() > 0) && (auth_domain.Length() > 0)) {
572 options[op++] = "global_auth_file";
573 options[op++] = auth_file.Data();
574 options[op++] = "authentication_domain";
575 options[op++] = auth_domain.Data();
576 }
577
578 if (log_file.Length() > 0) {
579 options[op++] = "error_log_file";
580 options[op++] = log_file.Data();
581 }
582
583 if (ssl_cert.Length() > 0) {
584 options[op++] = "ssl_certificate";
585 options[op++] = ssl_cert.Data();
586 } else if (IsSecured()) {
587 Error("Create", "No SSL certificate file configured");
588 }
589
590 if (max_age.Length() > 0) {
591 options[op++] = "static_file_max_age";
592 options[op++] = max_age.Data();
593 }
594
595 options[op++] = nullptr;
596
597 // Start the web server.
598 fCtx = mg_start((struct mg_callbacks *)fCallbacks, this, options);
599
600 if (!fCtx)
601 return kFALSE;
602
603 mg_set_request_handler((struct mg_context *)fCtx, "/", begin_request_handler, nullptr);
604
605 if (use_ws)
606 mg_set_websocket_handler((struct mg_context *)fCtx, "**root.websocket$", websocket_connect_handler,
608
609 return kTRUE;
610}
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
int websocket_connect_handler(const struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:86
static int begin_request_handler(struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:226
static int log_message_handler(const struct mg_connection *conn, const char *message)
Definition: TCivetweb.cxx:208
int websocket_data_handler(struct mg_connection *conn, int code, char *data, size_t len, void *)
Definition: TCivetweb.cxx:136
void websocket_close_handler(const struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:186
void websocket_ready_handler(struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:112
char name[80]
Definition: TGX11.cxx:109
#define INVALID_HANDLE_VALUE
Definition: TMapFile.cxx:84
double log(double)
#define BUFSIZE
#define free
Definition: civetweb.c:1539
int mg_printf(struct mg_connection *conn, const char *fmt,...)
Definition: civetweb.c:6979
void mg_send_file(struct mg_connection *conn, const char *path)
Definition: civetweb.c:9841
void mg_set_user_connection_data(struct mg_connection *conn, void *data)
Definition: civetweb.c:3450
struct mg_context * mg_start(const struct mg_callbacks *callbacks, void *user_data, const char **options)
Definition: civetweb.c:18342
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)
Definition: civetweb.c:13386
const char * mg_get_header(const struct mg_connection *conn, const char *name)
Definition: civetweb.c:4016
int mg_write(struct mg_connection *conn, const void *buf, size_t len)
Definition: civetweb.c:6755
const struct mg_request_info * mg_get_request_info(const struct mg_connection *conn)
Definition: civetweb.c:3745
void * mg_get_user_connection_data(const struct mg_connection *conn)
Definition: civetweb.c:3459
#define malloc
Definition: civetweb.c:1536
int mg_read(struct mg_connection *conn, void *buf, size_t len)
Definition: civetweb.c:6655
void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata)
Definition: civetweb.c:13364
struct mg_context * mg_get_context(const struct mg_connection *conn)
Definition: civetweb.c:3436
void mg_stop(struct mg_context *ctx)
Definition: civetweb.c:18256
void * mg_get_user_data(const struct mg_context *ctx)
Definition: civetweb.c:3443
CIVETWEB_API int mg_websocket_write(struct mg_connection *conn, int opcode, const char *data, size_t data_len)
@ MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE
Definition: civetweb.h:840
@ MG_WEBSOCKET_OPCODE_BINARY
Definition: civetweb.h:839
@ MG_WEBSOCKET_OPCODE_TEXT
Definition: civetweb.h:838
Bool_t IsTerminating() const
Definition: TCivetweb.h:42
Int_t GetMaxAge() const
Definition: TCivetweb.h:46
const char * GetTopName() const
Definition: TCivetweb.h:38
void * fCtx
! civetweb context
Definition: TCivetweb.h:20
TCivetweb(Bool_t only_secured=kFALSE)
constructor
Definition: TCivetweb.cxx:416
Int_t fMaxAge
! max-age parameter
Definition: TCivetweb.h:26
Int_t ProcessLog(const char *message)
process civetweb log message, can be used to detect critical errors
Definition: TCivetweb.cxx:436
TString fTopName
! name of top item
Definition: TCivetweb.h:22
Bool_t fTerminating
! server doing shutdown and not react on requests
Definition: TCivetweb.h:24
Bool_t IsSecured() const
Definition: TCivetweb.h:30
Bool_t IsDebugMode() const
Definition: TCivetweb.h:40
virtual ~TCivetweb()
destructor
Definition: TCivetweb.cxx:425
Bool_t fDebug
! debug mode
Definition: TCivetweb.h:23
void * fCallbacks
! call-back table for civetweb webserver
Definition: TCivetweb.h:21
virtual Bool_t Create(const char *args)
Creates embedded civetweb server As main argument, http port should be specified like "8090".
Definition: TCivetweb.cxx:466
THttpServer * GetServer() const
Returns pointer to THttpServer associated with engine.
Definition: THttpEngine.h:40
Bool_t IsFileRequested(const char *uri, TString &res) const
Check if file is requested, thread safe.
Bool_t ExecuteWS(std::shared_ptr< THttpCallArg > &arg, Bool_t external_thrd=kFALSE, Bool_t wait_process=kFALSE)
Execute WS request.
Bool_t ExecuteHttp(std::shared_ptr< THttpCallArg > arg)
Execute HTTP request.
void SetCors(const std::string &domain="*")
Enable CORS header to ProcessRequests() responses Specified location (typically "*") add as "Access-C...
Definition: THttpServer.h:97
static char * ReadFileContent(const char *filename, Int_t &len)
Reads content of file from the disk.
static const char * GetMimeType(const char *path)
Guess mime type base on file extension.
virtual void SendCharStar(const char *str)
Envelope for sending string via the websocket.
virtual UInt_t GetId() const =0
virtual void SendHeader(const char *hdr, const void *buf, int len)=0
virtual Bool_t SupportSendThrd() const
Indicate if engine require extra thread to complete postponed thread operation.
Definition: THttpWSEngine.h:48
virtual void Send(const void *buf, int len)=0
virtual void ClearHandle(Bool_t)=0
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1921
const char * Data() const
Definition: TString.h:364
@ kIgnoreCase
Definition: TString.h:263
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition: TString.cxx:638
TString & Append(const char *cs)
Definition: TString.h:559
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
This class represents a WWW compatible URL.
Definition: TUrl.h:35
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
Definition: TUrl.cxx:646
Bool_t IsValid() const
Definition: TUrl.h:82
Int_t GetIntValueFromOptions(const char *key) const
Return a value for a given key from the URL options as an Int_t, a missing key returns -1.
Definition: TUrl.cxx:658
void ParseOptions() const
Parse URL options into a key/value map.
Definition: TUrl.cxx:615
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.
Definition: TUrl.cxx:669
const Int_t n
Definition: legend1.C:16
const char * value
Definition: civetweb.h:140
const char * name
Definition: civetweb.h:139
struct mg_header http_headers[MG_MAX_HEADERS]
Definition: civetweb.h:170
const char * local_uri
Definition: civetweb.h:149
void * user_data
Definition: civetweb.h:166
const char * request_method
Definition: civetweb.h:146
const char * query_string
Definition: civetweb.h:156
void * conn_data
Definition: civetweb.h:167
const char * remote_user
Definition: civetweb.h:158