DABC (Data Acquisition Backbone Core)  2.9.9
Civetweb.cxx
Go to the documentation of this file.
1 // $Id: Civetweb.cxx 4623 2020-11-17 09:22:36Z linev $
2 
3 /************************************************************
4  * The Data Acquisition Backbone Core (DABC) *
5  ************************************************************
6  * Copyright (C) 2009 - *
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
8  * Planckstr. 1, 64291 Darmstadt, Germany *
9  * Contact: http://dabc.gsi.de *
10  ************************************************************
11  * This software can be used under the GPL license *
12  * agreements as stated in LICENSE.txt file *
13  * which is part of the distribution. *
14  ************************************************************/
15 
16 #include "http/Civetweb.h"
17 
18 #include <cstring>
19 
20 http::Civetweb::Civetweb(const std::string &name, dabc::Command cmd) :
21  http::Server(name, cmd),
22  fHttpPort(),
23  fHttpsPort(),
24  fAuthFile(),
25  fAuthDomain(),
26  fSslCertif(),
27  fCtx(0)
28 {
29  fHttpPort = Cfg("port", cmd).AsStr("8090");
30  fHttpsPort = Cfg("ports", cmd).AsStr();
31  fNumThreads = Cfg("thrds", cmd).AsInt(5);
32  fAuthFile = Cfg("auth_file", cmd).AsStr();
33  fAuthDomain = Cfg("auth_domain", cmd).AsStr("dabc@server");
34 
35  // when authentication file specified, one could decide which is default behavior
36  if (!fAuthFile.empty())
37  fDefaultAuth = Cfg("auth_default", cmd).AsBool(true) ? 1 : 0;
38 
39  fSslCertif = Cfg("ssl_certif", cmd).AsStr("");
40  if (!fSslCertif.empty() && (fHttpsPort.length()==0)) fHttpsPort = "443";
41  if (fSslCertif.empty()) fHttpsPort.clear();
42 
43  memset(&fCallbacks, 0, sizeof(fCallbacks));
44 }
45 
47 {
48  if (fCtx!=0) {
49  mg_stop(fCtx);
50  fCtx = 0;
51  }
52 }
53 
54 
56 {
58 
59  std::string sport, sthrds;
60 
61  if (fHttpPort.length()>0) sport = fHttpPort;
62  if (fHttpsPort.length()>0) {
63  if (!sport.empty()) sport.append(",");
64  sport.append(fHttpsPort);
65  }
66  sthrds = dabc::format("%d", fNumThreads);
67 
68  //std::string sport = dabc::format("%d", fHttpPort);
69  DOUT0("Starting HTTP server on port(s) %s", sport.c_str());
70 
71  const char *options[100];
72  int op(0);
73 
74  options[op++] = "listening_ports";
75  options[op++] = sport.c_str();
76  options[op++] = "num_threads";
77  options[op++] = sthrds.c_str();
78 
79  if (!fSslCertif.empty()) {
80  options[op++] = "ssl_certificate";
81  options[op++] = fSslCertif.c_str(); // "ssl_cert.pem";
82  }
83 
84  if (!fAuthFile.empty() && !fAuthDomain.empty()) {
85  options[op++] = "global_auth_file";
86  options[op++] = fAuthFile.c_str();
87  options[op++] = "authentication_domain";
88  options[op++] = fAuthDomain.c_str();
89  }
90  options[op++] = 0;
91 
92  // fCallbacks.begin_request = http::Civetweb::begin_request_handler;
93  fCallbacks.log_message = http::Civetweb::log_message_handler;
94 
95  // Start the web server.
96  fCtx = mg_start(&fCallbacks, this, options);
97 
98  mg_set_request_handler(fCtx,"/",http::Civetweb::begin_request_handler,0);
99 
100  if (fCtx==0) EOUT("Fail to start civetweb on port %s", sport.c_str());
101 }
102 
103 int http::Civetweb::log_message_handler(const struct mg_connection *conn, const char *message)
104 {
105  //const struct mg_context *ctx = mg_get_context(conn);
106  //http::Civetweb* server = (http::Civetweb*) mg_get_user_data(ctx);
107 
108  EOUT("civetweb: %s",message);
109 
110  return 0;
111 }
112 
113 
114 int http::Civetweb::begin_request_handler(struct mg_connection *conn, void* )
115 {
116  const struct mg_request_info *request_info = mg_get_request_info(conn);
117  http::Civetweb* server = (http::Civetweb*) (request_info ? request_info->user_data : 0);
118  if (server==0) return 0;
119 
120  DOUT3("BEGIN_REQ: uri:%s query:%s", request_info->local_uri, request_info->query_string);
121 
122  std::string filename;
123 
124  if (server->IsFileRequested(request_info->local_uri, filename)) {
125  mg_send_file(conn, filename.c_str());
126  return 1;
127  }
128 
129  std::string content_type, content_header, content_str;
130  dabc::Buffer content_bin;
131 
132  if (!server->Process(request_info->local_uri, request_info->query_string,
133  content_type, content_header, content_str, content_bin)) {
134  mg_printf(conn, "HTTP/1.1 404 Not Found\r\n"
135  "Content-Length: 0\r\n"
136  "Connection: close\r\n\r\n");
137  } else
138 
139  if (content_type=="__file__") {
140  mg_send_file(conn, content_str.c_str());
141  } else
142 
143  if (!content_bin.null()) {
144  mg_printf(conn,
145  "HTTP/1.1 200 OK\r\n"
146  "Content-Type: %s\r\n"
147  "%s"
148  "Content-Length: %u\r\n"
149  "Connection: keep-alive\r\n"
150  "\r\n",
151  content_type.c_str(),
152  content_header.c_str(),
153  (unsigned) content_bin.GetTotalSize());
154  mg_write(conn, content_bin.SegmentPtr(), (size_t) content_bin.GetTotalSize());
155  } else {
156 
157  // Send HTTP reply to the client
158  mg_printf(conn,
159  "HTTP/1.1 200 OK\r\n"
160  "Content-Type: %s\r\n"
161  "%s"
162  "Content-Length: %d\r\n" // Always set Content-Length
163  "\r\n"
164  "%s",
165  content_type.c_str(),
166  content_header.c_str(),
167  (int) content_str.length(),
168  content_str.c_str());
169  }
170 
171  // Returning non-zero tells civetweb that our function has replied to
172  // the client, and civetweb should not send client any more data.
173  return 1;
174 }
Reference on memory from memory pool.
Definition: Buffer.h:135
BufferSize_t GetTotalSize() const
Return total size of all buffer segments.
Definition: Buffer.cxx:91
void * SegmentPtr(unsigned n=0) const
Returns pointer on the segment, no any boundary checks.
Definition: Buffer.h:171
Represents command with its arguments.
Definition: Command.h:99
bool AsBool(bool dflt=false) const
Definition: Record.cxx:477
std::string AsStr(const std::string &dflt="") const
Definition: Record.cxx:749
int64_t AsInt(int64_t dflt=0) const
Definition: Record.cxx:501
bool null() const
Returns true if reference contains nullptr.
Definition: Reference.h:151
virtual void OnThreadAssigned()
Definition: Worker.h:392
RecordField Cfg(const std::string &name, Command cmd=nullptr) const
Returns configuration field of specified name Configuration value of specified name searched in follo...
Definition: Worker.cxx:521
Server provides http access to DABC
Definition: Civetweb.h:31
Civetweb(const std::string &name, dabc::Command cmd=nullptr)
Definition: Civetweb.cxx:20
virtual void OnThreadAssigned()
Definition: Civetweb.cxx:55
static int log_message_handler(const struct mg_connection *conn, const char *message)
Definition: Civetweb.cxx:103
std::string fSslCertif
SSL certificate file name in plm format.
Definition: Civetweb.h:38
virtual ~Civetweb()
Definition: Civetweb.cxx:46
std::string fAuthFile
authentication file, generated by htdigest utility
Definition: Civetweb.h:36
int fNumThreads
number of civetweb threads
Definition: Civetweb.h:35
static int begin_request_handler(struct mg_connection *conn, void *)
Definition: Civetweb.cxx:114
struct mg_callbacks fCallbacks
Definition: Civetweb.h:41
std::string fHttpPort
port number for HTTP server
Definition: Civetweb.h:33
std::string fAuthDomain
realm parameter in authentication, "dabc@server" is default
Definition: Civetweb.h:37
std::string fHttpsPort
port number for HTTPS server
Definition: Civetweb.h:34
Server provides http access to DABC
Definition: Server.h:31
int fDefaultAuth
0 - false, 1 - true, -1 - ignored
Definition: Server.h:45
bool IsFileRequested(const char *uri, std::string &fname)
Check if file is requested.
Definition: Server.cxx:207
bool Process(const char *uri, const char *query, std::string &content_type, std::string &content_header, std::string &content_str, dabc::Buffer &content_bin)
Method process different URL requests, should be called from server thread.
Definition: Server.cxx:259
#define DOUT0(args ...)
Definition: logging.h:156
#define DOUT3(args ...)
Definition: logging.h:176
#define EOUT(args ...)
Definition: logging.h:150
std::string format(const char *fmt,...)
Definition: string.cxx:49
Support of HTTP in DABC.
Definition: Civetweb.h:25