You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
335 lines
16 KiB
335 lines
16 KiB
/** |
|
* ******************************************************************************** |
|
* 프로그램명 : HttpFileUploadDir.java 작 성 자 : 강원중 작 성 일 : 2003. 7.23 최신변경일 : 2013. |
|
* 1.11 |
|
********************************************************************************** |
|
*/ |
|
package kr.co.kihyun.beans.totsys.board; |
|
|
|
import java.io.File; |
|
import java.io.FileInputStream; |
|
import java.io.IOException; |
|
import java.net.URLEncoder; |
|
import java.util.Arrays; |
|
|
|
import javax.jdo.PersistenceManager; |
|
import javax.jdo.Transaction; |
|
import javax.servlet.ServletException; |
|
import javax.servlet.annotation.WebServlet; |
|
import javax.servlet.http.HttpServlet; |
|
import javax.servlet.http.HttpServletRequest; |
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import kr.co.kihyun.beans.entity.TotReport; |
|
import kr.co.kihyun.beans.entity.util.PMF; |
|
import kr.co.kihyun.beans.user.HttpSSOLogin; |
|
import kr.co.kihyun.db.CommonDBManager; |
|
import kr.co.kihyun.io.FileUtil; |
|
import kr.co.kihyun.io.MultipartRequest; |
|
import kr.co.kihyun.lang.MInteger; |
|
import kr.co.kihyun.lang.MLong; |
|
import kr.co.kihyun.lang.MString; |
|
import kr.co.kihyun.moumi.MoumiConfig; |
|
//import kr.co.kihyun.text.html.ServletUtil; |
|
import kr.co.kihyun.util.MRandom; |
|
|
|
import org.apache.commons.fileupload.FileItem; |
|
import org.apache.commons.io.FileUtils; |
|
import org.slf4j.Logger; |
|
import org.slf4j.LoggerFactory; |
|
@WebServlet("/servlet/kr.co.kihyun.beans.totsys.board.HttpFileUploadDir") |
|
public class HttpFileUploadDir extends HttpServlet { |
|
|
|
/** |
|
* |
|
*/ |
|
private static final long serialVersionUID = 1L; |
|
private static final Logger LOG = LoggerFactory.getLogger(HttpFileUploadDir.class); |
|
|
|
@Override |
|
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { |
|
|
|
res.setContentType("text/html;charset=UTF-8"); |
|
|
|
MultipartRequest multi = null; |
|
String svrFilename = ""; |
|
String usrFilename = ""; |
|
String boardGroupID = ""; |
|
String connURL = ""; |
|
String mode = ""; |
|
String usID = HttpSSOLogin.getLoginID(req); |
|
// String dtID = HttpSSOLogin.getDeptID(req); |
|
String dtID = ""; |
|
Long docID = null; |
|
String reportID = null; |
|
String boardID = ""; |
|
String msg = ""; |
|
String maxSize = "3"; |
|
String checkSize = ""; |
|
boolean isExtNullOk = true; //7.+++ |
|
boolean isExtFileOk = true; //7.+++ |
|
boolean isDirectoryOk = true; //3.+++ |
|
|
|
Long currentFileSize = 0L; // 업로드할 파일의 크기(byte)를 저장할 변수. 2014.09.02 by youngjun cho. |
|
Long accumulateFileSize = 0L; // 업로드된 파일들의 총 누적 크기(byte)를 저장할 변수. 2014.09.02 by youngjun cho. |
|
|
|
CommonDBManager acdbm1=new CommonDBManager(); |
|
PersistenceManager pm = PMF.get().getPersistenceManager(); |
|
Transaction tx = pm.currentTransaction(); |
|
|
|
|
|
try { |
|
|
|
maxSize = req.getParameter("maxSize"); |
|
if (maxSize == null || maxSize.equals("")) { |
|
maxSize = "10"; |
|
} |
|
int tmpSize = Integer.parseInt(maxSize) * 1024 * 1024; //사이즈를 정해준다. |
|
checkSize = String.valueOf(tmpSize); |
|
|
|
multi = new MultipartRequest(req, tmpSize); |
|
|
|
mode = MString.checkNull(multi.getParameter("mode")); |
|
boardGroupID = multi.getParameter("boardGroupID"); |
|
usrFilename = multi.getParameter("appendFile"); |
|
|
|
//20170818 파일 검사수행 이전으로 옮김 by wonseok Lee. false 리턴시 첨부파일 관련 아래의 ID들을 이전페이지로 전달키 위해서임 |
|
docID = MLong.parseLong(multi.getParameter("docID")); |
|
reportID = MString.checkNull(multi.getParameter("reportID")); |
|
boardID = MString.checkNull(multi.getParameter("boardID")); |
|
dtID = MString.checkNull(multi.getParameter("dtID")); |
|
|
|
|
|
//7.위험한 형식 파일 업로드(MultipartRequest)_CWE-434 : Add by KWON,HAN |
|
int extIndex = 0 ; |
|
extIndex = usrFilename.lastIndexOf('.'); |
|
if(extIndex < 0 ) { |
|
//LOG.debug("7.위험한 형식 파일 업로드(MultipartRequest)_CWE-434 : Not Test / usrFilename: {}", usrFilename); |
|
isExtNullOk = false; |
|
//out.print("<script language='javascript'>alert('확장자가 없는 파일입니다.');</script>"); |
|
return; |
|
} |
|
|
|
//v2 22.정수형 오버플로우_CWE-190 : Update by YOUNGJUN,CHO |
|
if (extIndex < Integer.MAX_VALUE) { |
|
//String file_ext = usrFilename.substring(usrFilename.lastIndexOf('.') + 1); |
|
String file_ext = usrFilename.substring(extIndex + 1); |
|
|
|
if( file_ext.equalsIgnoreCase("exe") || file_ext.equalsIgnoreCase("bat") || file_ext.equalsIgnoreCase("sh") ) { |
|
//LOG.debug("7.위험한 형식 파일 업로드(MultipartRequest)_CWE-434 : Not Test / usrFilename: {}", usrFilename); |
|
//out.print("<script language='javascript'>alert('확장자가 [exe, bat, sh]는 업로드가 제한된 파일입니다.');</script>"); |
|
isExtFileOk = false; |
|
return; |
|
} |
|
} else { |
|
//LOG.debug("v2 22.정수형 오버플로우_CWE-190 : Not Test / usrFilename: {}", usrFilename); |
|
//out.print("<script language='javascript'>alert('확장자가 [exe, bat, sh]는 업로드가 제한된 파일입니다.');</script>"); |
|
isExtFileOk = false; |
|
return; |
|
} |
|
//================================================ v2 22.정수형 오버플로우_CWE-190 : Update by YOUNGJUN,CHO |
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7.위험한 형식 파일 업로드(MultipartRequest)_CWE-434 : Add by KWON,HAN |
|
|
|
// 2014.09.02 by youngjun cho. |
|
// 업로드된 파일들의 총 누적 크기(byte)를 jsp 의 hidden value 에 저장 후 파라미터로 받아온다. |
|
//accumulateFileSize = MLong.parseLong(multi.getParameter("accumulateFileSize")); |
|
|
|
//LOG.debug("docID: {}, boardID: {}, mode: {}", new Object[] {docID, boardID, mode}); |
|
if (!MString.isNull(usrFilename)) { |
|
String[] usrFilenamePath = usrFilename.split("\\\\"); |
|
usrFilename = usrFilenamePath[usrFilenamePath.length - 1]; |
|
|
|
String imsi = ""; |
|
// String[] filter_word = {" ", "\\?", "\\/", "\\~", "\\!", "\\@", "\\#", "\\$", "\\%", "\\^", "\\&", "\\*", "\\(", "\\)", "\\+", "\\=", "\\|", "\\\\", "\\}", "\\]", "\\{", "\\[", "\\\"", "\\'", "\\:", "\\;", "\\<", "\\,", "\\>", "\\?", "\\/"}; |
|
String[] filter_word = {"\\?","\\/","\\~","\\!","\\@","\\#","\\$","\\%","\\^","\\&","\\*","\\+","\\=","\\|","\\\\","\\\"","\\'","\\:","\\;","\\,"}; |
|
for (int ii = 0; ii < filter_word.length; ii++) { |
|
imsi = usrFilename.replaceAll(filter_word[ii], "_"); |
|
usrFilename = imsi; |
|
} |
|
|
|
LOG.debug("usrFilename: {}", usrFilename); |
|
} |
|
|
|
File path; |
|
//svrFilename = FileUtil.getName(usrFilename, Integer.toString(MRandom.getInt(100))); //두자리의 랜덤 수치를 얻음 |
|
|
|
if (docID != null) { |
|
path = MoumiConfig.getFileDirectory(); |
|
LOG.debug("MoumiConfig.getFileDirectory(): " + MoumiConfig.getFileDirectory()); |
|
} else if (reportID != null) { |
|
path = MoumiConfig.getFileDirectory(); |
|
LOG.debug("MoumiConfig.getFileDirectory(): " + MoumiConfig.getFileDirectory()); |
|
// } else if (!MString.isNull(boardID)) { |
|
// path = new File(MoumiConfig.getBoardFileRoot(), boardID.toString()); |
|
// LOG.debug("MoumiConfig.getBoardFileRoot(): " + MoumiConfig.getBoardFileRoot()); |
|
} else if ("csv".equals(mode)) { |
|
path = MoumiConfig.getCsvFileRoot(); |
|
LOG.debug("MoumiConfig.getCsvFileRoot(): " + MoumiConfig.getCsvFileRoot()); |
|
} else { |
|
path = MoumiConfig.getFileDirectory(); |
|
LOG.debug("MoumiConfig.getFileDirectory(): " + MoumiConfig.getFileDirectory()); |
|
} |
|
|
|
LOG.debug("passLine: {}"); |
|
//20170809_02 by wonseok Lee. 접수자료 > 자료입력 > 파일제출시 파일 업로드 수정, 파일직접 다운로드를 위해 업로드하는 파일을 MoumiConfig.getFileDirectory()2/DOCID/REPORTID/DeptID 디렉토리에 저장한다. |
|
|
|
if(mode.equals("repoper")) { |
|
svrFilename = usrFilename; |
|
|
|
LOG.debug("Long.toString(docID): {}",Long.toString(docID)); |
|
LOG.debug("Long.toString(reportID): {}",reportID); |
|
LOG.debug("Long.toString(dtID): {}",dtID); |
|
path = new File(MoumiConfig.getFileDirectory()+"/"+Long.toString(docID)+"/"+reportID+"/"+dtID); |
|
} |
|
|
|
LOG.debug("passLine: {}"); |
|
if (!path.isDirectory()) { |
|
if (!path.mkdirs()) { |
|
throw new ServletException(path + " is not a directory."); |
|
} |
|
} |
|
accumulateFileSize = FileUtils.sizeOfDirectory(path); |
|
|
|
|
|
FileItem upFile = multi.getFileItem("appendFile"); |
|
LOG.debug("UPFILE: {}", upFile); |
|
|
|
// 업로드할 파일의 크기를 구한다. (2014.09.02 by youngjun cho.) |
|
currentFileSize = upFile.getSize(); |
|
LOG.debug("UPFILE currentFileSize : {}", currentFileSize); |
|
accumulateFileSize = accumulateFileSize + currentFileSize; |
|
|
|
LOG.debug("passLine: {}"); |
|
|
|
LOG.debug("accumulateFileSize : {}"+ accumulateFileSize); |
|
// 제한용량 이상이면 "-66" 을 리턴한다. (2014.09.02 by youngjun cho.) |
|
//if (tmpSize <= accumulateFileSize) { |
|
if (accumulateFileSize > 3096000) { //(20170817 by wonseok Lee.) maxSize를 1로하고 1MB 이상의 첨부파일을 첨부하면 다음 exception 발생함=>org.apache.commons.fileupload.FileUploadBase$FileSizeLimitExceededException: |
|
msg = "-66"; |
|
return; |
|
} |
|
|
|
//3.디렉토리 경로 조작(getParameter)_CWE-22/23/36 : Add by KWON,HAN |
|
LOG.debug("svrFilename: {}", svrFilename); |
|
if(svrFilename.contains("..") || svrFilename. contains("/")) { // 특수문자열 검증 |
|
//LOG.debug("3.디렉토리 경로 조작(getParameter)_CWE-22/23/36 : Test OK {}", svrFilename); |
|
isDirectoryOk = false; |
|
return; |
|
} |
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
//20170814 if문 추가 by wonseok Lee. 업로드 파일이 중복이면 삭제하고 write. |
|
if(mode.equals("repoper")) { |
|
File existFile = new File(path+"/"+svrFilename); |
|
if(existFile.isFile()) { |
|
existFile.delete(); |
|
} |
|
} |
|
|
|
File attachFile = new File(path, svrFilename); |
|
LOG.debug("path writed to attachFile: {}/{}", attachFile); |
|
upFile.write(attachFile); |
|
LOG.debug("UPFILE writed to svrFilename: {}/{}", path, svrFilename); |
|
|
|
// ** 첨부파일을 DB에 저장하는 기능 ** |
|
// * 파일서버 경로에 저장하도록 개선하여 사용하지 않도록 주석 처리 17.12.14 jskim |
|
// tx.begin(); |
|
// TotReport totReport = pm.getObjectById(TotReport.class, Long.parseLong(reportID)); |
|
// |
|
// FileInputStream fis1 = null; |
|
// try { |
|
// |
|
// byte[] content1 = new byte[(int)attachFile.length()]; |
|
// Byte[] contentObj1 = new Byte[content1.length]; |
|
// |
|
// fis1 = new FileInputStream(attachFile); |
|
// fis1.read(content1);//파일의 내용을 읽어온다. |
|
// |
|
// for (int i = 0; i < content1.length; i++) { |
|
// contentObj1[i] = content1[i]; |
|
// } |
|
// |
|
// totReport.addAttachment(svrFilename, Arrays.asList(contentObj1)); //파일명과 내용을 HashMap에 입력 한다. |
|
// pm.makePersistent(totReport); |
|
// content1 = null; |
|
// contentObj1 = null; |
|
// tx.commit(); |
|
// |
|
// }catch(IOException e){ |
|
// e.printStackTrace(); |
|
// }finally{ |
|
// fis1.close(); |
|
// } |
|
|
|
|
|
StringBuilder sql = new StringBuilder(250); |
|
|
|
sql.delete(0, sql.length()); |
|
sql.append("UPDATE MOUMI_TOT_REPORT SET ATTACHMENTS_PATH = ATTACHMENTS_PATH|| ? WHERE ID = ? "); |
|
acdbm1.execUpdate(sql.toString(), svrFilename+";", reportID); |
|
acdbm1.pstmt.close(); |
|
|
|
sql.delete(0, sql.length()); |
|
sql.append("UPDATE MOUMI_TOT_REPORT_VERSION SET ATTACHMENTS_PATH = ATTACHMENTS_PATH|| ? WHERE REPORT_ID = ? AND ID=(SELECT MAX(ID) FROM MOUMI_TOT_REPORT_VERSION WHERE DEL_TYPE = 'N' AND REPORT_ID = ? )"); |
|
acdbm1.execUpdate(sql.toString(), svrFilename+";", reportID, reportID); |
|
acdbm1.pstmt.close(); |
|
|
|
acdbm1.commit(); |
|
svrFilename = URLEncoder.encode(svrFilename, "UTF-8"); |
|
usrFilename = URLEncoder.encode(usrFilename, "UTF-8"); |
|
|
|
|
|
} catch (Exception ex) { |
|
ex.printStackTrace(); |
|
|
|
if (tx.isActive()) |
|
tx.rollback(); |
|
acdbm1.rollback(); |
|
|
|
msg = ex.getMessage(); |
|
if (msg.indexOf(checkSize) > 0) { |
|
msg = "-99"; |
|
} else { |
|
msg = "-88"; |
|
} |
|
} finally { |
|
|
|
pm.close(); |
|
acdbm1.execClose(); |
|
|
|
connURL = "/totsys/common/inc/board/doc/write_file_upload_dir.jsp?execMode=up&svrFilename=" |
|
+ svrFilename + "&usrFilename=" + usrFilename + "&boardGroupID=" + boardGroupID + "&docID=" + docID |
|
+ "&reportID=" + reportID+ "&dtID=" + dtID + "&boardID=" + boardID + "&mode=" + mode + "&MSG=" + msg + "&maxSize=" + maxSize + "¤tFileSize=" + currentFileSize; |
|
if (connURL.length() > 2047) { |
|
msg = "-77"; |
|
} |
|
if(!isExtNullOk) { |
|
msg="-33"; |
|
} //7.+++ |
|
if(!isExtFileOk) { |
|
msg="-55"; |
|
} //7.+++ |
|
if(!isDirectoryOk) { |
|
msg="-44"; |
|
} //3.+++ |
|
if (!msg.equals("")) { |
|
svrFilename = ""; |
|
usrFilename = ""; |
|
currentFileSize = 0L; // 에러인 경우 파일이 업로드되지 않으므로 파일 크기를 0으로 리턴한다. (2014.09.02 by youngjun cho.) |
|
} |
|
|
|
|
|
if (svrFilename != null || usrFilename != null) { |
|
String filtered_svrFilename = svrFilename.replaceAll("\r","").replaceAll("\n",""); |
|
String filtered_usrFilename = usrFilename.replaceAll("\r","").replaceAll("\n",""); |
|
String allowURL[] = { "/totsys/common/inc/board/doc/write_file_upload_dir.jsp" }; |
|
connURL = allowURL[0] + "?execMode=up&svrFilename=" |
|
+ filtered_svrFilename + "&usrFilename=" + filtered_usrFilename + "&boardGroupID=" + boardGroupID + "&docID=" + docID |
|
+ "&reportID=" + reportID+ "&dtID=" + dtID + "&boardID=" + boardID + "&mode=" + mode + "&MSG=" + msg + "&maxSize=" + maxSize + "¤tFileSize=" + currentFileSize; |
|
LOG.debug("v2 3.신뢰되지 않는 URL 주소로 자동 접속 연결_CWE-601 : HttpFileUploadDir.doPost() connURL={} : Test OK", connURL); |
|
//========================================================================= |
|
} |
|
//======================================== |
|
res.sendRedirect(connURL); |
|
} |
|
} |
|
}
|
|
|