Poniższy program wysyła metodą HEAD nagłówki do serwera, dzięki temu otrzymuje od serwera tylko nagłówki bez ew. treści pliku i stwierdza po nich obecność pliki na serwerze.
Do sekcji uses należy dopisać unit IdTCPClient - unit jest z pakietu Indy a program był testowany na Indy 9 i Delphi 7
Kod:
type TPlikInfo=record
status:string;
rozmiar:Int64;
blad:byte;
lokalizacja:string;
typ:string;
end;
const HeFileExist=0;
HeServerError=1;
HeFileNotFound=2;
HeRedirected=3;
// powyżej jest zadeklarowany typ który zwraca funkcja sprawdzająca, zwraca ona status otrzymany od serwera, rozmiar pliku, rodzaj błędu jeśli wystąpił, lokalizację pliku jeśli nastąpiło przekierowanie oraz typ mime
{
Kod sprawdzania dostępu do pliku na serwerze HTTP by Adamo 2005
}
function dajResztePo(co,wczym:string):string;
// funkcja zwraca ze stringa wszystko po wystąpieniu innego stringu
var c,w:string;
begin
c:=lowercase(co); w:=lowercase(wczym);
if Pos(c,w)>0 then
Result:=Copy(wczym,Pos(c,w)+Length(c),Length(w)) else
Result:='';
end;
function plikIstnieje(nazwa:string):TPlikInfo;
var host,request,data,text,status:string; client:TIdTCPClient;
r:TPlikInfo;
const CRL=#13#10;
begin
r.status:='503 Service Unavailable';
r.rozmiar:=-1;
r.blad:=HeServerError;
r.typ:='...';
client:=TIdTCPClient.Create(nil);
host:=nazwa;
if pos('://',host)>0 then
host:=Copy(host,pos('://',host)+3,length(host));
request:='';
if pos('/',host)>0 then begin
request:=Copy(host,pos('/',host),length(host));
host:=Copy(host,1,pos('/',host)-1);
end;
if pos('?',host)>0 then begin
request:=Copy(host,pos('?',host),length(host))+request;
host:=Copy(host,1,pos('?',host)-1);
end;
if (length(request)<1) or (request[1]<>'/') then
request:='/'+request;
r.lokalizacja:='http://'+host+request;
client.Port:=80;
client.Host:=host;
try
client.Connect(3000);
data:='HEAD '+request+' HTTP/1.0'+CRL+
'Accept: ..., */*'+CRL+
'Referer: http://'+host+CRL+
'Accept-Language: pl'+CRL+
'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'+CRL+
'Host: '+host+CRL+
'Connection: close'+CRL+CRL;
client.Write(data);
r.blad:=HeFileNotFound;
repeat
data:=client.ReadLn(#$A,1000);
////
text:=dajResztePo('HTTP/',data);
if text<>'' then
status:=dajResztePo(' ',text);
////
text:=dajResztePo('Content-type: ',data);
if text<>'' then r.typ:=text;
////
text:=dajResztePo('Location: ',data);
if text<>'' then begin
r.lokalizacja:=text;
r.blad:=3;
end;
////
text:=dajResztePo('Content-Length: ',data);
if text<>'' then r.rozmiar:=StrToInt(text);
////
until data='';
if Pos('200',status)>0 then r.blad:=HeFileExist;
r.status:=status;
except
r.blad:=HeServerError;
end;
if client.Connected then client.Disconnect;
client.Free;
if r.blad<>HeFileExist then r.rozmiar:=-1;
Result:=r;
end;
Przykład użycia:
na formę wrzucić trzy kontrolki Label i jeden Edit oraz jeden Button, pod OnClick buttona przypisać tą procedurę:
procedure TForm1.Button1Click(Sender: TObject);
var r:TPlikInfo;
begin
Enabled:=false;
Label1.Caption:='Wysyłam zapytanie do serwera ...';
Application.ProcessMessages;
r:=plikIstnieje(Edit1.Text);
case r.blad of
HeServerError: Label1.Caption:='Plik jest nieosiągalny';
HeFileNotFound: Label1.Caption:='Plik nie istnieje na serwerze';
HeRedirected: Label1.Caption:='Nastąpiło przekierowanie na '+r.lokalizacja;
HeFileExist: begin
Label1.Caption:='Plik istnieje na serwerze';
if r.rozmiar<>-1 then
Label1.Caption:=Label1.Caption+' i zajmuje '+
IntToStr(r.rozmiar)+' bajtów';
end;
end;
////
Label2.Caption:='Typ: '+r.typ;
Label3.Caption:='Status: '+r.status;
Enabled:=true;
end;
procedura zwróci w pierwszym Labelu text czy plik istnieje i ew. ile zajmuje, w drugim typ mime tego pliku a w trzecim status zwrócony przez serwer, jeśli chcemy tylko "true" lub "false" to można dopisać taką funkcję i się do niej odwoływać:
function FileExistsOnServer(URL: String): Boolean;
var r:TPlikInfo; ur:string;
begin
ur:=URL;
repeat
r:=plikIstnieje(ur);
if r.blad=HeRedirected then ur:=r.lokalizacja;
until r.blad<>HeRedirected;
Result:=r.blad=HeFileExist; // zwraca true jeśli plik istnieje
end;
Wsio
że zwraca ze stringa wszystko po wystąpieniu innego stringa :P
tj. jest string
abcdefghijkl
i po wykonaniu tej funkcji (innystring,string) jako innystring podając "def" zwróci "ghijkl"
// funkcja zwraca ze stringa wszystko po wystąpieniu innego stringu
o so cho?