What is the maximum data size I can send in a single HttpURLConnection to Tomcat? Is there any limitation for the request size?
You have to modify two possible limits:
In conf\server.xml
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxPostSize="67589953" />
In webapps\manager\WEB-INF\web.xml
<multipart-config>
<!-- 52MB max -->
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
The connector section has the parameter
maxPostSize
The maximum size in bytes of the POST which will be handled by the container FORM URL parameter parsing. The limit can be disabled by setting this attribute to a value less than or equal to 0. If not specified, this attribute is set to 2097152 (2 megabytes).
Another Limit is:
maxHttpHeaderSize The maximum size of the request and response HTTP header, specified in bytes. If not specified, this attribute is set to 4096 (4 KB).
You find them in
$TOMCAT_HOME/conf/server.xml
The full answer
1. The default (fresh install of tomcat)
When you download tomcat from their official website (of today that's tomcat version 9.0.26), all the apps you installed to tomcat can handle HTTP requests of unlimited size, given that the apps themselves do not have any limits on request size.
However, when you try to upload an app in tomcat's manager app, that app has a default war file limit of 50MB. If you're trying to install Jenkins for example which is 77 MB as ot today, it will fail.
2. Configure tomcat's per port http request size limit
Tomcat itself has size limit for each port, and this is defined in conf\server.xml. This is controlled by maxPostSize attribute of each Connector(port). If this attribute does not exist, which it is by default, there is no limit on the request size.
To add a limit to a specific port, set a byte size for the attribute. For example, the below config for the default 8080 port limits request size to 200 MB. This means that all the apps installed under port 8080 now has the size limit of 200MB
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxPostSize="209715200" />
3. Configure app level size limit
After passing the port level size limit, you can still configure app level limit. This also means that app level limit should be less than port level limit. The limit can be done through annotation within each servlet, or in the web.xml file. Again, if this is not set at all, there is no limit on request size.
To set limit through java annotation
#WebServlet("/uploadFiles")
#MultipartConfig( fileSizeThreshold = 0, maxFileSize = 209715200, maxRequestSize = 209715200)
public class FileUploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) {
// ...
}
}
To set limit through web.xml
<web-app>
...
<servlet>
...
<multipart-config>
<file-size-threshold>0</file-size-threshold>
<max-file-size>209715200</max-file-size>
<max-request-size>209715200</max-request-size>
</multipart-config>
...
</servlet>
...
</web-app>
4. Appendix - If you see file upload size error when trying to install app through Tomcat's Manager app
Tomcat's Manager app (by default localhost:8080/manager) is nothing but a default web app. By default that app has a web.xml configuration of request limit of 50MB. To install (upload) app with size greater than 50MB through this manager app, you have to change the limit. Open the manager app's web.xml file from webapps\manager\WEB-INF\web.xml and follow the above guide to change the size limit and finally restart tomcat.
Although other answers include some of the following information, this is the absolute minimum that needs to be changed on EC2 instances, specifically regarding deployment of large WAR files, and is the least likely to cause issues during future updates. I've been running into these limits about every other year due to the ever-increasing size of the Jenkins WAR file (now ~72MB).
More specifically, this answer is applicable if you encounter a variant of the following error in catalina.out:
SEVERE [https-jsse-nio-8443-exec-17] org.apache.catalina.core.ApplicationContext.log HTMLManager:
FAIL - Deploy Upload Failed, Exception:
[org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException:
the request was rejected because its size (75333656) exceeds the configured maximum (52428800)]
On Amazon EC2 Linux instances, the only file that needs to be modified from the default installation of Tomcat (sudo yum install tomcat8) is:
/usr/share/tomcat8/webapps/manager/WEB-INF/web.xml
By default, the maximum upload size is exactly 50MB:
<multipart-config>
<!-- 50MB max -->
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
There are only two values that need to be modified (max-file-size and max-request-size):
<multipart-config>
<!-- 100MB max -->
<max-file-size>104857600</max-file-size>
<max-request-size>104857600</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
When Tomcat is upgraded on these instances, the new version of the manager web.xml will be placed in web.xml.rpmnew, so any modifications to the original file will not be overwritten during future updates.
Just to add to the answers, App Server Apache Geronimo 3.0 uses Tomcat 7 as the web server, and in that environment the file server.xml is located at
<%GERONIMO_HOME%>/var/catalina/server.xml.
The configuration does take effect even when the Geronimo Console at Application Server->WebServer->TomcatWebConnector->maxPostSize still displays 2097152 (the default value)
Related
I have a Spring Boot application where I fill in a generated form based on a certain file that the user has to upload.
Somtimes in this file, a table can occur >100 times.
When this is the case, whenever I try to submit the form, I get the error:
More than the maximum number of request parameters (GET plus POST) for a single request ([10,000]) were detected. Any parameters beyond this limit have been ignored. To change this limit, set the maxParameterCount attribute on the Connector.
I have tried solving this by adding the following code to my server.xml:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" maxParameterCount="1000000"/>
As is stated in this post - set the maxParameterCount attribute on the Connector. But this doesn't seem to do anything.
My application is running on port 8081, but changing this in the connector code doesn't make any difference. I still get the error that my request exceeded 10 000 parameters.
Does anyone have an idea?
Thanks in advance.
Kind Regards
The third party tool we used for security test is giving Slow HTTP POST Vulnerability on Tomcat 8. We have a simple Spring Controller and JSP in the application.
Existing Tomcat connector config is below:
<Connector port="8643" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true" compression="on"
clientAuth="false" sslProtocol="TLS" maxPostSize="20480"
maxSwallowSize="20480" maxHeaderCount="25" maxParameterCount="100"/>
Note that we don't have Apache or Nginx in front of tomcat. Please suggest the configs that we can use directly on Tomcat.
An example of Slow HTTP Attack is SLOWLORIS
To mitigate it with Tomcat, the solution is to use the NIO Connector, as explained in this tutorial.
What is unclear with your problem, is that Tomcat already uses the NIO connector by default on Tomcat 8, which is your configuration :
The default value is HTTP/1.1 which uses an auto-switching mechanism
to select either a non blocking Java NIO based connector or an
APR/native based connector.
Maybe should you set some other Connector parameters to specifically limit POST abuse, I suggest :
maxPostSize="1048576" (1 MByte)
connectionTimeout="10000" (10 seconds between the connection and the URI request)
disableUploadTimeout="false" (activate the POST maximum time allowed)
connectionUploadTimeout="20000" (maximum POST of 20 seconds)
An option is also to limit the headers number (default being 100), but this can have side effects with people using smartphones (which are known to send many headers) :
maxHeaderCount="25"
But it depends if your traffic is coming from Internet, or if it is a pro intranet with known users. In this latter case you could adjust the settings to be more permissive.
Edit 1: hardening with MultipartConfig
As stated on some other posts, maxPostSize might not work for limitting uploads. When using Java 7 built-in uploads, it is possible to configure limits by an annotation to the Servlet, or by configuration. It's not a pure Tomcat configuration as you asked, but it is necessary to know about it and talk with the DEV team as security must be taken in account since the early stages of development.
Edit 2: disabling chunked Transfer-Encoding
Some Slow HTTP POST attacks are based on requests sent with a Transfer-Encoding : chunked header, and then send many or an infinite number of chunks. To counter this attack, I suggest configuring a Rewrite Valve.
To achieve this, add the valve in your Host definition in server.xml :
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
Supposing your host name is the default one (localhost), you need to create $CATALINA_BASE/conf/Catalina/localhost/rewrite.config file with this content :
RewriteCond %{HTTP:Transfer-Encoding} chunked
RewriteRule ^(.*)$ / [F]
If necessary, you can adapt the RewriteRule to reply with something else than a 403 Forbidden which is due to the F flag. This is pure Tomcat config and flexible.
I want to apply compression to my responses at tomcat level however it does not work. It seems like an esay protocol, however somehow I am unable to apply it. Here is my connector conf in server.xml
<Connector port="80" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
maxThreads="500"
processorCache="500"
maxConnections="10000"
acceptCount="5000"
URIEncoding="UTF-8"
useSendfile="false"
compression="force"
compressionMinSize="4"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript"/>
I disabled antivirus on my local macihne(Client-side) and the requests have Accept-Encoding:gzip header. Thank you in advance.
Too late but:
Note: There is a tradeoff between using compression (saving your bandwidth) and using the sendfile feature (saving your CPU cycles). If the connector supports the sendfile feature, e.g. the NIO2 connector, using sendfile will take precedence over compression. The symptoms will be that static files greater that 48 Kb will be sent uncompressed. You can turn off sendfile by setting useSendfile attribute of the protocol, as documented below, or change the sendfile usage threshold in the configuration of the DefaultServlet in the default conf/web.xml or in the web.xml of your web application.
I get following error when I try to access some JasperReports Server pages:
Request Entity Too Large The requested resource
/jasperserver/olap/viewOlap.html does not allow request data with GET
requests, or the amount of data provided in the request exceeds the
capacity limit.
I checked the Apache log files and got following error in mod_jk.log
[Thu Nov 10 10:25:00 2016][8964:3876] [error]
ajp_marshal_into_msgb::jk_ajp_common.c (517): failed appending the
query string of length 7417
I already tried many different ways to solve it.
I added the maxHttpHeaderSize and max_packet_size attributes to the ajp connect of Tomcat (server.xml):
<Connector port="8010" protocol="AJP/1.3" connectionTimeout="20000" redirectPort="8443" maxHttpHeaderSize="65536" max_packet_size="65536" />
Also I added the LimitRequestLine, LimitRequestBody, LimitRequestFieldSize and LimitRequestFields to the Apache httpd.conf file (added it to the end of the file without any VirtualHost):
LimitRequestLine 65536
LimitRequestBody 0
LimitRequestFieldSize 65536
LimitRequestFields 10000
I am still getting the error above.
I also found some suggestions to add the max_packet_size to the workers.properties of Apache. But if I add the attribute I get a HTTP 400 error and a white page. That's why I commented the property in workers.properties:
#worker.jasper.max_packet_size=65536
I restarted all services after changing the configurations.
When I access the same pages via HTTP-Connector of Tomcat (http://HOSTNAME:8081/jasperserver/..) it works fine. Only when I access it via AJP-Connector of Apache (http://HOSTNAME/jasperserver/..) I get the error. So I think there should be any problem with the AJP-Connector.
Apache: 2.4.12
JasperReports Server: 6.2.1
Apache Tomcat Version 8.0.14:
Does anyone have a suggestion what I have to do to solve the issue?
I figured out the problem.
The attribute in server.xml for Tomcat has to be
packetSize
and not
max_packet_size
See also documentation AJP Connector
After renaming it, it works fine.
Here are my configurations:
Tomcat server.xml:
Connector port="8010" protocol="AJP/1.3" redirectPort="8443" packetSize="65536"
Apache workers.properties:
worker.jasper.max_packet_size=65536
If you get afterwards the error:
Request-URI Too Long
The requested URL's length exceeds the capacity limit for this server.
You have to set following attributes in Apache httpd.conf file:
LimitRequestLine 65536
LimitRequestBody 0
LimitRequestFieldSize 65536
LimitRequestFields 10000
I hope this answer helps others too.
I am developing a web based application using GlassFish 4 server. Today i got the following exception:
WARNING: GRIZZLY0173: More than the maximum number of request parameters (GET plus POST) for a single request ([10 000]) were detected. Any parameters beyond this limit have been ignored. To change this limit, set the maxParameterCount attribute on the Connector.
This means that when i did a post request to the server i sent more than the currently maximum allowed request parameters so i have to increace the value.
Anyone knows how this can be configured in case of GlassFish 4.
P.S. I dont want to decomplice the source files and change some value. I want to do it thought some xml configuration or throught the server administration console.
In GlassFish 4 you can change the setting max-request-parameters with the asadmin command-line utility:
asadmin set server.network-config.protocols.protocol.http-listener-1.http.max-request-parameters=10001
or manually in the domain.xml:
<protocols>
<protocol name="http-listener-1">
<http max-request-parameters="10001" max-connections="250"
default-virtual-server="server">
<file-cache></file-cache>
</http>
</protocol>
// more protocols...
<protocols>
Add the param max-request-parameters if it doesn't exist. Make sure to use the correct http-listener.