CFHTTP fileContent binary to string

Description

When downloading a file using Http(), Lucee downloads as text or byte array based on mimetype. I have a use case where I want to download various files and make them readable to the user, but javascript files are getting converted to a byte array. Both ACF and Lucee consider javascript as non-text, however ACF allows you to call result.fileContent.toString() to gracefully override the type. Using the same code in Lucee returns string representation of a byte array (e.g. "[B@44951b19").

From what I can tell, the root cause is that Lucee uses byte[] where as ACF uses java.io.ByteArrayOutputStream, and that class is what provides the desired toString() behaviour.

The workaround in Lucee is to manually create a java.lang.String and pass the byte[] to init().

Lucee's Http also has a "getasbinary" flag, but this can only be used to force binary download of text objects, not force text download of binary objects.

Solutions in order of preference:

  1. Use a ByteArrayOutputStream instead of byte[] to store the fileContent variable, although I worry about it impacting other things (I've only glanced through the code).

  2. Change getAsBinary behaviour so that setting "false" forces text-based download.

  3. Add "application/javascript" to the HTTPUtil::isTextMimeType() check, although this would be creating another inconsistency between ACF and Lucee

Sample code:

<cfscript> local.http = new Http(url = "https://apis.google.com/js/api.js", method="GET"); local.result = local.http.send().getPrefix(); WriteDump(local.result); WriteDump(local.result.fileContent.toString()); // Lucee workaround -- fails in ACF WriteDump(CreateObject('java', 'java.lang.String').init(local.result.fileContent)); </cfscript>

Activity

Show:

Joe Wakefield 24 September 2018 at 14:23

Ah that works great, thanks! I didn't consider that the global toString() would have been different.

Michael Offner 21 September 2018 at 23:03
Edited


I'm strongly against returning a ByteArrayOutputStream in that case, it feels wrong on so many levels.
the reason Lucee does not provide a ByteArrayOutputStream is very simple, in my opinion this is wrong in ACF.
ByteArrayOutputStream is a container to pass data from a stream to memory, as soon you done you extract the bytes with help of the method

toByteArray()

Normally in Java you never use ByteArrayOutputStream as a permanent container to hold data.

But there is a simple solution, use CFML functionality instaed of underlaying undocumented Java methods.
So instead

WriteDump(local.result.fileContent.toString());

do

WriteDump(toString(local.result.fileContent));

This not only solve your problem, it is also not relaying on undocumented functionality.

Actually the attribute "getAsBinary" sucks, instead we should have a attribute "contentType" that allows 3 possible values

  • text

  • binary

  • auto

We can use the problem by adding a member function "toString" for byte[].

i will reduce priority of this ticket, because there is a solution for your problem that does NOT relay on undocumented functionality.

Pothys - MitrahSoft 4 September 2018 at 15:28

I've added a test case for this ticket & Confirmed the issue happened while using toString() in file content, It returns 'B@10b0030a' string values.

But, If we use http(for calling internal js file) instead of https, it working fine.

Pull request : https://github.com/lucee/Lucee/pull/569

Details

Assignee

Reporter

Labels

New Issue warning screen

Before you create a new Issue, please post to the mailing list first https://dev.lucee.org

Once the issue has been verified, one of the Lucee team will ask you to file an issue

Affects versions

Priority

Created 29 August 2018 at 18:33
Updated 4 February 2024 at 23:21