Quantcast
Channel: Active questions tagged servlets - Stack Overflow
Viewing all articles
Browse latest Browse all 714

Large file download using Servlet with Streaming without browser buffering

$
0
0

I am developing a Java 8 servlet to download a zipped resource. The file size can vary significantly, sometimes reaching up to 700MB. For testing, I am using a 350MB ZIP file.

The expected behavior is that the file should start downloading immediately while streaming, but instead, the browser buffers the file before prompting the user to save it. This results in a delay of 30-40 seconds before the save dialog appears.

My Servlet Code:

@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    String strCryptedURL = request.getParameter(DownloadFolderServlet.URL_PARAM_NAME);    String strURL = PasswordUtil.isPasswordEncrypted(strCryptedURL) ? PasswordUtil.decryptPassword(strCryptedURL) : strCryptedURL;    try {        URL url = new URL(strURL);        String userInfo = url.getUserInfo();        if (userInfo == null || !userInfo.contains(":")) {            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing credentials for WebDAV.");            return;        }        String[] userPass = userInfo.split(":", 2);        String username = userPass[0];        String password = userPass[1];        String sanitizedURL = url.getProtocol() +"://" + url.getHost() +":" + url.getPort() + url.getPath();        HttpURLConnection fileConn = (HttpURLConnection) new URL(sanitizedURL).openConnection();        fileConn.setRequestMethod("GET");        fileConn.setConnectTimeout(10000);        fileConn.setReadTimeout(60000);        String encodedAuth = Base64.getEncoder().encodeToString((username +":" + password).getBytes(StandardCharsets.UTF_8));        fileConn.setRequestProperty("Authorization", "Basic " + encodedAuth);        if (fileConn.getResponseCode() != HttpURLConnection.HTTP_OK) {            response.sendError(fileConn.getResponseCode(), "Error retrieving file from WebDAV.");            return;        }        String fileName = url.getPath().substring(url.getPath().lastIndexOf("/") + 1);        response.reset();        response.setContentType("application/octet-stream");        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName +"\"");        response.setHeader("Content-Transfer-Encoding", "binary");        response.setHeader("Transfer-Encoding", "chunked"); // Tried enabling chunked encoding        response.flushBuffer();        try (InputStream inputStream = fileConn.getInputStream();             OutputStream outputStream = response.getOutputStream()) {            byte[] buffer = new byte[8192]; // 8 KB buffer            int bytesRead;            while ((bytesRead = inputStream.read(buffer)) != -1) {                outputStream.write(buffer, 0, bytesRead);                outputStream.flush(); // Ensuring data is sent immediately            }        }    } catch (Exception e) {        e.printStackTrace();        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error while downloading the ZIP file.");    }}

I have tried:

  1. Setting Transfer-Encoding: chunked
  2. Ensuring Content-Type: application/octet-stream
  3. Using flushBuffer()
  4. Explicitly avoiding Content-Length (to prevent buffering)

Expected Behavior:The browser should prompt the user immediately and start downloading progressively instead of waiting for the entire file to be received.

Questions:

  1. Is there anything in my implementation that causes the browser tobuffer everything before showing the save prompt?
  2. Is there a way to force the browser to stream the file as soon asbytes are available?

Viewing all articles
Browse latest Browse all 714

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>