static
void GetFormatedDateTimeString (const XBOX::VTime& inTime, XBOX::VString &outDateTimeString)
{
	sLONG8 ms = inTime.GetMilliseconds() - (inTime.GetJulianDay() * 24 * 60 * 60 * 1000);

	outDateTimeString.Clear();
	outDateTimeString.Printf ("D%04d%02d%02dT%08d",
		inTime.GetLocalYear(),
		inTime.GetLocalMonth(),
		inTime.GetLocalDay(),
		ms);
}
void VHTTPServerLog::_GetCurrentFormatedTime (XBOX::VString& outTimeString, bool inLocalTime)
{
	sWORD		year, month, day, hour, minute, seconds, milliseconds;
	XBOX::VTime	time;
	
	time.FromSystemTime();	// GMT time
	if (inLocalTime)
		time.GetLocalTime (year, month, day, hour, minute, seconds, milliseconds);
	else
		time.GetUTCTime (year, month, day, hour, minute, seconds, milliseconds);
	
	outTimeString.Clear();
	outTimeString.Printf ("%02d:%02d:%02d", hour, minute, seconds);
}
bool VHTTPResponse::GetIfUnmodifiedSinceHeader (XBOX::VTime& outTime)
{
	XBOX::VString timeString;

	if (!GetRequestHeader().GetHeaderValue (STRING_HEADER_IF_UNMODIFIED_SINCE, timeString))
	{
		outTime.Clear();
		return false;
	}

	outTime.FromRfc822String (timeString);

	return true;
}
void VRemoteDebugPilot::HandleDisconnectingState()
{
	XBOX::VError			err;
	VSize					msgLen;
	bool					isMsgTerminated;
	sBYTE*					tmpStr;

	msgLen = K_MAX_SIZE;
	tmpStr = NULL;

	err = fWS->ReadMessage((void*)fTmpData,msgLen,isMsgTerminated);
	if (err)
	{
		DebugMsg("VRemoteDebugPilot::HandleDisconnectingState fWS->ReadMessage pb\n");
		//AbortContexts(true);
		DisconnectBrowser();
		return;
	}
	if (msgLen)
	{
		if (msgLen < K_MAX_SIZE)
		{
			fTmpData[msgLen] = 0;
		}
		else
		{
			fTmpData[K_MAX_SIZE-1] = 0;
		}
		DebugMsg("VRemoteDebugPilot::HandleDisconnectingState received msg(len=%d)='%s'\n",msgLen,fTmpData);
		tmpStr = (sBYTE*)strstr((const char*)fTmpData,K_DBG_PROTOCOL_DISCONNECT_STR);
	}
	else
	{
		XBOX::VTime			curtTime;
		XBOX::VDuration		disconnectDuration;
		curtTime.Substract(fDisconnectTime,disconnectDuration);
		if (disconnectDuration.ConvertToSeconds() > 2)
		{
			tmpStr = fTmpData;
		}
	}
	if (tmpStr)
	{
		//AbortContexts(true);
		DisconnectBrowser();
		return;
	}
}
void VHTTPServerLog::_GetCurrentFormatedDate (XBOX::VString& outDateString, bool inLocalTime, const char inDateSeparator)
{
	sWORD		year, month, day, hour, minute, seconds, milliseconds;
	XBOX::VTime	time;
	
	time.FromSystemTime();	// GMT time
	if (inLocalTime)
		time.GetLocalTime (year, month, day, hour, minute, seconds, milliseconds);
	else
		time.GetUTCTime (year, month, day, hour, minute, seconds, milliseconds);
	
	outDateString.Clear();
	outDateString.Printf ("%04d%c%02d%c%02d %02d:%02d:%02d",	year, inDateSeparator,
																month, inDateSeparator, day,
																hour, minute, seconds);
}
BEGIN_TOOLBOX_NAMESPACE
USING_TOOLBOX_NAMESPACE


