#1 2014-11-12 09:26:27

esmondb
Member
From: London
Registered: 2010-07-20
Posts: 299

TSQLRestServerURIContext.ReturnFile headers

Could TSQLRestServerURIContext.ReturnFile in mORMot.pas be extended so that additional http headers can be added? I want to add 'Content-Disposition: attachment; filename="myfile.ext"'.

The modified function below with an extra 'additionalHeader' parameter seems to work. Can this feature be added?

procedure TSQLRestServerURIContext.ReturnFile(const FileName: TFileName;
  Handle304NotModified: boolean; const ContentType: RawUTF8; const AdditionalHeader: RawUTF8{=''});
var FileTime: TDateTime;
    clientHash, serverHash: RawUTF8;
begin
  FileTime := FileAgeToDateTime(FileName);
  if FileTime=0 then
    Error('',HTML_NOTFOUND) else begin
    if ContentType<>'' then
      Call.OutHead := HEADER_CONTENT_TYPE+ContentType else
      Call.OutHead := HEADER_CONTENT_TYPE+GetMimeContentType(nil,0,FileName);
    Call.OutStatus := HTML_SUCCESS;
    if Handle304NotModified then begin
      clientHash := FindIniNameValue(pointer(Call.InHead),'IF-NONE-MATCH: ');
      serverHash := '"'+DateTimeToIso8601(FileTime,false)+'"';
      Call.OutHead := Call.OutHead+#13#10'ETag: '+serverHash;
      if clientHash=serverHash then begin
        Call.OutStatus := HTML_NOTMODIFIED;
        exit;
      end;
    end;
    // Content-Type: appears twice: 1st to notify static file, 2nd for mime type
    Call.OutHead := STATICFILE_CONTENT_TYPE_HEADER+#13#10+Call.OutHead;
    if AdditionalHeader <> '' then
      Call.OutHead := Call.OutHead+#13#10+AdditionalHeader;
    StringToUTF8(FileName,Call.OutBody);
  end;
end;

Offline

#2 2014-11-12 10:20:19

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: TSQLRestServerURIContext.ReturnFile headers

You can still access the headers AFTER a call to ReturnFile().

So the easiest is to write:

  Ctxt.ReturnFile(...);
  if Ctxt.Call.OutStatus=HTML_SUCCESS then
    Ctxt.Call.OutHead := Ctxt.Call.OutHead+#13#10+AdditionalHeader;

Offline

#3 2014-11-12 10:30:14

esmondb
Member
From: London
Registered: 2010-07-20
Posts: 299

Re: TSQLRestServerURIContext.ReturnFile headers

Thanks, I thought there could be an easier.

Offline

#4 2014-11-12 10:50:22

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: TSQLRestServerURIContext.ReturnFile headers

So perhaps an explicit AttachmentFileName: RawUTF8 parameter could make more sense, in this case.

Offline

#5 2014-11-12 11:23:51

esmondb
Member
From: London
Registered: 2010-07-20
Posts: 299

Re: TSQLRestServerURIContext.ReturnFile headers

I guess that could be useful otherwise the default filename for the client is taken from the url which is probably the service name.

In which case the function could become:

procedure TSQLRestServerURIContext.ReturnFile(const FileName: TFileName;
  Handle304NotModified: boolean; const ContentType: RawUTF8; const AttachmentFileName: RawUTF8{=''});
var FileTime: TDateTime;
    clientHash, serverHash: RawUTF8;
begin
  FileTime := FileAgeToDateTime(FileName);
  if FileTime=0 then
    Error('',HTML_NOTFOUND) else begin
    if ContentType<>'' then
      Call.OutHead := HEADER_CONTENT_TYPE+ContentType else
      Call.OutHead := HEADER_CONTENT_TYPE+GetMimeContentType(nil,0,FileName);
    Call.OutStatus := HTML_SUCCESS;
    if Handle304NotModified then begin
      clientHash := FindIniNameValue(pointer(Call.InHead),'IF-NONE-MATCH: ');
      serverHash := '"'+DateTimeToIso8601(FileTime,false)+'"';
      Call.OutHead := Call.OutHead+#13#10'ETag: '+serverHash;
      if clientHash=serverHash then begin
        Call.OutStatus := HTML_NOTMODIFIED;
        exit;
      end;
    end;
    // Content-Type: appears twice: 1st to notify static file, 2nd for mime type
    Call.OutHead := STATICFILE_CONTENT_TYPE_HEADER+#13#10+Call.OutHead;
    if AttachmentFileName <> '' then
      Call.OutHead := Call.OutHead+#13#10+'Content-Disposition: attachment; filename="'+AttachmentFileName+'"';
    StringToUTF8(FileName,Call.OutBody);
  end;
end;

Offline

#6 2014-11-12 11:43:21

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: TSQLRestServerURIContext.ReturnFile headers

OK. I've added an optional AttachmentFileName parameter to TSQLRestServerURIContext.ReturnFile() method.
See http://synopse.info/fossil/info/85dcdbbd38

Thanks for the feedback!

Offline

Board footer

Powered by FluxBB