XBOX::VError AddProcessingHandler (std::map<XBOX::VRefPtr<XBOX::VRegexMatcher>, XBOX::VRefPtr<Type> >& ioMap, Type *inProcessHandler)
{
	if (NULL == inProcessHandler)
		return VE_HTTP_INVALID_ARGUMENT;

	XBOX::VError error = VE_PROCESSING_HANDLER_ALREADY_EXISTS;

	if (!ProcessingHandlerExists (ioMap, inProcessHandler))
	{
		XBOX::VectorOfVString	patterns;
		XBOX::VRefPtr<Type>		processHandler = inProcessHandler;

		processHandler->GetPatterns (&patterns);
		for (XBOX::VectorOfVString::iterator it = patterns.begin(); it != patterns.end(); ++it)
		{
			error = XBOX::VE_OK;
			XBOX::VRegexMatcher *matcher = XBOX::VRegexMatcher::Create ((*it), &error);

			if (NULL != matcher)
			{
				if (XBOX::VE_OK == error)
				{
					ioMap[matcher] = processHandler.Get();
				}
				else
				{
					XBOX::QuickReleaseRefCountable (matcher);
				}
			}
		}
	}

	return error;
}
XBOX::VError VHTTPServerProject::AddHTTPRequestHandler (IHTTPRequestHandler *inRequestHandler)
{
	if (NULL == inRequestHandler)
		return VE_HTTP_INVALID_ARGUMENT;

	XBOX::VRefPtr<IHTTPRequestHandler> requestHandler = inRequestHandler;
	XBOX::VTaskLock lock (&fRequestHandlersLock);
	XBOX::VError	error = XBOX::VE_OK;

	VectorOfRequestHandler::iterator	iterHandlers = fRequestHandlers.begin();
	VectorOfRequestHandler::iterator	foundHandler = fRequestHandlers.end();

	while (iterHandlers != fRequestHandlers.end())
	{
		foundHandler = std::find_if (fRequestHandlers.begin(), fRequestHandlers.end(), FindMatchingRequestHandlerFunctor (requestHandler.Get()));
		if (foundHandler != fRequestHandlers.end())
			break;
		++iterHandlers;
	}

	if (foundHandler == fRequestHandlers.end())
	{
		XBOX::VectorOfVString handlerPatterns;

		requestHandler->GetPatterns (&handlerPatterns);
		for (XBOX::VectorOfVString::iterator it = handlerPatterns.begin(); it != handlerPatterns.end(); ++it)
		{
			XBOX::VString			patternString (*it);
			XBOX::VRegexMatcher *	matcher = NULL;
			
			error = _BuildRegexMatcher (*it, &matcher);

			if (NULL != matcher)
			{
				if (XBOX::VE_OK == error)
				{
					fRegexCache[matcher] = requestHandler.Get();
				}
				else
				{
					XBOX::QuickReleaseRefCountable (matcher);
				}
			}
		}

		fRequestHandlers.push_back (requestHandler.Get());
	}
	else
	{
		return VE_HTTP_REQUEST_HANDLER_ALREADY_EXISTS;
	}

	return error;
}
void VHTTPServerProjectSettings::SetLogFormat (const XBOX::VString& inLogFormatName, const XBOX::VectorOfVString& inLogTokensNames)
{
	VectorOfLogToken logTokens;
	
	for (VectorOfVString::const_iterator iter = inLogTokensNames.begin() ; iter != inLogTokensNames.end() ; ++iter)
	{
		EHTTPServerLogToken token = HTTPServerTools::GetLogTokenFromName( *iter);
		if (token != LOG_TOKEN_NONE)
			AppendUniqueValueToVector( logTokens, token);
	}

	SetLogFormat( HTTPServerTools::GetLogFormatFromName (inLogFormatName), &logTokens);
}
XBOX::VError VRemoteDebugPilot::BreakpointReached(
											OpaqueDebuggerContext		inContext,
											int							inLineNumber,
											RemoteDebuggerPauseReason	inDebugReason,
											XBOX::VString&				inException,
											XBOX::VString&				inSourceUrl,
											XBOX::VectorOfVString&		inSourceData)
{

	VError	err = VE_INVALID_PARAMETER;

	XBOX::VSemaphore*	sem = NULL;
	VContextDebugInfos	debugInfos;
	
	debugInfos.fFileName = inSourceUrl;

	VURL::Decode( debugInfos.fFileName );
	VIndex				idx = debugInfos.fFileName.FindUniChar( L'/', debugInfos.fFileName.GetLength(), true );
	if (idx  > 1)
	{
		VString			tmpStr;
		debugInfos.fFileName.GetSubString(idx+1,debugInfos.fFileName.GetLength()-idx,tmpStr);
		debugInfos.fFileName = tmpStr;
	}

	debugInfos.fLineNb = inLineNumber+1;
	debugInfos.fReason = ( inDebugReason == EXCEPTION_RSN ? "exception" : (inDebugReason == BREAKPOINT_RSN ? "breakpoint" : "dbg statement" ) );
	debugInfos.fComment = "To Be Completed";
	debugInfos.fSourceLine = ( inLineNumber < inSourceData.size() ? inSourceData[inLineNumber] : " NO SOURCE AVAILABLE  " );
	err = ContextUpdated(inContext,debugInfos,&sem);

	if (err == VE_OK)
	{
		fPendingContextsNumberSem.Unlock();
		// if sem not NULL then wait for a browser page granted for debug
		if (sem)
		{
			sem->Lock();
			ReleaseRefCountable(&sem);
		}

		RemoteDebugPilotMsg_t	msg;
		msg.type = BREAKPOINT_REACHED_MSG;
		msg.ctx = inContext;
		msg.linenb = inLineNumber;
		msg.datavectstr = inSourceData;
		msg.datastr = inException;
		msg.urlstr = inSourceUrl;
		err = Send( msg );
		//testAssert(err == VE_OK);
		fPendingContextsNumberSem.Lock();
	}
	VString trace = VString("VRemoteDebugPilot::BreakpointReached ctx activation pb for ctxid=");
	trace.AppendLong8((unsigned long long)inContext);
	trace += " ,ok=";
	trace += (!err ? "1" : "0" );
	sPrivateLogHandler->Put( (err ? WAKDBG_ERROR_LEVEL : WAKDBG_INFO_LEVEL),trace);

	return err;
}
bool ProcessingHandlerExists (std::map<XBOX::VRefPtr<XBOX::VRegexMatcher>, XBOX::VRefPtr<Type> >& ioMap, Type *inProcessHandler)
{
	if ((NULL == inProcessHandler) || (0 == ioMap.size()))
		return false;

	XBOX::VectorOfVString	patterns;

	inProcessHandler->GetPatterns (&patterns);
	for (XBOX::VectorOfVString::iterator it = patterns.begin(); it != patterns.end(); ++it)
	{
		typename std::map<XBOX::VRefPtr<XBOX::VRegexMatcher>, XBOX::VRefPtr<Type> >::iterator found = std::find_if (ioMap.begin(), ioMap.end(), EqualVRegexMatcherFunctor<XBOX::VRefPtr<Type> > (*it));
		if (ioMap.end() != found)
			return true;
	}

	return false;
}
bool VHTTPResponse::IsCookieSet (const XBOX::VString& inName) const
{
	XBOX::VectorOfVString cookieValues;

	if (GetHeaders().GetHeaderValues (HEADER_SET_COOKIE, cookieValues))
	{
		XBOX::VString cookieName (inName);
		cookieName.AppendUniChar (CHAR_EQUALS_SIGN);

		for (XBOX::VectorOfVString::const_iterator it = cookieValues.begin(); it != cookieValues.end(); ++it)
		{
			if (HTTPServerTools::FindASCIIVString ((*it), cookieName) > 0)
				return true;
		}
	}

	return false;
}
bool VHTTPResponse::IsCookieSet (const VHTTPCookie& inCookie) const
{
	XBOX::VectorOfVString	cookieValues;
	
	if (GetHeaders().GetHeaderValues (HEADER_SET_COOKIE, cookieValues))
	{
		XBOX::VString cookieName (inCookie.GetName());
		cookieName.AppendUniChar (CHAR_EQUALS_SIGN);
		
		for (XBOX::VectorOfVString::const_iterator it = cookieValues.begin(); it != cookieValues.end(); ++it)
		{
			XBOX::VectorOfVString multipleCookieValues;

			(*it).GetSubStrings (CHAR_SEMICOLON, multipleCookieValues, false, true);

			XBOX::VectorOfVString::const_iterator found = std::find_if (multipleCookieValues.begin(), multipleCookieValues.end(), FindVStringFunctor (cookieName));
			if (found != multipleCookieValues.end())
			{
				VHTTPCookie cookie (*found);
				if (cookie == inCookie)
					return true;
			}
		}
	}

	return false;
}
void VHTTPServerProject::SaveToBag (XBOX::VValueBag& outBag)
{
	outBag.SetLong (NSHTTPServerProject::refCount, GetRefCount());
	outBag.SetLong (NSHTTPServerProject::taskID, fServerTaskID);
	outBag.SetTime (NSHTTPServerProject::startingTime, fStartingTime);
	outBag.SetBool (NSHTTPServerProject::acceptRequests, fAcceptIncommingRequests);
	outBag.SetLong (NSHTTPServerProject::hitCount, GetHitsCount());
	outBag.SetLong (NSHTTPServerProject::runningRequests, GetRunningRequestsCount());
	outBag.SetBool (NSHTTPServerProject::securityComponentAvailable, (NULL != fSecurityManager));
	outBag.SetBool (NSHTTPServerProject::authenticationManagerAvailable, (NULL != fAuthenticationManager));

	XBOX::VBagArray *bagArray = new XBOX::VBagArray();
	if (NULL != bagArray)
	{
		XBOX::VTaskLock lock (&fRequestHandlersLock);
		for (VectorOfRequestHandler::const_iterator it = fRequestHandlers.begin(); it != fRequestHandlers.end(); ++it)
		{
			XBOX::VString string;
			XBOX::VectorOfVString patterns;
			(*it)->GetPatterns (&patterns);

			for (XBOX::VectorOfVString::const_iterator itString = patterns.begin(); itString != patterns.end(); ++itString)
			{
				string.AppendString (*itString);
				string.AppendUniChar (CHAR_SEMICOLON);
			}

			XBOX::VValueBag *handlerBag = new XBOX::VValueBag();
			if (NULL != handlerBag)
			{
				handlerBag->SetLong (NSHTTPServerProject::requestHandlers::refCount, (*it)->GetRefCount());
				handlerBag->SetString (NSHTTPServerProject::requestHandlers::patterns, string);
				handlerBag->SetBool (NSHTTPServerProject::requestHandlers::enabled, (*it)->GetEnable());
				bagArray->AddTail (handlerBag);
				XBOX::QuickReleaseRefCountable (handlerBag);
			}
		}

		outBag.SetElements (L"requestHandlers", bagArray);
		XBOX::QuickReleaseRefCountable (bagArray);
	}

	XBOX::VValueBag *settingsBag = new XBOX::VValueBag();
	if (NULL != settingsBag)
	{
		fSettings->SaveToBag (settingsBag);
		outBag.AddElement (L"settings", settingsBag);
		XBOX::QuickReleaseRefCountable (settingsBag);
	}

	XBOX::VValueBag *serverBag = new XBOX::VValueBag();
	if (NULL != serverBag)
	{
		serverBag->SetLong (NSHTTPServerProject::serverInfos::refCount, fHTTPServer->GetRefCount());
		serverBag->SetBool (NSHTTPServerProject::serverInfos::zipComponentAvailable, fHTTPServer->GetZipComponentAvailable());

		outBag.AddElement (L"server", serverBag);
		XBOX::QuickReleaseRefCountable (serverBag);
	}

	bagArray = new XBOX::VBagArray();
	if (NULL != bagArray)
	{
		XBOX::VTaskLock lock (&fVirtualHostsLock);
		for (std::vector<VVirtualHost *>::const_iterator it = fVirtualHosts.begin(); it != fVirtualHosts.end(); ++it)
		{
			XBOX::VValueBag *virtualHostBag = new XBOX::VValueBag();
			if (NULL != virtualHostBag)
			{
				(*it)->SaveToBag (*virtualHostBag);
				bagArray->AddTail (virtualHostBag);
				XBOX::QuickReleaseRefCountable (virtualHostBag);
			}
		}

		outBag.SetElements (L"virtualHosts", bagArray);
		XBOX::QuickReleaseRefCountable (bagArray);
	}

	bagArray = new XBOX::VBagArray();
	if (NULL != bagArray)
	{
		if ((NULL != fAuthenticationManager) && (NULL != fAuthenticationManager->GetAuthenticationReferee()))
		{
			XBOX::VValueBag *authResourcesBag = new XBOX::VValueBag();
			if (NULL != authResourcesBag)
			{
				fAuthenticationManager->GetAuthenticationReferee()->SaveToBag (authResourcesBag);
				bagArray->AddTail (authResourcesBag);
				XBOX::QuickReleaseRefCountable (authResourcesBag);
			}
		}

		if (bagArray->GetCount() > 0)
			outBag.SetElements (L"authResources", bagArray);

		XBOX::QuickReleaseRefCountable (bagArray);
	}
}
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);
		}
	}
}