Merge remote-tracking branch 'origin/jetty-7' into jetty-8

Conflicts:
	jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java
	jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
This commit is contained in:
Jan Bartel 2013-06-24 16:44:45 +10:00
commit a7436bc774
3 changed files with 99 additions and 10 deletions

View File

@ -49,13 +49,15 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.Part; import javax.servlet.http.Part;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.MultiPartInputStream; import org.eclipse.jetty.util.MultiPartInputStream;
import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -268,12 +270,11 @@ public class MultiPartFilter implements Filter
{ {
try try
{ {
String s=new String((byte[])o,_encoding); return getParameterBytesAsString(name, (byte[])o);
return s;
} }
catch(Exception e) catch(Exception e)
{ {
e.printStackTrace(); LOG.warn(e);
} }
} }
else if (o!=null) else if (o!=null)
@ -292,8 +293,7 @@ public class MultiPartFilter implements Filter
for ( Object key : _params.keySet() ) for ( Object key : _params.keySet() )
{ {
String[] a = LazyList.toStringArray(getParameter((String)key)); cmap.put((String)key,getParameterValues((String)key));
cmap.put((String)key,a);
} }
return Collections.unmodifiableMap(cmap); return Collections.unmodifiableMap(cmap);
@ -327,7 +327,7 @@ public class MultiPartFilter implements Filter
{ {
try try
{ {
v[i]=new String((byte[])o,_encoding); v[i]=getParameterBytesAsString(name, (byte[])o);
} }
catch(Exception e) catch(Exception e)
{ {
@ -350,5 +350,23 @@ public class MultiPartFilter implements Filter
{ {
_encoding=enc; _encoding=enc;
} }
/* ------------------------------------------------------------------------------- */
private String getParameterBytesAsString (String name, byte[] bytes)
throws UnsupportedEncodingException
{
//check if there is a specific encoding for the parameter
Object ct = _params.get(name+CONTENT_TYPE_SUFFIX);
//use default if not
String contentType = _encoding;
if (ct != null)
{
String tmp = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer((String)ct));
contentType = (tmp == null?_encoding:tmp);
}
return new String(bytes,contentType);
}
} }
} }

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.servlets;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
@ -38,12 +39,13 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.servlet.FilterMapping;
import org.eclipse.jetty.testing.HttpTester; import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester; import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.StringUtil;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -813,6 +815,66 @@ public class MultipartFilterTest
assertTrue(response.getContent().indexOf("brown cow")>=0); assertTrue(response.getContent().indexOf("brown cow")>=0);
} }
public static class TestServletCharSet extends HttpServlet
{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
//test that the multipart content bytes were converted correctly from their charset to unicode
String content = (String)req.getParameter("ttt");
assertNotNull(content);
assertEquals("ttt\u01FCzzz",content);
assertEquals("application/octet-stream; charset=UTF-8",req.getParameter("ttt"+MultiPartFilter.CONTENT_TYPE_SUFFIX));
//test that the parameter map retrieves values as String[]
Map map = req.getParameterMap();
Object o = map.get("ttt");
assertTrue(o.getClass().isArray());
super.doPost(req, resp);
}
}
@Test
public void testWithCharSet()
throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester() {
};
HttpTester response = new HttpTester();
tester.addServlet(TestServletCharSet.class,"/test2");
// test GET
request.setMethod("POST");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setURI("/context/test2");
String boundary="XyXyXy";
request.setHeader("Content-Type","multipart/form-data; boundary="+boundary);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(("--" + boundary + "\r\n"+
"Content-Disposition: form-data; name=\"ttt\"\r\n"+
"Content-Type: application/octet-stream; charset=UTF-8\r\n\r\n").getBytes());
baos.write("ttt\u01FCzzz".getBytes(StringUtil.__UTF8));
baos.write(("\r\n--" + boundary + "--\r\n\r\n").getBytes());
request.setContentBytes(baos.toByteArray());
response.parse(tester.getResponses(new ByteArrayBuffer(request.generate().getBytes(StringUtil.__UTF8))).toString());
}
public static class DumpServlet extends HttpServlet public static class DumpServlet extends HttpServlet
{ {
private static final long serialVersionUID = 201012011130L; private static final long serialVersionUID = 201012011130L;

View File

@ -532,6 +532,15 @@ public class HttpTester
} }
} }
/* ------------------------------------------------------------ */
public void setContentBytes(byte[] bytes)
{
_parsedContent = null;
_genContent = bytes;
setLongHeader(HttpHeaders.CONTENT_LENGTH, bytes.length);
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private class PH extends HttpParser.EventHandler private class PH extends HttpParser.EventHandler
{ {