| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- unit httpprothandler;
- interface
- {$IFDEF FPC}
- {$mode delphi}{$H+}
- {$ENDIF}
- {$ifdef unix}
- {$define usezlib}
- {$define useopenssl}
- {$endif}
- {$IFDEF POSIX}
- {$define usezlib}
- {$define useopenssl}
- {$ENDIF}
- {$ifdef win32}
- {$define usezlib}
- {$define useopenssl}
- {$endif}
- {$ifdef win64}
- {$define usezlib}
- {$define useopenssl}
- {$endif}
- uses
- {$IFNDEF NO_HTTP}
- {$ifdef usezlib}
- IdCompressorZLib, //for deflate and gzip content encoding
- {$endif}
- IdAuthenticationDigest, //MD5-Digest authentication
- {$ifdef useopenssl}
- IdSSLOpenSSL, //ssl
- IdAuthenticationNTLM, //NTLM - uses OpenSSL libraries
- {$endif}
- Classes, SysUtils,
- IdHTTPHeaderInfo, //for HTTP request and response info.
- IdHTTP,
- {$ENDIF}
- prothandler,
- IdURI;
- type
- THTTPProtHandler = class(TProtHandler)
- protected
- {$IFNDEF NO_HTTP}
- function GetTargetFileName(AHTTP : TIdHTTP; AURI : TIdURI) : String;
- {$ENDIF}
- public
- class function CanHandleURL(AURL : TIdURI) : Boolean; override;
- procedure GetFile(AURL : TIdURI); override;
- end;
- implementation
- class function THTTPProtHandler.CanHandleURL(AURL : TIdURI) : Boolean;
- begin
- {$IFNDEF NO_HTTP}
- Result := UpperCase(AURL.Protocol)='HTTP';
- {$ifdef useopenssl}
- if not Result then
- begin
- Result := UpperCase(AURL.Protocol)='HTTPS';
- end;
- {$endif}
- {$ELSE}
- Result := False;
- {$ENDIF}
- end;
- procedure THTTPProtHandler.GetFile(AURL : TIdURI);
- {$IFNDEF NO_HTTP}
- var
- {$ifdef useopenssl}
- LIO : TIdSSLIOHandlerSocketOpenSSL;
- {$endif}
- LHTTP : TIdHTTP;
- LStr : TMemoryStream;
- i : Integer;
- LHE : EIdHTTPProtocolException;
- LFName : String;
- {$ifdef usezlib}
- LC : TIdCompressorZLib;
- {$endif}
- begin
- {$ifdef useopenssl}
- LIO := TIdSSLIOHandlerSocketOpenSSL.Create;
- {$endif}
- {$ifdef usezlib}
- LC := TIdCompressorZLib.Create;
- {$endif}
- try
- LHTTP := TIdHTTP.Create;
- try
- {$ifdef useopenssl}
- LHTTP.Compressor := LC;
- {$endif}
- //set to false if you want this to simply raise an exception on redirects
- LHTTP.HandleRedirects := True;
- {
- Note that you probably should set the UserAgent because some servers now screen out requests from
- our default string "Mozilla/3.0 (compatible; Indy Library)" to prevent address harvesters
- and Denial of Service attacks. SOme people have used Indy for these.
- Note that you do need a Mozilla string for the UserAgent property. The format is like this:
- Mozilla/4.0 (compatible; MyProgram)
- }
- LHTTP.Request.UserAgent := 'Mozilla/4.0 (compatible; httpget)';
- LStr := TMemoryStream.Create;
- {$ifdef useopenssl}
- LHTTP.IOHandler := LIO;
- {$endif}
- for i := 0 to LHTTP.Request.RawHeaders.Count -1 do
- begin
- FLogData.Add(LHTTP.Request.RawHeaders[i]);
- if FVerbose then
- begin
- WriteLn({$IFDEF FPC}stdout{$ELSE}output{$ENDIF},LHTTP.Request.RawHeaders[i]);
- end;
- end;
- LHTTP.Get(AURL.URI,LStr);
- for i := 0 to LHTTP.Response.RawHeaders.Count -1 do
- begin
- FLogData.Add(LHTTP.Response.RawHeaders[i]);
- if FVerbose then
- begin
- WriteLn({$IFDEF FPC}stdout{$ELSE}output{$ENDIF},LHTTP.Response.RawHeaders[i]);
- end;
- end;
- LFName := GetTargetFileName(LHTTP,AURL);
- if LFName <> '' then
- begin
- LStr.SaveToFile(LFName);
- end;
- except
- on E : Exception do
- begin
- if E is EIdHTTPProtocolException then
- begin
- LHE := E as EIdHTTPProtocolException;
- WriteLn({$IFDEF FPC}stderr{$ELSE}ErrOutput {$ENDIF},'HTTP Protocol Error - '+IntToStr(LHE.ErrorCode));
- WriteLn({$IFDEF FPC}stderr{$ELSE}ErrOutput {$ENDIF},LHE.ErrorMessage);
- if Verbose = False then
- begin
- for i := 0 to FLogData.Count -1 do
- begin
- Writeln({$IFDEF FPC}stderr{$ELSE}ErrOutput {$ENDIF},FLogData[i]);
- end;
- end;
- end
- else
- begin
- Writeln({$IFDEF FPC}stderr{$ELSE}ErrOutput {$ENDIF},E.Message);
- end;
- end;
- end;
- FreeAndNil(LHTTP);
- FreeAndNil(LStr);
- finally
- {$ifdef useopenssl}
- FreeAndNil(LIO);
- {$endif}
- {$ifdef usezlib}
- FreeAndNil(LC);
- {$endif}
- end;
- {$ELSE}
- begin
- {$ENDIF}
- end;
- {$IFNDEF NO_HTTP}
- function THTTPProtHandler.GetTargetFileName(AHTTP : TIdHTTP; AURI : TIdURI) : String;
- begin
- {
- We do things this way in case the server gave you a specific document type
- in response to a request.
- eg.
- Request: http://www.indyproject.org/
- Response: http://www.indyproject.org/index.html
- }
- if AHTTP.Response.Location <> '' then
- begin
- AURI.URI := AHTTP.Response.Location;
- end;
- Result := AURI.Document;
- if Result = '' then
- begin
- Result := 'index.html';
- end;
- end;
- {$ENDIF}
- end.
|