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:
yjogol
2010-02-25 20:00:09 +00:00
parent 80797c9661
commit 7bfed91651
30 changed files with 1711 additions and 1905 deletions

View File

@@ -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

View 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

View File

@@ -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);
}
}

View File

@@ -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
"')\">&nbsp;%d. %s%s</a>&nbsp;<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&nbsp;%s&nbsp;"
"<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

View File

@@ -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"},

View File

@@ -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)

View File

@@ -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>

View File

@@ -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");
}
//]]>

View File

@@ -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">&nbsp;</th>
<th colspan="2"><img id="logo" src="{=ini-get:/var/tuxbox/config/nhttpd.conf;Tuxbox.LogosURL=}/{=logoid=}.jpg" style="visibility:hidden">&nbsp;</th>
<th>{=L:date=}</th><th>{=L:from=}</th><th>{=L:to=}</th><th>{=L:program=}</th>
</tr>
</thead>

View File

@@ -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=}"/>&nbsp;{=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>

View File

@@ -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

View File

@@ -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

View File

@@ -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"]);
}

View File

@@ -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__

View File

@@ -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;
}

View File

@@ -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));
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 "";
}

View File

@@ -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__

View File

@@ -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>&nbsp;" \
"<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>&nbsp;"
"<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>");
}

View File

@@ -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__ */

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);