//
//  ========================================================================
//  Copyright (c) 1995-2017 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 static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletException;
import javax.servlet.http.Part;

import org.eclipse.jetty.util.MultiPartInputStreamParser.MultiPart;
import org.junit.Test;

/**
 * MultiPartInputStreamTest
 *
 *
 */
public class MultiPartInputStreamTest
{
    private static final String FILENAME = "stuff.txt";
    protected String _contentType = "multipart/form-data, boundary=AaB03x";
    protected String _multi = createMultipartRequestString(FILENAME);
    protected String _dirname = System.getProperty("java.io.tmpdir")+File.separator+"myfiles-"+System.currentTimeMillis();
    protected File _tmpDir = new File(_dirname);
    
    public MultiPartInputStreamTest ()
    {
        _tmpDir.deleteOnExit();
    }
    
    public void testBadMultiPartRequest()
    throws Exception
    {
        String boundary = "X0Y0";
        String str = "--" + boundary + "\r\n"+
        "Content-Disposition: form-data; name=\"fileup\"; filename=\"test.upload\"\r\n"+
        "Content-Type: application/octet-stream\r\n\r\n"+
        "How now brown cow."+
        "\r\n--" + boundary + "-\r\n\r\n";
        
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(str.getBytes()), 
                                                             "multipart/form-data, boundary="+boundary,
                                                             config,
                                                             _tmpDir);
        mpis.setDeleteOnExit(true);
        try
        {
            mpis.getParts();
            fail ("Multipart incomplete");
        }
        catch (IOException e)
        {
            assertTrue(e.getMessage().startsWith("Incomplete"));
        }
    }

    
    public void testNoBoundaryRequest()
    throws Exception
    {
        String str = "--\r\n"+
        "Content-Disposition: form-data; name=\"fileName\"\r\n"+
            "Content-Type: text/plain; charset=US-ASCII\r\n"+
            "Content-Transfer-Encoding: 8bit\r\n"+
            "\r\n"+
            "abc\r\n"+
            "--\r\n"+
            "Content-Disposition: form-data; name=\"desc\"\r\n"+ 
            "Content-Type: text/plain; charset=US-ASCII\r\n"+ 
            "Content-Transfer-Encoding: 8bit\r\n"+
            "\r\n"+
            "123\r\n"+ 
            "--\r\n"+ 
            "Content-Disposition: form-data; name=\"title\"\r\n"+
            "Content-Type: text/plain; charset=US-ASCII\r\n"+
            "Content-Transfer-Encoding: 8bit\r\n"+ 
            "\r\n"+
            "ttt\r\n"+ 
            "--\r\n"+
            "Content-Disposition: form-data; name=\"datafile5239138112980980385.txt\"; filename=\"datafile5239138112980980385.txt\"\r\n"+
            "Content-Type: application/octet-stream; charset=ISO-8859-1\r\n"+
            "Content-Transfer-Encoding: binary\r\n"+ 
            "\r\n"+
            "000\r\n"+ 
            "----\r\n";
        
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(str.getBytes()),
                                                             "multipart/form-data",
                                                             config,
                                                             _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(4));
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Part fileName = mpis.getPart("fileName");
        assertThat(fileName, notNullValue());
        assertThat(fileName.getSize(), is(3L));
        IO.copy(fileName.getInputStream(), baos);
        assertThat(baos.toString("US-ASCII"), is("abc"));
       
        baos = new ByteArrayOutputStream();
        Part desc = mpis.getPart("desc");
        assertThat(desc, notNullValue());
        assertThat(desc.getSize(), is(3L));
        IO.copy(desc.getInputStream(), baos);
        assertThat(baos.toString("US-ASCII"), is("123"));
        
        baos = new ByteArrayOutputStream();
        Part title = mpis.getPart("title");
        assertThat(title, notNullValue());
        assertThat(title.getSize(), is(3L));
        IO.copy(title.getInputStream(), baos);
        assertThat(baos.toString("US-ASCII"), is("ttt"));  
    }

    @Test
    public void testNonMultiPartRequest()
    throws Exception
    {
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(_multi.getBytes()),
                                                            "Content-type: text/plain",
                                                             config,
                                                            _tmpDir);
        mpis.setDeleteOnExit(true);
        assertTrue(mpis.getParts().isEmpty());
    }

    @Test
    public void testNoBody()
            throws Exception
            {
        String body = "";

        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(body.getBytes()), 
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        try
        {
            mpis.getParts();
            fail ("Multipart missing body");
        }
        catch (IOException e)
        {
            assertTrue(e.getMessage().startsWith("Missing content"));
        }
    }
    
    @Test
    public void testWhitespaceBodyWithCRLF()
            throws Exception
            {
        String whitespace = "              \n\n\n\r\n\r\n\r\n\r\n";


        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(whitespace.getBytes()), 
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        try
        {
            mpis.getParts();
            fail ("Multipart missing body");
        }
        catch (IOException e)
        {
            assertTrue(e.getMessage().startsWith("Missing initial"));
        }
    }

    @Test
    public void testWhitespaceBody()
            throws Exception
            {
        String whitespace = " ";

        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(whitespace.getBytes()), 
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        try
        {
            mpis.getParts();
            fail ("Multipart missing body");
        }
        catch (IOException e)
        {
            assertTrue(e.getMessage().startsWith("Missing initial"));
        }
    }

    @Test
    public void testLeadingWhitespaceBodyWithCRLF()
    throws Exception
    {
        String body = "              \n\n\n\r\n\r\n\r\n\r\n"+
                "--AaB03x\r\n"+
                "content-disposition: form-data; name=\"field1\"\r\n"+
                "\r\n"+
                "Joe Blow\r\n"+
                "--AaB03x\r\n"+
                "content-disposition: form-data; name=\"stuff\"; filename=\"" + "foo.txt" + "\"\r\n"+
                "Content-Type: text/plain\r\n"+
                "\r\n"+"aaaa"+
                "bbbbb"+"\r\n" +
                "--AaB03x--\r\n";


        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(body.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);

        Collection<Part> parts =    mpis.getParts();
        assertThat(parts, notNullValue());
        assertThat(parts.size(), is(2));
        Part field1 = mpis.getPart("field1");
        assertThat(field1, notNullValue());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IO.copy(field1.getInputStream(), baos);
        assertThat(baos.toString("US-ASCII"), is("Joe Blow"));
        
        Part stuff = mpis.getPart("stuff");
        assertThat(stuff, notNullValue());
        baos = new ByteArrayOutputStream();
        IO.copy(stuff.getInputStream(), baos);
        assertTrue(baos.toString("US-ASCII").contains("aaaa"));
    }
    


    @Test
    public void testLeadingWhitespaceBodyWithoutCRLF()
            throws Exception
            {
        String body = "            "+
                "--AaB03x\r\n"+
                "content-disposition: form-data; name=\"field1\"\r\n"+
                "\r\n"+
                "Joe Blow\r\n"+
                "--AaB03x\r\n"+
                "content-disposition: form-data; name=\"stuff\"; filename=\"" + "foo.txt" + "\"\r\n"+
                "Content-Type: text/plain\r\n"+
                "\r\n"+"aaaa"+
                "bbbbb"+"\r\n" +
                "--AaB03x--\r\n";

        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(body.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);

        Collection<Part> parts =    mpis.getParts();
        assertThat(parts, notNullValue());
        assertThat(parts.size(), is(2));
        Part field1 = mpis.getPart("field1");
        assertThat(field1, notNullValue());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IO.copy(field1.getInputStream(), baos);
        assertThat(baos.toString("US-ASCII"), is("Joe Blow"));
        
        Part stuff = mpis.getPart("stuff");
        assertThat(stuff, notNullValue());
        baos = new ByteArrayOutputStream();
        IO.copy(stuff.getInputStream(), baos);
        assertTrue(baos.toString("US-ASCII").contains("bbbbb"));
    }
    
    
    
    
    

    @Test
    public void testNoLimits()
    throws Exception
    {
        MultipartConfigElement config = new MultipartConfigElement(_dirname);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(_multi.getBytes()),
                                                             _contentType,
                                                             config,
                                                             _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertFalse(parts.isEmpty());
    }

    @Test
    public void testRequestTooBig ()
    throws Exception
    {
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 60, 100, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(_multi.getBytes()),
                                                            _contentType,
                                                             config,
                                                             _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = null;
        try
        {
            parts = mpis.getParts();
            fail("Request should have exceeded maxRequestSize");
        }
        catch (IllegalStateException e)
        {
            assertTrue(e.getMessage().startsWith("Request exceeds maxRequestSize"));
        }
    }

    @Test
    public void testFileTooBig()
    throws Exception
    {
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 40, 1024, 30);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(_multi.getBytes()),
                                                            _contentType,
                                                             config,
                                                             _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = null;
        try
        {
            parts = mpis.getParts();
            fail("stuff.txt should have been larger than maxFileSize");
        }
        catch (IllegalStateException e)
        {
            assertTrue(e.getMessage().startsWith("Multipart Mime part"));
        }
    }

    @Test
    public void testPartFileNotDeleted () throws Exception
    {
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);  
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(createMultipartRequestString("tptfd").getBytes()),
                _contentType,
                config,
                _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        
        MultiPart part = (MultiPart)mpis.getPart("stuff");
        File stuff = ((MultiPartInputStreamParser.MultiPart)part).getFile();
        assertThat(stuff,notNullValue()); // longer than 100 bytes, should already be a tmp file
        part.write("tptfd.txt");
        File tptfd = new File (_dirname+File.separator+"tptfd.txt");
        assertThat(tptfd.exists(), is(true));
        assertThat(stuff.exists(), is(false)); //got renamed
        part.cleanUp();
        assertThat(tptfd.exists(), is(true));  //explicitly written file did not get removed after cleanup
        tptfd.deleteOnExit(); //clean up test
    }
    
    @Test
    public void testPartTmpFileDeletion () throws Exception
    {
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);  
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(createMultipartRequestString("tptfd").getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();

        MultiPart part = (MultiPart)mpis.getPart("stuff");
        File stuff = ((MultiPartInputStreamParser.MultiPart)part).getFile();
        assertThat(stuff,notNullValue()); // longer than 100 bytes, should already be a tmp file
        assertThat (stuff.exists(), is(true));
        part.cleanUp();
        assertThat(stuff.exists(), is(false));  //tmp file was removed after cleanup
    }
    
    @Test
    public void testLFOnlyRequest()
    throws Exception
    {
        String str = "--AaB03x\n"+
                "content-disposition: form-data; name=\"field1\"\n"+
                "\n"+
                "Joe Blow\n"+ 
                "--AaB03x\n"+
                "content-disposition: form-data; name=\"field2\"\n"+
                "\n"+
                "Other\n"+        
                "--AaB03x--\n";

        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(str.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(2));
        Part p1 = mpis.getPart("field1");
        assertThat(p1, notNullValue());      
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IO.copy(p1.getInputStream(), baos);
        assertThat(baos.toString("UTF-8"), is("Joe Blow"));
                
        Part p2 = mpis.getPart("field2");
        assertThat(p2, notNullValue());
        baos = new ByteArrayOutputStream();
        IO.copy(p2.getInputStream(), baos);
        assertThat(baos.toString("UTF-8"), is("Other"));
    }
    
    @Test
    public void testCROnlyRequest()
    throws Exception
    {
        String str = "--AaB03x\r"+
        "content-disposition: form-data; name=\"field1\"\r"+
        "\r"+
        "Joe Blow\r"+ 
        "--AaB03x\r"+
        "content-disposition: form-data; name=\"field2\"\r"+
        "\r"+
        "Other\r"+        
        "--AaB03x--\r";

        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(str.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(2));
        
        assertThat(parts.size(), is(2));
        Part p1 = mpis.getPart("field1");
        assertThat(p1, notNullValue());
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IO.copy(p1.getInputStream(), baos);
        assertThat(baos.toString("UTF-8"), is("Joe Blow"));
        
        Part p2 = mpis.getPart("field2");
        assertThat(p2, notNullValue());
        baos = new ByteArrayOutputStream();
        IO.copy(p2.getInputStream(), baos);
        assertThat(baos.toString("UTF-8"), is("Other"));
    }

    @Test
    public void testCRandLFMixRequest()
    throws Exception
    {
        String str = "--AaB03x\r"+
                "content-disposition: form-data; name=\"field1\"\r"+
                "\r"+
                "\nJoe Blow\n"+ 
                "\r"+
                "--AaB03x\r"+
                "content-disposition: form-data; name=\"field2\"\r"+
                "\r"+
                "Other\r"+        
                "--AaB03x--\r";
        
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(str.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(2));

        Part p1 = mpis.getPart("field1");
        assertThat(p1, notNullValue());      
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IO.copy(p1.getInputStream(), baos);
        assertThat(baos.toString("UTF-8"), is("\nJoe Blow\n"));
        
        Part p2 = mpis.getPart("field2");
        assertThat(p2, notNullValue());
        baos = new ByteArrayOutputStream();
        IO.copy(p2.getInputStream(), baos);
        assertThat(baos.toString("UTF-8"), is("Other")); 
    }
    
    @Test
    public void testBufferOverflowNoCRLF () throws Exception
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write("--AaB03x".getBytes());
        for (int i=0; i< 8500; i++) //create content that will overrun default buffer size of BufferedInputStream
        {
            baos.write('a');
        }
        
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(baos.toByteArray()), 
                                                             _contentType,
                                                             config,
                                                             _tmpDir);
        mpis.setDeleteOnExit(true);
        try
        {
            mpis.getParts();
            fail ("Multipart buffer overrun");
        }
        catch (IOException e)
        {
            assertTrue(e.getMessage().startsWith("Buffer size exceeded"));
        }

    }
    
    
    public void testCharsetEncoding () throws Exception
    {
        String contentType = "multipart/form-data; boundary=TheBoundary; charset=ISO-8859-1";
        String str = "--TheBoundary\r"+
                "content-disposition: form-data; name=\"field1\"\r"+
                "\r"+
                "\nJoe Blow\n"+ 
                "\r"+
                "--TheBoundary--\r";
        
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(str.getBytes()),
                                                                         contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(1));
    }
    
    
    @Test
    public void testBadlyEncodedFilename() throws Exception
    {
        
        String contents =  "--AaB03x\r\n"+
        "content-disposition: form-data; name=\"stuff\"; filename=\"" +"Taken on Aug 22 \\ 2012.jpg"  + "\"\r\n"+
        "Content-Type: text/plain\r\n"+
        "\r\n"+"stuff"+
        "aaa"+"\r\n" +
        "--AaB03x--\r\n";
        
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(contents.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(1));
        assertThat(((MultiPartInputStreamParser.MultiPart)parts.iterator().next()).getSubmittedFileName(), is("Taken on Aug 22 \\ 2012.jpg"));
    }
    
    @Test
    public void testBadlyEncodedMSFilename() throws Exception
    {
        
        String contents =  "--AaB03x\r\n"+
        "content-disposition: form-data; name=\"stuff\"; filename=\"" +"c:\\this\\really\\is\\some\\path\\to\\a\\file.txt"  + "\"\r\n"+
        "Content-Type: text/plain\r\n"+
        "\r\n"+"stuff"+
        "aaa"+"\r\n" +
        "--AaB03x--\r\n";
        
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(contents.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(1));
        assertThat(((MultiPartInputStreamParser.MultiPart)parts.iterator().next()).getSubmittedFileName(), is("c:\\this\\really\\is\\some\\path\\to\\a\\file.txt"));
    }

    @Test
    public void testCorrectlyEncodedMSFilename() throws Exception
    {
        String contents =  "--AaB03x\r\n"+
        "content-disposition: form-data; name=\"stuff\"; filename=\"" +"c:\\\\this\\\\really\\\\is\\\\some\\\\path\\\\to\\\\a\\\\file.txt"  + "\"\r\n"+
        "Content-Type: text/plain\r\n"+
        "\r\n"+"stuff"+
        "aaa"+"\r\n" +
        "--AaB03x--\r\n";
        
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(contents.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(1));
        assertThat(((MultiPartInputStreamParser.MultiPart)parts.iterator().next()).getSubmittedFileName(), is("c:\\this\\really\\is\\some\\path\\to\\a\\file.txt"));
    }
    
    public void testMulti ()
    throws Exception
    {
        testMulti(FILENAME);
    }

    @Test
    public void testMultiWithSpaceInFilename() throws Exception
    {
        testMulti("stuff with spaces.txt");
    }

    
    
    
    private void testMulti(String filename) throws IOException, ServletException, InterruptedException
    {
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(createMultipartRequestString(filename).getBytes()),
                _contentType,
                config,
                _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertThat(parts.size(), is(2));
        Part field1 = mpis.getPart("field1");  //field 1 too small to go into tmp file, should be in internal buffer
        assertThat(field1,notNullValue());
        assertThat(field1.getName(),is("field1"));
        InputStream is = field1.getInputStream();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        IO.copy(is, os);
        assertEquals("Joe Blow", new String(os.toByteArray()));
        assertEquals(8, field1.getSize());

        assertNotNull(((MultiPartInputStreamParser.MultiPart)field1).getBytes());//in internal buffer
        field1.write("field1.txt");
        assertNull(((MultiPartInputStreamParser.MultiPart)field1).getBytes());//no longer in internal buffer
        File f = new File (_dirname+File.separator+"field1.txt");
        assertTrue(f.exists());
        field1.write("another_field1.txt"); //write after having already written
        File f2 = new File(_dirname+File.separator+"another_field1.txt");
        assertTrue(f2.exists());
        assertFalse(f.exists()); //should have been renamed
        field1.delete();  //file should be deleted
        assertFalse(f.exists()); //original file was renamed
        assertFalse(f2.exists()); //2nd written file was explicitly deleted

        MultiPart stuff = (MultiPart)mpis.getPart("stuff");
        assertThat(stuff.getSubmittedFileName(), is(filename));
        assertThat(stuff.getContentType(),is("text/plain"));
        assertThat(stuff.getHeader("Content-Type"),is("text/plain"));
        assertThat(stuff.getHeaders("content-type").size(),is(1));
        assertThat(stuff.getHeader("content-disposition"),is("form-data; name=\"stuff\"; filename=\"" + filename + "\""));
        assertThat(stuff.getHeaderNames().size(),is(2));
        assertThat(stuff.getSize(),is(51L));
        
        File tmpfile = ((MultiPartInputStreamParser.MultiPart)stuff).getFile();
        assertThat(tmpfile,notNullValue()); // longer than 100 bytes, should already be a tmp file
        assertThat(((MultiPartInputStreamParser.MultiPart)stuff).getBytes(),nullValue()); //not in an internal buffer
        assertThat(tmpfile.exists(),is(true));
        assertThat(tmpfile.getName(),is(not("stuff with space.txt")));
        stuff.write(filename);
        f = new File(_dirname+File.separator+filename);
        assertThat(f.exists(),is(true));
        assertThat(tmpfile.exists(), is(false));
        try
        {
            stuff.getInputStream();          
        }
        catch (Exception e)
        {
            fail("Part.getInputStream() after file rename operation");
        }
        f.deleteOnExit(); //clean up after test
    }

    @Test
    public void testMultiSameNames ()
    throws Exception
    {
        String sameNames =  "--AaB03x\r\n"+
        "content-disposition: form-data; name=\"stuff\"; filename=\"stuff1.txt\"\r\n"+
        "Content-Type: text/plain\r\n"+
        "\r\n"+
        "00000\r\n"+
        "--AaB03x\r\n"+
        "content-disposition: form-data; name=\"stuff\"; filename=\"stuff2.txt\"\r\n"+
        "Content-Type: text/plain\r\n"+
        "\r\n"+
        "110000000000000000000000000000000000000000000000000\r\n"+
        "--AaB03x--\r\n";

        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(sameNames.getBytes()),
                                                             _contentType,
                                                             config,
                                                             _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertEquals(2, parts.size());
        for (Part p:parts)
            assertEquals("stuff", p.getName());

        //if they all have the name name, then only retrieve the first one
        Part p = mpis.getPart("stuff");
        assertNotNull(p);
        assertEquals(5, p.getSize());
    }

    @Test
    public void testBase64EncodedContent () throws Exception
    {
        String contentWithEncodedPart =
                "--AaB03x\r\n"+
                        "Content-disposition: form-data; name=\"other\"\r\n"+
                        "Content-Type: text/plain\r\n"+
                        "\r\n"+
                        "other" + "\r\n"+
                        "--AaB03x\r\n"+
                        "Content-disposition: form-data; name=\"stuff\"; filename=\"stuff.txt\"\r\n"+
                        "Content-Transfer-Encoding: base64\r\n"+
                        "Content-Type: application/octet-stream\r\n"+
                        "\r\n"+
                        B64Code.encode("hello jetty") + "\r\n"+                  
                        "--AaB03x\r\n"+
                        "Content-disposition: form-data; name=\"final\"\r\n"+
                        "Content-Type: text/plain\r\n"+
                        "\r\n"+
                        "the end" + "\r\n"+
                        "--AaB03x--\r\n";

        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(contentWithEncodedPart.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertEquals(3, parts.size());

        Part p1 = mpis.getPart("other");
        assertNotNull(p1);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IO.copy(p1.getInputStream(), baos);
        assertEquals("other", baos.toString("US-ASCII"));

        Part p2 = mpis.getPart("stuff");
        assertNotNull(p2);
        baos = new ByteArrayOutputStream();
        IO.copy(p2.getInputStream(), baos);
        assertEquals("hello jetty", baos.toString("US-ASCII"));
        
        Part p3 = mpis.getPart("final");
        assertNotNull(p3);
        baos = new ByteArrayOutputStream();
        IO.copy(p3.getInputStream(), baos);
        assertEquals("the end", baos.toString("US-ASCII"));
    }
    
    @Test
    public void testQuotedPrintableEncoding () throws Exception
    {
        String contentWithEncodedPart = 
                "--AaB03x\r\n"+
                        "Content-disposition: form-data; name=\"other\"\r\n"+
                        "Content-Type: text/plain\r\n"+
                        "\r\n"+
                        "other" + "\r\n"+
                        "--AaB03x\r\n"+
                        "Content-disposition: form-data; name=\"stuff\"; filename=\"stuff.txt\"\r\n"+
                        "Content-Transfer-Encoding: quoted-printable\r\n"+
                        "Content-Type: text/plain\r\n"+
                        "\r\n"+
                        "truth=3Dbeauty" + "\r\n"+
                        "--AaB03x--\r\n";  
        MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
        MultiPartInputStreamParser mpis = new MultiPartInputStreamParser(new ByteArrayInputStream(contentWithEncodedPart.getBytes()),
                                                                         _contentType,
                                                                         config,
                                                                         _tmpDir);
        mpis.setDeleteOnExit(true);
        Collection<Part> parts = mpis.getParts();
        assertEquals(2, parts.size());

        Part p1 = mpis.getPart("other");
        assertNotNull(p1);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IO.copy(p1.getInputStream(), baos);
        assertEquals("other", baos.toString("US-ASCII"));

        Part p2 = mpis.getPart("stuff");
        assertNotNull(p2);
        baos = new ByteArrayOutputStream();
        IO.copy(p2.getInputStream(), baos);
        assertEquals("truth=beauty", baos.toString("US-ASCII"));
    }




    
    private String createMultipartRequestString(String filename)
    {
        int length = filename.length();
        String name = filename;
        if (length > 10)
            name = filename.substring(0,10);
        StringBuffer filler = new StringBuffer();
        int i = name.length();
        while (i < 51)
        {
            filler.append("0");
            i++;
        }
        
        return "--AaB03x\r\n"+
        "content-disposition: form-data; name=\"field1\"; filename=\"frooble.txt\"\r\n"+
        "\r\n"+
        "Joe Blow\r\n"+
        "--AaB03x\r\n"+
        "content-disposition: form-data; name=\"stuff\"; filename=\"" + filename + "\"\r\n"+
        "Content-Type: text/plain\r\n"+
        "\r\n"+name+
        filler.toString()+"\r\n" +
        "--AaB03x--\r\n";
    }
}
