Skip to main content
New Participant
May 21, 2024
Question

Pipe a remote file to response

  • May 21, 2024
  • 1 reply
  • 1264 views

How can I pipe a remote file directly to the response, without having to read the file in the memory or writing it to disk on the server? The remote file can be huge and I'm not going to do anything to the file itself. If possible I'd like to be able to set the basic headers like 'content-type' and 'content-length'. 

    This topic has been closed for replies.

    1 reply

    BKBK
    Adobe Expert
    May 22, 2024

    You can do it using three lines of code:

    <cfhttp  method="get" getasbinary="yes" result="httpResult" charset="utf-8" url="url_of_remote_file">
    <!--- Here, ".ext" stands for an arbitrary file extension. Specify the one you want ---> 
    <cfheader name="content-disposition" value="inline;filename=binaryfile.ext">
    <!--- Application/octet-stream is the default MIME type for binary files. ---> 
    <cfcontent type="application/octet-stream" variable="#httpresult.filecontent#">

    Example:

    <cfhttp  method="get" getasbinary="yes" result="httpResult" charset="utf-8" url="https://community.adobe.com/t5/image/serverpage/image-id/694431i786EBFDC18FC0D6D/image-size/original?v=v2&px=-1">
    <!--- I have used JPG extension because I know the URL points to a pivture --->
    <cfheader name="content-disposition" value="inline;filename=binaryfile.jpg">
    <cfcontent type="application/octet-stream" variable="#httpresult.filecontent#">

     

    charlieCFAuthor
    New Participant
    May 22, 2024

    @BKBK Thank you for your reply. 

    But isn't that cfhttp will hold the entire remote file in-memory? I have files in the hundreds of MB hence I'd like to avoid holding the files in-memory or writing them to disk. More like "piping" the remote file to the response directly. If CF can't do this, maybe I can tap on Java, but what package or library to use? TIA

    BKBK
    Adobe Expert
    May 22, 2024

    Ah, thanks for the clarification. Yes, what you have clarified can be done in ColdFusion.

     

    You've already guessed what I, too, have in mind: using Java. The good news is, if you can do this in Java, tehn you can do it in ColdFusion. The challenge is then to convert the Java code to CFML.

     

    Here is some sample code, courtesy of ChatGPT:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet("/download")
    public class FileDownloadServlet extends HttpServlet {
    
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // Path to the file to be downloaded
            String filePath = "C:/path/to/your/file/example.pdf";
            File file = new File(filePath);
    
            // Set the content type
            response.setContentType("application/pdf"); // Change this to the appropriate MIME type
            response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
            response.setHeader("Content-Length", String.valueOf(file.length()));
    
            // Stream the file content directly to the response output stream
            try (FileInputStream fileInputStream = new FileInputStream(file);
                 OutputStream responseOutputStream = response.getOutputStream()) {
                 
                byte[] buffer = new byte[8192];
                int bytesRead;
    
                while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                    responseOutputStream.write(buffer, 0, bytesRead);
                }
            }
        }
    }
    

    ChatGPT Explanation:

    1. Servlet Setup: The servlet is annotated with @WebServlet to define the URL pattern. In this example, it listens to /download.
    2. File Path: The path to the file to be streamed is specified.
    3. Response Headers:
      • Content-Type is set to the MIME type of the file (e.g., application/pdf).
      • Content-Disposition is set to display the file inline with the filename.
      • Content-Length is set to the size of the file.
    4. Streaming the File:
      • A FileInputStream is created to read the file.
      • The response output stream (response.getOutputStream()) is used to write the file content to the response.
      • A buffer is used to read the file in chunks (8 KB in this example) to avoid loading the entire file into memory.

    This approach ensures that the file is streamed in manageable chunks, minimizing memory usage and avoiding the need to load the entire file into memory.