/*
* Copyright (C) 2000-2015 aw2.0 LTD
*
* This file is part of Open BlueDragon (OpenBD) CFML Server Engine.
*
* OpenBD is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Free Software Foundation,version 3.
*
* OpenBD is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenBD. If not, see http://www.gnu.org/licenses/
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with any of the JARS listed in the README.txt (or a modified version of
* (that library), containing parts covered by the terms of that JAR, the
* licensors of this Program grant you additional permission to convey the
* resulting work.
* README.txt @ http://www.openbluedragon.org/license/README.txt
*
* http://www.openbd.org/
* $Id: cfDecodedInput.java 2526 2015-02-26 15:58:34Z alan $
*/
package com.naryx.tagfusion.cfm.engine;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.vfs.FileSystemException;
import com.nary.servlet.MultipartRequestDecode;
import com.nary.servlet.MultiPartUploadedFile;
/**
* This class is used to co-ordinate the multi-part HTTP streams for uploading files
*/
public class cfDecodedInput extends Object implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private List<MultiPartUploadedFile> fileList;
private Hashtable rawParams;
public static final String DATA_BIN_KEY = "CFDECODEDINPUT_DATA";
private String encoding;
public void setFiles( cfSession _session, List<MultiPartUploadedFile> _fileList ) {
fileList = _fileList;
MultiPartUploadedFile nextFile;
cfData formData = _session.getQualifiedData( variableStore.FORM_SCOPE );
// loop thru files adding formName-realFile pair to formData
Iterator<MultiPartUploadedFile> it = fileList.iterator();
while ( it.hasNext() ){
nextFile = it.next();
if ( nextFile.filename.length() == 0 ){
formData.setData( nextFile.formName, cfStringData.EMPTY_STRING );
}else{
formData.setData( nextFile.formName, new cfStringData( nextFile.tempFile.toString() ) );
}
}
}
public void setParameters( cfSession Session, MultipartRequestDecode mRequest ) throws Exception {
Enumeration E = mRequest.getParameterNames();
rawParams = mRequest.getRawParameters();
String key, data;
cfFormData formData = (cfFormData) Session.getQualifiedData( variableStore.FORM_SCOPE );
while ( E.hasMoreElements() ){
key = (String)E.nextElement();
data = mRequest.getParameter( key );
formData.setData( key, new cfStringData( data ) );
}
if ( formData.size() > 0 ){
formData.put( "fieldnames", new cfStringData( formData.getKeyList( "," ) ) );
}
}
/**
* Returns the file form that was uploaded
*
* @param Name
* @return
* @throws FileSystemException
*/
public MultiPartUploadedFile getFile( String Name ) {
Iterator<MultiPartUploadedFile> it = fileList.iterator();
MultiPartUploadedFile uFile;
while ( it.hasNext() ){
uFile = it.next();
if ( uFile.formName.equalsIgnoreCase( Name ) && uFile.tempFile.length() != 0 )
return uFile;
}
return null;
}
/**
* Returns a list of all the uploaded files
*
* @return
*/
public List<MultiPartUploadedFile> getFiles(){
List<MultiPartUploadedFile> fL = new ArrayList<MultiPartUploadedFile>(2);
Iterator<MultiPartUploadedFile> it = fileList.iterator();
MultiPartUploadedFile uFile;
while ( it.hasNext() ){
uFile = it.next();
if ( uFile.tempFile.length() != 0 )
fL.add( uFile );
}
return fL;
}
/**
* Deletes all the uploaded files
*/
public void deleteFiles(){
Iterator<MultiPartUploadedFile> it = fileList.iterator();
while ( it.hasNext() ){
it.next().deleteTempFile();
}
}
public void reencodeParameters( cfSession _session, String _currEncoding, String _encoding ) throws UnsupportedEncodingException{
// don't need to reencode if it's already this encoding
if ( _encoding.equalsIgnoreCase( encoding ) ){
return;
}
cfFormData formdata = (cfFormData) _session.getQualifiedData( variableStore.FORM_SCOPE );
Enumeration keys = rawParams.keys();
while ( keys.hasMoreElements() ){
String nextKey = (String) keys.nextElement();
Object nextElement = rawParams.get( nextKey );
if ( nextElement instanceof List ){
List values = (List) nextElement;
StringBuilder valuesStr = new StringBuilder( (String) values.get(0) );
for ( int i = 1; i < values.size(); i++ ){
String nextValue = (String) values.get(i);
valuesStr.append( ',' );
valuesStr.append( new String( nextValue.getBytes(), _encoding ) );
}
}else{
String reencoded = new String( ( (String) nextElement).getBytes(), _encoding );
formdata.put( nextKey, new cfStringData(reencoded) );
}
}
formdata.remove( "fieldnames" );
if ( formdata.size() > 0 ){
formdata.put( "fieldnames", new cfStringData( formdata.getKeyList( "," ) ) );
}
// the filenames also need to be converted to the new encoding
Iterator<MultiPartUploadedFile> it = fileList.iterator();
while ( it.hasNext() ){
MultiPartUploadedFile nextFile = it.next();
nextFile.filename = new String( nextFile.filename.getBytes( _currEncoding ), _encoding );
}
}
//-----------------------------------------------------------------
//--] This is a static method for pulling back the content
//-----------------------------------------------------------------
public static void checkAndDecodePost( cfSession Session ) throws cfmRunTimeException {
// Check to see if the request is the result of a file upload
if ( Session.REQ.getContentType() == null || Session.REQ.getContentType().indexOf("multipart/form-data") == -1 )
return;
try{
// Register this file with the Session so a cfFILE=UPLOAD may be able to get it
cfDecodedInput DI = new cfDecodedInput();
Session.setDataBin( DATA_BIN_KEY, DI );
// Decode the input stream
String encoding = cfEngine.getDefaultEncoding();
cfFormData formData = (cfFormData)Session.getQualifiedData(variableStore.FORM_SCOPE);
byte[] requestData = formData.getRequestData();
InputStream requestStream = null;
if ( requestData != null ){ // unlikely
requestStream = new ByteArrayInputStream( requestData );
}else{ // multipart/form-data
requestStream = Session.REQ.getInputStream();
}
MultipartRequestDecode mRequest = new MultipartRequestDecode( Session.REQ.getContentType(),
requestStream,
cfEngine.thisPlatform.getFileIO().getTempDirectory(),
encoding );
DI.encoding = encoding;
DI.setFiles( Session, mRequest.getFiles() );
DI.setParameters( Session, mRequest );
}catch(cfmRunTimeException RTE){
throw RTE;
}catch(Exception E){
cfCatchData catchData = new cfCatchData( Session );
catchData.setMessage( "An error has occurred while attempting to process the incoming multipart/form-data stream: " + E );
throw new cfmRunTimeException( catchData );
}
}
}