23 #ifndef DABC_WITHOUT_ZLIB
30 const char *extension;
32 const char *mime_type;
33 } builtin_mime_types[] = {
34 {
".xml", 4,
"text/xml"},
35 {
".json", 5,
"application/json"},
36 {
".bin", 4,
"application/x-binary"},
37 {
".gif", 4,
"image/gif"},
38 {
".jpg", 4,
"image/jpeg"},
39 {
".png", 4,
"image/png"},
40 {
".html", 5,
"text/html"},
41 {
".htm", 4,
"text/html"},
42 {
".shtm", 5,
"text/html"},
43 {
".shtml", 6,
"text/html"},
44 {
".css", 4,
"text/css"},
45 {
".js", 3,
"application/x-javascript"},
46 {
".ico", 4,
"image/x-icon"},
47 {
".jpeg", 5,
"image/jpeg"},
48 {
".svg", 4,
"image/svg+xml"},
49 {
".txt", 4,
"text/plain"},
50 {
".torrent", 8,
"application/x-bittorrent"},
51 {
".wav", 4,
"audio/x-wav"},
52 {
".mp3", 4,
"audio/x-mp3"},
53 {
".mid", 4,
"audio/mid"},
54 {
".m3u", 4,
"audio/x-mpegurl"},
55 {
".ogg", 4,
"application/ogg"},
56 {
".ram", 4,
"audio/x-pn-realaudio"},
57 {
".xslt", 5,
"application/xml"},
58 {
".xsl", 4,
"application/xml"},
59 {
".ra", 3,
"audio/x-pn-realaudio"},
60 {
".doc", 4,
"application/msword"},
61 {
".exe", 4,
"application/octet-stream"},
62 {
".zip", 4,
"application/x-zip-compressed"},
63 {
".xls", 4,
"application/excel"},
64 {
".tgz", 4,
"application/x-tar-gz"},
65 {
".tar", 4,
"application/x-tar"},
66 {
".gz", 3,
"application/x-gunzip"},
67 {
".arj", 4,
"application/x-arj-compressed"},
68 {
".rar", 4,
"application/x-arj-compressed"},
69 {
".rtf", 4,
"application/rtf"},
70 {
".pdf", 4,
"application/pdf"},
71 {
".swf", 4,
"application/x-shockwave-flash"},
72 {
".mpg", 4,
"video/mpeg"},
73 {
".webm", 5,
"video/webm"},
74 {
".mpeg", 5,
"video/mpeg"},
75 {
".mov", 4,
"video/quicktime"},
76 {
".mp4", 4,
"video/mp4"},
77 {
".m4v", 4,
"video/x-m4v"},
78 {
".asf", 4,
"video/x-ms-asf"},
79 {
".avi", 4,
"video/x-msvideo"},
80 {
".bmp", 4,
"image/bmp"},
81 {
".ttf", 4,
"application/x-font-ttf"},
85 int path_len = strlen(path);
87 for (
int i = 0; builtin_mime_types[i].extension != NULL; i++) {
88 if (path_len <= builtin_mime_types[i].ext_len)
continue;
89 const char* ext = path + (path_len - builtin_mime_types[i].ext_len);
90 if (strcmp(ext, builtin_mime_types[i].extension) == 0) {
91 return builtin_mime_types[i].mime_type;
100 dabc::Worker(MakePair(name)),
108 const char* dabcsys = getenv(
"DABCSYS");
120 std::string urlopt = cmd.
GetStr(
"urlopt");
121 if (!urlopt.empty()) {
133 const char* jsrootsys = getenv(
"JSROOTSYS");
143 fAutoLoad =
Cfg(
"AutoLoad", cmd).
AsStr(
"httpsys/scripts/dabc.js;httpsys/scripts/gauge.js;");
157 const std::string &absprefix,
158 const std::string &nameprefix,
159 const std::string &nameprefixrepl)
162 fLocations.back().fFilePath = filepath;
163 fLocations.back().fAbsPrefix = absprefix;
164 fLocations.back().fNamePrefix = nameprefix;
165 fLocations.back().fNamePrefixRepl = nameprefixrepl;
171 if ((fname==0) || (*fname==0))
return false;
175 while (*fname != 0) {
178 const char* next = strpbrk(fname,
"/\\");
179 if (next==0)
return true;
182 if ((next == fname + 2) && (*fname ==
'.') && (*(fname+1) ==
'.')) {
184 if (level<0)
return false;
189 if ((next == fname + 1) && (*fname ==
'.')) {
209 if ((uri==0) || (strlen(uri)==0))
return false;
211 std::string fname = uri;
213 for (
unsigned n=0;n<fLocations.size();n++) {
214 size_t pos = fname.rfind(fLocations[n].fAbsPrefix);
215 if (pos!=std::string::npos) {
216 fname.erase(0, pos + fLocations[n].fAbsPrefix.length() - 1);
217 if (!VerifyFilePath(fname.c_str()))
return false;
218 res = fLocations[n].fFilePath + fname;
229 const char* rslash = strrchr(uri,
'/');
233 pathname.append(uri, rslash - uri);
234 if (pathname ==
"/") pathname.clear();
242 if (fDefaultAuth<0)
return false;
244 std::string pathname, fname;
246 if (IsFileRequested(uri, fname))
return fDefaultAuth > 0;
248 ExtractPathAndFile(uri, pathname, fname);
254 if (res<0) res = fDefaultAuth;
260 std::string& content_type,
261 std::string& content_header,
262 std::string& content_str,
266 std::string pathname, filename, query;
268 content_header.clear();
274 DOUT2(
"http::Server::Process uri %s path %s file %s type %s", uri ? uri :
"---", pathname.c_str(), filename.c_str(), content_type.c_str());
276 if (content_type ==
"__error__")
return false;
278 if (content_type ==
"__user__") {
279 content_str = pathname;
280 if (filename.empty()) content_str +=
"main.htm";
281 else content_str += filename;
282 content_type =
"__file__";
283 IsFileRequested(content_str.c_str(), content_str);
287 if (filename ==
"draw.htm") {
288 content_str = fJsRootSys +
"/files/draw.htm";
289 content_type =
"__file__";
295 if (filename.empty() || (filename==
"main.htm") || (filename==
"index.htm")) {
296 content_str = fJsRootSys +
"/files/online.htm";
297 content_type =
"__file__";
301 for (
unsigned n=0;n<fLocations.size();n++)
302 if (!fLocations[n].fNamePrefix.empty() && (filename.find(fLocations[n].fNamePrefix)==0)) {
303 size_t len = fLocations[n].fNamePrefix.length();
304 if ((filename.length()<=len) || (filename[len]==
'.'))
continue;
305 filename.erase(0, len);
306 if (!VerifyFilePath(filename.c_str()))
return false;
307 content_str = fLocations[n].fFilePath + fLocations[n].fNamePrefixRepl + filename;
308 content_type =
"__file__";
312 if (_query!=0) query = _query;
314 if (filename ==
"execute") {
315 if (pathname.empty())
return false;
321 content_type =
"application/json";
327 if (filename.empty())
return false;
329 bool iszipped =
false;
331 if ((filename.length() > 3) && (filename.rfind(
".gz") == filename.length()-3)) {
332 filename.resize(filename.length()-3);
336 if ((filename ==
"h.xml") || (filename ==
"h.json")) {
338 bool isxml = (filename ==
"h.xml");
342 if (!fAutoLoad.empty()) cmd.
AddHeader(
"_autoload", fAutoLoad);
343 if (!fTopTitle.empty()) cmd.
AddHeader(
"_toptitle", fTopTitle);
344 if (!fBrowser.empty()) cmd.
AddHeader(
"_browser", fBrowser);
345 if (!fLayout.empty()) cmd.
AddHeader(
"_layout", fLayout);
346 if (!fDrawItem.empty() && (pathname==
"/")) {
350 if (fMonitoring >= 100)
351 cmd.
AddHeader(
"_monitoring", std::to_string(fMonitoring),
false);
357 content_str = cmd.
GetStr(
"astext");
360 content_type =
"text/xml";
361 content_str = std::string(
"<?xml version=\"1.0\"?>\n<dabc>\n") + content_str +
"</dabc>";
363 content_type =
"application/json";
366 }
else if (filename ==
"multiget.json") {
368 content_type =
"application/json";
370 std::string opt = query;
373 if (opt.find(
"items=")==0) {
374 std::size_t separ = opt.find(
"&");
375 if (separ == std::string::npos) separ = opt.length();
376 std::string items = opt.substr(6, separ-6);
377 opt = opt.erase(0, separ+1);
378 DOUT3(
"MULTIGET path %s items=%s rest:%s", pathname.c_str(), items.c_str(), opt.c_str());
381 std::vector<std::string> arr = field.
AsStrVect();
386 for (
unsigned n=0;n<arr.size();n++) {
387 if (n>0) content_str.append(
",");
395 content_str.append(
dabc::format(
"{ \"item\": \"%s\", \"result\":", arr[n].c_str()));
397 if (content_bin.
null())
398 content_str.append(
"null");
402 content_str.append(
"}");
407 content_str.append(
"]");
410 content_str =
"null";
421 content_type = cmd.
GetStr(
"content_type");
423 if (content_type.empty())
424 content_type = GetMimeType(filename.c_str());
433 if (content_bin.
null()) content_str = cmd.
GetStr(
"StringReply");
437 if (content_bin.
null() && (content_str.length()==0)) {
438 DOUT2(
"Is empty buffer is error for uri %s ?", uri);
444 #ifdef DABC_WITHOUT_ZLIB
445 DOUT0(
"It is requested to compress buffer, but ZLIB is not available!!!");
448 unsigned long objlen = 0;
451 if (!content_bin.
null()) {
455 objlen = content_str.length();
456 objptr = (Bytef*) content_str.c_str();
459 unsigned long objcrc = crc32(0, NULL, 0);
460 objcrc = crc32(objcrc, objptr, objlen);
463 unsigned long zipbuflen = 18 + compressBound(objlen);
464 if (zipbuflen<512) zipbuflen = 512;
465 void* zipbuf = malloc(zipbuflen);
468 EOUT(
"Fail to allocate %lu bytes memory !!!", zipbuflen);
472 char *bufcur = (
char*) zipbuf;
492 int res = compress((Bytef*)bufcur-2, &zipbuflen, objptr, objlen);
494 EOUT(
"Fail to compress buffer with ZLIB");
502 bufcur += (zipbuflen - 6);
505 *bufcur++ = objcrc & 0xff;
506 *bufcur++ = (objcrc >> 8) & 0xff;
507 *bufcur++ = (objcrc >> 16) & 0xff;
508 *bufcur++ = (objcrc >> 24) & 0xff;
510 *bufcur++ = objlen & 0xff;
511 *bufcur++ = (objlen >> 8) & 0xff;
512 *bufcur++ = (objlen >> 16) & 0xff;
513 *bufcur++ = (objlen >> 24) & 0xff;
518 content_header.append(
"Content-Encoding: gzip\r\n");
520 DOUT3(
"Compress original object %lu into zip buffer %lu", objlen, zipbuflen);
525 content_header.append(
"Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0\r\n");
Reference on memory from memory pool.
unsigned SegmentSize(unsigned n=0) const
Returns size on the segment, no any boundary checks.
BufferSize_t GetTotalSize() const
Return total size of all buffer segments.
static Buffer CreateBuffer(BufferSize_t sz)
This static method create independent buffer for any other memory pools Therefore it can be used in s...
void * SegmentPtr(unsigned n=0) const
Returns pointer on the segment, no any boundary checks.
Command used to produce custom binary data for published in hierarchy entries.
Command to request names list.
void AddHeader(const std::string &name, const std::string &value, bool withquotes=true)
Represents command with its arguments.
unsigned GetUInt(const std::string &name, unsigned dflt=0) const
std::string GetStr(const std::string &name, const std::string &dflt="") const
Command & SetTimeout(double tm)
Set maximum time which can be used for command execution.
Buffer GetRawData()
Returns reference on raw data Can be called only once - raw data reference will be cleaned.
int NeedAuth(const std::string &path)
Returns 1 - need auth, 0 - no need auth, -1 - undefined.
Command ExeCmd(const std::string &fullname, const std::string &query)
Execute item is command, providing parameters in query.
std::string UserInterfaceKind(const char *uri, std::string &path, std::string &fname)
Returns "" - undefined, "__tree__" – tree hierarchy "__single__" – single element "__file__" – just a...
std::vector< std::string > AsStrVect() const
std::string AsStr(const std::string &dflt="") const
int64_t AsInt(int64_t dflt=0) const
bool HasField(const std::string &name) const
std::string SaveToJson(unsigned mask=0)
Store record in JSON form.
void Release()
Releases reference on the object.
bool null() const
Returns true if reference contains nullptr.
Uniform Resource Locator interpreter.
std::string GetOptionStr(const std::string &optname, const std::string &dflt="") const
bool HasOption(const std::string &optname) const
static void ReplaceSpecialSymbols(std::string &opt)
!
void SetOptions(const std::string &opt)
Method allows to set URL options directly to be able use all Get methods.
Reference on dabc::Worker
bool Execute(Command cmd, double tmout=-1.)
RecordField Cfg(const std::string &name, Command cmd=nullptr) const
Returns configuration field of specified name Configuration value of specified name searched in follo...
int fMonitoring
_monitoring value in h.json, only for top page
bool IsFileRequested(const char *uri, std::string &fname)
Check if file is requested.
static bool VerifyFilePath(const char *fname)
Check if relative path below current dir - prevents file access to top directories via http.
std::string fJsRootSys
location of JSROOT code, need to read special files
Server(const std::string &name, dabc::Command cmd=nullptr)
std::string fHttpSys
location of http plugin, need to read special files
std::string fDrawItem
_drawitem value in h.json, only for top page
std::string fLayout
_layout value in h.json
bool IsAuthRequired(const char *uri)
Returns true if authentication is required.
std::string fTopTitle
_toptitle value in h.json
std::string fBrowser
_browser value in h.json
void ExtractPathAndFile(const char *uri, std::string &pathname, std::string &filename)
std::string fDrawOpt
_drawopt value in h.json, only for top page
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.
std::string fAutoLoad
_autoload value in h.json
static const char * GetMimeType(const char *fname)
void AddLocation(const std::string &filepath, const std::string &absprefix, const std::string &nameprefix="", const std::string &nameprefixrepl="")
Add files location.
std::string format(const char *fmt,...)