示例#1
0
//-----------------------------------------------------------------------------
// Parse the start-line
//	from RFC2616 / 5.1 Request-Line (start-line):
//	Request-Line   = Method SP Request-URI SP HTTP-Version CRLF (SP=Space)
//
//	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;

	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");
				Connection->Response.SendError(HTTP_NOT_IMPLEMENTED);
				log_level_printf(3,"Request: '%s'\n",rawbuffer.c_str());
				return false;
			}
			log_level_printf(3,"Request: FullURL: %s\n",UrlData["fullurl"].c_str());
			return true;
		}
	}
	return false;
}
示例#2
0
//-----------------------------------------------------------------------------
// HOOK: Response Send Handler
// If an other Hook has set HookVarList["CacheCategory"] then the Conntent
// in hh->yresult should be cached into a file.
// Remeber: url, filename, mimetype, category, createdate
//-----------------------------------------------------------------------------
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());	

	std::string category = hh->HookVarList["CacheCategory"];
	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
		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->status = HANDLED_READY;
		if(hh->UrlData["filename"] == "cache-info")
			yshowCacheInfo(hh);
		else if(hh->UrlData["filename"] == "cache-clear")
			yCacheClear(hh);
		else
			hh->status = HANDLED_CONTINUE;	// y-calls can be implemented anywhere
	}
	log_level_printf(4,"mod_cache hook end status:%d\n",(int)hh->status);	
	
	return hh->status;
}
示例#3
0
//=============================================================================
// y Parsing and sending .yhtm Files (Main ENTRY)
//=============================================================================
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());

	hh->SetHeader(HTTP_OK, "text/html; charset=UTF-8");
	if (hh->Method == M_HEAD)
		return;
	if (hh->ParamList["debug"] != "") // switch debug on
		ydebug = true;
	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
	}
	// parsing given file
	yresult += cgi_file_parsing(hh, hh->UrlData["path"]+hh->UrlData["filename"], ydebug);
	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;
			hh->status = HANDLED_CONTINUE;
		}
	}
}
示例#4
0
//-------------------------------------------------------------------------
// Get text block named <blockname> from file <filename>
// 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 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());
		yfile = yCached_blocks_content;
	} else {
		bool found = false;
		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()) {
				found = true;
				while (!fin.eof()) // read whole file into yfile
				{
					getline(fin, ytmp);
					yfile += ytmp + "\n";
				}
				fin.close();
			}
		}
		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());
	}
	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());

	return yresult;
}
//-------------------------------------------------------------------------
// Webserver-Thread for each connection
//-------------------------------------------------------------------------
void *WebThread(void *args) {
	TWebserverConnectionArgs *newConn = (TWebserverConnectionArgs *) args;
	if (!newConn) {
		dperror("WebThread called without arguments!\n");
		return NULL;
	}

	bool is_threaded = newConn->is_treaded;
	if (is_threaded)
		log_level_printf(1, "++ Thread 0x06%X gestartet\n", (int) pthread_self());

	// (1) create & init Connection
	CWebserver *ws = newConn->WebserverBackref;
	if (!ws) {
		dperror("WebThread CWebserver error!\n");
		return NULL;
	}

	CWebserverConnection *con = new CWebserverConnection(ws);
	if (!con) {
		dperror("WebThread CWebserverConnection error!\n");
		return NULL;
	}

	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

	// (2) handle the connection
	con->HandleConnection();

	// (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());
	else
		ws->addSocketToMasterSet(con->sock->get_socket()); // add to master set
#endif
	if (!con->keep_alive)
		con->sock->isValid = false;
	con->sock->handling = false; // socket can be handled by webserver main loop (select) again

#ifndef Y_CONFIG_FEATURE_KEEP_ALIVE
	delete newConn->ySock;
	newConn->ySock = NULL;
#endif

	// (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());
		ws->clear_Thread_List_Number(thread_number);
		pthread_exit( NULL);
	}
	return NULL;
}
示例#6
0
//=============================================================================
// Parsing Request
//=============================================================================
//-----------------------------------------------------------------------------
// Main Request Parsing
// RFC2616
//	generic-message = start-line
//		*(message-header CRLF)
//		CRLF
//		[ message-body ]
//	start-line      = Request-Line | Status-Line
//-----------------------------------------------------------------------------
bool CWebserverRequest::HandleRequest(void) {
	std::string start_line = "";
	// read first line
	do {
		start_line = Connection->sock->ReceiveLine();
		if (!Connection->sock->isValid)
			return false;
		if (start_line == "") // Socket empty
		{
			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

	start_line = trim(start_line);
	log_level_printf(1, "Request: %s\n", start_line.c_str());
	UrlData["startline"] = start_line;
	if (!ParseStartLine(start_line))
		return false;

	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) {
			Connection->Response.SendError(HTTP_INTERNAL_SERVER_ERROR);
			return false;
		}

		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) {
		//todo: implement
		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) {
		Connection->Response.Write("HTTP/1.1 100 Continue\r\n\r\n"); // POST Requests requires CONTINUE in HTTP/1.1
		return HandlePost();
	}
	// if you are here, something went wrong

	return true;
}
示例#7
0
//-----------------------------------------------------------------------------
// BASIC Send File over Socket for FILE*
// fd is an opened FILE-Descriptor
//-----------------------------------------------------------------------------
int CySocket::SendFile(int filed) {
	if (!isValid)
		return false;
#ifdef Y_CONFIG_HAVE_SENDFILE
	// does not work with SSL !!!
	off_t start = 0;
	off_t end = lseek(filed,0,SEEK_END);
	int written = 0;
	if((written = ::sendfile(sock,filed,&start,end)) == -1)
	{
		perror("sendfile failed\n");
		return false;
	}
	else
	BytesSend += written;
#else
	char sbuf[1024];
	unsigned int r = 0;
	while ((r = read(filed, sbuf, 1024)) > 0) {
		if (Send(sbuf, r) < 0) {
			perror("sendfile failed\n");
			return false;
		}
	}
#endif // Y_CONFIG_HAVE_SENDFILE
	log_level_printf(9, "<Sock:SendFile>: Bytes:%ld\n", BytesSend);
	return true;
}
//-----------------------------------------------------------------------------
// Look for Sockets to close
//-----------------------------------------------------------------------------
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) {
				log_level_printf(2, "FD: close con Timeout fd:%d\n", thisSocket);
				SL_CloseSocketBySlot(j);
			}
		}
}
//=============================================================================
// SocketList Handler
//=============================================================================
//-----------------------------------------------------------------------------
// Accept new Connection
//-----------------------------------------------------------------------------
int CWebserver::AcceptNewConnectionSocket() {
	int slot = -1;
	CySocket *connectionSock = NULL;

	if (!(connectionSock = listenSocket.accept())) // Blocking wait
	{
		dperror("Socket accept error. Continue.\n");
		delete connectionSock;
		return -1;
	}
#ifdef Y_CONFIG_USE_OPEN_SSL
	if(Cyhttpd::ConfigList["SSL"]=="true")
	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());

	// Add Socket to List
	slot = SL_GetFreeSlot();
	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
		int newfd = connectionSock->get_socket();
		if (newfd > fdmax) // keep track of the maximum fd
			fdmax = newfd;
	}
	return slot;
}
示例#10
0
//-----------------------------------------------------------------------------
// Read Webserver Configurationfile for languages
//-----------------------------------------------------------------------------
void Cyhttpd::ReadLanguage(void) {
	// Init Class vars
	CLanguage *lang = CLanguage::getInstance();
	log_level_printf(3, "ReadLanguage:%s\n",
			ConfigList["Language.selected"].c_str());
	lang->setLanguage(ConfigList["Language.selected"]);
}
示例#11
0
//-----------------------------------------------------------------------------
// parse parameter string
//       parameter               = attribute "=" value
//       attribute               = token
//       value                   = token | quoted-string
//
// 	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 ende = false;
	std::string param, name="", value, number;

	while(!ende)
	{
		if(!ySplitStringExact(param_string,"&",param,param_string))
			ende = true;
		if(ySplitStringExact(param,"=",name,value))
		{
			name = decodeString(name);
			value = trim(decodeString(value));
			if(ParameterList[name].empty())
				ParameterList[name] = value;
			else
			{
				ParameterList[name] += ",";
				ParameterList[name] += value;
			}
		}
		else
			name = trim(decodeString(name));
		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;
}
示例#12
0
//-----------------------------------------------------------------------------
// Hook Dispatcher for Server based Hooks
// 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 _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());
		// 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))
			break;
	}
	log_level_printf(4, "ReadConfig Hook-List End\n");
	return _status;
}
示例#13
0
//-------------------------------------------------------------------------
// Main
// Handle the Request, Handle (Send) Response), End the Connection
//-------------------------------------------------------------------------
void CWebserverConnection::HandleConnection() {
	gettimeofday(&tv_connection_start, &tz_connection_start);

	// get the request
	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));

		// 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;
