XBOX::VError VHTTPServerLog::_WriteFileHeader (XBOX::VString& ioBuffer)
{
	/*
		see: http://www.w3.org/TR/WD-logfile.html
	*/
	XBOX::VString	serverName;
	XBOX::VString	dateString;
	XBOX::VString	formatName;
	XBOX::VString	tokenNames;

	fNeedHeader = false;
	/*
		#Version: 1.0
		#Date: 12-Jan-1996 00:00:00
	*/
	HTTPProtocol::MakeServerString (serverName);
	_GetCurrentFormatedDate (dateString);
	HTTPServerTools::GetLogFormatName (fSettings.GetLogFormat(), formatName);
	HTTPServerTools::GetLogTokenNamesList (fSettings.GetLogTokens(), tokenNames);

	ioBuffer.AppendCString ("#Version: 1.0\n#Software: ");
	ioBuffer.AppendString (serverName);
	ioBuffer.AppendCString ("\n#Date: ");
	ioBuffer.AppendString (dateString);

	ioBuffer.AppendCString ("\n#Remark: format ");
	ioBuffer.AppendString (formatName);

	ioBuffer.AppendCString ("\n#Fields: ");
	ioBuffer.AppendString (tokenNames);

	ioBuffer.AppendUniChar (HTTP_LF);

	return XBOX::VE_OK;
}
	bool HttpRequest::SetUserInfos(const XBOX::VString& inUser, const XBOX::VString& inPasswd, bool inAllowBasic)
	{
		if(!fHandle)
            return false;
		
		XBOX::VString userInfos;
		userInfos.AppendString(inUser).AppendCString(":").AppendString(inPasswd);
	
		int maxlen=2*userInfos.GetLength()+1;  //We convert utf16 to utf8, it should be large enough.
        char* buf=new char[maxlen];
		
        if(!buf)
            return false;
		
		int len=userInfos.ToBlock(buf, maxlen, XBOX::VTC_UTF_8, true, false);
		
		curl_easy_setopt(fHandle, CURLOPT_USERPWD, buf);
		
		delete buf;
		
		if(inAllowBasic)
			curl_easy_setopt(fHandle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC|CURLAUTH_DIGEST);
		else	
			curl_easy_setopt(fHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
		
		return true;
	}
void VHTTPServerLog::_WriteUsername (const XBOX::VString& inUserName, XBOX::VString& ioStream)
{
	if (!inUserName.IsEmpty())
	{
		bool			wasCtrl = false;
		XBOX::VString	userName;

		for (XBOX::VIndex pos = 0; pos < inUserName.GetLength(); ++pos)
		{
			// When user name contains CHAR_SPACE, replace it by CHAR_LOW_LINE '_'
			if ((inUserName[pos] <= CHAR_SPACE) && (inUserName[pos] > 0))
			{
				if (!wasCtrl)
					userName.AppendUniChar (CHAR_LOW_LINE);
				wasCtrl = (inUserName[pos] != CHAR_SPACE);
			}
			else
			{
				userName.AppendUniChar (inUserName[pos]);
				wasCtrl = false;
			}
		}

		ioStream.AppendString (userName);
	}
	else
	{
		ioStream.AppendUniChar (CHAR_HYPHEN_MINUS);
	}
}
IHTTPRequestHandler *VHTTPServerProject::RetainMatchingHTTPRequestHandler (const XBOX::VString& inURL)
{
	IHTTPRequestHandler *resultHandler = NULL;
	XBOX::VTaskLock		lock (&fRegexCacheLock);
	XBOX::VString		urlString (inURL);
/*
	// URL Start with project pattern ?
	if (!fSettings->GetProjectPattern().IsEmpty())
	{
		sLONG pos = HTTPServerTools::FindASCIIVString (urlString, fSettings->GetProjectPattern());
		if (pos == 2) // Takes the starting CHAR_SOLIDUS into account
			inURL.GetSubString (pos + fSettings->GetProjectPattern().GetLength(), inURL.GetLength() - fSettings->GetProjectPattern().GetLength() - 1, urlString);
	}
*/

	resultHandler = RetainProcessingHandler<IHTTPRequestHandler> (fRegexCache, urlString, false);

	/* YT 18-Jan-2012 - ACI0075015, ACI0074936 & ACI0074300
		When no requestHandler match and the URL ends by SOLIDUS '/', try to find a requestHandler matching the URL + 
		the index page name (typically for 4D: /index.shtml have to be handled by a specific requestHandler)
	*/
	if ((NULL == resultHandler) && (urlString.GetUniChar (urlString.GetLength()) == CHAR_SOLIDUS))
	{
		urlString.AppendString (fSettings->GetIndexPageName());

		resultHandler = RetainProcessingHandler<IHTTPRequestHandler> (fRegexCache, urlString, false);
	}

	return resultHandler;
}
XBOX::VError VHTTPServerProject::_BuildRegexMatcher (const XBOX::VString& inPatternString, XBOX::VRegexMatcher **outMatcher)
{
	if (NULL == outMatcher)
		return XBOX::VE_INVALID_PARAMETER;

	XBOX::VString	patternString (inPatternString);
	XBOX::VError	error = XBOX::VE_OK;
	sLONG			pos = 0;

	if (!HTTPServerTools::BeginsWithASCIICString (patternString.GetCPointer(), "(?i)"))
		patternString.Insert (CVSTR ("(?i)"), 1);

	if (HTTPServerTools::EndsWithASCIICString (patternString, "/") &&
		!HTTPServerTools::EndsWithASCIICString (patternString, "$"))
		patternString.AppendString (CVSTR (".*"));

	XBOX::VString string;

	if ((pos = patternString.FindUniChar (CHAR_CIRCUMFLEX_ACCENT)) == 0)
	{
		string.FromCString ("^");
		pos = HTTPServerTools::FindASCIICString (patternString, "(?i)") + 4;
	}
	else
	{
		++pos;
	}

#if HTTP_SERVER_USE_PROJECT_PATTERNS
	if (!fSettings->GetProjectPattern().IsEmpty())
	{
		string.AppendCString ("(/");
		string.AppendString (fSettings->GetProjectPattern());
		string.AppendCString ("|)");
	}
#endif

	patternString.Insert (string, pos);

	if (!patternString.IsEmpty())
		*outMatcher = XBOX::VRegexMatcher::Create (patternString, &error);

	return error;
}
XBOX::VError VHTTPResponse::_SendResponseHeader()
{
	if (fHeaderSent)
		return XBOX::VE_OK; // Not sure we have to report the error

	_NormalizeResponseHeader();

	// Write Status-Line
	XBOX::VString string;
	XBOX::VString fieldValue;

	HTTPProtocol::MakeStatusLine (fHTTPVersion, fResponseStatusCode, string);

	/* Write Server Header */
	if (GetHeaders().IsHeaderSet (STRING_HEADER_SERVER))
		GetHeaders().RemoveHeader (STRING_HEADER_SERVER);

	HTTPProtocol::MakeServerString (fieldValue, false, true);
	string.AppendString (fieldValue);
	string.AppendCString (HTTP_CRLF);

	/* Write Date Header */
	if (!GetHeaders().IsHeaderSet (STRING_HEADER_DATE))
	{
		HTTPProtocol::MakeRFC822GMTDateString (GMT_NOW, fieldValue, true);
		string.AppendString (fieldValue);
		string.AppendCString (HTTP_CRLF);
	}

	// Write Headers
	GetHeaders().ToString (string);
	string.AppendCString (HTTP_CRLF);

	XBOX::StStringConverter<char>	converter (string, XBOX::VTC_UTF_8);
	char *							buffer = (char *)converter.GetCPointer();
	uLONG							bufferSize = (uLONG)converter.GetSize();
	XBOX::VError					error = _WriteToSocket (buffer, &bufferSize);

	fHeaderSent = (XBOX::VE_OK == error);

	return error;
}
void MakeHostString (const XBOX::VString& inHost, PortNumber inPort, XBOX::VString& outHostString)
{
	outHostString.Clear();

	if (!inHost.IsEmpty())
		outHostString.AppendString (inHost);

	if (inPort != DEFAULT_LISTENING_PORT)
	{
		outHostString.AppendUniChar (CHAR_COLON);
		outHostString.AppendLong (inPort);
	}
}
/* private */
void VVirtualFolder::_NormalizeFolder()
{
	assert (NULL != fFolder);

	if (!fFolder->Exists())
		fFolder->CreateRecursive();

	if (fFolder->Exists())
	{
		XBOX::VFilePath folderPath (fFolder->GetPath());
		XBOX::VFilePath indexPath;

		indexPath = folderPath.ToSubFile (fIndexFileName);

		if (indexPath.IsFile())
		{
			XBOX::VFile indexFile (indexPath);

			if (!indexFile.Exists())
			{
				XBOX::VFolder *componentFolder = VHTTPServer::RetainComponentFolder (kBF_RESOURCES_FOLDER);

				if (NULL != componentFolder)
				{
					XBOX::VFilePath		defaultIndexPath = componentFolder->GetPath();
					XBOX::DialectCode	dialectCode = XBOX::VIntlMgr::GetDefaultMgr()->GetCurrentDialectCode();
					XBOX::VString		languageCode;
					XBOX::VString		fileName;

					XBOX::VIntlMgr::GetDefaultMgr()->GetISO6391LanguageCode (dialectCode, languageCode);

					fileName.AppendCString ("index_");
					fileName.AppendString (languageCode);
					fileName.AppendCString (".html");

					defaultIndexPath.ToSubFolder (CVSTR ("Default Page")).ToSubFile (fileName);

					if (defaultIndexPath.IsFile())
					{
						XBOX::VFile defaultIndexFile (defaultIndexPath);

						if (defaultIndexFile.Exists())
							indexFile.CopyFrom (defaultIndexFile);
					}

					XBOX::QuickReleaseRefCountable (componentFolder);
				}
			}
		}
	}
}
void GetLogTokenNamesList (const VectorOfLogToken& inLogTokens, XBOX::VString& outTokenNames, const UniChar inSeparator)
{
	XBOX::VString						string;
	VectorOfLogToken::const_iterator	nextToken = inLogTokens.begin();

	outTokenNames.Clear();

	for (VectorOfLogToken::const_iterator it = inLogTokens.begin(); it != inLogTokens.end(); ++it)
	{
		GetLogTokenName (*it, string);
		outTokenNames.AppendString (string);
		nextToken = it; 
		if (++nextToken != inLogTokens.end())
			outTokenNames.AppendUniChar (CHAR_SPACE);
	}
}
void VJSRequireClass::_evaluate (VJSParms_callStaticFunction &ioParms, void *)
{
	XBOX::VJSContext	context(ioParms.GetContext());
	XBOX::VString		fullPath;
	XBOX::VJSObject		exportsObject(context), moduleObject(context);

	if (!ioParms.GetStringParam(1, fullPath)) {
		
		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_STRING, "1");
		return;

	}

	if (!ioParms.GetParamObject(2, exportsObject)) {

		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_OBJECT, "2");
		return;

	}

	if (!ioParms.GetParamObject(3, moduleObject)) {

		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_OBJECT, "3");
		return;

	}

	XBOX::VError	error;
	XBOX::VURL		url;
	XBOX::VString	script;
		
	if ((error = VJSModuleState::LoadScript(fullPath, &url, &script)) != XBOX::VE_OK) {

		if (error == XBOX::VE_JVSC_SCRIPT_NOT_FOUND) {

			// Should not happen as require() does already check for existence.

			XBOX::vThrowError(XBOX::VE_JVSC_SCRIPT_NOT_FOUND, fullPath);

		} else

			XBOX::vThrowError(error);
			
	} else {

		XBOX::VFilePath	path(fullPath, FPS_POSIX);
		XBOX::VFile		*file;
			
		if ((file = new XBOX::VFile(path)) == NULL) {

			XBOX::vThrowError(XBOX::VE_MEMORY_FULL);
			
		} else {

			context.GetGlobalObjectPrivateInstance()->RegisterIncludedFile(file);

			XBOX::VString				functionScript;
			XBOX::VJSValue				functionResult(context);
			XBOX::JS4D::ExceptionRef	exception;			

			// Make a function of the module script, then call it.
			
			functionScript.AppendString("(function (exports, module) {");
			functionScript.AppendString(script);
			functionScript.AppendString("})");

			if (!context.EvaluateScript(functionScript, &url, &functionResult, &exception)) {
						
				ioParms.SetException(exception);	// Syntax error.

			} else {

				xbox_assert(functionResult.IsFunction());

				XBOX::VJSObject				functionObject(context);
				std::vector<XBOX::VJSValue>	arguments;
				XBOX::VJSValue				result(context);

				functionObject.SetObjectRef((XBOX::JS4D::ObjectRef) functionResult.GetValueRef());
	
				arguments.push_back(exportsObject);
				arguments.push_back(moduleObject);

				if (!context.GetGlobalObject().CallFunction(functionObject, &arguments, &result, &exception, &path)) 

					ioParms.SetException(exception);

				else 

					ioParms.ReturnValue(result);

			}

			XBOX::ReleaseRefCountable<XBOX::VFile>(&file);

		}

	}	
}
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;
}
XBOX::VError VHTTPMessage::ReadFromStream (XBOX::VStream& inStream, const XBOX::VString& inBoundary)
{
#define	MAX_BUFFER_LENGTH	32768

	const char			HTTP_CR = '\r';
	const char			HTTP_LF = '\n';
	const char			HTTP_CRLF [] = { HTTP_CR, HTTP_LF, 0 };
	const char			HTTP_CRLFCRLF [] = { HTTP_CR, HTTP_LF, HTTP_CR, HTTP_LF, 0 };

	XBOX::VError		streamError = XBOX::VE_OK;
	HTTPParsingState	parsingState;
	XBOX::VError		parsingError = XBOX::VE_OK;
	XBOX::VSize			bufferSize = MAX_BUFFER_LENGTH;
	char *				buffer = (char *)XBOX::vMalloc (bufferSize, 0);
	XBOX::VSize			bufferOffset = 0;
	XBOX::VSize			unreadBytes = 0;
	sLONG				lineLen = 0;
	XBOX::VString		header;
	XBOX::VString		value;
	char *				startLinePtr = NULL;
	char *				endLinePtr = NULL;
	char *				endHeaderPtr = NULL;
	sLONG				endLineSize = sizeof (HTTP_CRLF) - 1;
	sLONG				contentLength = 0;
	void *				bodyContentBuffer = NULL;
	XBOX::VSize			bodyContentSize = 0;
	const sLONG			MAX_REQUEST_ENTITY_SIZE = XBOX::MaxLongInt;
	XBOX::VString		boundaryEnd;
	char *				boundary = NULL;
	bool				stopReadingStream = false;

	if (!inBoundary.IsEmpty())
	{
		boundaryEnd.AppendString ("--");
		boundaryEnd.AppendString (inBoundary);
		boundary = new char[boundaryEnd.GetLength() + 1];
		if (NULL != boundary)
			boundaryEnd.ToCString (boundary, boundaryEnd.GetLength() + 1);
	}

	if (NULL == buffer)
		return XBOX::VE_MEMORY_FULL;

	parsingState = PS_ReadingHeaders;

	XBOX::StErrorContextInstaller errorContext (XBOX::VE_STREAM_EOF, XBOX::VE_OK);

	bool isAlreadyReading = inStream.IsReading();

	if (!isAlreadyReading)
		streamError = inStream.OpenReading();

	while ((XBOX::VE_OK == streamError) && !stopReadingStream)
	{
		if (0 == unreadBytes)
			bufferOffset = 0;

		bufferSize = MAX_BUFFER_LENGTH - bufferOffset;

		streamError = inStream.GetData (buffer + bufferOffset, &bufferSize);

		unreadBytes = (bufferSize + bufferOffset);
		bufferOffset = 0;

		while ((unreadBytes > 0) && (XBOX::VE_OK == parsingError))
		{
			if (parsingState <= PS_ReadingHeaders)
			{
				startLinePtr = buffer + bufferOffset;
				endLinePtr = strstr (startLinePtr, HTTP_CRLF);

				if ((NULL != endLinePtr) && (NULL == endHeaderPtr))
					endHeaderPtr = strstr (startLinePtr, HTTP_CRLFCRLF);
			}

			/* Start to parse the Status-Line */
			switch (parsingState)
			{
			case PS_ReadingHeaders:
				{
					if (NULL != endLinePtr)
					{
						if (startLinePtr != (endHeaderPtr + endLineSize))
						{
							if (_ExtractHeaderValuePair (startLinePtr, endLinePtr, header, value))
							{
								GetHeaders().SetHeaderValue (header, value, false);
							}
						}

						else /*if (startLinePtr == endHeaderPtr)*/
						{
							parsingState = PS_ReadingBody;
							XBOX::VString contentLengthString;
							if (GetHeaders().GetHeaderValue (STRING_HEADER_CONTENT_LENGTH, contentLengthString))
								contentLength = HTTPTools::GetLongFromString (contentLengthString);
						}
					}
					break;
				}

			case PS_ReadingBody:
				{
					if (!boundaryEnd.IsEmpty())
					{
						if (NULL != boundary)
						{
							char *endBoundaryPtr = memstr (buffer + bufferOffset, unreadBytes, boundary, strlen (boundary));
							if (NULL != endBoundaryPtr)
							{
								XBOX::VSize nbBytesToCopy  = (endBoundaryPtr - (buffer + bufferOffset));
								inStream.UngetData (endBoundaryPtr, unreadBytes - nbBytesToCopy);
								unreadBytes = nbBytesToCopy;
								if (NULL != memstr (endBoundaryPtr - 2, 2, HTTP_CRLF, 2))
									unreadBytes -= 2;	// Skip CRLF after boundary part
								stopReadingStream = true;
							}
						}
					}

					if (NULL == bodyContentBuffer)
					{
						// There's no Content-Length field in header
						if (0 == contentLength)
						{
							bodyContentBuffer = XBOX::vMalloc (bufferSize, 0);
							bodyContentSize = 0;
						}
						// There's one Content-Length, just check it match limits
						else if ((contentLength > 0) && (contentLength < MAX_REQUEST_ENTITY_SIZE))
						{
							bodyContentBuffer = XBOX::vMalloc (contentLength, 0);
							bodyContentSize = 0;
						}
					}

					if ((NULL != bodyContentBuffer) && (bodyContentSize + unreadBytes < MAX_REQUEST_ENTITY_SIZE))
					{
						XBOX::VSize nbBytesToCopy = unreadBytes;
						if (bodyContentSize + nbBytesToCopy > contentLength)
							bodyContentBuffer = XBOX::vRealloc (bodyContentBuffer, bodyContentSize + nbBytesToCopy);

						memcpy ((char *)(bodyContentBuffer) + bodyContentSize, buffer + bufferOffset, unreadBytes);
						bodyContentSize += unreadBytes;
						bufferOffset = unreadBytes = 0;
					}
					else
					{
						parsingError = XBOX::VE_MEMORY_FULL;

						if (NULL != bodyContentBuffer)
						{
							XBOX::vFree (bodyContentBuffer);
							bodyContentBuffer = NULL;
						}
					}
					break;
				}
			}

			if (XBOX::VE_OK != parsingError)
				break;

			if (NULL != endLinePtr)
			{
				lineLen = (endLinePtr - startLinePtr) + endLineSize; // to skip CRLF;
				bufferOffset += lineLen;
				unreadBytes -= lineLen;
				endLinePtr = NULL;
			}
			else
			{
				if (bufferOffset > 0)
				{
					memmove (buffer, buffer + bufferOffset, unreadBytes);
					buffer[unreadBytes] = 0;
				}
				bufferOffset = unreadBytes;
				break;
			}
		}

		if (XBOX::VE_OK != parsingError)
			break;
	}

	if (!isAlreadyReading)
		inStream.CloseReading();

	if (XBOX::VE_STREAM_EOF == streamError)
		streamError = XBOX::VE_OK;

	if (!parsingError && !streamError)
	{
		if (NULL != bodyContentBuffer)
		{
#if VERSIONDEBUG
			if ((contentLength > 0) && (bodyContentSize != contentLength))
				assert (false);
#endif
			GetBody().SetDataPtr (bodyContentBuffer, bodyContentSize);

			XBOX::VString	contentType;
			XBOX::CharSet	charSet = XBOX::VTC_UNKNOWN;

			/* Set VStream charset according to content-type header other else set default charset to UTF-8 */
			if ((!GetHeaders().GetContentType (contentType, &charSet)) || (XBOX::VTC_UNKNOWN == charSet))
				charSet = XBOX::VTC_UTF_8;
			GetBody().SetCharSet (charSet);
		}

		parsingState = PS_ParsingFinished;
	}
	else
	{
		if (NULL != bodyContentBuffer)
			XBOX::vFree (bodyContentBuffer);
	}

	delete [] boundary;
	boundary = NULL;

	XBOX::vFree (buffer);
	buffer = NULL;

	return streamError;

#undef MAX_BUFFER_LENGTH
}
Example #13
0
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;
}
Example #14
0
XBOX::VError VRPCService::GetProxy( XBOX::VString& outProxy, const XBOX::VString& inModulePath, const XBOX::VString& inNamespace, const IHTTPRequest* inRequest, IHTTPResponse* inResponse)
{
	VError err = VE_OK;

	outProxy.Clear();

	if (fApplication != NULL)
	{
		VRIAContext *riaContext = fApplication->RetainNewContext( err);
		if (err == VE_OK)
		{
			VRPCCatalog *catalog = fApplication->RetainRPCCatalog( riaContext, &err, inRequest, inResponse);
			if (err == VE_OK)
			{
				if (catalog != NULL)
				{
					MapOfRPCSchema schemas;

					err = catalog->RetainSchemasByModule( inModulePath, schemas);
					if (err == VE_OK)
					{
						// Build the proxy
						VFile *bodyFile = NULL, *templateFile = NULL;
						VFilePath path;

						VRIAServerApplication::Get()->GetWAFrameworkFolderPath( path);
						path.ToSubFolder( L"Core").ToSubFolder( L"Runtime").ToSubFolder( L"rpcService");
						path.SetFileName( L"proxy-body.js", true);

						bodyFile = new VFile( path);
						if (bodyFile == NULL)
							err = vThrowError( VE_MEMORY_FULL);
						
						if (err == VE_OK)
						{
							path.SetFileName( L"proxy-template.js", true);
							templateFile = new VFile( path);
							if (templateFile == NULL)
								err = vThrowError( VE_MEMORY_FULL);
						}
						
						if (err == VE_OK && bodyFile->Exists() && templateFile->Exists())
						{
							VString templateString;
							VFileStream bodyStream( bodyFile);
							VFileStream templateStream( templateFile);
							
							err = bodyStream.OpenReading();
							if (err == VE_OK)
								templateStream.OpenReading();
							if (err == VE_OK)
								err = bodyStream.GetText( outProxy);
							if (err == VE_OK)
							{
								VValueBag bag;
								bag.SetString( L"rpc-pattern", fPatternForMethods);
								bag.SetString( L"publishInGlobalNamespace", (fPublishInClientGlobalNamespace) ? L"true" : L"false");
								outProxy.Format( &bag);
							}
							if (err == VE_OK)
								err = templateStream.GetText( templateString);
							if (err == VE_OK)
							{
								if (templateString.BeginsWith( L"/*"))
								{
									// sc 28/08/2014, remove the copyright
									VIndex end = templateString.Find( L"*/");
									if (end > 0)
									{
										templateString.Remove( 1, end + 1);
									}
								}

								for (MapOfRPCSchema::const_iterator iter = schemas.begin() ; iter != schemas.end() ; ++iter)
								{
									VValueBag bag;
									bag.SetString( L"function-name", iter->first.GetMethodName());
									bag.SetString( L"namespace", inNamespace);
									bag.SetString( L"modulePath", inModulePath);
									VString proxy( templateString);
									proxy.Format( &bag);
									outProxy.AppendString( proxy);
								}
							}

							bodyStream.CloseReading();
							templateStream.CloseReading();
						}
						else
						{
							err = vThrowError( VE_FILE_NOT_FOUND);
						}

						QuickReleaseRefCountable( bodyFile);
						QuickReleaseRefCountable( templateFile);
					}
				}
				else
				{
					err = vThrowError( VE_RIA_RPC_CATALOG_NOT_FOUND);
				}
			}
		}
		ReleaseRefCountable( &riaContext);
	}

	return err;	
}
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);
	}
}
XBOX::VError VVirtualFolder::GetFilePathFromURL (const XBOX::VString& inURL, XBOX::VString& outLocationPath)
{
	if (!fLocalFolder)
	{
		XBOX::VString URL (inURL);
		sLONG pos = HTTPServerTools::FindASCIIVString (URL, fName);

		if (pos > 0)
			URL.Remove (1, pos + fName.GetLength() - 1);

		if ((URL.GetLength() == 1) && (URL.GetUniChar (1) == CHAR_SOLIDUS) && (!fIndexFileName.IsEmpty()))
			URL.AppendString (fIndexFileName);
		
		outLocationPath.FromString (fLocationPath);
		if (outLocationPath.GetUniChar (outLocationPath.GetLength()) == CHAR_SOLIDUS)
			outLocationPath.Truncate (outLocationPath.GetLength() - 1);
		outLocationPath.AppendString (URL);

		return VE_HTTP_PROTOCOL_FOUND;
	}

	XBOX::VError	error = XBOX::VE_FILE_NOT_FOUND;
	XBOX::VFilePath	path (fFolder->GetPath());
	XBOX::VString	pathString (inURL);
	XBOX::VString	folder;
	XBOX::VString	docName;

	if ((pathString.GetLength() == 1) && (pathString.GetUniChar (1) == CHAR_SOLIDUS))
	{
		docName.FromString (fIndexFileName);
	}
	else
	{
		bool	notDone = true;
		sLONG	folderLen = 0;
		sLONG	pos = 0;
		sLONG	curPos = 0;

		// YT 16-Nov-2011 - ACI0073914
		if (pathString.FindUniChar (CHAR_COLON) > 0) // ':'
			pathString.ExchangeAll (CHAR_COLON, CHAR_SOLIDUS);

		if (pathString.FindUniChar (CHAR_REVERSE_SOLIDUS) > 0) // '\'
			pathString.ExchangeAll (CHAR_REVERSE_SOLIDUS, CHAR_SOLIDUS);

		while (notDone)
		{
			if ((pos = pathString.FindUniChar (CHAR_SOLIDUS, curPos + 1)) > 0)	// '/'
			{
				HTTPServerTools::GetSubString (pathString, curPos, pos - 2, folder);
				folderLen = folder.GetLength();
				if (folderLen > 0)
				{
					/* If URL first folder equals Virtual Folder Name or Project Pattern... Do nothing... */
					if ((curPos == 1) && !fName.IsEmpty() && HTTPServerTools::EqualASCIIVString (fName, folder))
						;
					/* YT 24-Feb-2011 - ACI0069901 - Project Pattern is already removed from URL in VHTTPResponse::_UpdateRequestURL()
					else if ((curPos == 1) && !fProjectPattern.IsEmpty() && HTTPServerTools::EqualASCIIVString (fProjectPattern, folder))
					{
						pathString.SubString (curPos + fProjectPattern.GetLength() + 1, pathString.GetLength() - fProjectPattern.GetLength() + 1); // YT 24-Nov-2010 - ACI0068942 - Remove Project Pattern from URL...
						folderLen = 0;
						curPos = -1;
					}
					*/
					else if ((folderLen == 2) && (folder[0] == CHAR_FULL_STOP) && (folder[1] == CHAR_FULL_STOP)) // ".."
						path = path.ToParent();
					else if  ((folderLen == 1) && (folder[0] == CHAR_FULL_STOP)) // "."
						;	// unchanged
					else
						path = path.ToSubFolder (folder);

					curPos += (folderLen + 1);
				}
				else
					curPos += 1;
			}
			else
				notDone = false;

			if (curPos >= pathString.GetLength())
				break;
		}
		
		if (curPos < pathString.GetLength())
			HTTPServerTools::GetSubString (pathString, curPos, pathString.GetLength() - 1, docName);
	}

	/* if URL does not include a filename, try using the index file name set in prefs */
	if (docName.IsEmpty())
		docName.FromString (fIndexFileName);

	path = path.ToSubFile (docName);

	/*
		at this stage path should contain a full path pointing to the wanted file
		check that this is inside the web folder (if it's a web connection)
	*/
	// SECURITY CHECK - change it with great care
	if (path.GetPath().BeginsWith (fFolder->GetPath().GetPath()))
	{
		outLocationPath.FromString (path.GetPath());
		error = VE_OK;
	}
	else
	{
		// UNDER ATTACK !!!
		path.Clear();
		error = VE_HTTP_PROTOCOL_FORBIDDEN;
	}

	return error;
}
XBOX::VError VMIMEMessage::ToStream (XBOX::VStream& outStream, sLONG inEncoding)
{
	XBOX::VError error = XBOX::VE_OK;

	if (XBOX::VE_OK == outStream.OpenWriting())
	{
		outStream.SetCarriageReturnMode(eCRM_CRLF);
		if (!fMIMEParts.empty())
		{
			XBOX::VString	string;
			XBOX::VString	charsetName;
			bool			bEncodeBody;	// Encode using base64.

			for (XBOX::VectorOfMIMEPart::const_iterator it = fMIMEParts.begin(); it != fMIMEParts.end(); ++it)
			{
				outStream.PutPrintf ("\r\n--%S\r\n", &fBoundary);

				string.FromCString ("Content-Type: ");
				string.AppendString ((*it)->GetMediaType());
 
				if (!(*it)->GetFileName().IsEmpty())
				{
					string.AppendCString ("; name=\"");
					if (!(*it)->GetName().IsEmpty())
						string.AppendString ((*it)->GetName());
					else
						string.AppendString ((*it)->GetFileName());

					string.AppendCString("\"\r\nContent-Disposition: ");
					string.AppendCString((*it)->IsInline() ? "inline; " : "attachment; ");					
					string.AppendCString("filename=\"");

					string.AppendString ((*it)->GetFileName());
					string.AppendCString ("\"\r\n");

					if (inEncoding == ENCODING_BINARY) {

						string.AppendCString ("Content-Transfer-Encoding: 8bit\r\n");
						bEncodeBody = false;

					} else {

						if ((inEncoding == ENCODING_BINARY_ONLY) && ((*it)->GetMediaTypeKind() == MIMETYPE_TEXT))
						{
							bEncodeBody = false;
						}
						else
						{
							string.AppendCString ("Content-Transfer-Encoding: base64\r\n");
							bEncodeBody = true;
						}
					}
				}
				else
				{
					if ((*it)->GetMediaTypeCharSet() != XBOX::VTC_UNKNOWN)
					{
						string.AppendCString ("; charset=\"");
						XBOX::VTextConverters::Get()->GetNameFromCharSet ((*it)->GetMediaTypeCharSet(), charsetName);
						string.AppendString (charsetName);
						string.AppendCString ("\"");
					}

					if (!(*it)->GetName().IsEmpty()) {

						string.AppendCString("; name=\"");
						string.AppendString((*it)->GetName());
						string.AppendCString("\"");

					}

					string.AppendCString ("\r\n");

					if ((*it)->IsInline())

						string.AppendCString("Content-Disposition: inline\r\n");
						
					if (inEncoding == ENCODING_7BIT || ((inEncoding == ENCODING_BINARY_ONLY) && ((*it)->GetMediaTypeKind() != MIMETYPE_TEXT))) {

						string.AppendCString ("Content-Transfer-Encoding: base64\r\n");
						bEncodeBody = true;

					} else {

						string.AppendCString("Content-Transfer-Encoding: 8bit\r\n");
						bEncodeBody = false;

					}
				}

				if ((*it)->GetContentID().GetLength()) {

					string.AppendCString("Content-ID: <");
					string.AppendString((*it)->GetContentID());
					string.AppendCString(">\r\n");

				}

				string.AppendCString ("\r\n");

				outStream.PutText (string);

				if (bEncodeBody)
				{
					XBOX::VMemoryBuffer<> buffer;
					if (XBOX::Base64Coder::Encode ((*it)->GetData().GetDataPtr(), (*it)->GetData().GetDataSize(), buffer, kBASE64_QUADS_PER_LINE))
					{
						outStream.PutData (buffer.GetDataPtr(), buffer.GetDataSize());
					}
				}
				else
				{
					outStream.PutData ((*it)->GetData().GetDataPtr(), (*it)->GetData().GetDataSize());
				}
			}

			outStream.PutPrintf ("\r\n--%S--\r\n", &fBoundary);
		}

		outStream.CloseWriting();
	}

	return error;
}