Jetty: Refactor (rather than remove) RequestWrapper to use Servlet 3.0 API.

Remove old org.mortbay helper classes copied from Jetty 5, saving about 24 KB.
Large attachments will now be written to temp files. (ticket #2109)
This commit is contained in:
zzz
2017-12-04 16:08:03 +00:00
parent 14941d0dda
commit c299976165
10 changed files with 118 additions and 1424 deletions

View File

@@ -30,12 +30,21 @@ import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import org.mortbay.servlet.MultiPartRequest;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
/**
* Refactored in 0.9.33 to use Servlet 3.0 API and remove dependency
* on old Jetty 5 MultiPartRequest code. See ticket 2109.
*
* Previous history:
*
* Required major changes for Jetty 6
* to support change from MultiPartRequest to MultiPartFilter.
* See http://docs.codehaus.org/display/JETTY/File+Upload+in+jetty6
@@ -52,15 +61,14 @@ import org.mortbay.servlet.MultiPartRequest;
*
* @author user
* @since 0.9.19 moved from susimail so it may be used by routerconsole too
* @deprecated scheduled for removal in 0.9.34, see ticket #2109
*/
@Deprecated
public class RequestWrapper {
private final HttpServletRequest httpRequest;
private final MultiPartRequest multiPartRequest;
private final boolean isMultiPartRequest;
private final Hashtable<String, String> cache;
private Hashtable<String, Integer> cachedParameterNames;
private static final int MAX_STRING_SIZE = 64*1024;
/**
* @param httpRequest
@@ -69,19 +77,7 @@ public class RequestWrapper {
cache = new Hashtable<String, String>();
this.httpRequest = httpRequest;
String contentType = httpRequest.getContentType();
MultiPartRequest mpr = null;
if( contentType != null && contentType.toLowerCase(Locale.US).startsWith( "multipart/form-data" ) ) {
try {
mpr = new MultiPartRequest( httpRequest );
} catch (OutOfMemoryError oome) {
// TODO Throw ioe from constructor?
oome.printStackTrace();
} catch (IOException e) {
// TODO Throw ioe from constructor?
e.printStackTrace();
}
}
multiPartRequest = mpr;
isMultiPartRequest = contentType != null && contentType.toLowerCase(Locale.US).startsWith("multipart/form-data");
}
/**
@@ -106,19 +102,27 @@ public class RequestWrapper {
/**
* @return List of request parameter names
*/
@SuppressWarnings("unchecked") // TODO-Java6: Remove, type is correct
public Enumeration<String> getParameterNames() {
if( multiPartRequest != null ) {
if (isMultiPartRequest) {
if( cachedParameterNames == null ) {
cachedParameterNames = new Hashtable<String, Integer>();
String[] partNames = multiPartRequest.getPartNames();
for( int i = 0; i < partNames.length; i++ )
cachedParameterNames.put( partNames[i], Integer.valueOf( i ) );
try {
Integer DUMMY = Integer.valueOf(0);
for (Part p : httpRequest.getParts()) {
cachedParameterNames.put(p.getName(), DUMMY);
}
} catch (IOException ioe) {
log(ioe);
} catch (ServletException se) {
log(se);
} catch (IllegalStateException ise) {
log(ise);
}
}
return cachedParameterNames.keys();
}
else
} else {
return httpRequest.getParameterNames();
}
}
/**
@@ -138,18 +142,17 @@ public class RequestWrapper {
public String getContentType( String partName )
{
String result = null;
if( multiPartRequest != null ) {
Hashtable<String, String> params = multiPartRequest.getParams( partName );
for( Map.Entry<String, String> e : params.entrySet() ) {
String key = e.getKey();
if( key.toLowerCase(Locale.US).compareToIgnoreCase( "content-type") == 0 ) {
String value = e.getValue();
int i = value.indexOf( ';' );
if( i != -1 )
result = value.substring( 0, i );
else
result = value;
}
if (isMultiPartRequest) {
try {
Part p = httpRequest.getPart(partName);
if (p != null)
result = p.getContentType();
} catch (IOException ioe) {
log(ioe);
} catch (ServletException se) {
log(se);
} catch (IllegalStateException ise) {
log(ise);
}
}
return result;
@@ -162,25 +165,38 @@ public class RequestWrapper {
public String getParameter( String name, String defaultValue )
{
String result = defaultValue;
if( multiPartRequest != null ) {
if (isMultiPartRequest) {
String str = cache.get(name);
if( str != null ) {
result = str;
}
else {
String[] partNames = multiPartRequest.getPartNames();
for( int i = 0; i < partNames.length; i++ )
if( partNames[i].compareToIgnoreCase( name ) == 0 ) {
str = multiPartRequest.getString( partNames[i] );
if( str != null ) {
result = str;
cache.put( name, result );
break;
}
} else {
InputStream in = null;
try {
Part p = httpRequest.getPart(name);
if (p != null) {
long len = p.getSize();
if (len > MAX_STRING_SIZE)
throw new IOException("String too big: " + len);
in = p.getInputStream();
byte[] data = new byte[(int) len];
DataHelper.read(in, data);
String enc = httpRequest.getCharacterEncoding();
if (enc == null)
enc = "UTF-8";
result = new String(data, enc);
cache.put( name, result );
}
} catch (IOException ioe) {
log(ioe);
} catch (ServletException se) {
log(se);
} catch (IllegalStateException ise) {
log(ise);
} finally {
if (in != null) try { in.close(); } catch (IOException ioe) {}
}
}
}
else {
} else {
String str = httpRequest.getParameter( name );
if( str != null )
result = str;
@@ -191,10 +207,18 @@ public class RequestWrapper {
public String getFilename(String partName )
{
String result = null;
if( multiPartRequest != null ) {
String str = multiPartRequest.getFilename( partName );
if( str != null )
result = str;
if (isMultiPartRequest) {
try {
Part p = httpRequest.getPart(partName);
if (p != null)
result = p.getSubmittedFileName();
} catch (IOException ioe) {
log(ioe);
} catch (ServletException se) {
log(se);
} catch (IllegalStateException ise) {
log(ise);
}
}
return result;
}
@@ -202,10 +226,25 @@ public class RequestWrapper {
public InputStream getInputStream(String partName )
{
InputStream result = null;
if( multiPartRequest != null ) {
result = multiPartRequest.getInputStream( partName );
if (isMultiPartRequest) {
try {
Part p = httpRequest.getPart(partName);
if (p != null)
result = p.getInputStream();
} catch (IOException ioe) {
log(ioe);
} catch (ServletException se) {
log(se);
} catch (IllegalStateException ise) {
log(ise);
}
}
return result;
}
/** @since 0.9.33 */
private static void log(Exception e) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RequestWrapper.class);
log.error("Multipart form error", e);
}
}