You are not logged in.
I have a problem. When I retrive big data from server I don't see any progress. Yes, I can handle OnIdle event but it is not enough!
So we have
function TWinHttpAPI.InternalRetrieveAnswer(var Header, Encoding, AcceptEncoding,
Data: SockString): integer;
var Bytes, ContentLength, Read: DWORD;
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 ContentLength<>0 then begin
SetLength(Data,ContentLength);
repeat
Bytes := InternalReadData(Data,Read);
// ////
// ---> we can notify
if Assigned(OnProgress) then
OnProgress(Read+Bytes, ContentLength);
// ////
if Bytes=0 then begin
SetLength(Data,Read); // truncated content
break;
end else
inc(Read,Bytes);
until Read=ContentLength;
end else begin
// Content-Length not set: read response in blocks of HTTP_RESP_BLOCK_SIZE
repeat
SetLength(Data,Read+HTTP_RESP_BLOCK_SIZE);
Bytes := InternalReadData(Data,Read);
if Bytes=0 then
break;
inc(Read,Bytes);
until false;
SetLength(Data,Read);
end;
end;
Next problem is InternalReadData
function TWinHTTP.InternalReadData(var Data: SockString; Read: integer): cardinal;
begin
if not WinHttpReadData(fRequest, @PByteArray(Data)[Read], length(Data)-Read, result) then
RaiseLastModuleError(winhttpdll,EWinHTTP);
end;
No possibility to request a predetermined amount of data. OnProgress will fire only once.
I want
function TWinHTTP.InternalReadData(var Data: SockString; Read: integer; Count: Integer): cardinal;
begin
if not WinHttpReadData(fRequest, @PByteArray(Data)[Read], Min(length(Data)-Read, Count), result) then
RaiseLastModuleError(winhttpdll,EWinHTTP);
end;
and our code
if ContentLength<>0 then begin
SetLength(Data,ContentLength);
repeat
// ////
// read chunk HTTP_RESP_BLOCK_SIZE
Bytes := InternalReadData(Data,Read,HTTP_RESP_BLOCK_SIZE);
if Assigned(OnProgress) then
OnProgress(Read+Bytes, ContentLength);
// ////
if Bytes=0 then begin
SetLength(Data,Read); // truncated content
break;
end else
inc(Read,Bytes);
until Read=ContentLength;
end else begin
And I am not sure about HTTP_RESP_BLOCK_SIZE...
What do you think? Of course we need access to OnProgress...
Is it implementable?
Offline