#else
		keep_alive = false;
#endif
		// Send a response
		Response.SendResponse();

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

		// 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());

	} 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));
	}
	EndConnection();
}
示例#14
0
//-----------------------------------------------------------------------------
// Hook Dispatcher for EndConnection
//-----------------------------------------------------------------------------
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());
		// 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))
			break;
	}
	log_level_printf(4, "EndConnection Hook-List End\n");
	status = _status;
	return _status;
}
示例#15
0
//-----------------------------------------------------------------------------
// main parsing (nested and recursive)
//-----------------------------------------------------------------------------
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;

	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
		{
			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());

				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());
			}
		}
	} while (is_cmd);
	return html_template;
}
示例#16
0
//-------------------------------------------------------------------------
// y-func : dispatching and executing
//-------------------------------------------------------------------------
std::string  CNeutrinoYParser::YWeb_cgi_func(CyhookHandler *hh, std::string ycmd)
{
	std::string func="", para="", yresult="ycgi func not found";
	bool found = false;
	ySplitString(ycmd," ",func, para);

	log_level_printf(4,"NeutrinoYParser: func:(%s)\n", func.c_str());
	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,"NeutrinoYParser: func:(%s) para:(%s) Result:(%s)\n", func.c_str(), para.c_str(), yresult.c_str() );
	if(!found)
		yresult = CyParser::YWeb_cgi_func(hh, ycmd);
	return yresult;
}
示例#17
0
//-----------------------------------------------------------------------------
// 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 _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());
		// 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))
			break;
	}
	log_level_printf(4, "UploadReady Hook-List End\n");
	status = _status;
	return _status;
}
示例#18
0
//-----------------------------------------------------------------------------
// HOOK: Response Prepare Handler
// Response Prepare Check.
// Is it in cache?
//-----------------------------------------------------------------------------
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());	
	std::string url = hh->UrlData["fullurl"];
	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"].empty())	// Have If-Modified-Since Requested by Browser?
		{
			struct tm mod;
			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
			}
		}

		// normalize obj_last_modified to GMT
		struct tm lt;
		gmtime_r(&CacheList[url].created, &lt);
		time_t obj_last_modified_gmt = mktime(&lt);
		bool modified = (if_modified_since == (time_t)-1) || (if_modified_since < obj_last_modified_gmt);

		// Send file or not-modified header
		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);
		pthread_mutex_unlock(&mutex);
	}
	log_level_printf(4,"mod_cache hook prepare end status:%d\n",(int)hh->status);	
	
	return hh->status;
}
//-----------------------------------------------------------------------------
// 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)
		return;
	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
}
示例#20
0
//-----------------------------------------------------------------------------
// Receive File over Socket for FILE* filed
// read/write in small blocks (to save memory).
// usind sleep for sync input
// 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 _readbytes = 0;
	char buffer[RECEIVE_BLOCK_LEN];
	int retries=0;

	do
	{
		// check bytes in Socket buffer
		u_long readarg = 0;
#ifdef Y_CONFIG_USE_OPEN_SSL
		if(isSSLSocket)
			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(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
			{
				isValid = false;
				break;
			}	
			_readbytes += 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 _readbytes;
}
示例#21
0
//-----------------------------------------------------------------------------
// BASIC Send over Socket for Strings (char*)
//-----------------------------------------------------------------------------
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));
		Connection->RequestCanceled = true;
		return false;
	}
	else
		return true;
}
示例#22
0
//-----------------------------------------------------------------------------
// 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 _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());
		// 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))
			break;
	}
	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;
}
示例#23
0
//-----------------------------------------------------------------------------
// parse the header of the request
//	from RFC 2616 / 4.2 Message Header:
//	message-header = field-name ":" [ field-value ]
//	field-name     = token
//	field-value    = *( field-content | LWS )
//	field-content  = <the OCTETs making up the field-value
//		and consisting of either *TEXT or combinations
//		of token, separators, and quoted-string>
//-----------------------------------------------------------------------------
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))
			ende = true;
		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());
	}
	return true;
}
示例#24
0
//=============================================================================
// Hooks!
//=============================================================================
//-----------------------------------------------------------------------------
// HOOK: response_hook Handler
// This is the main dispatcher for this module
//-----------------------------------------------------------------------------
THandleStatus CNeutrinoYParser::Hook_SendResponse(CyhookHandler *hh)
{
	hh->status = HANDLED_NONE;

	log_level_printf(4,"Neutrinoparser Hook Start url:%s\n",hh->UrlData["url"].c_str());
	init(hh);

	CNeutrinoYParser *yP = new CNeutrinoYParser(NeutrinoAPI);		// create a Session
	if (hh->UrlData["fileext"] == "yhtm" || hh->UrlData["fileext"] == "yjs" || hh->UrlData["fileext"] == "ysh") // yParser for y*-Files
		yP->ParseAndSendFile(hh);
	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
	}

	delete yP;

	log_level_printf(4,"Neutrinoparser Hook Ende status:%d\n",(int)hh->status);
