You are not logged in.
Hello Administrator,
I have done a modification to SynCrtSock.pas in order to allow customize the block size of the data that is read in TWinHttpAPI.InternalRetrieveAnswer.
The changes has been the following ( I have remarked the changes with the word "changed" ) :
TWinHttpAPI = class(THttpRequest)
protected
...
fBlockSize : cardinal; // <------------------------- changed
...
public
...
/// hoy many bytes should be retrieved for each InternalRead in InternalRetrieveAnswer
property BlockSize : cardinal
read fBlockSize write fBlockSize; // <---------------------------- changed
end;
...
function TWinHttpAPI.InternalRetrieveAnswer(
var Header, Encoding, AcceptEncoding, Data: SockString): integer;
var Bytes, ContentLength, Read: DWORD;
tmp: SockString;
begin // HTTP_QUERY* and WINHTTP_QUERY* do match -> common to TWinINet + TWinHTTP
result := InternalGetInfo32(HTTP_QUERY_STATUS_CODE);
Header := InternalGetInfo(HTTP_QUERY_RAW_HEADERS_CRLF);
Encoding := InternalGetInfo(HTTP_QUERY_CONTENT_ENCODING);
AcceptEncoding := InternalGetInfo(HTTP_QUERY_ACCEPT_ENCODING);
// retrieve received content (if any)
Read := 0;
ContentLength := InternalGetInfo32(HTTP_QUERY_CONTENT_LENGTH);
if Assigned(fOnDownload) then begin
// download per-chunk using calback event
Bytes := fOnDownloadChunkSize;
if Bytes<=0 then
Bytes := 65536; // 64KB seems fair enough by default
SetLength(tmp,Bytes);
repeat
Bytes := InternalReadData(tmp,0);
if Bytes=0 then
break;
inc(Read,Bytes);
if not fOnDownload(self,Read,ContentLength,Bytes,pointer(tmp)^) then
break; // returned false = aborted
if Assigned(fOnProgress) then
fOnProgress(self,Read,ContentLength);
until false;
end else
if ContentLength<>0 then begin
// optimized version reading "Content-Length: xxx" bytes
if fBlockSize <= 0 then // <------------------------------------------ changed
SetLength(Data,ContentLength);
repeat
// ------------------ changed start
if fBlockSize > 0 then
begin
if Read + fBlockSize > ContentLength then
Bytes := ContentLength - Read
else
Bytes := fBlockSize;
SetLength( Data, Read + Bytes );
end;
// ------------------ changed end
Bytes := InternalReadData(Data,Read);
if Bytes=0 then begin
SetLength(Data,Read); // truncated content
break;
end;
inc(Read,Bytes);
if Assigned(fOnProgress) then
fOnProgress(self,Read,ContentLength);
until Read=ContentLength;
end else begin
// Content-Length not set: read response in blocks of HTTP_RESP_BLOCK_SIZE or fBlockSize <------------------- changed
repeat
if fBlockSize <= 0 then // <------------------------------- changed
SetLength(Data,Read+HTTP_RESP_BLOCK_SIZE)
else
SetLength(Data,Read+fBlockSize); // <------------------------------- changed
Bytes := InternalReadData(Data,Read);
if Bytes=0 then
break;
inc(Read,Bytes);
if Assigned(fOnProgress) then
fOnProgress(self,Read,ContentLength);
until false;
SetLength(Data,Read);
end;
end;
These changes are very useful when I use a TSQLHttpClient to allow to consume a function of a interface based services server that returns a RawByteString that is very large, and I need that the client application show a progress during the "download" of this data. Without my modification, the OnProgress is only shown once, but If I set the new BlockSize property to 65535 for example, the progress is shown every 65535 bytes received and the user interface is updated showing a responsive progressbar.
Can you tell me if this is usefull for the synopse framework?.
Thank you and best regards.
Offline