knu project
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

/**
* ********************************************************************************
* 프로그램명 : 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 + "&currentFileSize=" + 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 + "&currentFileSize=" + currentFileSize;
LOG.debug("v2 3.신뢰되지 않는 URL 주소로 자동 접속 연결_CWE-601 : HttpFileUploadDir.doPost() connURL={} : Test OK", connURL);
//=========================================================================
}
//========================================
res.sendRedirect(connURL);
}
}
}