/*============================================================================= WebResponse is used by WebApplication to handle most aspects of sending http information to the client. It serves as a bridge between WebApplication and WebConnection. =============================================================================*/ class WebResponse extends Object native noexport; var private native const TMultiMap ReplacementMap; // C++ placeholder. var const config string IncludePath; var localized string CharSet; var WebConnection Connection; var bool bSentText; // used to warn headers already sent var bool bSentResponse; native final function Subst(string Variable, coerce string Value, optional bool bClear); native final function ClearSubst(); native final function IncludeUHTM(string Filename); native final function IncludeBinaryFile(string Filename); native final function string LoadParsedUHTM(string Filename); // For templated web items, uses Subst too native final function string GetHTTPExpiration(optional int OffsetSeconds); native final function Dump(); // only works in dev mode event SendText(string Text, optional bool bNoCRLF) { if(!bSentText) { SendStandardHeaders(); bSentText = True; } if(bNoCRLF) Connection.SendText(Text); else Connection.SendText(Text$Chr(13)$Chr(10)); } event SendBinary(int Count, byte B[255]) { Connection.SendBinary(Count, B); } function SendCachedFile(string Filename, optional string ContentType) { if(!bSentText) { SendStandardHeaders(ContentType, true); bSentText = True; } IncludeUHTM(Filename); } function FailAuthentication(string Realm) { HTTPError(401, Realm); } function HTTPResponse(string Header) { HTTPHeader(Header); bSentResponse = True; } function HTTPHeader(string Header) { if(bSentText) Log("Can't send headers - already called SendText()"); Connection.SendText(Header$Chr(13)$Chr(10)); } function HTTPError(int ErrorNum, optional string Data) { switch(ErrorNum) { case 400: HTTPResponse("HTTP/1.1 400 Bad Request"); SendText("400 Bad Request

400 Bad Request

If you got this error from a standard web browser, please mail jack@epicgames.com and submit a bug report."); break; case 401: HTTPResponse("HTTP/1.1 401 Unauthorized"); HTTPHeader("WWW-authenticate: basic realm=\""$Data$"\""); SendText("401 Unauthorized

401 Unauthorized

"); break; case 404: HTTPResponse("HTTP/1.1 404 Object Not Found"); SendText("404 File Not Found

404 File Not Found

The URL you requested was not found."); break; default: break; } } function SendStandardHeaders( optional string ContentType, optional bool bCache ) { if(ContentType == "") ContentType = "text/html"; if(!bSentResponse) HTTPResponse("HTTP/1.1 200 OK"); // if _RO_ HTTPHeader("Server: UnrealEngine UWeb Web Server Build "$Connection.Level.ROVersion); // else //HTTPHeader("Server: UnrealEngine UWeb Web Server Build "$Connection.Level.EngineVersion); HTTPHeader("Content-Type: "$ContentType); if (bCache) { HTTPHeader("Cache-Control: max-age="$Connection.WebServer.ExpirationSeconds); // Need to compute an Expires: tag .... arrgggghhh HTTPHeader("Expires:"@GetHTTPExpiration(Connection.WebServer.ExpirationSeconds)); } HTTPHeader("Connection: Close"); HTTPHeader(""); } function Redirect(string URL) { HTTPResponse("HTTP/1.1 302 Document Moved"); HTTPHeader("Location: "$URL); SendText("Document Moved"); SendText("

Object Moved

This document may be found here."); } defaultproperties { IncludePath="/Web" CharSet="iso-8859-1" }