From d28702273683cb154e07ce05aabe38c37ca7c7d2 Mon Sep 17 00:00:00 2001 From: Michael Neu Date: Mon, 4 Mar 2019 00:20:07 +0100 Subject: [PATCH] read and write fastcgi records on sockets --- src/Classes/FastCGIBeginRequest.cls | 21 ++++++++- src/Classes/FastCGIEndRequest.cls | 35 ++++++++++++++ src/Classes/FastCGIParams.cls | 36 +++++++++++++-- src/Classes/FastCGIStream.cls | 9 +++- src/Classes/FastCGIWebController.cls | 68 ++++++++++++++++++++++++---- src/Classes/TcpClient.cls | 22 ++++++--- 6 files changed, 169 insertions(+), 22 deletions(-) diff --git a/src/Classes/FastCGIBeginRequest.cls b/src/Classes/FastCGIBeginRequest.cls index 7769a54..84baaa3 100644 --- a/src/Classes/FastCGIBeginRequest.cls +++ b/src/Classes/FastCGIBeginRequest.cls @@ -18,8 +18,8 @@ Public Reserved As String Private Sub Class_Initialize() Set m_header = New FastCGIHeader m_header.ProtocolVersion = 1 - m_header.RequestId = m_requestId m_header.MessageType = FastCGI.FASTCGI_TYPE_BEGIN_REQUEST + m_header.RequestId = 1 m_header.ContentLength = 8 m_header.PaddingLength = 0 @@ -29,15 +29,32 @@ End Sub Private Sub IFastCGIRecord_ReadFromTcpClient(client As TcpClient) + Dim record As IFastCGIRecord + Set record = m_header + record.ReadFromTcpClient client + + Dim bytes As String + bytes = client.ReceiveBytes(m_header.ContentLength) + + Role = Marshal.BytesToInt16(StringExtensions.Substring(bytes, 0, 2)) + bytes = StringExtensions.Substring(bytes, 2) + + Flags = Marshal.BytesToInt8(StringExtensions.Substring(bytes, 0, 1)) + bytes = StringExtensions.Substring(bytes, 1) + + Reserved = bytes + + client.ReceiveBytes m_header.PaddingLength End Sub Private Sub IFastCGIRecord_WriteToTcpClient(client As TcpClient) Dim header As IFastCGIRecord Set header = m_header + header.WriteToTcpClient client Dim bytes As String - bytes = header.ToBytes() + bytes = "" bytes = bytes & Marshal.Int16ToBytes(Role) bytes = bytes & Marshal.Int8ToBytes(Flags) diff --git a/src/Classes/FastCGIEndRequest.cls b/src/Classes/FastCGIEndRequest.cls index e30ffe8..f6105a2 100644 --- a/src/Classes/FastCGIEndRequest.cls +++ b/src/Classes/FastCGIEndRequest.cls @@ -17,12 +17,47 @@ Public Reserved As String Private Sub Class_Initialize() Set m_header = New FastCGIHeader + m_header.ProtocolVersion = 1 + m_header.MessageType = FastCGI.FASTCGI_TYPE_END_REQUEST + m_header.RequestId = 1 + m_header.ContentLength = 8 + m_header.PaddingLength = 0 + + Reserved = StringExtensions.Repeat(Chr(0), 5) End Sub Private Sub IFastCGIRecord_ReadFromTcpClient(client As TcpClient) + Dim record As IFastCGIRecord + Set record = m_header + record.ReadFromTcpClient client + + Dim bytes As String + bytes = client.ReceiveBytes(m_header.ContentLength) + + AppStatus = Marshal.BytesToInt32(StringExtensions.Substring(bytes, 0, 4)) + bytes = StringExtensions.Substring(bytes, 4) + + ProtocolStatus = Marshal.BytesToInt8(StringExtensions.Substring(bytes, 0, 1)) + bytes = StringExtensions.Substring(bytes, 1) + + Reserved = bytes + + client.ReceiveBytes m_header.PaddingLength End Sub Private Sub IFastCGIRecord_WriteToTcpClient(client As TcpClient) + Dim record As IFastCGIRecord + Set record = m_header + record.WriteToTcpClient client + + Dim bytes As String + bytes = "" + + bytes = bytes & Marshal.Int32ToBytes(AppStatus) + bytes = bytes & Marshal.Int8ToBytes(ProtocolStatus) + bytes = bytes & Reserved + + client.SendString bytes End Sub diff --git a/src/Classes/FastCGIParams.cls b/src/Classes/FastCGIParams.cls index 08d5891..ab5867a 100644 --- a/src/Classes/FastCGIParams.cls +++ b/src/Classes/FastCGIParams.cls @@ -16,8 +16,8 @@ Private m_params As Collection Private Sub Class_Initialize() Set m_header = New FastCGIHeader m_header.ProtocolVersion = 1 - m_header.RequestId = m_requestId m_header.MessageType = FastCGI.FASTCGI_TYPE_PARAMS + m_header.RequestId = 1 m_header.PaddingLength = 0 Set m_params = New Collection @@ -36,6 +36,37 @@ End Sub Private Sub IFastCGIRecord_ReadFromTcpClient(client As TcpClient) + Dim record As IFastCGIRecord + Set record = m_header + record.ReadFromTcpClient client + + Set m_params = New Collection + + Dim bytes As String + bytes = client.ReceiveBytes(m_header.ContentLength) + + Dim keyLength As Integer + Dim valueLength As Integer + Dim param As FastCGIParam + + Do While Len(bytes) > 0 + keyLength = Marshal.BytesToInt8(StringExtensions.Substring(bytes, 0, 1)) + bytes = StringExtensions.Substring(bytes, 1) + valueLength = Marshal.BytesToInt8(StringExtensions.Substring(bytes, 0, 1)) + bytes = StringExtensions.Substring(bytes, 1) + + Set param = New FastCGIParam + + param.key = StringExtensions.Substring(bytes, 0, keyLength) + bytes = StringExtensions.Substring(bytes, keyLength) + + param.value = StringExtensions.Substring(bytes, 0, valueLength) + bytes = StringExtensions.Substring(bytes, valueLength) + + m_params.Add param + Loop + + client.ReceiveBytes m_header.PaddingLength End Sub @@ -53,7 +84,6 @@ Private Sub IFastCGIRecord_WriteToTcpClient(client As TcpClient) m_header.ContentLength = Len(bytes) Set record = m_header - bytes = record.ToBytes() & bytes - + record.WriteToTcpClient client client.SendString bytes End Sub diff --git a/src/Classes/FastCGIStream.cls b/src/Classes/FastCGIStream.cls index 252d1f4..3353761 100644 --- a/src/Classes/FastCGIStream.cls +++ b/src/Classes/FastCGIStream.cls @@ -34,6 +34,12 @@ End Property Private Sub IFastCGIRecord_ReadFromTcpClient(client As TcpClient) + Dim record As IFastCGIRecord + Set record = m_header + record.ReadFromTcpClient client + + Content = client.ReceiveBytes(m_header.ContentLength) + client.ReceiveBytes m_header.PaddingLength End Sub @@ -42,6 +48,7 @@ Private Sub IFastCGIRecord_WriteToTcpClient(client As TcpClient) Dim record As IFastCGIRecord Set record = m_header + record.WriteToTcpClient client - client.SendString record.ToBytes() & Content + client.SendString Content End Sub diff --git a/src/Classes/FastCGIWebController.cls b/src/Classes/FastCGIWebController.cls index 1bb8b51..50ff849 100644 --- a/src/Classes/FastCGIWebController.cls +++ b/src/Classes/FastCGIWebController.cls @@ -30,15 +30,22 @@ Private Function IWebController_ProcessRequest(request As HttpRequest) As HttpRe End Function -Private Sub SendBegin() +Private Sub WriteBegin() Dim record As IFastCGIRecord Set record = New FastCGIBeginRequest - - record.WriteToTcpClient client + record.WriteToTcpClient m_clientSocket End Sub -Private Sub SendParams() +Private Function ReadBegin() As FastCGIBeginRequest + Dim record As IFastCGIRecord + Set record = New FastCGIBeginRequest + record.ReadFromTcpClient m_clientSocket + Set ReadBegin = record +End Function + + +Private Sub WriteParams() Dim params As FastCGIParams Set params = New FastCGIParams @@ -47,14 +54,22 @@ Private Sub SendParams() Dim record As IFastCGIRecord Set record = params - record.WriteToTcpClient client + record.WriteToTcpClient m_clientSocket Set record = New FastCGIParams - record.WriteToTcpClient client + record.WriteToTcpClient m_clientSocket End Sub -Private Sub SendInput(text As String) +Private Function ReadParams() As FastCGIParams + Dim record As IFastCGIRecord + Set record = New FastCGIParams + record.ReadFromTcpClient m_clientSocket + Set ReadParams = record +End Function + + +Private Sub WriteInput(text As String) Dim stdin As FastCGIStream Set stdin = New FastCGIStream stdin.StreamType = FastCGI.FASTCGI_TYPE_STDIN @@ -63,11 +78,46 @@ Private Sub SendInput(text As String) Dim bytes As String Dim record As IFastCGIRecord Set record = stdin - record.WriteToTcpClient client + record.WriteToTcpClient m_clientSocket If Len(text) > 0 Then stdin.Content = "" Set record = stdin - record.WriteToTcpClient client + record.WriteToTcpClient m_clientSocket End If End Sub + + +Private Sub WriteOutput(text As String) + Dim stdin As FastCGIStream + Set stdin = New FastCGIStream + stdin.StreamType = FastCGI.FASTCGI_TYPE_STDOUT + stdin.Content = text + + Dim bytes As String + Dim record As IFastCGIRecord + Set record = stdin + record.WriteToTcpClient m_clientSocket +End Sub + + +Private Sub ReadStream() + Dim record As IFastCGIRecord + Set record = New FastCGIStream + record.ReadFromTcpClient m_clientSocket +End Sub + + +Private Sub WriteEnd() + Dim record As IFastCGIRecord + Set record = New FastCGIEndRequest + record.WriteToTcpClient m_clientSocket +End Sub + + +Private Sub ReadEnd() + Dim record As IFastCGIRecord + Set record = New FastCGIEndRequest + record.ReadFromTcpClient m_clientSocket +End Sub + diff --git a/src/Classes/TcpClient.cls b/src/Classes/TcpClient.cls index a120e20..de902df 100644 --- a/src/Classes/TcpClient.cls +++ b/src/Classes/TcpClient.cls @@ -41,21 +41,29 @@ Public Function SendString(ByVal message As String) As Long End Function -Public Function ReceiveString() As String - Dim message As String - Dim buffer As String * 1024 +Public Function ReceiveBytes(ByVal bytes As Long) As String + Dim buffer As String + buffer = StringExtensions.Repeat(Chr(0), bytes) + Dim readBytes As Long + readBytes = wsock32.recv(m_clientSocket, buffer, bytes, 0) + ReceiveBytes = StringExtensions.Substring(buffer, 0, readBytes) +End Function + + +Public Function ReceiveString() As String + Dim buffer As String + Dim message As String message = "" Do - buffer = "" - readBytes = wsock32.recv(m_clientSocket, buffer, Len(buffer), 0) + buffer = ReceiveBytes(1024) - If readBytes > 0 Then + If Len(buffer) > 0 Then message = message & Trim(buffer) End If - Loop While readBytes > 0 + Loop While Len(buffer) > 0 ReceiveString = Trim(message) End Function