//--------------------------------------------------------------------------------------------------


static
void _GetRFC1123DateString (const XBOX::VTime& inDate, XBOX::VString& outString)
{
	sWORD year, month, day, hour, minute, second, millisecond;
	inDate.GetUTCTime (year, month, day, hour, minute, second, millisecond);

	outString.Clear();

	switch (inDate.GetWeekDay())
	{
	case 0:		outString.AppendCString ("Sun");	break;
	case 1:		outString.AppendCString ("Mon");	break;
	case 2:		outString.AppendCString ("Tue");	break;
	case 3:		outString.AppendCString ("Wed");	break;
	case 4:		outString.AppendCString ("Thu");	break;
	case 5:		outString.AppendCString ("Fri");	break;
	case 6:		outString.AppendCString ("Sat");	break;
	}

	outString.AppendPrintf (", %02d-", day);

	switch (month)
	{
	case 1:		outString.AppendCString ("Jan");	break;
	case 2:		outString.AppendCString ("Feb");	break;
	case 3:		outString.AppendCString ("Mar");	break;
	case 4:		outString.AppendCString ("Apr");	break;
	case 5:		outString.AppendCString ("May");	break;
	case 6:		outString.AppendCString ("Jun");	break;
	case 7:		outString.AppendCString ("Jul");	break;
	case 8:		outString.AppendCString ("Aug");	break;
	case 9:		outString.AppendCString ("Sep");	break;
	case 10:	outString.AppendCString ("Oct");	break;
	case 11:	outString.AppendCString ("Nov");	break;
	case 12:	outString.AppendCString ("Dec");	break;
	}

	outString.AppendPrintf ("-%04d %02d:%02d:%02d GMT", year, hour, minute, second);
}
bool VHTTPServerLog::_NeedFileRotation()
{
	if (fBackupSettings.GetLogRotationMode() == LRC_NO_ROTATION)
		return false;
	
	if (fNeedSplit)
		return true;

	if (fBackupSettings.RotateOnSchedule() && (fNextFileRotationTime.GetStamp() > 0))
	{
		XBOX::VTime currentTime;
		currentTime.FromSystemTime();

		if (fNextFileRotationTime.GetStamp() < currentTime.GetStamp())
			return true;
	}

	return false;
}
void VRemoteDebugPilot::VStatusHysteresis::Get(bool& ioConnected)
{
	XBOX::VTime			curtTime;

	curtTime.FromSystemTime();
	fLock.Lock();
	if (ioConnected)
	{
		fLastConnectedTime = curtTime;
	}
	else
	{
		XBOX::VDuration		disconnectedDuration;
		curtTime.Substract(fLastConnectedTime,disconnectedDuration);
		// if disconnection quite recent (< approx 1 s) consider it always connected
		if (disconnectedDuration.ConvertToMilliseconds() < 1100)
		{
			ioConnected = true;
		}
	}
	fLock.Unlock();
	
}
/*
 *	Set the Time part of a XBOX::VTime (does NOT touch Date)
 */
