Services - Streaming a response from a file in a service controller

Enonic version: 6.9.3
OS: Ubuntu

I’m working on a spreadsheet library and want to stream the created content result. Currently I can successfully create a media content and then create a attachment url that can be used to download the resource. But The best solution would be able to stream the response immediately.

Is this possible ?

You can return the stream by setting it in the body property of the response:

var stream = getSpreadsheetStream();

return {
   body: stream
}

If the spreadsheet file comes from a Java lib, the best is to convert it or wrap it as a ByteSource object. Returning an object of type byte[] would also works but is probably less efficient.

1 Like

Hmm, Having some issues i’m trying to append an extra header to the response so the browser will open a spreadsheet viewer.

I’m trying this:

 return {
        body: <BODY>,
        contentType : "application/vnd.ms-excel",
        contentDisposition: 'attachment; filename="filename.xlsx"'
    }; 

But it seems that the “contentDisposition” header gets lost on its way back to the browser.

HTTP/1.1 200 OK
Date: Mon, 20 Mar 2017 12:48:43 GMT
Content-Type: application/vnd.ms-excel
Vary: Accept-Encoding, User-Agent
Content-Encoding: gzip
Content-Length: 2088 

Can you see anything wrong ?

Almost right, you are missing the headers property:

 return {
        body: <BODY>,
        contentType : "application/vnd.ms-excel",
        headers : {
                "Content-Disposition": 'attachment; filename="filename.xlsx"'
        }
    };

The contentType is a special property, even though it’s also a header and could be specified inside the headers object.

http://xp.readthedocs.io/en/6.9/developer/ssjs/http-response.html

2 Likes

Thanks works.
I’m must have overlooked that part of the response. So I learned something today too :slight_smile:

2 Likes

Also, if you set xls or xlsx as the name in the content-disposition you should not have to specify the contentType? Bit unsure about this but there is a default mimeType list in XP for this (I hope…).

Actually, the contentType property is just a shortcut to setting the “Content-Type” header.

I can confirm that this also works.

 return {
        body: stream,
        headers : {
            "Content-Disposition": 'attachment; filename="filename.xlsx"'
        }
    };