//	log_level_printf(5,"Neutrinoparser Hook Result:%s\n",hh->yresult.c_str());

	return hh->status;
}
示例#25
0
//-----------------------------------------------------------------------------
// URL Function Dispatching
//-----------------------------------------------------------------------------
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());
	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());
	}

	// get function index
	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
	{
		hh->SetError(HTTP_NOT_IMPLEMENTED, HANDLED_NOT_IMPLEMENTED);
		return;
	}

	// send header
	if (std::string(yCgiCallList[index].mime_type) == "") // set by self
		;
	else if (std::string(yCgiCallList[index].mime_type) == "+xml") // Parameter xml?
		if (hh->ParamList["xml"] != "")
			hh->SetHeader(HTTP_OK, "text/xml");
		else
			hh->SetHeader(HTTP_OK, "text/plain");
	else
		hh->SetHeader(HTTP_OK, yCgiCallList[index].mime_type);
	// response
	hh->status = HANDLED_READY;
	if (hh->Method == M_HEAD) // HEAD or function call
		return;
	else {
		(this->*yCgiCallList[index].pfunc)(hh);
		return;
	}
}
示例#26
0
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 "";
}
示例#27
0
//=============================================================================
// Main Dispacher for Response
// To understand HOOKS reade yhook.cpp Comments!!!
//-----------------------------------------------------------------------------
// RFC 2616 / 6 Response
//
//	After receiving and interpreting a request message, a server responds
//	with an HTTP response message.
//	Response       =Status-Line		; generated by SendHeader
//			*(( general-header	; generated by SendHeader
//			 | response-header	; generated by SendHeader
//			 | entity-header ) CRLF); generated by SendHeader
//			 CRLF			; generated by SendHeader
//			 [ message-body ]	; by HOOK Handling Loop or Sendfile
//=============================================================================
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);
	//--------------------------------------------------------------
	// HOOK Handling Loop [ PREPARE response hook ]
	// Checking and Preperation: Auth, static, cache, ...
	//--------------------------------------------------------------

	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");
			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)
		{
			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);
	
	// Prepare = 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;

		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)
	{
		bool cache = true;
//		if(Connection->HookHandler.UrlData["path"] == "/tmp/")//TODO: un-cachable dirs
//			cache = false;
		Write(Connection->HookHandler.BuildHeader(cache));
		if(Connection->Method != M_HEAD)
			Sendfile(Connection->Request.UrlData["url"]);
		return true;
	}			

	// arrived here? = error!
	SendError(HTTP_NOT_FOUND);
	return false;
}
示例#28
0
//=============================================================================
// Main Dispacher for Response
// To understand HOOKS reade yhook.cpp Comments!!!
//-----------------------------------------------------------------------------
// RFC 2616 / 6 Response
//
//	After receiving and interpreting a request message, a server responds
//	with an HTTP response message.
//	Response       =Status-Line		; generated by SendHeader
//			*(( general-header	; generated by SendHeader
//			 | response-header	; generated by SendHeader
//			 | entity-header ) CRLF); generated by SendHeader
//			 CRLF			; generated by SendHeader
//			 [ message-body ]	; by HOOK Handling Loop or Sendfile
//=============================================================================
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);
	//--------------------------------------------------------------
	// HOOK Handling Loop [ PREPARE response hook ]
	// Checking and Preperation: Auth, static, cache, ...
	//--------------------------------------------------------------

