Hi,
I'm trying to write 2 Sparkle servers, one is a 'Gateway' server which in turn calls the other 'Host' server when a request is received. All works fine, but I'm now trying to work it so that if a file is requested, the file is streamed from the 'Host' server back to the 'Gateway' server and client app bit by bit in one process, rather than the entire file being first transferred to the 'Gateway' server and then onto the client app. By doing this I should be able to show an accurate download progress bar at the client app.
Client App --> Gateway Server --> Host Server (Request)
<-- <-- (Response)
Here is the abbreviated code :
Gateway Server Method Code
const
BufSize = 65536;
var
httpClient: THttpClient;
httpRequest: THttpRequest;
httpResponse: THttpResponse;
Buf: array[0..BufSize - 1] of Byte;
begin
// Call method on the host server
httpClient := THttpClient.Create;
httpRequest := httpClient.CreateRequest;
httpRequest.Uri := 'https://hostserver/api/downloadfile';
httpRequest.Method := 'POST';
httpRequest.SetContent(C.Request.Content); // Pass request content from calling app
httpResponse := nil;
try
httpResponse := httpClient.Send(httpRequest);
finally
if (httpResponse <> nil) then
begin
C.Response.StatusCode := httpResponse.StatusCode;
C.Response.ContentLength := httpResponse.ContentLength;
C.Response.ContentType := httpResponse.ContentType;
repeat
intBytesRead := httpResponse.ContentAsStream.Read(Buf, BufSize);
C.Response.Content.Write(Buf, intBytesRead);
until (intBytesRead < BufSize);
C.Response.Close;
httpResponse.Free;
end;
end;
httpRequest.Free;
httpClient.Free;
end;
Host Server Method Code
const
BufSize = 65536;
var
strFileStream: TFileStream;
intBytesRead: Integer;
Buf: array[0..BufSize - 1] of Byte;
begin
// Respond with PDF file from disk location
if (FileExists('C:\MyPDFFile.pdf') = True) then
begin
C.Response.StatusCode := 200;
C.Response.ContentType := 'application/pdf';
strFileStream := TFileStream.Create('C:\MyPDFFile.pdf', fmShareDenyNone);
C.Response.ContentLength := strFileStream.Size;
repeat
intBytesRead := strFileStream.Read(Buf, BufSize);
C.Response.Content.Write(Buf, intBytesRead);
until (intBytesRead < BufSize);
C.Response.Close;
strFileStream.Free;
end;
end;
If I call the host server method directly, the file downloads fine. However if I call the gateway server method, the file is read from/written to the streams for so long but then just freezes (no errors, just hangs).
Is there some kind of read/write conflict causing it to freeze? Is is possible to do what I want?
Thanks,
Jonathan