Core.Object | +--Engine.Actor | +--Engine.Info | +--Engine.InternetInfo | +--IpDrv.InternetLink | +--IpDrv.TcpLink | +--UWeb.WebConnection
WebApplication
Application
int
RawBytesExpecting
string
ReceivedData
WebRequest
Request
WebResponse
Response
WebServer
void
CheckRawBytes()
Cleanup()
CreateResponseObject()
EndOfHeaders()
ProcessGet(string S)
ProcessPost(string S)
ReceivedLine(string S)
00001 class WebConnection expands TcpLink; 00002 00003 var WebServer WebServer; 00004 var string ReceivedData; 00005 00006 var WebRequest Request; 00007 var WebResponse Response; 00008 var WebApplication Application; 00009 00010 var int RawBytesExpecting; 00011 00012 event Accepted() 00013 { 00014 WebServer = WebServer(Owner); 00015 SetTimer(30, False); 00016 } 00017 00018 event Closed() 00019 { 00020 Destroy(); 00021 } 00022 00023 event Timer() 00024 { 00025 Close(); 00026 } 00027 00028 event ReceivedText( string Text ) 00029 { 00030 local int i; 00031 local string S; 00032 00033 ReceivedData = ReceivedData $ Text; 00034 if(RawBytesExpecting > 0) 00035 { 00036 RawBytesExpecting -= Len(Text); 00037 CheckRawBytes(); 00038 00039 return; 00040 } 00041 00042 // remove a LF which arrived in a new packet 00043 // and thus didn't get cleaned up by the code below 00044 if(Left(ReceivedData, 1) == Chr(10)) 00045 ReceivedData = Mid(ReceivedData, 1); 00046 i = InStr(ReceivedData, Chr(13)); 00047 while(i != -1) 00048 { 00049 S = Left(ReceivedData, i); 00050 i++; 00051 // check for any LF following the CR. 00052 if(Mid(ReceivedData, i, 1) == Chr(10)) 00053 i++; 00054 00055 ReceivedData = Mid(ReceivedData, i); 00056 00057 ReceivedLine(S); 00058 00059 if(LinkState != STATE_Connected) 00060 return; 00061 if(RawBytesExpecting > 0) 00062 { 00063 CheckRawBytes(); 00064 return; 00065 } 00066 00067 i = InStr(ReceivedData, Chr(13)); 00068 } 00069 } 00070 00071 function ReceivedLine(string S) 00072 { 00073 if(Left(S, 4) ~= "GET ") 00074 ProcessGet(S); 00075 else 00076 if(Left(S, 5) ~= "POST ") 00077 ProcessPost(S); 00078 else 00079 if(S == "") 00080 EndOfHeaders(); 00081 else 00082 if(Request != None) 00083 { 00084 Request.ProcessHeaderString(S); 00085 } 00086 } 00087 00088 function ProcessGet(string S) 00089 { 00090 local int i; 00091 local string D; 00092 00093 if(Request == None) 00094 CreateResponseObject(); 00095 00096 Request.RequestType = Request_GET; 00097 S = Mid(S, 4); 00098 while(Left(S, 1) == " ") 00099 S = Mid(S, 1); 00100 00101 i = InStr(S, " "); 00102 00103 if(i != -1) 00104 S = Left(S, i); 00105 00106 i = InStr(S, "?"); 00107 if(i != -1) 00108 { 00109 Request.DecodeFormData(Mid(S, i+1)); 00110 S = Left(S, i); 00111 } 00112 00113 Application = WebServer.GetApplication(S, Request.URI); 00114 if(Application != None && Request.URI == "") 00115 { 00116 Response.Redirect(WebServer.ServerURL$S$"/"); 00117 Cleanup(); 00118 } 00119 else 00120 if(Application == None && Webserver.DefaultApplication != -1) 00121 { 00122 Response.Redirect(WebServer.ServerURL$Webserver.ApplicationPaths[Webserver.DefaultApplication]$"/"); 00123 Cleanup(); 00124 } 00125 } 00126 00127 function ProcessPost(string S) 00128 { 00129 local int i; 00130 00131 if(Request == None) 00132 CreateResponseObject(); 00133 00134 Request.RequestType = Request_POST; 00135 00136 S = Mid(S, 5); 00137 while(Left(S, 1) == " ") 00138 S = Mid(S, 1); 00139 00140 i = InStr(S, " "); 00141 00142 if(i != -1) 00143 S = Left(S, i); 00144 00145 i = InStr(S, "?"); 00146 if(i != -1) 00147 { 00148 Request.DecodeFormData(Mid(S, i+1)); 00149 S = Left(S, i); 00150 } 00151 Application = WebServer.GetApplication(S, Request.URI); 00152 if(Application != None && Request.URI == "") 00153 { 00154 Response.Redirect(WebServer.ServerURL$S$"/"); 00155 Cleanup(); 00156 } 00157 } 00158 00159 function CreateResponseObject() 00160 { 00161 Request = new(None) class'WebRequest'; 00162 00163 Response = new(None) class'WebResponse'; 00164 Response.Connection = Self; 00165 } 00166 00167 function EndOfHeaders() 00168 { 00169 if(Response == None) 00170 { 00171 CreateResponseObject(); 00172 Response.HTTPError(400); // Bad Request 00173 Cleanup(); 00174 return; 00175 } 00176 00177 if(Application == None) 00178 { 00179 Response.HTTPError(404); // FNF 00180 Cleanup(); 00181 return; 00182 } 00183 00184 if(Request.ContentLength != 0 && Request.RequestType == Request_POST) 00185 { 00186 RawBytesExpecting = Request.ContentLength; 00187 RawBytesExpecting -= Len(ReceivedData); 00188 CheckRawBytes(); 00189 } 00190 else 00191 { 00192 Application.Query(Request, Response); 00193 Cleanup(); 00194 } 00195 } 00196 00197 function CheckRawBytes() 00198 { 00199 if(RawBytesExpecting <= 0) 00200 { 00201 if(!(Request.ContentType ~= "application/x-www-form-urlencoded")) 00202 { 00203 Log("WebConnection: Unknown form data content-type: "$Request.ContentType); 00204 Response.HTTPError(400); // Can't deal with this type of form data 00205 } 00206 else 00207 { 00208 Request.DecodeFormData(ReceivedData); 00209 Application.Query(Request, Response); 00210 ReceivedData = ""; 00211 } 00212 Cleanup(); 00213 } 00214 } 00215 00216 function Cleanup() 00217 { 00218 if(Request != None) 00219 Request = None; 00220 00221 if(Response != None) 00222 { 00223 Response.Connection = None; 00224 Response = None; 00225 } 00226 00227 if(Application != None) 00228 Application = None; 00229 00230 Close(); 00231 } 00232 00233 defaultproperties 00234 { 00235 }