static
void SetTimeValue (XBOX::VTime& ioTime, sLONG inDayHour)
{
	sLONG8 timeMilliseconds = 0;

	ioTime.SetLocalHour (0);
	ioTime.SetLocalMinute (0);
	ioTime.SetLocalSecond (0);
	ioTime.SetLocalMillisecond (0);

	timeMilliseconds = ioTime.GetMilliseconds();
	timeMilliseconds += (inDayHour * 1000);
	ioTime.FromMilliseconds (timeMilliseconds);
}
void VHTTPServerLog::_MakeDateString (const XBOX::VTime& inTime, XBOX::VString& outDateString)
{
	/*	See description: http://httpd.apache.org/docs/2.2/logs.html#common

	[day/month/year:hour:minute:second zone]
	day = 2*digit
	month = 3*letter
	year = 4*digit
	hour = 2*digit
	minute = 2*digit
	second = 2*digit
	zone = (`+' | `-') 4*digit
	*/

	sWORD			year = 0, month = 0, day = 0, hour = 0, minute = 0, seconds = 0, milliseconds = 0;
	static sLONG	sGMTOffSet = 0;
	static bool		sGMTOffSetUndefined = true;

	inTime.GetUTCTime (year, month, day, hour, minute, seconds, milliseconds);

	if (sGMTOffSetUndefined)
	{
		sGMTOffSet = (XBOX::VSystem::GetGMTOffset (true) / (3600));
		sGMTOffSetUndefined = false;
	}

	outDateString.Clear();
	outDateString.Printf (	"%02d/%s/%04d:%02d:%02d:%02d %c%02ld00",
		day,
		CONST_ABBREVIATED_ENGLISH_MONTH_NAMES[month],
		year,
		hour,
		minute,
		seconds,
		(sGMTOffSet >= 0) ? '+' : '-',
		sGMTOffSet);
}
XBOX::VError VHTTPServerLog::_WriteCLF_DLF (const IHTTPResponse& inHTTPResponse)
{
	XBOX::VString	string;
	XBOX::VTime		time;

	// GMT time
	time.FromSystemTime();

	// Client IP address
	HTTPServerTools::MakeIPv4String (inHTTPResponse.GetIPv4(), string);
	fRequestsBuffer.AppendString (string);
	fRequestsBuffer.AppendUniChar (CHAR_SPACE);
	
	// RFC931
	fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS);
	fRequestsBuffer.AppendUniChar (CHAR_SPACE);
	
	// AuthUser
	XBOX::VString userName;
	inHTTPResponse.GetRequest().GetAuthenticationInfos()->GetUserName (userName);
	
	if (userName.IsEmpty())
		fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS);
	else
		fRequestsBuffer.AppendString (userName);
	fRequestsBuffer.AppendUniChar (CHAR_SPACE);

	// Date & Time
	string.Clear();
	_MakeDateString (time, string);

	fRequestsBuffer.AppendUniChar (CHAR_LEFT_SQUARE_BRACKET);
	fRequestsBuffer.AppendString (string);
	fRequestsBuffer.AppendUniChar (CHAR_RIGHT_SQUARE_BRACKET);
	fRequestsBuffer.AppendUniChar (CHAR_SPACE);

	// HTTP Request
	fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK);
	fRequestsBuffer.AppendString (inHTTPResponse.GetRequest().GetRequestLine());
	fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK);
	fRequestsBuffer.AppendUniChar (CHAR_SPACE);
	
	// HTTP Status
	string.Clear();
	string.FromLong ((sLONG)inHTTPResponse.GetResponseStatusCode());
	fRequestsBuffer.AppendString (string);
	fRequestsBuffer.AppendUniChar (CHAR_SPACE);

	// HTTP Content Length
	string.Clear();
	if (!inHTTPResponse.GetResponseHeader (STRING_HEADER_CONTENT_LENGTH, string) || string.IsEmpty())
		string.FromLong(0);
	fRequestsBuffer.AppendString (string);
	
	// We add the last fields for the DLF log format
	if (fSettings.GetLogFormat() == LOG_FORMAT_DLF)
	{	
		// HTTP Referrer
		string.Clear();
		fRequestsBuffer.AppendUniChar (CHAR_SPACE);
		inHTTPResponse.GetRequest().GetHTTPHeaders().GetHeaderValue (STRING_HEADER_REFERER, string);
		fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK);
		fRequestsBuffer.AppendString (string);
		fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK);
		fRequestsBuffer.AppendUniChar (CHAR_SPACE);
		
		// HTTP User-Agent
		string.Clear();
		inHTTPResponse.GetRequest().GetHTTPHeaders().GetHeaderValue (STRING_HEADER_USER_AGENT, string);
		fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK);
		fRequestsBuffer.AppendString (string);
		fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK);
	}

	fRequestsBuffer.AppendUniChar (HTTP_LF);

	return XBOX::VE_OK;
}
XBOX::VError VHTTPServerLog::_RotateFile()
{
	XBOX::VError	error = XBOX::VE_OK;
	XBOX::VFilePath	logFilePath;
	XBOX::VTime		curTime;

	curTime.FromSystemTime();

	_GetLogFilePath (logFilePath);

	if (fLogFileAccessLock.Lock())
	{
		if (NULL == fLogFile)
			fLogFile = new XBOX::VFile (logFilePath);

		if (fLogFile->Exists())
		{
			// the backup fileName will look like "HTTPServer_DAAAAMMJJT00000000.waLog" => "HTTPServer_D20100122T113307.waLog"
			// I used this format to have the files sorted by time thanks to their name

			XBOX::VString	newFileName;
			XBOX::VString	dateTimeString;

			GetFormatedDateTimeString (curTime, dateTimeString);

			fLogFile->GetNameWithoutExtension (newFileName);
			newFileName.AppendUniChar (CHAR_LOW_LINE);
			newFileName.AppendString (dateTimeString);
			newFileName.AppendUniChar (CHAR_FULL_STOP);
			newFileName.AppendString (fSettings.GetLogFileNameExtension());

			if (fSettings.GetArchivesFolderName().IsEmpty())
			{
				error = fLogFile->Rename (newFileName);
			}
			else
			{
				XBOX::VFilePath	destinationFilePath;

				fLogFile->GetPath (destinationFilePath);
				destinationFilePath.ToParent().ToSubFolder (fSettings.GetArchivesFolderName());

				if (destinationFilePath.IsFolder())
				{
					XBOX::VFolder *	destinationFolder = new XBOX::VFolder (destinationFilePath);
					if (NULL != destinationFolder)
					{
						if (!destinationFolder->Exists())
							error = destinationFolder->CreateRecursive();
						XBOX::ReleaseRefCountable (&destinationFolder);

						if (XBOX::VE_OK == error)
						{
							destinationFilePath.SetFileName (newFileName);

							error = fLogFile->Move (destinationFilePath, NULL, XBOX::FCP_Overwrite);
						}
					}
					else
					{
						error = XBOX::VE_MEMORY_FULL;
					}
				}
			}

			XBOX::ReleaseRefCountable (&fLogFile);
		}

		//Creating the log file
		if ((XBOX::VE_OK == error) && (NULL == fLogFile))
		{
			fLogFile = new XBOX::VFile (logFilePath);
			if (NULL != fLogFile)
			{
				error = fLogFile->Create();

				// Set correct dates & times (used later to determine the next backup time)
				if (XBOX::VE_OK == error)
					error = fLogFile->SetTimeAttributes (&curTime, &curTime, &curTime);
				fLogFileSize = 0;
				
				fLastFileRotationTime.FromTime (curTime);
				_CalculateNextFileRotationTime();
			}
			else
			{
				error = VE_CANNOT_CREATE_LOG_FILE;
			}
		}
		else
		{
			error = VE_CANNOT_OPEN_LOG_FILE;
		}

		fNeedSplit = false;
		fLogFileAccessLock.Unlock();
	}

	return error;
}
bool VHTTPResponse::SetExpiresHeader (const XBOX::VTime& inValue)
{
	XBOX::VString dateString;
	inValue.GetRfc822String (dateString);
	return GetHeaders().SetHeaderValue (STRING_HEADER_EXPIRES, dateString, true);
}
XBOX::VString VHTTPCookie::ToString (bool inAlwaysExpires) const
{
	XBOX::VString result;

	if (!IsValid())
		return result;

	result.AppendString (fName);
	result.AppendUniChar (CHAR_EQUALS_SIGN);

	if (0 == fVersion)
	{
		// Netscape cookie
		result.AppendString (fValue);
		if (!fDomain.IsEmpty())
		{
			result.AppendCString ("; Domain=");
			result.AppendString (fDomain);
		}

		if (!fPath.IsEmpty())
		{
			result.AppendCString ("; Path=");
			result.AppendString (fPath);
		}

		if (fMaxAge >= 0)
		{
			XBOX::VTime		curTime;
			XBOX::VString	timeString;

			XBOX::VTime::Now (curTime);
			
			curTime.AddSeconds (fMaxAge);
			_GetRFC1123DateString (curTime, timeString);
			result.AppendCString ("; Expires=");
			result.AppendString (timeString);
		}

		if (fSecure)
		{
			result.AppendCString ("; Secure");
		}

		if (fHTTPOnly)
		{
			result.AppendCString ("; HttpOnly");
		}
	}
	else
	{
		// RFC 2109 cookie
		result.AppendString (fValue);

		if (!fComment.IsEmpty())
		{
			result.AppendCString ("; Comment=\"");
			result.AppendString (fComment);
			result.AppendUniChar (CHAR_QUOTATION_MARK);
		}

		if (!fDomain.IsEmpty())
		{
			result.AppendCString ("; Domain=");
			result.AppendString (fDomain);
		}

		if (!fPath.IsEmpty())
		{
			result.AppendCString ("; Path=");
			result.AppendString (fPath);
		}
		else
		{
			result.AppendCString ("; Path=/");
		}

		if (fMaxAge >= 0)
		{
			result.AppendCString ("; Max-Age=");
			result.AppendLong (fMaxAge);

			/* For Internet Explorer 6, 7 & 8 which does not support 'max-age' */ 
			if (inAlwaysExpires)
			{
				XBOX::VTime		curTime;
				XBOX::VString	timeString;

				XBOX::VTime::Now (curTime);

				curTime.AddSeconds (fMaxAge);
				_GetRFC1123DateString (curTime, timeString);
				result.AppendCString ("; Expires=");
				result.AppendString (timeString);
			}
		}

		if (fSecure)
		{
			result.AppendCString ("; Secure");
		}

		if (fHTTPOnly)
		{
			result.AppendCString ("; HttpOnly");
		}

		result.AppendCString ("; Version=1");
	}

	return result;
}
void VHTTPServerLog::_CalculateNextFileRotationTime()
{
	fNextFileRotationTime.Clear();

	if (fBackupSettings.RotateOnSchedule())
	{
		XBOX::VTime		curTime;
		XBOX::VDuration tempDuration;
		XBOX::VFilePath logPath;

		_GetLogFilePath (logPath);
		fNextFileRotationTime.FromSystemTime();
		curTime.FromSystemTime();

		if (GetFileCreationTime (logPath, &fLastFileRotationTime) != XBOX::VE_OK)
		{
			fLastFileRotationTime.FromSystemTime();
			fLastFileRotationTime.AddDays (-1);
		}

		switch (fBackupSettings.GetLogRotationMode())
		{
			case LRC_NO_ROTATION:
			case LRC_ROTATE_ON_FILE_SIZE:
				fNextFileRotationTime.Clear();
				break;
				
			case LRC_ROTATE_EVERY_HOUR:
			{				
				// I will first get the date of the last backup, or the creation date
				fNextFileRotationTime = fLastFileRotationTime;	
				
				
				// if the date (dd/mm/yy) is different from the curent date, we have to backup to the current date
				if ((fNextFileRotationTime.GetLocalDay()!=curTime.GetLocalDay())||(fNextFileRotationTime.GetLocalMonth()!=curTime.GetLocalMonth())||(fNextFileRotationTime.GetLocalYear()!=curTime.GetLocalYear()))
				{
					// we use the date of today 
					fNextFileRotationTime.FromSystemTime();	
				}
				
				// set the time to the "starting at" value
				SetTimeValue (fNextFileRotationTime, fBackupSettings.GetStartingTime());

				while(fNextFileRotationTime <= fLastFileRotationTime)
				{
					fNextFileRotationTime.AddHours( fBackupSettings.GetFrequency());
				}
				
				if ((fNextFileRotationTime.GetLocalDay()!=curTime.GetLocalDay())||(fNextFileRotationTime.GetLocalMonth()!=curTime.GetLocalMonth())||(fNextFileRotationTime.GetLocalYear()!=curTime.GetLocalYear()))
				{
					// set the time to the "starting at" value
					SetTimeValue (fNextFileRotationTime, fBackupSettings.GetStartingTime());
				}
				break;	// LRC_ROTATE_EVERY_HOUR
			}

			case LRC_ROTATE_EVERY_DAY:
			{
				// I will first get the date of the last backup, or the creation date
				fNextFileRotationTime = fLastFileRotationTime;
				fNextFileRotationTime.AddDays (fBackupSettings.GetFrequency());

				// set the time to the "starting at" value
				SetTimeValue (fNextFileRotationTime, fBackupSettings.GetStartingTime());

				break;	// LRC_ROTATE_EVERY_DAY
			}
				
			case LRC_ROTATE_EVERY_WEEK:
			{
				sLONG dayHour = 0;
				//	First, we check if there is a backup today
				//	Then if there is one this week				
				
				// I will first get the date of the last backup, or the creation date
				fNextFileRotationTime = fLastFileRotationTime;	
				// if the date is the date of today, we just update the hour
				if ((fNextFileRotationTime.GetLocalDay()==curTime.GetLocalDay())&&(fNextFileRotationTime.GetLocalMonth()==curTime.GetLocalMonth())&&(fNextFileRotationTime.GetLocalYear()==curTime.GetLocalYear()))
				{
					VHTTPServerLogBackupSettings::EWeekDay weekDay = (VHTTPServerLogBackupSettings::EWeekDay)curTime.GetWeekDay();

					if (fBackupSettings.GetSaveOnWeekDay (weekDay))
					{	
						dayHour = fBackupSettings.GetWeekDayBackupHour (weekDay);
						
						SetTimeValue (fNextFileRotationTime, dayHour);
					}

					if (fLastFileRotationTime < fNextFileRotationTime)
					{
						break;	// we will have to backup later this day
					}
				}
				// no backup time has been determined
				// let's search the next day which has a backup planned
				
				bool flagIsOk = false;
				fNextFileRotationTime = fLastFileRotationTime;	
				//	This week a backup is planned... because a backup has been done already
				//	Let's check if another backup is planned this week
				//	note : like in the database backup, if we missed one backup, it will be done ASAP
				if (fNextFileRotationTime.GetWeekDay() != VHTTPServerLogBackupSettings::eSunday)
				{
					while (fNextFileRotationTime.GetWeekDay() != VHTTPServerLogBackupSettings::eSunday  && !flagIsOk)
					{
						VHTTPServerLogBackupSettings::EWeekDay weekDay = (VHTTPServerLogBackupSettings::EWeekDay)fNextFileRotationTime.GetWeekDay();

						fNextFileRotationTime.AddDays (1);		// check the next day

						if (fBackupSettings.GetSaveOnWeekDay (weekDay))
						{
							dayHour = fBackupSettings.GetWeekDayBackupHour (weekDay);
							
							SetTimeValue (fNextFileRotationTime, dayHour);
							flagIsOk = true;
						}
					}
				}

				if (flagIsOk)	// another backup has been planned
					break;
				
				//	There is no backup to do this week
				//	Let's look gEveryWeek after ...
				fNextFileRotationTime = fLastFileRotationTime;	
				fNextFileRotationTime.AddDays (fBackupSettings.GetFrequency() * 7);

				//	We "rewind" the week until the first day of the week : Monday !
				while (fNextFileRotationTime.GetWeekDay() != VHTTPServerLogBackupSettings::eMonday)
					fNextFileRotationTime.AddDays(-1);

				//	We look each day of the week
				if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eMonday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eMonday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eTuesday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eTuesday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(1);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eWednesday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eWednesday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(2);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eThursday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eThursday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(3);
					
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eFriday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eFriday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(4);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eSaturday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eSaturday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(5);
				}
				else if (fBackupSettings.GetSaveOnWeekDay (VHTTPServerLogBackupSettings::eSunday))
				{
					dayHour = fBackupSettings.GetWeekDayBackupHour (VHTTPServerLogBackupSettings::eSunday);
					
					SetTimeValue (fNextFileRotationTime, dayHour);
					
					fNextFileRotationTime.AddDays(6);
				}

				break; // LRC_ROTATE_EVERY_WEEK
			}

			case LRC_ROTATE_EVERY_MONTH:
			{	
				fNextFileRotationTime = fLastFileRotationTime;
				fNextFileRotationTime.AddMonths( fBackupSettings.GetFrequency());
				
				if (fBackupSettings.GetMonthDay() == 29)	// the preference selected is "Last"
				{
					fNextFileRotationTime.AddMonths(1);
					fNextFileRotationTime.SetLocalDay(1);	// sets the time to the first day of he month
					fNextFileRotationTime.AddDays(-1);		// removes one day to get the last day of the previous month
				}
				else
				{
					fNextFileRotationTime.SetLocalDay(fBackupSettings.GetMonthDay());
				}
				// set the time to the "starting at" value
				SetTimeValue (fNextFileRotationTime, fBackupSettings.GetMonthDayHour());

				break;	// LRC_ROTATE_EVERY_MONTH
			}
				
			default : // Trying to backup on an unknown schedule
				assert (false);
				break;
		}
	}
}
void VHTTPCookie::FromString (const XBOX::VString& inString)
{
	XBOX::VectorOfVString	stringValues;
	XBOX::VString			string;
	XBOX::VString			nameString;
	XBOX::VString			valueString;

	Clear();

	inString.GetSubStrings (CHAR_SEMICOLON, stringValues, false, true);

	for (VectorOfVString::iterator it = stringValues.begin(); it != stringValues.end(); ++it)
	{
		sLONG pos = 0;
		string.FromString (*it);

		if ((pos = HTTPTools::FindASCIICString (string, "secure")) == 1)
		{
			SetSecure (true);
		}
		else if ((pos = HTTPTools::FindASCIICString (string, "httpOnly")) == 1)
		{
			SetHttpOnly (true);
		}
		else if ((pos = HTTPTools::FindASCIICString (string, "version")) == 1)
		{
			SetVersion (1);
		}
		else if ((pos = HTTPTools::FindASCIICString (string, "max-age")) == 1)
		{
			HTTPTools::ExtractFieldNameValue (string, nameString, valueString);
			fMaxAge = valueString.GetLong();
		}
		else if ((pos = HTTPTools::FindASCIICString (string, "expires")) == 1)
		{
			XBOX::VTime curTime;
			XBOX::VTime expiresTime;
			XBOX::VTime::Now (curTime);

			HTTPTools::ExtractFieldNameValue (string, nameString, valueString);
			expiresTime.FromRfc822String (valueString);

			if (expiresTime.GetMilliseconds() > curTime.GetMilliseconds())
				fMaxAge = (expiresTime.GetMilliseconds() - curTime.GetMilliseconds()) / 1000;
		}
		else if ((pos = HTTPTools::FindASCIICString (string, "path")) == 1)
		{
			HTTPTools::ExtractFieldNameValue (string, nameString, fPath);
		}
		else if ((pos = HTTPTools::FindASCIICString (string, "domain")) == 1)
		{
			HTTPTools::ExtractFieldNameValue (string, nameString, fDomain);
		}
		else if ((pos = HTTPTools::FindASCIICString (string, "comment")) == 1)
		{
			HTTPTools::ExtractFieldNameValue (string, nameString, fComment);
		}
		else if ((pos = HTTPTools::FindASCIICString (string, "=")))
		{
			HTTPTools::ExtractFieldNameValue (string, fName, fValue);
		}
	}
}
void VJSTimer::_SetTimer (VJSParms_callStaticFunction &ioParms, VJSWorker *inWorker, bool inIsInterval) 
{
	xbox_assert(inWorker != NULL);

	if (!ioParms.CountParams())
		
		return;

	XBOX::VJSContext	context(ioParms.GetContext());
	XBOX::VJSObject		functionObject(context);

	ioParms.GetParamObject(1, functionObject);
	if (!functionObject.IsFunction())

		return;

	functionObject.Protect();

	Real	duration;

	duration = 0.0;
	if (ioParms.CountParams() >= 2) {

		if (ioParms.IsNumberParam(2)) {
			
			if (!ioParms.GetRealParam(2, &duration))
			
				duration = 0.0;

		} else {

			// According to specification, if timeout is an object, call its toString() method if any. 
			// Then apply ToNumber() on the string to obtain duration.
			
			XBOX::VJSObject	timeOutObject(context);

			if (ioParms.GetParamObject(2, timeOutObject)) {

				timeOutObject.SetContext(context);
				if (timeOutObject.HasProperty("toString")) {

					XBOX::VJSObject	toStringObject = timeOutObject.GetPropertyAsObject("toString");

					if (toStringObject.IsFunction()) {

						std::vector<XBOX::VJSValue>	values;
						XBOX::VJSValue				string(context);

						toStringObject.SetContext(context);
						timeOutObject.CallFunction(toStringObject, &values, &string, NULL);

						if (string.IsString()) {

							// If Number() is called as a function (and not as a constructor), it acts as ToNumber().
							// See section 15.7.1 of ECMA-262 specification.

							XBOX::VJSObject	toNumberObject = context.GetGlobalObject().GetPropertyAsObject("Number");

							if (toNumberObject.IsFunction()) {

								XBOX::VJSValue	number(context);

								values.clear();
								values.push_back(string);
								toNumberObject.SetContext(context);
								context.GetGlobalObject().CallFunction(toNumberObject, &values, &number, NULL);

								if (number.IsNumber() && !number.GetReal(&duration))

									duration = 0.0;

							}

						}

					}

				}

			}
		
		}

		// (value != value) is true if value is a NaN.

		if (duration < 0.0 || duration > XBOX::kMAX_Real || duration != duration)
		
			duration = 0.0;

	}	
	
	std::vector<XBOX::VJSValue> *arguments;

	arguments = new std::vector<XBOX::VJSValue>;
	for (sLONG i = 3; i <= ioParms.CountParams(); i++) 

		arguments->push_back(ioParms.GetParamValue(i));

	sLONG		period, id;
	VJSTimer	*timer;

	period = (sLONG) duration;
	if (inIsInterval) {

		if (period < VJSTimer::kMinimumInterval)

			period = VJSTimer::kMinimumInterval;

	} else {

		if (period < VJSTimer::kMinimumTimeout)

			period = VJSTimer::kMinimumTimeout;

	}		 
	timer = new VJSTimer(functionObject, inIsInterval ? period : VJSTimer::kTimeOut);
	if ((id = inWorker->GetTimerContext()->InsertTimer(timer)) < 0) {

		// Too many timers (should never happen). Silently ignore. 
		// Returned ID (-1) isn't valid and a clear on it, will do nothing.

		timer->Release();
		delete arguments;
	
	} else {

		XBOX::VTime	triggerTime;
	
		triggerTime.FromSystemTime();
		triggerTime.AddMilliseconds(period);

		inWorker->QueueEvent(VJSTimerEvent::Create(timer, triggerTime, arguments));

	}

	ioParms.ReturnNumber(id);
}