org.eclipse.jetty.util.MultiPartInputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletException;
import javax.servlet.http.Part;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* MultiPartInputStream
*
* Handle a MultiPart Mime input stream, breaking it up on the boundary into files and strings.
*/
public class MultiPartInputStream
{
private static final Logger LOG = Log.getLogger(MultiPartInputStream.class);
public static final MultipartConfigElement __DEFAULT_MULTIPART_CONFIG = new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
protected InputStream _in;
protected MultipartConfigElement _config;
protected String _contentType;
protected MultiMap _parts;
protected File _tmpDir;
protected File _contextTmpDir;
protected boolean _deleteOnExit;
public class MultiPart implements Part
{
protected String _name;
protected String _filename;
protected File _file;
protected OutputStream _out;
protected ByteArrayOutputStream2 _bout;
protected String _contentType;
protected MultiMap _headers;
protected long _size = 0;
protected boolean _temporary = true;
public MultiPart (String name, String filename)
throws IOException
{
_name = name;
_filename = filename;
}
protected void setContentType (String contentType)
{
_contentType = contentType;
}
protected void open()
throws IOException
{
//We will either be writing to a file, if it has a filename on the content-disposition
//and otherwise a byte-array-input-stream, OR if we exceed the getFileSizeThreshold, we
//will need to change to write to a file.
if (_filename != null && _filename.trim().length() > 0)
{
createFile();
}
else
{
//Write to a buffer in memory until we discover we've exceed the
//MultipartConfig fileSizeThreshold
_out = _bout= new ByteArrayOutputStream2();
}
}
protected void close()
throws IOException
{
_out.close();
}
protected void write (int b)
throws IOException
{
if (MultiPartInputStream.this._config.getMaxFileSize() > 0 && _size + 1 > MultiPartInputStream.this._config.getMaxFileSize())
throw new IllegalStateException ("Multipart Mime part "+_name+" exceeds max filesize");
if (MultiPartInputStream.this._config.getFileSizeThreshold() > 0 && _size + 1 > MultiPartInputStream.this._config.getFileSizeThreshold() && _file==null)
createFile();
_out.write(b);
_size ++;
}
protected void write (byte[] bytes, int offset, int length)
throws IOException
{
if (MultiPartInputStream.this._config.getMaxFileSize() > 0 && _size + length > MultiPartInputStream.this._config.getMaxFileSize())
throw new IllegalStateException ("Multipart Mime part "+_name+" exceeds max filesize");
if (MultiPartInputStream.this._config.getFileSizeThreshold() > 0 && _size + length > MultiPartInputStream.this._config.getFileSizeThreshold() && _file==null)
createFile();
_out.write(bytes, offset, length);
_size += length;
}
protected void createFile ()
throws IOException
{
_file = File.createTempFile("MultiPart", "", MultiPartInputStream.this._tmpDir);
if (_deleteOnExit)
_file.deleteOnExit();
FileOutputStream fos = new FileOutputStream(_file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
if (_size > 0 && _out != null)
{
//already written some bytes, so need to copy them into the file
_out.flush();
_bout.writeTo(bos);
_out.close();
_bout = null;
}
_out = bos;
}
protected void setHeaders(MultiMap headers)
{
_headers = headers;
}
/**
* @see javax.servlet.http.Part#getContentType()
*/
public String getContentType()
{
return _contentType;
}
/**
* @see javax.servlet.http.Part#getHeader(java.lang.String)
*/
public String getHeader(String name)
{
if (name == null)
return null;
return (String)_headers.getValue(name.toLowerCase(Locale.ENGLISH), 0);
}
/**
* @see javax.servlet.http.Part#getHeaderNames()
*/
public Collection getHeaderNames()
{
return _headers.keySet();
}
/**
* @see javax.servlet.http.Part#getHeaders(java.lang.String)
*/
public Collection getHeaders(String name)
{
return _headers.getValues(name);
}
/**
* @see javax.servlet.http.Part#getInputStream()
*/
public InputStream getInputStream() throws IOException
{
if (_file != null)
{
//written to a file, whether temporary or not
return new BufferedInputStream (new FileInputStream(_file));
}
else
{
//part content is in memory
return new ByteArrayInputStream(_bout.getBuf(),0,_bout.size());
}
}
public byte[] getBytes()
{
if (_bout!=null)
return _bout.toByteArray();
return null;
}
/**
* @see javax.servlet.http.Part#getName()
*/
public String getName()
{
return _name;
}
/**
* @see javax.servlet.http.Part#getSize()
*/
public long getSize()
{
return _size;
}
/**
* @see javax.servlet.http.Part#write(java.lang.String)
*/
public void write(String fileName) throws IOException
{
if (_file == null)
{
_temporary = false;
//part data is only in the ByteArrayOutputStream and never been written to disk
_file = new File (_tmpDir, fileName);
BufferedOutputStream bos = null;
try
{
bos = new BufferedOutputStream(new FileOutputStream(_file));
_bout.writeTo(bos);
bos.flush();
}
finally
{
if (bos != null)
bos.close();
_bout = null;
}
}
else
{
//the part data is already written to a temporary file, just rename it
_temporary = false;
File f = new File(_tmpDir, fileName);
if (_file.renameTo(f))
_file = f;
}
}
/**
* Remove the file, whether or not Part.write() was called on it
* (ie no longer temporary)
* @see javax.servlet.http.Part#delete()
*/
public void delete() throws IOException
{
if (_file != null && _file.exists())
_file.delete();
}
/**
* Only remove tmp files.
*
* @throws IOException
*/
public void cleanUp() throws IOException
{
if (_temporary && _file != null && _file.exists())
_file.delete();
}
/**
* Get the file, if any, the data has been written to.
* @return
*/
public File getFile ()
{
return _file;
}
/**
* Get the filename from the content-disposition.
* @return null or the filename
*/
public String getContentDispositionFilename ()
{
return _filename;
}
}
/**
* @param in Request input stream
* @param contentType Content-Type header
* @param config MultipartConfigElement
* @param contextTmpDir javax.servlet.context.tempdir
*/
public MultiPartInputStream (InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir)
{
_in = new ReadLineInputStream(in);
_contentType = contentType;
_config = config;
_contextTmpDir = contextTmpDir;
if (_contextTmpDir == null)
_contextTmpDir = new File (System.getProperty("java.io.tmpdir"));
if (_config == null)
_config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath());
}
/**
* Get the already parsed parts.
*
* @return
*/
public Collection getParsedParts()
{
if (_parts == null)
return Collections.emptyList();
Collection