class StreamFile extends DfsServlet {

  @SuppressWarnings("unchecked")
  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    final String filename = ServletUtil.getDecodedPath(request, "/streamFile");
    final String rawFilename = ServletUtil.getRawPath(request, "/streamFile");

    if (filename == null || filename.length() == 0) {
      response.setContentType("text/plain");
      PrintWriter out = response.getWriter();
      out.print("Invalid input");
      return;
    }
    
    DFSClient dfs;
    try {
      dfs = getDFSClient(request);
    } catch (InterruptedException e) {
      response.sendError(400, e.getMessage());
      return;
    }

    Enumeration<String> reqRanges = request.getHeaders("Range");
    if (reqRanges != null && !reqRanges.hasMoreElements()) {
      reqRanges = null;
    }

    DFSInputStream in = null;
    OutputStream out = null;

    try {
      in = dfs.open(filename);
      out = response.getOutputStream();
      final long fileLen = in.getFileLength();

      if (reqRanges != null) {
        List<InclusiveByteRange> ranges =
          InclusiveByteRange.satisfiableRanges(reqRanges, fileLen);
        StreamFile.sendPartialData(in, out, response, fileLen, ranges);
      } else {
        // No ranges, so send entire file
        response.setHeader("Content-Disposition", "attachment; filename=\"" + 
                           rawFilename + "\"");
        response.setContentType("application/octet-stream");
        response.setHeader(CONTENT_LENGTH, "" + in.getFileLength());
        StreamFile.copyFromOffset(in, out, 0L, fileLen);
      }
      in.close();
      in = null;
      out.close();
      out = null;
      dfs.close();
      dfs = null;
    } catch (IOException ioe) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("response.isCommitted()=" + response.isCommitted(), ioe);
      }
      throw ioe;
    } finally {
      IOUtils.cleanup(LOG, in);
      IOUtils.cleanup(LOG, out);
      IOUtils.cleanup(LOG, dfs);
    }
  }

}