forked from I2P_Developers/i2p.i2p
Susimail, Console, Jetty:
- Adjust multipart size limits - Better handling of errors when multipart limits are exceeded - Fix multipart config for /configplugins - Test for total size limit in susimail
This commit is contained in:
@ -101,6 +101,7 @@ public class RequestWrapper {
|
||||
|
||||
/**
|
||||
* @return List of request parameter names
|
||||
* @throws IllegalStateException if the request is too large
|
||||
*/
|
||||
public Enumeration<String> getParameterNames() {
|
||||
if (isMultiPartRequest) {
|
||||
@ -117,6 +118,7 @@ public class RequestWrapper {
|
||||
log(se);
|
||||
} catch (IllegalStateException ise) {
|
||||
log(ise);
|
||||
throw ise;
|
||||
}
|
||||
}
|
||||
return cachedParameterNames.keys();
|
||||
@ -139,6 +141,9 @@ public class RequestWrapper {
|
||||
return httpRequest.getContentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalStateException if the request is too large
|
||||
*/
|
||||
public String getContentType( String partName )
|
||||
{
|
||||
String result = null;
|
||||
@ -153,6 +158,7 @@ public class RequestWrapper {
|
||||
log(se);
|
||||
} catch (IllegalStateException ise) {
|
||||
log(ise);
|
||||
throw ise;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -162,6 +168,9 @@ public class RequestWrapper {
|
||||
return httpRequest.getAttribute( string );
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalStateException if the request is too large
|
||||
*/
|
||||
public String getParameter( String name, String defaultValue )
|
||||
{
|
||||
String result = defaultValue;
|
||||
@ -192,6 +201,7 @@ public class RequestWrapper {
|
||||
log(se);
|
||||
} catch (IllegalStateException ise) {
|
||||
log(ise);
|
||||
throw ise;
|
||||
} finally {
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
@ -204,6 +214,9 @@ public class RequestWrapper {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalStateException if the request is too large
|
||||
*/
|
||||
public String getFilename(String partName )
|
||||
{
|
||||
String result = null;
|
||||
@ -218,11 +231,15 @@ public class RequestWrapper {
|
||||
log(se);
|
||||
} catch (IllegalStateException ise) {
|
||||
log(ise);
|
||||
throw ise;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalStateException if the request is too large
|
||||
*/
|
||||
public InputStream getInputStream(String partName )
|
||||
{
|
||||
InputStream result = null;
|
||||
@ -237,6 +254,7 @@ public class RequestWrapper {
|
||||
log(se);
|
||||
} catch (IllegalStateException ise) {
|
||||
log(ise);
|
||||
throw ise;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -9,6 +9,7 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @since 0.9.14
|
||||
@ -25,6 +26,14 @@ public class XSSFilter implements Filter {
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
try {
|
||||
chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
|
||||
} catch (IllegalStateException ise) {
|
||||
// Multipart form error, probably file too big
|
||||
// We need to send the error quickly, if we just throw a ServletException,
|
||||
// the data keeps coming and the connection gets reset.
|
||||
// This way we at least get the error to the browser.
|
||||
((HttpServletResponse)response).sendError(413, ise.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -448,7 +448,7 @@
|
||||
<!-- Add multipart config to servlets that need them -->
|
||||
<property name="__match1" value="<servlet-class>net.i2p.router.web.jsp." />
|
||||
<property name="__match2" value="_jsp</servlet-class>" />
|
||||
<property name="__class1" value="${__match1}configclients${__match2}" />
|
||||
<property name="__class1" value="${__match1}configplugins${__match2}" />
|
||||
<property name="__class2" value="${__match1}configfamily${__match2}" />
|
||||
<property name="__class3" value="${__match1}configreseed${__match2}" />
|
||||
<property name="__multipart" value="
|
||||
|
@ -17,9 +17,10 @@
|
||||
<servlet-name>SusiMail</servlet-name>
|
||||
<servlet-class>i2p.susi.webmail.WebMail</servlet-class>
|
||||
<multipart-config>
|
||||
<max-file-size>67108864</max-file-size>
|
||||
<max-request-size>67108864</max-request-size>
|
||||
<file-size-threshold>262144</file-size-threshold>
|
||||
<!-- 23 MB. See SMTPClient for discussion -->
|
||||
<max-file-size>24117248</max-file-size>
|
||||
<max-request-size>24117248</max-request-size>
|
||||
<file-size-threshold>131072</file-size-threshold>
|
||||
</multipart-config>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
|
@ -72,6 +72,14 @@ public class Attachment {
|
||||
return new FileInputStream(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The unencoded size
|
||||
* @since 0.9.33
|
||||
*/
|
||||
public long getSize() {
|
||||
return data.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the data file
|
||||
* @since 0.9.33
|
||||
|
@ -1648,6 +1648,7 @@ public class WebMail extends HttpServlet
|
||||
sessionObject.isMobile = isMobile;
|
||||
|
||||
if (isPOST) {
|
||||
try {
|
||||
String nonce = request.getParameter(SUSI_NONCE);
|
||||
if (nonce == null || !sessionObject.isValidNonce(nonce)) {
|
||||
// These two strings are already in the router console FormHandler,
|
||||
@ -1660,6 +1661,11 @@ public class WebMail extends HttpServlet
|
||||
ctx);
|
||||
isPOST = false;
|
||||
}
|
||||
} catch (IllegalStateException ise) {
|
||||
// too big, can't get any parameters
|
||||
sessionObject.error += ise.getMessage() + '\n';
|
||||
isPOST = false;
|
||||
}
|
||||
}
|
||||
|
||||
// This must be called to add the attachment before
|
||||
@ -2027,6 +2033,19 @@ public class WebMail extends HttpServlet
|
||||
sessionObject.error += "Internal error: Header line encoder not available.";
|
||||
}
|
||||
|
||||
long total = text.length();
|
||||
boolean multipart = sessionObject.attachments != null && !sessionObject.attachments.isEmpty();
|
||||
if (multipart) {
|
||||
for(Attachment a : sessionObject.attachments) {
|
||||
total += a.getSize();
|
||||
}
|
||||
}
|
||||
if (total > SMTPClient.BINARY_MAX_SIZE) {
|
||||
ok = false;
|
||||
sessionObject.error += _t("Email is too large, max is {0}",
|
||||
DataHelper.formatSize2(SMTPClient.BINARY_MAX_SIZE, false) + 'B') + '\n';
|
||||
}
|
||||
|
||||
if( ok ) {
|
||||
StringBuilder body = new StringBuilder(1024);
|
||||
body.append( "From: " + from + "\r\n" );
|
||||
@ -2040,9 +2059,7 @@ public class WebMail extends HttpServlet
|
||||
sessionObject.error += e.getMessage();
|
||||
}
|
||||
String boundary = "_=" + I2PAppContext.getGlobalContext().random().nextLong();
|
||||
boolean multipart = false;
|
||||
if( sessionObject.attachments != null && !sessionObject.attachments.isEmpty() ) {
|
||||
multipart = true;
|
||||
if (multipart) {
|
||||
body.append( "\r\nMIME-Version: 1.0\r\nContent-type: multipart/mixed; boundary=\"" + boundary + "\"\r\n\r\n" );
|
||||
}
|
||||
else {
|
||||
|
@ -47,6 +47,20 @@ import net.i2p.data.DataHelper;
|
||||
*/
|
||||
public class SMTPClient {
|
||||
|
||||
/**
|
||||
* 31.84 MB
|
||||
* smtp.postman.i2p as of 2017-12.
|
||||
* @since 0.9.33
|
||||
*/
|
||||
public static final long DEFAULT_MAX_SIZE = 33388608;
|
||||
|
||||
/**
|
||||
* About 23.25 MB.
|
||||
* Base64 encodes 57 chars to 76 + \r\n on a line
|
||||
* @since 0.9.33
|
||||
*/
|
||||
public static final long BINARY_MAX_SIZE = (long) ((DEFAULT_MAX_SIZE * 57.0d / 78) - 32*1024);
|
||||
|
||||
private Socket socket;
|
||||
public String error;
|
||||
private String lastResponse;
|
||||
|
Reference in New Issue
Block a user