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;
}
예제 #2
0
void VMIMEMessage::_ReadUrl (const XBOX::VString& inString)
{
	if (!inString.IsEmpty())
	{
		const UniChar *stringPtr = inString.GetCPointer();
		UniChar ch = *stringPtr;

		while (ch != '\0')
		{
			XBOX::VString	name;
			XBOX::VString	value;

			while (ch != '\0' && ch != CHAR_EQUALS_SIGN && ch != CHAR_AMPERSAND)
			{
				if (ch == CHAR_PLUS_SIGN) ch = CHAR_SPACE;
				name.AppendUniChar (ch);
				ch = *(++stringPtr);
			}

			if (ch == CHAR_EQUALS_SIGN)
			{
				ch = *(++stringPtr);
				while (ch != '\0' && ch != CHAR_AMPERSAND)
				{
					if (ch == CHAR_PLUS_SIGN) ch = CHAR_SPACE;
					value.AppendUniChar (ch);
					ch = *(++stringPtr);
				}
			}

			XBOX::VString decodedName (name);
			XBOX::VString decodedValue (value);
			XBOX::VURL::Decode (decodedName);
			XBOX::VURL::Decode (decodedValue);

			XBOX::StStringConverter<char> buffer (decodedValue, XBOX::VTC_UTF_8);
			_AddValuePair (decodedName, CONST_TEXT_PLAIN_UTF_8, (void *)buffer.GetCPointer(), buffer.GetLength());

			if (ch == CHAR_AMPERSAND) ch = *(++stringPtr);
		}
	}
}
XBOX::VError VHTTPServerLog::_Flush()
{
	XBOX::VFilePath	logFilePath;
	XBOX::VError	error = XBOX::VE_OK;

	_GetLogFilePath (logFilePath);

	if (!logFilePath.IsValid())
		return XBOX::VE_FILE_NOT_FOUND;

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

		if (testAssert (NULL != fLogFile))
		{
			XBOX::VFileDesc *fileDesc = NULL;

			error = fLogFile->Open (XBOX::FA_READ_WRITE, &fileDesc, XBOX::FO_CreateIfNotFound);

			if ((XBOX::VE_OK == error) && (NULL != fileDesc))
			{
				sLONG8 logFileSize = fileDesc->GetSize();

				if ((CHAR_NUMBER_SIGN != fRequestsBuffer.GetUniChar (1)) && (0 == logFileSize))
				{
					XBOX::VString fileHeader;
					_WriteFileHeader (fileHeader);

					XBOX::StStringConverter<char> buffer (fileHeader, XBOX::VTC_DefaultTextExport);
					fileDesc->SetPos (fileDesc->GetSize());
					error = fileDesc->PutDataAtPos (buffer.GetCPointer(), buffer.GetSize());
					fileDesc->Flush();
				}

				if (fLogBufferAccessLock.Lock())
				{
					// Flushing the buffer
					XBOX::StStringConverter<char> buffer (fRequestsBuffer, XBOX::VTC_DefaultTextExport);
					fileDesc->SetPos (fileDesc->GetSize());
					error = fileDesc->PutDataAtPos (buffer.GetCPointer(), buffer.GetSize());

					fRequestsBuffer.Clear();
					fRequestsInBuffer = 0;

					fLogBufferAccessLock.Unlock();
				}

				error = fileDesc->Flush();
				fLogFileSize = fileDesc->GetSize();
				delete fileDesc;
				fileDesc = NULL;
			}
			else
			{
				error = VE_CANNOT_OPEN_LOG_FILE;
			}
		}
		else
		{
			error = VE_CANNOT_CREATE_LOG_FILE;
		}

		fLogFileAccessLock.Unlock();

		_CalculateNextFileRotationTime();
	}

	return error;
}
XBOX::VError SendValueBagResponse (IHTTPResponse& ioResponse, const XBOX::VValueBag& inBag, const XBOX::VString& inBagName)
{
	XBOX::VError		error = XBOX::VE_OK;
	const XBOX::VString	stringURL = ioResponse.GetRequest().GetURLQuery();
	HTTPRequestMethod	method = ioResponse.GetRequest().GetRequestMethod();
	XBOX::VString		resultString;
	bool				isJSON = true;
	bool				prettyFormatting = false;
	bool				isValidRequest = ((method == HTTP_GET) || (method == HTTP_HEAD));

	if (isValidRequest)
	{
		sLONG			posFormat = 0, posPretty = 0;
		const UniChar *	stringPtr = stringURL.GetCPointer();
		const sLONG		stringLen = stringURL.GetLength();

		if ((posFormat = HTTPServerTools::FindASCIICString (stringPtr, "format=")) > 0)
		{
			posFormat += 6;

			sLONG startPos = 0;
			sLONG endPos = HTTPServerTools::FindASCIICString (stringPtr + posFormat, "&");
			if (endPos <= 0)
				endPos = stringLen;
			else
				endPos += (posFormat - 1);

			if (((startPos = HTTPServerTools::FindASCIICString (stringPtr + posFormat, "xml")) > 0) && (startPos < endPos))
				isJSON = false;
			else if(((startPos = HTTPServerTools::FindASCIICString (stringPtr + posFormat, "json")) > 0) && (startPos < endPos))
				isJSON = true;
			else
				isValidRequest = false;
		}

		if ((posPretty = HTTPServerTools::FindASCIICString (stringPtr, "pretty=")) > 0)
		{
			XBOX::VString prettyString;

			posPretty += 6;
			sLONG endPos = HTTPServerTools::FindASCIICString (stringPtr + posPretty, "&");
			if (endPos <= 0)
				endPos = stringLen;
			else
				endPos += (posPretty - 1);

			if (endPos > posPretty)
			{
				GetSubString (stringURL, posPretty, endPos - 1, prettyString);
				prettyFormatting = (HTTPServerTools::EqualASCIICString (prettyString, "yes"));
			}
			else
				isValidRequest = false;
		}
	}

	if (isValidRequest)
	{
		if (isJSON)
		{
			inBag.GetJSONString (resultString, prettyFormatting ? JSON_PrettyFormatting : JSON_Default);
		}
		else
		{
			resultString.FromCString ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
			inBag.DumpXML (resultString,  inBagName, prettyFormatting);
		}

		XBOX::StStringConverter<char> buffer (resultString, XBOX::VTC_UTF_8);

		error = ioResponse.SetResponseBody (buffer.GetCPointer(), buffer.GetLength());

		ioResponse.SetExpiresHeader (GMT_NOW);
		ioResponse.AddResponseHeader (STRING_HEADER_PRAGMA, STRING_HEADER_VALUE_NO_CACHE);
		ioResponse.AddResponseHeader (STRING_HEADER_CONTENT_TYPE, (isJSON) ? STRING_CONTENT_TYPE_JSON : STRING_CONTENT_TYPE_XML);

		ioResponse.SetContentLengthHeader (buffer.GetLength());
		ioResponse.AllowCompression (true);
	}
	else
	{
		error = ioResponse.ReplyWithStatusCode (HTTP_BAD_REQUEST);
	}

	return error;
}