2
0

httpprothandler.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. unit httpprothandler;
  2. interface
  3. {$IFDEF FPC}
  4. {$mode delphi}{$H+}
  5. {$ENDIF}
  6. {$ifdef unix}
  7. {$define usezlib}
  8. {$define useopenssl}
  9. {$endif}
  10. {$IFDEF POSIX}
  11. {$define usezlib}
  12. {$define useopenssl}
  13. {$ENDIF}
  14. {$ifdef win32}
  15. {$define usezlib}
  16. {$define useopenssl}
  17. {$endif}
  18. {$ifdef win64}
  19. {$define usezlib}
  20. {$define useopenssl}
  21. {$endif}
  22. uses
  23. {$IFNDEF NO_HTTP}
  24. {$ifdef usezlib}
  25. IdCompressorZLib, //for deflate and gzip content encoding
  26. {$endif}
  27. IdAuthenticationDigest, //MD5-Digest authentication
  28. {$ifdef useopenssl}
  29. IdSSLOpenSSL, //ssl
  30. IdAuthenticationNTLM, //NTLM - uses OpenSSL libraries
  31. {$endif}
  32. Classes, SysUtils,
  33. IdHTTPHeaderInfo, //for HTTP request and response info.
  34. IdHTTP,
  35. {$ENDIF}
  36. prothandler,
  37. IdURI;
  38. type
  39. THTTPProtHandler = class(TProtHandler)
  40. protected
  41. {$IFNDEF NO_HTTP}
  42. function GetTargetFileName(AHTTP : TIdHTTP; AURI : TIdURI) : String;
  43. {$ENDIF}
  44. public
  45. class function CanHandleURL(AURL : TIdURI) : Boolean; override;
  46. procedure GetFile(AURL : TIdURI); override;
  47. end;
  48. implementation
  49. class function THTTPProtHandler.CanHandleURL(AURL : TIdURI) : Boolean;
  50. begin
  51. {$IFNDEF NO_HTTP}
  52. Result := UpperCase(AURL.Protocol)='HTTP';
  53. {$ifdef useopenssl}
  54. if not Result then
  55. begin
  56. Result := UpperCase(AURL.Protocol)='HTTPS';
  57. end;
  58. {$endif}
  59. {$ELSE}
  60. Result := False;
  61. {$ENDIF}
  62. end;
  63. procedure THTTPProtHandler.GetFile(AURL : TIdURI);
  64. {$IFNDEF NO_HTTP}
  65. var
  66. {$ifdef useopenssl}
  67. LIO : TIdSSLIOHandlerSocketOpenSSL;
  68. {$endif}
  69. LHTTP : TIdHTTP;
  70. LStr : TMemoryStream;
  71. i : Integer;
  72. LHE : EIdHTTPProtocolException;
  73. LFName : String;
  74. {$ifdef usezlib}
  75. LC : TIdCompressorZLib;
  76. {$endif}
  77. begin
  78. {$ifdef useopenssl}
  79. LIO := TIdSSLIOHandlerSocketOpenSSL.Create;
  80. {$endif}
  81. {$ifdef usezlib}
  82. LC := TIdCompressorZLib.Create;
  83. {$endif}
  84. try
  85. LHTTP := TIdHTTP.Create;
  86. try
  87. {$ifdef useopenssl}
  88. LHTTP.Compressor := LC;
  89. {$endif}
  90. //set to false if you want this to simply raise an exception on redirects
  91. LHTTP.HandleRedirects := True;
  92. {
  93. Note that you probably should set the UserAgent because some servers now screen out requests from
  94. our default string "Mozilla/3.0 (compatible; Indy Library)" to prevent address harvesters
  95. and Denial of Service attacks. SOme people have used Indy for these.
  96. Note that you do need a Mozilla string for the UserAgent property. The format is like this:
  97. Mozilla/4.0 (compatible; MyProgram)
  98. }
  99. LHTTP.Request.UserAgent := 'Mozilla/4.0 (compatible; httpget)';
  100. LStr := TMemoryStream.Create;
  101. {$ifdef useopenssl}
  102. LHTTP.IOHandler := LIO;
  103. {$endif}
  104. for i := 0 to LHTTP.Request.RawHeaders.Count -1 do
  105. begin
  106. FLogData.Add(LHTTP.Request.RawHeaders[i]);
  107. if FVerbose then
  108. begin
  109. WriteLn({$IFDEF FPC}stdout{$ELSE}output{$ENDIF},LHTTP.Request.RawHeaders[i]);
  110. end;
  111. end;
  112. LHTTP.Get(AURL.URI,LStr);
  113. for i := 0 to LHTTP.Response.RawHeaders.Count -1 do
  114. begin
  115. FLogData.Add(LHTTP.Response.RawHeaders[i]);
  116. if FVerbose then
  117. begin
  118. WriteLn({$IFDEF FPC}stdout{$ELSE}output{$ENDIF},LHTTP.Response.RawHeaders[i]);
  119. end;
  120. end;
  121. LFName := GetTargetFileName(LHTTP,AURL);
  122. if LFName <> '' then
  123. begin
  124. LStr.SaveToFile(LFName);
  125. end;
  126. except
  127. on E : Exception do
  128. begin
  129. if E is EIdHTTPProtocolException then
  130. begin
  131. LHE := E as EIdHTTPProtocolException;
  132. WriteLn({$IFDEF FPC}stderr{$ELSE}ErrOutput {$ENDIF},'HTTP Protocol Error - '+IntToStr(LHE.ErrorCode));
  133. WriteLn({$IFDEF FPC}stderr{$ELSE}ErrOutput {$ENDIF},LHE.ErrorMessage);
  134. if Verbose = False then
  135. begin
  136. for i := 0 to FLogData.Count -1 do
  137. begin
  138. Writeln({$IFDEF FPC}stderr{$ELSE}ErrOutput {$ENDIF},FLogData[i]);
  139. end;
  140. end;
  141. end
  142. else
  143. begin
  144. Writeln({$IFDEF FPC}stderr{$ELSE}ErrOutput {$ENDIF},E.Message);
  145. end;
  146. end;
  147. end;
  148. FreeAndNil(LHTTP);
  149. FreeAndNil(LStr);
  150. finally
  151. {$ifdef useopenssl}
  152. FreeAndNil(LIO);
  153. {$endif}
  154. {$ifdef usezlib}
  155. FreeAndNil(LC);
  156. {$endif}
  157. end;
  158. {$ELSE}
  159. begin
  160. {$ENDIF}
  161. end;
  162. {$IFNDEF NO_HTTP}
  163. function THTTPProtHandler.GetTargetFileName(AHTTP : TIdHTTP; AURI : TIdURI) : String;
  164. begin
  165. {
  166. We do things this way in case the server gave you a specific document type
  167. in response to a request.
  168. eg.
  169. Request: http://www.indyproject.org/
  170. Response: http://www.indyproject.org/index.html
  171. }
  172. if AHTTP.Response.Location <> '' then
  173. begin
  174. AURI.URI := AHTTP.Response.Location;
  175. end;
  176. Result := AURI.Document;
  177. if Result = '' then
  178. begin
  179. Result := 'index.html';
  180. end;
  181. end;
  182. {$ENDIF}
  183. end.