package com.csc.upload; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URLDecoder; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Vector; import javax.servlet.ServletInputStream; import com.csc.library.session.InitialEnvironment; import com.csc.library.utilities.CscCalendar; import com.csc.library.utilities.UProfile; // A Class with methods used to process a ServletInputStream public class HttpMultiPartParser{ private final String lineSeparator = System.getProperty("line.separator", "\n"); private final int ONE_MB=1024*1024*1; private final InitialEnvironment en= new InitialEnvironment("GLOBAL"); private String foldername=""; private Vector fileName=new Vector(); private UProfile up=null; private String realpath=""; public Hashtable processData(ServletInputStream is, String boundary, String saveInDir) throws IllegalArgumentException, IOException { if (is == null) throw new IllegalArgumentException("InputStream"); if (boundary == null || boundary.trim().length() < 1) throw new IllegalArgumentException("\"" + boundary + "\" is an illegal boundary indicator"); boundary = "--" + boundary; StringTokenizer stLine = null, stFields = null; FileInfo fileInfo = null; Hashtable dataTable = new Hashtable(5); String line = null, field = null, paramName = null; boolean saveFiles = (saveInDir != null && saveInDir.trim().length() > 0); boolean isFile = false; if (saveFiles){ // Create the required directory (including parent dirs) File f = new File(saveInDir); f.mkdirs(); } line = getLine(is); if (line == null || !line.startsWith(boundary)) throw new IOException("Boundary not found; boundary = " + boundary + ", line = " + line); while (line != null){ if (line == null || !line.startsWith(boundary)) return dataTable; line = getLine(is); if (line == null) return dataTable; stLine = new StringTokenizer(line, ";\r\n"); if (stLine.countTokens() < 2) throw new IllegalArgumentException("Bad data in second line"); line = stLine.nextToken().toLowerCase(); if (line.indexOf("form-data") < 0) throw new IllegalArgumentException("Bad data in second line"); stFields = new StringTokenizer(stLine.nextToken(), "=\""); if (stFields.countTokens() < 2) throw new IllegalArgumentException("Bad data in second line"); fileInfo = new FileInfo(); stFields.nextToken(); paramName = stFields.nextToken(); isFile = false; if (stLine.hasMoreTokens()){ field = stLine.nextToken(); stFields = new StringTokenizer(field, "=\""); if (stFields.countTokens() > 1){ if (stFields.nextToken().trim().equalsIgnoreCase("filename")){ fileInfo.name=paramName; String value = stFields.nextToken(); if (value != null && value.trim().length() > 0){ fileInfo.clientFileName=value; isFile = true; } else{ line = getLine(is); // Skip "Content-Type:" line line = getLine(is); // Skip blank line line = getLine(is); // Skip blank line line = getLine(is); // Position to boundary line continue; } } } else if (field.toLowerCase().indexOf("filename") >= 0){ line = getLine(is); // Skip "Content-Type:" line line = getLine(is); // Skip blank line line = getLine(is); // Skip blank line line = getLine(is); // Position to boundary line continue; } } boolean skipBlankLine = true; if (isFile){ line = getLine(is); if (line == null) return dataTable; if (line.trim().length() < 1) skipBlankLine = false; else{ stLine = new StringTokenizer(line, ": "); if (stLine.countTokens() < 2) throw new IllegalArgumentException("Bad data in third line"); stLine.nextToken(); // Content-Type fileInfo.fileContentType=stLine.nextToken(); } } if (skipBlankLine){ line = getLine(is); if (line == null) return dataTable; } if (!isFile){ line = getLine(is); if (line == null) return dataTable; dataTable.put(paramName, line); // If parameter is dir, change saveInDir to dir if (paramName.equals("dir")) saveInDir = line; line = getLine(is); continue; } try{ OutputStream os = null; String path = null; if (saveFiles) os = new FileOutputStream(path = getFileName(saveInDir, fileInfo.clientFileName)); else os = new ByteArrayOutputStream(ONE_MB); boolean readingContent = true; byte previousLine[] = new byte[2 * ONE_MB]; byte temp[] = null; byte currentLine[] = new byte[2 * ONE_MB]; int read, read3; if ((read = is.readLine(previousLine, 0, previousLine.length)) == -1) { line = null; break; } while (readingContent){ if ((read3 = is.readLine(currentLine, 0, currentLine.length)) == -1) { line = null; break; } if (compareBoundary(boundary, currentLine)){ os.write(previousLine, 0, read-2); line = new String(currentLine, 0, read3); break; } else{ os.write(previousLine, 0, read); temp = currentLine; currentLine = previousLine; previousLine = temp; read = read3; }//end else }//end while os.flush(); os.close(); if (!saveFiles){ ByteArrayOutputStream baos = (ByteArrayOutputStream)os; fileInfo.setFileContents(baos.toByteArray()); } else fileInfo.file = new File(path); dataTable.put(paramName, fileInfo); }//end try catch (IOException e) { throw e; } } return dataTable; } // * Compares boundary string to byte array public boolean compareBoundary(String boundary, byte ba[]){ byte b; if (boundary == null || ba == null) return false; for (int i=0; i < boundary.length(); i++) if ((byte)boundary.charAt(i) != ba[i]) return false; return true; } // Convenience method to read HTTP header lines public synchronized String getLine(ServletInputStream sis) throws IOException{ byte b[] = new byte[1024]; int read = sis.readLine(b, 0, b.length), index; String line = null; if (read != -1){ line = new String(b, 0, read); if ((index = line.indexOf('\n')) >= 0) line = line.substring(0, index-1); } return line; } public Vector expandFileList(String[] files, boolean inclDirs){ Vector v = new Vector(); if (files == null) return v; for (int i=0; i < files.length; i++) v.add (new File(URLDecoder.decode(files[i]))); for (int i=0; i < v.size(); i++){ File f = (File) v.get(i); if (f.isDirectory()){ File[] fs = f.listFiles(); for (int n = 0; n < fs.length; n++) v.add(fs[n]); if (!inclDirs){ v.remove(i); i--; } } } return v; } public String getFileName(String dir, String fileName) throws IllegalArgumentException{ String path = null; if (dir == null || fileName == null) throw new IllegalArgumentException("dir or fileName is null"); int index = fileName.lastIndexOf('/'); String name = null; if (index >= 0) name = fileName.substring(index + 1); else name = fileName; index = name.lastIndexOf('\\'); if (index >= 0) fileName = name.substring(index + 1); path = dir + File.separator + fileName; if (File.separatorChar == '/') return path.replace('\\', File.separatorChar); else return path.replace('/', File.separatorChar); } public boolean uploadFiles(Hashtable ht,UProfile u){ boolean error=false; String path=""; if (ht.get("myFile")!=null){ path = (String)ht.get("dir"); FileInfo fi = (FileInfo)ht.get("myFile"); File fipath=null; if(u!=null ){ this.up=u; // this.deleteTempFile(); // path = en.getValue("TEMP-dir"); // path+="UPLOAD/"+this.getFoldername()+"/"; fipath=new File(path); if(!fipath.exists()) fipath.mkdirs(); error=this.processFileAuto(fi,"",path); up.put("upload_temp_file", fileName); }else{ fipath=new File(path); if(!fipath.exists()) fipath.mkdirs(); error=this.processFile(fi,"",path); } } else{ error = false; } return error; } public boolean uploadFiles(Hashtable ht){ boolean error=uploadFiles(ht, null); return error; } private boolean processFile(FileInfo fi,String reNamefile,String path){ File f = fi.file; String typefile="",file_Name=""; String newname=f.getName(); if(newname.indexOf(".")>-1){ typefile=newname.substring(newname.indexOf(".")+1); file_Name=newname.substring(0,newname.indexOf(".")); } if(reNamefile.trim().length()>0){ if(reNamefile.indexOf(".")>-1) newname=reNamefile; else newname=reNamefile+"."+typefile; } if (!path.endsWith(File.separator)) path = path+File.separator; if (!f.renameTo(new File(path+newname))){ f.delete(); return true; } return false; } private boolean processFileAuto(FileInfo fi,String reNamefile,String path){ File f = fi.file; String typefile="",file_Name=""; if(f.getName().lastIndexOf(".")>-1){ typefile=f.getName().substring(f.getName().lastIndexOf(".")+1); file_Name=f.getName().substring(0,f.getName().lastIndexOf(".")); } String newname=this.createFilename("."+typefile); if (!path.endsWith(File.separator)) path = path+File.separator; fileName.addElement(newname); if (!f.renameTo(new File(path+newname))){ f.delete(); return true; } return false; } private String createFilename(String postfix){ CscCalendar cs=new CscCalendar(); String filename=String.valueOf(cs.getTimeInMillis())+postfix; if(fileName.contains(filename)) filename=this.createFilename(postfix); return filename; } public boolean uploadMultiFilesAuto(Hashtable ht,String reqname,String reNamefile){ boolean error=false; if (ht.get(reqname)!=null){ FileInfo fi = (FileInfo)ht.get(reqname); String path = (String)ht.get("dir"); // String path = en.getValue("TEMP-dir"); // path+="UPLOAD/"+this.getFoldername(); File fipath=new File(path); if(!fipath.exists()) fipath.mkdirs(); error=this.processFileAuto(fi,"",path); } else{ error = false; } return error; } public boolean uploadMultiFiles(Hashtable ht,String reqname,String reNamefile){ boolean error=false; if (ht.get(reqname)!=null){ FileInfo fi = (FileInfo)ht.get(reqname); String path = (String)ht.get("dir"); File fipath=new File(path); if(!fipath.exists()) fipath.mkdirs(); error=this.processFile(fi,reNamefile,path); } else{ error = false; } return error; } public boolean uploadMultiFiles(Hashtable ht,String reqname,String reNamefile,String path){ boolean error=false; if (ht.get(reqname)!=null){ File fipath=new File(path); if(!fipath.exists()) fipath.mkdirs(); FileInfo fi = (FileInfo)ht.get(reqname); error=this.processFile(fi,reNamefile,path); }else{ error = false; } return error; } public boolean uploadMultiFiles(Hashtable ht,String fileList){ UProfile u=null; boolean error=uploadMultiFiles(ht,fileList,u); return error; } public boolean uploadMultiFiles(Hashtable ht,String fileList,UProfile u){ boolean error=false; String fList=(String)ht.get(fileList); StringTokenizer stk=new StringTokenizer(fList,","); Vector v=new Vector(); while(stk.hasMoreTokens()){ v.addElement((String)stk.nextElement()); } if(u==null){ this.uploadMultiFiles(ht,v); }else{ this.uploadMultiFiles(ht, v,u); } return error; } public boolean uploadMultiFiles(Hashtable ht,Vector filelist){ boolean error=false; if(filelist.size()>0){ String path= (String) ht.get("dir"); File fipath=new File(path); if(!fipath.exists()) fipath.mkdirs(); String fname=""; for(int c=0;c<filelist.size();c++){ fname=(String)filelist.get(c); FileInfo fi = (FileInfo)ht.get(fname); this.processFile(fi,"",path); } error=true; } else{ error = false; } return error; } public boolean uploadMultiFiles(Hashtable ht,Vector filelist,UProfile u){ boolean error=false; if(filelist.size()>0){ this.up=u; String path = (String)ht.get("dir"); // this.deleteTempFile(); // String path = en.getValue("TEMP-dir"); // path+="UPLOAD/"+this.getFoldername(); File fipath=new File(path); if(!fipath.exists()) fipath.mkdirs(); String fname=""; for(int c=0;c<filelist.size();c++){ fname=(String)filelist.get(c); FileInfo fi = (FileInfo)ht.get(fname); this.processFileAuto(fi,"",path); } up.put("upload_temp_file", fileName); error=true; } else{ error = false; } return error; } public boolean deleteFile(Hashtable ht,String reqname){ boolean error=false; if (ht.get(reqname)!=null){ FileInfo fi = (FileInfo)ht.get(reqname); File f = fi.file; f.delete(); error=true; } else{ error = false; } return error; } /** * @return the foldername */ public String getFoldername() { if(up.containsKey("upload_temp_folder")){ this.setFoldername(up.get("upload_temp_folder")); }else{ if(this.foldername.length()==0){ CscCalendar cs=new CscCalendar(); this.setFoldername(String.valueOf(cs.getTimeInMillis())); up.set("upload_temp_folder", this.foldername); } } return foldername; } /** * @param foldername the foldername to set */ public void setFoldername(String foldername) { this.foldername = foldername; } private void deleteTempFile(){ File fipath=null; if(up.containsKey("upload_temp_file")){ fileName=(Vector)up.getObject("upload_temp_file"); for(int c=0;c<fileName.size();c++){ fipath=new File(en.getValue("TEMP-dir")+"UPLOAD/"+this.getFoldername()+"/"+fileName.get(c).toString()); if(fipath.isFile()&& fipath.exists()){ fipath.delete(); fileName.remove(c); c--; } } } } /** * @return the realpath */ public String getRealpath() { return realpath; } /** * @param realpath the realpath to set */ public void setRealpath(String realpath) { if(up!=null){ up.set("upload_realpath", realpath); } this.realpath = realpath; } public String getStringFile(){ String filelist=""; for(int v=0;v<fileName.size();v++){ if(v!=0 && v<fileName.size()-1) filelist+=","; filelist+=(String)fileName.get(v); } return filelist; } public Vector getVectorFile(){ return fileName; } } //End of class HttpMultiPartParser