sdlwebhttp.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. unit sdlwebhttp;
  2. {******************************************************************************}
  3. {
  4. $Id: sdlwebhttp.pas,v 1.2 2005/01/02 19:03:15 savage Exp $
  5. }
  6. { }
  7. { Borland Delphi SDL_Net - A x-platform network library for use with SDL.}
  8. { Conversion of the Simple DirectMedia Layer Network Headers }
  9. { }
  10. { Portions created by Sam Lantinga <[email protected]> are }
  11. { Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga }
  12. { 5635-34 Springhouse Dr. }
  13. { Pleasanton, CA 94588 (USA) }
  14. { }
  15. { All Rights Reserved. }
  16. { }
  17. { The original files are : SDL_net.h }
  18. { }
  19. { The initial developer of this Pascal code was : }
  20. { Dean Ellis <[email protected]> }
  21. { }
  22. { Portions created by Dean Ellis are }
  23. { Copyright (C) 2000 - 2001 Dean Ellis. }
  24. { }
  25. { }
  26. { Contributor(s) }
  27. { -------------- }
  28. { }
  29. { }
  30. { Obtained through: }
  31. { Joint Endeavour of Delphi Innovators ( Project JEDI ) }
  32. { }
  33. { You may retrieve the latest version of this file at the Project }
  34. { JEDI home page, located at http://delphi-jedi.org }
  35. { }
  36. { The contents of this file are used with permission, subject to }
  37. { the Mozilla Public License Version 1.1 (the "License"); you may }
  38. { not use this file except in compliance with the License. You may }
  39. { obtain a copy of the License at }
  40. { http://www.mozilla.org/MPL/MPL-1.1.html }
  41. { }
  42. { Software distributed under the License is distributed on an }
  43. { "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
  44. { implied. See the License for the specific language governing }
  45. { rights and limitations under the License. }
  46. { }
  47. { Description }
  48. { ----------- }
  49. { }
  50. { }
  51. { }
  52. { }
  53. { }
  54. { }
  55. { }
  56. { Requires }
  57. { -------- }
  58. { sdlweb.pas somehere in your search path }
  59. { }
  60. { Programming Notes }
  61. { ----------------- }
  62. { }
  63. { }
  64. { }
  65. { }
  66. { Revision History }
  67. { ---------------- }
  68. {
  69. $Log: sdlwebhttp.pas,v $
  70. Revision 1.2 2005/01/02 19:03:15 savage
  71. Slight Bug fix due to stray closed comment ( Thanks Michalis Kamburelis )
  72. Revision 1.1 2004/12/31 00:30:14 savage
  73. Initial release of Dean's excellent SDL Web classes. Demo coming soon.
  74. }
  75. {******************************************************************************}
  76. interface
  77. uses
  78. Classes,
  79. sdlweb;
  80. type
  81. TContentEncoding = ( ceNone, cegzip, cedeflate, ceform, cexml );
  82. TContentEncodings = set of TContentEncoding;
  83. TTransferEncoding = ( teNone, teChunked );
  84. TResponseResult = ( rsOK, rsError, rsProxyAutheticate );
  85. function SDL_Web_HTTP_GetPageToString( var Connection : TSDLWebConnection;
  86. Page : string; var Response : string; Progress : TWebProgressEvent = nil; Encoding : TContentEncoding = ceNone ) : Boolean;
  87. function SDL_Web_HTTP_GetPageToStream( var Connection : TSDLWebConnection;
  88. Page : string; var AResponse : TStream; Progress : TWebProgressEvent = nil; Encoding : TContentEncoding = ceNone ) : Boolean;
  89. function SDL_Web_HTTP_PostString( var Connection : TSDLWebConnection;
  90. TargetPage : string; Post : string; var Response : string; Progress : TWebProgressEvent = nil; Encoding : TContentEncoding = ceform ) : Boolean;
  91. function SDL_Web_HTTP_PostStream( var Connection : TSDLWebConnection;
  92. TargetPage : string; APost : TStream; var AResponse : TStream; Progress : TWebProgressEvent = nil; Encoding : TContentEncoding = ceform ) : Boolean;
  93. implementation
  94. uses
  95. SysUtils,
  96. sdl_net;
  97. const
  98. MAX_BUFFER_SIZE = 1024;
  99. HTTP_VER = '1.1';
  100. type
  101. THTTPResponse = record
  102. Status : Integer;
  103. ServerType : string;
  104. ContentLength : Integer;
  105. ContentType : string;
  106. ContentEncoding : TContentEncoding;
  107. TransferEncoding : TTransferEncoding;
  108. Closed : Boolean;
  109. end;
  110. THTTPRequest = record
  111. Host : string;
  112. Username : string;
  113. Password : string;
  114. Length : Integer;
  115. end;
  116. var
  117. Response : THTTPResponse;
  118. Request : THTTPRequest;
  119. {------------------------------------------------------------------------------}
  120. {Sends a HTTP Request to the Connection}
  121. {------------------------------------------------------------------------------}
  122. procedure SendHTTPRequest( var Connection : TSDLWebConnection; Method, Version, Page : string; Encoding : TContentEncoding = ceNone );
  123. const
  124. ContentEncoding : array[ TContentEncoding ] of string = ( '', 'gzip', 'deflate', 'application/x-www-form-urlencoded', 'text/xml' );
  125. begin
  126. if SDLWeb_Connected( Connection ) then
  127. begin
  128. if not Connection.IsProxy then
  129. SDLWeb_SendRequest( Connection, Method + ' ' + Page + ' HTTP/' + Version );
  130. if Version = '1.1' then
  131. begin
  132. if not Connection.IsProxy then
  133. SDLWeb_SendRequest( Connection, 'Host: ' + Connection.HostName )
  134. else
  135. begin
  136. SDLWeb_SendRequest( Connection, Method + ' http://' + Connection.HostName + Page + ' HTTP/' + Version );
  137. SDLWeb_SendRequest( Connection, 'Host: ' + Connection.Proxy );
  138. end;
  139. if Method = 'GET' then
  140. begin
  141. SDLWeb_SendRequest( Connection, 'Accept: text/html, text/xml, text/txt, application/zip, application/x-zip-compressed, */*' );
  142. SDLWeb_SendRequest( Connection, 'Accept-CharSet: *' );
  143. SDLWeb_SendRequest( Connection, 'Accept-Language: en' );
  144. SDLWeb_SendRequest( Connection, 'User-Agent: SDLWeb/1.0' );
  145. SDLWeb_SendRequest( Connection, 'Cache-Control: no-store, no-cache' );
  146. SDLWeb_SendRequest( Connection, 'Pragma: no-cache' );
  147. end;
  148. if Encoding <> ceNone then
  149. SDLWeb_SendRequest( Connection, 'Accept-Encoding: ' + ContentEncoding[ Encoding ] );
  150. if Connection.IsProxy then
  151. begin
  152. SDLWeb_SendRequest( Connection, 'Proxy-Authorization: Basic ' +
  153. SDLWeb_EncodeBase64( Connection.ProxyUser + ':' + Connection.ProxyPassword ) );
  154. end;
  155. end;
  156. if Method = 'POST' then
  157. begin
  158. SDLWeb_SendRequest( Connection, 'Content-Encoding: ' + ContentEncoding[ Encoding ] );
  159. SDLWeb_SendRequest( Connection, 'Content-Length:' + IntToStr( Request.Length ) );
  160. end;
  161. SDLWeb_SendRequest( Connection, EmptyStr );
  162. end;
  163. end;
  164. {------------------------------------------------------------------------------}
  165. {Reads a HTTP Response from the Connection}
  166. {------------------------------------------------------------------------------}
  167. function ReadHTTPResponse( var Connection : TSDLWebConnection; var Error : string ) : TResponseResult;
  168. var
  169. s, text : string;
  170. status : integer;
  171. begin
  172. Result := rsOK;
  173. //status := 0;
  174. Response.Status := 0;
  175. Response.ServerType := EmptyStr;
  176. Response.ContentType := EmptyStr;
  177. Response.ContentLength := -1;
  178. Response.ContentEncoding := ceNone;
  179. Response.TransferEncoding := teNone;
  180. repeat
  181. SDLWeb_ReadResponse( Connection, S );
  182. if ( CompareText( copy( s, 1, 8 ), 'HTTP/1.1' ) = 0 ) or
  183. ( CompareText( copy( s, 1, 8 ), 'HTTP/1.0' ) = 0 ) then
  184. begin
  185. status := StrToInt( copy( s, 10, 3 ) );
  186. text := copy( s, 14, length( s ) );
  187. Response.Status := status;
  188. if status >= 400 then
  189. begin
  190. Result := rsError;
  191. if not Connection.IsProxy then
  192. Break;
  193. if CompareText( copy( s, 1, 19 ), 'Proxy-Authenticate:' ) = 0 then
  194. begin
  195. // get the proxy authenticate method BASIC and resend the request.
  196. Result := rsProxyAutheticate;
  197. end;
  198. end;
  199. end;
  200. if CompareText( copy( s, 1, 7 ), 'Server:' ) = 0 then
  201. begin
  202. Response.ServerType := copy( s, 8, 255 );
  203. end;
  204. if CompareText( copy( s, 1, 11 ), 'Connection:' ) = 0 then
  205. begin
  206. Response.Closed := CompareText( copy( s, 13, 255 ), 'Close' ) = 0;
  207. end;
  208. if CompareText( copy( s, 1, 15 ), 'Content-Length:' ) = 0 then
  209. begin
  210. Response.ContentLength := StrToInt( copy( s, 16, 255 ) );
  211. end;
  212. if CompareText( copy( s, 1, 13 ), 'Content-Type:' ) = 0 then
  213. begin
  214. Response.ContentType := copy( s, 14, 255 );
  215. end;
  216. if CompareText( copy( s, 1, 17 ), 'Content-Encoding:' ) = 0 then
  217. begin
  218. if Pos( 'gzip', copy( s, 18, 255 ) ) > 0 then
  219. Response.ContentEncoding := cegzip;
  220. if Pos( 'deflate', copy( s, 18, 255 ) ) > 0 then
  221. Response.ContentEncoding := cedeflate;
  222. end;
  223. if CompareText( copy( s, 1, 18 ), 'Transfer-Encoding:' ) = 0 then
  224. begin
  225. if Pos( 'chunked', copy( s, 19, 255 ) ) > 0 then
  226. Response.TransferEncoding := teChunked;
  227. end;
  228. until S = EmptyStr;
  229. Error := Text;
  230. end;
  231. {------------------------------------------------------------------------------}
  232. {Reads a file from the HTTP Server into a string}
  233. {------------------------------------------------------------------------------}
  234. function SDL_Web_HTTP_GetPageToString( var Connection : TSDLWebConnection;
  235. Page : string; var Response : string; Progress : TWebProgressEvent = nil; Encoding : TContentEncoding = ceNone ) : Boolean;
  236. var
  237. Stream : TStream;
  238. begin
  239. Response := EmptyStr;
  240. Stream := TStringStream.Create( Response );
  241. try
  242. Result := SDL_Web_HTTP_GetPageToStream( Connection, Page, Stream, Progress, Encoding );
  243. //if Result then
  244. Response := TStringStream( Stream ).DataString;
  245. finally
  246. Stream.Free;
  247. end;
  248. end;
  249. {------------------------------------------------------------------------------}
  250. {Reads a file from the HTTP Server into a Stream}
  251. {------------------------------------------------------------------------------}
  252. function SDL_Web_HTTP_GetPageToStream( var Connection : TSDLWebConnection;
  253. Page : string; var AResponse : TStream; Progress : TWebProgressEvent = nil; Encoding : TContentEncoding = ceNone ) : Boolean;
  254. var
  255. Protocol, User, Password, Host, Port, Path, Error : string;
  256. Buffer : array[ 0..MAX_BUFFER_SIZE ] of Byte;
  257. BufferStream : TMemoryStream;
  258. function HexToInt( HexNum : string ) : LongInt;
  259. begin
  260. Result := StrToInt( '$' + HexNum );
  261. end;
  262. function ReadHTTPChunkData : Boolean;
  263. var
  264. i, l, error : integer;
  265. lp : Pointer;
  266. SocketSet : PSDLNet_SocketSet;
  267. sResponse : string;
  268. c : char;
  269. begin
  270. Result := False;
  271. { DONE 1 -oDRE -cHTTP : Implement Transfer encoding support }
  272. SocketSet := SDLNet_AllocSocketSet( 1 );
  273. try
  274. SDLNet_TCP_AddSocket( SocketSet, Connection.Socket );
  275. if ( Response.ContentLength = -1 ) or ( BufferStream.Size < Response.ContentLength ) then
  276. begin
  277. if SDLNet_CheckSockets( SocketSet, MAX_TIMEOUT ) > 0 then
  278. begin
  279. if SDLNet_SocketReady( PSDLNet_GenericSocket( Connection.Socket ) ) then
  280. begin
  281. // read the chunk data
  282. sResponse := EmptyStr;
  283. while true do
  284. begin
  285. Error := SDLNet_TCP_Recv( Connection.Socket, @C, 1 );
  286. if error <> 1 then
  287. Break;
  288. if C = #13 then
  289. else if C = #10 then
  290. Break
  291. else
  292. begin
  293. sResponse := sResponse + C;
  294. end;
  295. end;
  296. l := MAX_BUFFER_SIZE;
  297. if sResponse <> EmptyStr then
  298. l := HexToInt( sResponse ) + 2;
  299. l := SDLNet_TCP_Recv( Connection.Socket, @Buffer, l );
  300. Result := l > 0;
  301. lp := @Buffer;
  302. if Result then
  303. begin
  304. while l > 0 do
  305. begin
  306. i := BufferStream.Write( lp^, l );
  307. dec( l, i );
  308. lp := pointer( longint( lp ) + i );
  309. end;
  310. BufferStream.Position := BufferStream.Position - 2; // take off #13#10
  311. if Assigned( Progress ) then
  312. Progress( BufferStream.Size, Response.ContentLength )
  313. end;
  314. end;
  315. end;
  316. end;
  317. finally
  318. SDLNet_FreeSocketSet( SocketSet );
  319. end;
  320. end;
  321. {--------------------------------------------}
  322. {Reads Data from the Socket}
  323. {--------------------------------------------}
  324. function ReadHTTPData : Boolean;
  325. var
  326. i, l : integer;
  327. lp : Pointer;
  328. SocketSet : PSDLNet_SocketSet;
  329. begin
  330. Result := False;
  331. if Response.TransferEncoding = teChunked then
  332. begin
  333. Result := ReadHTTPChunkData;
  334. Exit;
  335. end;
  336. { DONE 1 -oDRE -cHTTP : Implement Transfer encoding support }
  337. SocketSet := SDLNet_AllocSocketSet( 1 );
  338. try
  339. SDLNet_TCP_AddSocket( SocketSet, Connection.Socket );
  340. if ( Response.ContentLength = -1 ) or ( BufferStream.Size < Response.ContentLength ) then
  341. begin
  342. if SDLNet_CheckSockets( SocketSet, MAX_TIMEOUT ) > 0 then
  343. begin
  344. if SDLNet_SocketReady( PSDLNet_GenericSocket( Connection.Socket ) ) then
  345. begin
  346. l := SDLNet_TCP_Recv( Connection.Socket, @Buffer, MAX_BUFFER_SIZE );
  347. Result := l > 0;
  348. lp := @Buffer;
  349. if Result then
  350. begin
  351. while l > 0 do
  352. begin
  353. i := BufferStream.Write( lp^, l );
  354. dec( l, i );
  355. lp := pointer( longint( lp ) + i );
  356. end;
  357. if Assigned( Progress ) then
  358. Progress( BufferStream.Size, Response.ContentLength )
  359. end;
  360. end;
  361. end;
  362. end;
  363. finally
  364. SDLNet_FreeSocketSet( SocketSet );
  365. end;
  366. end;
  367. begin
  368. Result := False;
  369. if Connection.Type_ <> wcHTTP then
  370. Exit;
  371. SDLWeb_ParseURL( Page, Protocol, User, Password, Host, Port, Path );
  372. if Path = EmptyStr then
  373. Path := Page;
  374. Request.Host := Host;
  375. if Request.Host = EmptyStr then
  376. Request.Host := Connection.HostName;
  377. Request.Host := Request.Host + ':' + Port;
  378. Request.Username := User;
  379. Request.Password := Password;
  380. SendHTTPRequest( Connection, 'GET', HTTP_VER, Path, Encoding );
  381. if ReadHTTPResponse( Connection, Error ) in [ rsError ] then
  382. begin
  383. AResponse.WriteBuffer( PChar( Error )^, Length( Error ) );
  384. Exit;
  385. end;
  386. // put this in another thread????
  387. BufferStream := TMemoryStream.Create;
  388. try
  389. while ReadHTTPData do
  390. ;
  391. BufferStream.Position := 0;
  392. case Response.ContentEncoding of
  393. ceNone : AResponse.CopyFrom( BufferStream, 0 );
  394. else
  395. Exit;
  396. end;
  397. Result := True;
  398. finally
  399. BufferStream.Free;
  400. end;
  401. end;
  402. function SDL_Web_HTTP_PostString( var Connection : TSDLWebConnection;
  403. TargetPage : string; Post : string; var Response : string; Progress : TWebProgressEvent = nil; Encoding : TContentEncoding = ceform ) : Boolean;
  404. var
  405. Stream, AResponse : TStream;
  406. begin
  407. Response := EmptyStr;
  408. Stream := TStringStream.Create( Post );
  409. AResponse := TStringStream.Create( Post );
  410. try
  411. Result := SDL_Web_HTTP_PostStream( Connection, TargetPage, Stream, AResponse, Progress, Encoding );
  412. //if Result then
  413. Response := TStringStream( AResponse ).DataString;
  414. finally
  415. AResponse.Free;
  416. Stream.Free;
  417. end;
  418. end;
  419. function SDL_Web_HTTP_PostStream( var Connection : TSDLWebConnection;
  420. TargetPage : string; APost : TStream; var AResponse : TStream; Progress : TWebProgressEvent = nil; Encoding : TContentEncoding = ceform ) : Boolean;
  421. var
  422. Protocol, User, Password, Host, Port, Path, Error : string;
  423. Buffer : array[ 0..MAX_BUFFER_SIZE ] of Byte;
  424. BytesSent, Bytes : Integer;
  425. BufferStream, PostStream : TStream;
  426. function HexToInt( HexNum : string ) : LongInt;
  427. begin
  428. Result := StrToInt( '$' + HexNum );
  429. end;
  430. function ReadHTTPChunkData : Boolean;
  431. var
  432. i, l, error : integer;
  433. lp : Pointer;
  434. SocketSet : PSDLNet_SocketSet;
  435. sResponse : string;
  436. c : char;
  437. begin
  438. Result := False;
  439. { TODO 1 -oDRE -cHTTP : Implement Transfer encoding support }
  440. SocketSet := SDLNet_AllocSocketSet( 1 );
  441. SDLNet_TCP_AddSocket( SocketSet, Connection.Socket );
  442. if ( Response.ContentLength = -1 ) or ( BufferStream.Size < Response.ContentLength ) then
  443. begin
  444. if SDLNet_CheckSockets( SocketSet, MAX_TIMEOUT ) > 0 then
  445. begin
  446. if SDLNet_SocketReady( PSDLNet_GenericSocket( Connection.Socket ) ) then
  447. begin
  448. // read the chunk data
  449. //
  450. sResponse := EmptyStr;
  451. while true do
  452. begin
  453. Error := SDLNet_TCP_Recv( Connection.Socket, @C, 1 );
  454. if error <> 1 then
  455. Break;
  456. if C = #13 then
  457. else if C = #10 then
  458. Break
  459. else
  460. begin
  461. sResponse := sResponse + C;
  462. end;
  463. end;
  464. l := MAX_BUFFER_SIZE;
  465. if sResponse <> EmptyStr then
  466. l := HexToInt( sResponse ) + 2;
  467. l := SDLNet_TCP_Recv( Connection.Socket, @Buffer, l );
  468. Result := l > 0;
  469. lp := @Buffer;
  470. if Result then
  471. begin
  472. while l > 0 do
  473. begin
  474. i := BufferStream.Write( lp^, l );
  475. dec( l, i );
  476. lp := pointer( longint( lp ) + i );
  477. end;
  478. BufferStream.Position := BufferStream.Position - 2; // take off #13#10
  479. if Assigned( Progress ) then
  480. Progress( BufferStream.Size, Response.ContentLength )
  481. end;
  482. end;
  483. end;
  484. end;
  485. SDLNet_FreeSocketSet( SocketSet );
  486. end;
  487. {--------------------------------------------}
  488. {Reads Data from the Socket}
  489. {--------------------------------------------}
  490. function ReadHTTPData : Boolean;
  491. var
  492. i, l : integer;
  493. lp : Pointer;
  494. SocketSet : PSDLNet_SocketSet;
  495. begin
  496. Result := False;
  497. if Response.TransferEncoding = teChunked then
  498. begin
  499. Result := ReadHTTPChunkData;
  500. Exit;
  501. end;
  502. { DONE 1 -oDRE -cHTTP : Implement Transfer encoding support }
  503. SocketSet := SDLNet_AllocSocketSet( 1 );
  504. SDLNet_TCP_AddSocket( SocketSet, Connection.Socket );
  505. if ( Response.ContentLength = -1 ) or ( BufferStream.Size < Response.ContentLength ) then
  506. begin
  507. if SDLNet_CheckSockets( SocketSet, MAX_TIMEOUT ) > 0 then
  508. begin
  509. if SDLNet_SocketReady( PSDLNet_GenericSocket( Connection.Socket ) ) then
  510. begin
  511. l := SDLNet_TCP_Recv( Connection.Socket, @Buffer, MAX_BUFFER_SIZE );
  512. Result := l > 0;
  513. lp := @Buffer;
  514. if Result then
  515. begin
  516. while l > 0 do
  517. begin
  518. i := BufferStream.Write( lp^, l );
  519. dec( l, i );
  520. lp := pointer( longint( lp ) + i );
  521. end;
  522. if Assigned( Progress ) then
  523. Progress( BufferStream.Size, Response.ContentLength )
  524. end;
  525. end;
  526. end;
  527. end;
  528. SDLNet_FreeSocketSet( SocketSet );
  529. end;
  530. begin
  531. Result := False;
  532. if Connection.Type_ <> wcHTTP then
  533. Exit;
  534. SDLWeb_ParseURL( TargetPage, Protocol, User, Password, Host, Port, Path );
  535. if Path = EmptyStr then
  536. Path := TargetPage;
  537. Request.Host := Host;
  538. if Request.Host = EmptyStr then
  539. Request.Host := Connection.HostName;
  540. Request.Username := User;
  541. Request.Password := Password;
  542. PostStream := TMemoryStream.Create;
  543. try
  544. PostStream.CopyFrom( APost, APost.Size );
  545. PostStream.Position := 0;
  546. Request.Length := PostStream.Size;
  547. SendHTTPRequest( Connection, 'POST', HTTP_VER, Path, Encoding );
  548. if ReadHTTPResponse( Connection, Error ) in [ rsError ] then
  549. begin
  550. AResponse.WriteBuffer( PChar( Error )^, Length( Error ) );
  551. Exit;
  552. end;
  553. // send the data in the stream
  554. BytesSent := 0;
  555. while BytesSent < PostStream.Size do
  556. begin
  557. Bytes := PostStream.Read( Buffer, MAX_BUFFER_SIZE );
  558. if SDLNet_TCP_Send( Connection.Socket, @Buffer, Bytes ) = Bytes then
  559. inc( BytesSent, Bytes );
  560. end;
  561. finally
  562. PostStream.Free;
  563. end;
  564. if ReadHTTPResponse( Connection, Error ) in [ rsError ] then
  565. begin
  566. AResponse.WriteBuffer( PChar( Error )^, Length( Error ) );
  567. Exit;
  568. end;
  569. BufferStream := TMemoryStream.Create;
  570. try
  571. while ReadHTTPData do
  572. ;
  573. BufferStream.Position := 0;
  574. case Response.ContentEncoding of
  575. ceNone : AResponse.CopyFrom( BufferStream, 0 );
  576. else
  577. Exit;
  578. end;
  579. Result := True;
  580. finally
  581. BufferStream.Free;
  582. end;
  583. end;
  584. end.