{This unit is part of United Openlibraries of Sound (uos)} { This is HTTP Thread Getter created by Andrew Haines -> andrewd207@aol.com License : modified LGPL. Fred van Stappen / fiens@hotmail.com} unit uos_httpgetthread; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Pipes; type { TThreadHttpGetter } TThreadHttpGetter = class(TThread) private FOutStream: TOutputPipeStream; FWantedURL: string; FIcyMetaInt: int64; FOnIcyMetaInt: TNotifyEvent; property OnIcyMetaInt: TNotifyEvent read FOnIcyMetaInt write FOnIcyMetaInt; procedure DoIcyMetaInt; function GetRedirectURL(AResponseStrings: TStrings): string; procedure Headers(Sender: TObject); protected procedure Execute; override; public FIsRunning: Boolean; ICYenabled: Boolean; property IcyMetaInt: int64 read FIcyMetaInt; property IsRunning: Boolean read FIsRunning; constructor Create(AWantedURL: string; AOutputStream: TOutputPipeStream); end; implementation uses fphttpclient, openssl, { This implements the procedure InitSSLInterface } opensslsockets; { TThreadHttpGetter } function TThreadHttpGetter.GetRedirectURL(AResponseStrings: TStrings): string; var S: string; F: integer; Search: string = 'location:'; begin Result := ''; for S in AResponseStrings do begin // WriteLn(S); F := Pos(Search, Lowercase(s)); if F > 0 then begin Inc(F, Length(Search)); Exit(Trim(Copy(S, F, Length(S) - F + 1))); end; end; end; procedure TThreadHttpGetter.DoIcyMetaInt; begin if Assigned(FOnIcyMetaInt) then FOnIcyMetaInt(Self); end; procedure TThreadHttpGetter.Headers(Sender: TObject); begin FIcyMetaInt := StrToInt64Def(TFPHTTPClient(Sender).GetHeader(TFPHTTPClient(Sender).ResponseHeaders, 'icy-metaint'), 0); if (FIcyMetaInt > 0) and (FOnIcyMetaInt <> nil) then Synchronize(@DoIcyMetaInt); end; procedure TThreadHttpGetter.Execute; var Http: TFPHTTPClient; URL: string; err: shortint = 0; begin URL := FWantedURL; if pos(' ', URL) > 0 then FIsRunning := False else begin InitSSLInterface; Http := TFPHTTPClient.Create(nil); http.AllowRedirect := True; http.IOTimeout := 2000; repeat try Http.RequestHeaders.Clear; if ICYenabled = True then Http.OnHeaders := @Headers; // writeln(' avant http.get'); Http.Get(URL, FOutStream); // writeln(' apres http.get'); except on e: EHTTPClient do begin // writeln(' Http.ResponseStatusCode ' +inttostr(Http.ResponseStatusCode)); if (Http.ResponseStatusCode > 399) or (Http.ResponseStatusCode < 1) then // not accessible begin FIsRunning := False; break; end; if Http.ResponseStatusCode = 302 then begin URL := GetRedirectURL(Http.ResponseHeaders); if URL <> '' then Continue; end else Break; // raise E; end; on e: Exception do begin // WriteLn(e.Message); end else // Raise; Break; end; Break; until (False); try //FOutStream.Free; Http.Free; finally // make sure this is set to false when done FIsRunning := False; end; end; end; constructor TThreadHttpGetter.Create(AWantedURL: string; AOutputStream: TOutputPipeStream); begin inherited Create(True); ICYenabled := False; FIsRunning := True; FWantedURL := AWantedURL; FOutStream := AOutputStream; // Start; end; end.