TXDataOperationContext.Current.Response.StatusCode

Hi,

I'm trying to implement Content-Ranges for serving a big video file via TStream,
the only problem I have, I cannot change the status response to 206 instead of 200.

I mean I have to change TXDataOperationContext.Current.Response.StatusCode := 206

I have a service implementation like:


function TPlayerController.GetStream: TStream;
const SEGMENT_SIZE=(1024*1024*10); //10 Mbytes
var
  oFile: TFileStream;
  StartPos, EndPos: Int64;
  start_req: string;
begin
  try

  DoGlobalThings(TXDataOperationContext.Current);
   TXDataOperationContext.Current.Response.Headers.AddValue('AcceptRanges','bytes');
  TXDataOperationContext.Current.Response.Headers.AddValue('content-type', 'video/x-matroska');
  oFile := TFileStream.Create('d:\bigfile.mkv', fmOpenRead or fmShareDenyWrite);

  if TXDataOperationContext.Current.Request.Headers.GetIfExists('Range',start_req) then
    begin
      StartPos := StrToIntDef(StringExtractBetween(start_req,'bytes=','-'),0);
      EndPos := StrToIntDef(StringExtractBetween(start_req+'#','-','#'),0);

    if StartPos < 0 then StartPos := 0;
    if EndPos <= 0 then EndPos := StartPos + SEGMENT_SIZE - 1;
    if (EndPos-StartPos)>SEGMENT_SIZE then EndPos := StartPos + SEGMENT_SIZE - 1;

      Result := TIdHTTPRangeStream.Create(oFile, StartPos, EndPos);
      TXDataOperationContext.Current.Handler.Response.StatusCode  := TIdHTTPRangeStream(Result).ResponseCode;

      if TXDataOperationContext.Current.Handler.Response.StatusCode = 206 then
        TXDataOperationContext.Current.Response.Headers.AddValue('Content-Range', Format('bytes=%d-%d/%d',[StartPos,EndPos,oFile.Size]));

    end
  else
    begin
      Result := oFile;
      TXDataOperationContext.Current.Handler.Response.StatusCode := 200;
    end;

  TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);

  finally
       //some stuff
  end;

end;

curl response is 200 instead of 206, however the binary response works, the video start playing for the first segment, :
curl -s -I -X "GET" "https://localhost:20000/api/player/get-stream" -H "Range: bytes=1023-2048"
HTTP/1.1 200 OK
Content-Length: 1026
Content-Type: video/x-matroska
Content-Range: bytes=1023-2048/7490174674
Server: Microsoft-HTTPAPI/2.0
acceptranges: bytes
xdata-version: 2
access-control-allow-origin: *
Date: Wed, 11 Aug 2021 01:31:56 GMT

That's currently not possible, indeed. But for such low level processing, why don't you simply use a Sparkle module (instead of XData), where you can fully process the request and response the way you want?

Thanks, I will try to migrate this service to Sparkle. Xdata was good in mapping at least incoming call classes.