ich schreibe gerade einen kleinen HTTP Proxy Server der auch mehrere Browserclients verwalten koennte. Das Teil laeuft an sich wirklich gut, bis er grafiken runterladen muss vom Webserver. Das will überhaupt nicht.
Kann mir einer dabei helfen. Bitte bitte, es ist sehr wichtig. Danke schonmal.
Hier der Code:
Code: Alles auswählen
;- Proxyversuch
OnErrorGoto(?CatchError)
Declare.s CreateServerMessage(Title.s, Head.s, Text.s)
If InitNetwork() = 0
MessageRequester("Error", "Can't initialize the network !", 0)
End
EndIf
Port = 6832
Structure ClientInformation
WebserverID.l
ClientID.l
Host.s
EndStructure
NewList ClientInfo.ClientInformation()
NewList WebserverIDtoClientID.l()
ControlledCancelb.b
ToSendRequest.b
*ReceiveBuffer = AllocateMemory(61440)
*tmpstr = AllocateMemory(61440)
If CreateNetworkServer(Port)
MessageRequester("PureBasic - Server", "Server created (Port "+Str(Port)+").", 0)
Repeat
Delay(10)
SEvent.l = NetworkServerEvent()
If SEvent
ClientID.l = NetworkClientID()
Select SEvent
Case 1
AddElement(ClientInfo())
ClientInfo()\ClientID = ClientID.l
Case 2
Source.s = ""
url.s = ""
Rest.s = ""
n.l = 0
i.l = 0
HTTPVersion.s = ""
Filepath.s = ""
FileTypes.s = ""
UserAgent.s = ""
Language.s = ""
Charset.s = ""
Encoding.s = ""
Connection.s = ""
Referer.s = ""
Command.s = ""
cookie.s = ""
Host.s = ""
Request.s = ""
d.s = ""
ResetList(ClientInfo())
While NextElement(ClientInfo())
If ClientInfo()\ClientID = ClientID.l
Break
EndIf
Wend
*ReceiveBuffer = AllocateMemory(61440)
ReceiveNetworkData(ClientID.l, *ReceiveBuffer, 61440) ; Maximal 60KByte abholen
Debug "==================== Empfangen vom Client Anfang ======================"
Debug PeekS(*ReceiveBuffer)
Debug "===================== Empfangen vom Client Ende ======================="
d.s = PeekS(*ReceiveBuffer)
Buffer.s = d.s
Buffer.s = LCase(Buffer)
;- Ob es ein Kommando ist, das modifiziert werden muss, oder nicht
If Left(Buffer.s, 3) <> "get" Or Left(Buffer.s, 4) = "post"
If ClientInfo()\WebserverID <> 0
SendNetworkData(ClientInfo()\WebserverID, *ReceiveBuffer, Len(PeekS(*ReceiveBuffer))) ; d.s)
EndIf
Else
Source.s = d.s
n.l = FindString(Source.s, Chr(13)+Chr(10), 0)
Request.s = Right(Source.s, Len(Source.s) - (n.l + 1))
Command.s = Left(Source.s, n.l - 1)
If Left(Command.s, 3) = "GET"
;- wenn der Browser Daten will
n.l = FindString(Command.s, " HTTP/", 0)
url.s = Mid(Command.s, 5, Len(Command.s) - 4 - 9)
HTTPVersion.s = (Right(Command.s, 8) + Chr(13)+Chr(10))
Buffer.s = Right(url.s, Len(url.s) - 7)
Host.s = Left(Buffer.s, FindString(Buffer.s, "/", 0) - 1)
Filepath.s = Right(Buffer.s, Len(Buffer.s) - Len(Host.s))
If FindString(Host.s, ":", 0) > 0
Port.l = Val(Mid(Host.s, FindString(Host.s, ":", 0) + 1, Len(Host.s)))
Host.s = Left(Host.s, FindString(Host.s, ":", 0) - 1)
Else
Port.l = 80
EndIf
; Kommando einstellen
Command.s = "GET"
ElseIf Left(Command.s, 4) = "POST"
;- wenn der Browser Daten schicken will
n.l = FindString(Command.s, " HTTP/", 0)
url.s = Mid(Command.s, 6, Len(Command.s) - 5 - 9)
HTTPVersion.s = (Right(Command.s, 8) + Chr(13)+Chr(10))
Buffer.s = Right(url.s, Len(url.s) - 7)
Host.s = Left(Buffer.s, FindString(Buffer.s, "/", 0) - 1)
Filepath.s = Right(Buffer.s, Len(Buffer.s) - Len(Host.s))
If FindString(Host.s, ":", 0) > 0
Port.l = Val(Mid(Host.s, FindString(Host.s, ":", 0) + 1, Len(Host.s)))
Host.s = Left(Host.s, FindString(Host.s, ":", 0) - 1)
Else
Port.l = 80
EndIf
; Kommando einstellen
Command.s = "POST"
EndIf
;- Den Rest des HTTP-Requests aufspalten und die Informationen auswerten
Repeat
; Solange wiederholen, Bis Request keine Zeilenumbrüche
; mehr enthält
n.l = FindString(Request.s, Chr(13)+Chr(10), 0)
If n.l <> 0
Buffer.s = Left(Request.s, n.l - 1)
Request.s = Right(Request.s, Len(Request.s) - (n.l + 1))
; Buffer.s = Right(Buffer.s, Len(Buffer.s) - 1)
If Left(Buffer.s, 7) = "Accept:"
;- Die Datei-(MIME-)Typen, die der Browser akzeptiert
FileTypes.s = (Buffer.s + Chr(13)+Chr(10))
ElseIf Left(Buffer.s, 16) = "Accept-Language:"
;- Die Sprache, Die neben Englisch noch akzeptiert wird
Language.s = (Buffer.s + Chr(13)+Chr(10))
ElseIf Left(Buffer.s, 16) = "Accept-Encoding:"
;- Die Codierungen, Die akzeptiert werden
Encoding.s = (Buffer.s + Chr(13)+Chr(10))
ElseIf Left(Buffer.s, 8) = "Referer:"
;- Der Referer (über welchen Link man die Seite aufgerufen hat)
Referer.s = (Buffer.s + Chr(13)+Chr(10))
ElseIf Left(Buffer.s, 11) = "User-Agent:"
; Der Browser-Typ
UserAgent.s = (Buffer.s + Chr(13)+Chr(10))
ElseIf Left(Buffer.s, 7) = "Cookie:"
; Der Browser-Typ
cookie.s = (Buffer.s + Chr(13)+Chr(10))
ElseIf Left(Buffer.s, 5) = "Host:"
; Der Browser-Typ
Host2.s = (Buffer.s + Chr(13)+Chr(10))
ElseIf Left(Buffer.s, 17) = "Proxy-Connection:"
; Ganz wichtig, Connection muss auf "Keep-Alive" stehen
Connection.s = ("Connection:" + Right(Buffer.s, Len(Buffer.s) - 17) + Chr(13)+Chr(10) + Chr(13)+Chr(10))
EndIf
Else
Break
EndIf
ForEver
If HiddeReferer.l = 1
; Referer austauschen (Verschleierung der Herkunft)
Referer.s = ("Referer: " + "www.google.de" + Chr(13)+Chr(10)) ; Zum Beispiel
EndIf
*tmpstr = AllocateMemory(61440)
; http-Request zusammensetzen
Request.s = Command.s + " " + Filepath.s + " " + HTTPVersion.s + FileTypes.s + Encoding.s + Referer.s + Language.s + cookie.s + UserAgent.s + Host2.s + Connection.s
; Wenn der Host immer noch der Gleiche und man noch immer mit ihm verbunden ist
If Host = ClientInfo()\Host And ClientInfo()\WebserverID <> 0
PokeS(*tmpstr, Request.s)
SendNetworkData(ClientInfo()\WebserverID, *tmpstr, Len(PeekS(*tmpstr)))
Else
If ClientInfo()\WebserverID <> 0
CloseNetworkConnection(ClientInfo()\WebserverID)
EndIf
; Wenn der Webserver nicht erreichbar ist
ClientInfo()\WebserverID = OpenNetworkConnection(Host.s, Port.l)
If ClientInfo()\WebserverID = 0
;- Fehlernachricht an den Client senden
Buffer.s = CreateServerMessage(Host.s + " nicht erreichbar", Host.s + " nicht erreichbar.", "Der Remote-Computer " + Host.s + " ist nicht erreichbar. Stellen Sie sicher dass Sie mit dem Internet verbunden sind und dass der Remotehost online ist. Bitte nutzen Sie diesen Server nur als HTTP-Proxy.")
PokeS(*tmpstr, Buffer.s)
SendNetworkData(ClientInfo()\WebserverID, *tmpstr, Len(PeekS(*tmpstr)))
Else
PokeS(*tmpstr, Request.s)
SendNetworkData(ClientInfo()\WebserverID, *tmpstr, Len(PeekS(*tmpstr)))
ClientInfo()\Host = Host.s
EndIf
EndIf
FreeMemory(*tmpstr)
FreeMemory(*ReceiveBuffer)
EndIf
Case 4
ResetList(ClientInfo())
While NextElement(ClientInfo())
If ClientInfo()\ClientID = ClientID.l
DeleteElement(ClientInfo())
Break
EndIf
Wend
EndSelect
EndIf
;- Kontrolliere ob was vom Webserver kommt.
ResetList(ClientInfo())
While NextElement(ClientInfo())
If ClientInfo()\WebserverID <> 0
CEvent.l = NetworkClientEvent(ClientInfo()\WebserverID)
Select CEvent
Case 2
*ReceiveBuffer = AllocateMemory(61440)
ReceiveNetworkData(ClientInfo()\WebserverID, *ReceiveBuffer, 61440) ; Maximal 60KByte abholen
Debug "==================== Empfangen vom WebServer Anfang ======================"
Debug PeekS(*ReceiveBuffer)
Debug "==================== Empfangen vom Webserver Ende ======================"
SendNetworkData(ClientInfo()\ClientID, *ReceiveBuffer, Len(PeekS(*ReceiveBuffer)))
FreeMemory(*ReceiveBuffer)
EndSelect
EndIf
Wend
Until Quit = 1
EndIf
End
Procedure.s CreateServerMessage(Title.s, Head.s, Text.s)
Message.s = ""
HTTPHeader.s = ""
Tag.s = ""
Monat.s = ""
; Tag einstellen
Select DayOfWeek(Date())
Case 0
Tag = ";Sun"
Case 1
Tag.s = ";Mon"
Case 2
Tag.s = ";Tue"
Case 3
Tag.s = ";Wed"
Case 4
Tag.s = ";Thu"
Case 5
Tag.s = ";Fri"
Case 6
Tag.s = ";Sat"
EndSelect
Select Month(Date())
Case 1
MonthName.s = "Jan"
Case 2
MonthName.s = "Feb"
Case 3
MonthName.s = "Mrz"
Case 4
MonthName.s = "Apr"
Case 5
MonthName.s = "Mai"
Case 6
MonthName.s = "Jun"
Case 7
MonthName.s = "Jul"
Case 8
MonthName.s = "Aug"
Case 9
MonthName.s = "Sep"
Case 10
MonthName.s = "Okt"
Case 11
MonthName.s = "Nov"
Case 12
MonthName.s = "Dez"
EndSelect
; Die Nachricht aus den Parametern im HTML-Format erstellen
Message.s = "<html>" + Chr(13)+Chr(10)+ "<head><title>" + Title.s + "</title></head>" + Chr(13)+Chr(10)+ "<body>" + Chr(13)+Chr(10)+ "<br><br><h1>" + Head.s + "</h1>" + "<br><br><br>" + Chr(13)+Chr(10)+ Text.s + Chr(13)+Chr(10)+ "<br><br><br><i>by(e) proxy...</i>" + Chr(13)+Chr(10)+ "</body>" + Chr(13)+Chr(10)+ "</html>"
; Und den HTTPHeader, der die Einleitung für die Nachricht gibt
HTTPHeader.s = "HTTP/1.1 OK" + Chr(13)+Chr(10)+ "Date: " + Tag.s + ", " + Str(DayOfWeek(Date())+1) + " " + MonthName.s + " " + Str(FormatDate("%yyyy %hh:&ii:&ss", Date())) + Chr(13)+Chr(10)+ "Accept-Ranges: bytes" + Chr(13)+Chr(10)+ "Content-Length: " + Str(Len(Message.s)) + Chr(13)+Chr(10)+ "Connection: Keep-Alive" + Chr(13)+Chr(10)+ "Content-Type: text/html" + Chr(13)+Chr(10)+ Chr(13)+Chr(10)
ProcedureReturn (HTTPHeader.s + Message.s)
EndProcedure
CatchError:
Msg$ = "There was an error:"+Chr(13)+Chr(10)+Chr(13)+Chr(10)
Msg$ + "Description: " + GetErrorDescription()+Chr(13)+Chr(10)
Msg$ + "Total number of errors: "+Str(GetErrorCounter())+Chr(13)+Chr(10)
Msg$ + "Error in linenr: "+Str(GetErrorLineNR())+Chr(13)+Chr(10)+Chr(13)+Chr(10)
Msg$ + "The program will end now."
MessageRequester("Error!", Msg$)
; Now end the program, because we can't jump back after OnErrorGoto()
End
Torakas