void TrimUniChar (XBOX::VString& ioString, const UniChar inCharToTrim) { if (ioString.GetLength() > 0) { sLONG length = ioString.GetLength(); UniChar * data = (UniChar *)ioString.GetCPointer(); XBOX::VIndex leadingChars = 0; XBOX::VIndex endingChars = 0; for (UniChar *p = data, *end = (data + length); (p != end) && (*p == inCharToTrim); p++, leadingChars++); for (UniChar *p = (data + length - 1), *start = (data - 1); (p != start) && (*p == inCharToTrim); p--, endingChars++); if ((0 != leadingChars) || (0 != endingChars)) { if ((leadingChars + endingChars) >= length) { ioString.Clear(); } else { ioString.SubString (leadingChars + 1, length - leadingChars - endingChars); } } } }
void VJSTextStream::_Read (VJSParms_callStaticFunction &ioParms, VJSTextStreamState *inStreamState) { if (inStreamState == NULL) XBOX::vThrowError(XBOX::VE_JVSC_INVALID_STATE, L"TextStream.read()"); else if (ioParms.CountParams() == 1 && ioParms.IsStringParam(1)) { XBOX::VString delimiter; if (!ioParms.GetStringParam(1, delimiter) || delimiter.GetLength() > 1) XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_STRING, "1"); else { XBOX::VString result; bool hasBeenFound; hasBeenFound = inStreamState->_ReadUntilDelimiter(delimiter, &result); inStreamState->fPosition += result.GetLength(); if (hasBeenFound) inStreamState->fPosition++; // Delimiter is not included. ioParms.ReturnString(result); } } else { // numberCharacters is the number of actual characters to read, not the number of bytes. sLONG numberCharacters; numberCharacters = 0; if (ioParms.CountParams() >= 1 && (!ioParms.GetLongParam(1, &numberCharacters) || numberCharacters < 0)) XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1"); else { XBOX::VString result; inStreamState->_ReadCharacters(numberCharacters, &result); inStreamState->fPosition += result.GetLength(); ioParms.ReturnString(result); } } }
static void BuildFolderPath (const XBOX::VFilePath& inBaseFolder, const XBOX::VString& inPath, XBOX::VFilePath& outPath) { if (inPath.IsEmpty()) { outPath.FromFilePath (inBaseFolder); } else { XBOX::VString pathString (inPath); if ((pathString[0] == CHAR_SOLIDUS) // POSIX Path ? #if VERSIONWIN || ((pathString.GetLength() > 2) && (pathString[1] == CHAR_COLON) && (pathString[2] == CHAR_SOLIDUS)) // POSIX path like c:/blahblah/ #endif ) { if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != CHAR_SOLIDUS)) pathString.AppendUniChar (CHAR_SOLIDUS); outPath.FromFullPath (pathString, XBOX::FPS_POSIX); } else if ((pathString[0] != CHAR_FULL_STOP) && (pathString.FindUniChar (XBOX::FOLDER_SEPARATOR) > 0)) { if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != XBOX::FOLDER_SEPARATOR)) pathString.AppendUniChar (XBOX::FOLDER_SEPARATOR); outPath.FromFullPath (pathString, XBOX::FPS_SYSTEM); } else { XBOX::VFilePath baseFolder (inBaseFolder); if ((pathString[0] == CHAR_FULL_STOP) && (pathString[1] == CHAR_SOLIDUS)) pathString.Remove (1, 2); while ((pathString[0] == CHAR_FULL_STOP) && (pathString[1] == CHAR_FULL_STOP) && (pathString[2] == CHAR_SOLIDUS)) { pathString.Remove (1, 3); baseFolder = baseFolder.ToParent(); } pathString.ExchangeAll (CHAR_SOLIDUS, XBOX::FOLDER_SEPARATOR); if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != XBOX::FOLDER_SEPARATOR)) pathString.AppendUniChar (XBOX::FOLDER_SEPARATOR); outPath.FromRelativePath (baseFolder, pathString); } } }
void ToXMLCompatibleText(const XBOX::VString& inText, XBOX::VString& outText) { outText = inText; sLONG len = inText.GetLength(); outText.Exchange( CVSTR("&"), CVSTR("&"), 1, len); len = outText.GetLength(); outText.Exchange( CVSTR("<"), CVSTR("<"), 1, len); len = outText.GetLength(); outText.Exchange( CVSTR(">"), CVSTR(">"), 1, len); outText.ConvertCarriageReturns(XBOX::eCRM_CR); len = outText.GetLength(); outText.Exchange( CVSTR("\r"), CVSTR("<BR/>"), 1, len); len = outText.GetLength(); outText.Exchange( CVSTR("\13"), CVSTR("<BR/>"), 1, len);//[MI] le 28/12/2010 ACI0069253 }
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); } }
void GetIPv4FromString (const XBOX::VString& inIPv4String, IP4& outIPv4) { sLONG hostNameSize = inIPv4String.GetLength() + 1; char * hostName = new char[hostNameSize]; outIPv4 = INADDR_NONE; if (NULL != hostName) { struct hostent * remoteHost = NULL; struct in_addr addr = {0}; inIPv4String.ToCString (hostName, hostNameSize); if (isalpha (hostName[0])) // host address is a name { remoteHost = gethostbyname (hostName); } else { addr.s_addr = inet_addr (hostName); if (addr.s_addr != INADDR_NONE) remoteHost = gethostbyaddr ((char *) &addr, 4, AF_INET); } if (NULL != remoteHost) outIPv4 = *((sLONG *)remoteHost->h_addr_list[0]); delete [] hostName; } }
sLONG GetLongFromString (const XBOX::VString& inString) { bool isneg = false; XBOX::VIndex sepPos = HTTPServerTools::FindASCIIVString (inString, XBOX::VIntlMgr::GetDefaultMgr()->GetDecimalSeparator()); if (sepPos <= 0) sepPos = inString.GetLength(); const UniChar* bb = inString.GetCPointer(); sLONG result = 0; for (XBOX::VIndex i = 0; i < sepPos; ++i) { if ((0 == result) && (bb[i] == CHAR_HYPHEN_MINUS)) isneg = true; if ((bb[i] < CHAR_DIGIT_ZERO) || (bb[i] > CHAR_DIGIT_NINE)) continue; result *= 10; result += bb[i] - CHAR_DIGIT_ZERO; } if (isneg) result = -result; return result; }
bool EndsWithASCIICString (const XBOX::VString& inText, const char *inPattern, bool isCaseSensitive) { sLONG textSize = inText.GetLength(); sLONG patternSize = (sLONG)strlen (inPattern); return (_FindASCIICString (inText.GetCPointer() + (textSize - patternSize), textSize, inPattern, patternSize, isCaseSensitive) == 1); }
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; }
void GetSubString (const XBOX::VString& inString, sLONG inFirst, sLONG inLast, XBOX::VString& outString) { if (testAssert ((inFirst >= 0) && (inLast < inString.GetLength()))) outString.FromBlock (inString.GetCPointer() + inFirst, (inLast - inFirst + 1) * sizeof(UniChar), XBOX::VTC_UTF_16); else outString.Clear(); }
static bool _RemoveProjectPatternFromURL (const XBOX::VString& inProjectPattern, XBOX::VString& ioURL) { if (inProjectPattern.IsEmpty()) return false; XBOX::VString url (ioURL); sLONG pos = HTTPServerTools::FindASCIIVString (url, inProjectPattern); if (pos == 2) // Takes the starting CHAR_SOLIDUS into account { url.GetSubString (pos + inProjectPattern.GetLength(), url.GetLength() - inProjectPattern.GetLength() - 1, ioURL); return true; } return false;; }
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 VJSMessagePort::SetCallbackName (VJSWorker *inWorker, const XBOX::VString &inCallbackName) { xbox_assert(inWorker != NULL && (inWorker == fOutsideWorker || inWorker == fInsideWorker)); xbox_assert((inWorker == fOutsideWorker && !fOutsideClosingFlag) || (inWorker == fInsideWorker && !fInsideClosingFlag)); xbox_assert(inCallbackName.GetLength()); if (inWorker == fOutsideWorker) fOutsideCallbackName = inCallbackName; else fInsideCallbackName = inCallbackName; }
std::string StdStringFromAsciiVString(const XBOX::VString inStr) { int len=inStr.GetLength(); char* buf=new char[len]; if(!buf) return std::string(); inStr.ToBlock(buf, len, XBOX::VTC_US_ASCII, false, false); std::string outStr(buf, len); delete[] buf; return outStr; }
void ParseHostString (const XBOX::VString& inHostString, XBOX::VString& outIPv4String, PortNumber& outPort) { XBOX::VIndex pos = inHostString.FindUniChar (CHAR_COLON); if (pos > 0) { XBOX::VString portString; inHostString.GetSubString (1, pos - 1, outIPv4String); inHostString.GetSubString (pos + 1, inHostString.GetLength() - pos, portString); outPort = portString.GetLong(); } else { outIPv4String.FromString (inHostString); outPort = DEFAULT_LISTENING_PORT; } }
bool HttpRequest::SetData(const XBOX::VString& inData, XBOX::CharSet inCS) { int maxlen=2*inData.GetLength(); //We convert utf16 to utf8, it should be large enough. char* buf=new char[maxlen]; if(!buf) return false; //int len=inData.ToBlock(buf, maxlen, XBOX::VTC_UTF_8, false, false); inCS=(inCS!=XBOX::VTC_UNKNOWN ? inCS : XBOX::VTC_US_ASCII); int len=inData.ToBlock(buf, maxlen, inCS, false, false); int count=fData.AddRawPtr(buf, len); delete(buf); fReqHdrs.FixContentThings(); curl_easy_setopt(fHandle, CURLOPT_POSTFIELDSIZE, count); return len==count; }
void VJSTextStream::_Write (VJSParms_callStaticFunction &ioParms, VJSTextStreamState *inStreamState) { if (inStreamState == NULL && !inStreamState->fStream->IsWriting()) XBOX::vThrowError(XBOX::VE_JVSC_INVALID_STATE, L"TextStream.write()"); else { XBOX::VString string; if (ioParms.CountParams() != 1 || !ioParms.IsStringParam(1) || !ioParms.GetStringParam(1, string)) XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1"); else { inStreamState->fStream->PutText(string); inStreamState->fPosition += string.GetLength(); } } }
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; }
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; }
// Environment block == null-terminated block of null-terminated strings of the form: name=value\0 wchar_t * XWinProcessLauncher::_CreateEnvironmentVariablesBlock(const EnvVarNamesAndValuesMap &inVarToUse) { wchar_t * initialEnvStrings = NULL; VMemoryBuffer<> allStrings; wchar_t * theEnvVarBlock = NULL; // Initial environment variables initialEnvStrings = ::GetEnvironmentStringsW(); if(initialEnvStrings != NULL) { wchar_t *currentStr = initialEnvStrings; size_t fullStrSize; while (*currentStr) { fullStrSize = ::wcslen(currentStr) + 1; allStrings.PutData(allStrings.GetDataSize(), currentStr, fullStrSize * sizeof(wchar_t)); currentStr += fullStrSize; } } // Prepare our envir. variables if(!inVarToUse.empty()) { XBOX::VString oneEnvVarAndValue; EnvVarNamesAndValuesMap::const_iterator envVarIterator; // Calculate final buffer size (concatenate name=value and add the 0 terminattion) for (envVarIterator = inVarToUse.begin(); envVarIterator != inVarToUse.end(); envVarIterator++) { oneEnvVarAndValue = envVarIterator->first; if(!oneEnvVarAndValue.IsEmpty()) { oneEnvVarAndValue += "="; oneEnvVarAndValue += envVarIterator->second; const wchar_t * varValueCStr = oneEnvVarAndValue.GetCPointer(); // Null terminated UniCode string. if(testAssert(varValueCStr != NULL)) { allStrings.PutData(allStrings.GetDataSize(), varValueCStr, (oneEnvVarAndValue.GetLength() + 1) * sizeof(wchar_t)); } } } } //if(!inVarToUse.empty()) if(allStrings.GetDataSize() > 0) { wchar_t theZero = 0; allStrings.PutData(allStrings.GetDataSize(), &theZero, sizeof(wchar_t)); theEnvVarBlock = new wchar_t[allStrings.GetDataSize()]; if(testAssert(theEnvVarBlock)) allStrings.GetData(0, theEnvVarBlock, allStrings.GetDataSize()); } if(initialEnvStrings != NULL) ::FreeEnvironmentStringsW(initialEnvStrings); return theEnvVarBlock; }
bool VJSTextStreamState::_ReadUntilDelimiter (const XBOX::VString &inDelimiter, XBOX::VString *outResult) { bool isFound = false; sLONG numberCharactersLeft; numberCharactersLeft = fBuffer.GetLength() - fIndex; outResult->Clear(); if (!inDelimiter.GetLength()) { for ( ; ; ) { if (!numberCharactersLeft) { fBuffer.Clear(); fIndex = 0; XBOX::VError error; if ((error = fStream->GetText(fBuffer, kREAD_SLICE_SIZE)) != XBOX::VE_OK && error != XBOX::VE_STREAM_EOF) break; // Error! if (!(numberCharactersLeft = fBuffer.GetLength())) break; // End-of-file. } const UniChar *p, *q; for (p = q = fBuffer.GetCPointer() + fIndex; *q != 0 && *q != '\r' && *q != '\n'; q++) ; if (*q) { outResult->AppendUniChars(p, q - p); fIndex = 1 + (q - fBuffer.GetCPointer()); if (fIndex == fBuffer.GetLength()) { fBuffer.Clear(); fIndex = 0; } isFound = true; break; } else { outResult->AppendUniChars(p, fBuffer.GetLength() - fIndex); numberCharactersLeft = 0; } } } else { UniChar delimiter; delimiter = inDelimiter[0]; for ( ; ; ) { if (!numberCharactersLeft) { fBuffer.Clear(); fIndex = 0; XBOX::VError error; if ((error = fStream->GetText(fBuffer, kREAD_SLICE_SIZE)) != XBOX::VE_OK && error != XBOX::VE_STREAM_EOF) break; // Error! if (!(numberCharactersLeft = fBuffer.GetLength())) break; // End-of-file. } VIndex index; if ((index = fBuffer.FindUniChar(delimiter, fIndex + 1))) { // Remember that fIndex starts at zero and index at one. outResult->AppendUniChars(fBuffer.GetCPointer() + fIndex, index - (fIndex + 1)); if (index == fBuffer.GetLength()) { fBuffer.Clear(); fIndex = 0; } else fIndex = index; // fIndex now indexes next character! isFound = true; break; } else { outResult->AppendUniChars(fBuffer.GetCPointer() + fIndex, fBuffer.GetLength() - fIndex); numberCharactersLeft = 0; } } } return isFound; }
void VJSNetServerClass::_listen (XBOX::VJSParms_callStaticFunction &ioParms, VJSNetServerObject *inServer) { xbox_assert(inServer != NULL); XBOX::VString address; sLONG port; if (!ioParms.CountParams()) { XBOX::vThrowError(XBOX::VE_JVSC_EXPECTING_PARAMETER, "net.Server.listen()"); return; } if (!ioParms.IsNumberParam(1) || !ioParms.GetLongParam(1, &port)) { XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1"); return; } XBOX::VString hostname; XBOX::VJSObject callback(ioParms.GetContext()); bool hasCallback; hostname = ""; hasCallback = false; if (ioParms.CountParams() >= 2) { if (ioParms.IsStringParam(2)) { if (!ioParms.GetStringParam(2, hostname)) { XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_STRING, "2"); return; } } else if (ioParms.IsObjectParam(2) && ioParms.GetParamFunc(2, callback)) { hasCallback = true; } else { XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_FUNCTION, "2"); return; } } if (ioParms.CountParams() == 3 ) { if ((hasCallback || !ioParms.IsObjectParam(3) || !ioParms.GetParamFunc(3, callback))) { XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_FUNCTION, "3"); return; } else hasCallback = true; } // We are already listening, stop previous listener. if (inServer->fConnectionListener != NULL) inServer->Close(); // Set up listener. if ((inServer->fConnectionListener = new XBOX::VTCPConnectionListener())== NULL) { XBOX::vThrowError(XBOX::VE_MEMORY_FULL); return; } if (inServer->fIsSSL) inServer->fConnectionListener->SetSSLKeyAndCertificate(inServer->fCertificate, inServer->fKey); VJSNetSocketObject::sMutex.Lock(); if (VJSNetSocketObject::sSelectIOPool == NULL) VJSNetSocketObject::sSelectIOPool = new XBOX::VTCPSelectIOPool(); VJSNetSocketObject::sMutex.Unlock(); inServer->fConnectionListener->AddSelectIOPool(VJSNetSocketObject::sSelectIOPool); VJSWorker *worker; worker = VJSWorker::RetainWorker(ioParms.GetContext()); VJSConnectionHandlerFactory *connectionHandlerFactory; if ((connectionHandlerFactory = new VJSConnectionHandlerFactory(worker, inServer, inServer->fIsSSL)) == NULL) { XBOX::vThrowError(XBOX::VE_MEMORY_FULL); XBOX::ReleaseRefCountable<VJSWorker>(&worker); return; } #if WITH_DEPRECATED_IPV4_API sLONG resolvedAddress; if (hostname.GetLength()) { address = hostname; resolvedAddress = XBOX::ServerNetTools::ResolveAddress(hostname); } else { address = "0.0.0.0"; std::vector<IP4> localIPs; if (XBOX::ServerNetTools::GetLocalIPv4Addresses(localIPs)) resolvedAddress = localIPs[0]; else resolvedAddress = 0; // Should be same as above. } connectionHandlerFactory->SetIP(resolvedAddress); #else XBOX::VNetAddressList addrList; bool isIPv6; if (hostname.GetLength()) { XBOX::VNetAddress addr(hostname, port); isIPv6 = addr.IsV6(); addrList.FromDnsQuery(hostname, port); } else { addrList.FromLocalInterfaces(); isIPv6 = false; } // Always take first matching type address. XBOX::VNetAddressList::const_iterator it; for (it = addrList.begin(); it != addrList.end(); it++) if ((*it).IsV6() == isIPv6) break; address = (*it).GetIP(); connectionHandlerFactory->SetIP(address); #endif connectionHandlerFactory->AddNewPort(port); XBOX::VError error; error = inServer->fConnectionListener->AddConnectionHandlerFactory(connectionHandlerFactory); connectionHandlerFactory->Release(); // AddConnectionHandlerFactory() has done a retain(). if (error != XBOX::VE_OK || (error = inServer->fConnectionListener->StartListening()) != XBOX::VE_OK) XBOX::vThrowError(error); else { inServer->fAddress = address; inServer->fPort = port; if (hasCallback) inServer->AddListener("listening", callback, false); worker->QueueEvent(VJSNetEvent::Create(inServer, "listening")); } XBOX::ReleaseRefCountable<VJSWorker>(&worker); }
/* static */ DialectCode VComponentManager::GetLocalizationLanguage(VFolder * inLocalizationResourcesFolder,bool inGotoResourceFolder) { DialectCode sResult = XBOX::DC_NONE; // sc 19/05/2008 was XBOX::DC_ENGLISH_US VFolder * localizationResourcesFolder = NULL; if(testAssert(inLocalizationResourcesFolder != NULL && inLocalizationResourcesFolder->Exists())) { if (inGotoResourceFolder) { XBOX::VFilePath componentOrPluginFolderPath = inLocalizationResourcesFolder->GetPath(); componentOrPluginFolderPath.ToSubFolder(CVSTR("Contents")).ToSubFolder(CVSTR("Resources")); localizationResourcesFolder = new XBOX::VFolder(componentOrPluginFolderPath); } else { localizationResourcesFolder = inLocalizationResourcesFolder; localizationResourcesFolder->Retain(); } bool englishFolderDetected = false; XBOX::DialectCode dialectCode = XBOX::DC_NONE; //Detect what is the favorite language of the OS/App #if VERSIONWIN LCID lcid = ::GetUserDefaultLCID(); XBOX::DialectCode currentDialectCode = (XBOX::DialectCode)LANGIDFROMLCID(lcid); #elif VERSION_LINUX //jmo - Be coherent with code in VIntlMgr.cpp XBOX::DialectCode currentDialectCode=XBOX::DC_ENGLISH_US; // Postponed Linux Implementation ! #else CFBundleRef bundle = ::CFBundleGetMainBundle(); XBOX::DialectCode currentDialectCode = XBOX::DC_ENGLISH_US; if ( bundle != nil ){ CFArrayRef array_ref = ::CFBundleCopyBundleLocalizations(bundle); if (array_ref != nil){ CFArrayRef usedLanguages = ::CFBundleCopyPreferredLocalizationsFromArray(array_ref); CFStringRef cfPrimaryLanguage = (CFStringRef)CFArrayGetValueAtIndex(usedLanguages, 0); XBOX::VString xboxPrimaryLanguage; xboxPrimaryLanguage.MAC_FromCFString(cfPrimaryLanguage); ::CFRelease(usedLanguages); if(!XBOX::VIntlMgr::GetDialectCodeWithISOLanguageName(xboxPrimaryLanguage, currentDialectCode)) if(!XBOX::VIntlMgr::GetDialectCodeWithRFC3066BisLanguageCode(xboxPrimaryLanguage, currentDialectCode)) currentDialectCode = XBOX::DC_ENGLISH_US; CFRelease(array_ref); } } #endif //Try to see if we have this language. If not, take english for ( XBOX::VFolderIterator folderIter( localizationResourcesFolder ); folderIter.IsValid() && currentDialectCode != dialectCode ; ++folderIter ) { XBOX::VString folderName; folderIter->GetName(folderName); uLONG posStr = folderName.Find(CVSTR(".lproj"), 1, false); if ( posStr > 0 ) { folderName.Remove(posStr, folderName.GetLength() - posStr + 1); if( XBOX::VIntlMgr::GetDialectCodeWithRFC3066BisLanguageCode(folderName, dialectCode ) || XBOX::VIntlMgr::GetDialectCodeWithISOLanguageName(folderName, dialectCode)){ if(dialectCode == XBOX::DC_ENGLISH_US) englishFolderDetected = true; if(currentDialectCode == dialectCode) sResult = dialectCode; } } } if ( sResult == XBOX::DC_NONE ){ if ( englishFolderDetected ) sResult = XBOX::DC_ENGLISH_US; else sResult = dialectCode; } ReleaseRefCountable(&localizationResourcesFolder); } return sResult; }
XBOX::VError VHTTPServerLog::_WriteWLF_ELF (const IHTTPResponse& inHTTPResponse) { XBOX::VString string; XBOX::VString ipAddress; const VectorOfLogToken tokens = fSettings.GetLogTokens(); const EHTTPServerLogFormat format = fSettings.GetLogFormat(); for (VectorOfLogToken::const_iterator it = tokens.begin(); it != tokens.end(); ++it) { switch (*it) { case LOG_TOKEN_DATE: string.Clear(); if (format == LOG_FORMAT_ELF) { _GetCurrentFormatedDate (string, false); } else { _GetCurrentFormatedDate (string, true, HTTP_SOLIDUS); } if (!string.IsEmpty()) { fRequestsBuffer.AppendString (string); } else { fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS); } break; case LOG_TOKEN_TIME: string.Clear(); if (format == LOG_FORMAT_WLF) _GetCurrentFormatedTime (string, true); else _GetCurrentFormatedTime (string, false); fRequestsBuffer.AppendString (string); break; case LOG_TOKEN_STATUS: string.FromLong ((sLONG)inHTTPResponse.GetResponseStatusCode()); fRequestsBuffer.AppendString (string); break; case LOG_TOKEN_ELF_S_IP: string.Clear(); HTTPServerTools::MakeIPv4String (inHTTPResponse.GetIPv4(), string); fRequestsBuffer.AppendString (string); break; case LOG_TOKEN_HOST_NAME: // = C_DNS ..... case LOG_TOKEN_ELF_C_DNS: // DNS lookup : tres couteux en perf : remplacé par l'IP du client (les analyseurs de log font le DNS lookup)... case LOG_TOKEN_ELF_C_IP: // Client IP Address 192.0.1.3 string.Clear(); HTTPServerTools::MakeIPv4String (inHTTPResponse.GetIPv4(), string); fRequestsBuffer.AppendString (string); break; case LOG_TOKEN_METHOD: // The HTTP method : GET HEAD POST. If Unknown, we just copy it string.Clear(); HTTPProtocol::MakeHTTPMethodString (inHTTPResponse.GetRequest().GetRequestMethod(), string); fRequestsBuffer.AppendString (string); break; case LOG_TOKEN_BYTES_SENT: //WLF : Bytes sent to the client : = HTTP Content Length string.Clear(); if (inHTTPResponse.GetResponseHeader (STRING_HEADER_CONTENT_LENGTH, string) && !string.IsEmpty()) fRequestsBuffer.AppendString (string); else fRequestsBuffer.AppendUniChar (CHAR_DIGIT_ZERO); break; case LOG_TOKEN_AGENT: // The identity of the browser software or other client. Mozilla/4.04_(Macintosh;_U;_PPC) string.Clear(); if (inHTTPResponse.GetRequest().GetHTTPHeaders().GetHeaderValue (STRING_HEADER_USER_AGENT, string) && !string.IsEmpty()) { string.Exchange (CHAR_SPACE, CHAR_LOW_LINE); fRequestsBuffer.AppendString (string); } else { fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS); } break; case LOG_TOKEN_CS_USER_AGENT: // HTTP request's "User-Agent" header field. "Mozilla/4.04 (Macintosh; U; PPC)" string.Clear(); inHTTPResponse.GetRequest().GetHTTPHeaders().GetHeaderValue (STRING_HEADER_USER_AGENT, string); fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK); fRequestsBuffer.AppendString (string); fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK); break; case LOG_TOKEN_USER: //The User Name if there was a Web User entry for a realm. string.Clear(); inHTTPResponse.GetRequest().GetAuthenticationInfos()->GetUserName (string); _WriteUsername (string, fRequestsBuffer); break; case LOG_TOKEN_REFERER: //HTTP request's "Referer" header field, sending the URL that referred to the current page. www.google.com string.Clear(); inHTTPResponse.GetRequest().GetHTTPHeaders().GetHeaderValue (STRING_HEADER_REFERER, string); if (!string.IsEmpty()) fRequestsBuffer.AppendString (string); else fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS); break; case LOG_TOKEN_CS_REFERER: //HTTP request's "Referer" header field, sending the URL that referred to the current page. www.google.com string.Clear(); inHTTPResponse.GetRequest().GetHTTPHeaders().GetHeaderValue (STRING_HEADER_REFERER, string); fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK); fRequestsBuffer.AppendString (string); fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK); break; case LOG_TOKEN_ELF_CS_HOST: // = LOG_TOKEN_HOSTFIELD. The "HOST" field of the HTTP request fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK); fRequestsBuffer.AppendString (inHTTPResponse.GetRequest().GetHost()); fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK); break; case LOG_TOKEN_ELF_URI: string.FromString (inHTTPResponse.GetRequest().GetURL()); if (!string.IsEmpty()) fRequestsBuffer.AppendString (string); else fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS); break; case LOG_TOKEN_URL: case LOG_TOKEN_ELF_CS_URI_STEM: // Path portion of the HTTP request. "/status/stat.html" string.FromString (inHTTPResponse.GetRequest().GetURLPath()); if (!string.IsEmpty()) fRequestsBuffer.AppendString (string); else fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS); break; case LOG_TOKEN_SEARCH_ARGS: // The search arguments to the URL (text after a question mark) string.FromString (inHTTPResponse.GetRequest().GetURLQuery()); fRequestsBuffer.AppendString (string); break; case LOG_TOKEN_ELF_CS_URI_QUERY: // Search argument portion of the HTTP request. "first=last&last=first" string.FromString (inHTTPResponse.GetRequest().GetURLQuery()); if (!string.IsEmpty()) fRequestsBuffer.AppendString (string); else fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS); break; case LOG_TOKEN_CONNECTION_ID: // A number that is unique for each connection for this invocation of the server. Typically socket number. { sLONG rawSocket = inHTTPResponse.GetRawSocket(); if (rawSocket > 0) { fRequestsBuffer.AppendLong (rawSocket); } else { fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS); } break; } case LOG_TOKEN_ELF_CS_COOKIE: // The "cookie" information sent in this request "Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 20-Jan-05 23:12:40 GMT" string.Clear(); inHTTPResponse.GetRequest().GetHTTPHeaders().GetHeaderValue (STRING_HEADER_COOKIE, string); fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK); fRequestsBuffer.AppendString (string); fRequestsBuffer.AppendUniChar (CHAR_QUOTATION_MARK); break; case LOG_TOKEN_TRANSFER_TIME: // Time-Taken in millisecond like IIS { uLONG timeTaken = (XBOX::VSystem::GetCurrentTime() - inHTTPResponse.GetStartRequestTime()); fRequestsBuffer.AppendLong (timeTaken); break; } case LOG_TOKEN_WLF_BYTES_RECEIVED: { sLONG8 bytesReceived = inHTTPResponse.GetRequest().GetRequestBody().GetDataSize(); if (bytesReceived > 0) { fRequestsBuffer.AppendLong8 (bytesReceived); } else { fRequestsBuffer.AppendUniChar (CHAR_DIGIT_ZERO); } break; } case LOG_TOKEN_PATH_ARGS: //The path arguments to the URL for a CGI (the text after a dollar sign) { sLONG posChar = 0; XBOX::VString pathArgString; string.FromString (inHTTPResponse.GetRequest().GetURL()); if (!string.IsEmpty() && (posChar = string.FindUniChar (CHAR_DOLLAR_SIGN)) > 0) { // Let's delete all the stuff before '$' string.GetSubString (posChar + 1, string.GetLength() - posChar, pathArgString); // We delete the query arguments after the ? : we only want the string after the '$' if ((posChar = pathArgString.FindUniChar (CHAR_QUESTION_MARK)) > 0) pathArgString.SubString (1, posChar - 1); } if (!pathArgString.IsEmpty()) { fRequestsBuffer.AppendString (pathArgString); } else { fRequestsBuffer.AppendUniChar (CHAR_HYPHEN_MINUS); } break; } default: // this should never happen. assert (false); fRequestsBuffer.AppendCString ("UNKNOWN_FIELD"); break; } VectorOfLogToken::const_iterator nextToken = it; if (++nextToken != tokens.end()) fRequestsBuffer.AppendUniChar (CHAR_SPACE); } fRequestsBuffer.AppendUniChar (HTTP_LF); return XBOX::VE_OK; }
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 }