1
0
KF2-Dev-Scripts/IpDrv/Classes/WebConnection.uc
2020-12-13 18:01:13 +03:00

298 lines
5.4 KiB
Ucode

/*=============================================================================
WebConnection is the bridge that will handle all communication between
the web server and the client's browser.
Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
=============================================================================*/
class WebConnection extends TcpLink config(Web);
var WebServer WebServer;
var string ReceivedData;
var WebRequest Request;
var WebResponse Response;
var WebApplication Application;
var bool bDelayCleanup;
var int RawBytesExpecting;
var config int MaxValueLength;
var config int MaxLineLength;
// MC: Debug
var int ConnID;
event Accepted()
{
WebServer = WebServer(Owner);
SetTimer(30, False);
ConnID = WebServer.ConnID++;
`Logd("Connection"@ConnID@"Accepted");
}
event Closed()
{
`Logd("Connection"@ConnID@"Closed");
Destroy();
}
event Timer()
{
`logd("Timer Up");
bDelayCleanup = False;
Cleanup();
}
event ReceivedText( string Text )
{
local int i;
local string S;
`logd("ReceivedText"@Text);
ReceivedData $= Text;
if(RawBytesExpecting > 0)
{
RawBytesExpecting -= Len(Text);
CheckRawBytes();
return;
}
// remove a LF which arrived in a new packet
// and thus didn't get cleaned up by the code below
if(Left(ReceivedData, 1) == Chr(10))
ReceivedData = Mid(ReceivedData, 1);
i = InStr(ReceivedData, Chr(13));
while(i != -1)
{
S = Left(ReceivedData, i);
i++;
// check for any LF following the CR.
if(Mid(ReceivedData, i, 1) == Chr(10))
i++;
ReceivedData = Mid(ReceivedData, i);
ReceivedLine(S);
if(LinkState != STATE_Connected)
return;
if(RawBytesExpecting > 0)
{
CheckRawBytes();
return;
}
i = InStr(ReceivedData, Chr(13));
}
}
function ReceivedLine(string S)
{
if (S == "")
{
EndOfHeaders();
}
else
{
if(Left(S, 4) ~= "GET ")
{
ProcessGet(S);
}
else if(Left(S, 5) ~= "POST ")
{
ProcessPost(S);
}
else if(Left(S, 5) ~= "HEAD ")
{
ProcessHead(S);
}
else if(Request != None)
{
Request.ProcessHeaderString(S);
}
}
}
function ProcessHead(string S)
{
`Logd("Received HEAD:"@S);
}
function ProcessGet(string S)
{
local int i;
`logd("Received GET:"@S);
if(Request == None)
CreateResponseObject();
Request.RequestType = Request_GET;
S = Mid(S, 4);
while(Left(S, 1) == " ")
S = Mid(S, 1);
i = InStr(S, " ");
if(i != -1)
S = Left(S, i);
i = InStr(S, "?");
if(i != -1)
{
Request.DecodeFormData(Mid(S, i+1));
S = Left(S, i);
}
Application = WebServer.GetApplication(S, Request.URI);
if(Application != None && Request.URI == "")
{
Response.Redirect(S$"/");
Cleanup();
}
else if(Application == None && Webserver.DefaultApplication != -1)
{
Response.Redirect(Webserver.ApplicationPaths[Webserver.DefaultApplication]$"/");
Cleanup();
}
}
function ProcessPost(string S)
{
local int i;
`logd("Received POST:"@S);
if(Request == None)
CreateResponseObject();
Request.RequestType = Request_POST;
S = Mid(S, 5);
while(Left(S, 1) == " ")
S = Mid(S, 1);
i = InStr(S, " ");
if(i != -1)
S = Left(S, i);
i = InStr(S, "?");
if(i != -1)
{
Request.DecodeFormData(Mid(S, i+1));
S = Left(S, i);
}
Application = WebServer.GetApplication(S, Request.URI);
if(Application != None && Request.URI == "")
{
// Response.Redirect(WebServer.ServerURL$S$"/");
Response.Redirect(S$"/");
Cleanup();
}
}
function CreateResponseObject()
{
local int i;
Request = new(None) class'WebRequest';
Request.RemoteAddr = IpAddrToString(RemoteAddr);
i = InStr(Request.RemoteAddr, ":");
if (i > -1)
{
Request.RemoteAddr = Left(Request.RemoteAddr, i);
}
Response = new(None) class'WebResponse';
Response.Connection = Self;
}
function EndOfHeaders()
{
if(Response == None)
{
CreateResponseObject();
Response.HTTPError(400); // Bad Request
Cleanup();
return;
}
if(Application == None)
{
Response.HTTPError(404); // FNF
Cleanup();
return;
}
if(Request.ContentLength != 0 && Request.RequestType == Request_POST)
{
RawBytesExpecting = Request.ContentLength;
RawBytesExpecting -= Len(ReceivedData);
CheckRawBytes();
}
else
{
if (Application.PreQuery(Request, Response))
{
Application.Query(Request, Response);
Application.PostQuery(Request, Response);
}
Cleanup();
}
}
function CheckRawBytes()
{
if(RawBytesExpecting <= 0)
{
if(InStr(Locs(Request.ContentType), "application/x-www-form-urlencoded") != 0)
{
`log("WebConnection: Unknown form data content-type: "$Request.ContentType);
Response.HTTPError(400); // Can't deal with this type of form data
}
else
{
Request.DecodeFormData(ReceivedData);
if (Application.PreQuery(Request, Response))
{
Application.Query(Request, Response);
Application.PostQuery(Request, Response);
}
ReceivedData = "";
}
Cleanup();
}
}
function Cleanup()
{
if (bDelayCleanup)
return;
if(Request != None)
Request = None;
if(Response != None)
{
Response.Connection = None;
Response = None;
}
if (Application != None)
Application = None;
Close();
}
final function bool IsHanging()
{
return bDelayCleanup;
}
defaultproperties
{
//MaxValueLength=512 // Maximum size of a variable value
//MaxLineLength=4096
}