FileDownLoad

 | JSP
2012. 5. 8. 18:13

[ 다운로드 ]


많은 분들이 download.jsp등이나 서블릿을 이용해서 download를 구현을 합니다.
그 이유는 download를 통해서 down을 받게함으로서 직접적인 파일의 경로를
감추어 서버의 파일구조를 감추려는 보안적인 이유도 있을 것이고
또 download.jsp안에서 session에 값을 체크하여 인증절차를 거쳐야
자료를 받을 수 있게 하기 위한 것일 수도 있고

request.getHeader("referer")를 가지고 이전 페이지 url을알아내거나
HTTP Headers Information중 Host를 체크하여 무단적인 링크를 방지하기
위한 이유등 많은 이유로 처리를 하고 있을 것입니다.

저는 download를 구현함에 있어 같은 질문이 자주 올라오는 것 같아서
그런 내용들에 대해서 간단한 답변들을 적어보도록 하겠습니다.

1. 다운로드시 익스플로러 5.5 버전에서만 제대로 안되요.

이것 버전에 따라서 Header를 다르게 설정해줘야 합니다.

================================================================
중략...

  1. if( strClient.indexOf("MSIE 5.5") != -1 ) {
        response.setHeader("Content-Type", "doesn/matter;");
        response.setHeader("Content-Disposition", "filename=" + strFileName + ";");
    } else {
        response.setHeader("Content-Type", "application/octet-stream;");
        response.setHeader("Content-Disposition", "attachment;filename="+strFileName + ";");
    };
    response.setHeader("Content-Transfer-Encoding", "binary;");
    response.setHeader("Content-Length", ""+file.length());
    response.setHeader("Pragma", "no-cache;");
    response.setHeader("Expires", "-1;");

중략..
================================================================
위의 소스와 같이 HTTP Response Headers의 User-Agent를 체크해서

버전이 5.5일경우와 그외 버전일 경우 header를 다르게 설정해줘야

합니다.


2. 파일 다운로드우 이상한 문자가 앞에 추가가 됩니다.(서버에 파일은 문제없음)

이것은 jsp일때 앞부분에 page지시자를 기술할때 다른 내용이 들어가서 그문자가

파일에 추가되어 나타나는 현상입니다. 해결방법은
================================================================
<%@ page language="java" import="java.util.*,java.io.*,java.sql.*,java.text.*"%>
<%
   String file_path = "D:/resin/webapps"+request.getParameter("file_path");
중략..
================================================================
과 같이 Enter를 입력해서 벌어진 부분을
================================================================
<%@ page language="java" import="java.util.*"%><%
   String file_path = "D:/resin/webapps"+request.getParameter("file_path");
중략..
================================================================
과 같이 붙여서 만들어주면 해결할 수 있습니다.


3. 엑셀, 워드, 파워포인트 파일의 다운로드

ppt나 xls확장자같은경우 전 아래와같이 해서 다운로드를 받고 있습니다.
어디서 소스를 봤는지 기억은 잘 안나지만..아래는 jsp화일의 일부분입니다.

String type  = request.getParameter("do");
String fileurl  = request.getParameter("fileurl");
String filepath = request.getParameter("filepath");
String filename = fileurl.substring(filepath.length()+1,fileurl.length());
PrintStream printstream = new PrintStream(response.getOutputStream(), true);
try {
         File file = new File(filepath,filename);
         FileInputStream fin = new FileInputStream(file);
         
         int ifilesize = (int)file.length();
         byte b[] = new byte[ifilesize];
         
         response.setContentLength(ifilesize);
         response.setContentType("application/smnet");
         response.setHeader("Content-Disposition","attachment; filename="+filename+";");
         
         ServletOutputStream oout = response.getOutputStream();
         
         fin.read(b);
         oout.write(b,0,ifilesize);
         oout.close();
         fin.close(); 
} catch(Exception e) {  }


4. 초간단 파일다운로드 소스

간단한 파일 다운로드 프로그램임다..
링크는 download.jsp?db=db이름&table=table이름&num=번호 와 같이 하면 됩니다.

-- download.jsp --

<%@ page contentType="text/html; charset=EUC_KR" %>
<%@ page import="java.io.*, IBboard.beans.file.FileDownload" %>
<%
//응답 헤더의 Content-Type을 세팅한다.
response.setContentType("application/x-msdownload");

FileDownload filedown = new FileDownload();

//DB에서 해당 번호에 해당하는 파일의 이름을 얻어온다.
String filename = filedown.NumToFilename(request.getParameter("db"),request.getParameter("table"),Integer.parseInt(request.getParameter("num")));
//Content-Disposition 헤더에 세팅하기위해 file 이름을 코드 변환한다.
//한글파일 Download 시에 에러가 나는게 이 코드가 빠져 있어서 그런거 같은디..^^
String filename2 = new String(filename.getBytes("euc-kr"),"8859_1");
//Content-Disposition 헤더에 파일 이름 세팅.
response.setHeader("Content-Disposition","attachment; filename="+filename2);
//해당 경로의 파일 객체를 만든다.
File file = new File ("/usr/local/apache/htdocs/upload/"+filename);
//파일 스트림을 저장하기 위한 바이트 배열 생성.
byte[] bytestream = new byte[(int)file.length()];
//파일 객체를 스트림으로 불러온다.
FileInputStream filestream = new FileInputStream(file);
//파일 스트림을 바이트 배열에 넣는다.
int i = 0, j = 0;

while((i = filestream.read()) != -1) {

bytestream[j] = (byte)i;

j++;

}

