WebClient (HttpRequest, HttpResponse)
Übersicht

![]() |
JolinahBetreff: WebClient (HttpRequest, HttpResponse) |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
hab ein paar Types geschrieben um den Download von Dateien oder Quellcodes von einem HTTP-Server zu vereinfachen. Der WebClient Type berücksichtigt auch Weiterleitungen und macht automatisch einen neuen Request auf die Weiterleitung. Das ganze ist nur eine kleine Spielerei und ist nicht so optimiert, aber es funktioniert (einigermassen) ![]() HttpRequest stellt eine Anfrage an den Server dar. Mit der Methode GetResponse() erhält man dann ein HttpResponse-Objekt, welches die Antwort vom Server darstellt und Methoden bietet um die Antwort zu Speichern oder als String auszugeben. WebClient ist sozusagen ein Wrapper, der die Benutzung mit HttpRequest und HttpResponse vereinfacht. Zusätzlich gibts noch 3 Beispiele (example1-3.bmx). HttpRequest.bmx Code: [AUSKLAPPEN] 'Sendet einen Request an einen HTTP-Server Type HttpRequest Field RequestMethod:String Field HttpVersion:String Field URL:String Field Port:Int Field UserAgent:String Field PostContent:String Field Stream:TStream '--- HttpRequest erstellen --- Function Create:HttpRequest(URL:String, Port:Int = 80, RequestMethod:String = "GET", PostContent:String = "", HttpVersion:String = "HTTP/1.1") Local req:HttpRequest = New HttpRequest req.URL = URL req.Port = Port req.RequestMethod = RequestMethod.ToUpper() req.PostContent = PostContent req.HttpVersion = HttpVersion 'Verbinden und Streamobjekt erstellen Local s:TSocket = TSocket.CreateTCP() If s <> Null Then If s.Connect(HostIp(req.GetHost()), Port) Then req.Stream = TSocketStream.Create(s) 'Erste Zeile an Server senden (z.B. GET / HTTP/1.1) If req.Stream <> Null Then WriteLine(req.Stream, req.RequestMethod + " " + req.URL + " " + req.HttpVersion) EndIf Return req End Function '--- Einen zusätzlichen Header hinzufügen --- Method AddHeader(key:String, value:String) If Stream = Null Then Return 'Wird direkt zum Server gesendet WriteLine(Stream, key + ": " + value) End Method '--- Aus der URL den Host rauslesen --- Method GetHost:String() If URL = "" Then Return "" 'Teil zwischen http:// und dem nächsten Slash auslesen If Left(URL.ToLower(), 7) = "http://" Then Local pos:Int = Instr(URL, "/", 8) If pos > 0 Then Return Mid(URL.ToLower(), 8, pos - 8) Else Return Mid(URL.ToLower(), 8) EndIf EndIf Return "" End Method '--- HttpRequest durchführen und Antwort auslesen --- Method GetResponse:HttpResponse() If Stream = Null Then Return Null 'Host-Header hinzufügen Local Host:String = GetHost() If Host <> "" Then AddHeader("Host", Host) 'User-Agent-Header hinzufügen If UserAgent <> "" Then AddHeader("User-Agent", UserAgent) Else AddHeader("User-Agent", "BlitzMax Browser") EndIf 'Content-Header hinzufügen If RequestMethod.ToUpper() = "POST" 'Für POST muss der Content-Type so sein: AddHeader("Content-Type", "application/x-www-form-urlencoded") If PostContent <> "" Then AddHeader("Content-Length", PostContent.Length + 2) Else AddHeader("Content-Length", "0") EndIf EndIf 'Header abschliessen WriteLine(Stream, "") 'Bei POST den Content schreiben If RequestMethod.ToUpper() = "POST" And PostContent <> "" Then WriteLine(Stream, PostContent) EndIf 'Antwort vom Stream auslesen Local res:HttpResponse = HttpResponse.Create(Stream) Return res End Method End Type HttpResponse.bmx Code: [AUSKLAPPEN] 'Liest die Antwort von einem HTTP-Server aus Type HttpResponse Field Status:Int Field ContentType:String Field ContentLength:Int Field Header:TMap Field Stream:TStream Method New() Header = New TMap End Method '--- Von einem Stream die Antwort auslesen und als HttpResponse-Objekt zurückgeben --- Function Create:HttpResponse(Stream:TStream) Local res:HttpResponse = New HttpResponse res.Stream = Stream If Stream = Null Then Return Null 'Status-Code auslesen Local status:String = ReadLine(Stream) Local pos:Int = Instr(status, " ") If pos > 0 Then res.Status = Int(Mid(status, pos+1, 3)) 'Header auslesen und in TMap speichern While Not Eof(res.Stream) Local line:String = ReadLine(res.Stream) If line = "" Then Exit pos = Instr(line, ": ") If pos > 0 Then Local key:String = Mid(line, 1, pos-1) Local value:String = Mid(line, pos+2) res.Header.Insert(key.ToLower(), value) Select key.ToLower() Case "content-type" res.ContentType = value Case "content-length" res.ContentLength = Int(value) End Select EndIf Wend Return res End Function '--- Inhalt als String auslesen --- Method ContentString:String() Local ret:String = "" If ContentLength > 0 Then For Local i:Int = 0 To ContentLength - 1 If TSocketStream(Stream)._socket.ReadAvail() < 1 Then Exit ret :+ Chr(ReadByte(Stream)) Next Else Local read:Int = 0 While TSocketStream(Stream)._socket.ReadAvail() > 0 ret :+ Chr(ReadByte(Stream)) read :+ 1 Wend EndIf Stream.Close() Stream = Null Return ret End Method '--- Inhalt als Bank auslesen --- Method ContentBank:TBank() Local Bank:TBank = Null If ContentLength > 0 Then Bank = TBank.Create(ContentLength) For Local i:Int = 0 To ContentLength - 1 If TSocketStream(Stream)._socket.ReadAvail() < 1 Then Exit Bank.PokeByte(i, ReadByte(Stream)) Next Else Bank = TBank.Create(0) Local read:Int = 0 While TSocketStream(Stream)._socket.ReadAvail() > 0 Bank.Resize(read+1) Bank.PokeByte(read, ReadByte(Stream)) read :+ 1 Wend EndIf Stream.Close() Stream = Null Return Bank End Method '--- Inhalt in eine Datei schreiben --- Method SaveContent:Int(Path:String) If Path = Null Or Path = "" Then Return False Local dir:String = ExtractDir(Path) If FileType(dir) = 0 Then CreateDir(dir, True) Local s:TStream = WriteFile(Path) If s = Null Then Return False Local b:Int = 0 If ContentLength > 0 Then For Local i:Int = 0 To ContentLength - 1 If TSocketStream(Stream)._socket.ReadAvail() < 1 Then Exit b = ReadByte(Stream) WriteByte(s, b) Next Else Local read:Int = 0 While TSocketStream(Stream)._socket.ReadAvail() > 0 b = ReadByte(Stream) WriteByte(s, b) read :+ 1 Wend EndIf s.Close() s = Null Stream.Close() Stream = Null Return True End Method End Type WebClient.bmx Code: [AUSKLAPPEN] Include "HttpRequest.bmx" Include "HttpResponse.bmx" 'Vereinfacht die Nutzung von HttpRequest und HttpResponse Type WebClient '--- Einen Request machen der Weiterleitungen beachtet --- Function _DoRequest:HttpResponse(URL:String, Port:Int = 80) Local req:HttpRequest = HttpRequest.Create(URL, Port) Local res:HttpResponse = req.GetResponse() 'Weiterleitungen beachten... Local redircount:Int = 0 While res.Status >= 300 And res.Status <= 303 Or res.Status = 307 'Bei mehr als 5 Weiterleitungen abbrechen (Gefahr einer Endlosschleife) redircount :+ 1 If redircount > 5 Then Exit 'Stream vom vorhergehenden Request schliessen res.Stream.Close() 'Weiterleitung auslesen Local location:String = String(res.Header.ValueForKey("location")) If location = Null Or location = "" Then Exit 'Port von Weiterleitung auslesen Local p:Int = Port Local pos:Int = 0 If Left(location.ToLower(), 7) = "http://" Then pos = Instr(location, ":", 8) If pos > 0 Then Local pos2:Int = Instr(location, "/", pos+1) If pos2 > 0 Then p = Int(Mid(location, pos+1, pos2-pos-1)) Else p = Int(Mid(location, pos+1)) EndIf EndIf 'Neuer Request zur Weiterleitung machen req = HttpRequest.Create(location, p) res = req.GetResponse() Wend Return res End Function '--- Seite bzw. Datei als String zurück geben --- Function GetString:String(URL:String, Port:Int = 80) Local res:HttpResponse = _DoRequest(URL, Port) Return res.ContentString() End Function '--- Seite bzw. Datei herunterladen (in einer lokalen Datei speichern) --- Function DownloadFile:Int(Path:String, URL:String, Port:Int = 80) Local res:HttpResponse = _DoRequest(URL, Port) Return res.SaveContent(Path) End Function '--- Seite bzw. Datei als Bank zurück geben --- Function GetBank:TBank(URL:String, Port:Int = 80) Local res:HttpResponse = _DoRequest(URL, Port) Return res.ContentBank() End Function End Type example1.bmx Code: [AUSKLAPPEN] SuperStrict
Include "WebClient.bmx" 'Ein kleiner Button Type Button Field X:Int, Y:Int Field Width:Int, Height:Int Field Color:Int Field Text:String Field TextColor:Int Field OnClick() 'Callback-Funktion 'Button erstellen Function Create:Button(X:Int, Y:Int, Width:Int, Height:Int, Text:String, Color:Int = $FFFFFF, TextColor:Int = 0) Local b:Button = New Button b.X = X b.Y = Y b.Width = Width b.Height = Height b.Text = Text b.Color = Color b.TextColor = TextColor Return b End Function 'Button aktualisieren (auf Klick überprüfen) Method Update() Local mx:Int = MouseX() Local my:Int = MouseY() Local mh:Int = MouseHit(1) If mx > X And my > Y And mx < X + Width And my < Y + Height If mh Then 'Beim anklicken wird die Callback-Funktion aufgerufen If OnClick <> Null Then OnClick() EndIf EndIf End Method 'Button zeichnen Method Draw() SetColor((Color Shr 16) & $FF, (Color Shr 8) & $FF, Color & $FF) DrawRect X, Y, Width, Height SetColor((TextColor Shr 16) & $FF, (TextColor Shr 8) & $FF, TextColor & $FF) DrawText Text, X + Width / 2 - TextWidth(Text) / 2, Y + Height / 2 - TextHeight(Text) / 2 SetColor(255, 255, 255) End Method End Type Graphics 800, 600, 0 'Bild das dynamisch geladen wird Global img:TImage = Null 'Button Local b:Button = Button.Create(100, 100, 150, 30, "Klick mich!", $FFFF00) 'Funktion die bei einem Klick ausgeführt wird setzen b.OnClick = b_OnClick 'Hauptschleife Repeat Cls 'Button aktualisieren und zeichnen b.Update() b.Draw() 'Bild zeichnen wenn es vorhanden ist If img <> Null Then DrawImage img, 300, 100 Flip Until KeyHit(KEY_ESCAPE) EndGraphics End 'Funktion die vom Button aus aufgerufen wird Function b_OnClick() If img = Null Then 'Bild mit dem Type WebClient herunterladen WebClient.DownloadFile("C:\english.png", "http://www.blitzforum.de/themes/Standard/english.png") 'Bild von Festplatte laden img = LoadImage("C:\english.png") EndIf End Function example2.bmx Code: [AUSKLAPPEN] SuperStrict
Include "WebClient.bmx" 'Ein Formular automatisch ausfüllen (POST) Local req:HttpRequest = HttpRequest.Create("http://tools.cybernet.ch/adslcheck/index.php", 80, "POST") 'Variablen des Formulars übergeben req.PostContent = "requestedbc=06&tel=033 333 33 32&submit=prüfen" 'Antwort vom Server lesen Local res:HttpResponse = req.GetResponse() 'Antwort lokal speichern und im Browser öffnen If res.SaveContent("C:\response.html") Then OpenURL("C:\response.html") EndIf End example3.bmx Code: [AUSKLAPPEN] SuperStrict
Include "WebClient.bmx" 'Mit WebClient ganz einfach den Quelltext einer Seite auslesen Local text:String = WebClient.GetString("http://blitzforum.de/") Print text End |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group