HTTPServer.pas 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 11261: HTTPServer.pas
  11. {
  12. Rev 1.3 6/18/2003 11:58:34 PM BGooijen
  13. uses ResponseInfo.ServeFile now
  14. }
  15. {
  16. Rev 1.2 6/18/2003 7:37:20 PM BGooijen
  17. Works now
  18. }
  19. {
  20. Rev 1.1 4/4/2003 7:43:46 PM BGooijen
  21. compile again
  22. }
  23. {
  24. { Rev 1.0 11/12/2002 09:18:44 PM JPMugaas
  25. { Initial check in. Import from FTP VC.
  26. }
  27. unit HTTPServer;
  28. interface
  29. uses
  30. IndyBox,
  31. Classes,
  32. IdGlobal,
  33. IdCustomHTTPServer, IdHTTPServer,IdContext,
  34. IdTCPServer;
  35. type
  36. THTTPServer = class(TIndyBox)
  37. protected
  38. FMIMEType : TIdMIMETable;
  39. FUseAuthenticaiton : Boolean;
  40. FManageSessions : Boolean;
  41. function GetMIMEType(sFile: String): String;
  42. public
  43. constructor Create(AOwner : TComponent); override;
  44. destructor Destroy; override;
  45. procedure HTTPServerCommandGet(AContext:TIdContext;
  46. RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo);
  47. procedure Test; override;
  48. end;
  49. implementation
  50. uses IdHTTP,
  51. IdCoreGlobal,
  52. SysUtils{$IFDEF VER130},FileCtrl{$ENDIF};
  53. const
  54. sauthenticationrealm = 'Indy http server demo';
  55. { THTTPServer }
  56. constructor THTTPServer.Create(AOwner: TComponent);
  57. begin
  58. inherited Create(AOwner);
  59. FMIMEType := TIdMIMETable.Create(True);
  60. end;
  61. destructor THTTPServer.Destroy;
  62. begin
  63. FMIMEType.Free;
  64. inherited Destroy;
  65. end;
  66. function THTTPServer.GetMIMEType(sFile: String): String;
  67. begin
  68. Result := FMIMEType.GetFileMIMEType(sFile)
  69. end;
  70. procedure THTTPServer.HTTPServerCommandGet(AContext:TIdContext;
  71. RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo);
  72. procedure AuthFailed;
  73. begin
  74. ResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>Authentication failed</h1>'#13 +
  75. 'Check the demo source code to discover the password:<br><ul><li>Search for <b>AuthUsername</b> in <b>Main.pas</b>!</ul></body></html>';
  76. ResponseInfo.AuthRealm := sauthenticationrealm;
  77. end;
  78. procedure AccessDenied;
  79. begin
  80. ResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>Access denied</h1>'#13 +
  81. 'You do not have sufficient priviligies to access this document.</body></html>';
  82. ResponseInfo.ResponseNo := 403;
  83. end;
  84. var
  85. LocalDoc: string;
  86. ResultFile: TFileStream;
  87. begin
  88. if FUseAuthenticaiton and
  89. ((RequestInfo.AuthUsername <> 'Indy') or (RequestInfo.AuthPassword <> 'rocks')) then
  90. begin
  91. AuthFailed;
  92. exit;
  93. end;
  94. // Interprete the command to it's final path (avoid sending files in parent folders)
  95. LocalDoc := ExpandFilename(GetDataDir + RequestInfo.Document);
  96. // Default document (index.html) for folder
  97. if (LocalDoc[Length(LocalDoc)] = GPathDelim) and DirectoryExists(LocalDoc) then begin
  98. LocalDoc := ExpandFileName(LocalDoc + '/index.html');
  99. end;
  100. {if not FileExists(LocalDoc) and DirectoryExists(LocalDoc) and FileExists(ExpandFileName(LocalDoc + '/index.html')) then
  101. begin
  102. LocalDoc := ExpandFileName(LocalDoc + '/index.html');
  103. end;}
  104. if FileExists(LocalDoc) then // File exists
  105. begin
  106. if AnsiSameText(Copy(LocalDoc, 1, Length(GetDataDir)), ExtractFilePath(GetDataDir)) then // File down in dir structure
  107. begin
  108. if AnsiSameText(RequestInfo.Command, 'HEAD') then
  109. begin
  110. // HEAD request, don't send the document but still send back it's size
  111. ResultFile := TFileStream.create(LocalDoc, fmOpenRead or fmShareDenyWrite);
  112. try
  113. ResponseInfo.ResponseNo := 200;
  114. ResponseInfo.ContentType := GetMIMEType(LocalDoc);
  115. ResponseInfo.ContentLength := ResultFile.Size;
  116. finally
  117. ResultFile.Free; // We must free this file since it won't be done by the web server component
  118. end;
  119. end
  120. else
  121. begin
  122. // Normal document request
  123. // Send the document back
  124. ResponseInfo.ResponseNo := 200;
  125. ResponseInfo.ContentType := GetMIMEType(LocalDoc);
  126. ResponseInfo.ServeFile(AContext, LocalDoc);
  127. end;
  128. end
  129. else
  130. AccessDenied;
  131. end
  132. else
  133. begin
  134. ResponseInfo.ResponseNo := 404; // Not found
  135. ResponseInfo.ContentText := '<html><head><title>Error</title></head><body><h1>' + ResponseInfo.ResponseText + '</h1></body></html>';
  136. end;
  137. end;
  138. procedure THTTPServer.Test;
  139. var HClient : TIdHTTP;
  140. HServer : TIdHTTPServer;
  141. Results : TStream;
  142. begin
  143. HClient := TIdHTTP.Create(nil);
  144. try
  145. HServer := TIdHTTPServer.Create(nil);
  146. try
  147. HServer.OnCommandGet := HTTPServerCommandGet;
  148. HServer.Active := True;
  149. Results := TMemoryStream.Create;
  150. try
  151. Status('Running PDF file test on 99-BG-1518.pdf with no authorization required');
  152. HClient.Get('http://127.0.0.1/99-BG-1518.pdf',Results);
  153. if Results.Size <> FileSizeByName(GetDataDir + '99-BG-1518.pdf') then
  154. begin
  155. Status('File size of received data not the same as the file size');
  156. end
  157. else
  158. begin
  159. Status('All bytes in file were sent');
  160. end;
  161. if (HClient.Response.ContentType <> 'application/pdf') then
  162. begin
  163. Status( 'Content Type should have been application/pdf' );
  164. end
  165. else
  166. begin
  167. Status('Content Type is correct');
  168. end;
  169. finally
  170. FreeAndNil(Results);
  171. end;
  172. FUseAuthenticaiton := True;
  173. Results := TMemoryStream.Create;
  174. try
  175. Status('Running PDF file test on 99-BG-1518.pdf with authorization required');
  176. HClient.Request.BasicAuthentication := True;
  177. HClient.Request.Username := 'Indy';
  178. HClient.Request.Password := 'rocks';
  179. HClient.Get('http://127.0.0.1/99-BG-1518.pdf',Results);
  180. if Results.Size <> FileSizeByName(GetDataDir + '99-BG-1518.pdf') then
  181. begin
  182. Status('File size of received data not the same as the file size');
  183. end
  184. else
  185. begin
  186. Status('All bytes in file were sent');
  187. end;
  188. if (HClient.Response.ContentType <> 'application/pdf') then
  189. begin
  190. Status( 'Content Type should have been application/pdf' );
  191. end
  192. else
  193. begin
  194. Status('Content Type is correct');
  195. end;
  196. finally
  197. FreeAndNil(Results);
  198. end;
  199. finally
  200. FreeAndNil(HServer);
  201. end;
  202. finally
  203. FreeAndNil(HClient);
  204. end;
  205. end;
  206. initialization
  207. TIndyBox.RegisterBox(THTTPServer, 'HTTP Server', 'Servers');
  208. end.