[GB.XML.RPC]
* BUG: miniServer would give an out-of-bound with multiple parallel requests git-svn-id: svn://localhost/gambas/trunk@5971 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
f3264a5126
commit
183bfa39d7
1 changed files with 60 additions and 61 deletions
|
@ -28,16 +28,10 @@
|
|||
'
|
||||
'***************************************************************************
|
||||
Private Http As ServerSocket
|
||||
Private hSocket As Object[]
|
||||
Private hBuffer As String[]
|
||||
Private hProt As Short[]
|
||||
Private hLen As Integer[]
|
||||
Private hConn As Integer[]
|
||||
Private hType As Byte[]
|
||||
Private SockColl As Collection
|
||||
|
||||
Private hReply As String
|
||||
|
||||
|
||||
Event GotData(Data As String)
|
||||
Event ProcessData(Data As String)
|
||||
|
||||
|
@ -73,18 +67,12 @@ End
|
|||
|
||||
Private Sub RemoveSocket(hS As Socket)
|
||||
|
||||
Dim Bucle As Integer
|
||||
Dim cCol As Collection
|
||||
|
||||
For Bucle = 0 To hSocket.Count - 1
|
||||
|
||||
If hS = hSocket[Bucle] Then
|
||||
For Each cCol In SockColl
|
||||
If hS = cCol["socket"] Then
|
||||
Try Close #hS
|
||||
hSocket.Remove(Bucle)
|
||||
hBuffer.Remove(Bucle)
|
||||
hLen.Remove(Bucle)
|
||||
hProt.Remove(Bucle)
|
||||
hConn.Remove(Bucle)
|
||||
hType.Remove(Bucle)
|
||||
SockColl.Remove(cCol["id"])
|
||||
Break
|
||||
End If
|
||||
|
||||
|
@ -231,22 +219,23 @@ Public Sub Socket_Read()
|
|||
Dim cCount As Integer
|
||||
Dim cLen As Integer
|
||||
Dim cWait As Integer = 1
|
||||
Dim cCol As Collection
|
||||
|
||||
For Bucle = 0 To hSocket.Count - 1
|
||||
If hSocket[Bucle] = Last Then
|
||||
For Each cCol In SockColl
|
||||
If cCol["socket"] = Last Then
|
||||
hS = Last
|
||||
Break
|
||||
End If
|
||||
Endif
|
||||
Next
|
||||
|
||||
If hS = Null Then Return
|
||||
|
||||
If hBuffer[Bucle] = "" Then
|
||||
If cCol["buffer"] = "" Then
|
||||
If Lof(hS) >= 5 Then
|
||||
|
||||
Try Read #hS, Buf, Lof(hS)
|
||||
hBuffer[Bucle] = hBuffer[Bucle] & Buf
|
||||
If Left(hBuffer[Bucle], 5) <> "POST " Then
|
||||
cCol["buffer"] &= Buf
|
||||
If Left(cCol["buffer"], 5) <> "POST " Then
|
||||
hError(hS, "405 Method Not Allowed")
|
||||
RemoveSocket(hS)
|
||||
Return
|
||||
|
@ -255,21 +244,21 @@ Public Sub Socket_Read()
|
|||
End If
|
||||
Else
|
||||
Try Read #hS, Buf, Lof(hS)
|
||||
hBuffer[Bucle] = hBuffer[Bucle] & Buf
|
||||
cCol["buffer"] &= Buf
|
||||
|
||||
' Don't continue, because this is the second (or more) iteration to read the data
|
||||
' The first iteration will handle the complete request
|
||||
Return
|
||||
End If
|
||||
|
||||
If hProt[Bucle] = - 1 Then
|
||||
If InStr(hBuffer[Bucle], Chr(13)) > 0 Then
|
||||
Buf = Trim(Left(hBuffer[Bucle], InStr(hBuffer[Bucle], Chr(13)) - 1))
|
||||
If cCol["protocol"] = - 1 Then
|
||||
If InStr(cCol["buffer"], Chr(13)) > 0 Then
|
||||
Buf = Trim(Left(cCol["buffer"], InStr(cCol["buffer"], Chr(13)) - 1))
|
||||
Buf = Right(Buf, 8)
|
||||
If Buf = "HTTP/1.1" Then
|
||||
hProt[Bucle] = 1
|
||||
cCol["protocol"] = 1
|
||||
Else If Buf = "HTTP/1.0" Then
|
||||
hProt[Bucle] = 0
|
||||
cCol["protocol"] = 0
|
||||
Else
|
||||
hError(hS, "505 HTTP Version Not Supported")
|
||||
RemoveSocket(hS)
|
||||
|
@ -277,7 +266,7 @@ Public Sub Socket_Read()
|
|||
End If
|
||||
|
||||
Else
|
||||
If Len(hBuffer[Bucle]) > 4096 Then
|
||||
If Len(cCol["buffer"]) > 4096 Then
|
||||
hError(hS, "413 Request Entity Too Large")
|
||||
RemoveSocket(hS)
|
||||
Return
|
||||
|
@ -288,13 +277,13 @@ Public Sub Socket_Read()
|
|||
' It is possible the HTTP headers are send in separate TCP packets, we will wait a maximum of 1000msec
|
||||
For cCount = cWait To 199 Step 1
|
||||
If hS = Null Then Return
|
||||
If InStr(hBuffer[Bucle], Chr(13) & Chr(10) & Chr(13) & Chr(10)) Then Break
|
||||
If InStr(cCol["buffer"], Chr(13) & Chr(10) & Chr(13) & Chr(10)) Then Break
|
||||
Wait 0.005
|
||||
Next
|
||||
|
||||
If InStr(hBuffer[Bucle], Chr(13) & Chr(10) & Chr(13) & Chr(10)) Then
|
||||
If hType[Bucle] = 0 Then
|
||||
Buf = Left(hBuffer[Bucle], InStr(hBuffer[Bucle], Chr(13) & Chr(10) & Chr(13) & Chr(10)))
|
||||
If InStr(cCol["buffer"], Chr(13) & Chr(10) & Chr(13) & Chr(10)) Then
|
||||
If cCol["type"] = 0 Then
|
||||
Buf = Left(cCol["buffer"], InStr(cCol["buffer"], Chr(13) & Chr(10) & Chr(13) & Chr(10)))
|
||||
|
||||
If InStr(UCase(Buf), "CONTENT-TYPE:") > 0 Then
|
||||
sCad = Mid(Buf, InStr(UCase(Buf), "CONTENT-TYPE:") + 13)
|
||||
|
@ -304,7 +293,7 @@ Public Sub Socket_Read()
|
|||
RemoveSocket(hS)
|
||||
Return
|
||||
Else
|
||||
hType[Bucle] = 1
|
||||
cCol["type"] = 1
|
||||
End If
|
||||
Else
|
||||
hError(hS, "415 Unsupported Media Type")
|
||||
|
@ -315,7 +304,7 @@ Public Sub Socket_Read()
|
|||
If InStr(UCase(Buf), "CONTENT-LENGTH:") > 0 Then
|
||||
sCad = Mid(Buf, InStr(UCase(Buf), "CONTENT-LENGTH:") + 15)
|
||||
sCad = Trim(Left(sCad, InStr(sCad, Chr(13))))
|
||||
Try hLen[Bucle] = CInt(sCad)
|
||||
Try cCol["length"] = CInt(sCad)
|
||||
If Error Then
|
||||
hError(hS, "411 Length Required")
|
||||
RemoveSocket(hS)
|
||||
|
@ -328,9 +317,9 @@ Public Sub Socket_Read()
|
|||
End If
|
||||
|
||||
' Check for "Expect: 100-continue" option & HTTP/1.1
|
||||
If hProt[Bucle] = 1 And InStr(UCase(Buf), "EXPECT: 100-CONTINUE") > 0 Then
|
||||
If cCol["protocol"] = 1 And InStr(UCase(Buf), "EXPECT: 100-CONTINUE") > 0 Then
|
||||
' Do a special check if no body is received - only then reply
|
||||
If InStr(hBuffer[Bucle], Chr(13) & Chr(10) & Chr(13) & Chr(10)) + 3 = Len(hBuffer[Bucle]) Then
|
||||
If InStr(cCol["buffer"], Chr(13) & Chr(10) & Chr(13) & Chr(10)) + 3 = Len(cCol["buffer"]) Then
|
||||
hS.Begin
|
||||
hS.EndOfLine = gb.Windows
|
||||
Print #hS, "HTTP/1.1 100 Continue"
|
||||
|
@ -342,9 +331,9 @@ Public Sub Socket_Read()
|
|||
End If
|
||||
End If
|
||||
|
||||
If InStr(hBuffer[Bucle], Chr(13) & Chr(10) & Chr(13) & Chr(10)) Then
|
||||
If InStr(cCol["buffer"], Chr(13) & Chr(10) & Chr(13) & Chr(10)) Then
|
||||
|
||||
If hLen[Bucle] = - 1 Or hType[Bucle] <> 1 Then
|
||||
If cCol["length"] = - 1 Or cCol["type"] <> 1 Then
|
||||
hError(hS, "406 Not Acceptable")
|
||||
RemoveSocket(hS)
|
||||
Return
|
||||
|
@ -352,19 +341,19 @@ Public Sub Socket_Read()
|
|||
|
||||
For cCount = cWait To 200 Step 1
|
||||
If hS = Null Then Return
|
||||
cLen = Len(hBuffer[Bucle]) - InStr(hBuffer[Bucle], Chr(13) & Chr(10) & Chr(13) & Chr(10)) - 3
|
||||
If cLen >= hLen[Bucle] Then Break
|
||||
cLen = Len(cCol["buffer"]) - InStr(cCol["buffer"], Chr(13) & Chr(10) & Chr(13) & Chr(10)) - 3
|
||||
If cLen >= cCol["length"] Then Break
|
||||
Wait 0.005
|
||||
Next
|
||||
|
||||
' HTTP/1.0 = looseless checking, some older clients generation wrong length
|
||||
' HTTP/1.1 = strict checking
|
||||
If (hProt[Bucle] = 1 And hLen[Bucle] = cLen) Or (hProt[Bucle] = 0 And hLen[Bucle] <= cLen) Then
|
||||
ProcessQuery(hS, hBuffer[Bucle])
|
||||
If (cCol["protocol"] = 1 And cCol["length"] = cLen) Or (cCol["protocol"] = 0 And cCol["length"] <= cLen) Then
|
||||
ProcessQuery(hS, cCol["buffer"])
|
||||
Return
|
||||
Else
|
||||
|
||||
If Len(hBuffer[Bucle]) > 4096 Then
|
||||
If Len(cCol["buffer"]) > 4096 Then
|
||||
hError(hS, "413 Request Entity Too Large")
|
||||
RemoveSocket(hS)
|
||||
Return
|
||||
|
@ -378,7 +367,7 @@ Public Sub Socket_Read()
|
|||
End If
|
||||
|
||||
Else
|
||||
If Len(hBuffer[Bucle]) > 4096 Then
|
||||
If Len(cCol["buffer"]) > 4096 Then
|
||||
hError(hS, "413 Request Entity Too Large")
|
||||
RemoveSocket(hS)
|
||||
Return
|
||||
|
@ -395,20 +384,33 @@ End
|
|||
|
||||
Public Sub Http_Connection(RemoteHost As String)
|
||||
|
||||
hSocket.Add(Http.Accept())
|
||||
hBuffer.Add("")
|
||||
hProt.Add(- 1)
|
||||
hLen.Add(- 1)
|
||||
hConn.Add(0)
|
||||
hType.Add(0)
|
||||
Dim SockCollEntry As New Collection
|
||||
Dim iId As Integer
|
||||
|
||||
Randomize
|
||||
Do
|
||||
iId = Int(Rnd(1, 32768))
|
||||
Loop Until Not SockColl.Exist(iId)
|
||||
|
||||
SockCollEntry.Add("", "buffer")
|
||||
SockCollEntry.Add(Http.Accept(), "socket")
|
||||
SockCollEntry.Add(-1, "protocol")
|
||||
SockCollEntry.Add(-1, "length")
|
||||
SockCollEntry.Add(0, "type")
|
||||
SockCollEntry.Add(CStr(iId), "id")
|
||||
|
||||
SockColl.Add(SockCollEntry, CStr(iId))
|
||||
|
||||
End
|
||||
|
||||
|
||||
Public Sub Close()
|
||||
|
||||
Do While hSocket.Count > 0
|
||||
RemoveSocket(hSocket[0])
|
||||
Loop
|
||||
Dim cCol As Collection
|
||||
|
||||
For Each cCol In SockColl
|
||||
RemoveSocket(cCol["socket"])
|
||||
Next
|
||||
|
||||
Try Http.Close()
|
||||
Http = Null
|
||||
|
@ -442,17 +444,14 @@ Public Sub Listen(Port As Integer, MaxConn As Integer)
|
|||
|
||||
End
|
||||
|
||||
|
||||
Public Sub _New()
|
||||
|
||||
hSocket = New Object[]
|
||||
hBuffer = New String[]
|
||||
hProt = New Byte[]
|
||||
hLen = New Integer[]
|
||||
hConn = New Integer[]
|
||||
hType = New Byte[]
|
||||
SockColl = New Collection
|
||||
|
||||
End
|
||||
|
||||
|
||||
Public Sub _Free()
|
||||
|
||||
Me.Close()
|
||||
|
|
Loading…
Reference in a new issue