// 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);
#endif //Y_CONFIG_USE_HOSTEDWEB
	log_level_printf(5,"UrlPath:%s\n",(Connection->Request.UrlData["path"]).c_str());

	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");
			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)
		{
			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);
	
	// Prepare = 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;

		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)
	{
		bool cache = true;
//		if(Connection->HookHandler.UrlData["path"] == "/tmp/")//TODO: un-cachable dirs
//			cache = false;
		Write(Connection->HookHandler.BuildHeader(cache));
		if(Connection->Method != M_HEAD)
			Sendfile(Connection->Request.UrlData["url"]);
		return true;
	}			

	// arrived here? = error!
	SendError(HTTP_NOT_FOUND);
	return false;
}
示例#29
0
//-------------------------------------------------------------------------
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());
}
bool CWebserver::run(void) {
	set_threadname(__func__);
	if (!listenSocket.listen(port, HTTPD_MAX_CONNECTIONS)) {
		if (port != 80) {
			fprintf(stderr, "[yhttpd] Socket cannot bind and listen on port %d Abort.\n", port);
			return false;
		}
		fprintf(stderr, "[yhttpd] cannot bind and listen on port 80, retrying on port 8080.\n");
		port = 8080;
		if (!listenSocket.listen(port, HTTPD_MAX_CONNECTIONS)) {
			fprintf(stderr, "[yhttpd] Socket cannot bind and listen on port %d Abort.\n", port);
			return false;
		}
	}
#ifdef Y_CONFIG_FEATURE_KEEP_ALIVE

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

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

		// 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
		else
		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);

		// Socket Error?
		if(fd == -1 && errno != EINTR)
		{
			perror("select");
			return false;
		}

		// Socket Timeout?
		if(fd == 0)
		{
			// Testoutput for long living threads
			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);
				test_counter=0;
			}
			// some connection closing previous missed?
			if(++timeout_counter >= MAX_TIMEOUTS_TO_CLOSE)
			{
				CloseConnectionSocketsByTimeout();
				timeout_counter=0;
			}
			continue; // main loop again
		}
		//----------------------------------------------------------------------------------------
		// Check all observed descriptors & check new or re-use Connections
		//----------------------------------------------------------------------------------------
		for(int i = listener; i <= fdmax; i++)
		{
			int slot = -1;
			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)
				{
					slot = SL_GetExistingSocket(i);
					if(slot>=0)
					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);
					}
				}
			}
		}// for
		CloseConnectionSocketsByTimeout(); // Check connections to close

	}//while
#else
	while (!terminate) {
		CySocket *newConnectionSock;
		if (!(newConnectionSock = listenSocket.accept())) //Now: Blocking wait
		{
			pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
			pthread_testcancel();
			dperror("Socket accept error. Continue.\n");
			continue;
		}
		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
#endif
		handle_connection(newConnectionSock);
	}
#endif
	return true;
}