Logo ROOT   6.10/09
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 #include "THttpServer.h"
20 #include "TUrl.h"
21 
22 //////////////////////////////////////////////////////////////////////////
23 // //
24 // TCivetwebWSEngine //
25 // //
26 // Implementation of THttpWSEngine for Civetweb //
27 // //
28 //////////////////////////////////////////////////////////////////////////
29 
30 class TCivetwebWSEngine : public THttpWSEngine {
31 protected:
32  struct mg_connection *fWSconn;
33 
34 public:
35  TCivetwebWSEngine(const char *name, const char *title, struct mg_connection *conn)
36  : THttpWSEngine(name, title), fWSconn(conn)
37  {
38  }
39 
40  virtual ~TCivetwebWSEngine() {}
41 
42  virtual UInt_t GetId() const { return TString::Hash((void *)fWSconn, sizeof(void *)); }
43 
44  virtual void ClearHandle() { fWSconn = 0; }
45 
46  virtual void Send(const void *buf, int len)
47  {
48  if (fWSconn) mg_websocket_write(fWSconn, WEBSOCKET_OPCODE_TEXT, (const char *)buf, len);
49  }
50 };
51 
52 //////////////////////////////////////////////////////////////////////////
53 
54 int websocket_connect_handler(const struct mg_connection *conn, void *)
55 {
56  const struct mg_request_info *request_info = mg_get_request_info(conn);
57  if (request_info == 0) return 1;
58 
59  TCivetweb *engine = (TCivetweb *)request_info->user_data;
60  if (engine == 0) return 1;
61  THttpServer *serv = engine->GetServer();
62  if (serv == 0) return 1;
63 
64  THttpCallArg arg;
65  arg.SetPathAndFileName(request_info->uri); // path and file name
66  arg.SetQuery(request_info->query_string); // query arguments
67  arg.SetWSId(TString::Hash((void *)conn, sizeof(void *)));
68  arg.SetMethod("WS_CONNECT");
69 
70  Bool_t execres = serv->ExecuteHttp(&arg);
71 
72  return execres && !arg.Is404() ? 0 : 1;
73 }
74 
75 //////////////////////////////////////////////////////////////////////////
76 
77 void websocket_ready_handler(struct mg_connection *conn, void *)
78 {
79  const struct mg_request_info *request_info = mg_get_request_info(conn);
80 
81  TCivetweb *engine = (TCivetweb *)request_info->user_data;
82  if (engine == 0) return;
83  THttpServer *serv = engine->GetServer();
84  if (serv == 0) return;
85 
86  THttpCallArg arg;
87  arg.SetPathAndFileName(request_info->uri); // path and file name
88  arg.SetQuery(request_info->query_string); // query arguments
89  arg.SetMethod("WS_READY");
90 
91  arg.SetWSId(TString::Hash((void *)conn, sizeof(void *)));
92  arg.SetWSHandle(new TCivetwebWSEngine("websocket", "title", conn));
93 
94  serv->ExecuteHttp(&arg);
95 }
96 
97 //////////////////////////////////////////////////////////////////////////
98 
99 int websocket_data_handler(struct mg_connection *conn, int, char *data, size_t len, void *)
100 {
101  const struct mg_request_info *request_info = mg_get_request_info(conn);
102 
103  TCivetweb *engine = (TCivetweb *)request_info->user_data;
104  if (engine == 0) return 1;
105  THttpServer *serv = engine->GetServer();
106  if (serv == 0) return 1;
107 
108  THttpCallArg arg;
109  arg.SetPathAndFileName(request_info->uri); // path and file name
110  arg.SetQuery(request_info->query_string); // query arguments
111  arg.SetWSId(TString::Hash((void *)conn, sizeof(void *)));
112  arg.SetMethod("WS_DATA");
113 
114  void *buf = malloc(len + 1); // one byte more for null-termination
115  memcpy(buf, data, len);
116  arg.SetPostData(buf, len);
117 
118  serv->ExecuteHttp(&arg);
119 
120  return 1;
121 }
122 
123 //////////////////////////////////////////////////////////////////////////
124 
125 void websocket_close_handler(const struct mg_connection *conn, void *)
126 {
127  const struct mg_request_info *request_info = mg_get_request_info(conn);
128 
129  TCivetweb *engine = (TCivetweb *)request_info->user_data;
130  if (engine == 0) return;
131  THttpServer *serv = engine->GetServer();
132  if (serv == 0) return;
133 
134  THttpCallArg arg;
135  arg.SetPathAndFileName(request_info->uri); // path and file name
136  arg.SetQuery(request_info->query_string); // query arguments
137  arg.SetWSId(TString::Hash((void *)conn, sizeof(void *)));
138  arg.SetMethod("WS_CLOSE");
139 
140  serv->ExecuteHttp(&arg);
141 }
142 
143 //////////////////////////////////////////////////////////////////////////
144 
145 static int log_message_handler(const struct mg_connection *conn, const char *message)
146 {
147  const struct mg_context *ctx = mg_get_context(conn);
148 
149  TCivetweb *engine = (TCivetweb *)mg_get_user_data(ctx);
150 
151  if (engine) return engine->ProcessLog(message);
152 
153  // provide debug output
154  if ((gDebug > 0) || (strstr(message, "cannot bind to") != 0))
155  fprintf(stderr, "Error in <TCivetweb::Log> %s\n", message);
156 
157  return 0;
158 }
159 
160 //////////////////////////////////////////////////////////////////////////
161 
162 static int begin_request_handler(struct mg_connection *conn, void *)
163 {
164  const struct mg_request_info *request_info = mg_get_request_info(conn);
165 
166  TCivetweb *engine = (TCivetweb *)request_info->user_data;
167  if (engine == 0) return 0;
168  THttpServer *serv = engine->GetServer();
169  if (serv == 0) return 0;
170 
171  THttpCallArg arg;
172 
173  TString filename;
174 
175  Bool_t execres = kTRUE, debug = engine->IsDebugMode();
176 
177  if (!debug && serv->IsFileRequested(request_info->uri, filename)) {
178  if ((filename.Index(".js") != kNPOS) || (filename.Index(".css") != kNPOS)) {
179  Int_t length = 0;
180  char *buf = THttpServer::ReadFileContent(filename.Data(), length);
181  if (buf == 0) {
182  arg.Set404();
183  } else {
185  arg.SetBinData(buf, length);
186  arg.AddHeader("Cache-Control", "max-age=3600");
187  arg.SetZipping(2);
188  }
189  } else {
190  arg.SetFile(filename.Data());
191  }
192  } else {
193  arg.SetPathAndFileName(request_info->uri); // path and file name
194  arg.SetQuery(request_info->query_string); // query arguments
195  arg.SetTopName(engine->GetTopName());
196  arg.SetMethod(request_info->request_method); // method like GET or POST
197  if (request_info->remote_user != 0) arg.SetUserName(request_info->remote_user);
198 
199  TString header;
200  for (int n = 0; n < request_info->num_headers; n++)
201  header.Append(
202  TString::Format("%s: %s\r\n", request_info->http_headers[n].name, request_info->http_headers[n].value));
203  arg.SetRequestHeader(header);
204 
205  const char *len = mg_get_header(conn, "Content-Length");
206  Int_t ilen = len != 0 ? TString(len).Atoi() : 0;
207 
208  if (ilen > 0) {
209  void *buf = malloc(ilen + 1); // one byte more for null-termination
210  Int_t iread = mg_read(conn, buf, ilen);
211  if (iread == ilen)
212  arg.SetPostData(buf, ilen);
213  else
214  free(buf);
215  }
216 
217  if (debug) {
218  TString cont;
219  cont.Append("<title>Civetweb echo</title>");
220  cont.Append("<h1>Civetweb echo</h1>\n");
221 
222  static int count = 0;
223 
224  cont.Append(TString::Format("Request %d:<br/>\n<pre>\n", ++count));
225  cont.Append(TString::Format(" Method : %s\n", arg.GetMethod()));
226  cont.Append(TString::Format(" PathName : %s\n", arg.GetPathName()));
227  cont.Append(TString::Format(" FileName : %s\n", arg.GetFileName()));
228  cont.Append(TString::Format(" Query : %s\n", arg.GetQuery()));
229  cont.Append(TString::Format(" PostData : %ld\n", arg.GetPostDataLength()));
230  if (arg.GetUserName()) cont.Append(TString::Format(" User : %s\n", arg.GetUserName()));
231 
232  cont.Append("</pre><p>\n");
233 
234  cont.Append("Environment:<br/>\n<pre>\n");
235  for (int n = 0; n < request_info->num_headers; n++)
236  cont.Append(
237  TString::Format(" %s = %s\n", request_info->http_headers[n].name, request_info->http_headers[n].value));
238  cont.Append("</pre><p>\n");
239 
240  arg.SetContentType("text/html");
241 
242  arg.SetContent(cont);
243 
244  } else {
245  execres = serv->ExecuteHttp(&arg);
246  }
247  }
248 
249  if (!execres || arg.Is404()) {
250  TString hdr;
251  arg.FillHttpHeader(hdr, "HTTP/1.1");
252  mg_printf(conn, "%s", hdr.Data());
253  } else if (arg.IsFile()) {
254  mg_send_file(conn, (const char *)arg.GetContent());
255  } else {
256 
257  Bool_t dozip = arg.GetZipping() > 0;
258  switch (arg.GetZipping()) {
259  case 2:
260  if (arg.GetContentLength() < 10000) {
261  dozip = kFALSE;
262  break;
263  }
264  case 1:
265  // check if request header has Accept-Encoding
266  dozip = kFALSE;
267  for (int n = 0; n < request_info->num_headers; n++) {
268  TString name = request_info->http_headers[n].name;
269  if (name.Index("Accept-Encoding", 0, TString::kIgnoreCase) != 0) continue;
270  TString value = request_info->http_headers[n].value;
271  dozip = (value.Index("gzip", 0, TString::kIgnoreCase) != kNPOS);
272  break;
273  }
274 
275  break;
276  case 3: dozip = kTRUE; break;
277  }
278 
279  if (dozip) arg.CompressWithGzip();
280 
281  TString hdr;
282  arg.FillHttpHeader(hdr, "HTTP/1.1");
283  mg_printf(conn, "%s", hdr.Data());
284 
285  if (arg.GetContentLength() > 0) mg_write(conn, arg.GetContent(), (size_t)arg.GetContentLength());
286  }
287 
288  // Returning non-zero tells civetweb that our function has replied to
289  // the client, and civetweb should not send client any more data.
290  return 1;
291 }
292 
293 //////////////////////////////////////////////////////////////////////////
294 // //
295 // TCivetweb //
296 // //
297 // http server implementation, based on civetweb embedded server //
298 // It is default kind of engine, created for THttpServer //
299 // //
300 // Following additional options can be specified //
301 // top=foldername - name of top folder, seen in the browser //
302 // thrds=N - use N threads to run civetweb server (default 5) //
303 // auth_file - global authentication file //
304 // auth_domain - domain name, used for authentication //
305 // //
306 // Example: //
307 // new THttpServer("http:8080?top=MyApp&thrds=3"); //
308 // //
309 // Authentication: //
310 // When auth_file and auth_domain parameters are specified, access //
311 // to running http server will be possible only after user //
312 // authentication, using so-call digest method. To generate //
313 // authentication file, htdigest routine should be used: //
314 // //
315 // [shell] htdigest -c .htdigest domain_name user //
316 // //
317 // When creating server, parameters should be: //
318 // //
319 // new THttpServer("http:8080?auth_file=.htdigets&auth_domain=domain_name"); //
320 // //
321 //////////////////////////////////////////////////////////////////////////
322 
324 
325  ////////////////////////////////////////////////////////////////////////////////
326  /// constructor
327 
329  : THttpEngine("civetweb", "compact embedded http server"), fCtx(0), fCallbacks(0), fTopName(), fDebug(kFALSE)
330 {
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 /// destructor
335 
337 {
338  if (fCtx != 0) mg_stop((struct mg_context *)fCtx);
339  if (fCallbacks != 0) free(fCallbacks);
340  fCtx = 0;
341  fCallbacks = 0;
342 }
343 
344 ////////////////////////////////////////////////////////////////////////////////
345 /// process civetweb log message, can be used to detect critical errors
346 
347 Int_t TCivetweb::ProcessLog(const char *message)
348 {
349  if ((gDebug > 0) || (strstr(message, "cannot bind to") != 0)) Error("Log", "%s", message);
350 
351  return 0;
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Creates embedded civetweb server
356 /// As main argument, http port should be specified like "8090".
357 /// Or one can provide combination of ipaddress and portnumber like 127.0.0.1:8090
358 /// Extra parameters like in URL string could be specified after '?' mark:
359 /// thrds=N - there N is number of threads used by the civetweb (default is 5)
360 /// top=name - configure top name, visible in the web browser
361 /// auth_file=filename - authentication file name, created with htdigets utility
362 /// auth_domain=domain - authentication domain
363 /// websocket_timeout=tm - set web sockets timeout in seconds (default 300)
364 /// loopback - bind specified port to loopback 127.0.0.1 address
365 /// debug - enable debug mode, server always returns html page with request info
366 
367 Bool_t TCivetweb::Create(const char *args)
368 {
369  fCallbacks = malloc(sizeof(struct mg_callbacks));
370  memset(fCallbacks, 0, sizeof(struct mg_callbacks));
371  //((struct mg_callbacks *) fCallbacks)->begin_request = begin_request_handler;
372  ((struct mg_callbacks *)fCallbacks)->log_message = log_message_handler;
373  TString sport = "8080", num_threads = "5", websocket_timeout = "300000";
374  TString auth_file, auth_domain, log_file;
375 
376  // extract arguments
377  if ((args != 0) && (strlen(args) > 0)) {
378 
379  // first extract port number
380  sport = "";
381  while ((*args != 0) && (*args != '?') && (*args != '/')) sport.Append(*args++);
382 
383  // than search for extra parameters
384  while ((*args != 0) && (*args != '?')) args++;
385 
386  if (*args == '?') {
387  TUrl url(TString::Format("http://localhost/folder%s", args));
388 
389  if (url.IsValid()) {
390  url.ParseOptions();
391 
392  const char *top = url.GetValueFromOptions("top");
393  if (top != 0) fTopName = top;
394 
395  const char *log = url.GetValueFromOptions("log");
396  if (log != 0) log_file = log;
397 
398  Int_t thrds = url.GetIntValueFromOptions("thrds");
399  if (thrds > 0) num_threads.Form("%d", thrds);
400 
401  const char *afile = url.GetValueFromOptions("auth_file");
402  if (afile != 0) auth_file = afile;
403 
404  const char *adomain = url.GetValueFromOptions("auth_domain");
405  if (adomain != 0) auth_domain = adomain;
406 
407  Int_t wtmout = url.GetIntValueFromOptions("websocket_timeout");
408  if (wtmout > 0) websocket_timeout.Format("%d", wtmout * 1000);
409 
410  if (url.HasOption("debug")) fDebug = kTRUE;
411 
412  if (url.HasOption("loopback") && (sport.Index(":") == kNPOS)) sport = TString("127.0.0.1:") + sport;
413  }
414  }
415  }
416 
417  const char *options[20];
418  int op(0);
419 
420  Info("Create", "Starting HTTP server on port %s", sport.Data());
421 
422  options[op++] = "listening_ports";
423  options[op++] = sport.Data();
424  options[op++] = "num_threads";
425  options[op++] = num_threads.Data();
426  options[op++] = "websocket_timeout_ms";
427  options[op++] = websocket_timeout.Data();
428 
429  if ((auth_file.Length() > 0) && (auth_domain.Length() > 0)) {
430  options[op++] = "global_auth_file";
431  options[op++] = auth_file.Data();
432  options[op++] = "authentication_domain";
433  options[op++] = auth_domain.Data();
434  }
435 
436  if (log_file.Length() > 0) {
437  options[op++] = "error_log_file";
438  options[op++] = log_file.Data();
439  }
440 
441  options[op++] = 0;
442 
443  // Start the web server.
444  fCtx = mg_start((struct mg_callbacks *)fCallbacks, this, options);
445 
446  if (fCtx == 0) return kFALSE;
447 
448  mg_set_request_handler((struct mg_context *)fCtx, "/", begin_request_handler, 0);
449 
450  mg_set_websocket_handler((struct mg_context *)fCtx, "**root.websocket$", websocket_connect_handler,
452 
453  return kTRUE;
454 }
const char * GetFileName() const
returns file name from request URL
Definition: THttpCallArg.h:130
void SetZipping(Int_t kind)
Set kind of content zipping 0 - none 1 - only when supported in request header 2 - if supported and c...
Definition: THttpCallArg.h:185
const char * remote_user
Definition: civetweb.h:68
void SetRequestHeader(const char *h)
set full set of request header
Definition: THttpCallArg.h:100
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:847
const char * uri
Definition: civetweb.h:64
void websocket_ready_handler(struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:77
void SetWSHandle(TNamed *handle)
assign websocket handle with HTTP call
const Ssiz_t kNPOS
Definition: RtypesCore.h:115
This class represents a WWW compatible URL.
Definition: TUrl.h:35
int mg_read(struct mg_connection *conn, void *buf, size_t len)
Definition: civetweb.c:4146
void mg_stop(struct mg_context *ctx)
Definition: civetweb.c:12800
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:587
Basic string class.
Definition: TString.h:129
virtual Bool_t Create(const char *args)
Creates embedded civetweb server As main argument, http port should be specified like "8090"...
Definition: TCivetweb.cxx:367
const char * GetPathName() const
returns path name from request URL
Definition: THttpCallArg.h:127
void SetQuery(const char *q)
set request query
Definition: THttpCallArg.h:85
int Int_t
Definition: RtypesCore.h:41
struct mg_request_info::mg_header http_headers[64]
bool Bool_t
Definition: RtypesCore.h:59
virtual void Send(const void *buf, int len)=0
#define malloc
Definition: civetweb.c:818
const char * GetQuery() const
returns request query (string after ? in request URL)
Definition: THttpCallArg.h:136
Bool_t IsValid() const
Definition: TUrl.h:82
const char * GetTopName() const
Definition: TCivetweb.h:31
void SetContentType(const char *typ)
set content type like "text/xml" or "application/json"
Definition: THttpCallArg.h:141
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition: TString.cxx:616
void SetUserName(const char *n)
set name of authenticated user
Definition: THttpCallArg.h:82
THttpServer * GetServer() const
Returns pointer to THttpServer associated with engine.
Definition: THttpEngine.h:41
void SetContent(const char *c)
Set content directly.
Definition: THttpCallArg.h:176
void SetTopName(const char *topname)
set engine-specific top-name
Definition: THttpCallArg.h:71
void websocket_close_handler(const struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:125
const char * request_method
Definition: civetweb.h:58
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:2345
void SetPostData(void *data, Long_t length)
set data, posted with the request buffer should be allocated with malloc(length+1) call...
void SetPathAndFileName(const char *fullpath)
set complete path of requested http element For instance, it could be "/folder/subfolder/get.bin" Here "/folder/subfolder/" is element path and "get.bin" requested file.
virtual ~TCivetweb()
destructor
Definition: TCivetweb.cxx:336
void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata)
Definition: civetweb.c:9566
void Set404()
mark reply as 404 error - page/request not exists or refused
Definition: THttpCallArg.h:144
Int_t ProcessLog(const char *message)
process civetweb log message, can be used to detect critical errors
Definition: TCivetweb.cxx:347
int websocket_connect_handler(const struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:54
TString & Append(const char *cs)
Definition: TString.h:497
const char * GetUserName() const
return authenticated user name (0 - when no authentication)
Definition: THttpCallArg.h:133
void mg_send_file(struct mg_connection *conn, const char *path)
Definition: civetweb.c:6674
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
Definition: TUrl.cxx:649
int mg_printf(struct mg_connection *conn, const char *fmt,...)
Definition: civetweb.c:4400
void SetBinData(void *data, Long_t length)
set binary data, which will be returned as reply body
virtual UInt_t GetId() const =0
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
Ssiz_t Length() const
Definition: TString.h:388
struct mg_context * mg_start(const struct mg_callbacks *callbacks, void *user_data, const char **options)
Definition: civetweb.c:12875
int mg_write(struct mg_connection *conn, const void *buf, size_t len)
Definition: civetweb.c:4235
Bool_t ExecuteHttp(THttpCallArg *arg)
Execute HTTP request.
const Bool_t kFALSE
Definition: RtypesCore.h:92
const void * GetContent() const
Definition: THttpCallArg.h:208
#define ClassImp(name)
Definition: Rtypes.h:336
const char * mg_get_header(const struct mg_connection *conn, const char *name)
Definition: civetweb.c:2063
static int log_message_handler(const struct mg_connection *conn, const char *message)
Definition: TCivetweb.cxx:145
CIVETWEB_API int mg_websocket_write(struct mg_connection *conn, int opcode, const char *data, size_t data_len)
void * mg_get_user_data(const struct mg_context *ctx)
Definition: civetweb.c:1755
void SetWSId(UInt_t id)
set web-socket id
Definition: THttpCallArg.h:94
void SetMethod(const char *method)
set request method kind like GET or POST
Definition: THttpCallArg.h:68
#define free
Definition: civetweb.c:821
void ParseOptions() const
Parse URL options into a key/value map.
Definition: TUrl.cxx:618
void * user_data
Definition: civetweb.h:81
Bool_t IsDebugMode() const
Definition: TCivetweb.h:33
static const char * GetMimeType(const char *path)
Guess mime type base on file extension.
int websocket_data_handler(struct mg_connection *conn, int, char *data, size_t len, void *)
Definition: TCivetweb.cxx:99
const struct mg_request_info * mg_get_request_info(const struct mg_connection *conn)
Definition: civetweb.c:1972
void AddHeader(const char *name, const char *value)
Set name: value pair to reply header Content-Type field handled separately - one should use SetConten...
static char * ReadFileContent(const char *filename, Int_t &len)
Reads content of file from the disk.
Bool_t IsFile() const
Definition: THttpCallArg.h:200
Bool_t Is404() const
Definition: THttpCallArg.h:199
void SetFile(const char *filename=0)
indicate that http request should response with file content
Definition: THttpCallArg.h:150
R__EXTERN Int_t gDebug
Definition: Rtypes.h:83
bool debug
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1975
virtual void ClearHandle()=0
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:661
const char * query_string
Definition: civetweb.h:66
static int begin_request_handler(struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:162
Int_t GetZipping() const
return kind of content zipping
Definition: THttpCallArg.h:188
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:9586
Long_t GetPostDataLength() const
return length of posted with request data
Definition: THttpCallArg.h:124
const Bool_t kTRUE
Definition: RtypesCore.h:91
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.
Definition: TUrl.cxx:672
const Int_t n
Definition: legend1.C:16
const char * GetMethod() const
returns request method like GET or POST
Definition: THttpCallArg.h:115
Bool_t IsFileRequested(const char *uri, TString &res) const
Check if file is requested, thread safe.
double log(double)
struct mg_context * mg_get_context(const struct mg_connection *conn)
Definition: civetweb.c:1748
Bool_t CompressWithGzip()
compress reply data with gzip compression
void FillHttpHeader(TString &buf, const char *header=0)
fill HTTP header
const char * Data() const
Definition: TString.h:347
Long_t GetContentLength() const
Definition: THttpCallArg.h:206