mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-28 07:51:11 +02:00
yWeb 2.8.a.4
- updated nhttpd
- Code clean up
- changes to nhttpd.conf
- some changes for logo display
git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@416 e54a6e83-5905-42d5-8d5c-058d10e6a962
Origin commit data
------------------
Commit: bad0521f6c
Author: yjogol <yjogol2@online.de>
Date: 2010-02-25 (Thu, 25 Feb 2010)
This commit is contained in:
@@ -2,6 +2,11 @@
|
||||
nhttpd Version 3.x = (yhttpd 3.x + tuxboxapi)
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
25.02.2010 (yjogol)
|
||||
-------------------
|
||||
C/C++ Coding-Style switched to GNU-Style
|
||||
All Files edited with Tab width = 4
|
||||
|
||||
13.09.2006 (yjogol)
|
||||
-------------------
|
||||
Starting with Version 3.0 the nhttpd source code was splitted into
|
||||
@@ -16,3 +21,35 @@ for the tuxboxapi. So both tuxboxapi and yhttpd can be developed seperatlly and
|
||||
independ from each other.
|
||||
|
||||
Look at yhttpd_core/README
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
nhttpd.conf Description
|
||||
------------------------------------------------------------------------------
|
||||
Language.directory=languages
|
||||
Language.selected=Deutsch
|
||||
Tuxbox.LogosURL=
|
||||
WebsiteMain.directory=/share/tuxbox/neutrino/httpd // Main HTML,Javascript, Images Directoty root (e.g. read-only area in mFlash)
|
||||
WebsiteMain.override_directory=/var/httpd // Override directory (writable) for extensions or Updates. Webserver first search here.
|
||||
WebsiteMain.port=80 // Port the webserver is running on
|
||||
WebsiteMain.hosted_directory=/var/hosted // our own directory hosted by the webserver. Adressable with <box ip>/hosted/<your files>
|
||||
configfile.version=4 // Version of this config file
|
||||
mod_auth.authenticate=false // ask for username/password (http digit authentication)
|
||||
mod_auth.no_auth_client= // IP Adress without http authentication
|
||||
mod_auth.password=coolstream
|
||||
mod_auth.username=root
|
||||
mod_cache.cache_directory=/tmp/.cache
|
||||
mod_sendfile.mime_types=htm:text/html,html:text/html,xml:text/xml,txt:text/plain,jpg:image/jpeg,jpeg:image/jpeg,gif:image/gif,png:image/png,bmp:image/bmp,css:text/css,js:text/plain,img:application/octet-stream,ico:image/x-icon,m3u:application/octet-stream,tar:application/octet-stream
|
||||
mod_weblog.log_format=
|
||||
mod_weblog.logfile=/tmp/yhhtpd.log
|
||||
server.chroot=
|
||||
server.group_name=
|
||||
server.log.loglevel=0
|
||||
server.no_keep-alive_ips=
|
||||
server.user_name=
|
||||
webserver.threading=false
|
||||
webserver.websites=WebsiteMain // Dont change
|
||||
#if SSL compiled
|
||||
WebsiteMain.ssl=false
|
||||
WebsiteMain.ssl_pemfile
|
||||
WebsiteMain.ssl_ca_file
|
@@ -1,14 +1,13 @@
|
||||
ExtrasDocRoot=web
|
||||
ExtrasDocURL=
|
||||
Tuxbox.HostedDocumentRoot=
|
||||
Language.directory=languages
|
||||
Language.selected=Deutsch
|
||||
Tuxbox.LogosURL=
|
||||
WebsiteMain.directory=/share/tuxbox/neutrino/httpd
|
||||
WebsiteMain.override_directory=/var/httpd
|
||||
WebsiteMain.port=80
|
||||
WebsiteMain.special_locations=/hosted/=/mnt/hosted
|
||||
Zapit_XML_Path=/var/tuxbox/config/zapit
|
||||
configfile.version=1
|
||||
WebsiteMain.hosted_directory=/var/hosted
|
||||
configfile.version=4
|
||||
mod_auth.authenticate=false
|
||||
mod_auth.no_auth_client=172.16.1.1
|
||||
mod_auth.no_auth_client=
|
||||
mod_auth.password=coolstream
|
||||
mod_auth.username=root
|
||||
mod_cache.cache_directory=/tmp/.cache
|
||||
@@ -20,5 +19,5 @@ server.group_name=
|
||||
server.log.loglevel=0
|
||||
server.no_keep-alive_ips=
|
||||
server.user_name=
|
||||
webserver.threading=
|
||||
webserver.threading=false
|
||||
webserver.websites=WebsiteMain
|
||||
|
@@ -63,9 +63,9 @@ void CControlAPI::init(CyhookHandler *hh)
|
||||
{
|
||||
if(PLUGIN_DIRS[0] == "")
|
||||
{ // given in nhttpd.conf
|
||||
PLUGIN_DIRS[0]=hh->WebserverConfigList["PublicDocumentRoot"];
|
||||
PLUGIN_DIRS[0]=hh->WebserverConfigList["WebsiteMain.override_directory"];
|
||||
PLUGIN_DIRS[0].append("/scripts");
|
||||
PLUGIN_DIRS[1]=hh->WebserverConfigList["PrivatDocumentRoot"];
|
||||
PLUGIN_DIRS[1]=hh->WebserverConfigList["WebsiteMain.directory"];
|
||||
PLUGIN_DIRS[1].append("/scripts");
|
||||
PLUGIN_DIRS[2]="/var/tuxbox/plugins";
|
||||
PLUGIN_DIRS[3]=PLUGINDIR;
|
||||
@@ -145,37 +145,37 @@ const CControlAPI::TyCgiCall CControlAPI::yCgiCallList[]=
|
||||
{"channellist", &CControlAPI::ChannellistCGI, "text/plain"},
|
||||
{"getbouquet", &CControlAPI::GetBouquetCGI, "+xml"},
|
||||
{"getbouquets", &CControlAPI::GetBouquetsCGI, "text/plain"},
|
||||
{"getmode", &CControlAPI::GetModeCGI, "text/plain"},
|
||||
{"setmode", &CControlAPI::SetModeCGI, "text/plain"},
|
||||
{"epg", &CControlAPI::EpgCGI, ""},
|
||||
{"zapto", &CControlAPI::ZaptoCGI, "text/plain"},
|
||||
{"getmode", &CControlAPI::GetModeCGI, "text/plain"},
|
||||
{"setmode", &CControlAPI::SetModeCGI, "text/plain"},
|
||||
{"epg", &CControlAPI::EpgCGI, ""},
|
||||
{"zapto", &CControlAPI::ZaptoCGI, "text/plain"},
|
||||
{"getonidsid", &CControlAPI::GetChannel_IDCGI, "text/plain"},
|
||||
// boxcontrol - system
|
||||
{"standby", &CControlAPI::StandbyCGI, "text/plain"},
|
||||
{"shutdown", &CControlAPI::ShutdownCGI, "text/plain"},
|
||||
{"reboot", &CControlAPI::RebootCGI, "text/plain"},
|
||||
{"getdate", &CControlAPI::GetDateCGI, "text/plain"},
|
||||
{"gettime", &CControlAPI::GetTimeCGI, "text/plain"},
|
||||
{"info", &CControlAPI::InfoCGI, "text/plain"},
|
||||
{"version", &CControlAPI::VersionCGI, ""},
|
||||
{"standby", &CControlAPI::StandbyCGI, "text/plain"},
|
||||
{"shutdown", &CControlAPI::ShutdownCGI, "text/plain"},
|
||||
{"reboot", &CControlAPI::RebootCGI, "text/plain"},
|
||||
{"getdate", &CControlAPI::GetDateCGI, "text/plain"},
|
||||
{"gettime", &CControlAPI::GetTimeCGI, "text/plain"},
|
||||
{"info", &CControlAPI::InfoCGI, "text/plain"},
|
||||
{"version", &CControlAPI::VersionCGI, ""},
|
||||
// boxcontrol - devices
|
||||
{"volume", &CControlAPI::VolumeCGI, "text/plain"},
|
||||
{"lcd", &CControlAPI::LCDAction, "text/plain"},
|
||||
{"system", &CControlAPI::SystemCGI, "text/plain"},
|
||||
{"message", &CControlAPI::MessageCGI, "text/plain"},
|
||||
{"rc", &CControlAPI::RCCGI, "text/plain"},
|
||||
{"rcem", &CControlAPI::RCEmCGI, "text/plain"},
|
||||
{"volume", &CControlAPI::VolumeCGI, "text/plain"},
|
||||
{"lcd", &CControlAPI::LCDAction, "text/plain"},
|
||||
{"system", &CControlAPI::SystemCGI, "text/plain"},
|
||||
{"message", &CControlAPI::MessageCGI, "text/plain"},
|
||||
{"rc", &CControlAPI::RCCGI, "text/plain"},
|
||||
{"rcem", &CControlAPI::RCEmCGI, "text/plain"},
|
||||
// Start skripts, plugins
|
||||
{"startplugin", &CControlAPI::StartPluginCGI, "text/plain"},
|
||||
{"exec", &CControlAPI::ExecCGI, "+xml"},
|
||||
{"yweb", &CControlAPI::YWebCGI, "text/plain"},
|
||||
{"exec", &CControlAPI::ExecCGI, "+xml"},
|
||||
{"yweb", &CControlAPI::YWebCGI, "text/plain"},
|
||||
// video handling
|
||||
{"videoformat", &CControlAPI::VideoFormatCGI, "text/plain"},
|
||||
{"videooutput", &CControlAPI::VideoOutputCGI, "text/plain"},
|
||||
{"vcroutput", &CControlAPI::VCROutputCGI, "text/plain"},
|
||||
{"scartmode", &CControlAPI::ScartModeCGI, "text/plain"},
|
||||
{"vcroutput", &CControlAPI::VCROutputCGI, "text/plain"},
|
||||
{"scartmode", &CControlAPI::ScartModeCGI, "text/plain"},
|
||||
// timer
|
||||
{"timer", &CControlAPI::TimerCGI, "text/plain"},
|
||||
{"timer", &CControlAPI::TimerCGI, "text/plain"},
|
||||
// bouquet editing
|
||||
{"setbouquet", &CControlAPI::setBouquetCGI, "text/plain"},
|
||||
{"savebouquet", &CControlAPI::saveBouquetCGI, "text/plain"},
|
||||
@@ -652,53 +652,53 @@ static const struct key keynames[] = {
|
||||
};
|
||||
|
||||
// The code here is based on rcsim. Thx Carjay!
|
||||
void CControlAPI::RCEmCGI(CyhookHandler *hh)
|
||||
{
|
||||
if (hh->ParamList.empty()) {
|
||||
hh->SendError();
|
||||
return;
|
||||
}
|
||||
std::string keyname = hh->ParamList["1"];
|
||||
int sendcode = -1;
|
||||
for (unsigned int i = 0; sendcode == -1 && i < sizeof(keynames)/sizeof(key); i++) {
|
||||
if (!strcmp(keyname.c_str(), keynames[i].name))
|
||||
sendcode = keynames[i].code;
|
||||
}
|
||||
void CControlAPI::RCEmCGI(CyhookHandler *hh) {
|
||||
if (hh->ParamList.empty()) {
|
||||
hh->SendError();
|
||||
return;
|
||||
}
|
||||
std::string keyname = hh->ParamList["1"];
|
||||
int sendcode = -1;
|
||||
for (unsigned int i = 0; sendcode == -1 && i < sizeof(keynames)
|
||||
/ sizeof(key); i++) {
|
||||
if (!strcmp(keyname.c_str(), keynames[i].name))
|
||||
sendcode = keynames[i].code;
|
||||
}
|
||||
|
||||
if (sendcode == -1) {
|
||||
printf("[nhttpd] Key %s not found\n", keyname.c_str());
|
||||
hh->SendError();
|
||||
return;
|
||||
}
|
||||
unsigned int repeat = 1;
|
||||
unsigned int delay = 250;
|
||||
if (hh->ParamList["delay"] != "")
|
||||
delay = atoi(hh->ParamList["delay"].c_str());
|
||||
if (hh->ParamList["duration"] != "")
|
||||
repeat = atoi(hh->ParamList["duration"].c_str())*1000/delay;
|
||||
if (hh->ParamList["repeat"] != "")
|
||||
repeat = atoi(hh->ParamList["repeat"].c_str());
|
||||
if (sendcode == -1) {
|
||||
printf("[nhttpd] Key %s not found\n", keyname.c_str());
|
||||
hh->SendError();
|
||||
return;
|
||||
}
|
||||
unsigned int repeat = 1;
|
||||
unsigned int delay = 250;
|
||||
if (hh->ParamList["delay"] != "")
|
||||
delay = atoi(hh->ParamList["delay"].c_str());
|
||||
if (hh->ParamList["duration"] != "")
|
||||
repeat = atoi(hh->ParamList["duration"].c_str()) * 1000 / delay;
|
||||
if (hh->ParamList["repeat"] != "")
|
||||
repeat = atoi(hh->ParamList["repeat"].c_str());
|
||||
|
||||
int evd = open(EVENTDEV, O_RDWR);
|
||||
if (evd < 0) {
|
||||
hh->SendError();
|
||||
perror("opening event0 failed");
|
||||
return;
|
||||
}
|
||||
if (rc_send(evd, sendcode, KEY_PRESSED) < 0){
|
||||
perror("writing 'KEY_PRESSED' event failed");
|
||||
hh->SendError();
|
||||
close(evd);
|
||||
return;
|
||||
}
|
||||
if (rc_send(evd, sendcode, KEY_RELEASED)<0){
|
||||
perror("writing 'KEY_RELEASED' event failed");
|
||||
close(evd);
|
||||
hh->SendError();
|
||||
return;
|
||||
}
|
||||
close(evd);
|
||||
hh->SendOk();
|
||||
int evd = open(EVENTDEV, O_RDWR);
|
||||
if (evd < 0) {
|
||||
hh->SendError();
|
||||
perror("opening event0 failed");
|
||||
return;
|
||||
}
|
||||
if (rc_send(evd, sendcode, KEY_PRESSED) < 0) {
|
||||
perror("writing 'KEY_PRESSED' event failed");
|
||||
hh->SendError();
|
||||
close(evd);
|
||||
return;
|
||||
}
|
||||
if (rc_send(evd, sendcode, KEY_RELEASED) < 0) {
|
||||
perror("writing 'KEY_RELEASED' event failed");
|
||||
close(evd);
|
||||
hh->SendError();
|
||||
return;
|
||||
}
|
||||
close(evd);
|
||||
hh->SendOk();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void CControlAPI::VideoFormatCGI(CyhookHandler *hh)
|
||||
@@ -926,8 +926,8 @@ void CControlAPI::EpgCGI(CyhookHandler *hh)
|
||||
{
|
||||
t_channel_id channel_id;
|
||||
sscanf(hh->ParamList["id"].c_str(),
|
||||
SCANF_CHANNEL_ID_TYPE,
|
||||
&channel_id);
|
||||
SCANF_CHANNEL_ID_TYPE,
|
||||
&channel_id);
|
||||
sectionsd_getEventsServiceKey(channel_id&0xFFFFFFFFFFFFULL, NeutrinoAPI->eList);
|
||||
CChannelEventList::iterator eventIterator;
|
||||
for (eventIterator = NeutrinoAPI->eList.begin(); eventIterator != NeutrinoAPI->eList.end(); eventIterator++)
|
||||
@@ -947,8 +947,8 @@ void CControlAPI::EpgCGI(CyhookHandler *hh)
|
||||
//eventlist for a chan
|
||||
t_channel_id channel_id;
|
||||
sscanf(hh->ParamList["1"].c_str(),
|
||||
SCANF_CHANNEL_ID_TYPE,
|
||||
&channel_id);
|
||||
SCANF_CHANNEL_ID_TYPE,
|
||||
&channel_id);
|
||||
SendEventList(hh, channel_id);
|
||||
}
|
||||
}
|
||||
|
@@ -85,10 +85,8 @@ THandleStatus CNeutrinoYParser::Hook_SendResponse(CyhookHandler *hh)
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CNeutrinoYParser::Hook_ReadConfig(CConfigFile *Config, CStringList &ConfigList)
|
||||
{
|
||||
ConfigList["ExtrasDocumentRoot"]= Config->getString("ExtrasDocRoot", EXTRASDOCUMENTROOT);
|
||||
ConfigList["ExtrasDocumentURL"] = Config->getString("ExtrasDocURL", EXTRASDOCUMENTURL);
|
||||
// ConfigList["NewGui"] = Config->getString("NewGui", "true");
|
||||
ConfigList["Zapit_XML_Path"] = Config->getString("Zapit_XML_Path", ZAPITXMLPATH);
|
||||
// ConfigList["ExtrasDocumentRoot"]= Config->getString("ExtrasDocRoot", EXTRASDOCUMENTROOT);
|
||||
// ConfigList["ExtrasDocumentURL"] = Config->getString("ExtrasDocURL", EXTRASDOCUMENTURL);
|
||||
ConfigList["TUXBOX_LOGOS_URL"]= Config->getString("Tuxbox.LogosURL", TUXBOX_LOGOS_URL);
|
||||
|
||||
if (Config->getInt32("configfile.version") < 3)
|
||||
@@ -106,26 +104,26 @@ THandleStatus CNeutrinoYParser::Hook_ReadConfig(CConfigFile *Config, CStringList
|
||||
//=============================================================================
|
||||
const CNeutrinoYParser::TyFuncCall CNeutrinoYParser::yFuncCallList[]=
|
||||
{
|
||||
{"mount-get-list", &CNeutrinoYParser::func_mount_get_list},
|
||||
{"mount-set-values", &CNeutrinoYParser::func_mount_set_values},
|
||||
{"mount-get-list", &CNeutrinoYParser::func_mount_get_list},
|
||||
{"mount-set-values", &CNeutrinoYParser::func_mount_set_values},
|
||||
{"get_bouquets_as_dropdown", &CNeutrinoYParser::func_get_bouquets_as_dropdown},
|
||||
{"get_bouquets_as_templatelist",&CNeutrinoYParser::func_get_bouquets_as_templatelist},
|
||||
{"get_actual_bouquet_number", &CNeutrinoYParser::func_get_actual_bouquet_number},
|
||||
{"get_channels_as_dropdown", &CNeutrinoYParser::func_get_channels_as_dropdown},
|
||||
{"get_bouquets_with_epg", &CNeutrinoYParser::func_get_bouquets_with_epg},
|
||||
{"get_actual_channel_id", &CNeutrinoYParser::func_get_actual_channel_id},
|
||||
{"get_mode", &CNeutrinoYParser::func_get_mode},
|
||||
{"get_video_pids", &CNeutrinoYParser::func_get_video_pids},
|
||||
{"get_audio_pid", &CNeutrinoYParser::func_get_radio_pid},
|
||||
{"get_bouquets_with_epg", &CNeutrinoYParser::func_get_bouquets_with_epg},
|
||||
{"get_actual_channel_id", &CNeutrinoYParser::func_get_actual_channel_id},
|
||||
{"get_mode", &CNeutrinoYParser::func_get_mode},
|
||||
{"get_video_pids", &CNeutrinoYParser::func_get_video_pids},
|
||||
{"get_audio_pid", &CNeutrinoYParser::func_get_radio_pid},
|
||||
{"get_audio_pids_as_dropdown", &CNeutrinoYParser::func_get_audio_pids_as_dropdown},
|
||||
{"umount_get_list", &CNeutrinoYParser::func_unmount_get_list},
|
||||
{"get_partition_list", &CNeutrinoYParser::func_get_partition_list},
|
||||
{"get_boxtype", &CNeutrinoYParser::func_get_boxtype},
|
||||
{"get_current_stream_info", &CNeutrinoYParser::func_get_current_stream_info},
|
||||
{"get_timer_list", &CNeutrinoYParser::func_get_timer_list},
|
||||
{"set_timer_form", &CNeutrinoYParser::func_set_timer_form},
|
||||
{"bouquet_editor_main", &CNeutrinoYParser::func_bouquet_editor_main},
|
||||
{"set_bouquet_edit_form", &CNeutrinoYParser::func_set_bouquet_edit_form},
|
||||
{"umount_get_list", &CNeutrinoYParser::func_unmount_get_list},
|
||||
{"get_partition_list", &CNeutrinoYParser::func_get_partition_list},
|
||||
{"get_boxtype", &CNeutrinoYParser::func_get_boxtype},
|
||||
{"get_current_stream_info", &CNeutrinoYParser::func_get_current_stream_info},
|
||||
{"get_timer_list", &CNeutrinoYParser::func_get_timer_list},
|
||||
{"set_timer_form", &CNeutrinoYParser::func_set_timer_form},
|
||||
{"bouquet_editor_main", &CNeutrinoYParser::func_bouquet_editor_main},
|
||||
{"set_bouquet_edit_form", &CNeutrinoYParser::func_set_bouquet_edit_form},
|
||||
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -330,7 +328,7 @@ std::string CNeutrinoYParser::func_get_bouquets_with_epg(CyhookHandler *hh, std:
|
||||
std::string timestr;
|
||||
bool have_logos = false;
|
||||
|
||||
if(hh->WebserverConfigList["TUXBOX_LOGOS_URL"] != "" ||hh->WebserverConfigList["ExtrasDocumentRoot"] == "web" || (access((hh->WebserverConfigList["ExtrasDocumentRoot"]+"/logos").c_str(),4)==0) )
|
||||
if(hh->WebserverConfigList["Tuxbox.LogosURL"] != "")
|
||||
have_logos = true;
|
||||
for(int j = 0; j < (int) channels.size(); j++)
|
||||
{
|
||||
@@ -348,10 +346,10 @@ std::string CNeutrinoYParser::func_get_bouquets_with_epg(CyhookHandler *hh, std:
|
||||
if(have_logos)
|
||||
yresult += string_printf("<td class=\"%c\" width=\"44\" rowspan=\"2\"><a href=\"javascript:do_zap('"
|
||||
PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
|
||||
"')\"><img class=\"channel_logo\" src=\"%s/logos/"
|
||||
"')\"><img class=\"channel_logo\" src=\"%s/"
|
||||
PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
|
||||
".jpg\"/></a></td>", classname, channel->channel_id,
|
||||
(hh->WebserverConfigList["ExtrasDocumentURL"]).c_str(),
|
||||
(hh->WebserverConfigList["Tuxbox.LogosURL"]).c_str(),
|
||||
channel->channel_id & 0xFFFFFFFFFFFFULL);
|
||||
|
||||
/* timer slider */
|
||||
@@ -376,6 +374,8 @@ std::string CNeutrinoYParser::func_get_bouquets_with_epg(CyhookHandler *hh, std:
|
||||
PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
|
||||
"')\"> %d. %s%s</a> <a href=\"javascript:do_epg('"
|
||||
PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
|
||||
"','"
|
||||
PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
|
||||
"')\">%s</a>\n",
|
||||
((channel->channel_id == current_channel) ? "<a name=\"akt\"></a>" : " "),
|
||||
channel->channel_id,
|
||||
@@ -383,6 +383,7 @@ std::string CNeutrinoYParser::func_get_bouquets_with_epg(CyhookHandler *hh, std:
|
||||
channel->getName().c_str(),
|
||||
(channel->getServiceType() == ST_NVOD_REFERENCE_SERVICE) ? " (NVOD)" : "",
|
||||
channel->channel_id,
|
||||
channel->channel_id & 0xFFFFFFFFFFFFULL,
|
||||
((NeutrinoAPI->ChannelListEvents[channel->channel_id]) ? "<img src=\"/images/elist.gif\" alt=\"Programmvorschau\" style=\"border: 0px\" />" : ""));
|
||||
|
||||
if (channel->channel_id == current_channel)
|
||||
@@ -441,7 +442,7 @@ std::string CNeutrinoYParser::func_get_bouquets_with_epg(CyhookHandler *hh, std:
|
||||
|
||||
yresult += string_printf("<tr><td class=\"%cepg\">",classname);
|
||||
yresult += string_printf("%s %s "
|
||||
"<span style=\"font-size: 8pt; white-space: nowrap\">(%ld von %d min, %d%%)</span>"
|
||||
"<span style=\"font-size: 8pt; white-space: nowrap\">(%ld von %d min, %d%%)</span>"
|
||||
, timestr.c_str()
|
||||
, event->description.c_str()
|
||||
, (time(NULL) - event->startTime)/60
|
||||
|
@@ -54,9 +54,9 @@ void CControlAPI::init(CyhookHandler *hh)
|
||||
{
|
||||
if(PLUGIN_DIRS[0] == "")
|
||||
{ // given in nhttpd.conf
|
||||
PLUGIN_DIRS[0]=hh->WebserverConfigList["PublicDocumentRoot"];
|
||||
PLUGIN_DIRS[0]=hh->WebserverConfigList["WebsiteMain.override_directory"];
|
||||
PLUGIN_DIRS[0].append("/scripts");
|
||||
PLUGIN_DIRS[1]=hh->WebserverConfigList["PrivatDocumentRoot"];
|
||||
PLUGIN_DIRS[1]=hh->WebserverConfigList["WebsiteMain.directory"];
|
||||
PLUGIN_DIRS[1].append("/scripts");
|
||||
PLUGIN_DIRS[2]="/var/tuxbox/plugins";
|
||||
PLUGIN_DIRS[3]=PLUGINDIR;
|
||||
@@ -136,40 +136,40 @@ const CControlAPI::TyCgiCall CControlAPI::yCgiCallList[]=
|
||||
{"channellist", &CControlAPI::ChannellistCGI, "text/plain"},
|
||||
{"getbouquet", &CControlAPI::GetBouquetCGI, "+xml"},
|
||||
{"getbouquets", &CControlAPI::GetBouquetsCGI, "text/plain"},
|
||||
{"getmode", &CControlAPI::GetModeCGI, "text/plain"},
|
||||
{"setmode", &CControlAPI::SetModeCGI, "text/plain"},
|
||||
{"epg", &CControlAPI::EpgCGI, ""},
|
||||
{"zapto", &CControlAPI::ZaptoCGI, "text/plain"},
|
||||
{"getmode", &CControlAPI::GetModeCGI, "text/plain"},
|
||||
{"setmode", &CControlAPI::SetModeCGI, "text/plain"},
|
||||
{"epg", &CControlAPI::EpgCGI, ""},
|
||||
{"zapto", &CControlAPI::ZaptoCGI, "text/plain"},
|
||||
{"getonidsid", &CControlAPI::GetChannel_IDCGI, "text/plain"},
|
||||
// boxcontrol - system
|
||||
{"standby", &CControlAPI::StandbyCGI, "text/plain"},
|
||||
{"shutdown", &CControlAPI::ShutdownCGI, "text/plain"},
|
||||
{"reboot", &CControlAPI::RebootCGI, "text/plain"},
|
||||
{"esound", &CControlAPI::EsoundCGI, "text/plain"},
|
||||
{"getdate", &CControlAPI::GetDateCGI, "text/plain"},
|
||||
{"gettime", &CControlAPI::GetTimeCGI, "text/plain"},
|
||||
{"settings", &CControlAPI::SettingsCGI, "text/plain"},
|
||||
{"info", &CControlAPI::InfoCGI, "text/plain"},
|
||||
{"version", &CControlAPI::VersionCGI, ""},
|
||||
{"standby", &CControlAPI::StandbyCGI, "text/plain"},
|
||||
{"shutdown", &CControlAPI::ShutdownCGI, "text/plain"},
|
||||
{"reboot", &CControlAPI::RebootCGI, "text/plain"},
|
||||
{"esound", &CControlAPI::EsoundCGI, "text/plain"},
|
||||
{"getdate", &CControlAPI::GetDateCGI, "text/plain"},
|
||||
{"gettime", &CControlAPI::GetTimeCGI, "text/plain"},
|
||||
{"settings", &CControlAPI::SettingsCGI, "text/plain"},
|
||||
{"info", &CControlAPI::InfoCGI, "text/plain"},
|
||||
{"version", &CControlAPI::VersionCGI, ""},
|
||||
// boxcontrol - devices
|
||||
{"volume", &CControlAPI::VolumeCGI, "text/plain"},
|
||||
{"lcd", &CControlAPI::LCDAction, "text/plain"},
|
||||
{"system", &CControlAPI::SystemCGI, "text/plain"},
|
||||
{"message", &CControlAPI::MessageCGI, "text/plain"},
|
||||
{"rc", &CControlAPI::RCCGI, "text/plain"},
|
||||
{"rcem", &CControlAPI::RCEmCGI, "text/plain"},
|
||||
{"volume", &CControlAPI::VolumeCGI, "text/plain"},
|
||||
{"lcd", &CControlAPI::LCDAction, "text/plain"},
|
||||
{"system", &CControlAPI::SystemCGI, "text/plain"},
|
||||
{"message", &CControlAPI::MessageCGI, "text/plain"},
|
||||
{"rc", &CControlAPI::RCCGI, "text/plain"},
|
||||
{"rcem", &CControlAPI::RCEmCGI, "text/plain"},
|
||||
// Start skripts, plugins
|
||||
{"startplugin", &CControlAPI::StartPluginCGI, "text/plain"},
|
||||
{"exec", &CControlAPI::ExecCGI, "+xml"},
|
||||
{"yweb", &CControlAPI::YWebCGI, "text/plain"},
|
||||
{"exec", &CControlAPI::ExecCGI, "+xml"},
|
||||
{"yweb", &CControlAPI::YWebCGI, "text/plain"},
|
||||
// video handling
|
||||
{"aspectratio", &CControlAPI::AspectRatioCGI, "text/plain"},
|
||||
{"videoformat", &CControlAPI::VideoFormatCGI, "text/plain"},
|
||||
{"videooutput", &CControlAPI::VideoOutputCGI, "text/plain"},
|
||||
{"vcroutput", &CControlAPI::VCROutputCGI, "text/plain"},
|
||||
{"scartmode", &CControlAPI::ScartModeCGI, "text/plain"},
|
||||
{"vcroutput", &CControlAPI::VCROutputCGI, "text/plain"},
|
||||
{"scartmode", &CControlAPI::ScartModeCGI, "text/plain"},
|
||||
// timer
|
||||
{"timer", &CControlAPI::TimerCGI, "text/plain"},
|
||||
{"timer", &CControlAPI::TimerCGI, "text/plain"},
|
||||
// bouquet editing
|
||||
{"setbouquet", &CControlAPI::setBouquetCGI, "text/plain"},
|
||||
{"savebouquet", &CControlAPI::saveBouquetCGI, "text/plain"},
|
||||
|
@@ -72,8 +72,6 @@ THandleStatus CNeutrinoYParser::Hook_ReadConfig(CConfigFile *Config, CStringList
|
||||
{
|
||||
ConfigList["ExtrasDocumentRoot"]= Config->getString("ExtrasDocRoot", EXTRASDOCUMENTROOT);
|
||||
ConfigList["ExtrasDocumentURL"] = Config->getString("ExtrasDocURL", EXTRASDOCUMENTURL);
|
||||
// ConfigList["NewGui"] = Config->getString("NewGui", "true");
|
||||
ConfigList["Zapit_XML_Path"] = Config->getString("Zapit_XML_Path", ZAPITXMLPATH);
|
||||
ConfigList["TUXBOX_LOGOS_URL"]= Config->getString("Tuxbox.LogosURL", TUXBOX_LOGOS_URL);
|
||||
|
||||
if (Config->getInt32("configfile.version") < 3)
|
||||
|
@@ -54,7 +54,7 @@ start-block~nhttpd_save_settings
|
||||
{=ini-set:/var/tuxbox/config/nhttpd.conf;WebsiteMain.port;{=port=}~cache=}
|
||||
{=ini-set:/var/tuxbox/config/nhttpd.conf;webserver.threading;{=threading=}~cache=}
|
||||
{=ini-set:/var/tuxbox/config/nhttpd.conf;server.no_keep-alive_ips;{=no_keep_alive_ips=}~cache=}
|
||||
{=ini-set:/var/tuxbox/config/nhttpd.conf;Tuxbox.HostedDocumentRoot;{=HostedDocRoot=}~cache=}
|
||||
{=ini-set:/var/tuxbox/config/nhttpd.conf;WebsiteMain.hosted_directory;{=HostedDocRoot=}~cache=}
|
||||
{=ini-set:/var/tuxbox/config/nhttpd.conf;WebsiteMain.override_directory;{=override_directory=}~cache=}
|
||||
{=ini-set:/var/tuxbox/config/nhttpd.conf;mod_sendfile.mime_types;{=mod_sendfile_mime_types=}~cache=}
|
||||
{=ini-set:/var/tuxbox/config/nhttpd.conf;mod_sendfile.sendAll;{=mod_sendfile_sendAll=}~cache=}
|
||||
@@ -423,7 +423,7 @@ start-block~frame_live_epg
|
||||
</head>
|
||||
<frameset rows="100,*" frameborder="0" framespacing="0">
|
||||
<frame name="epg_info" src="Y_Live_EPG_Info.yhtm" scrolling="auto" frameborder="0" />
|
||||
<frame name="epg_list" src="Y_Live_EPG.yhtm?channel={=channel=}" scrolling="auto" frameborder="0" style="height:100%" />
|
||||
<frame name="epg_list" src="Y_Live_EPG.yhtm?channel={=channel=}&logoid={=logoid=}" scrolling="auto" frameborder="0" style="height:100%" />
|
||||
<noframes>
|
||||
<body>
|
||||
<p>Your Browser does not support Frames.</p>
|
||||
|
@@ -3,18 +3,14 @@
|
||||
<script type="text/javascript" src="/Y_Baselib.js"></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function do_zap(channelid)
|
||||
{
|
||||
function do_zap(channelid) {
|
||||
dbox_zapto(channelid);
|
||||
window.location.reload();
|
||||
}
|
||||
function do_epg(channelid)
|
||||
{
|
||||
window.location.href="Y_Dyn_Pages.yhtm?page=frame_live_epg&channel="+channelid;
|
||||
// window.open("Y_Dyn_Pages.yhtm?page=frame_live_epg&channel="+channelid, "epg", "width=400");
|
||||
function do_epg(channelid,logoid) {
|
||||
window.location.href="Y_Dyn_Pages.yhtm?page=frame_live_epg&channel="+channelid+"&logoid="+logoid;
|
||||
}
|
||||
function do_streaminfo()
|
||||
{
|
||||
function do_streaminfo() {
|
||||
window.open("Y_StreamInfo.yhtm", "stream", "width=400");
|
||||
}
|
||||
//]]>
|
||||
|
@@ -50,11 +50,9 @@ function show_info(_index)
|
||||
}
|
||||
function check_logo()
|
||||
{
|
||||
{=if-equal:{=ini-get:/var/tuxbox/config/nhttpd.conf;ExtrasDocRoot=}~web~~
|
||||
var test = loadSyncURL("{=ini-get:/var/tuxbox/config/nhttpd.conf;ExtrasDocURL=}/logos/{=channel=}.gif");
|
||||
if(test != "")
|
||||
=}
|
||||
{=if-empty:{=logoid=}~~
|
||||
show_obj("logo",true);
|
||||
=}
|
||||
}
|
||||
function show_epg() {
|
||||
show_waitbox(true);
|
||||
@@ -108,7 +106,7 @@ function _show_epg()
|
||||
<table id="epglist" class="y_invisible_table" cellpadding="4" cellspacing="0" width="100%">
|
||||
<thead align="left">
|
||||
<tr>
|
||||
<th colspan="2"><img id="logo" src="{=ini-get:/var/tuxbox/config/nhttpd.conf;Tuxbox.LogosURL=}/{=channel=}.gif" style="visibility:hidden"> </th>
|
||||
<th colspan="2"><img id="logo" src="{=ini-get:/var/tuxbox/config/nhttpd.conf;Tuxbox.LogosURL=}/{=logoid=}.jpg" style="visibility:hidden"> </th>
|
||||
<th>{=L:date=}</th><th>{=L:from=}</th><th>{=L:to=}</th><th>{=L:program=}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@@ -73,7 +73,7 @@ function do_submit()
|
||||
<tr>
|
||||
<td>{=L:alternate_web_folder=}</td>
|
||||
<td><input type="text" name="override_directory" size="20" value="{=ini-get:/var/tuxbox/config/nhttpd.conf;WebsiteMain.override_directory~cache=}" title="{=L:alternate_web_folder=}"/> {=L:active_after_boot=}
|
||||
<input type="hidden" name="HostedDocRoot" size="60" value="{=ini-get:/var/tuxbox/config/nhttpd.conf;Tuxbox.HostedDocumentRoot~cache=}" title="Root of hosted Web. Enter mount directory."/></td>
|
||||
<input type="hidden" name="HostedDocRoot" size="60" value="{=ini-get:/var/tuxbox/config/nhttpd.conf;WebsiteMain.hosted_directory~cache=}" title="Root of hosted Web. Enter mount directory."/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{=L:allowed_file_extensions=}</td>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
version=2.8.a.3
|
||||
date=24.02.2010
|
||||
version=2.8.a.4
|
||||
date=25.02.2010
|
||||
type=Alpha
|
||||
info=Port Coolstream
|
||||
|
||||
|
@@ -12,25 +12,27 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
//=============================================================================
|
||||
// Base Configuration
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
// System Choice <configure!> ONE choice
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef CONFIG_SYSTEM_BY_COMPILER // use Compiler directive to set CONFIG_SYSTEM
|
||||
//#define CONFIG_SYSTEM_TUXBOX y // Tuxbox dbox project
|
||||
#define CONFIG_SYSTEM_TUXBOX_COOLSTREAM y // Tuxbox dbox project for coolstream
|
||||
//#define CONFIG_SYSTEM_TUXBOX y // Tuxbox project
|
||||
#define CONFIG_SYSTEM_TUXBOX_COOLSTREAM y // Tuxbox project for coolstream
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
// General central Definitions <configure!>
|
||||
//-----------------------------------------------------------------------------
|
||||
#define HTTPD_VERSION "3.2.2" // Webserver version (can be overloaded)
|
||||
#define YHTTPD_VERSION "1.3.0" // Webserver version (Version of yhttpd-core!)
|
||||
#define HTTPD_VERSION "3.2.3" // Webserver version (can be overloaded)
|
||||
#define YHTTPD_VERSION "1.3.1" // Webserver version (Version of yhttpd-core!)
|
||||
#define IADDR_LOCAL "127.0.0.1" // local IP
|
||||
#define HTTPD_NAME "yhttpd" // Webserver name (can be overloaded)
|
||||
#define YHTTPD_NAME "yhttpd_core" // Webserver name (Name of yhttpd-core!)
|
||||
#define HTTPD_NAME "yhttpd" // Webserver name (can be overloaded)
|
||||
#define YHTTPD_NAME "yhttpd_core" // Webserver name (Name of yhttpd-core!)
|
||||
#define AUTH_NAME_MSG "yhhtpd" // Name in Authentication Dialogue
|
||||
#define CONF_VERSION 4 // Version of yhttpd-conf file
|
||||
|
||||
#define HTTPD_KEEPALIVE_TIMEOUT 500000 // Timeout for Keep-Alive in mircoseconds
|
||||
#define CONF_VERSION 4 // Version of yhttpd-conf file
|
||||
#define HTTPD_KEEPALIVE_TIMEOUT 500000 // Timeout for Keep-Alive in mircoseconds
|
||||
//=============================================================================
|
||||
// Features wanted <configure!>
|
||||
//=============================================================================
|
||||
@@ -46,18 +48,17 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Features & Build
|
||||
//-----------------------------------------------------------------------------
|
||||
#define Y_CONFIG_FEATURE_CHECK_PORT_AUTORITY y // System: Port < 1024 need Admin-Privileges-Check
|
||||
#define Y_CONFIG_FEATURE_CHECK_PORT_AUTORITY y // System: Port < 1024 need Admin-Privileges-Check
|
||||
#define Y_CONFIG_HAVE_SENDFILE y // System: Have *IX SendFile
|
||||
#define Y_CONFIG_FEATURE_UPLOAD y // Add Feature: File Upload POST Command
|
||||
#define Y_CONFIG_USE_HOSTEDWEB y // Add Feature: Use HOSTED Web
|
||||
#define Y_CONFIG_FEATURE_SHOW_SERVER_CONFIG y // Add Feature (in yParser): add /y/server-config
|
||||
#define Y_CONFIG_FEATURE_SHOW_SERVER_CONFIG y // Add Feature (in yParser): add /y/server-config
|
||||
//#define Y_CONFIG_USE_OPEN_SSL y // Add Feature: use openSSL
|
||||
//#define Y_CONFIG_FEATURE_KEEP_ALIVE y // Add Feature: Keep-alive //FIXME: does not work correctly now
|
||||
#define Y_CONFIG_FEATUE_SENDFILE_CAN_ACCESS_ALL y // Add Feature: every file can be accessed (use carefully: security!!)
|
||||
//#define Y_CONFIG_FEATURE_KEEP_ALIVE y // Add Feature: Keep-alive //FIXME: does not work correctly now
|
||||
#define Y_CONFIG_FEATUE_SENDFILE_CAN_ACCESS_ALL y // Add Feature: every file can be accessed (use carefully: security!!)
|
||||
//#define Y_CONFIG_FEATURE_CHROOT y // Add Feature: Use Change Root for Security
|
||||
//#define Y_CONFIG_FEATURE_HTTPD_USER y // Add Feature: Set User for yhttpd-Process
|
||||
#define Y_CONFIG_BUILD_AS_DAEMON y // Build as a Daemon
|
||||
|
||||
//#define Y_CONFIG_FEATURE_HTTPD_USER y // Add Feature: Set User for yhttpd-Process
|
||||
#define Y_CONFIG_BUILD_AS_DAEMON y // Build as a Daemon with possibility for multi threading
|
||||
//-----------------------------------------------------------------------------
|
||||
// Define/Undefine Features forced by CONFIG_SYSTEM_xxx
|
||||
// Dependencies
|
||||
@@ -83,43 +84,43 @@
|
||||
// Configurations for LINUX (Tuxbox dbox2, coolstream)
|
||||
//-----------------------------------------------------------------------------
|
||||
#undef HTTPD_NAME
|
||||
#define HTTPD_NAME "nhttpd"
|
||||
#define HTTPD_STANDARD_PORT 80
|
||||
#define HTTPD_MAX_CONNECTIONS 10
|
||||
#define HTTPD_REQUEST_LOG "/tmp/httpd_log"
|
||||
#define SSL_PEMFILE HTTPD_CONFIGDIR "/server.pem"
|
||||
#define SSL_CA_FILE HTTPD_CONFIGDIR "/cacert.pem"
|
||||
#define LOG_FILE "/tmp/yhhtpd.log"
|
||||
#define LOG_FORMAT ""
|
||||
#define UPLOAD_TMP_FILE "/tmp/upload.tmp"
|
||||
#define CACHE_DIR "/tmp/.cache"
|
||||
#define HTTPD_ERRORPAGE "/Y_ErrorPage.yhtm"
|
||||
#define HTTPD_SENDFILE_EXT "htm:text/html,html:text/html,xml:text/xml,txt:text/plain,jpg:image/jpeg,jpeg:image/jpeg,gif:image/gif,png:image/png,bmp:image/bmp,css:text/css,js:text/plain,img:application/octet-stream,ico:image/x-icon,m3u:application/octet-stream,tar:application/octet-stream,gz:text/x-gzip"
|
||||
#define HTTPD_SENDFILE_ALL "false"
|
||||
#define HTTPD_LANGUAGEDIR "languages"
|
||||
#define HTTPD_DEFAULT_LANGUAGE "English"
|
||||
#define AUTHUSER "root"
|
||||
#define HTTPD_NAME "nhttpd"
|
||||
#define HTTPD_STANDARD_PORT 80
|
||||
#define HTTPD_MAX_CONNECTIONS 10
|
||||
#define HTTPD_REQUEST_LOG "/tmp/httpd_log"
|
||||
#define SSL_PEMFILE HTTPD_CONFIGDIR "/server.pem"
|
||||
#define SSL_CA_FILE HTTPD_CONFIGDIR "/cacert.pem"
|
||||
#define LOG_FILE "/tmp/yhhtpd.log"
|
||||
#define LOG_FORMAT ""
|
||||
#define UPLOAD_TMP_FILE "/tmp/upload.tmp"
|
||||
#define CACHE_DIR "/tmp/.cache"
|
||||
#define HTTPD_ERRORPAGE "/Y_ErrorPage.yhtm"
|
||||
#define HTTPD_SENDFILE_EXT "htm:text/html,html:text/html,xml:text/xml,txt:text/plain,jpg:image/jpeg,jpeg:image/jpeg,gif:image/gif,png:image/png,bmp:image/bmp,css:text/css,js:text/plain,img:application/octet-stream,ico:image/x-icon,m3u:application/octet-stream,tar:application/octet-stream,gz:text/x-gzip"
|
||||
#define HTTPD_SENDFILE_ALL "false"
|
||||
#define HTTPD_LANGUAGEDIR "languages"
|
||||
#define HTTPD_DEFAULT_LANGUAGE "English"
|
||||
#define AUTHUSER "root"
|
||||
|
||||
#define HTTPD_CONFIGDIR "/var/tuxbox/config"
|
||||
#define HTTPD_CONFIGDIR "/var/tuxbox/config"
|
||||
#define HTTPD_CONFIGFILE HTTPD_CONFIGDIR "/nhttpd.conf"
|
||||
#define PUBLICDOCUMENTROOT "/var/httpd"
|
||||
#define NEUTRINO_CONFIGFILE "/var/tuxbox/config/neutrino.conf"
|
||||
#define HOSTEDDOCUMENTROOT "/mnt/hosted"
|
||||
#define EXTRASDOCUMENTROOT "/mnt/hosted/extras"
|
||||
#define EXTRASDOCUMENTURL "/hosted/extras"
|
||||
#define ZAPITXMLPATH "/var/tuxbox/config/zapit"
|
||||
#define TUXBOX_LOGOS_URL ""
|
||||
#define PUBLICDOCUMENTROOT "/var/httpd"
|
||||
#define NEUTRINO_CONFIGFILE "/var/tuxbox/config/neutrino.conf"
|
||||
#define HOSTEDDOCUMENTROOT "/mnt/hosted"
|
||||
#define EXTRASDOCUMENTROOT "/mnt/hosted/extras"
|
||||
#define EXTRASDOCUMENTURL "/hosted/extras"
|
||||
#define ZAPITXMLPATH "/var/tuxbox/config/zapit"
|
||||
#define TUXBOX_LOGOS_URL ""
|
||||
|
||||
// switch for Box differences
|
||||
#ifdef CONFIG_SYSTEM_TUXBOX
|
||||
#define AUTHPASSWORD "dbox2"
|
||||
#define PRIVATEDOCUMENTROOT "/share/tuxbox/neutrino/httpd-y"
|
||||
#define AUTHPASSWORD "dbox2"
|
||||
#define PRIVATEDOCUMENTROOT "/share/tuxbox/neutrino/httpd-y"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYSTEM_TUXBOX_COOLSTREAM
|
||||
#define AUTHPASSWORD "coolstream"
|
||||
#define PRIVATEDOCUMENTROOT "/share/tuxbox/neutrino/httpd"
|
||||
#undef Y_CONFIG_BUILD_AS_DAEMON // No Daemon
|
||||
#define AUTHPASSWORD "coolstream"
|
||||
#define PRIVATEDOCUMENTROOT "/share/tuxbox/neutrino/httpd"
|
||||
#undef Y_CONFIG_BUILD_AS_DAEMON // No Daemon
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
// Aggregated definitions
|
||||
|
@@ -70,21 +70,21 @@ static void sig_catch(int msignal)
|
||||
{
|
||||
aprintf("!!! SIGNAL !!! :%d!\n",msignal);
|
||||
switch (msignal) {
|
||||
// case SIGTERM:
|
||||
// case SIGINT:
|
||||
// case SIGTERM:
|
||||
// case SIGINT:
|
||||
|
||||
case SIGPIPE:
|
||||
case SIGPIPE:
|
||||
aprintf("got signal PIPE, nice!\n");
|
||||
break;
|
||||
case SIGHUP:
|
||||
case SIGUSR1:
|
||||
case SIGHUP:
|
||||
case SIGUSR1:
|
||||
aprintf("got signal HUP/USR1, reading config\n");
|
||||
if (yhttpd)
|
||||
yhttpd->ReadConfig();
|
||||
yhttpd->ReadConfig();
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
aprintf("No special SIGNAL-Handler:%d!\n",msignal);
|
||||
// log_level_printf(1, "Got SIGTERM\n");
|
||||
// log_level_printf(1, "Got SIGTERM\n");
|
||||
Cyhttpd::sig_do_shutdown = 1;
|
||||
yhttpd->stop_webserver();
|
||||
delete yhttpd;
|
||||
@@ -96,8 +96,7 @@ static void sig_catch(int msignal)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void yhttpd_reload_config()
|
||||
{
|
||||
void yhttpd_reload_config() {
|
||||
if (yhttpd)
|
||||
yhttpd->ReadConfig();
|
||||
}
|
||||
@@ -105,15 +104,13 @@ void yhttpd_reload_config()
|
||||
// Main Entry
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef Y_CONFIG_BUILD_AS_DAEMON
|
||||
void * nhttpd_main_thread(void *)
|
||||
{
|
||||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
void * nhttpd_main_thread(void *) {
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
aprintf("Webserver %s tid %ld\n", WEBSERVERNAME, syscall(__NR_gettid));
|
||||
yhttpd = new Cyhttpd();
|
||||
//CLogging::getInstance()->setDebug(true);
|
||||
//CLogging::getInstance()->LogLevel = 9;
|
||||
if(!yhttpd)
|
||||
{
|
||||
//CLogging::getInstance()->setDebug(true);
|
||||
//CLogging::getInstance()->LogLevel = 9;
|
||||
if (!yhttpd) {
|
||||
aprintf("Error initializing WebServer\n");
|
||||
return (void *) EXIT_FAILURE;
|
||||
}
|
||||
@@ -121,8 +118,7 @@ void * nhttpd_main_thread(void *)
|
||||
|
||||
yhttpd->hooks_attach();
|
||||
yhttpd->ReadConfig();
|
||||
if(yhttpd->Configure())
|
||||
{
|
||||
if (yhttpd->Configure()) {
|
||||
// Start Webserver: fork ist if not in debug mode
|
||||
aprintf("Webserver starting...\n");
|
||||
dprintf("Start in Debug-Mode\n"); // non forked debugging loop
|
||||
@@ -174,7 +170,7 @@ int main(int argc, char **argv)
|
||||
else if ((!strncmp(argv[i], "-l", 2)) )
|
||||
{
|
||||
if(argv[i][2] >= '0' && argv[i][2] <= '9')
|
||||
CLogging::getInstance()->LogLevel = (argv[i][2]-'0');
|
||||
CLogging::getInstance()->LogLevel = (argv[i][2]-'0');
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -189,7 +185,7 @@ int main(int argc, char **argv)
|
||||
signal(SIGUSR1, sig_catch);
|
||||
signal(SIGTERM, sig_catch);
|
||||
signal(SIGCLD, SIG_IGN);
|
||||
// signal(SIGALRM, sig_catch);
|
||||
// signal(SIGALRM, sig_catch);
|
||||
|
||||
yhttpd->hooks_attach();
|
||||
yhttpd->ReadConfig();
|
||||
@@ -201,12 +197,12 @@ int main(int argc, char **argv)
|
||||
{
|
||||
log_level_printf(9,"do fork\n");
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
case -1:
|
||||
dperror("fork");
|
||||
return -1;
|
||||
case 0:
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -229,15 +225,13 @@ int main(int argc, char **argv)
|
||||
//=============================================================================
|
||||
// Class yhttpd
|
||||
//=============================================================================
|
||||
Cyhttpd::Cyhttpd()
|
||||
{
|
||||
Cyhttpd::Cyhttpd() {
|
||||
webserver = new CWebserver();
|
||||
flag_threading_off = false;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
Cyhttpd::~Cyhttpd()
|
||||
{
|
||||
if(webserver)
|
||||
Cyhttpd::~Cyhttpd() {
|
||||
if (webserver)
|
||||
delete webserver;
|
||||
webserver = NULL;
|
||||
}
|
||||
@@ -245,10 +239,9 @@ Cyhttpd::~Cyhttpd()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Change to Root
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Cyhttpd::Configure()
|
||||
{
|
||||
bool Cyhttpd::Configure() {
|
||||
|
||||
if(!getuid()) // you must be root to do that!
|
||||
if (!getuid()) // you must be root to do that!
|
||||
{
|
||||
// Get user and group data
|
||||
#ifdef Y_CONFIG_FEATURE_HTTPD_USER
|
||||
@@ -276,7 +269,7 @@ bool Cyhttpd::Configure()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// change root directory
|
||||
// change root directory
|
||||
#ifdef Y_CONFIG_FEATURE_CHROOT
|
||||
if(!ConfigList["server.chroot"].empty())
|
||||
{
|
||||
@@ -305,7 +298,7 @@ bool Cyhttpd::Configure()
|
||||
setgroups(0, NULL);
|
||||
// set user group
|
||||
if(groupname != "")
|
||||
initgroups(username.c_str(), grp->gr_gid);
|
||||
initgroups(username.c_str(), grp->gr_gid);
|
||||
// set user
|
||||
if(setuid(pwd->pw_uid) == -1)
|
||||
{
|
||||
@@ -320,32 +313,27 @@ bool Cyhttpd::Configure()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main Webserver call
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cyhttpd::run()
|
||||
{
|
||||
if(webserver)
|
||||
{
|
||||
if(flag_threading_off)
|
||||
void Cyhttpd::run() {
|
||||
if (webserver) {
|
||||
if (flag_threading_off)
|
||||
webserver->is_threading = false;
|
||||
webserver->run();
|
||||
stop_webserver();
|
||||
}
|
||||
else
|
||||
} else
|
||||
aprintf("Error initializing WebServer\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Show Version Text and Number
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cyhttpd::version(FILE *dest)
|
||||
{
|
||||
void Cyhttpd::version(FILE *dest) {
|
||||
fprintf(dest, "%s - Webserver v%s\n", HTTPD_NAME, HTTPD_VERSION);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Show Usage
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cyhttpd::usage(FILE *dest)
|
||||
{
|
||||
void Cyhttpd::usage(FILE *dest) {
|
||||
version(dest);
|
||||
fprintf(dest, "command line parameters:\n");
|
||||
fprintf(dest, "-d, --debug enable debugging code (implies -f)\n");
|
||||
@@ -359,8 +347,7 @@ void Cyhttpd::usage(FILE *dest)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stop WebServer
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cyhttpd::stop_webserver()
|
||||
{
|
||||
void Cyhttpd::stop_webserver() {
|
||||
aprintf("stop requested......\n");
|
||||
if (webserver) {
|
||||
webserver->stop();
|
||||
@@ -370,8 +357,7 @@ void Cyhttpd::stop_webserver()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Attach hooks (use hook order carefully)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cyhttpd::hooks_attach()
|
||||
{
|
||||
void Cyhttpd::hooks_attach() {
|
||||
#ifdef Y_CONFIG_USE_AUTHHOOK
|
||||
// First Check Authentication
|
||||
auth = new CmAuth();
|
||||
@@ -410,8 +396,7 @@ void Cyhttpd::hooks_attach()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Detach hooks & Destroy
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cyhttpd::hooks_detach()
|
||||
{
|
||||
void Cyhttpd::hooks_detach() {
|
||||
#ifdef Y_CONFIG_USE_AUTHHOOK
|
||||
CyhookHandler::detach(auth);
|
||||
delete auth;
|
||||
@@ -448,95 +433,128 @@ void Cyhttpd::hooks_detach()
|
||||
// Read Webserver Configurationfile
|
||||
// Call "Hooks_ReadConfig" so Hooks can read/write own Configuration Values
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cyhttpd::ReadConfig(void)
|
||||
{
|
||||
log_level_printf(3,"ReadConfig Start\n");
|
||||
void Cyhttpd::ReadConfig(void) {
|
||||
log_level_printf(3, "ReadConfig Start\n");
|
||||
CConfigFile *Config = new CConfigFile(',');
|
||||
bool have_config = false;
|
||||
if(access(HTTPD_CONFIGFILE,4) == 0)
|
||||
if (access(HTTPD_CONFIGFILE, 4) == 0)
|
||||
have_config = true;
|
||||
Config->loadConfig(HTTPD_CONFIGFILE);
|
||||
// convert old config files
|
||||
if(have_config)
|
||||
{
|
||||
if(Config->getInt32("configfile.version",0) == 0)
|
||||
{
|
||||
if (have_config) {
|
||||
if (Config->getInt32("configfile.version", 0) == 0) {
|
||||
CConfigFile OrgConfig = *Config;
|
||||
Config->clear();
|
||||
|
||||
Config->setInt32("server.log.loglevel", OrgConfig.getInt32("LogLevel", 0));
|
||||
Config->setInt32("server.log.loglevel", OrgConfig.getInt32(
|
||||
"LogLevel", 0));
|
||||
Config->setInt32("configfile.version", CONF_VERSION);
|
||||
Config->setString("webserver.websites", "WebsiteMain");
|
||||
Config->setBool("webserver.threading", OrgConfig.getBool("THREADS", true));
|
||||
Config->setInt32("WebsiteMain.port",OrgConfig.getInt32("Port", HTTPD_STANDARD_PORT));
|
||||
Config->setString("WebsiteMain.directory", OrgConfig.getString("PrivatDocRoot", PRIVATEDOCUMENTROOT));
|
||||
if(OrgConfig.getString("PublicDocRoot", "") != "")
|
||||
Config->setString("WebsiteMain.override_directory", OrgConfig.getString("PublicDocRoot", PRIVATEDOCUMENTROOT));
|
||||
if(OrgConfig.getString("HostedDocRoot", "") != "")
|
||||
Config->setString("WebsiteMain.special_locations", "/hosted/="+OrgConfig.getString("HostedDocRoot", PRIVATEDOCUMENTROOT));
|
||||
if(OrgConfig.getString("HostedDocRoot", "") != "")
|
||||
Config->setString("Tuxbox.HostedDocumentRoot", OrgConfig.getString("HostedDocRoot", PRIVATEDOCUMENTROOT));
|
||||
Config->setBool("webserver.threading", OrgConfig.getBool("THREADS",
|
||||
true));
|
||||
Config->setInt32("WebsiteMain.port", OrgConfig.getInt32("Port",
|
||||
HTTPD_STANDARD_PORT));
|
||||
Config->setString("WebsiteMain.directory", OrgConfig.getString(
|
||||
"PrivatDocRoot", PRIVATEDOCUMENTROOT));
|
||||
if (OrgConfig.getString("PublicDocRoot", "") != "")
|
||||
Config->setString("WebsiteMain.override_directory",
|
||||
OrgConfig.getString("PublicDocRoot",
|
||||
PRIVATEDOCUMENTROOT));
|
||||
// mod_auth
|
||||
Config->setString("mod_auth.username", OrgConfig.getString("AuthUser", AUTHUSER));
|
||||
Config->setString("mod_auth.password", OrgConfig.getString("AuthPassword", AUTHPASSWORD));
|
||||
Config->setString("mod_auth.no_auth_client", OrgConfig.getString("NoAuthClient", ""));
|
||||
Config->setString("mod_auth.authenticate", OrgConfig.getString("Authenticate", "false"));
|
||||
Config->setString("mod_auth.username", OrgConfig.getString(
|
||||
"AuthUser", AUTHUSER));
|
||||
Config->setString("mod_auth.password", OrgConfig.getString(
|
||||
"AuthPassword", AUTHPASSWORD));
|
||||
Config->setString("mod_auth.no_auth_client", OrgConfig.getString(
|
||||
"NoAuthClient", ""));
|
||||
Config->setString("mod_auth.authenticate", OrgConfig.getString(
|
||||
"Authenticate", "false"));
|
||||
|
||||
Config->setString("mod_sendfile.mime_types", HTTPD_SENDFILE_EXT);
|
||||
|
||||
Config->saveConfig(HTTPD_CONFIGFILE);
|
||||
|
||||
}
|
||||
if (Config->getInt32("configfile.version") < 2)
|
||||
{
|
||||
// Add Defaults for Version 2
|
||||
if (Config->getInt32("configfile.version") < 2) {
|
||||
Config->setString("mod_sendfile.mime_types", HTTPD_SENDFILE_EXT);
|
||||
Config->setInt32("configfile.version", CONF_VERSION);
|
||||
Config->setString("mod_sendfile.sendAll","false");
|
||||
Config->setString("mod_sendfile.sendAll", "false");
|
||||
Config->saveConfig(HTTPD_CONFIGFILE);
|
||||
}
|
||||
if (Config->getInt32("configfile.version") < 4)
|
||||
{
|
||||
// Add Defaults for Version 4
|
||||
if (Config->getInt32("configfile.version") < 4) {
|
||||
Config->setInt32("configfile.version", CONF_VERSION);
|
||||
Config->setString("Language.selected", HTTPD_DEFAULT_LANGUAGE);
|
||||
Config->setString("Language.directory", HTTPD_LANGUAGEDIR);
|
||||
if (Config->getString("WebsiteMain.hosted_directory", "") == "")
|
||||
Config->setString("WebsiteMain.hosted_directory", "/var/hosted");
|
||||
Config->saveConfig(HTTPD_CONFIGFILE);
|
||||
}
|
||||
}
|
||||
// configure debugging & logging
|
||||
if(CLogging::getInstance()->LogLevel == 0)
|
||||
CLogging::getInstance()->LogLevel = Config->getInt32("server.log.loglevel", 0);
|
||||
if (CLogging::getInstance()->LogLevel == 0)
|
||||
CLogging::getInstance()->LogLevel = Config->getInt32(
|
||||
"server.log.loglevel", 0);
|
||||
|
||||
// get variables
|
||||
webserver->init(Config->getInt32("WebsiteMain.port", HTTPD_STANDARD_PORT), Config->getBool("webserver.threading", true));
|
||||
webserver->init(Config->getInt32("WebsiteMain.port", HTTPD_STANDARD_PORT),
|
||||
Config->getBool("webserver.threading", true));
|
||||
// informational use
|
||||
ConfigList["WebsiteMain.port"]= itoa(Config->getInt32("WebsiteMain.port", HTTPD_STANDARD_PORT));
|
||||
ConfigList["webserver.threading"]= Config->getString("webserver.threading", "true");
|
||||
ConfigList["configfile.version"]= Config->getInt32("configfile.version", CONF_VERSION);
|
||||
ConfigList["server.log.loglevel"]= itoa(Config->getInt32("server.log.loglevel", 0));
|
||||
ConfigList["server.no_keep-alive_ips"]= Config->getString("server.no_keep-alive_ips", "");
|
||||
webserver->conf_no_keep_alive_ips = Config->getStringVector("server.no_keep-alive_ips");
|
||||
ConfigList["WebsiteMain.port"] = itoa(Config->getInt32("WebsiteMain.port",
|
||||
HTTPD_STANDARD_PORT));
|
||||
ConfigList["webserver.threading"] = Config->getString(
|
||||
"webserver.threading", "true");
|
||||
ConfigList["configfile.version"] = Config->getInt32("configfile.version",
|
||||
CONF_VERSION);
|
||||
ConfigList["server.log.loglevel"] = itoa(Config->getInt32(
|
||||
"server.log.loglevel", 0));
|
||||
ConfigList["server.no_keep-alive_ips"] = Config->getString(
|
||||
"server.no_keep-alive_ips", "");
|
||||
webserver->conf_no_keep_alive_ips = Config->getStringVector(
|
||||
"server.no_keep-alive_ips");
|
||||
|
||||
// MainSite
|
||||
ConfigList["PrivatDocumentRoot"]= Config->getString("WebsiteMain.directory", PRIVATEDOCUMENTROOT);
|
||||
ConfigList["PublicDocumentRoot"]= Config->getString("WebsiteMain.override_directory", PUBLICDOCUMENTROOT);
|
||||
ConfigList["HostedDocumentRoot"]= Config->getString("Tuxbox.HostedDocumentRoot", HOSTEDDOCUMENTROOT);
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
ConfigList["SSL"] = Config->getString("WebsiteMain.ssl", "false");
|
||||
ConfigList["SSL_pemfile"] = Config->getString("WebsiteMain.ssl_pemfile", SSL_PEMFILE);
|
||||
ConfigList["SSL_CA_file"] = Config->getString("WebsiteMain.ssl_ca_file", SSL_CA_FILE);
|
||||
ConfigList["WebsiteMain.directory"] = Config->getString(
|
||||
"WebsiteMain.directory", PRIVATEDOCUMENTROOT);
|
||||
ConfigList["WebsiteMain.override_directory"] = Config->getString(
|
||||
"WebsiteMain.override_directory", PUBLICDOCUMENTROOT);
|
||||
ConfigList["WebsiteMain.hosted_directory"] = Config->getString(
|
||||
"WebsiteMain.hosted_directory", HOSTEDDOCUMENTROOT);
|
||||
|
||||
CySocket::SSL_pemfile = ConfigList["SSL_pemfile"];
|
||||
CySocket::SSL_CA_file = ConfigList["SSL_CA_file"];
|
||||
// Check location of logos
|
||||
if (Config->getString("Tuxbox.LogosURL", "") == "") {
|
||||
if (access(std::string(ConfigList["WebsiteMain.directory"] + "/logos").c_str(), 4) == 0) {
|
||||
Config->setString("Tuxbox.LogosURL", ConfigList["WebsiteMain.directory"] + "/logos");
|
||||
have_config = false; //save config
|
||||
}
|
||||
else if (access(std::string(ConfigList["WebsiteMain.override_directory"] ).c_str(), 4) == 0){
|
||||
Config->setString("Tuxbox.LogosURL", ConfigList["WebsiteMain.override_directory"] + "/logos");
|
||||
have_config = false; //save config
|
||||
}
|
||||
}
|
||||
ConfigList["Tuxbox.LogosURL"] = Config->getString("Tuxbox.LogosURL", "");
|
||||
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
ConfigList["SSL"] = Config->getString("WebsiteMain.ssl", "false");
|
||||
ConfigList["SSL_pemfile"] = Config->getString("WebsiteMain.ssl_pemfile", SSL_PEMFILE);
|
||||
ConfigList["SSL_CA_file"] = Config->getString("WebsiteMain.ssl_ca_file", SSL_CA_FILE);
|
||||
|
||||
CySocket::SSL_pemfile = ConfigList["SSL_pemfile"];
|
||||
CySocket::SSL_CA_file = ConfigList["SSL_CA_file"];
|
||||
if(ConfigList["SSL"] == "true")
|
||||
CySocket::initSSL();
|
||||
CySocket::initSSL();
|
||||
#endif
|
||||
ConfigList["server.user_name"]= Config->getString("server.user_name", "");
|
||||
ConfigList["server.group_name"]= Config->getString("server.group_name", "");
|
||||
ConfigList["server.chroot"]= Config->getString("server.chroot", "");
|
||||
ConfigList["server.user_name"] = Config->getString("server.user_name", "");
|
||||
ConfigList["server.group_name"]
|
||||
= Config->getString("server.group_name", "");
|
||||
ConfigList["server.chroot"] = Config->getString("server.chroot", "");
|
||||
|
||||
// language
|
||||
ConfigList["Language.directory"]=Config->getString("Language.directory", HTTPD_LANGUAGEDIR);
|
||||
ConfigList["Language.selected"]=Config->getString("Language.selected", HTTPD_DEFAULT_LANGUAGE);
|
||||
ConfigList["Language.directory"] = Config->getString("Language.directory",
|
||||
HTTPD_LANGUAGEDIR);
|
||||
ConfigList["Language.selected"] = Config->getString("Language.selected",
|
||||
HTTPD_DEFAULT_LANGUAGE);
|
||||
yhttpd->ReadLanguage();
|
||||
|
||||
// Read App specifig settings by Hook
|
||||
@@ -545,16 +563,16 @@ void Cyhttpd::ReadConfig(void)
|
||||
// Save if new defaults are set
|
||||
if (!have_config)
|
||||
Config->saveConfig(HTTPD_CONFIGFILE);
|
||||
log_level_printf(3,"ReadConfig End\n");
|
||||
log_level_printf(3, "ReadConfig End\n");
|
||||
delete Config;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read Webserver Configurationfile for languages
|
||||
//-----------------------------------------------------------------------------
|
||||
void Cyhttpd::ReadLanguage(void)
|
||||
{
|
||||
void Cyhttpd::ReadLanguage(void) {
|
||||
// Init Class vars
|
||||
CLanguage *lang = CLanguage::getInstance();
|
||||
log_level_printf(3,"ReadLanguage:%s\n",ConfigList["Language.selected"].c_str());
|
||||
log_level_printf(3, "ReadLanguage:%s\n",
|
||||
ConfigList["Language.selected"].c_str());
|
||||
lang->setLanguage(ConfigList["Language.selected"]);
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
// Main Class
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cyhttpd
|
||||
// Main Function and Class for Handlicg the Webserver-Application
|
||||
// Main Function and Class for Handling the Webserver-Application
|
||||
// - Handles Command Line Input
|
||||
// - Reads and Handles "ReadConfig" (inclusive Hooking)
|
||||
// - Creates Webserver and start them listening
|
||||
@@ -18,16 +18,14 @@
|
||||
#include "ytypes_globals.h"
|
||||
#include "ywebserver.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class Cyhttpd
|
||||
{
|
||||
class Cyhttpd {
|
||||
private:
|
||||
CWebserver *webserver; // Aggregation of Webserver (now: only one)
|
||||
CWebserver *webserver; // Aggregation of Webserver (now: only one)
|
||||
|
||||
public:
|
||||
bool flag_threading_off; // switch of Connection Threading
|
||||
static CStringList ConfigList; // Vars & Values from ReadConfig
|
||||
bool flag_threading_off; // switch of Connection Threading
|
||||
static CStringList ConfigList; // Vars & Values from ReadConfig
|
||||
|
||||
// signal handler
|
||||
static volatile sig_atomic_t sig_do_shutdown;
|
||||
@@ -37,16 +35,16 @@ public:
|
||||
~Cyhttpd();
|
||||
|
||||
// Main Programm calls
|
||||
void run(); // Init Hooks, ReadConfig, Start Webserver
|
||||
bool Configure();
|
||||
void stop_webserver(); // Remove Hooks, Stop Webserver
|
||||
static void version(FILE *dest); // Show Webserver Version
|
||||
static void usage(FILE *dest); // Show command line usage
|
||||
void run(); // Init Hooks, ReadConfig, Start Webserver
|
||||
bool Configure();
|
||||
void stop_webserver(); // Remove Hooks, Stop Webserver
|
||||
static void version(FILE *dest);// Show Webserver Version
|
||||
static void usage(FILE *dest); // Show command line usage
|
||||
// Hooks
|
||||
void hooks_attach(); // Add a Hook-Class to HookList
|
||||
void hooks_detach(); // Remove a Hook-Class from HookList
|
||||
void ReadConfig(void); // Read the config file for the webserver
|
||||
void ReadLanguage(void); // Read Language Files
|
||||
void hooks_attach(); // Add a Hook-Class to HookList
|
||||
void hooks_detach(); // Remove a Hook-Class from HookList
|
||||
void ReadConfig(void); // Read the config file for the webserver
|
||||
void ReadLanguage(void); // Read Language Files
|
||||
};
|
||||
|
||||
#endif // __yhttpd_h__
|
||||
|
@@ -4,9 +4,9 @@
|
||||
//=============================================================================
|
||||
|
||||
// c
|
||||
#include <cstdio> // printf prototype.
|
||||
#include <cstdlib> // calloc and free prototypes.
|
||||
#include <cstring> // str* and memset prototypes.
|
||||
#include <cstdio> // printf prototype.
|
||||
#include <cstdlib> // calloc and free prototypes.
|
||||
#include <cstring> // str* and memset prototypes.
|
||||
#include <cstdarg>
|
||||
|
||||
// yhttpd
|
||||
@@ -21,10 +21,11 @@
|
||||
//-------------------------------------------------------------------------
|
||||
// Check and set integer inside boundaries (min, max)
|
||||
//-------------------------------------------------------------------------
|
||||
int minmax(int value,int min, int max)
|
||||
{
|
||||
if(value < min) return min;
|
||||
if(value > max) return max;
|
||||
int minmax(int value, int min, int max) {
|
||||
if (value < min)
|
||||
return min;
|
||||
if (value > max)
|
||||
return max;
|
||||
return value;
|
||||
}
|
||||
//=============================================================================
|
||||
@@ -33,15 +34,14 @@ int minmax(int value,int min, int max)
|
||||
//-------------------------------------------------------------------------
|
||||
// Check and set Date/Time (tm*) inside boundaries
|
||||
//-------------------------------------------------------------------------
|
||||
void correctTime(struct tm *zt)
|
||||
{
|
||||
void correctTime(struct tm *zt) {
|
||||
|
||||
zt->tm_year = minmax(zt->tm_year,0,129);
|
||||
zt->tm_mon = minmax(zt->tm_mon,0,11);
|
||||
zt->tm_mday = minmax(zt->tm_mday,1,31); //-> eine etwas laxe pruefung, aber mktime biegt das wieder grade
|
||||
zt->tm_hour = minmax(zt->tm_hour,0,23);
|
||||
zt->tm_min = minmax(zt->tm_min,0,59);
|
||||
zt->tm_sec = minmax(zt->tm_sec,0,59);
|
||||
zt->tm_year = minmax(zt->tm_year, 0, 129);
|
||||
zt->tm_mon = minmax(zt->tm_mon, 0, 11);
|
||||
zt->tm_mday = minmax(zt->tm_mday, 1, 31); //-> eine etwas laxe pruefung, aber mktime biegt das wieder grade
|
||||
zt->tm_hour = minmax(zt->tm_hour, 0, 23);
|
||||
zt->tm_min = minmax(zt->tm_min, 0, 59);
|
||||
zt->tm_sec = minmax(zt->tm_sec, 0, 59);
|
||||
}
|
||||
//=============================================================================
|
||||
// Strings
|
||||
@@ -49,23 +49,20 @@ void correctTime(struct tm *zt)
|
||||
//-------------------------------------------------------------------------
|
||||
// Integer to Hexadecimal-String
|
||||
//-------------------------------------------------------------------------
|
||||
std::string itoh(unsigned int conv)
|
||||
{
|
||||
return string_printf("0x%06x",conv);
|
||||
std::string itoh(unsigned int conv) {
|
||||
return string_printf("0x%06x", conv);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// Integer to String
|
||||
//-------------------------------------------------------------------------
|
||||
std::string itoa(unsigned int conv)
|
||||
{
|
||||
return string_printf("%u",conv);
|
||||
std::string itoa(unsigned int conv) {
|
||||
return string_printf("%u", conv);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// convert timer_t to "<hour>:<minutes>" String
|
||||
//-------------------------------------------------------------------------
|
||||
std::string timeString(time_t time)
|
||||
{
|
||||
char tmp[7]={'\0'};
|
||||
std::string timeString(time_t time) {
|
||||
char tmp[7] = { '\0' };
|
||||
struct tm *tm = localtime(&time);
|
||||
if (strftime(tmp, 6, "%H:%M", tm))
|
||||
return std::string(tmp);
|
||||
@@ -77,13 +74,11 @@ std::string timeString(time_t time)
|
||||
// max length up to bufferlen -> then snip
|
||||
//-------------------------------------------------------------------------
|
||||
#define bufferlen 4*1024
|
||||
std::string string_printf(const char *fmt, ...)
|
||||
{
|
||||
std::string string_printf(const char *fmt, ...) {
|
||||
char buffer[bufferlen];
|
||||
va_list arglist;
|
||||
va_start( arglist, fmt );
|
||||
if(arglist)
|
||||
vsnprintf( buffer, bufferlen, fmt, arglist );
|
||||
va_start(arglist, fmt);
|
||||
vsnprintf(buffer, bufferlen, fmt, arglist);
|
||||
va_end(arglist);
|
||||
return std::string(buffer);
|
||||
}
|
||||
@@ -91,16 +86,13 @@ std::string string_printf(const char *fmt, ...)
|
||||
// ySplitString: spit string "str" in two strings "left" and "right" at
|
||||
// one of the chars in "delimiter" returns true if delimiter found
|
||||
//-------------------------------------------------------------------------
|
||||
bool ySplitString(std::string str, std::string delimiter, std::string& left, std::string& right)
|
||||
{
|
||||
bool ySplitString(std::string str, std::string delimiter, std::string& left,
|
||||
std::string& right) {
|
||||
std::string::size_type pos;
|
||||
if ((pos = str.find_first_of(delimiter)) != std::string::npos)
|
||||
{
|
||||
if ((pos = str.find_first_of(delimiter)) != std::string::npos) {
|
||||
left = str.substr(0, pos);
|
||||
right = str.substr(pos + 1, str.length() - (pos + 1 ));
|
||||
}
|
||||
else
|
||||
{
|
||||
right = str.substr(pos + 1, str.length() - (pos + 1));
|
||||
} else {
|
||||
left = str; //default if not found
|
||||
right = "";
|
||||
}
|
||||
@@ -110,16 +102,14 @@ bool ySplitString(std::string str, std::string delimiter, std::string& left, std
|
||||
// ySplitString: spit string "str" in two strings "left" and "right" at
|
||||
// one of the chars in "delimiter" returns true if delimiter found
|
||||
//-------------------------------------------------------------------------
|
||||
bool ySplitStringExact(std::string str, std::string delimiter, std::string& left, std::string& right)
|
||||
{
|
||||
bool ySplitStringExact(std::string str, std::string delimiter,
|
||||
std::string& left, std::string& right) {
|
||||
std::string::size_type pos;
|
||||
if ((pos = str.find(delimiter)) != std::string::npos)
|
||||
{
|
||||
if ((pos = str.find(delimiter)) != std::string::npos) {
|
||||
left = str.substr(0, pos);
|
||||
right = str.substr(pos + delimiter.length(), str.length() - (pos + delimiter.length() ));
|
||||
}
|
||||
else
|
||||
{
|
||||
right = str.substr(pos + delimiter.length(), str.length() - (pos
|
||||
+ delimiter.length()));
|
||||
} else {
|
||||
left = str; //default if not found
|
||||
right = "";
|
||||
}
|
||||
@@ -129,16 +119,13 @@ bool ySplitStringExact(std::string str, std::string delimiter, std::string& left
|
||||
// ySplitStringRight: spit string "str" in two strings "left" and "right" at
|
||||
// one of the chars in "delimiter" returns true if delimiter found
|
||||
//-------------------------------------------------------------------------
|
||||
bool ySplitStringLast(std::string str, std::string delimiter, std::string& left, std::string& right)
|
||||
{
|
||||
bool ySplitStringLast(std::string str, std::string delimiter,
|
||||
std::string& left, std::string& right) {
|
||||
std::string::size_type pos;
|
||||
if ((pos = str.find_last_of(delimiter)) != std::string::npos)
|
||||
{
|
||||
if ((pos = str.find_last_of(delimiter)) != std::string::npos) {
|
||||
left = str.substr(0, pos);
|
||||
right = str.substr(pos + 1, str.length() - (pos + 1 ));
|
||||
}
|
||||
else
|
||||
{
|
||||
right = str.substr(pos + 1, str.length() - (pos + 1));
|
||||
} else {
|
||||
left = str; //default if not found
|
||||
right = "";
|
||||
}
|
||||
@@ -147,33 +134,29 @@ bool ySplitStringLast(std::string str, std::string delimiter, std::string& left,
|
||||
//-------------------------------------------------------------------------
|
||||
// ySplitStringVector: spit string "str" and build vector of strings
|
||||
//-------------------------------------------------------------------------
|
||||
CStringArray ySplitStringVector(std::string str, std::string delimiter)
|
||||
{
|
||||
CStringArray ySplitStringVector(std::string str, std::string delimiter) {
|
||||
std::string left, right, rest;
|
||||
bool found;
|
||||
CStringArray split;
|
||||
rest = str;
|
||||
do
|
||||
{
|
||||
do {
|
||||
found = ySplitString(rest, delimiter, left, right);
|
||||
split.push_back(left);
|
||||
rest = right;
|
||||
}
|
||||
while(found);
|
||||
} while (found);
|
||||
return split;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// trim whitespaces
|
||||
//-------------------------------------------------------------------------
|
||||
std::string trim(std::string const& source, char const* delims)
|
||||
{
|
||||
std::string trim(std::string const& source, char const* delims) {
|
||||
std::string result(source);
|
||||
std::string::size_type index = result.find_last_not_of(delims);
|
||||
if(index != std::string::npos)
|
||||
if (index != std::string::npos)
|
||||
result.erase(++index);
|
||||
|
||||
index = result.find_first_not_of(delims);
|
||||
if(index != std::string::npos)
|
||||
if (index != std::string::npos)
|
||||
result.erase(0, index);
|
||||
else
|
||||
result.erase();
|
||||
@@ -182,53 +165,45 @@ std::string trim(std::string const& source, char const* delims)
|
||||
//-------------------------------------------------------------------------
|
||||
// replace all occurrences find_what
|
||||
//-------------------------------------------------------------------------
|
||||
void replace(std::string &str, const std::string &find_what, const std::string &replace_with)
|
||||
{
|
||||
std::string::size_type pos=0;
|
||||
while((pos=str.find(find_what, pos))!=std::string::npos)
|
||||
{
|
||||
void replace(std::string &str, const std::string &find_what,
|
||||
const std::string &replace_with) {
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = str.find(find_what, pos)) != std::string::npos) {
|
||||
str.erase(pos, find_what.length());
|
||||
str.insert(pos, replace_with);
|
||||
pos+=replace_with.length();
|
||||
pos += replace_with.length();
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// equal-function for case insensitive compare
|
||||
//-------------------------------------------------------------------------
|
||||
bool nocase_compare (char c1, char c2)
|
||||
{
|
||||
bool nocase_compare(char c1, char c2) {
|
||||
return toupper(c1) == toupper(c2);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Decode URLEncoded std::string
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string decodeString(std::string encodedString)
|
||||
{
|
||||
std::string decodeString(std::string encodedString) {
|
||||
const char *string = encodedString.c_str();
|
||||
unsigned int count=0;
|
||||
char hex[3]={'\0'};
|
||||
unsigned int count = 0;
|
||||
char hex[3] = { '\0' };
|
||||
unsigned long iStr;
|
||||
std::string result = "";
|
||||
count = 0;
|
||||
|
||||
while(count<encodedString.length()) /* use the null character as a loop terminator */
|
||||
while (count < encodedString.length()) /* use the null character as a loop terminator */
|
||||
{
|
||||
if(string[count] == '%' && count+2 <encodedString.length())
|
||||
{
|
||||
hex[0]=string[count+1];
|
||||
hex[1]=string[count+2];
|
||||
hex[2]='\0';
|
||||
iStr = strtoul(hex,NULL,16); /* convert to Hex char */
|
||||
result += (char)iStr;
|
||||
if (string[count] == '%' && count + 2 < encodedString.length()) {
|
||||
hex[0] = string[count + 1];
|
||||
hex[1] = string[count + 2];
|
||||
hex[2] = '\0';
|
||||
iStr = strtoul(hex, NULL, 16); /* convert to Hex char */
|
||||
result += (char) iStr;
|
||||
count += 3;
|
||||
}
|
||||
else if(string[count] == '+')
|
||||
{
|
||||
} else if (string[count] == '+') {
|
||||
result += ' ';
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
result += string[count];
|
||||
count++;
|
||||
}
|
||||
@@ -238,29 +213,27 @@ std::string decodeString(std::string encodedString)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Encode URLEncoded std::string
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string encodeString(std::string decodedString)
|
||||
{
|
||||
unsigned int len = sizeof(char) * decodedString.length()*5 + 1;
|
||||
std::string result( len, '\0' );
|
||||
char *newString = (char *)result.c_str();
|
||||
char *dstring = (char *)decodedString.c_str();
|
||||
std::string encodeString(std::string decodedString) {
|
||||
unsigned int len = sizeof(char) * decodedString.length() * 5 + 1;
|
||||
std::string result(len, '\0');
|
||||
char *newString = (char *) result.c_str();
|
||||
char *dstring = (char *) decodedString.c_str();
|
||||
char one_char;
|
||||
if(len == result.length()) // got memory needed
|
||||
if (len == result.length()) // got memory needed
|
||||
{
|
||||
while((one_char = *dstring++)) /* use the null character as a loop terminator */
|
||||
while ((one_char = *dstring++)) /* use the null character as a loop terminator */
|
||||
{
|
||||
if(isalnum(one_char))
|
||||
if (isalnum(one_char))
|
||||
*newString++ = one_char;
|
||||
else
|
||||
newString += sprintf(newString, "&#%d;", (unsigned char) one_char);
|
||||
newString += sprintf(newString, "&#%d;",
|
||||
(unsigned char) one_char);
|
||||
}
|
||||
|
||||
*newString='\0'; /* when done copying the string,need to terminate w/ null char */
|
||||
result.resize((unsigned int)(newString - result.c_str()), '\0');
|
||||
*newString = '\0'; /* when done copying the string,need to terminate w/ null char */
|
||||
result.resize((unsigned int) (newString - result.c_str()), '\0');
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -268,9 +241,8 @@ std::string encodeString(std::string decodedString)
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns string in lower case
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string string_tolower(std::string str)
|
||||
{
|
||||
for(unsigned int i = 0; i < str.length(); i++)
|
||||
std::string string_tolower(std::string str) {
|
||||
for (unsigned int i = 0; i < str.length(); i++)
|
||||
str[i] = tolower(str[i]);
|
||||
return str;
|
||||
}
|
||||
@@ -278,16 +250,14 @@ std::string string_tolower(std::string str)
|
||||
//-----------------------------------------------------------------------------
|
||||
// write string to a file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool write_to_file(std::string filename, std::string content)
|
||||
{
|
||||
bool write_to_file(std::string filename, std::string content) {
|
||||
FILE *fd = NULL;
|
||||
if((fd = fopen(filename.c_str(),"w")) != NULL) // open file
|
||||
if ((fd = fopen(filename.c_str(), "w")) != NULL) // open file
|
||||
{
|
||||
fwrite(content.c_str(), content.length(), 1, fd);
|
||||
fflush(fd); // flush and close file
|
||||
fflush(fd); // flush and close file
|
||||
fclose(fd);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
@@ -21,46 +21,43 @@ long CWebserverConnection::GConnectionNumber = 0;
|
||||
//=============================================================================
|
||||
// Constructor & Destructor & Initialization
|
||||
//=============================================================================
|
||||
CWebserverConnection::CWebserverConnection(CWebserver *pWebserver)
|
||||
{
|
||||
Webserver = pWebserver;
|
||||
Request.Webserver = pWebserver;
|
||||
Request.Connection = this;
|
||||
Response.Webserver = pWebserver;
|
||||
Response.Connection = this;
|
||||
Method = M_UNKNOWN;
|
||||
HttpStatus = 0;
|
||||
RequestCanceled = false;
|
||||
CWebserverConnection::CWebserverConnection(CWebserver *pWebserver) {
|
||||
Webserver = pWebserver;
|
||||
Request.Webserver = pWebserver;
|
||||
Request.Connection = this;
|
||||
Response.Webserver = pWebserver;
|
||||
Response.Connection = this;
|
||||
Method = M_UNKNOWN;
|
||||
HttpStatus = 0;
|
||||
RequestCanceled = false;
|
||||
#ifdef Y_CONFIG_FEATURE_KEEP_ALIVE
|
||||
keep_alive = true;
|
||||
keep_alive = true;
|
||||
#else
|
||||
keep_alive = false;
|
||||
keep_alive = false;
|
||||
#endif
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
CWebserverConnection::CWebserverConnection()
|
||||
{
|
||||
// aprintf("test CWebserverConnection::CWebserverConnection()\n");
|
||||
CWebserverConnection::CWebserverConnection() {
|
||||
// aprintf("test CWebserverConnection::CWebserverConnection()\n");
|
||||
ConnectionNumber = ++GConnectionNumber;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
CWebserverConnection::~CWebserverConnection(void)
|
||||
{
|
||||
CWebserverConnection::~CWebserverConnection(void) {
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// End The Connection. Request and Response allready handled.
|
||||
// do "after done" work, like create a www-Log entry.
|
||||
// Use "Hooks_EndConnection()" Handler to write own Hooks.
|
||||
//-------------------------------------------------------------------------
|
||||
void CWebserverConnection::EndConnection()
|
||||
{
|
||||
HookHandler.HookVarList["enlapsed_request"] = itoa(enlapsed_request/1000);
|
||||
HookHandler.HookVarList["enlapsed_response"] = itoa(enlapsed_response/1000);
|
||||
HookHandler.Hooks_EndConnection(); // Handle Hooks
|
||||
if(RequestCanceled) // Canceled
|
||||
void CWebserverConnection::EndConnection() {
|
||||
HookHandler.HookVarList["enlapsed_request"] = itoa(enlapsed_request / 1000);
|
||||
HookHandler.HookVarList["enlapsed_response"] = itoa(enlapsed_response
|
||||
/ 1000);
|
||||
HookHandler.Hooks_EndConnection(); // Handle Hooks
|
||||
if (RequestCanceled) // Canceled
|
||||
keep_alive = false;
|
||||
RequestCanceled = true;
|
||||
// sock->Flush();
|
||||
// sock->Flush();
|
||||
#ifndef Y_CONFIG_FEATURE_KEEP_ALIVE
|
||||
sock->close();
|
||||
#endif
|
||||
@@ -69,24 +66,25 @@ void CWebserverConnection::EndConnection()
|
||||
// Main
|
||||
// Handle the Request, Handle (Send) Response), End the Connection
|
||||
//-------------------------------------------------------------------------
|
||||
void CWebserverConnection::HandleConnection()
|
||||
{
|
||||
void CWebserverConnection::HandleConnection() {
|
||||
gettimeofday(&tv_connection_start, &tz_connection_start);
|
||||
|
||||
// get the request
|
||||
if (Request.HandleRequest())
|
||||
{
|
||||
if (Request.HandleRequest()) {
|
||||
// determine time from Connection creation until now
|
||||
gettimeofday(&tv_connection_Response_start, &tz_connection_Response_start);
|
||||
enlapsed_request = ((tv_connection_Response_start.tv_sec - tv_connection_start.tv_sec) * 1000000
|
||||
+ (tv_connection_Response_start.tv_usec - tv_connection_start.tv_usec));
|
||||
gettimeofday(&tv_connection_Response_start,
|
||||
&tz_connection_Response_start);
|
||||
enlapsed_request = ((tv_connection_Response_start.tv_sec
|
||||
- tv_connection_start.tv_sec) * 1000000
|
||||
+ (tv_connection_Response_start.tv_usec
|
||||
- tv_connection_start.tv_usec));
|
||||
|
||||
// Keep-Alive checking
|
||||
#ifdef Y_CONFIG_FEATURE_KEEP_ALIVE
|
||||
if(string_tolower(Request.HeaderList["Connection"]) == "close"
|
||||
|| (httprotocol != "HTTP/1.1" && string_tolower(Request.HeaderList["Connection"]) != "keep-alive")
|
||||
|| !Webserver->CheckKeepAliveAllowedByIP(sock->get_client_ip()))
|
||||
keep_alive = false;
|
||||
if(string_tolower(Request.HeaderList["Connection"]) == "close"
|
||||
|| (httprotocol != "HTTP/1.1" && string_tolower(Request.HeaderList["Connection"]) != "keep-alive")
|
||||
|| !Webserver->CheckKeepAliveAllowedByIP(sock->get_client_ip()))
|
||||
keep_alive = false;
|
||||
#else
|
||||
keep_alive = false;
|
||||
#endif
|
||||
@@ -95,40 +93,39 @@ void CWebserverConnection::HandleConnection()
|
||||
|
||||
// determine time for SendResponse
|
||||
gettimeofday(&tv_connection_Response_end, &tz_connection_Response_end);
|
||||
enlapsed_response = ((tv_connection_Response_end.tv_sec - tv_connection_Response_start.tv_sec) * 1000000
|
||||
+ (tv_connection_Response_end.tv_usec - tv_connection_Response_start.tv_usec));
|
||||
enlapsed_response = ((tv_connection_Response_end.tv_sec
|
||||
- tv_connection_Response_start.tv_sec) * 1000000
|
||||
+ (tv_connection_Response_end.tv_usec
|
||||
- tv_connection_Response_start.tv_usec));
|
||||
|
||||
// print production times
|
||||
log_level_printf(1,"enlapsed time request:%ld response:%ld url:%s\n",
|
||||
enlapsed_request, enlapsed_response, (Request.UrlData["fullurl"]).c_str());
|
||||
log_level_printf(1, "enlapsed time request:%ld response:%ld url:%s\n",
|
||||
enlapsed_request, enlapsed_response,
|
||||
(Request.UrlData["fullurl"]).c_str());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
RequestCanceled = true;
|
||||
keep_alive = false; // close this connection socket
|
||||
// dperror("Error while parsing request\n");
|
||||
log_level_printf(1,"request canceled: %s\n", strerror(errno));
|
||||
keep_alive = false; // close this connection socket
|
||||
// dperror("Error while parsing request\n");
|
||||
log_level_printf(1, "request canceled: %s\n", strerror(errno));
|
||||
}
|
||||
EndConnection();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void CWebserverConnection::ShowEnlapsedRequest(char *text)
|
||||
{
|
||||
void CWebserverConnection::ShowEnlapsedRequest(char *text) {
|
||||
|
||||
long enlapsed = GetEnlapsedRequestTime() / 1000;
|
||||
log_level_printf(1,"enlapsed-f-start (%s) t:%ld url:%s\n",
|
||||
text, enlapsed, (Request.UrlData["fullurl"]).c_str());
|
||||
long enlapsed = GetEnlapsedRequestTime() / 1000;
|
||||
log_level_printf(1, "enlapsed-f-start (%s) t:%ld url:%s\n", text, enlapsed,
|
||||
(Request.UrlData["fullurl"]).c_str());
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// Time from creation of socket until now in microseconds!
|
||||
//-------------------------------------------------------------------------
|
||||
long CWebserverConnection::GetEnlapsedRequestTime()
|
||||
{
|
||||
struct timeval tv_now;
|
||||
struct timezone tz_now;
|
||||
gettimeofday(&tv_now, &tz_now);
|
||||
long CWebserverConnection::GetEnlapsedRequestTime() {
|
||||
struct timeval tv_now;
|
||||
struct timezone tz_now;
|
||||
gettimeofday(&tv_now, &tz_now);
|
||||
return ((tv_now.tv_sec - tv_connection_start.tv_sec) * 1000000
|
||||
+ (tv_now.tv_usec - tv_connection_start.tv_usec));
|
||||
}
|
||||
@@ -136,11 +133,10 @@ long CWebserverConnection::GetEnlapsedRequestTime()
|
||||
//-------------------------------------------------------------------------
|
||||
// Time from beginning of response until now in microseconds!
|
||||
//-------------------------------------------------------------------------
|
||||
long CWebserverConnection::GetEnlapsedResponseTime()
|
||||
{
|
||||
struct timeval tv_now;
|
||||
struct timezone tz_now;
|
||||
gettimeofday(&tv_now, &tz_now);
|
||||
long CWebserverConnection::GetEnlapsedResponseTime() {
|
||||
struct timeval tv_now;
|
||||
struct timezone tz_now;
|
||||
gettimeofday(&tv_now, &tz_now);
|
||||
return ((tv_now.tv_sec - tv_connection_Response_start.tv_sec) * 1000000
|
||||
+ (tv_now.tv_usec - tv_connection_Response_start.tv_usec));
|
||||
}
|
||||
|
@@ -25,22 +25,22 @@ THookList CyhookHandler::HookList;
|
||||
// Hook Dispatcher for Session Hooks
|
||||
// Execute every Hook in HookList until State change != HANDLED_NONE
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CyhookHandler::Hooks_SendResponse()
|
||||
{
|
||||
log_level_printf(4,"Response Hook-List Start\n");
|
||||
THandleStatus CyhookHandler::Hooks_SendResponse() {
|
||||
log_level_printf(4, "Response Hook-List Start\n");
|
||||
THandleStatus _status = HANDLED_NONE;
|
||||
THookList::iterator i = HookList.begin();
|
||||
for ( ; i!= HookList.end(); i++ )
|
||||
{
|
||||
log_level_printf(4,"Response Hook-List (%s) Start\n", ((*i)->getHookName()).c_str());
|
||||
for (; i != HookList.end(); i++) {
|
||||
log_level_printf(4, "Response Hook-List (%s) Start\n",
|
||||
((*i)->getHookName()).c_str());
|
||||
// response Hook
|
||||
_status = (*i)->Hook_SendResponse(this);
|
||||
log_level_printf(4,"Response Hook-List (%s) End. Status (%d)\n", ((*i)->getHookName()).c_str(), status);
|
||||
if((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
log_level_printf(4, "Response Hook-List (%s) End. Status (%d)\n",
|
||||
((*i)->getHookName()).c_str(), status);
|
||||
if ((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
break;
|
||||
}
|
||||
log_level_printf(4,"Response Hook-List End\n");
|
||||
log_level_printf(8,"Response Hook-List Result:\n%s\n", yresult.c_str());
|
||||
log_level_printf(4, "Response Hook-List End\n");
|
||||
log_level_printf(8, "Response Hook-List Result:\n%s\n", yresult.c_str());
|
||||
status = _status;
|
||||
return _status;
|
||||
}
|
||||
@@ -48,22 +48,25 @@ THandleStatus CyhookHandler::Hooks_SendResponse()
|
||||
// Hook Dispatcher for Session Hooks
|
||||
// Execute every Hook in HookList until State change != HANDLED_NONE
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CyhookHandler::Hooks_PrepareResponse()
|
||||
{
|
||||
log_level_printf(4,"PrepareResponse Hook-List Start\n");
|
||||
THandleStatus CyhookHandler::Hooks_PrepareResponse() {
|
||||
log_level_printf(4, "PrepareResponse Hook-List Start\n");
|
||||
THandleStatus _status = HANDLED_NONE;
|
||||
THookList::iterator i = HookList.begin();
|
||||
for ( ; i!= HookList.end(); i++ )
|
||||
{
|
||||
log_level_printf(4,"PrepareResponse Hook-List (%s) Start\n", ((*i)->getHookName()).c_str());
|
||||
for (; i != HookList.end(); i++) {
|
||||
log_level_printf(4, "PrepareResponse Hook-List (%s) Start\n",
|
||||
((*i)->getHookName()).c_str());
|
||||
// response Hook
|
||||
_status = (*i)->Hook_PrepareResponse(this);
|
||||
log_level_printf(4,"PrepareResponse Hook-List (%s) End. Status (%d) HTTP Status (%d)\n", ((*i)->getHookName()).c_str(), status, httpStatus);
|
||||
if((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
log_level_printf(
|
||||
4,
|
||||
"PrepareResponse Hook-List (%s) End. Status (%d) HTTP Status (%d)\n",
|
||||
((*i)->getHookName()).c_str(), status, httpStatus);
|
||||
if ((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
break;
|
||||
}
|
||||
log_level_printf(4,"PrepareResponse Hook-List End\n");
|
||||
log_level_printf(8,"PrepareResponse Hook-List Result:\n%s\n", yresult.c_str());
|
||||
log_level_printf(4, "PrepareResponse Hook-List End\n");
|
||||
log_level_printf(8, "PrepareResponse Hook-List Result:\n%s\n",
|
||||
yresult.c_str());
|
||||
status = _status;
|
||||
return _status;
|
||||
}
|
||||
@@ -73,83 +76,86 @@ THandleStatus CyhookHandler::Hooks_PrepareResponse()
|
||||
// Execute every Hook in HookList until State change != HANDLED_NONE and
|
||||
// != HANDLED_CONTINUE
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CyhookHandler::Hooks_ReadConfig(CConfigFile *Config, CStringList &ConfigList)
|
||||
{
|
||||
log_level_printf(4,"ReadConfig Hook-List Start\n");
|
||||
THandleStatus CyhookHandler::Hooks_ReadConfig(CConfigFile *Config,
|
||||
CStringList &ConfigList) {
|
||||
log_level_printf(4, "ReadConfig Hook-List Start\n");
|
||||
THandleStatus _status = HANDLED_NONE;
|
||||
THookList::iterator i = HookList.begin();
|
||||
for ( ; i!= HookList.end(); i++ )
|
||||
{
|
||||
// log_level_printf(4,"ReadConfig Hook-List (%s) Start\n", ((*i)->getHookName()).c_str());
|
||||
for (; i != HookList.end(); i++) {
|
||||
// log_level_printf(4,"ReadConfig Hook-List (%s) Start\n", ((*i)->getHookName()).c_str());
|
||||
// response Hook
|
||||
_status = (*i)->Hook_ReadConfig(Config, ConfigList);
|
||||
log_level_printf(4,"ReadConfig Hook-List (%s) Status (%d)\n", ((*i)->getHookName()).c_str(), _status);
|
||||
if((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
log_level_printf(4, "ReadConfig Hook-List (%s) Status (%d)\n",
|
||||
((*i)->getHookName()).c_str(), _status);
|
||||
if ((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
break;
|
||||
}
|
||||
log_level_printf(4,"ReadConfig Hook-List End\n");
|
||||
log_level_printf(4, "ReadConfig Hook-List End\n");
|
||||
return _status;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hook Dispatcher for EndConnection
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CyhookHandler::Hooks_EndConnection()
|
||||
{
|
||||
log_level_printf(4,"EndConnection Hook-List Start\n");
|
||||
THandleStatus CyhookHandler::Hooks_EndConnection() {
|
||||
log_level_printf(4, "EndConnection Hook-List Start\n");
|
||||
THandleStatus _status = HANDLED_NONE;
|
||||
THookList::iterator i = HookList.begin();
|
||||
for ( ; i!= HookList.end(); i++ )
|
||||
{
|
||||
log_level_printf(4,"EndConnection Hook-List (%s) Start\n", ((*i)->getHookName()).c_str());
|
||||
for (; i != HookList.end(); i++) {
|
||||
log_level_printf(4, "EndConnection Hook-List (%s) Start\n",
|
||||
((*i)->getHookName()).c_str());
|
||||
// response Hook
|
||||
_status = (*i)->Hook_EndConnection(this);
|
||||
log_level_printf(4,"EndConnection Hook-List (%s) End. Status (%d)\n", ((*i)->getHookName()).c_str(), _status);
|
||||
if((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
log_level_printf(4, "EndConnection Hook-List (%s) End. Status (%d)\n",
|
||||
((*i)->getHookName()).c_str(), _status);
|
||||
if ((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
break;
|
||||
}
|
||||
log_level_printf(4,"EndConnection Hook-List End\n");
|
||||
log_level_printf(4, "EndConnection Hook-List End\n");
|
||||
status = _status;
|
||||
return _status;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hook Dispatcher for UploadSetFilename
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CyhookHandler::Hooks_UploadSetFilename(std::string &Filename)
|
||||
{
|
||||
log_level_printf(4,"UploadSetFilename Hook-List Start. Filename:(%s)\n", Filename.c_str());
|
||||
THandleStatus CyhookHandler::Hooks_UploadSetFilename(std::string &Filename) {
|
||||
log_level_printf(4, "UploadSetFilename Hook-List Start. Filename:(%s)\n",
|
||||
Filename.c_str());
|
||||
THandleStatus _status = HANDLED_NONE;
|
||||
THookList::iterator i = HookList.begin();
|
||||
for ( ; i!= HookList.end(); i++ )
|
||||
{
|
||||
log_level_printf(4,"UploadSetFilename Hook-List (%s) Start\n", ((*i)->getHookName()).c_str());
|
||||
for (; i != HookList.end(); i++) {
|
||||
log_level_printf(4, "UploadSetFilename Hook-List (%s) Start\n",
|
||||
((*i)->getHookName()).c_str());
|
||||
// response Hook
|
||||
_status = (*i)->Hook_UploadSetFilename(this, Filename);
|
||||
log_level_printf(4,"UploadSetFilename Hook-List (%s) End. Status (%d)\n", ((*i)->getHookName()).c_str(), _status);
|
||||
if((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
log_level_printf(4,
|
||||
"UploadSetFilename Hook-List (%s) End. Status (%d)\n",
|
||||
((*i)->getHookName()).c_str(), _status);
|
||||
if ((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
break;
|
||||
}
|
||||
log_level_printf(4,"UploadSetFilename Hook-List End\n");
|
||||
log_level_printf(4, "UploadSetFilename Hook-List End\n");
|
||||
status = _status;
|
||||
return _status;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hook Dispatcher for UploadSetFilename
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CyhookHandler::Hooks_UploadReady(const std::string& Filename)
|
||||
{
|
||||
log_level_printf(4,"UploadReady Hook-List Start. Filename:(%s)\n", Filename.c_str());
|
||||
THandleStatus CyhookHandler::Hooks_UploadReady(const std::string& Filename) {
|
||||
log_level_printf(4, "UploadReady Hook-List Start. Filename:(%s)\n",
|
||||
Filename.c_str());
|
||||
THandleStatus _status = HANDLED_NONE;
|
||||
THookList::iterator i = HookList.begin();
|
||||
for ( ; i!= HookList.end(); i++ )
|
||||
{
|
||||
log_level_printf(4,"UploadReady Hook-List (%s) Start\n", ((*i)->getHookName()).c_str());
|
||||
for (; i != HookList.end(); i++) {
|
||||
log_level_printf(4, "UploadReady Hook-List (%s) Start\n",
|
||||
((*i)->getHookName()).c_str());
|
||||
// response Hook
|
||||
_status = (*i)->Hook_UploadReady(this, Filename);
|
||||
log_level_printf(4,"UploadReady Hook-List (%s) End. Status (%d)\n", ((*i)->getHookName()).c_str(), _status);
|
||||
if((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
log_level_printf(4, "UploadReady Hook-List (%s) End. Status (%d)\n",
|
||||
((*i)->getHookName()).c_str(), _status);
|
||||
if ((_status != HANDLED_NONE) && (_status != HANDLED_CONTINUE))
|
||||
break;
|
||||
}
|
||||
log_level_printf(4,"UploadReady Hook-List End\n");
|
||||
log_level_printf(4, "UploadReady Hook-List End\n");
|
||||
status = _status;
|
||||
return _status;
|
||||
}
|
||||
@@ -157,19 +163,19 @@ THandleStatus CyhookHandler::Hooks_UploadReady(const std::string& Filename)
|
||||
//=============================================================================
|
||||
// Output helpers
|
||||
//=============================================================================
|
||||
void CyhookHandler::session_init(CStringList _ParamList, CStringList _UrlData, CStringList _HeaderList,
|
||||
CStringList& _ConfigList, THttp_Method _Method, bool _keep_alive)
|
||||
{
|
||||
ParamList = _ParamList;
|
||||
UrlData = _UrlData;
|
||||
HeaderList = _HeaderList;
|
||||
WebserverConfigList = _ConfigList;
|
||||
Method = _Method;
|
||||
status = HANDLED_NONE;
|
||||
httpStatus = HTTP_OK;
|
||||
ContentLength = 0;
|
||||
LastModified = (time_t)-1;
|
||||
keep_alive = _keep_alive;
|
||||
void CyhookHandler::session_init(CStringList _ParamList, CStringList _UrlData,
|
||||
CStringList _HeaderList, CStringList& _ConfigList,
|
||||
THttp_Method _Method, bool _keep_alive) {
|
||||
ParamList = _ParamList;
|
||||
UrlData = _UrlData;
|
||||
HeaderList = _HeaderList;
|
||||
WebserverConfigList = _ConfigList;
|
||||
Method = _Method;
|
||||
status = HANDLED_NONE;
|
||||
httpStatus = HTTP_OK;
|
||||
ContentLength = 0;
|
||||
LastModified = (time_t) - 1;
|
||||
keep_alive = _keep_alive;
|
||||
HookVarList.clear();
|
||||
}
|
||||
|
||||
@@ -202,113 +208,111 @@ void CyhookHandler::session_init(CStringList _ParamList, CStringList _UrlData, C
|
||||
// | Via ; not implemented
|
||||
// | Warning ; not implemented
|
||||
//
|
||||
// response-header = Accept-Ranges ; not implemented
|
||||
// | Age ; not implemented
|
||||
// | ETag ; not implemented
|
||||
// | Location ; implemented (redirection / Object moved)
|
||||
// | Proxy-Authenticate ; not implemented
|
||||
// | Retry-After ; not implemented
|
||||
// | Server ; implemented
|
||||
// | Vary ; not implemented
|
||||
// | WWW-Authenticate ; implemented (by mod_auth and SendHeader)
|
||||
// response-header = Accept-Ranges ; not implemented
|
||||
// | Age ; not implemented
|
||||
// | ETag ; not implemented
|
||||
// | Location ; implemented (redirection / Object moved)
|
||||
// | Proxy-Authenticate ; not implemented
|
||||
// | Retry-After ; not implemented
|
||||
// | Server ; implemented
|
||||
// | Vary ; not implemented
|
||||
// | WWW-Authenticate ; implemented (by mod_auth and SendHeader)
|
||||
//
|
||||
// entity-header = Allow ; not implemented
|
||||
// | Content-Encoding ; not implemented
|
||||
// | Content-Language ; not implemented
|
||||
// | Content-Length ; implemented
|
||||
// | Content-Location ; not implemented
|
||||
// | Content-MD5 ; not implemented
|
||||
// | Content-Range ; not implemented
|
||||
// | Content-Type ; implemented
|
||||
// | Expires ; not implemented
|
||||
// | Last-Modified ; implemented for static files
|
||||
// | extension-header
|
||||
// entity-header = Allow ; not implemented
|
||||
// | Content-Encoding ; not implemented
|
||||
// | Content-Language ; not implemented
|
||||
// | Content-Length ; implemented
|
||||
// | Content-Location ; not implemented
|
||||
// | Content-MD5 ; not implemented
|
||||
// | Content-Range ; not implemented
|
||||
// | Content-Type ; implemented
|
||||
// | Expires ; not implemented
|
||||
// | Last-Modified ; implemented for static files
|
||||
// | extension-header
|
||||
//
|
||||
// extension-header = message-header
|
||||
// extension-header = message-header
|
||||
//=============================================================================
|
||||
std::string CyhookHandler::BuildHeader(bool cache)
|
||||
{
|
||||
std::string result="";
|
||||
std::string CyhookHandler::BuildHeader(bool cache) {
|
||||
std::string result = "";
|
||||
|
||||
const char *responseString = "";
|
||||
const char *infoString = 0;
|
||||
|
||||
// get Info Index
|
||||
for (unsigned int i = 0;i < (sizeof(httpResponseNames)/sizeof(httpResponseNames[0])); i++)
|
||||
if (httpResponseNames[i].type == httpStatus)
|
||||
{
|
||||
for (unsigned int i = 0; i < (sizeof(httpResponseNames)
|
||||
/ sizeof(httpResponseNames[0])); i++)
|
||||
if (httpResponseNames[i].type == httpStatus) {
|
||||
responseString = httpResponseNames[i].name;
|
||||
infoString = httpResponseNames[i].info;
|
||||
break;
|
||||
}
|
||||
// print Status-line
|
||||
result = string_printf(HTTP_PROTOCOL " %d %s\r\nContent-Type: %s\r\n",httpStatus, responseString, ResponseMimeType.c_str());
|
||||
log_level_printf(2,"Respose: HTTP/1.1 %d %s\r\nContent-Type: %s\r\n",httpStatus, responseString, ResponseMimeType.c_str());
|
||||
log_level_printf(2, "Respose: HTTP/1.1 %d %s\r\nContent-Type: %s\r\n",
|
||||
httpStatus, responseString, ResponseMimeType.c_str());
|
||||
|
||||
switch (httpStatus)
|
||||
{
|
||||
case HTTP_UNAUTHORIZED:
|
||||
result += "WWW-Authenticate: Basic realm=\"";
|
||||
result += AUTH_NAME_MSG "\r\n";
|
||||
break;
|
||||
switch (httpStatus) {
|
||||
case HTTP_UNAUTHORIZED:
|
||||
result += "WWW-Authenticate: Basic realm=\"";
|
||||
result += AUTH_NAME_MSG "\r\n";
|
||||
break;
|
||||
|
||||
case HTTP_MOVED_TEMPORARILY:
|
||||
case HTTP_MOVED_PERMANENTLY:
|
||||
// Status HTTP_*_TEMPORARILY (redirection)
|
||||
result += string_printf("Location: %s\r\n",NewURL.c_str());
|
||||
// NO break HERE !!!
|
||||
case HTTP_MOVED_TEMPORARILY:
|
||||
case HTTP_MOVED_PERMANENTLY:
|
||||
// Status HTTP_*_TEMPORARILY (redirection)
|
||||
result += string_printf("Location: %s\r\n", NewURL.c_str());
|
||||
// NO break HERE !!!
|
||||
|
||||
default:
|
||||
time_t timer = time(0);
|
||||
char timeStr[80];
|
||||
// cache
|
||||
if(!cache && (HookVarList["CacheCategory"]).empty() )
|
||||
result += "Cache-Control: no-cache\r\n";
|
||||
else
|
||||
{
|
||||
time_t x_time = time(NULL);
|
||||
struct tm *ptm = gmtime(&x_time);
|
||||
ptm->tm_mday+=1;
|
||||
x_time = mktime(ptm);
|
||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&x_time));
|
||||
result += string_printf("Expires: %s\r\n", timeStr);
|
||||
}
|
||||
result += "Server: " WEBSERVERNAME "\r\n";
|
||||
// actual date
|
||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&timer));
|
||||
result += string_printf("Date: %s\r\n", timeStr);
|
||||
// connection type
|
||||
default:
|
||||
time_t timer = time(0);
|
||||
char timeStr[80];
|
||||
// cache
|
||||
if (!cache && (HookVarList["CacheCategory"]).empty())
|
||||
result += "Cache-Control: no-cache\r\n";
|
||||
else {
|
||||
time_t x_time = time(NULL);
|
||||
struct tm *ptm = gmtime(&x_time);
|
||||
ptm->tm_mday += 1;
|
||||
x_time = mktime(ptm);
|
||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&x_time));
|
||||
result += string_printf("Expires: %s\r\n", timeStr);
|
||||
}
|
||||
result += "Server: " WEBSERVERNAME "\r\n";
|
||||
// actual date
|
||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&timer));
|
||||
result += string_printf("Date: %s\r\n", timeStr);
|
||||
// connection type
|
||||
#ifdef Y_CONFIG_FEATURE_KEEP_ALIVE
|
||||
if(keep_alive)
|
||||
result += "Connection: keep-alive\r\n";
|
||||
else
|
||||
result += "Connection: close\r\n";
|
||||
if(keep_alive)
|
||||
result += "Connection: keep-alive\r\n";
|
||||
else
|
||||
result += "Connection: close\r\n";
|
||||
#else
|
||||
result += "Connection: close\r\n";
|
||||
result += "Connection: close\r\n";
|
||||
#endif
|
||||
// gzipped ?
|
||||
if(UrlData["fileext"] == "gz")
|
||||
result += "Content-Encoding: gzip\r\n";
|
||||
// content-len, last-modified
|
||||
if(httpStatus == HTTP_NOT_MODIFIED ||httpStatus == HTTP_NOT_FOUND)
|
||||
result += "Content-Length: 0\r\n";
|
||||
else if(GetContentLength() >0)
|
||||
{
|
||||
time_t mod_time = time(NULL);
|
||||
if(LastModified != (time_t)-1)
|
||||
mod_time = LastModified;
|
||||
// gzipped ?
|
||||
if (UrlData["fileext"] == "gz")
|
||||
result += "Content-Encoding: gzip\r\n";
|
||||
// content-len, last-modified
|
||||
if (httpStatus == HTTP_NOT_MODIFIED || httpStatus == HTTP_NOT_FOUND)
|
||||
result += "Content-Length: 0\r\n";
|
||||
else if (GetContentLength() > 0) {
|
||||
time_t mod_time = time(NULL);
|
||||
if (LastModified != (time_t) - 1)
|
||||
mod_time = LastModified;
|
||||
|
||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&mod_time));
|
||||
result += string_printf("Last-Modified: %s\r\nContent-Length: %ld\r\n", timeStr, GetContentLength());
|
||||
}
|
||||
result += "\r\n"; // End of Header
|
||||
break;
|
||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&mod_time));
|
||||
result += string_printf(
|
||||
"Last-Modified: %s\r\nContent-Length: %ld\r\n", timeStr,
|
||||
GetContentLength());
|
||||
}
|
||||
result += "\r\n"; // End of Header
|
||||
break;
|
||||
}
|
||||
|
||||
// Body
|
||||
if (Method != M_HEAD)
|
||||
switch (httpStatus)
|
||||
{
|
||||
switch (httpStatus) {
|
||||
case HTTP_OK:
|
||||
case HTTP_NOT_MODIFIED:
|
||||
case HTTP_CONTINUE:
|
||||
@@ -321,13 +325,16 @@ std::string CyhookHandler::BuildHeader(bool cache)
|
||||
case HTTP_MOVED_TEMPORARILY:
|
||||
case HTTP_MOVED_PERMANENTLY:
|
||||
result += "<html><head><title>Object moved</title></head><body>";
|
||||
result += string_printf("302 : Object moved.<br/>If you dont get redirected click <a href=\"%s\">here</a></body></html>\n",NewURL.c_str());
|
||||
result
|
||||
+= string_printf(
|
||||
"302 : Object moved.<br/>If you dont get redirected click <a href=\"%s\">here</a></body></html>\n",
|
||||
NewURL.c_str());
|
||||
break;
|
||||
|
||||
default:
|
||||
// Error pages
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -335,27 +342,24 @@ std::string CyhookHandler::BuildHeader(bool cache)
|
||||
// Output helpers
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
void CyhookHandler::SendHTMLHeader(const std::string& Titel)
|
||||
{
|
||||
void CyhookHandler::SendHTMLHeader(const std::string& Titel) {
|
||||
WriteLn("<html>\n<head><title>" + Titel + "</title>\n");
|
||||
WriteLn("<meta http-equiv=\"cache-control\" content=\"no-cache\" />");
|
||||
WriteLn("<meta http-equiv=\"expires\" content=\"0\" />\n</head>\n<body>\n");
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void CyhookHandler::SendHTMLFooter(void)
|
||||
{
|
||||
void CyhookHandler::SendHTMLFooter(void) {
|
||||
WriteLn("</body>\n</html>\n\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#define OUTBUFSIZE 4096
|
||||
void CyhookHandler::printf ( const char *fmt, ... )
|
||||
{
|
||||
void CyhookHandler::printf(const char *fmt, ...) {
|
||||
char outbuf[OUTBUFSIZE];
|
||||
bzero(outbuf,OUTBUFSIZE);
|
||||
bzero(outbuf, OUTBUFSIZE);
|
||||
va_list arglist;
|
||||
va_start( arglist, fmt );
|
||||
vsnprintf( outbuf,OUTBUFSIZE, fmt, arglist );
|
||||
va_start(arglist, fmt);
|
||||
vsnprintf(outbuf, OUTBUFSIZE, fmt, arglist);
|
||||
va_end(arglist);
|
||||
Write(outbuf);
|
||||
}
|
||||
|
@@ -83,10 +83,10 @@ std::string CLanguage::getTranslation(std::string id){
|
||||
std::string CLanguage::getLanguageDir(void){
|
||||
std::string tmpfilename = "/"+Cyhttpd::ConfigList["Language.directory"],dir="";
|
||||
|
||||
if( access(std::string(Cyhttpd::ConfigList["PublicDocumentRoot"] + tmpfilename).c_str(),4) == 0)
|
||||
dir = Cyhttpd::ConfigList["PublicDocumentRoot"] + tmpfilename;
|
||||
else if(access(std::string(Cyhttpd::ConfigList["PrivatDocumentRoot"] + tmpfilename).c_str(),4) == 0)
|
||||
dir = Cyhttpd::ConfigList["PrivatDocumentRoot"] + tmpfilename;
|
||||
if( access(std::string(Cyhttpd::ConfigList["WebsiteMain.override_directory"] + tmpfilename).c_str(),4) == 0)
|
||||
dir = Cyhttpd::ConfigList["WebsiteMain.override_directory"] + tmpfilename;
|
||||
else if(access(std::string(Cyhttpd::ConfigList["WebsiteMain.directory"] + tmpfilename).c_str(),4) == 0)
|
||||
dir = Cyhttpd::ConfigList["WebsiteMain.directory"] + tmpfilename;
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
@@ -24,16 +24,14 @@ CLogging *CLogging::instance = NULL;
|
||||
//-----------------------------------------------------------------------------
|
||||
// There is only one Instance
|
||||
//-----------------------------------------------------------------------------
|
||||
CLogging *CLogging::getInstance(void)
|
||||
{
|
||||
CLogging *CLogging::getInstance(void) {
|
||||
if (!instance)
|
||||
instance = new CLogging();
|
||||
return instance;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogging::deleteInstance(void)
|
||||
{
|
||||
void CLogging::deleteInstance(void) {
|
||||
if (instance)
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
@@ -42,30 +40,26 @@ void CLogging::deleteInstance(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CLogging::CLogging(void)
|
||||
{
|
||||
Debug = false;
|
||||
LogToFile = false; //not implemented
|
||||
LogLevel = 0;
|
||||
Logfile = NULL;
|
||||
CLogging::CLogging(void) {
|
||||
Debug = false;
|
||||
LogToFile = false; //not implemented
|
||||
LogLevel = 0;
|
||||
Logfile = NULL;
|
||||
pthread_mutex_init(&Log_mutex, NULL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CLogging::~CLogging(void)
|
||||
{
|
||||
CLogging::~CLogging(void) {
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogging::setDebug(bool _debug)
|
||||
{
|
||||
Debug = _debug;
|
||||
void CLogging::setDebug(bool _debug) {
|
||||
Debug = _debug;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CLogging::getDebug(void)
|
||||
{
|
||||
return Debug;
|
||||
bool CLogging::getDebug(void) {
|
||||
return Debug;
|
||||
}
|
||||
//=============================================================================
|
||||
// Logging Calls
|
||||
@@ -74,22 +68,19 @@ bool CLogging::getDebug(void)
|
||||
//=============================================================================
|
||||
#define bufferlen 1024*8
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogging::printf ( const char *fmt, ... )
|
||||
{
|
||||
void CLogging::printf(const char *fmt, ...) {
|
||||
char buffer[bufferlen];
|
||||
|
||||
|
||||
va_list arglist;
|
||||
va_start( arglist, fmt );
|
||||
if(arglist)
|
||||
vsnprintf( buffer, bufferlen, fmt, arglist );
|
||||
va_start(arglist, fmt);
|
||||
vsnprintf(buffer, bufferlen, fmt, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
pthread_mutex_lock( &Log_mutex );
|
||||
pthread_mutex_lock(&Log_mutex);
|
||||
::printf(buffer);
|
||||
if(LogToFile) {
|
||||
; //FIXME Logging to File
|
||||
if (LogToFile) {
|
||||
; //FIXME Logging to File
|
||||
}
|
||||
pthread_mutex_unlock( &Log_mutex );
|
||||
pthread_mutex_unlock(&Log_mutex);
|
||||
}
|
||||
|
||||
|
@@ -33,8 +33,7 @@
|
||||
//=============================================================================
|
||||
// Constructor & Destructor
|
||||
//=============================================================================
|
||||
CWebserverRequest::CWebserverRequest(CWebserver *pWebserver)
|
||||
{
|
||||
CWebserverRequest::CWebserverRequest(CWebserver *pWebserver) {
|
||||
Webserver = pWebserver;
|
||||
CWebserverRequest();
|
||||
}
|
||||
@@ -51,61 +50,53 @@ CWebserverRequest::CWebserverRequest(CWebserver *pWebserver)
|
||||
// [ message-body ]
|
||||
// start-line = Request-Line | Status-Line
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverRequest::HandleRequest(void)
|
||||
{
|
||||
bool CWebserverRequest::HandleRequest(void) {
|
||||
std::string start_line = "";
|
||||
// read first line
|
||||
do
|
||||
{
|
||||
do {
|
||||
start_line = Connection->sock->ReceiveLine();
|
||||
if(!Connection->sock->isValid)
|
||||
if (!Connection->sock->isValid)
|
||||
return false;
|
||||
if(start_line == "") // Socket empty
|
||||
if (start_line == "") // Socket empty
|
||||
{
|
||||
log_level_printf(1,"HandleRequest: End of line not found\n");
|
||||
log_level_printf(1, "HandleRequest: End of line not found\n");
|
||||
Connection->Response.SendError(HTTP_INTERNAL_SERVER_ERROR);
|
||||
Connection->RequestCanceled = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while(start_line == "\r\n"); // ignore empty lines at begin on start-line
|
||||
} while (start_line == "\r\n"); // ignore empty lines at begin on start-line
|
||||
|
||||
start_line = trim(start_line);
|
||||
log_level_printf(1,"Request: %s\n", start_line.c_str() );
|
||||
log_level_printf(1, "Request: %s\n", start_line.c_str());
|
||||
UrlData["startline"] = start_line;
|
||||
if(!ParseStartLine(start_line))
|
||||
if (!ParseStartLine(start_line))
|
||||
return false;
|
||||
|
||||
|
||||
if(Connection->Method == M_GET || Connection->Method == M_HEAD)
|
||||
{
|
||||
if (Connection->Method == M_GET || Connection->Method == M_HEAD) {
|
||||
std::string tmp_line;
|
||||
//read header (speed up: read rest of request in blockmode)
|
||||
tmp_line = Connection->sock->ReceiveBlock();
|
||||
if(!Connection->sock->isValid)
|
||||
{
|
||||
if (!Connection->sock->isValid) {
|
||||
Connection->Response.SendError(HTTP_INTERNAL_SERVER_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(tmp_line == "")
|
||||
{
|
||||
if (tmp_line == "") {
|
||||
Connection->Response.SendError(HTTP_INTERNAL_SERVER_ERROR);
|
||||
return false;
|
||||
}
|
||||
ParseHeader(tmp_line);
|
||||
}
|
||||
// Other Methods
|
||||
if(Connection->Method == M_DELETE || Connection->Method == M_PUT || Connection->Method == M_TRACE)
|
||||
{
|
||||
if (Connection->Method == M_DELETE || Connection->Method == M_PUT
|
||||
|| Connection->Method == M_TRACE) {
|
||||
//todo: implement
|
||||
aprintf("HTTP Method not implemented :%d\n",Connection->Method);
|
||||
aprintf("HTTP Method not implemented :%d\n", Connection->Method);
|
||||
Connection->Response.SendError(HTTP_NOT_IMPLEMENTED);
|
||||
return false;
|
||||
}
|
||||
// handle POST (read header & body)
|
||||
if(Connection->Method == M_POST)
|
||||
{
|
||||
if (Connection->Method == M_POST) {
|
||||
Connection->Response.Write("HTTP/1.1 100 Continue\r\n\r\n"); // POST Requests requires CONTINUE in HTTP/1.1
|
||||
return HandlePost();
|
||||
}
|
||||
@@ -122,33 +113,29 @@ bool CWebserverRequest::HandleRequest(void)
|
||||
// Determine Reqest-Method, URL, HTTP-Version and Split Parameters
|
||||
// Split URL into path, filename, fileext .. UrlData[]
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverRequest::ParseStartLine(std::string start_line)
|
||||
{
|
||||
std::string method,url,http,tmp;
|
||||
bool CWebserverRequest::ParseStartLine(std::string start_line) {
|
||||
std::string method, url, http, tmp;
|
||||
|
||||
log_level_printf(8,"<ParseStartLine>: line: %s\n", start_line.c_str() );
|
||||
if(ySplitString(start_line," ",method,tmp))
|
||||
{
|
||||
if(ySplitStringLast(tmp," ",url,Connection->httprotocol))
|
||||
{
|
||||
log_level_printf(8, "<ParseStartLine>: line: %s\n", start_line.c_str());
|
||||
if (ySplitString(start_line, " ", method, tmp)) {
|
||||
if (ySplitStringLast(tmp, " ", url, Connection->httprotocol)) {
|
||||
analyzeURL(url);
|
||||
UrlData["httprotocol"] = Connection->httprotocol;
|
||||
// determine http Method
|
||||
if(method.compare("POST") == 0) Connection->Method = M_POST;
|
||||
else if(method.compare("GET") == 0) Connection->Method = M_GET;
|
||||
else if(method.compare("PUT") == 0) Connection->Method = M_PUT;
|
||||
else if(method.compare("HEAD") == 0) Connection->Method = M_HEAD;
|
||||
else if(method.compare("PUT") == 0) Connection->Method = M_PUT;
|
||||
else if(method.compare("DELETE") == 0) Connection->Method = M_DELETE;
|
||||
else if(method.compare("TRACE") == 0) Connection->Method = M_TRACE;
|
||||
else
|
||||
{
|
||||
log_level_printf(1,"Unknown Method or invalid request\n");
|
||||
if (method.compare("POST") == 0) Connection->Method = M_POST;
|
||||
else if (method.compare("GET") == 0) Connection->Method = M_GET;
|
||||
else if (method.compare("PUT") == 0) Connection->Method = M_PUT;
|
||||
else if (method.compare("HEAD") == 0) Connection->Method = M_HEAD;
|
||||
else if (method.compare("PUT") == 0) Connection->Method = M_PUT;
|
||||
else if (method.compare("DELETE") == 0) Connection->Method = M_DELETE;
|
||||
else if (method.compare("TRACE") == 0) Connection->Method = M_TRACE;
|
||||
else {
|
||||
log_level_printf(1, "Unknown Method or invalid request\n");
|
||||
Connection->Response.SendError(HTTP_NOT_IMPLEMENTED);
|
||||
log_level_printf(3,"Request: '%s'\n",rawbuffer.c_str());
|
||||
log_level_printf(3, "Request: '%s'\n", rawbuffer.c_str());
|
||||
return false;
|
||||
}
|
||||
log_level_printf(3,"Request: FullURL: %s\n",UrlData["fullurl"].c_str());
|
||||
log_level_printf(3, "Request: FullURL: %s\n", UrlData["fullurl"].c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -164,28 +151,24 @@ bool CWebserverRequest::ParseStartLine(std::string start_line)
|
||||
// If parameter attribute is multiple times given, the values are stored like this:
|
||||
// <attribute>=<value1>,<value2>,..,<value n>
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverRequest::ParseParams(std::string param_string)
|
||||
{
|
||||
bool CWebserverRequest::ParseParams(std::string param_string) {
|
||||
bool ende = false;
|
||||
std::string param, name="", value, number;
|
||||
std::string param, name = "", value, number;
|
||||
|
||||
while(!ende)
|
||||
{
|
||||
if(!ySplitStringExact(param_string,"&",param,param_string))
|
||||
while (!ende) {
|
||||
if (!ySplitStringExact(param_string, "&", param, param_string))
|
||||
ende = true;
|
||||
if(ySplitStringExact(param,"=",name,value))
|
||||
{
|
||||
if (ySplitStringExact(param, "=", name, value)) {
|
||||
value = trim(decodeString(value));
|
||||
if(ParameterList[name].empty())
|
||||
if (ParameterList[name].empty())
|
||||
ParameterList[name] = value;
|
||||
else
|
||||
{
|
||||
else {
|
||||
ParameterList[name] += ",";
|
||||
ParameterList[name] += value;
|
||||
}
|
||||
}
|
||||
number = string_printf("%d", ParameterList.size()+1);
|
||||
log_level_printf(7,"ParseParams: name: %s value: %s\n",name.c_str(), value.c_str());
|
||||
number = string_printf("%d", ParameterList.size() + 1);
|
||||
log_level_printf(7, "ParseParams: name: %s value: %s\n", name.c_str(), value.c_str());
|
||||
ParameterList[number] = name;
|
||||
}
|
||||
return true;
|
||||
@@ -201,19 +184,17 @@ bool CWebserverRequest::ParseParams(std::string param_string)
|
||||
// and consisting of either *TEXT or combinations
|
||||
// of token, separators, and quoted-string>
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverRequest::ParseHeader(std::string header)
|
||||
{
|
||||
bool CWebserverRequest::ParseHeader(std::string header) {
|
||||
bool ende = false;
|
||||
std::string sheader, name, value;
|
||||
HeaderList.clear();
|
||||
|
||||
while(!ende)
|
||||
{
|
||||
if(!ySplitStringExact(header,"\r\n",sheader,header))
|
||||
while (!ende) {
|
||||
if (!ySplitStringExact(header, "\r\n", sheader, header))
|
||||
ende = true;
|
||||
if(ySplitStringExact(sheader,":",name,value))
|
||||
if (ySplitStringExact(sheader, ":", name, value))
|
||||
HeaderList[name] = trim(value);
|
||||
log_level_printf(8,"ParseHeader: name: %s value: %s\n",name.c_str(), value.c_str());
|
||||
log_level_printf(8, "ParseHeader: name: %s value: %s\n", name.c_str(), value.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -225,66 +206,65 @@ bool CWebserverRequest::ParseHeader(std::string header)
|
||||
// http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
|
||||
// query data is splitted and stored in ParameterList
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWebserverRequest::analyzeURL(std::string url)
|
||||
{
|
||||
void CWebserverRequest::analyzeURL(std::string url) {
|
||||
ParameterList.clear();
|
||||
// URI decode
|
||||
url = decodeString(url);
|
||||
url = trim(url, "\r\n"); // non-HTTP-Standard: allow \r or \n in URL. Delete it.
|
||||
UrlData["fullurl"] = url;
|
||||
// split Params
|
||||
if(ySplitString(url,"?",UrlData["url"],UrlData["paramstring"])) // split pure URL and all Params
|
||||
ParseParams(UrlData["paramstring"]); // split params to ParameterList
|
||||
else // No Params
|
||||
if (ySplitString(url, "?", UrlData["url"], UrlData["paramstring"])) // split pure URL and all Params
|
||||
ParseParams( UrlData["paramstring"]); // split params to ParameterList
|
||||
else
|
||||
// No Params
|
||||
UrlData["url"] = url;
|
||||
|
||||
if(!ySplitStringLast(UrlData["url"],"/",UrlData["path"],UrlData["filename"]))
|
||||
{
|
||||
UrlData["path"] = "/"; // Set "/" if not contained
|
||||
}
|
||||
else
|
||||
if (!ySplitStringLast(UrlData["url"], "/", UrlData["path"],
|
||||
UrlData["filename"])) {
|
||||
UrlData["path"] = "/"; // Set "/" if not contained
|
||||
} else
|
||||
UrlData["path"] += "/";
|
||||
if(( UrlData["url"].length() == 1) || (UrlData["url"][UrlData["url"].length()-1] == '/' ))
|
||||
{ // if "/" at end use index.html
|
||||
if ((UrlData["url"].length() == 1)
|
||||
|| (UrlData["url"][UrlData["url"].length() - 1] == '/')) { // if "/" at end use index.html
|
||||
UrlData["path"] = UrlData["url"];
|
||||
UrlData["filename"] = "index.html";
|
||||
}
|
||||
ySplitStringLast(UrlData["filename"],".",UrlData["filenamepure"],UrlData["fileext"]);
|
||||
ySplitStringLast(UrlData["filename"], ".", UrlData["filenamepure"],
|
||||
UrlData["fileext"]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle Post (Form and ONE file upload)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverRequest::HandlePost()
|
||||
{
|
||||
bool CWebserverRequest::HandlePost() {
|
||||
//read header: line by line
|
||||
std::string raw_header, tmp_line;
|
||||
do
|
||||
{
|
||||
do {
|
||||
tmp_line = Connection->sock->ReceiveLine();
|
||||
if(tmp_line == "") // Socket empty
|
||||
if (tmp_line == "") // Socket empty
|
||||
{
|
||||
log_level_printf(1,"HandleRequest: (Header) End of line not found: %s\n", strerror(errno));
|
||||
log_level_printf(1,
|
||||
"HandleRequest: (Header) End of line not found: %s\n",
|
||||
strerror(errno));
|
||||
Connection->Response.SendError(HTTP_INTERNAL_SERVER_ERROR);
|
||||
return false;
|
||||
}
|
||||
raw_header.append(tmp_line);
|
||||
}
|
||||
while(tmp_line != "\r\n"); // header ends with first empty line
|
||||
} while (tmp_line != "\r\n"); // header ends with first empty line
|
||||
ParseHeader(raw_header);
|
||||
|
||||
// read meesage body
|
||||
unsigned int content_len = 0;
|
||||
if(HeaderList["Content-Length"] != "")
|
||||
content_len = atoi( HeaderList["Content-Length"].c_str() );
|
||||
if (HeaderList["Content-Length"] != "")
|
||||
content_len = atoi(HeaderList["Content-Length"].c_str());
|
||||
|
||||
// Get Rest of Request from Socket
|
||||
log_level_printf(2,"Connection->Method Post !\n");
|
||||
log_level_printf(9,"Conntent Type:%s\n",(HeaderList["Content-Type"]).c_str());
|
||||
log_level_printf(8,"Post Content-Length:%d as string:(%s)\n", content_len, HeaderList["Content-Length"].c_str());
|
||||
log_level_printf(2, "Connection->Method Post !\n");
|
||||
log_level_printf(9, "Conntent Type:%s\n", (HeaderList["Content-Type"]).c_str());
|
||||
log_level_printf(8, "Post Content-Length:%d as string:(%s)\n", content_len, HeaderList["Content-Length"].c_str());
|
||||
|
||||
static const std::string t = "multipart/form-data; boundary=";
|
||||
if(HeaderList["Content-Type"].compare(0,t.length(),t) == 0) // this a a multpart POST, normallly: file upload
|
||||
if (HeaderList["Content-Type"].compare(0, t.length(), t) == 0) // this a a multpart POST, normallly: file upload
|
||||
{
|
||||
#ifdef Y_CONFIG_FEATURE_UPLOAD
|
||||
std::string boundary = "--" + HeaderList["Content-Type"].substr(t.length(),HeaderList["Content-Type"].length() - t.length());
|
||||
@@ -298,21 +278,20 @@ bool CWebserverRequest::HandlePost()
|
||||
Connection->Response.SendError(HTTP_NOT_IMPLEMENTED);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else if(HeaderList["Content-Type"].compare("application/x-www-form-urlencoded") == 0) //this is a normal POST with form-data (no upload)
|
||||
} else if (HeaderList["Content-Type"].compare(
|
||||
"application/x-www-form-urlencoded") == 0) //this is a normal POST with form-data (no upload)
|
||||
{
|
||||
// handle normal form POST
|
||||
log_level_printf(6,"Handle POST application/x-www-form-urlencoded\n");
|
||||
log_level_printf(6, "Handle POST application/x-www-form-urlencoded\n");
|
||||
std::string post_header;
|
||||
// get message-body
|
||||
post_header = Connection->sock->ReceiveBlock();
|
||||
while(post_header.length() < content_len)
|
||||
{
|
||||
while (post_header.length() < content_len) {
|
||||
post_header += Connection->sock->ReceiveBlock();
|
||||
/* aprintf("POST form less data then expected\n");
|
||||
Connection->Response.SendError(HTTP_INTERNAL_SERVER_ERROR);
|
||||
return false;
|
||||
*/
|
||||
/* aprintf("POST form less data then expected\n");
|
||||
Connection->Response.SendError(HTTP_INTERNAL_SERVER_ERROR);
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
// parse the params in post_header (message-body) an add them to ParameterList
|
||||
ParseParams(post_header);
|
||||
@@ -401,35 +380,31 @@ bool CWebserverRequest::HandlePost()
|
||||
// where the original filename is known. This is useful or necessary in
|
||||
// many applications.
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int CWebserverRequest::HandlePostBoundary(std::string boundary, unsigned int content_len)
|
||||
{
|
||||
unsigned int CWebserverRequest::HandlePostBoundary(std::string boundary,
|
||||
unsigned int content_len) {
|
||||
std::string tmp_line;
|
||||
|
||||
// read boundary
|
||||
tmp_line = Connection->sock->ReceiveLine();
|
||||
content_len -= tmp_line.length();
|
||||
|
||||
log_level_printf(2,"<POST Boundary> Start\n");
|
||||
if(tmp_line.find(boundary) != std::string::npos)
|
||||
{
|
||||
log_level_printf(2, "<POST Boundary> Start\n");
|
||||
if (tmp_line.find(boundary) != std::string::npos) {
|
||||
// is it the boudary end?
|
||||
if(tmp_line.find(boundary+"--") != std::string::npos)
|
||||
{
|
||||
log_level_printf(7,"<POST Boundary> Boundary END found\n");
|
||||
if (tmp_line.find(boundary + "--") != std::string::npos) {
|
||||
log_level_printf(7, "<POST Boundary> Boundary END found\n");
|
||||
return 0;
|
||||
}
|
||||
log_level_printf(7,"<POST Boundary> Boundary START found\n");
|
||||
log_level_printf(7, "<POST Boundary> Boundary START found\n");
|
||||
|
||||
// read content-disposition: ...
|
||||
tmp_line = Connection->sock->ReceiveLine();
|
||||
content_len -= tmp_line.length();
|
||||
if(tmp_line.find("Content-Disposition:") == std::string::npos)
|
||||
{
|
||||
log_level_printf(7,"<POST Boundary> no content-disposition found. line:(%s)\n", tmp_line.c_str());
|
||||
if (tmp_line.find("Content-Disposition:") == std::string::npos) {
|
||||
log_level_printf(7, "<POST Boundary> no content-disposition found. line:(%s)\n", tmp_line.c_str());
|
||||
return 0;
|
||||
}
|
||||
if(tmp_line.find("filename") != std::string::npos)
|
||||
{
|
||||
if (tmp_line.find("filename") != std::string::npos) {
|
||||
#ifdef Y_CONFIG_FEATURE_UPLOAD
|
||||
// this part is a file
|
||||
log_level_printf(2,"<POST Boundary> disposition !!this is a file!! found. line:(%s)\n", tmp_line.c_str());
|
||||
@@ -473,7 +448,6 @@ unsigned int CWebserverRequest::HandlePostBoundary(std::string boundary, unsigne
|
||||
ParameterList[var_name+"_mime"] = var_value;
|
||||
log_level_printf(7,"<POST Boundary> Content-Type found. name:(%s_mime) value:(%s)\n", var_name.c_str(), var_value.c_str());
|
||||
|
||||
|
||||
//read empty line as separator
|
||||
tmp_line = Connection->sock->ReceiveLine();
|
||||
content_len -= tmp_line.length();
|
||||
@@ -505,7 +479,7 @@ unsigned int CWebserverRequest::HandlePostBoundary(std::string boundary, unsigne
|
||||
// It only works, if no multipart/mixed is used (e.g. in file attachments). Not nessesary in embedded systems.
|
||||
// To speed up uploading, read content_len - SEARCH_BOUNDARY_LEN bytes in blockmode.
|
||||
// To save memory, write them direct into the file.
|
||||
#define SEARCH_BOUNDARY_LEN 2*RECEIVE_BLOCK_LEN // >= RECEIVE_BLOCK_LEN in ySocket
|
||||
#define SEARCH_BOUNDARY_LEN 2*RECEIVE_BLOCK_LEN // >= RECEIVE_BLOCK_LEN in ySocket
|
||||
unsigned int _readbytes = 0;
|
||||
if((int)content_len - SEARCH_BOUNDARY_LEN >0)
|
||||
{
|
||||
@@ -529,17 +503,17 @@ unsigned int CWebserverRequest::HandlePostBoundary(std::string boundary, unsigne
|
||||
if(tmp_line.find(boundary) != std::string::npos)
|
||||
{
|
||||
if(tmp_line.find(boundary+"--") != std::string::npos)
|
||||
found_end_boundary = true; // it is the end! of POST request!
|
||||
break; // boundary found. end of file.
|
||||
found_end_boundary = true; // it is the end! of POST request!
|
||||
break; // boundary found. end of file.
|
||||
}
|
||||
else // no Boundary: write CRFL if found in last line
|
||||
{
|
||||
if(is_CRLF)
|
||||
if ((unsigned int)write(fd, "\r\n", 2) != 2)
|
||||
{
|
||||
perror("write file failed\n");
|
||||
return 0;
|
||||
}
|
||||
if ((unsigned int)write(fd, "\r\n", 2) != 2)
|
||||
{
|
||||
perror("write file failed\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// normal line: write it to file
|
||||
// CRLF at end? Maybe CRLF before boundary. Can not decide yet
|
||||
@@ -563,29 +537,25 @@ unsigned int CWebserverRequest::HandlePostBoundary(std::string boundary, unsigne
|
||||
return 0;
|
||||
}
|
||||
#endif // Y_CONFIG_FEATURE_UPLOAD
|
||||
}
|
||||
else
|
||||
} else
|
||||
// this part is a POST variable/parameter
|
||||
{
|
||||
// get var_name from 'content-disposition: form-data; name="var_name"'
|
||||
std::string left, right, var_name, var_value;
|
||||
if(!ySplitStringExact(tmp_line, "name=\"", left, right))
|
||||
{
|
||||
log_level_printf(7,"<POST Boundary> no var_name START found. line:(%s)\n", tmp_line.c_str());
|
||||
if (!ySplitStringExact(tmp_line, "name=\"", left, right)) {
|
||||
log_level_printf(7, "<POST Boundary> no var_name START found. line:(%s)\n", tmp_line.c_str());
|
||||
return 0;
|
||||
}
|
||||
if(!ySplitStringExact(right, "\"", var_name, right))
|
||||
{
|
||||
log_level_printf(7,"<POST Boundary> no var_name END found. line:(%s)\n", tmp_line.c_str());
|
||||
if (!ySplitStringExact(right, "\"", var_name, right)) {
|
||||
log_level_printf(7, "<POST Boundary> no var_name END found. line:(%s)\n", tmp_line.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
//read empty line as separator
|
||||
tmp_line = Connection->sock->ReceiveLine();
|
||||
content_len -= tmp_line.length();
|
||||
if(tmp_line != "\r\n")
|
||||
{
|
||||
log_level_printf(7,"<POST Boundary> no empty line found. line:(%s)\n", tmp_line.c_str());
|
||||
if (tmp_line != "\r\n") {
|
||||
log_level_printf(7, "<POST Boundary> no empty line found. line:(%s)\n", tmp_line.c_str());
|
||||
return 0;
|
||||
|
||||
}
|
||||
@@ -596,7 +566,7 @@ unsigned int CWebserverRequest::HandlePostBoundary(std::string boundary, unsigne
|
||||
content_len -= tmp_line.length();
|
||||
var_value = trim(decodeString(var_value));
|
||||
ParameterList[var_name] = var_value;
|
||||
log_level_printf(7,"<POST Boundary> Parameter found. name:(%s) value:(%s)\n", var_name.c_str(), var_value.c_str());
|
||||
log_level_printf(7, "<POST Boundary> Parameter found. name:(%s) value:(%s)\n", var_name.c_str(), var_value.c_str());
|
||||
}
|
||||
}
|
||||
return content_len;
|
||||
|
@@ -29,14 +29,12 @@
|
||||
//=============================================================================
|
||||
// Constructor & Destructor
|
||||
//=============================================================================
|
||||
CWebserverResponse::CWebserverResponse(CWebserver *pWebserver)
|
||||
{
|
||||
CWebserverResponse::CWebserverResponse(CWebserver *pWebserver) {
|
||||
Webserver = pWebserver;
|
||||
CWebserverResponse();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
CWebserverResponse::CWebserverResponse()
|
||||
{
|
||||
CWebserverResponse::CWebserverResponse() {
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@@ -54,198 +52,177 @@ CWebserverResponse::CWebserverResponse()
|
||||
// CRLF ; generated by SendHeader
|
||||
// [ message-body ] ; by HOOK Handling Loop or Sendfile
|
||||
//=============================================================================
|
||||
bool CWebserverResponse::SendResponse()
|
||||
{
|
||||
bool CWebserverResponse::SendResponse() {
|
||||
// Init Hookhandler
|
||||
Connection->HookHandler.session_init(Connection->Request.ParameterList, Connection->Request.UrlData,
|
||||
(Connection->Request.HeaderList), (Cyhttpd::ConfigList), Connection->Method, Connection->keep_alive);
|
||||
Connection->HookHandler.session_init(Connection->Request.ParameterList,
|
||||
Connection->Request.UrlData, (Connection->Request.HeaderList),
|
||||
(Cyhttpd::ConfigList), Connection->Method, Connection->keep_alive);
|
||||
//--------------------------------------------------------------
|
||||
// HOOK Handling Loop [ PREPARE response hook ]
|
||||
// Checking and Preperation: Auth, static, cache, ...
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// move to mod_sendfile ???
|
||||
// move to mod_sendfile ???
|
||||
#ifdef Y_CONFIG_USE_HOSTEDWEB
|
||||
// for hosted webs: rewrite URL
|
||||
std::string _hosted="/hosted/";
|
||||
if((Connection->Request.UrlData["path"]).compare(0,_hosted.length(),"/hosted/") == 0) // hosted Web ?
|
||||
Connection->Request.UrlData["path"]=Cyhttpd::ConfigList["HostedDocumentRoot"]
|
||||
+(Connection->Request.UrlData["path"]).substr(_hosted.length()-1);
|
||||
if((Connection->Request.UrlData["path"]).compare(0,_hosted.length(),"/hosted/") == 0) // hosted Web ?
|
||||
Connection->Request.UrlData["path"]=Cyhttpd::ConfigList["WebsiteMain.hosted_directory"]
|
||||
+(Connection->Request.UrlData["path"]).substr(_hosted.length()-1);
|
||||
#endif //Y_CONFIG_USE_HOSTEDWEB
|
||||
|
||||
do
|
||||
{
|
||||
if(Connection->RequestCanceled)
|
||||
do {
|
||||
if (Connection->RequestCanceled)
|
||||
return false;
|
||||
|
||||
Connection->HookHandler.Hooks_PrepareResponse();
|
||||
if(Connection->HookHandler.status == HANDLED_ERROR || Connection->HookHandler.status == HANDLED_ABORT)
|
||||
{
|
||||
log_level_printf(2,"Response Prepare Hook found but Error\n");
|
||||
if (Connection->HookHandler.status == HANDLED_ERROR
|
||||
|| Connection->HookHandler.status == HANDLED_ABORT) {
|
||||
log_level_printf(2, "Response Prepare Hook found but Error\n");
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
Write(Connection->HookHandler.yresult);
|
||||
return false;
|
||||
}
|
||||
// URL has new value. Analyze new URL for SendFile
|
||||
else if(Connection->HookHandler.status == HANDLED_SENDFILE ||
|
||||
Connection->HookHandler.status == HANDLED_REWRITE)
|
||||
{
|
||||
else if (Connection->HookHandler.status == HANDLED_SENDFILE
|
||||
|| Connection->HookHandler.status == HANDLED_REWRITE) {
|
||||
Connection->Request.analyzeURL(Connection->HookHandler.NewURL);
|
||||
Connection->HookHandler.UrlData = Connection->Request.UrlData;
|
||||
}
|
||||
if(Connection->HookHandler.status == HANDLED_REDIRECTION)
|
||||
{
|
||||
if (Connection->HookHandler.status == HANDLED_REDIRECTION) {
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while(Connection->HookHandler.status == HANDLED_REWRITE);
|
||||
|
||||
} while (Connection->HookHandler.status == HANDLED_REWRITE);
|
||||
|
||||
// Prepare = NOT_MODIFIED ?
|
||||
if(Connection->HookHandler.httpStatus == HTTP_NOT_MODIFIED)
|
||||
{
|
||||
if (Connection->HookHandler.httpStatus == HTTP_NOT_MODIFIED) {
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// HOOK Handling Loop [ response hook ]
|
||||
// Production
|
||||
//--------------------------------------------------------------
|
||||
if(Connection->HookHandler.status != HANDLED_SENDFILE)
|
||||
do
|
||||
{
|
||||
if(Connection->RequestCanceled)
|
||||
return false;
|
||||
if (Connection->HookHandler.status != HANDLED_SENDFILE)
|
||||
do {
|
||||
if (Connection->RequestCanceled)
|
||||
return false;
|
||||
|
||||
Connection->HookHandler.Hooks_SendResponse();
|
||||
if((Connection->HookHandler.status == HANDLED_READY)||(Connection->HookHandler.status == HANDLED_CONTINUE))
|
||||
{
|
||||
log_level_printf(2,"Response Hook Output. Status:%d\n", Connection->HookHandler.status);
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
if(Connection->Method != M_HEAD)
|
||||
Write(Connection->HookHandler.yresult);
|
||||
if(Connection->HookHandler.status != HANDLED_CONTINUE)
|
||||
return true;
|
||||
}
|
||||
else if(Connection->HookHandler.status == HANDLED_ERROR)
|
||||
{
|
||||
log_level_printf(2,"Response Hook found but Error\n");
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
if(Connection->Method != M_HEAD)
|
||||
Write(Connection->HookHandler.yresult);
|
||||
return false;
|
||||
}
|
||||
else if(Connection->HookHandler.status == HANDLED_ABORT)
|
||||
return false;
|
||||
// URL has new value. Analyze new URL for SendFile
|
||||
else if(Connection->HookHandler.status == HANDLED_SENDFILE ||
|
||||
Connection->HookHandler.status == HANDLED_REWRITE)
|
||||
{
|
||||
Connection->Request.analyzeURL(Connection->HookHandler.NewURL);
|
||||
Connection->HookHandler.UrlData = Connection->Request.UrlData;
|
||||
}
|
||||
if(Connection->HookHandler.status == HANDLED_REDIRECTION)
|
||||
{
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while(Connection->HookHandler.status == HANDLED_REWRITE);
|
||||
Connection->HookHandler.Hooks_SendResponse();
|
||||
if ((Connection->HookHandler.status == HANDLED_READY)
|
||||
|| (Connection->HookHandler.status == HANDLED_CONTINUE)) {
|
||||
log_level_printf(2, "Response Hook Output. Status:%d\n", Connection->HookHandler.status);
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
if (Connection->Method != M_HEAD)
|
||||
Write(Connection->HookHandler.yresult);
|
||||
if (Connection->HookHandler.status != HANDLED_CONTINUE)
|
||||
return true;
|
||||
} else if (Connection->HookHandler.status == HANDLED_ERROR) {
|
||||
log_level_printf(2, "Response Hook found but Error\n");
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
if (Connection->Method != M_HEAD)
|
||||
Write(Connection->HookHandler.yresult);
|
||||
return false;
|
||||
} else if (Connection->HookHandler.status == HANDLED_ABORT)
|
||||
return false;
|
||||
// URL has new value. Analyze new URL for SendFile
|
||||
else if (Connection->HookHandler.status == HANDLED_SENDFILE
|
||||
|| Connection->HookHandler.status == HANDLED_REWRITE) {
|
||||
Connection->Request.analyzeURL(Connection->HookHandler.NewURL);
|
||||
Connection->HookHandler.UrlData = Connection->Request.UrlData;
|
||||
}
|
||||
if (Connection->HookHandler.status == HANDLED_REDIRECTION) {
|
||||
Write(Connection->HookHandler.BuildHeader());
|
||||
return false;
|
||||
}
|
||||
} while (Connection->HookHandler.status == HANDLED_REWRITE);
|
||||
|
||||
// Send static file
|
||||
if(Connection->HookHandler.status == HANDLED_SENDFILE && !Connection->RequestCanceled)
|
||||
{
|
||||
if (Connection->HookHandler.status == HANDLED_SENDFILE
|
||||
&& !Connection->RequestCanceled) {
|
||||
bool cache = true;
|
||||
// if(Connection->HookHandler.UrlData["path"] == "/tmp/")//TODO: un-cachable dirs
|
||||
// cache = false;
|
||||
// if(Connection->HookHandler.UrlData["path"] == "/tmp/")//TODO: un-cachable dirs
|
||||
// cache = false;
|
||||
Write(Connection->HookHandler.BuildHeader(cache));
|
||||
if(Connection->Method != M_HEAD)
|
||||
if (Connection->Method != M_HEAD)
|
||||
Sendfile(Connection->Request.UrlData["url"]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// arrived here? = error!
|
||||
SendError(HTTP_NOT_FOUND);
|
||||
SendError( HTTP_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Output
|
||||
//=============================================================================
|
||||
void CWebserverResponse::SendHeader(HttpResponseType responseType, bool cache, std::string ContentType)
|
||||
{
|
||||
Connection->HookHandler.SetHeader(responseType, ContentType);
|
||||
void CWebserverResponse::SendHeader(HttpResponseType responseType, bool cache,
|
||||
std::string ContentType) {
|
||||
Connection->HookHandler.SetHeader(responseType, ContentType);
|
||||
Write(Connection->HookHandler.BuildHeader(cache));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// BASIC Send over Socket for Strings (char*)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverResponse::WriteData(char const * data, long length)
|
||||
{
|
||||
if(Connection->RequestCanceled)
|
||||
bool CWebserverResponse::WriteData(char const * data, long length) {
|
||||
if (Connection->RequestCanceled)
|
||||
return false;
|
||||
if(Connection->sock->Send(data, length) == -1)
|
||||
{
|
||||
log_level_printf(1,"response canceled: %s\n", strerror(errno));
|
||||
if (Connection->sock->Send(data, length) == -1) {
|
||||
log_level_printf(1, "response canceled: %s\n", strerror(errno));
|
||||
Connection->RequestCanceled = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
#define bufferlen 4*1024
|
||||
void CWebserverResponse::printf ( const char *fmt, ... )
|
||||
{
|
||||
void CWebserverResponse::printf(const char *fmt, ...) {
|
||||
char buffer[bufferlen];
|
||||
va_list arglist;
|
||||
va_start( arglist, fmt );
|
||||
vsnprintf( buffer, bufferlen, fmt, arglist );
|
||||
va_start(arglist, fmt);
|
||||
vsnprintf(buffer, bufferlen, fmt, arglist);
|
||||
va_end(arglist);
|
||||
Write(buffer);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverResponse::Write(char const *text)
|
||||
{
|
||||
bool CWebserverResponse::Write(char const *text) {
|
||||
return WriteData(text, strlen(text));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverResponse::WriteLn(char const *text)
|
||||
{
|
||||
if(!WriteData(text, strlen(text)))
|
||||
bool CWebserverResponse::WriteLn(char const *text) {
|
||||
if (!WriteData(text, strlen(text)))
|
||||
return false;
|
||||
return WriteData("\r\n",2);
|
||||
return WriteData("\r\n", 2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserverResponse::Sendfile(std::string filename)
|
||||
{
|
||||
if(Connection->RequestCanceled)
|
||||
bool CWebserverResponse::Sendfile(std::string filename) {
|
||||
if (Connection->RequestCanceled)
|
||||
return false;
|
||||
int filed = open( filename.c_str(), O_RDONLY );
|
||||
if(filed != -1 ) //can access file?
|
||||
int filed = open(filename.c_str(), O_RDONLY);
|
||||
if (filed != -1) //can access file?
|
||||
{
|
||||
if(!Connection->sock->SendFile(filed))
|
||||
if (!Connection->sock->SendFile(filed))
|
||||
Connection->RequestCanceled = true;
|
||||
close(filed);
|
||||
}
|
||||
return (filed != -1 );
|
||||
return (filed != -1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Send File: Determine MIME-Type fro File-Extention
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CWebserverResponse::GetContentType(std::string ext)
|
||||
{
|
||||
std::string CWebserverResponse::GetContentType(std::string ext) {
|
||||
std::string ctype = "text/plain";
|
||||
ext = string_tolower(ext);
|
||||
for (unsigned int i = 0;i < (sizeof(MimeFileExtensions)/sizeof(MimeFileExtensions[0])); i++)
|
||||
if (MimeFileExtensions[i].fileext == ext)
|
||||
{
|
||||
for (unsigned int i = 0; i < (sizeof(MimeFileExtensions)
|
||||
/ sizeof(MimeFileExtensions[0])); i++)
|
||||
if (MimeFileExtensions[i].fileext == ext) {
|
||||
ctype = MimeFileExtensions[i].mime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ctype;
|
||||
}
|
||||
|
@@ -32,46 +32,43 @@
|
||||
// Initialization of static variables
|
||||
//=============================================================================
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
SSL_CTX *CySocket::SSL_ctx;
|
||||
std::string CySocket::SSL_pemfile;
|
||||
std::string CySocket::SSL_CA_file;
|
||||
SSL_CTX *CySocket::SSL_ctx;
|
||||
std::string CySocket::SSL_pemfile;
|
||||
std::string CySocket::SSL_CA_file;
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Constructor & Destructor & Initialization
|
||||
//=============================================================================
|
||||
CySocket::CySocket()
|
||||
: sock(0)
|
||||
{
|
||||
CySocket::CySocket() :
|
||||
sock(0) {
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
ssl = NULL;
|
||||
#endif
|
||||
tv_start_waiting.tv_sec = 0;
|
||||
tv_start_waiting.tv_usec = 0;
|
||||
BytesSend =0;
|
||||
sock = socket(AF_INET,SOCK_STREAM,0);
|
||||
BytesSend = 0;
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
init();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
CySocket::~CySocket()
|
||||
{
|
||||
CySocket::~CySocket() {
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
if(isSSLSocket && ssl != NULL)
|
||||
SSL_free(ssl);
|
||||
SSL_free(ssl);
|
||||
#endif
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// initialize
|
||||
//-----------------------------------------------------------------------------
|
||||
void CySocket::init(void)
|
||||
{
|
||||
handling = false;
|
||||
isOpened = false;
|
||||
isValid = true;
|
||||
addr_len = sizeof(addr);
|
||||
void CySocket::init(void) {
|
||||
handling = false;
|
||||
isOpened = false;
|
||||
isValid = true;
|
||||
addr_len = sizeof(addr);
|
||||
memset(&addr, 0, addr_len);
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
isSSLSocket = false;
|
||||
isSSLSocket = false;
|
||||
#endif
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -82,13 +79,13 @@ void CySocket::init(void)
|
||||
bool CySocket::initAsSSL(void)
|
||||
{
|
||||
isSSLSocket = true;
|
||||
if (NULL == (ssl = SSL_new(CySocket::SSL_ctx))) // create SSL-socket
|
||||
if (NULL == (ssl = SSL_new(CySocket::SSL_ctx))) // create SSL-socket
|
||||
{
|
||||
aprintf("ySocket:SSL Error: Create SSL_new : %s\n", ERR_error_string(ERR_get_error(), NULL) );
|
||||
return false;
|
||||
}
|
||||
SSL_set_accept_state(ssl); // accept connection
|
||||
if(1 != (SSL_set_fd(ssl, sock))) // associate socket descriptor
|
||||
SSL_set_accept_state(ssl); // accept connection
|
||||
if(1 != (SSL_set_fd(ssl, sock))) // associate socket descriptor
|
||||
if (NULL == (ssl = SSL_new(CySocket::SSL_ctx)))
|
||||
{
|
||||
aprintf("ySocket:SSL Error: Create SSL_new : %s\n", ERR_error_string(ERR_get_error(), NULL) );
|
||||
@@ -102,9 +99,9 @@ bool CySocket::initAsSSL(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CySocket::initSSL(void)
|
||||
{
|
||||
SSL_load_error_strings(); // Load SSL Error Strings
|
||||
SSL_library_init(); // Load SSL Library
|
||||
if (0 == RAND_status()) // set Random
|
||||
SSL_load_error_strings(); // Load SSL Error Strings
|
||||
SSL_library_init(); // Load SSL Library
|
||||
if (0 == RAND_status()) // set Random
|
||||
{
|
||||
aprintf("ySocket:SSL got no rand\n");
|
||||
return false;
|
||||
@@ -119,12 +116,12 @@ bool CySocket::initSSL(void)
|
||||
aprintf("ySocket:SSL Error: no pemfile given\n");
|
||||
return false;
|
||||
}
|
||||
if(SSL_CA_file != "") // have a CA?
|
||||
if(1 != SSL_CTX_load_verify_locations(SSL_ctx, SSL_CA_file.c_str(), NULL))
|
||||
{
|
||||
aprintf("ySocket:SSL Error: %s CA-File:%s\n",ERR_error_string(ERR_get_error(), NULL), SSL_CA_file.c_str());
|
||||
return false;
|
||||
}
|
||||
if(SSL_CA_file != "") // have a CA?
|
||||
if(1 != SSL_CTX_load_verify_locations(SSL_ctx, SSL_CA_file.c_str(), NULL))
|
||||
{
|
||||
aprintf("ySocket:SSL Error: %s CA-File:%s\n",ERR_error_string(ERR_get_error(), NULL), SSL_CA_file.c_str());
|
||||
return false;
|
||||
}
|
||||
if(SSL_CTX_use_certificate_file(SSL_ctx, SSL_pemfile.c_str(), SSL_FILETYPE_PEM) < 0)
|
||||
{
|
||||
aprintf("ySocket:SSL Error: %s PEM-File:%s\n",ERR_error_string(ERR_get_error(), NULL), SSL_pemfile.c_str());
|
||||
@@ -147,54 +144,48 @@ bool CySocket::initSSL(void)
|
||||
//=============================================================================
|
||||
// Socket handling
|
||||
//=============================================================================
|
||||
void CySocket::close(void)
|
||||
{
|
||||
if(sock != 0 && sock != INVALID_SOCKET)
|
||||
::close(sock);
|
||||
void CySocket::close(void) {
|
||||
if (sock != 0 && sock != INVALID_SOCKET)
|
||||
::close( sock);
|
||||
#ifndef Y_CONFIG_FEATURE_KEEP_ALIVE
|
||||
sock = 0;
|
||||
#endif
|
||||
isOpened = false;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void CySocket::shutdown(void)
|
||||
{
|
||||
if(sock != 0 && sock != INVALID_SOCKET)
|
||||
::shutdown(sock,SHUT_RDWR);
|
||||
void CySocket::shutdown(void) {
|
||||
if (sock != 0 && sock != INVALID_SOCKET)
|
||||
::shutdown(sock, SHUT_RDWR);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CySocket::listen(int port, int max_connections)
|
||||
{
|
||||
if(sock == INVALID_SOCKET)
|
||||
bool CySocket::listen(int port, int max_connections) {
|
||||
if (sock == INVALID_SOCKET)
|
||||
return false;
|
||||
|
||||
// set sockaddr for listening
|
||||
sockaddr_in sai;
|
||||
memset(&sai, 0, sizeof(sai));
|
||||
sai.sin_family = AF_INET; // Protocol
|
||||
sai.sin_addr.s_addr = htonl(INADDR_ANY); // No Filter
|
||||
sai.sin_port = htons(port); // Listening Port
|
||||
memset(&sai, 0, sizeof(sai));
|
||||
sai.sin_family = AF_INET; // Protocol
|
||||
sai.sin_addr.s_addr = htonl(INADDR_ANY); // No Filter
|
||||
sai.sin_port = htons(port); // Listening Port
|
||||
|
||||
set_reuse_port(); // Re-Use Port
|
||||
set_reuse_addr(); // Re-Use IP
|
||||
if(bind(sock, (sockaddr *)&sai, sizeof(sockaddr_in)) != SOCKET_ERROR)
|
||||
if(::listen(sock, max_connections) == 0)
|
||||
set_reuse_port(); // Re-Use Port
|
||||
set_reuse_addr(); // Re-Use IP
|
||||
if (bind(sock, (sockaddr *) &sai, sizeof(sockaddr_in)) != SOCKET_ERROR)
|
||||
if (::listen(sock, max_connections) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
CySocket* CySocket::accept()
|
||||
{
|
||||
CySocket* CySocket::accept() {
|
||||
init();
|
||||
SOCKET newSock = ::accept(sock, (sockaddr *) &addr, &addr_len);
|
||||
if(newSock == INVALID_SOCKET)
|
||||
{
|
||||
if (newSock == INVALID_SOCKET) {
|
||||
dperror("accept: invalid socket\n");
|
||||
return NULL;
|
||||
}
|
||||
CySocket *new_ySocket = new CySocket(newSock);
|
||||
if(new_ySocket != NULL)
|
||||
{
|
||||
if (new_ySocket != NULL) {
|
||||
new_ySocket->setAddr(addr);
|
||||
#ifdef TCP_CORK
|
||||
new_ySocket->set_option(IPPROTO_TCP, TCP_CORK);
|
||||
@@ -203,75 +194,67 @@ CySocket* CySocket::accept()
|
||||
#endif
|
||||
}
|
||||
new_ySocket->isOpened = true;
|
||||
// handling = true;
|
||||
// handling = true;
|
||||
return new_ySocket;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CySocket::get_client_ip(void)
|
||||
{
|
||||
std::string CySocket::get_client_ip(void) {
|
||||
return inet_ntoa(addr.sin_addr);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
int CySocket::get_accept_port(void)
|
||||
{
|
||||
return (int)ntohs(addr.sin_port);
|
||||
int CySocket::get_accept_port(void) {
|
||||
return (int) ntohs(addr.sin_port);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void CySocket::setAddr(sockaddr_in _addr)
|
||||
{
|
||||
void CySocket::setAddr(sockaddr_in _addr) {
|
||||
addr = _addr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set Socket Option (return = false = error)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CySocket::set_option(int typ, int option)
|
||||
{
|
||||
bool CySocket::set_option(int typ, int option) {
|
||||
int on = 1;
|
||||
return (setsockopt(sock, typ, option, (char *)&on, sizeof(on)) >= 0);
|
||||
return (setsockopt(sock, typ, option, (char *) &on, sizeof(on)) >= 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set Re-Use Option for Port.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CySocket::set_reuse_port()
|
||||
{
|
||||
void CySocket::set_reuse_port() {
|
||||
#ifdef SO_REUSEPORT
|
||||
if(!set_option(SOL_SOCKET, SO_REUSEPORT))
|
||||
dperror("setsockopt(SO_REUSEPORT)\n");
|
||||
dperror("setsockopt(SO_REUSEPORT)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set Re-Use Option for Address.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CySocket::set_reuse_addr()
|
||||
{
|
||||
void CySocket::set_reuse_addr() {
|
||||
#ifdef SO_REUSEADDR
|
||||
if(!set_option(SOL_SOCKET, SO_REUSEADDR))
|
||||
dperror("setsockopt(SO_REUSEADDR)\n");
|
||||
dperror("setsockopt(SO_REUSEADDR)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set Keep-Alive Option for Socket.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CySocket::set_keep_alive()
|
||||
{
|
||||
void CySocket::set_keep_alive() {
|
||||
#ifdef SO_KEEPALIVE
|
||||
if(!set_option(SOL_SOCKET, SO_KEEPALIVE))
|
||||
dperror("setsockopt(SO_KEEPALIVE)\n");
|
||||
dperror("setsockopt(SO_KEEPALIVE)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set Keep-Alive Option for Socket.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CySocket::set_tcp_nodelay()
|
||||
{
|
||||
void CySocket::set_tcp_nodelay() {
|
||||
#ifdef TCP_NODELAY
|
||||
if(!set_option(IPPROTO_TCP, TCP_NODELAY))
|
||||
dperror("setsockopt(SO_KEEPALIVE)\n");
|
||||
dperror("setsockopt(SO_KEEPALIVE)\n");
|
||||
#endif
|
||||
}
|
||||
//=============================================================================
|
||||
@@ -280,37 +263,34 @@ void CySocket::set_tcp_nodelay()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read a buffer (normal or SSL)
|
||||
//-----------------------------------------------------------------------------
|
||||
int CySocket::Read(char *buffer, unsigned int length)
|
||||
{
|
||||
int CySocket::Read(char *buffer, unsigned int length) {
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
if(isSSLSocket)
|
||||
return SSL_read(ssl, buffer, length);
|
||||
return SSL_read(ssl, buffer, length);
|
||||
else
|
||||
#endif
|
||||
return ::read(sock, buffer, length);
|
||||
return ::read(sock, buffer, length);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Send a buffer (normal or SSL)
|
||||
//-----------------------------------------------------------------------------
|
||||
int CySocket::Send(char const *buffer, unsigned int length)
|
||||
{
|
||||
int CySocket::Send(char const *buffer, unsigned int length) {
|
||||
unsigned int len = 0;
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
if(isSSLSocket)
|
||||
len = SSL_write(ssl, buffer, length);
|
||||
len = SSL_write(ssl, buffer, length);
|
||||
else
|
||||
#endif
|
||||
len = ::send(sock, buffer, length, MSG_NOSIGNAL);
|
||||
if(len > 0)
|
||||
len = ::send(sock, buffer, length, MSG_NOSIGNAL);
|
||||
if (len > 0)
|
||||
BytesSend += len;
|
||||
return len;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Check if Socket was closed by client
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CySocket::CheckSocketOpen()
|
||||
{
|
||||
char buffer[32]={0};
|
||||
bool CySocket::CheckSocketOpen() {
|
||||
char buffer[32] = { 0 };
|
||||
|
||||
#ifdef CONFIG_SYSTEM_CYGWIN
|
||||
return !(recv(sock, buffer, sizeof(buffer), MSG_PEEK | MSG_NOSIGNAL) == 0);
|
||||
@@ -327,9 +307,8 @@ bool CySocket::CheckSocketOpen()
|
||||
// BASIC Send File over Socket for FILE*
|
||||
// fd is an opened FILE-Descriptor
|
||||
//-----------------------------------------------------------------------------
|
||||
int CySocket::SendFile(int filed)
|
||||
{
|
||||
if(!isValid)
|
||||
int CySocket::SendFile(int filed) {
|
||||
if (!isValid)
|
||||
return false;
|
||||
#ifdef Y_CONFIG_HAVE_SENDFILE
|
||||
// does not work with SSL !!!
|
||||
@@ -339,23 +318,21 @@ int CySocket::SendFile(int filed)
|
||||
if((written = ::sendfile(sock,filed,&start,end)) == -1)
|
||||
{
|
||||
perror("sendfile failed\n");
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
BytesSend += written;
|
||||
BytesSend += written;
|
||||
#else
|
||||
char sbuf[1024];
|
||||
unsigned int r=0;
|
||||
while ((r=read(filed, sbuf, 1024)) > 0)
|
||||
{
|
||||
if (Send(sbuf, r) < 0)
|
||||
{
|
||||
unsigned int r = 0;
|
||||
while ((r = read(filed, sbuf, 1024)) > 0) {
|
||||
if (Send(sbuf, r) < 0) {
|
||||
perror("sendfile failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif // Y_CONFIG_HAVE_SENDFILE
|
||||
log_level_printf(9,"<Sock:SendFile>: Bytes:%ld\n", BytesSend);
|
||||
log_level_printf(9, "<Sock:SendFile>: Bytes:%ld\n", BytesSend);
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -365,107 +342,100 @@ int CySocket::SendFile(int filed)
|
||||
// fd is an opened FILE-Descriptor
|
||||
//-----------------------------------------------------------------------------
|
||||
//TODO: Write upload Progress Informations into a file
|
||||
unsigned int CySocket::ReceiveFileGivenLength(int filed, unsigned int _length)
|
||||
{
|
||||
unsigned int CySocket::ReceiveFileGivenLength(int filed, unsigned int _length) {
|
||||
unsigned int _readbytes = 0;
|
||||
char buffer[RECEIVE_BLOCK_LEN];
|
||||
int retries=0;
|
||||
int retries = 0;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
// check bytes in Socket buffer
|
||||
u_long readarg = 0;
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
if(isSSLSocket)
|
||||
readarg = RECEIVE_BLOCK_LEN;
|
||||
readarg = RECEIVE_BLOCK_LEN;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(ioctl(sock, FIONREAD, &readarg) != 0)// How many bytes avaiable on socket?
|
||||
break;
|
||||
if(readarg > RECEIVE_BLOCK_LEN) // enough bytes to read
|
||||
readarg = RECEIVE_BLOCK_LEN; // read only given length
|
||||
if (ioctl(sock, FIONREAD, &readarg) != 0)// How many bytes avaiable on socket?
|
||||
break;
|
||||
if (readarg > RECEIVE_BLOCK_LEN) // enough bytes to read
|
||||
readarg = RECEIVE_BLOCK_LEN; // read only given length
|
||||
}
|
||||
if(readarg == 0) // nothing to read: sleep
|
||||
{
|
||||
retries++;
|
||||
if(retries >NON_BLOCKING_MAX_RETRIES)
|
||||
break;
|
||||
sleep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (readarg == 0) // nothing to read: sleep
|
||||
{
|
||||
retries++;
|
||||
if (retries > NON_BLOCKING_MAX_RETRIES)
|
||||
break;
|
||||
sleep(1);
|
||||
} else {
|
||||
int bytes_gotten = Read(buffer, readarg);
|
||||
|
||||
if(bytes_gotten == -1 && errno == EINTR)// non-blocking
|
||||
continue;
|
||||
if(bytes_gotten <= 0) // ERROR Code gotten or Conection closed by peer
|
||||
if (bytes_gotten == -1 && errno == EINTR)// non-blocking
|
||||
continue;
|
||||
if (bytes_gotten <= 0) // ERROR Code gotten or Conection closed by peer
|
||||
{
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
_readbytes += bytes_gotten;
|
||||
if (write(filed, buffer, bytes_gotten) != bytes_gotten)
|
||||
{
|
||||
if (write(filed, buffer, bytes_gotten) != bytes_gotten) {
|
||||
perror("write file failed\n");
|
||||
return 0;
|
||||
}
|
||||
retries = 0;
|
||||
if(bytes_gotten < NON_BLOCKING_TRY_BYTES) // to few bytes gotten: sleep
|
||||
sleep(1);
|
||||
}
|
||||
log_level_printf(8,"Receive Block length:%d all:%d\n",_readbytes, _length);
|
||||
}
|
||||
while(_readbytes + RECEIVE_BLOCK_LEN < _length);
|
||||
return 0;
|
||||
}
|
||||
retries = 0;
|
||||
if (bytes_gotten < NON_BLOCKING_TRY_BYTES) // to few bytes gotten: sleep
|
||||
sleep(1);
|
||||
}
|
||||
log_level_printf(8, "Receive Block length:%d all:%d\n", _readbytes,
|
||||
_length);
|
||||
} while (_readbytes + RECEIVE_BLOCK_LEN < _length);
|
||||
return _readbytes;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// read all data avaiable on Socket
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CySocket::ReceiveBlock()
|
||||
{
|
||||
std::string CySocket::ReceiveBlock() {
|
||||
std::string result = "";
|
||||
char buffer[RECEIVE_BLOCK_LEN];
|
||||
|
||||
if(!isValid || !isOpened)
|
||||
if (!isValid || !isOpened)
|
||||
return "";
|
||||
// signal(SIGALRM, ytimeout);
|
||||
// signal(SIGALRM, ytimeout);
|
||||
alarm(1);
|
||||
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
// check bytes in Socket buffer
|
||||
u_long readarg = 0;
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
if(isSSLSocket)
|
||||
readarg = RECEIVE_BLOCK_LEN;
|
||||
readarg = RECEIVE_BLOCK_LEN;
|
||||
else
|
||||
#endif
|
||||
// determine bytes that can be read
|
||||
{
|
||||
if(ioctl(sock, FIONREAD, &readarg) != 0)
|
||||
break;
|
||||
if(readarg == 0) // nothing to read
|
||||
break;
|
||||
if(readarg > RECEIVE_BLOCK_LEN) // need more loops
|
||||
readarg = RECEIVE_BLOCK_LEN;
|
||||
if (ioctl(sock, FIONREAD, &readarg) != 0)
|
||||
break;
|
||||
if (readarg == 0) // nothing to read
|
||||
break;
|
||||
if (readarg > RECEIVE_BLOCK_LEN) // need more loops
|
||||
readarg = RECEIVE_BLOCK_LEN;
|
||||
}
|
||||
// Read data
|
||||
int bytes_gotten = Read(buffer, readarg);
|
||||
|
||||
if(bytes_gotten == -1 && errno == EINTR)// non-blocking
|
||||
continue;
|
||||
if(bytes_gotten <= 0) // ERROR Code gotten or Conection closed by peer
|
||||
if (bytes_gotten == -1 && errno == EINTR)// non-blocking
|
||||
continue;
|
||||
if (bytes_gotten <= 0) // ERROR Code gotten or Conection closed by peer
|
||||
{
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
result.append(buffer, bytes_gotten);
|
||||
if((u_long)bytes_gotten < readarg) // no more bytes
|
||||
if ((u_long) bytes_gotten < readarg) // no more bytes
|
||||
break;
|
||||
}
|
||||
alarm(0);
|
||||
signal(SIGALRM,SIG_IGN);
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -473,28 +443,23 @@ std::string CySocket::ReceiveBlock()
|
||||
// Read on line (Ends with LF) or maximum MAX_LINE_BUFFER chars
|
||||
// Result Contains [CR]LF!
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CySocket::ReceiveLine()
|
||||
{
|
||||
std::string CySocket::ReceiveLine() {
|
||||
char buffer[MAX_LINE_BUFFER];
|
||||
int bytes_gotten = 0;
|
||||
std::string result="";
|
||||
std::string result = "";
|
||||
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
// read one char
|
||||
if(Read(buffer+bytes_gotten, 1) == 1)
|
||||
{
|
||||
if(buffer[bytes_gotten] == '\n')
|
||||
if (Read(buffer + bytes_gotten, 1) == 1) {
|
||||
if (buffer[bytes_gotten] == '\n')
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(bytes_gotten < MAX_LINE_BUFFER-1)
|
||||
bytes_gotten ++;
|
||||
if (bytes_gotten < MAX_LINE_BUFFER - 1)
|
||||
bytes_gotten++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
@@ -30,21 +30,20 @@
|
||||
//=============================================================================
|
||||
// Initialization of static variables
|
||||
//=============================================================================
|
||||
bool CWebserver::is_threading = true;
|
||||
pthread_mutex_t CWebserver::mutex = PTHREAD_MUTEX_INITIALIZER;;
|
||||
bool CWebserver::is_threading = true;
|
||||
pthread_mutex_t CWebserver::mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
;
|
||||
|
||||
//=============================================================================
|
||||
// Constructor & Destructor & Initialization
|
||||
//=============================================================================
|
||||
CWebserver::CWebserver()
|
||||
{
|
||||
CWebserver::CWebserver() {
|
||||
terminate = false;
|
||||
for(int i=0;i<HTTPD_MAX_CONNECTIONS;i++)
|
||||
{
|
||||
Connection_Thread_List[i] = (pthread_t)NULL;
|
||||
for (int i = 0; i < HTTPD_MAX_CONNECTIONS; i++) {
|
||||
Connection_Thread_List[i] = (pthread_t) NULL;
|
||||
SocketList[i] = NULL;
|
||||
}
|
||||
FD_ZERO(&master); // initialize FD_SETs
|
||||
FD_ZERO(&master); // initialize FD_SETs
|
||||
FD_ZERO(&read_fds);
|
||||
fdmax = 0;
|
||||
open_connections = 0;
|
||||
@@ -52,13 +51,11 @@ CWebserver::CWebserver()
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
#endif
|
||||
port=80;
|
||||
|
||||
port = 80;
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
CWebserver::~CWebserver()
|
||||
{
|
||||
CWebserver::~CWebserver() {
|
||||
listenSocket.close();
|
||||
}
|
||||
//=============================================================================
|
||||
@@ -118,10 +115,8 @@ CWebserver::~CWebserver()
|
||||
//=============================================================================
|
||||
#define MAX_TIMEOUTS_TO_CLOSE 10
|
||||
#define MAX_TIMEOUTS_TO_TEST 100
|
||||
bool CWebserver::run(void)
|
||||
{
|
||||
if(!listenSocket.listen(port, HTTPD_MAX_CONNECTIONS))
|
||||
{
|
||||
bool CWebserver::run(void) {
|
||||
if (!listenSocket.listen(port, HTTPD_MAX_CONNECTIONS)) {
|
||||
dperror("Socket cannot bind and listen. Abort.\n");
|
||||
return false;
|
||||
}
|
||||
@@ -129,31 +124,31 @@ bool CWebserver::run(void)
|
||||
|
||||
// initialize values for select
|
||||
int listener = listenSocket.get_socket();// Open Listener
|
||||
struct timeval tv; // timeout struct
|
||||
FD_SET(listener, &master); // add the listener to the master set
|
||||
fdmax = listener; // init max fd
|
||||
fcntl(listener, F_SETFD , O_NONBLOCK); // listener master socket non-blocking
|
||||
int timeout_counter = 0; // Counter for Connection Timeout checking
|
||||
int test_counter = 0; // Counter for Testing long running Connections
|
||||
struct timeval tv; // timeout struct
|
||||
FD_SET(listener, &master); // add the listener to the master set
|
||||
fdmax = listener; // init max fd
|
||||
fcntl(listener, F_SETFD , O_NONBLOCK); // listener master socket non-blocking
|
||||
int timeout_counter = 0; // Counter for Connection Timeout checking
|
||||
int test_counter = 0; // Counter for Testing long running Connections
|
||||
|
||||
// main Webserver Loop
|
||||
while(!terminate)
|
||||
{
|
||||
// select : init vars
|
||||
read_fds = master; // copy it
|
||||
tv.tv_usec = 10000; // microsec: Timeout for select ! for re-use / keep-alive socket
|
||||
tv.tv_sec = 0; // seconds
|
||||
int fd = -1;
|
||||
read_fds = master; // copy it
|
||||
tv.tv_usec = 10000; // microsec: Timeout for select ! for re-use / keep-alive socket
|
||||
tv.tv_sec = 0; // seconds
|
||||
int fd = -1;
|
||||
|
||||
// select : wait for socket activity
|
||||
if(open_connections <= 0) // No open Connection. Wait in select.
|
||||
fd = select(fdmax+1,&read_fds, NULL, NULL, NULL);// wait for socket activity
|
||||
if(open_connections <= 0) // No open Connection. Wait in select.
|
||||
fd = select(fdmax+1,&read_fds, NULL, NULL, NULL);// wait for socket activity
|
||||
else
|
||||
fd = select(fdmax+1,&read_fds, NULL, NULL, &tv);// wait for socket activity or timeout
|
||||
fd = select(fdmax+1,&read_fds, NULL, NULL, &tv);// wait for socket activity or timeout
|
||||
|
||||
// too much to do : sleep
|
||||
if(open_connections >= HTTPD_MAX_CONNECTIONS-1)
|
||||
sleep(1);
|
||||
sleep(1);
|
||||
|
||||
// Socket Error?
|
||||
if(fd == -1 && errno != EINTR)
|
||||
@@ -169,9 +164,9 @@ bool CWebserver::run(void)
|
||||
if(++test_counter >= MAX_TIMEOUTS_TO_TEST)
|
||||
{
|
||||
for(int j=0;j < HTTPD_MAX_CONNECTIONS;j++)
|
||||
if(SocketList[j] != NULL) // here is a socket
|
||||
log_level_printf(2,"FD-TEST sock:%d handle:%d open:%d\n",SocketList[j]->get_socket(),
|
||||
SocketList[j]->handling,SocketList[j]->isOpened);
|
||||
if(SocketList[j] != NULL) // here is a socket
|
||||
log_level_printf(2,"FD-TEST sock:%d handle:%d open:%d\n",SocketList[j]->get_socket(),
|
||||
SocketList[j]->handling,SocketList[j]->isOpened);
|
||||
test_counter=0;
|
||||
}
|
||||
// some connection closing previous missed?
|
||||
@@ -180,7 +175,7 @@ bool CWebserver::run(void)
|
||||
CloseConnectionSocketsByTimeout();
|
||||
timeout_counter=0;
|
||||
}
|
||||
continue; // main loop again
|
||||
continue; // main loop again
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Check all observed descriptors & check new or re-use Connections
|
||||
@@ -188,48 +183,48 @@ bool CWebserver::run(void)
|
||||
for(int i = listener; i <= fdmax; i++)
|
||||
{
|
||||
int slot = -1;
|
||||
if(FD_ISSET(i, &read_fds)) // Socket observed?
|
||||
if(FD_ISSET(i, &read_fds)) // Socket observed?
|
||||
{ // we got one!!
|
||||
if (i == listener) // handle new connections
|
||||
slot = AcceptNewConnectionSocket();
|
||||
else // Connection on an existing open Socket = reuse (keep-alive)
|
||||
if (i == listener) // handle new connections
|
||||
slot = AcceptNewConnectionSocket();
|
||||
else // Connection on an existing open Socket = reuse (keep-alive)
|
||||
{
|
||||
slot = SL_GetExistingSocket(i);
|
||||
if(slot>=0)
|
||||
log_level_printf(2,"FD: reuse con fd:%d\n",SocketList[slot]->get_socket());
|
||||
log_level_printf(2,"FD: reuse con fd:%d\n",SocketList[slot]->get_socket());
|
||||
}
|
||||
// prepare Connection handling
|
||||
if(slot>=0)
|
||||
if(SocketList[slot] != NULL && !SocketList[slot]->handling && SocketList[slot]->isValid)
|
||||
{
|
||||
log_level_printf(2,"FD: START CON HANDLING con fd:%d\n",SocketList[slot]->get_socket());
|
||||
FD_CLR(SocketList[slot]->get_socket(), &master); // remove from master set
|
||||
SocketList[slot]->handling = true; // prepares for thread-handling
|
||||
if(!handle_connection(SocketList[slot]))// handle this activity
|
||||
{ // Can not handle more threads
|
||||
char httpstr[]=HTTP_PROTOCOL " 503 Service Unavailable\r\n\r\n";
|
||||
SocketList[slot]->Send(httpstr, strlen(httpstr));
|
||||
SL_CloseSocketBySlot(slot);
|
||||
}
|
||||
if(SocketList[slot] != NULL && !SocketList[slot]->handling && SocketList[slot]->isValid)
|
||||
{
|
||||
log_level_printf(2,"FD: START CON HANDLING con fd:%d\n",SocketList[slot]->get_socket());
|
||||
FD_CLR(SocketList[slot]->get_socket(), &master); // remove from master set
|
||||
SocketList[slot]->handling = true; // prepares for thread-handling
|
||||
if(!handle_connection(SocketList[slot]))// handle this activity
|
||||
{ // Can not handle more threads
|
||||
char httpstr[]=HTTP_PROTOCOL " 503 Service Unavailable\r\n\r\n";
|
||||
SocketList[slot]->Send(httpstr, strlen(httpstr));
|
||||
SL_CloseSocketBySlot(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}// for
|
||||
CloseConnectionSocketsByTimeout(); // Check connections to close
|
||||
CloseConnectionSocketsByTimeout(); // Check connections to close
|
||||
|
||||
}//while
|
||||
#else
|
||||
while(!terminate)
|
||||
{
|
||||
while (!terminate) {
|
||||
CySocket *newConnectionSock;
|
||||
if(!(newConnectionSock = listenSocket.accept() )) //Now: Blocking wait
|
||||
if (!(newConnectionSock = listenSocket.accept())) //Now: Blocking wait
|
||||
{
|
||||
dperror("Socket accept error. Continue.\n");
|
||||
continue;
|
||||
}
|
||||
log_level_printf(3,"Socket connect from %s\n", (listenSocket.get_client_ip()).c_str() );
|
||||
log_level_printf(3, "Socket connect from %s\n",
|
||||
(listenSocket.get_client_ip()).c_str());
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
if(Cyhttpd::ConfigList["SSL"]=="true")
|
||||
newConnectionSock->initAsSSL(); // make it a SSL-socket
|
||||
if(Cyhttpd::ConfigList["SSL"]=="true")
|
||||
newConnectionSock->initAsSSL(); // make it a SSL-socket
|
||||
#endif
|
||||
handle_connection(newConnectionSock);
|
||||
}
|
||||
@@ -242,13 +237,12 @@ bool CWebserver::run(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Accept new Connection
|
||||
//-----------------------------------------------------------------------------
|
||||
int CWebserver::AcceptNewConnectionSocket()
|
||||
{
|
||||
int CWebserver::AcceptNewConnectionSocket() {
|
||||
int slot = -1;
|
||||
CySocket *connectionSock = NULL;
|
||||
int newfd;
|
||||
|
||||
if(!(connectionSock = listenSocket.accept() )) // Blocking wait
|
||||
if (!(connectionSock = listenSocket.accept())) // Blocking wait
|
||||
{
|
||||
dperror("Socket accept error. Continue.\n");
|
||||
delete connectionSock;
|
||||
@@ -256,24 +250,22 @@ int CWebserver::AcceptNewConnectionSocket()
|
||||
}
|
||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||
if(Cyhttpd::ConfigList["SSL"]=="true")
|
||||
connectionSock->initAsSSL(); // make it a SSL-socket
|
||||
connectionSock->initAsSSL(); // make it a SSL-socket
|
||||
#endif
|
||||
log_level_printf(2,"FD: new con fd:%d on port:%d\n",connectionSock->get_socket(), connectionSock->get_accept_port());
|
||||
log_level_printf(2, "FD: new con fd:%d on port:%d\n",
|
||||
connectionSock->get_socket(), connectionSock->get_accept_port());
|
||||
|
||||
// Add Socket to List
|
||||
slot = SL_GetFreeSlot();
|
||||
if(slot < 0)
|
||||
{
|
||||
if (slot < 0) {
|
||||
connectionSock->close();
|
||||
aprintf("No free Slot in SocketList found. Open:%d\n",open_connections);
|
||||
}
|
||||
else
|
||||
{
|
||||
SocketList[slot] = connectionSock; // put it to list
|
||||
fcntl(connectionSock->get_socket() , F_SETFD , O_NONBLOCK); // set non-blocking
|
||||
open_connections++; // count open connectins
|
||||
aprintf("No free Slot in SocketList found. Open:%d\n", open_connections);
|
||||
} else {
|
||||
SocketList[slot] = connectionSock; // put it to list
|
||||
fcntl(connectionSock->get_socket(), F_SETFD, O_NONBLOCK); // set non-blocking
|
||||
open_connections++; // count open connectins
|
||||
newfd = connectionSock->get_socket();
|
||||
if (newfd > fdmax) // keep track of the maximum fd
|
||||
if (newfd > fdmax) // keep track of the maximum fd
|
||||
fdmax = newfd;
|
||||
}
|
||||
return slot;
|
||||
@@ -282,12 +274,11 @@ int CWebserver::AcceptNewConnectionSocket()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Get Index for Socket from SocketList
|
||||
//-----------------------------------------------------------------------------
|
||||
int CWebserver::SL_GetExistingSocket(SOCKET sock)
|
||||
{
|
||||
int CWebserver::SL_GetExistingSocket(SOCKET sock) {
|
||||
int slot = -1;
|
||||
for(int j=0;j < HTTPD_MAX_CONNECTIONS;j++)
|
||||
if(SocketList[j] != NULL // here is a socket
|
||||
&& SocketList[j]->get_socket() == sock) // we know that socket
|
||||
for (int j = 0; j < HTTPD_MAX_CONNECTIONS; j++)
|
||||
if (SocketList[j] != NULL // here is a socket
|
||||
&& SocketList[j]->get_socket() == sock) // we know that socket
|
||||
{
|
||||
slot = j;
|
||||
break;
|
||||
@@ -297,11 +288,10 @@ int CWebserver::SL_GetExistingSocket(SOCKET sock)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Get Index for free Slot in SocketList
|
||||
//-----------------------------------------------------------------------------
|
||||
int CWebserver::SL_GetFreeSlot()
|
||||
{
|
||||
int CWebserver::SL_GetFreeSlot() {
|
||||
int slot = -1;
|
||||
for(int j=0;j < HTTPD_MAX_CONNECTIONS;j++)
|
||||
if(SocketList[j] == NULL) // here is a free slot
|
||||
for (int j = 0; j < HTTPD_MAX_CONNECTIONS; j++)
|
||||
if (SocketList[j] == NULL) // here is a free slot
|
||||
{
|
||||
slot = j;
|
||||
break;
|
||||
@@ -312,67 +302,65 @@ int CWebserver::SL_GetFreeSlot()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Look for Sockets to close
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWebserver::CloseConnectionSocketsByTimeout()
|
||||
{
|
||||
void CWebserver::CloseConnectionSocketsByTimeout() {
|
||||
CySocket *connectionSock = NULL;
|
||||
for(int j=0;j < HTTPD_MAX_CONNECTIONS;j++)
|
||||
if(SocketList[j] != NULL // here is a socket
|
||||
&& !SocketList[j]->handling) // it is not handled
|
||||
{
|
||||
connectionSock = SocketList[j];
|
||||
SOCKET thisSocket = connectionSock->get_socket();
|
||||
bool shouldClose = true;
|
||||
|
||||
if(!connectionSock->isValid) // If not valid -> close
|
||||
; // close
|
||||
else if(connectionSock->tv_start_waiting.tv_sec != 0 || SocketList[j]->tv_start_waiting.tv_usec != 0)
|
||||
{ // calculate keep-alive timeout
|
||||
struct timeval tv_now;
|
||||
struct timezone tz_now;
|
||||
gettimeofday(&tv_now, &tz_now);
|
||||
int64_t tdiff = ((tv_now.tv_sec - connectionSock->tv_start_waiting.tv_sec) * 1000000
|
||||
+ (tv_now.tv_usec - connectionSock->tv_start_waiting.tv_usec));
|
||||
if(tdiff < HTTPD_KEEPALIVE_TIMEOUT || tdiff <0)
|
||||
shouldClose = false;
|
||||
}
|
||||
if(shouldClose)
|
||||
for (int j = 0; j < HTTPD_MAX_CONNECTIONS; j++)
|
||||
if (SocketList[j] != NULL // here is a socket
|
||||
&& !SocketList[j]->handling) // it is not handled
|
||||
{
|
||||
log_level_printf(2,"FD: close con Timeout fd:%d\n",thisSocket);
|
||||
SL_CloseSocketBySlot(j);
|
||||
connectionSock = SocketList[j];
|
||||
SOCKET thisSocket = connectionSock->get_socket();
|
||||
bool shouldClose = true;
|
||||
|
||||
if (!connectionSock->isValid) // If not valid -> close
|
||||
; // close
|
||||
else if (connectionSock->tv_start_waiting.tv_sec != 0
|
||||
|| SocketList[j]->tv_start_waiting.tv_usec != 0) { // calculate keep-alive timeout
|
||||
struct timeval tv_now;
|
||||
struct timezone tz_now;
|
||||
gettimeofday(&tv_now, &tz_now);
|
||||
int64_t tdiff = ((tv_now.tv_sec
|
||||
- connectionSock->tv_start_waiting.tv_sec) * 1000000
|
||||
+ (tv_now.tv_usec
|
||||
- connectionSock->tv_start_waiting.tv_usec));
|
||||
if (tdiff < HTTPD_KEEPALIVE_TIMEOUT || tdiff < 0)
|
||||
shouldClose = false;
|
||||
}
|
||||
if (shouldClose) {
|
||||
log_level_printf(2, "FD: close con Timeout fd:%d\n", thisSocket);
|
||||
SL_CloseSocketBySlot(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Add Socket fd to FD_SET again (for select-handling)
|
||||
// Add start-time for waiting for connection re-use / keep-alive
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWebserver::addSocketToMasterSet(SOCKET fd)
|
||||
{
|
||||
int slot = SL_GetExistingSocket(fd); // get slot/index for fd
|
||||
if(slot<0)
|
||||
void CWebserver::addSocketToMasterSet(SOCKET fd) {
|
||||
int slot = SL_GetExistingSocket(fd); // get slot/index for fd
|
||||
if (slot < 0)
|
||||
return;
|
||||
log_level_printf(2,"FD: add to master fd:%d\n",fd);
|
||||
struct timeval tv_now;
|
||||
struct timezone tz_now;
|
||||
log_level_printf(2, "FD: add to master fd:%d\n", fd);
|
||||
struct timeval tv_now;
|
||||
struct timezone tz_now;
|
||||
gettimeofday(&tv_now, &tz_now);
|
||||
SocketList[slot]->tv_start_waiting = tv_now; // add keep-alive wait time
|
||||
FD_SET(fd, &master); // add fd to select-master-set
|
||||
SocketList[slot]->tv_start_waiting = tv_now; // add keep-alive wait time
|
||||
FD_SET(fd, &master); // add fd to select-master-set
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Close (FD_SET handled) Socket
|
||||
// Clear it from SocketList
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWebserver::SL_CloseSocketBySlot(int slot)
|
||||
{
|
||||
open_connections--; // count open connections
|
||||
if(SocketList[slot] == NULL)
|
||||
void CWebserver::SL_CloseSocketBySlot(int slot) {
|
||||
open_connections--; // count open connections
|
||||
if (SocketList[slot] == NULL)
|
||||
return;
|
||||
SocketList[slot]->handling = false; // no handling anymore
|
||||
SocketList[slot]->handling = false; // no handling anymore
|
||||
FD_CLR(SocketList[slot]->get_socket(), &master);// remove from master set
|
||||
SocketList[slot]->close(); // close the socket
|
||||
delete SocketList[slot]; // destroy ySocket
|
||||
SocketList[slot] = NULL; // free in list
|
||||
SocketList[slot]->close(); // close the socket
|
||||
delete SocketList[slot]; // destroy ySocket
|
||||
SocketList[slot] = NULL; // free in list
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@@ -381,38 +369,34 @@ void CWebserver::SL_CloseSocketBySlot(int slot)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Check if IP is allowed for keep-alive
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserver::CheckKeepAliveAllowedByIP(std::string client_ip)
|
||||
{
|
||||
pthread_mutex_lock( &mutex );
|
||||
bool CWebserver::CheckKeepAliveAllowedByIP(std::string client_ip) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
bool do_keep_alive = true;
|
||||
CStringVector::const_iterator it = conf_no_keep_alive_ips.begin();
|
||||
while(it != conf_no_keep_alive_ips.end())
|
||||
{
|
||||
if(trim(*it) == client_ip)
|
||||
while (it != conf_no_keep_alive_ips.end()) {
|
||||
if (trim(*it) == client_ip)
|
||||
do_keep_alive = false;
|
||||
it++;
|
||||
}
|
||||
pthread_mutex_unlock( &mutex );
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return do_keep_alive;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set Entry(number)to NULL in Threadlist
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWebserver::clear_Thread_List_Number(int number)
|
||||
{
|
||||
pthread_mutex_lock( &mutex );
|
||||
if(number <HTTPD_MAX_CONNECTIONS)
|
||||
Connection_Thread_List[number] = (pthread_t)NULL;
|
||||
void CWebserver::clear_Thread_List_Number(int number) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
if (number < HTTPD_MAX_CONNECTIONS)
|
||||
Connection_Thread_List[number] = (pthread_t) NULL;
|
||||
CloseConnectionSocketsByTimeout();
|
||||
pthread_mutex_unlock( &mutex );
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A new Connection is established to newSock. Create a (threaded) Connection
|
||||
// and handle the Request.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWebserver::handle_connection(CySocket *newSock)
|
||||
{
|
||||
bool CWebserver::handle_connection(CySocket *newSock) {
|
||||
void *WebThread(void *args); //forward declaration
|
||||
|
||||
// create arguments
|
||||
@@ -432,56 +416,56 @@ bool CWebserver::handle_connection(CySocket *newSock)
|
||||
pthread_mutex_lock( &mutex );
|
||||
// look for free Thread slot
|
||||
for(int i=0;i<HTTPD_MAX_CONNECTIONS;i++)
|
||||
if(Connection_Thread_List[i] == (pthread_t)NULL)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
if(Connection_Thread_List[i] == (pthread_t)NULL)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
if(index == -1)
|
||||
{
|
||||
dperror("Maximum Connection-Threads reached\n");
|
||||
pthread_mutex_unlock( &mutex );
|
||||
return false;
|
||||
}
|
||||
newConn->thread_number = index; //remember Index of Thread slot (for clean up)
|
||||
newConn->thread_number = index; //remember Index of Thread slot (for clean up)
|
||||
|
||||
// Create an orphan Thread. It is not joinable anymore
|
||||
pthread_mutex_unlock( &mutex );
|
||||
|
||||
// start connection Thread
|
||||
if(pthread_create(&Connection_Thread_List[index], &attr, WebThread, (void *)newConn) != 0)
|
||||
dperror("Could not create Connection-Thread\n");
|
||||
dperror("Could not create Connection-Thread\n");
|
||||
}
|
||||
else // non threaded
|
||||
else // non threaded
|
||||
#endif
|
||||
WebThread((void *)newConn);
|
||||
WebThread((void *) newConn);
|
||||
return ((index != -1) || !is_threading);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// Webserver-Thread for each connection
|
||||
//-------------------------------------------------------------------------
|
||||
void *WebThread(void *args)
|
||||
{
|
||||
void *WebThread(void *args) {
|
||||
CWebserverConnection *con;
|
||||
CWebserver *ws;
|
||||
TWebserverConnectionArgs *newConn = (TWebserverConnectionArgs *) args;
|
||||
ws = newConn->WebserverBackref;
|
||||
|
||||
bool is_threaded = newConn->is_treaded;
|
||||
if(is_threaded)
|
||||
log_level_printf(1,"++ Thread 0x06%X gestartet\n", (int) pthread_self());
|
||||
if (is_threaded)
|
||||
log_level_printf(1, "++ Thread 0x06%X gestartet\n",
|
||||
(int) pthread_self());
|
||||
|
||||
if (!newConn) {
|
||||
dperror("WebThread called without arguments!\n");
|
||||
if(newConn->is_treaded)
|
||||
pthread_exit(NULL);
|
||||
if (newConn->is_treaded)
|
||||
pthread_exit( NULL);
|
||||
}
|
||||
|
||||
// (1) create & init Connection
|
||||
con = new CWebserverConnection(ws);
|
||||
con->Request.UrlData["clientaddr"] = newConn->ySock->get_client_ip(); // TODO:here?
|
||||
con->sock = newConn->ySock; // give socket reference
|
||||
newConn->ySock->handling = true; // dont handle this socket now be webserver main loop
|
||||
con->sock = newConn->ySock; // give socket reference
|
||||
newConn->ySock->handling = true; // dont handle this socket now be webserver main loop
|
||||
|
||||
// (2) handle the connection
|
||||
con->HandleConnection();
|
||||
@@ -489,25 +473,24 @@ void *WebThread(void *args)
|
||||
// (3) end connection handling
|
||||
#ifdef Y_CONFIG_FEATURE_KEEP_ALIVE
|
||||
if(!con->keep_alive)
|
||||
log_level_printf(2,"FD SHOULD CLOSE sock:%d!!!\n",con->sock->get_socket());
|
||||
log_level_printf(2,"FD SHOULD CLOSE sock:%d!!!\n",con->sock->get_socket());
|
||||
else
|
||||
ws->addSocketToMasterSet(con->sock->get_socket()); // add to master set
|
||||
ws->addSocketToMasterSet(con->sock->get_socket()); // add to master set
|
||||
#else
|
||||
delete newConn->ySock;
|
||||
#endif
|
||||
if(!con->keep_alive)
|
||||
if (!con->keep_alive)
|
||||
con->sock->isValid = false;
|
||||
con->sock->handling = false; // socket can be handled by webserver main loop (select) again
|
||||
con->sock->handling = false; // socket can be handled by webserver main loop (select) again
|
||||
|
||||
// (4) end thread
|
||||
delete con;
|
||||
int thread_number = newConn->thread_number;
|
||||
delete newConn;
|
||||
if(is_threaded)
|
||||
{
|
||||
log_level_printf(1,"-- Thread 0x06%X beendet\n",(int)pthread_self());
|
||||
if (is_threaded) {
|
||||
log_level_printf(1, "-- Thread 0x06%X beendet\n", (int) pthread_self());
|
||||
ws->clear_Thread_List_Number(thread_number);
|
||||
pthread_exit(NULL);
|
||||
pthread_exit( NULL);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -11,18 +11,15 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// HOOK: response_hook
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmAuth::Hook_PrepareResponse(CyhookHandler *hh)
|
||||
{
|
||||
THandleStatus CmAuth::Hook_PrepareResponse(CyhookHandler *hh) {
|
||||
THandleStatus status = HANDLED_CONTINUE;
|
||||
|
||||
if(authenticate)
|
||||
{
|
||||
if( (hh->UrlData["clientaddr"]).find(IADDR_LOCAL)>0 &&
|
||||
(no_auth_client == "" ||
|
||||
(hh->UrlData["clientaddr"]).find(no_auth_client)>0)) // dont check local calls or calls from NoAuthClient
|
||||
if (authenticate) {
|
||||
if ((hh->UrlData["clientaddr"]).find(IADDR_LOCAL) > 0
|
||||
&& (no_auth_client == "" || (hh->UrlData["clientaddr"]).find(
|
||||
no_auth_client) > 0)) // dont check local calls or calls from NoAuthClient
|
||||
{
|
||||
if (!CheckAuth(hh))
|
||||
{
|
||||
if (!CheckAuth(hh)) {
|
||||
hh->SetError(HTTP_UNAUTHORIZED);
|
||||
status = HANDLED_ERROR;
|
||||
}
|
||||
@@ -35,62 +32,66 @@ THandleStatus CmAuth::Hook_PrepareResponse(CyhookHandler *hh)
|
||||
// HOOK: webserver_readconfig_hook Handler
|
||||
// This hook ist called from ReadConfig
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmAuth::Hook_ReadConfig(CConfigFile *Config, CStringList &ConfigList)
|
||||
{
|
||||
username = Config->getString("mod_auth.username", AUTHUSER);
|
||||
password = Config->getString("mod_auth.password", AUTHPASSWORD);
|
||||
no_auth_client = Config->getString("mod_auth.no_auth_client", "");
|
||||
authenticate = Config->getBool("mod_auth.authenticate", false);
|
||||
THandleStatus CmAuth::Hook_ReadConfig(CConfigFile *Config,
|
||||
CStringList &ConfigList) {
|
||||
username = Config->getString("mod_auth.username", AUTHUSER);
|
||||
password = Config->getString("mod_auth.password", AUTHPASSWORD);
|
||||
no_auth_client = Config->getString("mod_auth.no_auth_client", "");
|
||||
authenticate = Config->getBool("mod_auth.authenticate", false);
|
||||
ConfigList["mod_auth.username"] = username;
|
||||
ConfigList["mod_auth.password"] = password;
|
||||
ConfigList["mod_auth.no_auth_client"] = no_auth_client;
|
||||
ConfigList["mod_auth.authenticate"] = Config->getString("mod_auth.authenticate", "false");
|
||||
ConfigList["mod_auth.authenticate"] = Config->getString(
|
||||
"mod_auth.authenticate", "false");
|
||||
return HANDLED_CONTINUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// check if given username an pssword are valid
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CmAuth::CheckAuth(CyhookHandler *hh)
|
||||
{
|
||||
bool CmAuth::CheckAuth(CyhookHandler *hh) {
|
||||
if (hh->HeaderList["Authorization"] == "")
|
||||
return false;
|
||||
std::string encodet = hh->HeaderList["Authorization"].substr(6,hh->HeaderList["Authorization"].length() - 6);
|
||||
std::string encodet = hh->HeaderList["Authorization"].substr(6,
|
||||
hh->HeaderList["Authorization"].length() - 6);
|
||||
std::string decodet = decodeBase64(encodet.c_str());
|
||||
int pos = decodet.find_first_of(':');
|
||||
std::string user = decodet.substr(0,pos);
|
||||
std::string user = decodet.substr(0, pos);
|
||||
std::string passwd = decodet.substr(pos + 1, decodet.length() - pos - 1);
|
||||
return (user.compare(username) == 0 &&
|
||||
passwd.compare(password) == 0);
|
||||
}
|
||||
return (user.compare(username) == 0 && passwd.compare(password) == 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// decode Base64 buffer to String
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CmAuth::decodeBase64(const char *b64buffer)
|
||||
{
|
||||
std::string CmAuth::decodeBase64(const char *b64buffer) {
|
||||
char *newString, *org_newString; //shorter then b64buffer
|
||||
std::string result;
|
||||
if((newString = (char *)malloc(sizeof(char) * strlen(b64buffer) + 1) ) != NULL)
|
||||
{
|
||||
if ((newString = (char *) malloc(sizeof(char) * strlen(b64buffer) + 1))
|
||||
!= NULL) {
|
||||
org_newString = newString;
|
||||
int i = 0;
|
||||
unsigned long c = 0;
|
||||
|
||||
while (*b64buffer)
|
||||
{
|
||||
|
||||
while (*b64buffer) {
|
||||
int oneChar = *b64buffer++;
|
||||
if(oneChar >= '0' && oneChar <= '9') oneChar = oneChar - '0' + 52;
|
||||
else if(oneChar >= 'A' && oneChar <= 'Z') oneChar = oneChar - 'A';
|
||||
else if(oneChar >= 'a' && oneChar <= 'z') oneChar = oneChar - 'a' + 26;
|
||||
else if(oneChar == '+') oneChar = 62;
|
||||
else if(oneChar == '/') oneChar = 63;
|
||||
else if(oneChar == '=') oneChar = 0;
|
||||
else continue;
|
||||
if (oneChar >= '0' && oneChar <= '9')
|
||||
oneChar = oneChar - '0' + 52;
|
||||
else if (oneChar >= 'A' && oneChar <= 'Z')
|
||||
oneChar = oneChar - 'A';
|
||||
else if (oneChar >= 'a' && oneChar <= 'z')
|
||||
oneChar = oneChar - 'a' + 26;
|
||||
else if (oneChar == '+')
|
||||
oneChar = 62;
|
||||
else if (oneChar == '/')
|
||||
oneChar = 63;
|
||||
else if (oneChar == '=')
|
||||
oneChar = 0;
|
||||
else
|
||||
continue;
|
||||
|
||||
c = (c << 6) | oneChar;
|
||||
if (++i == 4)
|
||||
{
|
||||
if (++i == 4) {
|
||||
*newString++ = (char) (c >> 16);
|
||||
*newString++ = (char) (c >> 8);
|
||||
*newString++ = (char) c;
|
||||
@@ -101,8 +102,7 @@ std::string CmAuth::decodeBase64(const char *b64buffer)
|
||||
result = std::string(org_newString);
|
||||
free(org_newString);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@@ -5,20 +5,27 @@
|
||||
#ifndef __yhttpd_mod_auth_h__
|
||||
#define __yhttpd_mod_auth_h__
|
||||
|
||||
|
||||
#include "yhook.h"
|
||||
class CmAuth : public Cyhook
|
||||
{
|
||||
class CmAuth: public Cyhook {
|
||||
public:
|
||||
bool authenticate;
|
||||
CmAuth(){};
|
||||
~CmAuth(){};
|
||||
bool authenticate;
|
||||
CmAuth() {
|
||||
}
|
||||
;
|
||||
~CmAuth() {
|
||||
}
|
||||
;
|
||||
|
||||
// Hooks
|
||||
virtual THandleStatus Hook_PrepareResponse(CyhookHandler *hh);
|
||||
virtual std::string getHookName(void) {return std::string("mod_auth");}
|
||||
virtual std::string getHookVersion(void) {return std::string("$Revision: 1.3 $");}
|
||||
virtual THandleStatus Hook_ReadConfig(CConfigFile *Config, CStringList &ConfigList);
|
||||
virtual THandleStatus Hook_PrepareResponse(CyhookHandler *hh);
|
||||
virtual std::string getHookName(void) {
|
||||
return std::string("mod_auth");
|
||||
}
|
||||
virtual std::string getHookVersion(void) {
|
||||
return std::string("$Revision: 1.3 $");
|
||||
}
|
||||
virtual THandleStatus Hook_ReadConfig(CConfigFile *Config,
|
||||
CStringList &ConfigList);
|
||||
protected:
|
||||
bool CheckAuth(CyhookHandler *hh);
|
||||
std::string decodeBase64(const char *b64buffer);
|
||||
@@ -27,4 +34,3 @@ protected:
|
||||
std::string no_auth_client;
|
||||
};
|
||||
#endif // __yhttpd_mod_auth_h__
|
||||
|
||||
|
@@ -16,55 +16,52 @@
|
||||
// Initialization of static variables
|
||||
//=============================================================================
|
||||
pthread_mutex_t CmodCache::mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
TCacheList CmodCache::CacheList;
|
||||
|
||||
//=============================================================================
|
||||
// Constructor & Destructor & Initialization
|
||||
//=============================================================================
|
||||
TCacheList CmodCache::CacheList;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HOOK: Response Prepare Handler
|
||||
// Response Prepare Check.
|
||||
// Is it in cache?
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmodCache::Hook_PrepareResponse(CyhookHandler *hh)
|
||||
{
|
||||
THandleStatus CmodCache::Hook_PrepareResponse(CyhookHandler *hh) {
|
||||
hh->status = HANDLED_NONE;
|
||||
|
||||
log_level_printf(4,"mod_cache prepare hook start url:%s\n",hh->UrlData["fullurl"].c_str());
|
||||
log_level_printf(4, "mod_cache prepare hook start url:%s\n",
|
||||
hh->UrlData["fullurl"].c_str());
|
||||
std::string url = hh->UrlData["fullurl"];
|
||||
if(CacheList.find(url) != CacheList.end()) // is in Cache. Rewrite URL or not modified
|
||||
if (CacheList.find(url) != CacheList.end()) // is in Cache. Rewrite URL or not modified
|
||||
{
|
||||
pthread_mutex_lock(&mutex); // yeah, its mine
|
||||
|
||||
// Check if modified
|
||||
time_t if_modified_since = (time_t)-1;
|
||||
if(hh->HeaderList["If-Modified-Since"] != "") // Have If-Modified-Since Requested by Browser?
|
||||
time_t if_modified_since = (time_t) - 1;
|
||||
if (hh->HeaderList["If-Modified-Since"] != "") // Have If-Modified-Since Requested by Browser?
|
||||
{
|
||||
struct tm mod;
|
||||
if(strptime(hh->HeaderList["If-Modified-Since"].c_str(), RFC1123FMT, &mod) != NULL)
|
||||
{
|
||||
if (strptime(hh->HeaderList["If-Modified-Since"].c_str(),
|
||||
RFC1123FMT, &mod) != NULL) {
|
||||
mod.tm_isdst = 0; // daylight saving flag!
|
||||
if_modified_since = mktime(&mod); // Date given
|
||||
if_modified_since = mktime(&mod); // Date given
|
||||
}
|
||||
}
|
||||
|
||||
// normalize obj_last_modified to GMT
|
||||
struct tm *tmp = gmtime(&(CacheList[url].created));
|
||||
time_t obj_last_modified_gmt = mktime(tmp);
|
||||
bool modified = (if_modified_since == (time_t)-1) || (if_modified_since < obj_last_modified_gmt);
|
||||
bool modified = (if_modified_since == (time_t) - 1)
|
||||
|| (if_modified_since < obj_last_modified_gmt);
|
||||
|
||||
// Send file or not-modified header
|
||||
if(modified)
|
||||
{
|
||||
if (modified) {
|
||||
hh->SendFile(CacheList[url].filename);
|
||||
hh->ResponseMimeType = CacheList[url].mime_type;
|
||||
}
|
||||
else
|
||||
hh->SetHeader(HTTP_NOT_MODIFIED, CacheList[url].mime_type, HANDLED_READY);
|
||||
} else
|
||||
hh->SetHeader(HTTP_NOT_MODIFIED, CacheList[url].mime_type,
|
||||
HANDLED_READY);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
log_level_printf(4,"mod_cache hook prepare end status:%d\n",(int)hh->status);
|
||||
log_level_printf(4, "mod_cache hook prepare end status:%d\n",
|
||||
(int) hh->status);
|
||||
|
||||
return hh->status;
|
||||
}
|
||||
@@ -74,31 +71,30 @@ THandleStatus CmodCache::Hook_PrepareResponse(CyhookHandler *hh)
|
||||
// in hh->yresult should be cached into a file.
|
||||
// Remeber: url, filename, mimetype, category, createdate
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmodCache::Hook_SendResponse(CyhookHandler *hh)
|
||||
{
|
||||
THandleStatus CmodCache::Hook_SendResponse(CyhookHandler *hh) {
|
||||
hh->status = HANDLED_NONE;
|
||||
std::string url = hh->UrlData["fullurl"];
|
||||
log_level_printf(4,"mod_cache hook start url:%s\n",url.c_str());
|
||||
log_level_printf(4, "mod_cache hook start url:%s\n", url.c_str());
|
||||
|
||||
std::string category = hh->HookVarList["CacheCategory"];
|
||||
if(!(hh->HookVarList["CacheCategory"]).empty()) // Category set = cache it
|
||||
if (!(hh->HookVarList["CacheCategory"]).empty()) // Category set = cache it
|
||||
{
|
||||
AddToCache(hh, url, hh->yresult, hh->HookVarList["CacheMimeType"], category); // create cache file and add to cache list
|
||||
AddToCache(hh, url, hh->yresult, hh->HookVarList["CacheMimeType"],
|
||||
category); // create cache file and add to cache list
|
||||
hh->ContentLength = (hh->yresult).length();
|
||||
hh->SendFile(CacheList[url].filename); // Send as file
|
||||
hh->ResponseMimeType = CacheList[url].mime_type; // remember mime
|
||||
}
|
||||
else if(hh->UrlData["path"] == "/y/") // /y/ commands
|
||||
hh->SendFile(CacheList[url].filename); // Send as file
|
||||
hh->ResponseMimeType = CacheList[url].mime_type; // remember mime
|
||||
} else if (hh->UrlData["path"] == "/y/") // /y/ commands
|
||||
{
|
||||
hh->status = HANDLED_READY;
|
||||
if(hh->UrlData["filename"] == "cache-info")
|
||||
if (hh->UrlData["filename"] == "cache-info")
|
||||
yshowCacheInfo(hh);
|
||||
else if(hh->UrlData["filename"] == "cache-clear")
|
||||
else if (hh->UrlData["filename"] == "cache-clear")
|
||||
yCacheClear(hh);
|
||||
else
|
||||
hh->status = HANDLED_CONTINUE; // y-calls can be implemented anywhere
|
||||
hh->status = HANDLED_CONTINUE; // y-calls can be implemented anywhere
|
||||
}
|
||||
log_level_printf(4,"mod_cache hook end status:%d\n",(int)hh->status);
|
||||
log_level_printf(4, "mod_cache hook end status:%d\n", (int) hh->status);
|
||||
|
||||
return hh->status;
|
||||
}
|
||||
@@ -107,9 +103,9 @@ THandleStatus CmodCache::Hook_SendResponse(CyhookHandler *hh)
|
||||
// HOOK: Hook_ReadConfig
|
||||
// This hook ist called from ReadConfig
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmodCache::Hook_ReadConfig(CConfigFile *Config, CStringList &ConfigList)
|
||||
{
|
||||
cache_directory= Config->getString("mod_cache.cache_directory", CACHE_DIR);
|
||||
THandleStatus CmodCache::Hook_ReadConfig(CConfigFile *Config,
|
||||
CStringList &ConfigList) {
|
||||
cache_directory = Config->getString("mod_cache.cache_directory", CACHE_DIR);
|
||||
ConfigList["mod_cache.cache_directory"] = cache_directory;
|
||||
return HANDLED_CONTINUE;
|
||||
}
|
||||
@@ -117,135 +113,124 @@ THandleStatus CmodCache::Hook_ReadConfig(CConfigFile *Config, CStringList &Confi
|
||||
//-------------------------------------------------------------------------
|
||||
// Build and Add a cache item
|
||||
//-------------------------------------------------------------------------
|
||||
void CmodCache::AddToCache(CyhookHandler *, std::string url, std::string content, std::string mime_type, std::string category)
|
||||
{
|
||||
void CmodCache::AddToCache(CyhookHandler *, std::string url,
|
||||
std::string content, std::string mime_type, std::string category) {
|
||||
FILE *fd = NULL;
|
||||
pthread_mutex_lock(&mutex);
|
||||
std::string filename = cache_directory + "/" + itoa(CacheList.size()); // build cache filename
|
||||
mkdir(cache_directory.c_str(), 0777); // Create Cache directory
|
||||
if((fd = fopen(filename.c_str(),"w")) != NULL) // open file
|
||||
std::string filename = cache_directory + "/" + itoa(CacheList.size()); // build cache filename
|
||||
mkdir(cache_directory.c_str(), 0777); // Create Cache directory
|
||||
if ((fd = fopen(filename.c_str(), "w")) != NULL) // open file
|
||||
{
|
||||
if(fwrite(content.c_str(), content.length(), 1, fd) == 1) // write cache file
|
||||
if (fwrite(content.c_str(), content.length(), 1, fd) == 1) // write cache file
|
||||
{
|
||||
CacheList[url].filename = filename; // add cache data item
|
||||
CacheList[url].filename = filename; // add cache data item
|
||||
CacheList[url].mime_type = mime_type;
|
||||
CacheList[url].category = category;
|
||||
CacheList[url].created = time(NULL);
|
||||
std::string test = CacheList[url].filename;
|
||||
}
|
||||
fflush(fd); // flush and close file
|
||||
fflush(fd); // flush and close file
|
||||
fclose(fd);
|
||||
}
|
||||
pthread_mutex_unlock(&mutex); // Free
|
||||
pthread_mutex_unlock(&mutex); // Free
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// Delete URL from cachelist
|
||||
//-------------------------------------------------------------------------
|
||||
void CmodCache::RemoveURLFromCache(std::string url)
|
||||
{
|
||||
pthread_mutex_lock(&mutex); // yeah, its mine
|
||||
if(CacheList.find(url) != CacheList.end())
|
||||
{
|
||||
remove((CacheList[url].filename).c_str()); // delete file
|
||||
CacheList.erase(url); // remove from list
|
||||
void CmodCache::RemoveURLFromCache(std::string url) {
|
||||
pthread_mutex_lock(&mutex); // yeah, its mine
|
||||
if (CacheList.find(url) != CacheList.end()) {
|
||||
remove((CacheList[url].filename).c_str()); // delete file
|
||||
CacheList.erase(url); // remove from list
|
||||
}
|
||||
pthread_mutex_unlock(&mutex); // Free
|
||||
pthread_mutex_unlock(&mutex); // Free
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
void CmodCache::RemoveCategoryFromCache(std::string category)
|
||||
{
|
||||
void CmodCache::RemoveCategoryFromCache(std::string category) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
bool restart = false;
|
||||
do
|
||||
{
|
||||
do {
|
||||
restart = false;
|
||||
TCacheList::iterator i = CacheList.begin();
|
||||
for ( ; i!= CacheList.end(); i++ )
|
||||
{
|
||||
for (; i != CacheList.end(); i++) {
|
||||
TCache *item = &((*i).second);
|
||||
if(item->category == category)
|
||||
{
|
||||
CacheList.erase( ((*i).first) );
|
||||
if (item->category == category) {
|
||||
CacheList.erase(((*i).first));
|
||||
restart = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(restart);
|
||||
} while (restart);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void CmodCache::DeleteCache(void)
|
||||
{
|
||||
pthread_mutex_lock(&mutex); // yeah, its mine
|
||||
CacheList.clear(); // Clear entire list
|
||||
pthread_mutex_unlock(&mutex); // Free
|
||||
void CmodCache::DeleteCache(void) {
|
||||
pthread_mutex_lock(&mutex); // yeah, its mine
|
||||
CacheList.clear(); // Clear entire list
|
||||
pthread_mutex_unlock(&mutex); // Free
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// y-Call : show cache Information
|
||||
//-------------------------------------------------------------------------
|
||||
void CmodCache::yshowCacheInfo(CyhookHandler *hh)
|
||||
{
|
||||
void CmodCache::yshowCacheInfo(CyhookHandler *hh) {
|
||||
std::string yresult;
|
||||
|
||||
hh->SendHTMLHeader("Cache Information");
|
||||
yresult += string_printf("<b>Cache Information</b><br/>\n<code>\n");
|
||||
yresult += string_printf("Cache Module...: %s<br/>\n",(getHookName()).c_str() );
|
||||
yresult += string_printf("Cache Version..: %s<br/>\n",(getHookVersion()).c_str() );
|
||||
yresult += string_printf("Cache Directory: %s<br/>\n",cache_directory.c_str() );
|
||||
yresult += string_printf("Cache Module...: %s<br/>\n",
|
||||
(getHookName()).c_str());
|
||||
yresult += string_printf("Cache Version..: %s<br/>\n",
|
||||
(getHookVersion()).c_str());
|
||||
yresult += string_printf("Cache Directory: %s<br/>\n",
|
||||
cache_directory.c_str());
|
||||
yresult += string_printf("</code>\n<br/><b>CACHE</b><br/>\n");
|
||||
|
||||
// cache list
|
||||
yresult += string_printf("<table border=\"1\">\n");
|
||||
yresult += string_printf("<tr><td>URL</td><td>Mime</td><td>Filename</td><td>Category</td><td>Created</td><td>Remove</td></tr>\n");
|
||||
yresult
|
||||
+= string_printf(
|
||||
"<tr><td>URL</td><td>Mime</td><td>Filename</td><td>Category</td><td>Created</td><td>Remove</td></tr>\n");
|
||||
pthread_mutex_lock(&mutex);
|
||||
TCacheList::iterator i = CacheList.begin();
|
||||
for ( ; i!= CacheList.end(); i++ )
|
||||
{
|
||||
for (; i != CacheList.end(); i++) {
|
||||
TCache *item = &((*i).second);
|
||||
char timeStr[80];
|
||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&(item->created)) );
|
||||
yresult += string_printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>" \
|
||||
"<td><a href=\"/y/cache-clear?url=%s\">url</a> " \
|
||||
"<a href=\"/y/cache-clear?category=%s\">category</a></td></tr>\n",
|
||||
((*i).first).c_str(),
|
||||
item->mime_type.c_str(),
|
||||
item->filename.c_str(),
|
||||
item->category.c_str(),
|
||||
timeStr,
|
||||
((*i).first).c_str(),
|
||||
item->category.c_str()
|
||||
);
|
||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&(item->created)));
|
||||
yresult
|
||||
+= string_printf(
|
||||
"<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>"
|
||||
"<td><a href=\"/y/cache-clear?url=%s\">url</a> "
|
||||
"<a href=\"/y/cache-clear?category=%s\">category</a></td></tr>\n",
|
||||
((*i).first).c_str(), item->mime_type.c_str(),
|
||||
item->filename.c_str(), item->category.c_str(),
|
||||
timeStr, ((*i).first).c_str(), item->category.c_str());
|
||||
}
|
||||
pthread_mutex_unlock(&mutex); // Free
|
||||
pthread_mutex_unlock(&mutex); // Free
|
||||
yresult += string_printf("</table>\n");
|
||||
yresult += string_printf("<a href=\"/y/cache-clear\">Delete Cache</a><br/>\n");
|
||||
yresult += string_printf(
|
||||
"<a href=\"/y/cache-clear\">Delete Cache</a><br/>\n");
|
||||
hh->addResult(yresult, HANDLED_READY);
|
||||
hh->SendHTMLFooter();
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// y-Call : clear cache
|
||||
//-------------------------------------------------------------------------
|
||||
void CmodCache::yCacheClear(CyhookHandler *hh)
|
||||
{
|
||||
std::string result="";
|
||||
if(hh->ParamList["category"] != "")
|
||||
{
|
||||
void CmodCache::yCacheClear(CyhookHandler *hh) {
|
||||
std::string result = "";
|
||||
if (hh->ParamList["category"] != "") {
|
||||
RemoveCategoryFromCache(hh->ParamList["category"]);
|
||||
result = string_printf("Category (%s) removed from cache.</br>", hh->ParamList["category"].c_str());
|
||||
}
|
||||
else if(hh->ParamList["url"] != "")
|
||||
{
|
||||
result = string_printf("Category (%s) removed from cache.</br>",
|
||||
hh->ParamList["category"].c_str());
|
||||
} else if (hh->ParamList["url"] != "") {
|
||||
RemoveURLFromCache(hh->ParamList["url"]);
|
||||
result = string_printf("URL (%s) removed from cache.</br>", hh->ParamList["url"].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
result = string_printf("URL (%s) removed from cache.</br>",
|
||||
hh->ParamList["url"].c_str());
|
||||
} else {
|
||||
DeleteCache();
|
||||
result = string_printf("Cache deleted.</br>");
|
||||
}
|
||||
|
@@ -16,41 +16,44 @@
|
||||
#include "yhook.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct
|
||||
{
|
||||
std::string filename;
|
||||
std::string mime_type;
|
||||
std::string category;
|
||||
time_t created;
|
||||
typedef struct {
|
||||
std::string filename;
|
||||
std::string mime_type;
|
||||
std::string category;
|
||||
time_t created;
|
||||
} TCache;
|
||||
|
||||
typedef std::map<std::string, TCache> TCacheList;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class CmodCache : public Cyhook
|
||||
{
|
||||
class CmodCache: public Cyhook {
|
||||
private:
|
||||
static TCacheList CacheList;
|
||||
std::string cache_directory;
|
||||
void yshowCacheInfo(CyhookHandler *hh);
|
||||
void yCacheClear(CyhookHandler *hh);
|
||||
static TCacheList CacheList;
|
||||
std::string cache_directory;
|
||||
void yshowCacheInfo(CyhookHandler *hh);
|
||||
void yCacheClear(CyhookHandler *hh);
|
||||
public:
|
||||
static pthread_mutex_t mutex;
|
||||
static pthread_mutex_t mutex;
|
||||
|
||||
CmodCache(){};
|
||||
~CmodCache(void){};
|
||||
CmodCache() {
|
||||
}
|
||||
;
|
||||
~CmodCache(void) {
|
||||
}
|
||||
;
|
||||
|
||||
void AddToCache(CyhookHandler *hh, std::string url, std::string content, std::string mime_type, std::string cartegory="none");
|
||||
static void RemoveURLFromCache(std::string url);
|
||||
static void RemoveCategoryFromCache(std::string category);
|
||||
static void DeleteCache(void);
|
||||
void AddToCache(CyhookHandler *hh, std::string url, std::string content,
|
||||
std::string mime_type, std::string cartegory = "none");
|
||||
static void RemoveURLFromCache(std::string url);
|
||||
static void RemoveCategoryFromCache(std::string category);
|
||||
static void DeleteCache(void);
|
||||
|
||||
// Hooks
|
||||
virtual THandleStatus Hook_PrepareResponse(CyhookHandler *hh);
|
||||
virtual THandleStatus Hook_SendResponse(CyhookHandler *hh);
|
||||
virtual std::string getHookVersion(void) {return std::string("$Revision: 1.2 $");}
|
||||
virtual std::string getHookName(void) {return std::string("mod_cache");}
|
||||
virtual THandleStatus Hook_ReadConfig(CConfigFile *Config, CStringList &ConfigList);
|
||||
virtual THandleStatus Hook_ReadConfig(CConfigFile *Config,CStringList &ConfigList);
|
||||
};
|
||||
|
||||
#endif /* __yhttpd_mod_cache_h__ */
|
||||
|
@@ -8,36 +8,36 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// RFC 2616 / 14.25 If-Modified-Since
|
||||
//
|
||||
// The If-Modified-Since request-header field is used with a method to
|
||||
// make it conditional: if the requested variant has not been modified
|
||||
// since the time specified in this field, an entity will not be
|
||||
// returned from the server; instead, a 304 (not modified) response will
|
||||
// be returned without any message-body.
|
||||
// The If-Modified-Since request-header field is used with a method to
|
||||
// make it conditional: if the requested variant has not been modified
|
||||
// since the time specified in this field, an entity will not be
|
||||
// returned from the server; instead, a 304 (not modified) response will
|
||||
// be returned without any message-body.
|
||||
//
|
||||
// If-Modified-Since = "If-Modified-Since" ":" HTTP-date
|
||||
// An example of the field is:
|
||||
// If-Modified-Since = "If-Modified-Since" ":" HTTP-date
|
||||
// An example of the field is:
|
||||
//
|
||||
// If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
|
||||
// If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
|
||||
//
|
||||
// A GET method with an If-Modified-Since header and no Range header
|
||||
// requests that the identified entity be transferred only if it has
|
||||
// been modified since the date given by the If-Modified-Since header.
|
||||
// The algorithm for determining this includes the following cases:
|
||||
// A GET method with an If-Modified-Since header and no Range header
|
||||
// requests that the identified entity be transferred only if it has
|
||||
// been modified since the date given by the If-Modified-Since header.
|
||||
// The algorithm for determining this includes the following cases:
|
||||
//
|
||||
// a) If the request would normally result in anything other than a
|
||||
// 200 (OK) status, or if the passed If-Modified-Since date is
|
||||
// invalid, the response is exactly the same as for a normal GET.
|
||||
// A date which is later than the server's current time is
|
||||
// invalid.
|
||||
// a) If the request would normally result in anything other than a
|
||||
// 200 (OK) status, or if the passed If-Modified-Since date is
|
||||
// invalid, the response is exactly the same as for a normal GET.
|
||||
// A date which is later than the server's current time is
|
||||
// invalid.
|
||||
//
|
||||
// b) If the variant has been modified since the If-Modified-Since
|
||||
// date, the response is exactly the same as for a normal GET.
|
||||
// b) If the variant has been modified since the If-Modified-Since
|
||||
// date, the response is exactly the same as for a normal GET.
|
||||
//
|
||||
// c) If the variant has not been modified since a valid If-
|
||||
// Modified-Since date, the server SHOULD return a 304 (Not
|
||||
// Modified) response.
|
||||
// c) If the variant has not been modified since a valid If-
|
||||
// Modified-Since date, the server SHOULD return a 304 (Not
|
||||
// Modified) response.
|
||||
//
|
||||
// yjogol: ASSUMPTION Date-Format is ONLY RFC 1123 compatible!
|
||||
// yjogol: ASSUMPTION Date-Format is ONLY RFC 1123 compatible!
|
||||
//=============================================================================
|
||||
|
||||
// system
|
||||
@@ -56,35 +56,30 @@
|
||||
//=============================================================================
|
||||
CStringList CmodSendfile::sendfileTypes;
|
||||
|
||||
//=============================================================================
|
||||
// Constructor & Destructor & Initialization
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HOOK: Response Prepare Handler
|
||||
// Response Prepare Check.
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmodSendfile::Hook_PrepareResponse(CyhookHandler *hh)
|
||||
{
|
||||
THandleStatus CmodSendfile::Hook_PrepareResponse(CyhookHandler *hh) {
|
||||
hh->status = HANDLED_NONE;
|
||||
|
||||
int filed;
|
||||
log_level_printf(4,"mod_sendfile prepare hook start url:%s\n",hh->UrlData["fullurl"].c_str());
|
||||
log_level_printf(4, "mod_sendfile prepare hook start url:%s\n", hh->UrlData["fullurl"].c_str());
|
||||
std::string mime = sendfileTypes[hh->UrlData["fileext"]];
|
||||
if(((mime != "") || (hh->WebserverConfigList["mod_sendfile.sendAll"] == "true")) && (hh->UrlData["fileext"] != "yhtm"))
|
||||
{
|
||||
if (((mime != "") || (hh->WebserverConfigList["mod_sendfile.sendAll"] == "true"))
|
||||
&& (hh->UrlData["fileext"] != "yhtm")) {
|
||||
//TODO: Check allowed directories / actually in GetFileName
|
||||
// build filename
|
||||
std::string fullfilename = GetFileName(hh, hh->UrlData["path"], hh->UrlData["filename"]);
|
||||
std::string fullfilename = GetFileName(hh, hh->UrlData["path"],
|
||||
hh->UrlData["filename"]);
|
||||
|
||||
if( (filed = OpenFile(hh, fullfilename) ) != -1 ) //can access file?
|
||||
if ((filed = OpenFile(hh, fullfilename)) != -1) //can access file?
|
||||
{
|
||||
struct stat statbuf;
|
||||
hh->LastModified = (time_t)0;
|
||||
hh->LastModified = (time_t) 0;
|
||||
// It is a regular file?
|
||||
fstat(filed,&statbuf);
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
{
|
||||
fstat(filed, &statbuf);
|
||||
if (S_ISREG(statbuf.st_mode)) {
|
||||
// get file size and modify date
|
||||
hh->ContentLength = statbuf.st_size;
|
||||
hh->LastModified = statbuf.st_mtime;
|
||||
@@ -92,12 +87,11 @@ THandleStatus CmodSendfile::Hook_PrepareResponse(CyhookHandler *hh)
|
||||
close(filed);
|
||||
|
||||
// check If-Modified-Since
|
||||
time_t if_modified_since = (time_t)-1;
|
||||
if(hh->HeaderList["If-Modified-Since"] != "")
|
||||
{
|
||||
time_t if_modified_since = (time_t) - 1;
|
||||
if (hh->HeaderList["If-Modified-Since"] != "") {
|
||||
struct tm mod;
|
||||
if(strptime(hh->HeaderList["If-Modified-Since"].c_str(), RFC1123FMT, &mod) != NULL)
|
||||
{
|
||||
if (strptime(hh->HeaderList["If-Modified-Since"].c_str(),
|
||||
RFC1123FMT, &mod) != NULL) {
|
||||
mod.tm_isdst = 0; // daylight saving flag!
|
||||
if_modified_since = mktime(&mod);
|
||||
}
|
||||
@@ -106,24 +100,23 @@ THandleStatus CmodSendfile::Hook_PrepareResponse(CyhookHandler *hh)
|
||||
// normalize obj_last_modified to GMT
|
||||
struct tm *tmp = gmtime(&(hh->LastModified));
|
||||
time_t LastModifiedGMT = mktime(tmp);
|
||||
bool modified = (if_modified_since == (time_t)-1) || (if_modified_since < LastModifiedGMT);
|
||||
bool modified = (if_modified_since == (time_t) - 1)
|
||||
|| (if_modified_since < LastModifiedGMT);
|
||||
|
||||
// Send normal or not-modified header
|
||||
if(modified)
|
||||
{
|
||||
if (modified) {
|
||||
hh->SendFile(fullfilename);
|
||||
hh->ResponseMimeType = mime;
|
||||
}
|
||||
else
|
||||
} else
|
||||
hh->SetHeader(HTTP_NOT_MODIFIED, mime, HANDLED_READY);
|
||||
}
|
||||
else
|
||||
{
|
||||
aprintf("mod_sendfile: File not found. url:(%s)\n", hh->UrlData["url"].c_str());
|
||||
} else {
|
||||
aprintf("mod_sendfile: File not found. url:(%s) fullfilename:(%s)\n",
|
||||
hh->UrlData["url"].c_str(), fullfilename.c_str());
|
||||
hh->SetError(HTTP_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
log_level_printf(4,"mod_sendfile prepare hook end status:%d\n",(int)hh->status);
|
||||
log_level_printf(4, "mod_sendfile prepare hook end status:%d\n",
|
||||
(int) hh->status);
|
||||
|
||||
return hh->status;
|
||||
}
|
||||
@@ -132,21 +125,21 @@ THandleStatus CmodSendfile::Hook_PrepareResponse(CyhookHandler *hh)
|
||||
// HOOK: Hook_ReadConfig
|
||||
// This hook ist called from ReadConfig
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmodSendfile::Hook_ReadConfig(CConfigFile *Config, CStringList &ConfigList)
|
||||
{
|
||||
std::string exttypes = Config->getString("mod_sendfile.mime_types", HTTPD_SENDFILE_EXT);
|
||||
THandleStatus CmodSendfile::Hook_ReadConfig(CConfigFile *Config,
|
||||
CStringList &ConfigList) {
|
||||
std::string exttypes = Config->getString("mod_sendfile.mime_types",
|
||||
HTTPD_SENDFILE_EXT);
|
||||
ConfigList["mod_sendfile.mime_types"] = exttypes;
|
||||
ConfigList["mod_sendfile.sendAll"] = Config->getString("mod_sendfile.sendAll", HTTPD_SENDFILE_ALL);
|
||||
ConfigList["mod_sendfile.sendAll"] = Config->getString(
|
||||
"mod_sendfile.sendAll", HTTPD_SENDFILE_ALL);
|
||||
|
||||
bool ende = false;
|
||||
std::string item, ext, mime;
|
||||
sendfileTypes.clear();
|
||||
while(!ende)
|
||||
{
|
||||
if(!ySplitStringExact(exttypes,",",item,exttypes))
|
||||
while (!ende) {
|
||||
if (!ySplitStringExact(exttypes, ",", item, exttypes))
|
||||
ende = true;
|
||||
if(ySplitStringExact(item,":",ext,mime))
|
||||
{
|
||||
if (ySplitStringExact(item, ":", ext, mime)) {
|
||||
ext = trim(ext);
|
||||
sendfileTypes[ext] = trim(mime);
|
||||
}
|
||||
@@ -158,28 +151,25 @@ THandleStatus CmodSendfile::Hook_ReadConfig(CConfigFile *Config, CStringList &Co
|
||||
// Send File: Build Filename
|
||||
// First Look at PublicDocumentRoot than PrivateDocumentRoot than pure path
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CmodSendfile::GetFileName(CyhookHandler *hh, std::string path, std::string filename)
|
||||
{
|
||||
std::string CmodSendfile::GetFileName(CyhookHandler *hh, std::string path, std::string filename) {
|
||||
std::string tmpfilename;
|
||||
if(path[path.length()-1] != '/')
|
||||
if (path[path.length() - 1] != '/')
|
||||
tmpfilename = path + "/" + filename;
|
||||
else
|
||||
tmpfilename = path + filename;
|
||||
|
||||
if( access(std::string(hh->WebserverConfigList["PublicDocumentRoot"] + tmpfilename).c_str(),4) == 0)
|
||||
tmpfilename = hh->WebserverConfigList["PublicDocumentRoot"] + tmpfilename;
|
||||
else if( access(std::string(hh->WebserverConfigList["PublicDocumentRoot"] + tmpfilename + ".gz").c_str(),4) == 0)
|
||||
tmpfilename = hh->WebserverConfigList["PublicDocumentRoot"] + tmpfilename + ".gz";
|
||||
else if(access(std::string(hh->WebserverConfigList["PrivatDocumentRoot"] + tmpfilename).c_str(),4) == 0)
|
||||
tmpfilename = hh->WebserverConfigList["PrivatDocumentRoot"] + tmpfilename;
|
||||
else if(access(std::string(hh->WebserverConfigList["PrivatDocumentRoot"] + tmpfilename + ".gz").c_str(),4) == 0)
|
||||
tmpfilename = hh->WebserverConfigList["PrivatDocumentRoot"] + tmpfilename + ".gz";
|
||||
if (access(std::string(hh->WebserverConfigList["WebsiteMain.override_directory"] + tmpfilename).c_str(), 4) == 0)
|
||||
tmpfilename = hh->WebserverConfigList["WebsiteMain.override_directory"] + tmpfilename;
|
||||
else if (access(std::string(hh->WebserverConfigList["WebsiteMain.override_directory"] + tmpfilename + ".gz").c_str(), 4) == 0)
|
||||
tmpfilename = hh->WebserverConfigList["WebsiteMain.override_directory"] + tmpfilename + ".gz";
|
||||
else if (access(std::string(hh->WebserverConfigList["WebsiteMain.directory"] + tmpfilename).c_str(), 4) == 0)
|
||||
tmpfilename = hh->WebserverConfigList["WebsiteMain.directory"] + tmpfilename;
|
||||
else if (access(std::string(hh->WebserverConfigList["WebsiteMain.directory"] + tmpfilename + ".gz").c_str(), 4) == 0)
|
||||
tmpfilename = hh->WebserverConfigList["WebsiteMain.directory"] + tmpfilename + ".gz";
|
||||
#ifdef Y_CONFIG_FEATUE_SENDFILE_CAN_ACCESS_ALL
|
||||
else if(access(tmpfilename.c_str(),4) == 0)
|
||||
;
|
||||
;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
return tmpfilename;
|
||||
@@ -187,15 +177,12 @@ std::string CmodSendfile::GetFileName(CyhookHandler *hh, std::string path, std::
|
||||
//-----------------------------------------------------------------------------
|
||||
// Send File: Open File and check file type
|
||||
//-----------------------------------------------------------------------------
|
||||
int CmodSendfile::OpenFile(CyhookHandler *, std::string fullfilename)
|
||||
{
|
||||
int fd= -1;
|
||||
int CmodSendfile::OpenFile(CyhookHandler *, std::string fullfilename) {
|
||||
int fd = -1;
|
||||
std::string tmpstring;
|
||||
if(fullfilename.length() > 0)
|
||||
{
|
||||
fd = open( fullfilename.c_str(), O_RDONLY );
|
||||
if (fd<=0)
|
||||
{
|
||||
if (fullfilename.length() > 0) {
|
||||
fd = open(fullfilename.c_str(), O_RDONLY);
|
||||
if (fd <= 0) {
|
||||
aprintf("cannot open file %s: ", fullfilename.c_str());
|
||||
dperror("");
|
||||
}
|
||||
@@ -203,15 +190,14 @@ int CmodSendfile::OpenFile(CyhookHandler *, std::string fullfilename)
|
||||
return fd;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Send File: Determine MIME-Type fro File-Extention
|
||||
// Send File: Determine MIME-Type for File-Extention
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CmodSendfile::GetContentType(std::string ext)
|
||||
{
|
||||
std::string CmodSendfile::GetContentType(std::string ext) {
|
||||
std::string ctype = "text/plain";
|
||||
ext = string_tolower(ext);
|
||||
for (unsigned int i = 0;i < (sizeof(MimeFileExtensions)/sizeof(MimeFileExtensions[0])); i++)
|
||||
if (MimeFileExtensions[i].fileext == ext)
|
||||
{
|
||||
for (unsigned int i = 0; i < (sizeof(MimeFileExtensions)
|
||||
/ sizeof(MimeFileExtensions[0])); i++)
|
||||
if (MimeFileExtensions[i].fileext == ext) {
|
||||
ctype = MimeFileExtensions[i].mime;
|
||||
break;
|
||||
}
|
||||
|
@@ -22,18 +22,16 @@
|
||||
//=============================================================================
|
||||
// Constructor & Destructor
|
||||
//=============================================================================
|
||||
CmWebLog::CmWebLog(void)
|
||||
{
|
||||
CmWebLog::CmWebLog(void) {
|
||||
pthread_mutex_lock(&WebLog_mutex); // yea, its mine
|
||||
RefCounter++;
|
||||
pthread_mutex_unlock(&WebLog_mutex);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
CmWebLog::~CmWebLog(void)
|
||||
{
|
||||
CmWebLog::~CmWebLog(void) {
|
||||
pthread_mutex_lock(&WebLog_mutex); // yea, its mine
|
||||
--RefCounter;
|
||||
if(RefCounter <= 0)
|
||||
if (RefCounter <= 0)
|
||||
CloseLogFile();
|
||||
pthread_mutex_unlock(&WebLog_mutex);
|
||||
}
|
||||
@@ -43,11 +41,10 @@ CmWebLog::~CmWebLog(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
// HOOK: Hook_EndConnection
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmWebLog::Hook_EndConnection(CyhookHandler *hh)
|
||||
{
|
||||
if(LogFormat == "CLF")
|
||||
THandleStatus CmWebLog::Hook_EndConnection(CyhookHandler *hh) {
|
||||
if (LogFormat == "CLF")
|
||||
AddLogEntry_CLF(hh);
|
||||
else if(LogFormat == "ELF")
|
||||
else if (LogFormat == "ELF")
|
||||
AddLogEntry_ELF(hh);
|
||||
return HANDLED_CONTINUE; // even on Log-Error: continue
|
||||
}
|
||||
@@ -56,31 +53,27 @@ THandleStatus CmWebLog::Hook_EndConnection(CyhookHandler *hh)
|
||||
// HOOK: Hook_ReadConfig
|
||||
// This hook ist called from ReadConfig
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CmWebLog::Hook_ReadConfig(CConfigFile *Config, CStringList &)
|
||||
{
|
||||
LogFormat = Config->getString("mod_weblog.log_format", LOG_FORMAT);
|
||||
WebLogFilename = Config->getString("mod_weblog.logfile", LOG_FILE);
|
||||
THandleStatus CmWebLog::Hook_ReadConfig(CConfigFile *Config, CStringList &) {
|
||||
LogFormat = Config->getString("mod_weblog.log_format", LOG_FORMAT);
|
||||
WebLogFilename = Config->getString("mod_weblog.logfile", LOG_FILE);
|
||||
return HANDLED_CONTINUE;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CmWebLog::OpenLogFile()
|
||||
{
|
||||
if(WebLogFilename == "")
|
||||
bool CmWebLog::OpenLogFile() {
|
||||
if (WebLogFilename == "")
|
||||
return false;
|
||||
if(WebLogFile == NULL)
|
||||
{
|
||||
if (WebLogFile == NULL) {
|
||||
bool isNew = false;
|
||||
pthread_mutex_lock(&WebLog_mutex); // yeah, its mine
|
||||
if(access(WebLogFilename.c_str(), 4) != 0)
|
||||
if (access(WebLogFilename.c_str(), 4) != 0)
|
||||
isNew = true;
|
||||
WebLogFile = fopen(WebLogFilename.c_str(),"a");
|
||||
if(isNew)
|
||||
{
|
||||
if(LogFormat == "ELF")
|
||||
{
|
||||
WebLogFile = fopen(WebLogFilename.c_str(), "a");
|
||||
if (isNew) {
|
||||
if (LogFormat == "ELF") {
|
||||
printf("#Version: 1.0\n");
|
||||
printf("#Remarks: yhttpd" WEBSERVERNAME "\n");
|
||||
printf("#Fields: c-ip username date time x-request cs-uri sc-status cs-method bytes time-taken x-time-request x-time-response cached\n");
|
||||
printf(
|
||||
"#Fields: c-ip username date time x-request cs-uri sc-status cs-method bytes time-taken x-time-request x-time-response cached\n");
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&WebLog_mutex);
|
||||
@@ -88,34 +81,30 @@ bool CmWebLog::OpenLogFile()
|
||||
return (WebLogFile != NULL);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void CmWebLog::CloseLogFile()
|
||||
{
|
||||
if(WebLogFile != NULL)
|
||||
{
|
||||
void CmWebLog::CloseLogFile() {
|
||||
if (WebLogFile != NULL) {
|
||||
pthread_mutex_lock(&WebLog_mutex); // yeah, its mine
|
||||
fclose(WebLogFile);
|
||||
fclose( WebLogFile);
|
||||
WebLogFile = NULL;
|
||||
pthread_mutex_unlock(&WebLog_mutex);
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
#define bufferlen 1024*8
|
||||
bool CmWebLog::printf(const char *fmt, ...)
|
||||
{
|
||||
if(!OpenLogFile())
|
||||
bool CmWebLog::printf(const char *fmt, ...) {
|
||||
if (!OpenLogFile())
|
||||
return false;
|
||||
bool success = false;
|
||||
char buffer[bufferlen];
|
||||
if(WebLogFile != NULL)
|
||||
{
|
||||
if (WebLogFile != NULL) {
|
||||
pthread_mutex_lock(&WebLog_mutex); // yeah, its mine
|
||||
va_list arglist;
|
||||
va_start( arglist, fmt );
|
||||
vsnprintf( buffer, bufferlen, fmt, arglist );
|
||||
va_start(arglist, fmt);
|
||||
vsnprintf(buffer, bufferlen, fmt, arglist);
|
||||
va_end(arglist);
|
||||
unsigned int len = strlen(buffer);
|
||||
success = (fwrite(buffer, len, 1, WebLogFile) == len);
|
||||
fflush(WebLogFile);
|
||||
fflush( WebLogFile);
|
||||
pthread_mutex_unlock(&WebLog_mutex);
|
||||
}
|
||||
return success;
|
||||
|
@@ -28,7 +28,8 @@
|
||||
//=============================================================================
|
||||
// Initialization of static variables
|
||||
//=============================================================================
|
||||
pthread_mutex_t CyParser::yParser_mutex = PTHREAD_MUTEX_INITIALIZER;;
|
||||
pthread_mutex_t CyParser::yParser_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
;
|
||||
std::string CyParser::HTML_DIRS[HTML_DIR_COUNT];
|
||||
std::string CyParser::PLUGIN_DIRS[PLUGIN_DIR_COUNT];
|
||||
std::map<std::string, std::string> CyParser::ycgi_global_vars;
|
||||
@@ -39,64 +40,59 @@ std::string CyParser::yCached_blocks_content;
|
||||
//=============================================================================
|
||||
// Constructor & Destructor
|
||||
//=============================================================================
|
||||
CyParser::CyParser()
|
||||
{
|
||||
CyParser::CyParser() {
|
||||
yConfig = new CConfigFile(',');
|
||||
yCached_blocks_attrib.st_mtime = 0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
CyParser::~CyParser(void)
|
||||
{
|
||||
if(yConfig != NULL)
|
||||
CyParser::~CyParser(void) {
|
||||
if (yConfig != NULL)
|
||||
delete yConfig;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void CyParser::init(CyhookHandler *hh)
|
||||
{
|
||||
if(HTML_DIRS[0] == "")
|
||||
{
|
||||
CyParser::HTML_DIRS[0]=hh->WebserverConfigList["PublicDocumentRoot"];
|
||||
HTML_DIRS[1]=hh->WebserverConfigList["PrivatDocumentRoot"];
|
||||
PLUGIN_DIRS[0]=HTML_DIRS[0];
|
||||
void CyParser::init(CyhookHandler *hh) {
|
||||
if (HTML_DIRS[0] == "") {
|
||||
CyParser::HTML_DIRS[0] = hh->WebserverConfigList["WebsiteMain.override_directory"];
|
||||
HTML_DIRS[1] = hh->WebserverConfigList["WebsiteMain.directory"];
|
||||
PLUGIN_DIRS[0] = HTML_DIRS[0];
|
||||
PLUGIN_DIRS[0].append("/scripts");
|
||||
PLUGIN_DIRS[1]=HTML_DIRS[1];
|
||||
PLUGIN_DIRS[1] = HTML_DIRS[1];
|
||||
PLUGIN_DIRS[1].append("/scripts");
|
||||
}
|
||||
}
|
||||
//=============================================================================
|
||||
// Main Dispatcher / Call definitions for /y/<dispatch>
|
||||
//=============================================================================
|
||||
const CyParser::TyCgiCall CyParser::yCgiCallList[]=
|
||||
{
|
||||
{"cgi", &CyParser::cgi, "text/html; charset=UTF-8"},
|
||||
const CyParser::TyCgiCall CyParser::yCgiCallList[] = {
|
||||
{ "cgi", &CyParser::cgi, "text/html; charset=UTF-8" },
|
||||
#ifdef Y_CONFIG_FEATURE_SHOW_SERVER_CONFIG
|
||||
{"server-config", &CyParser::cgi_server_config, "text/html"},
|
||||
{ "server-config", &CyParser::cgi_server_config, "text/html"},
|
||||
#endif
|
||||
};
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
// HOOK: response_hook Handler
|
||||
// This is the main dispatcher for this module
|
||||
//-----------------------------------------------------------------------------
|
||||
THandleStatus CyParser::Hook_SendResponse(CyhookHandler *hh)
|
||||
{
|
||||
THandleStatus CyParser::Hook_SendResponse(CyhookHandler *hh) {
|
||||
hh->status = HANDLED_NONE;
|
||||
|
||||
log_level_printf(4,"yparser hook start url:%s\n",hh->UrlData["url"].c_str());
|
||||
log_level_printf(4, "yparser hook start url:%s\n",
|
||||
hh->UrlData["url"].c_str());
|
||||
init(hh);
|
||||
|
||||
CyParser *yP = new CyParser(); // create a Session
|
||||
if(hh->UrlData["fileext"] == "yhtm") // yParser for yhtm-File
|
||||
CyParser *yP = new CyParser(); // create a Session
|
||||
if (hh->UrlData["fileext"] == "yhtm") // yParser for yhtm-File
|
||||
yP->ParseAndSendFile(hh);
|
||||
else if(hh->UrlData["path"] == "/y/") // /y/<cgi> commands
|
||||
else if (hh->UrlData["path"] == "/y/") // /y/<cgi> commands
|
||||
{
|
||||
yP->Execute(hh);
|
||||
if(hh->status == HANDLED_NOT_IMPLEMENTED)
|
||||
hh->status = HANDLED_NONE; // y-calls can be implemented anywhere
|
||||
if (hh->status == HANDLED_NOT_IMPLEMENTED)
|
||||
hh->status = HANDLED_NONE; // y-calls can be implemented anywhere
|
||||
}
|
||||
delete yP;
|
||||
|
||||
// log_level_printf(4,"yparser hook end status:%d\n",(int)hh->status);
|
||||
// log_level_printf(5,"yparser hook result:%s\n",hh->yresult.c_str());
|
||||
// log_level_printf(4,"yparser hook end status:%d\n",(int)hh->status);
|
||||
// log_level_printf(5,"yparser hook result:%s\n",hh->yresult.c_str());
|
||||
|
||||
return hh->status;
|
||||
}
|
||||
@@ -104,40 +100,39 @@ THandleStatus CyParser::Hook_SendResponse(CyhookHandler *hh)
|
||||
//-----------------------------------------------------------------------------
|
||||
// URL Function Dispatching
|
||||
//-----------------------------------------------------------------------------
|
||||
void CyParser::Execute(CyhookHandler *hh)
|
||||
{
|
||||
void CyParser::Execute(CyhookHandler *hh) {
|
||||
int index = -1;
|
||||
std::string filename = hh->UrlData["filename"];
|
||||
|
||||
log_level_printf(4,"yParser.Execute filename%s\n",filename.c_str());
|
||||
log_level_printf(4, "yParser.Execute filename%s\n", filename.c_str());
|
||||
filename = string_tolower(filename);
|
||||
|
||||
// debugging informations
|
||||
if(CLogging::getInstance()->getDebug())
|
||||
{
|
||||
dprintf("Execute CGI : %s\n",filename.c_str());
|
||||
for(CStringList::iterator it = hh->ParamList.begin() ;
|
||||
it != hh->ParamList.end() ; it++)
|
||||
dprintf(" Parameter %s : %s\n",it->first.c_str(), it->second.c_str());
|
||||
if (CLogging::getInstance()->getDebug()) {
|
||||
dprintf("Execute CGI : %s\n", filename.c_str());
|
||||
for (CStringList::iterator it = hh->ParamList.begin(); it
|
||||
!= hh->ParamList.end(); it++)
|
||||
dprintf(" Parameter %s : %s\n", it->first.c_str(),
|
||||
it->second.c_str());
|
||||
}
|
||||
|
||||
// get function index
|
||||
for(unsigned int i = 0;i < (sizeof(yCgiCallList)/sizeof(yCgiCallList[0])); i++)
|
||||
if (filename == yCgiCallList[i].func_name)
|
||||
{
|
||||
for (unsigned int i = 0; i < (sizeof(yCgiCallList)
|
||||
/ sizeof(yCgiCallList[0])); i++)
|
||||
if (filename == yCgiCallList[i].func_name) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
if(index == -1) // function not found
|
||||
if (index == -1) // function not found
|
||||
{
|
||||
hh->SetError(HTTP_NOT_IMPLEMENTED, HANDLED_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
|
||||
// send header
|
||||
if(std::string(yCgiCallList[index].mime_type) == "") // set by self
|
||||
if (std::string(yCgiCallList[index].mime_type) == "") // set by self
|
||||
;
|
||||
else if(std::string(yCgiCallList[index].mime_type) == "+xml") // Parameter xml?
|
||||
else if (std::string(yCgiCallList[index].mime_type) == "+xml") // Parameter xml?
|
||||
if (hh->ParamList["xml"] != "")
|
||||
hh->SetHeader(HTTP_OK, "text/xml");
|
||||
else
|
||||
@@ -146,10 +141,9 @@ void CyParser::Execute(CyhookHandler *hh)
|
||||
hh->SetHeader(HTTP_OK, yCgiCallList[index].mime_type);
|
||||
// response
|
||||
hh->status = HANDLED_READY;
|
||||
if (hh->Method == M_HEAD) // HEAD or function call
|
||||
if (hh->Method == M_HEAD) // HEAD or function call
|
||||
return;
|
||||
else
|
||||
{
|
||||
else {
|
||||
(this->*yCgiCallList[index].pfunc)(hh);
|
||||
return;
|
||||
}
|
||||
@@ -161,13 +155,11 @@ void CyParser::Execute(CyhookHandler *hh)
|
||||
//-----------------------------------------------------------------------------
|
||||
// mini cgi Engine (Entry for ycgi)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CyParser::cgi(CyhookHandler *hh)
|
||||
{
|
||||
void CyParser::cgi(CyhookHandler *hh) {
|
||||
bool ydebug = false;
|
||||
std::string htmlfilename, yresult, ycmd;
|
||||
|
||||
if (hh->ParamList.size() > 0)
|
||||
{
|
||||
if (hh->ParamList.size() > 0) {
|
||||
if (hh->ParamList["tmpl"] != "") // for GET and POST
|
||||
htmlfilename = hh->ParamList["tmpl"];
|
||||
else
|
||||
@@ -183,12 +175,11 @@ void CyParser::cgi(CyhookHandler *hh)
|
||||
yresult = cgi_cmd_parsing(hh, ycmd, ydebug); // parsing engine
|
||||
}
|
||||
// parsing given file
|
||||
if(htmlfilename != "")
|
||||
if (htmlfilename != "")
|
||||
yresult = cgi_file_parsing(hh, htmlfilename, ydebug);
|
||||
}
|
||||
else
|
||||
} else
|
||||
printf("[CyParser] Y-cgi:no parameter given\n");
|
||||
if (yresult.length()<=0)
|
||||
if (yresult.length() <= 0)
|
||||
hh->SetError(HTTP_NOT_IMPLEMENTED, HANDLED_NOT_IMPLEMENTED);
|
||||
else
|
||||
hh->addResult(yresult, HANDLED_READY);
|
||||
@@ -212,17 +203,17 @@ void CyParser::cgi_server_config(CyhookHandler *hh)
|
||||
// Cofig file
|
||||
yresult += string_printf("<table border=\"1\">\n");
|
||||
CStringList::iterator i = (hh->WebserverConfigList).begin();
|
||||
for ( ; i!= (hh->WebserverConfigList).end(); i++ )
|
||||
for (; i!= (hh->WebserverConfigList).end(); i++ )
|
||||
{
|
||||
if( ((*i).first) != "mod_auth.username" && ((*i).first) != "mod_auth.password")
|
||||
yresult += string_printf("<tr><td>%s</td><td>%s</td></tr>\n", ((*i).first).c_str(), ((*i).second).c_str());
|
||||
yresult += string_printf("<tr><td>%s</td><td>%s</td></tr>\n", ((*i).first).c_str(), ((*i).second).c_str());
|
||||
}
|
||||
yresult += string_printf("</table>\n");
|
||||
// hook list
|
||||
yresult += string_printf("<br/><b>Hooks (Compiled)</b><br/>\n");
|
||||
yresult += string_printf("<table border=\"1\">\n");
|
||||
THookList::iterator j = hh->HookList.begin();
|
||||
for ( ; j!= hh->HookList.end(); j++ )
|
||||
for (; j!= hh->HookList.end(); j++ )
|
||||
{
|
||||
yresult += string_printf("<tr><td>%s</td><td>%s</td></tr>\n", ((*j)->getHookName()).c_str(), ((*j)->getHookVersion()).c_str());
|
||||
}
|
||||
@@ -235,35 +226,34 @@ void CyParser::cgi_server_config(CyhookHandler *hh)
|
||||
//=============================================================================
|
||||
// y Parsing and sending .yhtm Files (Main ENTRY)
|
||||
//=============================================================================
|
||||
void CyParser::ParseAndSendFile(CyhookHandler *hh)
|
||||
{
|
||||
void CyParser::ParseAndSendFile(CyhookHandler *hh) {
|
||||
bool ydebug = false;
|
||||
std::string yresult, ycmd;
|
||||
log_level_printf(3,"yParser.ParseAndSendFile: File: %s\n",(hh->UrlData["filename"]).c_str());
|
||||
log_level_printf(3, "yParser.ParseAndSendFile: File: %s\n",
|
||||
(hh->UrlData["filename"]).c_str());
|
||||
|
||||
hh->SetHeader(HTTP_OK, "text/html; charset=UTF-8");
|
||||
if (hh->Method == M_HEAD)
|
||||
return;
|
||||
if (hh->ParamList["debug"] != "") // switch debug on
|
||||
if (hh->ParamList["debug"] != "") // switch debug on
|
||||
ydebug = true;
|
||||
if (hh->ParamList["execute"] != "") // execute done first!
|
||||
if (hh->ParamList["execute"] != "") // execute done first!
|
||||
{
|
||||
ycmd = hh->ParamList["execute"];
|
||||
ycmd = YPARSER_ESCAPE_START + ycmd + YPARSER_ESCAPE_END;
|
||||
log_level_printf(3,"<yParser.ParseAndSendFile>: Execute!: %s\n",ycmd.c_str());
|
||||
yresult = cgi_cmd_parsing(hh, ycmd, ydebug); // parsing engine
|
||||
log_level_printf(3, "<yParser.ParseAndSendFile>: Execute!: %s\n",
|
||||
ycmd.c_str());
|
||||
yresult = cgi_cmd_parsing(hh, ycmd, ydebug); // parsing engine
|
||||
}
|
||||
// parsing given file
|
||||
yresult += cgi_file_parsing(hh, hh->UrlData["filename"], ydebug);
|
||||
if (yresult.length()<=0)
|
||||
if (yresult.length() <= 0)
|
||||
hh->SetError(HTTP_NOT_IMPLEMENTED, HANDLED_NOT_IMPLEMENTED);
|
||||
else
|
||||
{
|
||||
hh->addResult(yresult,HANDLED_READY);
|
||||
if(!ycgi_vars["cancache"].empty())
|
||||
{
|
||||
hh->HookVarList["CacheCategory"]=ycgi_vars["cancache"];
|
||||
hh->HookVarList["CacheMimeType"]= hh->ResponseMimeType;
|
||||
else {
|
||||
hh->addResult(yresult, HANDLED_READY);
|
||||
if (!ycgi_vars["cancache"].empty()) {
|
||||
hh->HookVarList["CacheCategory"] = ycgi_vars["cancache"];
|
||||
hh->HookVarList["CacheMimeType"] = hh->ResponseMimeType;
|
||||
hh->status = HANDLED_CONTINUE;
|
||||
}
|
||||
}
|
||||
@@ -275,26 +265,23 @@ void CyParser::ParseAndSendFile(CyhookHandler *hh)
|
||||
//-----------------------------------------------------------------------------
|
||||
// mini cgi Engine (file parsing)
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CyParser::cgi_file_parsing(CyhookHandler *hh, std::string htmlfilename, bool ydebug)
|
||||
{
|
||||
std::string CyParser::cgi_file_parsing(CyhookHandler *hh,
|
||||
std::string htmlfilename, bool ydebug) {
|
||||
bool found = false;
|
||||
std::string htmlfullfilename, yresult, html_template;
|
||||
|
||||
char cwd[255];
|
||||
getcwd(cwd, 254);
|
||||
for (unsigned int i=0;i<HTML_DIR_COUNT && !found;i++)
|
||||
{
|
||||
htmlfullfilename = HTML_DIRS[i]+"/"+htmlfilename;
|
||||
for (unsigned int i = 0; i < HTML_DIR_COUNT && !found; i++) {
|
||||
htmlfullfilename = HTML_DIRS[i] + "/" + htmlfilename;
|
||||
std::fstream fin(htmlfullfilename.c_str(), std::fstream::in);
|
||||
if(fin.good())
|
||||
{
|
||||
if (fin.good()) {
|
||||
found = true;
|
||||
chdir(HTML_DIRS[i].c_str()); // set working dir
|
||||
|
||||
// read whole file into html_template
|
||||
std::string ytmp;
|
||||
while (!fin.eof())
|
||||
{
|
||||
while (!fin.eof()) {
|
||||
getline(fin, ytmp);
|
||||
html_template = html_template + ytmp + "\r\n";
|
||||
}
|
||||
@@ -303,11 +290,11 @@ std::string CyParser::cgi_file_parsing(CyhookHandler *hh, std::string htmlfilena
|
||||
}
|
||||
}
|
||||
chdir(cwd);
|
||||
if (!found)
|
||||
{
|
||||
printf("[CyParser] Y-cgi:template %s not found in\n",htmlfilename.c_str());
|
||||
for (unsigned int i=0;i<HTML_DIR_COUNT;i++) {
|
||||
printf("%s\n",HTML_DIRS[i].c_str());
|
||||
if (!found) {
|
||||
printf("[CyParser] Y-cgi:template %s not found in\n",
|
||||
htmlfilename.c_str());
|
||||
for (unsigned int i = 0; i < HTML_DIR_COUNT; i++) {
|
||||
printf("%s\n", HTML_DIRS[i].c_str());
|
||||
}
|
||||
}
|
||||
return yresult;
|
||||
@@ -316,37 +303,48 @@ std::string CyParser::cgi_file_parsing(CyhookHandler *hh, std::string htmlfilena
|
||||
//-----------------------------------------------------------------------------
|
||||
// main parsing (nested and recursive)
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string CyParser::cgi_cmd_parsing(CyhookHandler *hh, std::string html_template, bool ydebug)
|
||||
{
|
||||
std::string CyParser::cgi_cmd_parsing(CyhookHandler *hh,
|
||||
std::string html_template, bool ydebug) {
|
||||
std::string::size_type start, end;
|
||||
unsigned int esc_len = strlen(YPARSER_ESCAPE_START);
|
||||
bool is_cmd;
|
||||
std::string ycmd,yresult;
|
||||
std::string ycmd, yresult;
|
||||
|
||||
do // replace all {=<cmd>=} nested and recursive
|
||||
{
|
||||
is_cmd=false;
|
||||
if((end = html_template.find(YPARSER_ESCAPE_END)) != std::string::npos) // 1. find first y-end
|
||||
is_cmd = false;
|
||||
if ((end = html_template.find(YPARSER_ESCAPE_END)) != std::string::npos) // 1. find first y-end
|
||||
{
|
||||
if(ydebug) hh->printf("[ycgi debug]: END at:%d following:%s<br/>\n", end, (html_template.substr(end, 10)).c_str() );
|
||||
if((start = html_template.rfind(YPARSER_ESCAPE_START, end)) != std::string::npos) // 2. find next y-start befor
|
||||
if (ydebug)
|
||||
hh->printf("[ycgi debug]: END at:%d following:%s<br/>\n", end,
|
||||
(html_template.substr(end, 10)).c_str());
|
||||
if ((start = html_template.rfind(YPARSER_ESCAPE_START, end))
|
||||
!= std::string::npos) // 2. find next y-start befor
|
||||
{
|
||||
if(ydebug) hh->printf("[ycgi debug]: START at:%d following:%s<br/>\n", start, (html_template.substr(start+esc_len, 10)).c_str() );
|
||||
if (ydebug)
|
||||
hh->printf("[ycgi debug]: START at:%d following:%s<br/>\n",
|
||||
start,
|
||||
(html_template.substr(start + esc_len, 10)).c_str());
|
||||
|
||||
ycmd = html_template.substr(start+esc_len,end - (start+esc_len)); //3. get cmd
|
||||
if(ydebug) hh->printf("[ycgi debug]: CMD:[%s]<br/>\n", ycmd.c_str());
|
||||
yresult = YWeb_cgi_cmd( hh, ycmd ); // 4. execute cmd
|
||||
log_level_printf(5,"<yLoop>: ycmd...:%s\n",ycmd.c_str());
|
||||
log_level_printf(6,"<yLoop>: yresult:%s\n",yresult.c_str());
|
||||
if(ydebug) hh->printf("[ycgi debug]: RESULT:[%s]<br/>\n", yresult.c_str());
|
||||
html_template.replace(start,end - start + esc_len, yresult); // 5. replace cmd with output
|
||||
is_cmd = true; // one command found
|
||||
ycmd = html_template.substr(start + esc_len, end - (start
|
||||
+ esc_len)); //3. get cmd
|
||||
if (ydebug)
|
||||
hh->printf("[ycgi debug]: CMD:[%s]<br/>\n", ycmd.c_str());
|
||||
yresult = YWeb_cgi_cmd(hh, ycmd); // 4. execute cmd
|
||||
log_level_printf(5, "<yLoop>: ycmd...:%s\n", ycmd.c_str());
|
||||
log_level_printf(6, "<yLoop>: yresult:%s\n", yresult.c_str());
|
||||
if (ydebug)
|
||||
hh->printf("[ycgi debug]: RESULT:[%s]<br/>\n",
|
||||
yresult.c_str());
|
||||
html_template.replace(start, end - start + esc_len, yresult); // 5. replace cmd with output
|
||||
is_cmd = true; // one command found
|
||||
|
||||
if(ydebug) hh->printf("[ycgi debug]: STEP<br/>\n%s<br/>\n", html_template.c_str() );
|
||||
if (ydebug)
|
||||
hh->printf("[ycgi debug]: STEP<br/>\n%s<br/>\n",
|
||||
html_template.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
while(is_cmd);
|
||||
} while (is_cmd);
|
||||
return html_template;
|
||||
}
|
||||
//=============================================================================
|
||||
@@ -373,171 +371,124 @@ std::string CyParser::cgi_cmd_parsing(CyhookHandler *hh, std::string html_templ
|
||||
// L:<translation-id>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
std::string CyParser::YWeb_cgi_cmd(CyhookHandler *hh, std::string ycmd)
|
||||
{
|
||||
std::string CyParser::YWeb_cgi_cmd(CyhookHandler *hh, std::string ycmd) {
|
||||
std::string ycmd_type, ycmd_name, yresult;
|
||||
|
||||
if (ySplitString(ycmd,":",ycmd_type,ycmd_name))
|
||||
{
|
||||
if(ycmd_type == "L")
|
||||
if (ySplitString(ycmd, ":", ycmd_type, ycmd_name)) {
|
||||
if (ycmd_type == "L")
|
||||
yresult = CLanguage::getInstance()->getTranslation(ycmd_name);
|
||||
else if(ycmd_type == "script")
|
||||
else if (ycmd_type == "script")
|
||||
yresult = YexecuteScript(hh, ycmd_name);
|
||||
else if(ycmd_type == "if-empty")
|
||||
{
|
||||
else if (ycmd_type == "if-empty") {
|
||||
std::string if_value, if_then, if_else;
|
||||
if(ySplitString(ycmd_name,"~",if_value,if_then))
|
||||
{
|
||||
ySplitString(if_then,"~",if_then,if_else);
|
||||
if (ySplitString(ycmd_name, "~", if_value, if_then)) {
|
||||
ySplitString(if_then, "~", if_then, if_else);
|
||||
yresult = (if_value == "") ? if_then : if_else;
|
||||
}
|
||||
}
|
||||
else if(ycmd_type == "if-equal")
|
||||
{
|
||||
} else if (ycmd_type == "if-equal") {
|
||||
std::string if_left_value, if_right_value, if_then, if_else;
|
||||
if(ySplitString(ycmd_name,"~",if_left_value,if_right_value))
|
||||
{
|
||||
if(ySplitString(if_right_value,"~",if_right_value,if_then))
|
||||
{
|
||||
ySplitString(if_then,"~",if_then,if_else);
|
||||
yresult = (if_left_value == if_right_value) ? if_then : if_else;
|
||||
if (ySplitString(ycmd_name, "~", if_left_value, if_right_value)) {
|
||||
if (ySplitString(if_right_value, "~", if_right_value, if_then)) {
|
||||
ySplitString(if_then, "~", if_then, if_else);
|
||||
yresult = (if_left_value == if_right_value) ? if_then
|
||||
: if_else;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ycmd_type == "if-not-equal")
|
||||
{
|
||||
} else if (ycmd_type == "if-not-equal") {
|
||||
std::string if_left_value, if_right_value, if_then, if_else;
|
||||
if(ySplitString(ycmd_name,"~",if_left_value,if_right_value))
|
||||
{
|
||||
if(ySplitString(if_right_value,"~",if_right_value,if_then))
|
||||
{
|
||||
ySplitString(if_then,"~",if_then,if_else);
|
||||
yresult = (if_left_value != if_right_value) ? if_then : if_else;
|
||||
if (ySplitString(ycmd_name, "~", if_left_value, if_right_value)) {
|
||||
if (ySplitString(if_right_value, "~", if_right_value, if_then)) {
|
||||
ySplitString(if_then, "~", if_then, if_else);
|
||||
yresult = (if_left_value != if_right_value) ? if_then
|
||||
: if_else;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ycmd_type == "if-file-exists")
|
||||
{
|
||||
} else if (ycmd_type == "if-file-exists") {
|
||||
std::string if_value, if_then, if_else;
|
||||
if(ySplitString(ycmd_name,"~",if_value,if_then))
|
||||
{
|
||||
ySplitString(if_then,"~",if_then,if_else);
|
||||
yresult = (access(if_value.c_str(), 4) == 0) ? if_then : if_else;
|
||||
if (ySplitString(ycmd_name, "~", if_value, if_then)) {
|
||||
ySplitString(if_then, "~", if_then, if_else);
|
||||
yresult = (access(if_value.c_str(), 4) == 0) ? if_then
|
||||
: if_else;
|
||||
}
|
||||
}
|
||||
else if(ycmd_type == "include")
|
||||
{
|
||||
} else if (ycmd_type == "include") {
|
||||
std::string ytmp;
|
||||
std::fstream fin(ycmd_name.c_str(), std::fstream::in);
|
||||
if(fin.good())
|
||||
{
|
||||
while (!fin.eof())
|
||||
{
|
||||
if (fin.good()) {
|
||||
while (!fin.eof()) {
|
||||
getline(fin, ytmp);
|
||||
yresult += ytmp +"\n";
|
||||
yresult += ytmp + "\n";
|
||||
}
|
||||
fin.close();
|
||||
}
|
||||
}
|
||||
else if(ycmd_type == "include-block")
|
||||
{
|
||||
} else if (ycmd_type == "include-block") {
|
||||
std::string filename, blockname, tmp, ydefault;
|
||||
if (ySplitString(ycmd_name,";",filename,tmp))
|
||||
{
|
||||
ySplitString(tmp,";",blockname, ydefault);
|
||||
if (ySplitString(ycmd_name, ";", filename, tmp)) {
|
||||
ySplitString(tmp, ";", blockname, ydefault);
|
||||
yresult = YWeb_cgi_include_block(filename, blockname, ydefault);
|
||||
}
|
||||
}
|
||||
else if(ycmd_type == "func")
|
||||
} else if (ycmd_type == "func")
|
||||
yresult = this->YWeb_cgi_func(hh, ycmd_name);
|
||||
else if(ycmd_type == "ini-get")
|
||||
{
|
||||
else if (ycmd_type == "ini-get") {
|
||||
std::string filename, varname, tmp, ydefault, yaccess;
|
||||
ySplitString(ycmd_name,"~",filename,yaccess);
|
||||
if (ySplitString(filename,";",filename,tmp))
|
||||
{
|
||||
ySplitString(tmp,";",varname, ydefault);
|
||||
ySplitString(ycmd_name, "~", filename, yaccess);
|
||||
if (ySplitString(filename, ";", filename, tmp)) {
|
||||
ySplitString(tmp, ";", varname, ydefault);
|
||||
yresult = YWeb_cgi_get_ini(hh, filename, varname, yaccess);
|
||||
if(yresult == "" && ydefault != "")
|
||||
if (yresult == "" && ydefault != "")
|
||||
yresult = ydefault;
|
||||
}
|
||||
else
|
||||
} else
|
||||
yresult = "ycgi: ini-get: no ; found";
|
||||
}
|
||||
else if(ycmd_type == "ini-set")
|
||||
{
|
||||
} else if (ycmd_type == "ini-set") {
|
||||
std::string filename, varname, varvalue, tmp, yaccess;
|
||||
ySplitString(ycmd_name,"~",filename,yaccess);
|
||||
if (ySplitString(filename,";",filename,tmp))
|
||||
{
|
||||
if(ySplitString(tmp,";",varname, varvalue))
|
||||
ySplitString(ycmd_name, "~", filename, yaccess);
|
||||
if (ySplitString(filename, ";", filename, tmp)) {
|
||||
if (ySplitString(tmp, ";", varname, varvalue))
|
||||
YWeb_cgi_set_ini(hh, filename, varname, varvalue, yaccess);
|
||||
}
|
||||
else
|
||||
} else
|
||||
yresult = "ycgi: ini-get: no ; found";
|
||||
}
|
||||
else if(ycmd_type == "var-get")
|
||||
{
|
||||
} else if (ycmd_type == "var-get") {
|
||||
yresult = ycgi_vars[ycmd_name];
|
||||
}
|
||||
else if(ycmd_type == "var-set")
|
||||
{
|
||||
} else if (ycmd_type == "var-set") {
|
||||
std::string varname, varvalue;
|
||||
if (ySplitString(ycmd_name,"=",varname,varvalue))
|
||||
if (ySplitString(ycmd_name, "=", varname, varvalue))
|
||||
ycgi_vars[varname] = varvalue;
|
||||
}
|
||||
else if(ycmd_type == "global-var-get")
|
||||
{
|
||||
pthread_mutex_lock( &yParser_mutex );
|
||||
} else if (ycmd_type == "global-var-get") {
|
||||
pthread_mutex_lock(&yParser_mutex);
|
||||
yresult = ycgi_global_vars[ycmd_name];
|
||||
pthread_mutex_unlock( &yParser_mutex );
|
||||
}
|
||||
else if(ycmd_type == "global-var-set")
|
||||
{
|
||||
pthread_mutex_unlock(&yParser_mutex);
|
||||
} else if (ycmd_type == "global-var-set") {
|
||||
std::string varname, varvalue;
|
||||
if (ySplitString(ycmd_name,"=",varname,varvalue))
|
||||
{
|
||||
pthread_mutex_lock( &yParser_mutex );
|
||||
if (ySplitString(ycmd_name, "=", varname, varvalue)) {
|
||||
pthread_mutex_lock(&yParser_mutex);
|
||||
ycgi_global_vars[varname] = varvalue;
|
||||
pthread_mutex_unlock( &yParser_mutex );
|
||||
pthread_mutex_unlock(&yParser_mutex);
|
||||
}
|
||||
}
|
||||
else if(ycmd_type == "file-action")
|
||||
{
|
||||
} else if (ycmd_type == "file-action") {
|
||||
std::string filename, actionname, content, tmp, ydefault;
|
||||
if (ySplitString(ycmd_name,";",filename,tmp))
|
||||
{
|
||||
ySplitString(tmp,";",actionname, content);
|
||||
if (ySplitString(ycmd_name, ";", filename, tmp)) {
|
||||
ySplitString(tmp, ";", actionname, content);
|
||||
replace(content, "\r\n", "\n");
|
||||
if(actionname == "add")
|
||||
{
|
||||
std::fstream fout(filename.c_str(), std::fstream::out|std::fstream::binary);
|
||||
if (actionname == "add") {
|
||||
std::fstream fout(filename.c_str(), std::fstream::out
|
||||
| std::fstream::binary);
|
||||
fout << content;
|
||||
fout.close();
|
||||
}
|
||||
else
|
||||
if(actionname == "append")
|
||||
{
|
||||
std::fstream fout(filename.c_str(), std::fstream::app|std::fstream::binary );
|
||||
} else if (actionname == "append") {
|
||||
std::fstream fout(filename.c_str(), std::fstream::app
|
||||
| std::fstream::binary);
|
||||
fout << content;
|
||||
fout.close();
|
||||
}
|
||||
else
|
||||
if(actionname == "delete")
|
||||
{
|
||||
} else if (actionname == "delete") {
|
||||
remove(filename.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
yresult = "ycgi-type unknown";
|
||||
}
|
||||
else if (hh->ParamList[ycmd] != "")
|
||||
{
|
||||
if((hh->ParamList[ycmd]).find("script") == std::string::npos)
|
||||
} else if (hh->ParamList[ycmd] != "") {
|
||||
if ((hh->ParamList[ycmd]).find("script") == std::string::npos)
|
||||
yresult = hh->ParamList[ycmd];
|
||||
else
|
||||
yresult = "<!--Not Allowed script in "+ycmd+" -->";
|
||||
yresult = "<!--Not Allowed script in " + ycmd + " -->";
|
||||
}
|
||||
|
||||
return yresult;
|
||||
@@ -547,11 +498,10 @@ std::string CyParser::YWeb_cgi_cmd(CyhookHandler *hh, std::string ycmd)
|
||||
// Get Value from ini/conf-file (filename) for var (varname)
|
||||
// yaccess = open | cache
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::YWeb_cgi_get_ini(CyhookHandler *, std::string filename, std::string varname, std::string yaccess)
|
||||
{
|
||||
std::string CyParser::YWeb_cgi_get_ini(CyhookHandler *, std::string filename,
|
||||
std::string varname, std::string yaccess) {
|
||||
std::string result;
|
||||
if((yaccess == "open") || (yaccess == ""))
|
||||
{
|
||||
if ((yaccess == "open") || (yaccess == "")) {
|
||||
yConfig->clear();
|
||||
yConfig->loadConfig(filename);
|
||||
}
|
||||
@@ -563,16 +513,15 @@ std::string CyParser::YWeb_cgi_get_ini(CyhookHandler *, std::string filename, s
|
||||
// set Value from ini/conf-file (filename) for var (varname)
|
||||
// yaccess = open | cache | save
|
||||
//-------------------------------------------------------------------------
|
||||
void CyParser::YWeb_cgi_set_ini(CyhookHandler *, std::string filename, std::string varname, std::string varvalue, std::string yaccess)
|
||||
{
|
||||
void CyParser::YWeb_cgi_set_ini(CyhookHandler *, std::string filename,
|
||||
std::string varname, std::string varvalue, std::string yaccess) {
|
||||
std::string result;
|
||||
if((yaccess == "open") || (yaccess == ""))
|
||||
{
|
||||
if ((yaccess == "open") || (yaccess == "")) {
|
||||
yConfig->clear();
|
||||
yConfig->loadConfig(filename);
|
||||
}
|
||||
yConfig->setString(varname, varvalue);
|
||||
if((yaccess == "save") || (yaccess == ""))
|
||||
if ((yaccess == "save") || (yaccess == ""))
|
||||
yConfig->saveConfig(filename);
|
||||
}
|
||||
|
||||
@@ -581,34 +530,31 @@ void CyParser::YWeb_cgi_set_ini(CyhookHandler *, std::string filename, std::str
|
||||
// The textblock starts with "start-block~<blockname>" and ends with
|
||||
// "end-block~<blockname>"
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::YWeb_cgi_include_block(std::string filename, std::string blockname, std::string ydefault)
|
||||
{
|
||||
std::string CyParser::YWeb_cgi_include_block(std::string filename,
|
||||
std::string blockname, std::string ydefault) {
|
||||
std::string ytmp, yfile, yresult;
|
||||
struct stat attrib;
|
||||
yresult = ydefault;
|
||||
|
||||
stat(filename.c_str(), &attrib);
|
||||
|
||||
pthread_mutex_lock( &yParser_mutex );
|
||||
if( (attrib.st_mtime == yCached_blocks_attrib.st_mtime) && (filename == yCached_blocks_filename) )
|
||||
{
|
||||
log_level_printf(6, "include-block: (%s) from cache\n", blockname.c_str() );
|
||||
pthread_mutex_lock(&yParser_mutex);
|
||||
if ((attrib.st_mtime == yCached_blocks_attrib.st_mtime) && (filename
|
||||
== yCached_blocks_filename)) {
|
||||
log_level_printf(6, "include-block: (%s) from cache\n",
|
||||
blockname.c_str());
|
||||
yfile = yCached_blocks_content;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
bool found = false;
|
||||
for (unsigned int i=0;i<HTML_DIR_COUNT && !found;i++)
|
||||
{
|
||||
std::string ifilename = HTML_DIRS[i]+"/"+filename;
|
||||
for (unsigned int i = 0; i < HTML_DIR_COUNT && !found; i++) {
|
||||
std::string ifilename = HTML_DIRS[i] + "/" + filename;
|
||||
std::fstream fin(ifilename.c_str(), std::fstream::in);
|
||||
if(fin.good())
|
||||
{
|
||||
if (fin.good()) {
|
||||
found = true;
|
||||
while (!fin.eof()) // read whole file into yfile
|
||||
{
|
||||
getline(fin, ytmp);
|
||||
yfile += ytmp+"\n";
|
||||
yfile += ytmp + "\n";
|
||||
}
|
||||
fin.close();
|
||||
}
|
||||
@@ -616,69 +562,65 @@ std::string CyParser::YWeb_cgi_include_block(std::string filename, std::string
|
||||
yCached_blocks_content = yfile;
|
||||
yCached_blocks_attrib = attrib;
|
||||
yCached_blocks_filename = filename;
|
||||
log_level_printf(6, "include-block: (%s) from file\n", blockname.c_str() );
|
||||
log_level_printf(6, "include-block: (%s) from file\n",
|
||||
blockname.c_str());
|
||||
}
|
||||
pthread_mutex_unlock( &yParser_mutex );
|
||||
if(yfile.length() != 0)
|
||||
{
|
||||
std::string t = "start-block~"+blockname;
|
||||
pthread_mutex_unlock(&yParser_mutex);
|
||||
if (yfile.length() != 0) {
|
||||
std::string t = "start-block~" + blockname;
|
||||
std::string::size_type start, end;
|
||||
if((start = yfile.find(t)) != std::string::npos)
|
||||
{
|
||||
if((end = yfile.find("end-block~"+blockname, start+t.length())) != std::string::npos)
|
||||
{
|
||||
yresult = yfile.substr(start+t.length(),end - (start+t.length()) );
|
||||
log_level_printf(7, "include-block: (%s) yresult:(%s)\n", blockname.c_str(), yresult.c_str() );
|
||||
}
|
||||
else
|
||||
aprintf("include-blocks: Block END not found:%s Blockname:%s\n",filename.c_str() , blockname.c_str() );
|
||||
}
|
||||
else
|
||||
aprintf("include-blocks: Block START not found:%s Blockname:%s\n",filename.c_str() , blockname.c_str() );
|
||||
}
|
||||
else
|
||||
aprintf("include-blocks: file not found:%s Blockname:%s\n",filename.c_str() , blockname.c_str() );
|
||||
if ((start = yfile.find(t)) != std::string::npos) {
|
||||
if ((end = yfile.find("end-block~" + blockname, start + t.length()))
|
||||
!= std::string::npos) {
|
||||
yresult = yfile.substr(start + t.length(), end - (start
|
||||
+ t.length()));
|
||||
log_level_printf(7, "include-block: (%s) yresult:(%s)\n",
|
||||
blockname.c_str(), yresult.c_str());
|
||||
} else
|
||||
aprintf(
|
||||
"include-blocks: Block END not found:%s Blockname:%s\n",
|
||||
filename.c_str(), blockname.c_str());
|
||||
} else
|
||||
aprintf("include-blocks: Block START not found:%s Blockname:%s\n",
|
||||
filename.c_str(), blockname.c_str());
|
||||
} else
|
||||
aprintf("include-blocks: file not found:%s Blockname:%s\n",
|
||||
filename.c_str(), blockname.c_str());
|
||||
|
||||
return yresult;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
std::string CyParser::YexecuteScript(CyhookHandler *, std::string cmd)
|
||||
{
|
||||
std::string CyParser::YexecuteScript(CyhookHandler *, std::string cmd) {
|
||||
std::string script, para, result;
|
||||
bool found = false;
|
||||
|
||||
// split script and parameters
|
||||
int pos;
|
||||
if ((pos = cmd.find_first_of(" ")) > 0)
|
||||
{
|
||||
if ((pos = cmd.find_first_of(" ")) > 0) {
|
||||
script = cmd.substr(0, pos);
|
||||
para = cmd.substr(pos+1,cmd.length() - (pos+1)); // snip
|
||||
}
|
||||
else
|
||||
script=cmd;
|
||||
para = cmd.substr(pos + 1, cmd.length() - (pos + 1)); // snip
|
||||
} else
|
||||
script = cmd;
|
||||
// get file
|
||||
std::string fullfilename;
|
||||
script += ".sh"; //add script extention
|
||||
|
||||
char cwd[255];
|
||||
getcwd(cwd, 254);
|
||||
for (unsigned int i=0;i<PLUGIN_DIR_COUNT && !found;i++)
|
||||
{
|
||||
fullfilename = PLUGIN_DIRS[i]+"/"+script;
|
||||
FILE *test =fopen(fullfilename.c_str(),"r"); // use fopen: popen does not work
|
||||
if( test != NULL )
|
||||
{
|
||||
for (unsigned int i = 0; i < PLUGIN_DIR_COUNT && !found; i++) {
|
||||
fullfilename = PLUGIN_DIRS[i] + "/" + script;
|
||||
FILE *test = fopen(fullfilename.c_str(), "r"); // use fopen: popen does not work
|
||||
if (test != NULL) {
|
||||
fclose(test);
|
||||
chdir(PLUGIN_DIRS[i].c_str());
|
||||
FILE *f = popen( (fullfilename+" "+para).c_str(),"r"); //execute
|
||||
if (f != NULL)
|
||||
{
|
||||
FILE *f = popen((fullfilename + " " + para).c_str(), "r"); //execute
|
||||
if (f != NULL) {
|
||||
found = true;
|
||||
|
||||
char output[1024];
|
||||
while (fgets(output,1024,f)) // get script output
|
||||
while (fgets(output, 1024, f)) // get script output
|
||||
result += output;
|
||||
pclose(f);
|
||||
}
|
||||
@@ -686,13 +628,12 @@ std::string CyParser::YexecuteScript(CyhookHandler *, std::string cmd)
|
||||
}
|
||||
chdir(cwd);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
printf("<yparser> script %s not found in\n",script.c_str());
|
||||
for (unsigned int i=0;i<PLUGIN_DIR_COUNT;i++) {
|
||||
printf("%s\n",PLUGIN_DIRS[i].c_str());
|
||||
if (!found) {
|
||||
printf("<yparser> script %s not found in\n", script.c_str());
|
||||
for (unsigned int i = 0; i < PLUGIN_DIR_COUNT; i++) {
|
||||
printf("%s\n", PLUGIN_DIRS[i].c_str());
|
||||
}
|
||||
result="error";
|
||||
result = "error";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -704,42 +645,40 @@ std::string CyParser::YexecuteScript(CyhookHandler *, std::string cmd)
|
||||
// - Versions of httpd, yParser, Hooks,
|
||||
//=============================================================================
|
||||
|
||||
const CyParser::TyFuncCall CyParser::yFuncCallList[]=
|
||||
{
|
||||
{"get_request_data", &CyParser::func_get_request_data},
|
||||
{"get_header_data", &CyParser::func_get_header_data},
|
||||
{"get_config_data", &CyParser::func_get_config_data},
|
||||
{"do_reload_httpd_config", &CyParser::func_do_reload_httpd_config},
|
||||
{"httpd_change", &CyParser::func_change_httpd},
|
||||
{"get_languages_as_dropdown", &CyParser::func_get_languages_as_dropdown},
|
||||
{"set_language", &CyParser::func_set_language},
|
||||
const CyParser::TyFuncCall CyParser::yFuncCallList[] = {
|
||||
{ "get_request_data", &CyParser::func_get_request_data },
|
||||
{ "get_header_data", &CyParser::func_get_header_data },
|
||||
{ "get_config_data", &CyParser::func_get_config_data },
|
||||
{ "do_reload_httpd_config", &CyParser::func_do_reload_httpd_config },
|
||||
{ "httpd_change", &CyParser::func_change_httpd },
|
||||
{ "get_languages_as_dropdown", &CyParser::func_get_languages_as_dropdown },
|
||||
{ "set_language", &CyParser::func_set_language },
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// y-func : dispatching and executing
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::YWeb_cgi_func(CyhookHandler *hh, std::string ycmd)
|
||||
{
|
||||
std::string func, para, yresult="ycgi func not found";
|
||||
std::string CyParser::YWeb_cgi_func(CyhookHandler *hh, std::string ycmd) {
|
||||
std::string func, para, yresult = "ycgi func not found";
|
||||
bool found = false;
|
||||
ySplitString(ycmd," ",func, para);
|
||||
ySplitString(ycmd, " ", func, para);
|
||||
|
||||
for(unsigned int i = 0;i < (sizeof(yFuncCallList)/sizeof(yFuncCallList[0])); i++)
|
||||
if (func == yFuncCallList[i].func_name)
|
||||
{
|
||||
for (unsigned int i = 0; i < (sizeof(yFuncCallList)
|
||||
/ sizeof(yFuncCallList[0])); i++)
|
||||
if (func == yFuncCallList[i].func_name) {
|
||||
yresult = (this->*yFuncCallList[i].pfunc)(hh, para);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
log_level_printf(8,"<yparser: func>:%s Result:%s\n", func.c_str(), yresult.c_str() );
|
||||
log_level_printf(8, "<yparser: func>:%s Result:%s\n", func.c_str(),
|
||||
yresult.c_str());
|
||||
return yresult;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// y-func : get_request_data
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::func_get_request_data(CyhookHandler *hh, std::string para)
|
||||
{
|
||||
std::string CyParser::func_get_request_data(CyhookHandler *hh, std::string para) {
|
||||
std::string yresult;
|
||||
if (para == "client_addr")
|
||||
yresult = hh->UrlData["clientaddr"]; //compatibility TODO in yhtms
|
||||
@@ -750,16 +689,14 @@ std::string CyParser::func_get_request_data(CyhookHandler *hh, std::string para
|
||||
//-------------------------------------------------------------------------
|
||||
// y-func : get_header_data
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::func_get_header_data(CyhookHandler *hh, std::string para)
|
||||
{
|
||||
std::string CyParser::func_get_header_data(CyhookHandler *hh, std::string para) {
|
||||
return hh->HeaderList[para];
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// y-func : get_header_data
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::func_get_config_data(CyhookHandler *hh, std::string para)
|
||||
{
|
||||
if(para != "mod_auth.username" && para != "mod_auth.password")
|
||||
std::string CyParser::func_get_config_data(CyhookHandler *hh, std::string para) {
|
||||
if (para != "mod_auth.username" && para != "mod_auth.password")
|
||||
return hh->WebserverConfigList[para];
|
||||
else
|
||||
return "empty";
|
||||
@@ -768,9 +705,8 @@ std::string CyParser::func_get_config_data(CyhookHandler *hh, std::string para)
|
||||
// y-func : Reload the httpd.conf
|
||||
//-------------------------------------------------------------------------
|
||||
extern void yhttpd_reload_config();
|
||||
std::string CyParser::func_do_reload_httpd_config(CyhookHandler *, std::string )
|
||||
{
|
||||
log_level_printf(1,"func_do_reload_httpd_config: raise USR1 !!!\n");
|
||||
std::string CyParser::func_do_reload_httpd_config(CyhookHandler *, std::string) {
|
||||
log_level_printf(1, "func_do_reload_httpd_config: raise USR1 !!!\n");
|
||||
//raise(SIGUSR1); // Send HUP-Signal to Reload Settings
|
||||
yhttpd_reload_config();
|
||||
return "";
|
||||
@@ -779,48 +715,47 @@ std::string CyParser::func_do_reload_httpd_config(CyhookHandler *, std::string
|
||||
//-------------------------------------------------------------------------
|
||||
// y-func : Change httpd (process image) on the fly
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::func_change_httpd(CyhookHandler *hh, std::string para)
|
||||
{
|
||||
if(para != "" && access(para.c_str(), 4) == 0)
|
||||
{
|
||||
std::string CyParser::func_change_httpd(CyhookHandler *hh, std::string para) {
|
||||
if (para != "" && access(para.c_str(), 4) == 0) {
|
||||
hh->status = HANDLED_ABORT;
|
||||
int err = execvp(para.c_str(), NULL); // no return if successful
|
||||
return "ERROR [change_httpd]: execvp returns error code: "+err;
|
||||
}
|
||||
else
|
||||
return "ERROR [change_httpd]: para has not path to a file";
|
||||
return "ERROR [change_httpd]: execvp returns error code: " + err;
|
||||
} else
|
||||
return "ERROR [change_httpd]: para has not path to a file";
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// y-func : get_header_data
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::func_get_languages_as_dropdown(CyhookHandler *, std::string)
|
||||
{
|
||||
std::string CyParser::func_get_languages_as_dropdown(CyhookHandler *,
|
||||
std::string) {
|
||||
std::string yresult, sel;
|
||||
DIR *d;
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
|
||||
std::string act_language = CLanguage::getInstance()->language;
|
||||
d = opendir( (CLanguage::getInstance()->language_dir).c_str() );
|
||||
if( d != NULL ) {
|
||||
while( ( dir = readdir( d ) ) ) {
|
||||
if( strcmp( dir->d_name, "." ) == 0 || strcmp( dir->d_name, ".." ) == 0 )
|
||||
d = opendir((CLanguage::getInstance()->language_dir).c_str());
|
||||
if (d != NULL) {
|
||||
while ((dir = readdir(d))) {
|
||||
if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0)
|
||||
continue;
|
||||
if( dir->d_type != DT_DIR ) {
|
||||
sel=(act_language==std::string(dir->d_name)) ? "selected=\"selected\"" : "";
|
||||
if (dir->d_type != DT_DIR) {
|
||||
sel
|
||||
= (act_language == std::string(dir->d_name)) ? "selected=\"selected\""
|
||||
: "";
|
||||
yresult += string_printf("<option value=%s %s>%s</option>\n",
|
||||
dir->d_name, sel.c_str(), (encodeString(std::string(dir->d_name))).c_str());
|
||||
dir->d_name, sel.c_str(), (encodeString(std::string(
|
||||
dir->d_name))).c_str());
|
||||
}
|
||||
}
|
||||
closedir( d );
|
||||
closedir(d);
|
||||
}
|
||||
return yresult;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// y-func : get_header_data
|
||||
//-------------------------------------------------------------------------
|
||||
std::string CyParser::func_set_language(CyhookHandler *, std::string para)
|
||||
{
|
||||
if(para != ""){
|
||||
std::string CyParser::func_set_language(CyhookHandler *, std::string para) {
|
||||
if (para != "") {
|
||||
CConfigFile *Config = new CConfigFile(',');
|
||||
Config->loadConfig(HTTPD_CONFIGFILE);
|
||||
Config->setString("Language.selected", para);
|
||||
|
Reference in New Issue
Block a user