// 응답 스트림 객체를 생성한다.

OutputStream outStream = response.getOutputStream();

// 응답 스트림에 파일 바이트 배열을 쓴다.

outStream.write(bytestream);

outStream.close();

%>

 


<%-- Download.jsp --%>

<%@page contentType="text/html; charset=euc-kr" %>

<%@page import="java.io.*,java.net.*,javax.servlet.*,javax.servlet.http.*"%>
<%
 String realPath = "실제화일명.txt";
 String saveFileName = "저장시사용할화일.txt";

 

/* UTF8로 인코딩된 한글 이름의 파일을 다운로드 할때 경우에 해당한다.

 * 브라우저 옵션 고급에서 "URL을 항상 UTF-8로 보냄"로 체크되어 있을 경우는

 * 화일이름을 UTF8로 다시 인코딩 해 주어야 저장화일 이름이 깨지는 것을 막을 수 있다.

*/

 

saveFileName= URLEncoder.encode(saveFileName,"UTF8");

 

/** 다운로드 구현시 주의 사항

 * 보통 어플리케이션 서버를 root계정으로 돌리는 경우가 많다.

 * 이경우 잘못 하면 해킹의 기회를 제공 하는 경우가 있다.

 * 어떤 사이트를 보면 실제화일명을 파라미터로 받아서 처리 하는 경우 보안상 위험 할 수 있다.

 * 예를 들어 dowload.jsp?file=download/attach/../../../../../../etc/passwd

 * 위와같은 경우로 해커가 파라미터를 조작하면 계정 및 패스워드 화일외에 시스템 정보를

 * 얼마든지 획득 할 수 있다. 편의를 제공하기 우해 만든 다운로드 프로그램이.

 * 판단미스로 본 사이트를 해킹하는 툴로 사용 될 수 있다는 것이다.

 *  여기에서 아래와 같이 문자를 찾아서 해킹시도를 막는다.

  1.  if(realPath.indexOf("..") != -1 || realPath.indexOf("/") != -1) {
      return;
     }
  1.   PrintStream printstream = new PrintStream(response.getOutputStream(), true);
  1.   FileInputStream fin = null;
      ServletOutputStream outs = null;
  1.  try{
  1.  //이부분에서 화일객체 생성시 해킹에 사용 될 수 있다.
  1. // 가급적이면 화일명을 파라미터가 아니 DB에 가져오도록 로직을 구현하는게 좋다.
  1. //웹상에 보여주는 화일명과 실제화일명을 DB에 넣어 숨기는 것이 좋다.
  1. //여기서는 단순 다운로드 구현을 설명 하고자 걍 사용 하기로 한다.
  1.   File file = new File("/home/test/download/" + realpath);
  1.   fin = new FileInputStream(file);
     
      int ifilesize = (int)file.length();
      byte b[] = new byte[ifilesize];
  1.   String strClient = request.getHeader("User-Agent");
  1.   response.setContentLength(ifilesize);
      response.reset() ;
      response.setContentType("application/octet-stream");
     
      if(strClient.indexOf("MSIE 5.5") > -1) {
           response.setHeader("Content-Disposition", "filename=" + new String(saveFileName.getBytes(),"ISO-8859-1") + ";");
      } else {
           response.setHeader("Content-Disposition", "attachment;
  1.               filename=" +  new String(saveFileName.getBytes("EUC-KR"),"ISO-8859-1") + ";");
      }
      response.setHeader("Content-Length", ""+ifilesize );
      outs = response.getOutputStream();
      response.setHeader("Content-Transfer-Encoding", "binary;");
      response.setHeader("Pragma", "no-cache;");
      response.setHeader("Expires", "-1;");
  1.   if (ifilesize > 0 && files.isFile()) {
         int read = 0;
  1.      while((read = fin.read(b)) != -1) {
             outs.write(b,0,read);
         }
      }
     } catch (FileNotFoundException fnfe) {
         System.out.println(fnfe.toString());
     } catch (Exception e) {
         System.out.println(e.toString());
     } finally{
        try {
            if(outs != null) outs.close();
            if(fin != null) fin.close();
        } catch (Exception e) {}
     }
  1. %>

이 글은 스프링노트에서 작성되었습니다.

'JSP' 카테고리의 다른 글

엑셀파일다운로드  (0) 2012.05.08
fileDownload.jsp  (0) 2012.05.08
cubrid-dbcp설정.  (0) 2012.05.08
ERROR&cokie  (0) 2012.05.08
ss  (0) 2012.05.08
Posted by 사라링
BLOG main image
.. by 사라링

카테고리

사라링님의 노트 (301)
JSP (31)
J-Query (41)
JAVA (24)
VM-WARE (0)
디자인패턴 (1)
스크랩 (0)
스트러츠 (3)
안드로이드 (11)
오라클 (45)
우분투-오라클 (1)
이클립스메뉴얼 (6)
스프링3.0 (23)
자바스크립트 (10)
HTML5.0 (17)
정보처리기사 (1)
기타(컴퓨터 관련) (1)
문제점 해결 (3)
프로젝트 (2)
AJAX (4)
하이버네이트 (3)
트러스트폼 (11)
Jeus (2)
재무관리(회계) (5)
정규식 (5)
아이바티스 (8)
취미 (2)
소프트웨어 보안 관련모음 (0)
정보보안기사 (6)
C언어 베이직 및 프로그램 (3)
보안 관련 용어 정리 (2)
넥사크로 (6)
Total :
Today : Yesterday :