title: Returning CSV file from Servlet using ServletOutputStream over HTTPS in Internet Explorer
body: <p>I have a Servlet which is returning a csv file that is 'working' over HTTP in both internet explorer and firefox.  When I execute the same Servlet over HTTPS only firefox continues to download the csv file over HTTPS.  I don't think this is necessarily an Internet 6 or 7 issue described <a href="http://support.microsoft.com/kb/812935" rel="noreferrer">on MSDN</a> :</p>
  
  <p>The message is:</p>
  
  <blockquote>
    <p>Internet Explorer cannot download
    data.csv from mydomain.com   Internet
    Explorer was not able to open this
    Internet site.  The requested site is
    either unavailable or cannot be found.
    Please try again later.</p>
  </blockquote>
  
  <p>Please note that the site is still 'up' after this message and you can continue to browse the site, its just the download of the CSV that prompts this message.  I have been able to access similar files over https on IE from other j2ee applications so I believe it is our code.  <strong>Should we not be closing the bufferedOutputStream?</strong>  </p>
  
  <p><strong>UPDATE</strong></p>
  
  <p><strong>whether to close or not to close the output stream:</strong>
  I asked this question on the java posse forums and the <a href="http://groups.google.com/group/javaposse/browse_thread/thread/3213a24d63e371f6" rel="noreferrer">discussion</a> there is also insightful.  In the end it seems that no container should rely on the 'client' (your servlet code in this case) to close this output stream.  So if your failure to close the stream in your servlet causes a problem it is more a reflection on the poor implementation of your servlet container than your code.  I sited the behavior of the IDEs and tutortials from Sun, Oracle and BEA and how they are also inconsistent in whether they close the stream or not.</p>
  
  <p><strong>About IE specific behavior</strong>:  In our case a separate product 'Oracle Web Cache' was introducing the additional header values which impacts Internet explorer only because of the way IE implements the 'No Cache' requirement (<a href="http://blogs.msdn.com/ieinternals/archive/2009/10/02/Internet-Explorer-cannot-download-over-HTTPS-when-no-cache.aspx" rel="noreferrer">see the MSDN article</a>).
  The code is:</p>
  
  <pre><code>public class DownloadServlet extends HttpServlet {
      public void doGet(HttpServletRequest request, 
                        HttpServletResponse response) throws ServletException, 
                                                             IOException {
          ServletOutputStream out = null;
          ByteArrayInputStream byteArrayInputStream = null;
          BufferedOutputStream bufferedOutputStream = null;
          try {
              response.setContentType("text/csv");
                          String disposition = "attachment; fileName=data.csv";
              response.setHeader("Content-Disposition", disposition);
  
              out = response.getOutputStream();
              byte[] blobData = dao.getCSV();
  
              //setup the input as the blob to write out to the client
              byteArrayInputStream = new ByteArrayInputStream(blobData);
              bufferedOutputStream = new BufferedOutputStream(out);
              int length = blobData.length;
              response.setContentLength(length);
              //byte[] buff = new byte[length];
               byte[] buff = new byte[(1024 * 1024) * 2];
  
              //now lets shove the data down
              int bytesRead;
              // Simple read/write loop.
              while (-1 != 
                     (bytesRead = byteArrayInputStream.read(buff, 0, buff.length))) {
                  bufferedOutputStream.write(buff, 0, bytesRead);
              }
              out.flush();
              out.close();
  
          } catch (Exception e) {
              System.err.println(e); throw e;
  
          } finally {
              if (out != null)
                  out.close();
              if (byteArrayInputStream != null) {
                  byteArrayInputStream.close();
              }
              if (bufferedOutputStream != null) {
                  bufferedOutputStream.close();
              }
          }
      }
  </code></pre>