Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Funktion URLExists? (https://www.delphipraxis.net/97077-funktion-urlexists.html)

PeterPanino 4. Aug 2007 01:12


Funktion URLExists?
 
Ich möchte mit JvHttpUrlGrabber und JvFtpUrlGrabber (beide aus der JEDI-VCL) eine Datei aus dem Internet herunterladen, was eigentlich gut funktioniert.

Wie kann ich jedoch vor dem Herunterladen feststellen, ob die zu herunterladendene Datei überhaupt existiert? (Für lokale Dateien gibt es ja die Funktion FileExists, aber für Dateien im Internet?). Wie könnte also eine Funktion URLExists aussehen?

Die beiden oben genannten Komponenten geben bei OnError nämlich keinen Fehler aus, wenn die angegebene URL nicht existiert. Sie laden bei einer nicht existierenden URL stattdessen ohne zu fragen einfach die "Fehler-404" Seite herunter!

wicht 4. Aug 2007 01:52

Re: Funktion URLExists?
 
Ich kenne die von dir genannten Klassen nicht - aber es ist nicht sonderlich schwierig eine Verbindung aufzubauen und den Response-Code zu checken. Anders wird es hier vermutlich nicht gehen. Ist bei HTTP einfacher als bei FTP - da musst du dich verbinden, in das Verzeichnis wechseln und dann z.B. die Größe der auf-Existenz-zu-prüfenden Datei abfragen. Gibt das einen Fehler, existiert die Datei nicht, oder dir fehlen die Rechte, um auf selbige zuzugreifen...

Für HTTP jedenfalls müsstest du einfach ein "GET /pfad/zur/seite.html HTTP/1.0"#13#10#13#10 schicken, wenn du 404 zurückbekommst, gibt es die Seite nicht. Da es aber viele Response-Codes gibt, musst du da auch genau schauen, was als OK gilt und was nicht. Alternativ könntest du zum Beispiel die ICS-HTTP-Komponente benutzen - die wirft eine Exception, wenn ein HTTP-Dokument nicht existiert.

PeterPanino 4. Aug 2007 01:59

Re: Funktion URLExists?
 
Zitat:

Zitat von wicht
Ich kenne die von dir genannten Klassen nicht - aber es ist nicht sonderlich schwierig eine Verbindung aufzubauen und den Response-Code zu checken. Anders wird es hier vermutlich nicht gehen. Ist bei HTTP einfacher als bei FTP - da musst du dich verbinden, in das Verzeichnis wechseln und dann z.B. die Größe der auf-Existenz-zu-prüfenden Datei abfragen. Gibt das einen Fehler, existiert die Datei nicht, oder dir fehlen die Rechte, um auf selbige zuzugreifen...

Für HTTP jedenfalls müsstest du einfach ein "GET /pfad/zur/seite.html HTTP/1.0"#13#10#13#10 schicken, wenn du 404 zurückbekommst, gibt es die Seite nicht. Da es aber viele Response-Codes gibt, musst du da auch genau schauen, was als OK gilt und was nicht. Alternativ könntest du zum Beispiel die ICS-HTTP-Komponente benutzen - die wirft eine Exception, wenn ein HTTP-Dokument nicht existiert.

Hmm, danke vorerst mal, hört sich alles sehr kompliziert an. Präzisierung: Die gewünschte Funktion müsste sowohl bei HTTP als auch bei FTP funktionieren. Und es müsste nicht die Existenz einer Seite geprüft werden, sondern einer beliebigen Datei. Geht das?

Klaus01 4. Aug 2007 08:44

Re: Funktion URLExists?
 
Guten Morgen,

hättest Du die Suche bemüht, hättest Du diesen Post vom marabu finden können.

Grüße
Klaus

hathor 4. Aug 2007 09:29

Re: Funktion URLExists?
 
http://www.cryer.co.uk/brian/delphi/...isurlvalid.htm

Delphi-Quellcode:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, WinINet;



function IsUrlValid(const url: string): boolean;
var
  hInet: HINTERNET;
  hConnect: HINTERNET;
  infoBuffer: array [0..512] of char;
  dummy: DWORD;
  bufLen: DWORD;
  okay: LongBool;
  reply: String;
begin
  hInet := InternetOpen(PChar(application.title),
    INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,nil,nil,0);
  hConnect := InternetOpenUrl(hInet,PChar(url),nil,0,
    INTERNET_FLAG_NO_UI,0);
  if not Assigned(hConnect) then
    //----------------------------------------------------------
    // If we couldn't open a connection then we know the url
    // is bad. The most likely reason is that the url is bad,
    // but it could be because of an unknown or badly specified
    // protocol.
    //----------------------------------------------------------
    result := false
  else
  begin // Create a request for the url.
    dummy := 0;
    bufLen := Length(infoBuffer);
    okay := HttpQueryInfo(hConnect,HTTP_QUERY_STATUS_CODE,
      @infoBuffer[0],bufLen,dummy);
    if not okay then
      // Probably working offline, or no internet connection.
      result := False
    else
    begin
      reply := infoBuffer;
      if reply = '200' then
      begin
        Form1.Memo1.Lines.Add('200');    // File exists, all ok.
        result := True; end
      else if reply = '401' then
       begin
        Form1.Memo1.Lines.Add('401');    // Not authorised. Assume page exists,
                    // but we can't check it.
        result := True; end
      else if reply = '404' then
       begin
        Form1.Memo1.Lines.Add('404');   // No such file.
        result := False; end
      else if reply = '500' then
       begin
        Form1.Memo1.Lines.Add('500');   // Internal server error.
        result := False; end
      else
        // Shouldn't get here! It means there is
        // a status code left unhandled.
        result := False;
    end;
    InternetCloseHandle(hConnect);
  end;
  InternetCloseHandle(hInet);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 if IsUrlValid('http://www.alcpu.com/CoreTemp/CoreTemp.zip') then
 Memo1.Lines.Add('CORETEMP.zip exists');
end;
(*
     HTTP_STATUS_OK                 200
     HTTP_STATUS_CREATED            201
     HTTP_STATUS_ACCEPTED           202
     HTTP_STATUS_NO_CONTENT         204
     HTTP_STATUS_MOVED_PERM         301
     HTTP_STATUS_MOVED_TEMP         302
     HTTP_STATUS_NOT_MODIFIED       304
     HTTP_STATUS_USE_PROXY          305
     HTTP_STATUS_BAD_REQUEST        400
     HTTP_STATUS_UNAUTHORIZED       401
     HTTP_STATUS_FORBIDDEN          403
     HTTP_STATUS_NOT_FOUND          404
     HTTP_STATUS_METHOD_NOT_ALLOWED 405
     HTTP_STATUS_PROXY_AUTH_REQRD   407
     HTTP_STATUS_LENGTH_REQUIRED    411
     HTTP_STATUS_SERVER_ERROR       500
     HTTP_STATUS_NOT_IMPLEMENTED    501
     HTTP_STATUS_BAD_GATEWAY        502
     HTTP_STATUS_SERVICE_UNAVAILABLE 503
     HTTP_STATUS_GATEWAY_TIMEOUT    504
     HTTP_STATUS_UNSUPPORTED_VERSION 505
*)

fkerber 4. Aug 2007 09:31

Re: Funktion URLExists?
 
Hi!

Dazu fällt mir doch spontan folgendes ein:

http://www.delphipraxis.net/internal...t.php?t=115256



Ciao, Frederic

Klaus01 4. Aug 2007 10:23

Re: Funktion URLExists?
 
@hathor
Zitat:

Zitat von hathor
@Klaus01:

Deine Antwort ist off topic!
URLexists nützt ihm nichts - er will quasi ein URLFileExists...

Nein, sehe ich nicht so.

Sonst erklär mir bitte einmal den Unterschied zwischen der Routine vom marabu und der von Sakura.

Einen schönen Tag noch.

Grüße
Klaus

hathor 4. Aug 2007 18:41

Re: Funktion URLExists?
 
Beide Funktionen

function UrlExists

function HTTPFileExists

bringen das gleiche Resultat, aber der Funktionsname HTTPFileExists ist aussagekräftiger...

z.B. in einer Suchfunktion.

Im Übrigen finde ich fast alle Hinweise auf eine Suchfunktion überflüssig !!!

marabu 4. Aug 2007 19:26

Re: Funktion URLExists?
 
Hallo,

ausgehend von Peters Beschreibung in Beitrag #1 würde ich eine Funktion UrlExists() etwa so entwerfen:

Delphi-Quellcode:
function UrlExists(const url: string): Boolean;
begin
  if AnsiStartsText('ftp', url) then
    Result := FTPExists(url)
  else
  if AnsiStartsText('http', url) then
    Result := HTTPExists(url)
  else
    raise Exception.Create(S_WRONG_URL);
  end;
end;
Ich würde beim HTTP-Protokoll nicht auf ein automatisches Redirection-Handling verzichten mögen. Beim FTP-Protokoll würde ich im Zielverzeichnis mittels LIST-Befehl prüfen, ob die gesuchte Datei existiert. Besonderes Augenmerk muss man dabei der Konfiguration der Komponenten TIdHTTP und TIdFTP widmen. Wenn UrlExists() universell einsetzbar sein soll, dann müsste noch ein Config-Record als zusätzlicher Parameter übergeben werden, aus dem man Proxy-Parameter u.ä. entnehmen kann.

Freundliche Grüße

PeterPanino 4. Aug 2007 19:45

Re: Funktion URLExists?
 
Zitat:

Zitat von hathor
http://www.cryer.co.uk/brian/delphi/wininet/example_isurlvalid.htm
...

Vielen Dank an alle für die Tipps. Ich habe zum Testen zunächst mal das Beispiel von hathor gewählt, weil idHTTP (Indy) das Programm doch um sehr viele KBytes aufbläht; WinnINet hingegen scheint sehr "sparsam" zu sein.

Bei der Funktion IsUrlValid von hathor tritt folgender sehr seltsamer Fehler auf:

Dieser Aufruf ergibt True:
Delphi-Quellcode:
IsUrlValid([url]http://www.uni-muenster.de/Jura.itm/hoeren/material/Skript/skript_Januar2006.pdf[/url])
Dieser Aufruf (1 falsches Zeichen im Dateipfad) ergibt jedoch auch True(!!):
Delphi-Quellcode:
IsUrlValid([url]http://www.uni-muenster.de/Jura.itm/hoeren/material/Skript/skript_Januar2006.pdff[/url])
(ein f wurde an den Dateinamen angehängt)

Auch dieser Aufruf (2 falsche Zeichen im Dateipfad) ergibt True:
Delphi-Quellcode:
IsUrlValid([url]http://www.uni-muenster.de/Jura.itm/hoeren/matemrial/Skript/skript_Januar2006.pdff[/url])
(zusätzlich ein m wurde in den Pfad eingefügt)

Der folgende Aufruf (3 falsche Zeichen im Dateipfad) ergibt jedoch Fehlercode 404:
Delphi-Quellcode:
IsUrlValid([url]http://www.uni-muenster.de/Jura.itm/hoeren/matemmrial/Skript/skript_Januar2006.pdff[/url])
Das heißt also, bis zu 2 falsche Zeichen ergeben noch keinen Fehler! Warum? Bei anderen Servern jedoch ergibt schon 1 falsches Zeichen im Dateipfad einen Fehler. Warum?

hathor 4. Aug 2007 20:49

Re: Funktion URLExists?
 
http://www.uni-muenster.de/Jura.itm/...Januar2006.pdf
kann trotz Tippfehler geladen werden.
Begründung:

Zitat bei 3 Fehlern:

Nicht gefunden

Obwohl unser Server in der Lage ist, kleinere Tippfehler zu korrigieren, konnte die angeforderte Information nicht gefunden werden. Der Verweis, dem Sie gefolgt sind, ist überholt oder falsch oder der Server wurde so konfiguriert, dass Sie nicht darauf zugreifen können.
Probieren Sie, einfach die Adresse abzukürzen, indem Sie alles nach dem letzten, vorletzten, drittletzten usw. Schrägstrich weglassen.

Das heisst: Der Server ist sehr fehlertolerant....

DGL-luke 4. Aug 2007 21:13

Re: Funktion URLExists?
 
Zitat:

Zitat von wicht
Da es aber viele Response-Codes gibt, musst du da auch genau schauen, was als OK gilt und was nicht.

OK = 2xx ;-)

PeterPanino 4. Aug 2007 22:00

Re: Funktion URLExists?
 
Leider funktioniert IsUrlValid (von hathor genannt) bei FTP nicht. Wie könnte also eine universelle UrlExists-Funktion aussehen?

Der Ansatz von marabu ist ja schon sehr vielversprechend:

Delphi-Quellcode:
function UrlExists(const url: string): Boolean;
begin
  if AnsiStartsText('ftp', url) then
    Result := FTPExists(url)
  else
  if AnsiStartsText('http', url) then
    Result := HTTPExists(url)
  else
    raise Exception.Create(S_WRONG_URL);
  end;
end;

hathor 4. Aug 2007 23:09

Re: Funktion URLExists?
 
Example of FtpFindFirstFile and InternetFindNextFile:

http://www.cryer.co.uk/brian/delphi/...stnextfile.htm


FTP programming with the WinInet API:

http://www.cryer.co.uk/brian/delphi/...#HttpQueryInfo


Vielleicht bringt uns das weiter?

PeterPanino 5. Aug 2007 00:44

Re: Funktion URLExists?
 
Gibt es nicht Standardantworten, die FTP-Server zurückgeben, wenn eine angeforderte Datei nicht existiert?

PeterPanino 5. Aug 2007 01:03

Re: Funktion URLExists?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Jetzt hab ich's!!! -> Die JEDI-Komponente TJvUrlListGrabber macht alles das, was ich wollte!

Wenn die Datei auf dem FTP-Server nicht existiert, kommt bei OnError folgende Meldung:
Zitat:

550 Could not get file size.
550 Failed to open file.
(S. angehängtes Bild FtpError.gif)

Jetzt müsste ich nur noch wissen, ob diese Codes Standard bei allen FTP-Servern sind. Auf der Seite FTP Status-Codes werden die Rückgabecodes für den Microsoft Internet Information Server (IIS) beschrieben. Gelten die nur für den IIS oder allgemein für alle FTP-Server?

Klaus01 5. Aug 2007 09:44

Re: Funktion URLExists?
 
Vielleicht schaut Du einmal in die FTP RFC959, dort findest Du die ReturnCodes.

Grüße
Klaus


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz