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); } }
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; }
void VHTTPServerLogSettings::SetLogTokens (const VectorOfLogToken& inTokens) { XBOX::VTaskLock lock (&fLogTokensVectorLock); fLogTokens.clear(); fLogTokens.assign (inTokens.begin(), inTokens.end()); }