/* 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);
				}
			}
		}
	}
}
XBOX::VError VJSModuleState::LoadScript (const XBOX::VString &inURLString, XBOX::VURL *outURL, XBOX::VString *outScript)
{
	xbox_assert(outURL != NULL && outScript != NULL);

	outURL->FromFilePath(inURLString, eURL_POSIX_STYLE, CVSTR("file://"));

	XBOX::VError	error;
	XBOX::VFilePath	path;
					
	if (outURL->GetFilePath(path) && path.IsFile()) {

		XBOX::VFile			file(path);			
		XBOX::VFileStream	stream(&file);
				
		if ((error = stream.OpenReading()) == XBOX::VE_OK
		&& (error = stream.GuessCharSetFromLeadingBytes(XBOX::VTC_DefaultTextExport)) == XBOX::VE_OK) {

			stream.SetCarriageReturnMode(XBOX::eCRM_NATIVE);
			error = stream.GetText(*outScript);

		}
		stream.CloseReading();	// Ignore closing error, if any.

	} else

		error = XBOX::VE_JVSC_SCRIPT_NOT_FOUND;

	return error;
}
Пример #3
0
JS4D::ObjectRef JS4D::VFilePathToObjectAsFileOrFolder( ContextRef inContext, const XBOX::VFilePath& inPath, ValueRef *outException)
{
	ObjectRef value;
	if (inPath.IsFolder())
	{
		VFolder *folder = new VFolder( inPath);
		value = VFolderToObject( inContext, folder, outException);
		ReleaseRefCountable( &folder);
	}
	else if (inPath.IsFile())
	{
		VFile *file = new VFile( inPath);
		value = VFileToObject( inContext, file, outException);
		ReleaseRefCountable( &file);
	}
	else
	{
		value = JSValueToObject( inContext, JSValueMakeNull( inContext), outException);	// exception instead ?
	}
	return value;
}
XBOX::VError VHTTPResponse::SendResponse()
{
	XBOX::VError error = XBOX::VE_OK;

	if (fIsChunked)
	{
		// First send buffered data that was not already sent...
		if (XBOX::VE_OK == (error = _SendResponseBody()))
		{
			// Then send special ending line for chunked encoding
			error = _WriteChunkSize (0);
		}
	}
	else
	{
		XBOX::VString contentType;
		XBOX::VString contentEncoding;

		GetHeaders().GetContentType (contentType);
		
		if (GetHeaders().GetHeaderValue (HEADER_CONTENT_ENCODING, contentEncoding) && !contentEncoding.IsEmpty())
		{
			if (HTTPProtocol::NegotiateEncodingMethod (contentEncoding) != COMPRESSION_UNKNOWN)
				fCanCompressBody = false;
		}

		if (HTTP_UNDEFINED == fResponseStatusCode)
			fResponseStatusCode = HTTP_OK;

		VVirtualHost *virtualHost = dynamic_cast<VVirtualHost *>(GetVirtualHost());

		if (NULL != virtualHost)
		{
			// Compress HTTP Message body when applicable
#if HTTP_SERVER_GLOBAL_SETTINGS
			bool compressionEnabled = fHTTPServer->GetSettings()->GetEnableCompression();
#else
			bool compressionEnabled = virtualHost->GetSettings()->GetEnableCompression();
#endif
			if (fCanCompressBody && compressionEnabled)
			{
				sLONG size = (sLONG)GetBody().GetSize();
#if HTTP_SERVER_GLOBAL_SETTINGS
				sLONG minThreshold = (fMinCompressionThreshold == -1) ? fHTTPServer->GetSettings()->GetCompressionMinThreshold() : fMinCompressionThreshold;
				sLONG maxThreshold = (fMaxCompressionThreshold == -1) ? fHTTPServer->GetSettings()->GetCompressionMaxThreshold() : fMaxCompressionThreshold;
#else
				sLONG minThreshold = (fMinCompressionThreshold == -1) ? virtualHost->GetSettings()->GetCompressionMinThreshold() : fMinCompressionThreshold;
				sLONG maxThreshold = (fMaxCompressionThreshold == -1) ? virtualHost->GetSettings()->GetCompressionMaxThreshold() : fMaxCompressionThreshold;
#endif
				if ((size > minThreshold) && (size <= maxThreshold))
				{
					if (!contentType.IsEmpty() && (VMimeTypeManager::IsMimeTypeCompressible (contentType)))
					{
						error = _CompressData();
					}
				}
			}
		}

		// Put HTTP Message body in cache when applicable
		if ((NULL != virtualHost) && fCanCacheBody && (fResponseStatusCode == HTTP_OK))
		{
#if HTTP_SERVER_GLOBAL_CACHE
			VCacheManager *	cacheManager = virtualHost->GetProject()->GetHTTPServer()->GetCacheManager();
#else
			VCacheManager *	cacheManager = virtualHost->GetCacheManager();
#endif
			XBOX::VFilePath	filePath;
			XBOX::VString	locationPath;
			XBOX::VTime		lastModified;
			XBOX::VString	lastModifiedString;
			XBOX::VError	fileError = XBOX::VE_OK;
			bool			staticFile = false;

			if (XBOX::VE_OK == (fileError = virtualHost->GetFilePathFromURL (fRequest->GetURL(), locationPath)))
			{
				filePath.FromFullPath (locationPath);
				if (filePath.IsFile() && (XBOX::VE_OK == HTTPServerTools::GetFileInfos (filePath, &lastModified)))
				{
					staticFile = true;
					HTTPProtocol::MakeRFC822GMTDateString (lastModified, lastModifiedString);
				}
			}

			if ((XBOX::VE_OK == fileError) && (NULL != cacheManager) && cacheManager->GetEnableDataCache())
			{
				uLONG	bufferSize = (uLONG)GetBody().GetSize();
				if (bufferSize <= cacheManager->GetCachedObjectMaxSize())
				{
					void *			buffer = GetBody().GetDataPtr();
					XBOX::VTime		lastChecked;
					VCachedObject *	cachedObject = NULL;

					XBOX::VTime::Now (lastChecked);

					bool ok = cacheManager->AddPageToCache (fRequest->GetURL(),
															virtualHost->GetUUIDString(),
															contentType,
															buffer,
															bufferSize,
															filePath,
															lastChecked,
															lastModified,
															staticFile,
															fCompressionMode,
															&cachedObject);

					if (ok)
					{
						if (NULL != cachedObject)
						{
							XBOX::VTime expirationDate;
							sLONG maxAge = cachedObject->GetMaxAge();

							if (maxAge > 0)
							{
								XBOX::VString	string;

								string.FromCString ("max-age=");
								string.AppendLong (maxAge);
								AddResponseHeader (STRING_HEADER_CACHE_CONTROL, string);
								AddResponseHeader (STRING_HEADER_AGE, cachedObject->GetAge());
								if (cachedObject->GetExpirationDate (expirationDate))
									AddResponseHeader (STRING_HEADER_EXPIRES, expirationDate);
							}
							else if (cachedObject->GetExpirationDate (expirationDate) && IsVTimeValid (expirationDate))
							{
								AddResponseHeader (STRING_HEADER_EXPIRES, expirationDate);
							}

							XBOX::QuickReleaseRefCountable (cachedObject);
						}
					}
				}
			}

			if (!lastModifiedString.IsEmpty())
				AddResponseHeader (STRING_HEADER_LAST_MODIFIED, lastModifiedString);
		}

		if (HTTP_OK == fResponseStatusCode)
		{
			if (NULL != fFileToSend)
			{
				if (fFileToSend->Exists())
				{
					sLONG8	fileSize = 0;
					
					fFileToSend->GetSize (&fileSize);
					this->SetContentLengthHeader (fileSize); // YT 18-Jul-2011 - ACI0072287

					if (XBOX::VE_OK == (error = _SendResponseHeader()))
					{
						const sLONG CHUNK_BUFFER_SIZE = 0xFFFF;
						char *	chunkBuffer = (char *)XBOX::vMalloc (CHUNK_BUFFER_SIZE, 0);
						if (testAssert (NULL != chunkBuffer))
						{
							XBOX::VFileDesc *fileDesc = NULL;
							if ((XBOX::VE_OK == fFileToSend->Open (XBOX::FA_READ, &fileDesc, XBOX::FO_SequentialScan)) && (NULL != fileDesc))
							{
								uLONG			chunkSize = 0;
								XBOX::VSize		readBytes = 0;
								XBOX::VError	fileError = XBOX::VE_OK;
								sLONG8			unreadSize = 0;

								unreadSize = fileSize;
								fileDesc->SetPos (0, true);

								while ((XBOX::VE_OK == fileError) && (unreadSize > 0))
								{
									chunkSize = (unreadSize > CHUNK_BUFFER_SIZE) ? CHUNK_BUFFER_SIZE : unreadSize;
									fileError = fileDesc->GetDataAtPos (chunkBuffer, chunkSize, 0, &readBytes);
									unreadSize -= (sLONG8)readBytes;

									if ((XBOX::VE_OK == fileError) || (XBOX::VE_STREAM_EOF == fileError))
									{
										error = _WriteToSocket (chunkBuffer, &chunkSize);
										if (XBOX::VE_OK != error)
											break;
									}
								}

								delete fileDesc;
								fileDesc = NULL;
							}
							else
							{
								error = _SendResponseWithStatusCode (HTTP_INTERNAL_SERVER_ERROR);
							}

							XBOX::vFree (chunkBuffer);
							chunkBuffer = NULL;
						}
						else
						{
							error = _SendResponseWithStatusCode (HTTP_INTERNAL_SERVER_ERROR);
						}
					}
				}
				else
				{
					error = _SendResponseWithStatusCode (HTTP_NOT_FOUND);
				}

				XBOX::ReleaseRefCountable (&fFileToSend);
			}
			else if (GetBody().GetDataSize() >= 0)
			{
				if (XBOX::VE_OK == (error = _SendResponseHeader()))
				{
					if (NULL != GetBody().GetDataPtr())
						error = _SendResponseBody();
				}
			}
			else
			{
				error = _SendResponseWithStatusCode (HTTP_INTERNAL_SERVER_ERROR);
			}
		}
		else
		{
			error = _SendResponseWithStatusCode (fResponseStatusCode);
		}
	}

	return error;
}