Gleeb
Gleeb

Reputation: 11289

PlayFramework 2.4.6 error 413 Request Entity Too Large

I am using PlayFramework 2.4.6, trying to upload a multipart file (size 18M) and the server returns the following error:

For request 'POST /api/myEndpoint' [Request Entity Too Large]

I have looked around and tried the following with out success:

  1. play.http.parser.maxMemoryBuffer=2000000K
  2. parsers.MultipartFormData.maxLength=1024000K
  3. play.http.parser.maxDiskBuffer=2000000K
  4. Action.async(parse.anyContent(Some(1024*200L)))

And none of them solves the problem.

Here is the Stacktrace as well:

14:57:33.128 [New I/O worker #2] [error] -     p.c.server.netty.RequestBodyHandler - Exception caught in RequestBodyHandler
java.nio.channels.ClosedChannelException: null
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.setInterestOps(AbstractNioWorker.java:506) [netty-3.10.4.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker$1.run(AbstractNioWorker.java:455) [netty-3.10.4.Final.jar:na]
at org.jboss.netty.channel.socket.ChannelRunnableWrapper.run(ChannelRunnableWrapper.java:40) [netty-3.10.4.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.processTaskQueue(AbstractNioSelector.java:391) [netty-3.10.4.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:315) [netty-3.10.4.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89) [netty-3.10.4.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) [netty-3.10.4.Final.jar:na]
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108) [netty-3.10.4.Final.jar:na]
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) [netty-3.10.4.Final.jar:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_65]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_65]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_65]

Upvotes: 25

Views: 14100

Answers (5)

Manu Chadha
Manu Chadha

Reputation: 16735

In my case, I am using an AnyContent Parser. I changed the controller definition to following to make my code work

def newQuestion = silhouette.SecuredAction.async(parse.maxLength(1024 * 1024, parse.anyContent)(ActorMaterializer()(ActorSystem("MyApplication")))){

  implicit request => {
      println("got request with body:" + request.body)
      val anyBodyErrors: Either[MaxSizeExceeded, AnyContent] = request.body
      anyBodyErrors match {
        case Left(size) => {
          Future {
            EntityTooLarge(Json.toJson(JsonResultError(messagesApi("error.entityTooLarge")(langs.availables(0)))))
          }
        }
        case Right(body) => {

          //val body:AnyContent = request.body
          val jsonBodyOption = body.asJson
...
}
}

Upvotes: 0

AJS
AJS

Reputation: 47

For those who are facing issue with Play Framework 2.6.x see documentation at https://www.playframework.com/documentation/2.6.x/ScalaBodyParsers

Max content length Text based body parsers (such as text, json, xml or formUrlEncoded) use a max content length because they have to load all the content into memory. By default, the maximum content length that they will parse is 100KB. It can be overridden by specifying the play.http.parser.maxMemoryBuffer property in application.conf:

add following in application.conf:

play.http.parser.maxMemoryBuffer = 5MB

Upvotes: 2

Gleeb
Gleeb

Reputation: 11289

Solved the problem with this:

play.http.parser.maxDiskBuffer = 100MB

parsers.anyContent.maxLength = 100MB

Upvotes: 36

cdmckay
cdmckay

Reputation: 32270

See this documentation about the memory and disk buffers Play uses: https://www.playframework.com/documentation/2.4.x/ScalaBodyParsers#Max-content-length

Text based body parsers (such as text, json, xml or formUrlEncoded) use a max content length because they have to load all the content into memory. By default, the maximum content length that they will parse is 100KB. It can be overridden by specifying the play.http.parser.maxMemoryBuffer property in application.conf:

play.http.parser.maxMemoryBuffer=128K

For parsers that buffer content on disk, such as the raw parser or multipart/form-data, the maximum content length is specified using the play.http.parser.maxDiskBuffer property, it defaults to 10MB. The multipart/form-data parser also enforces the text max length property for the aggregate of the data fields.

So, since you're trying to uploading a multipart file, you'll need to increase the play.http.parser.maxDiskBuffer to something >18MB.

So, adding this to your application.conf should fix it:

play.http.parser.maxDiskBuffer=100MB

Upvotes: 20

juanignaciosl
juanignaciosl

Reputation: 3573

I was having the same problem sending a large form and play.http.parser.maxMemoryBuffer=4MB solved it.

Upvotes: 28

Related Questions