[Java-2.0.4] Is there a way to increase memoryThreshold of Raw body parser?

206 views
Skip to first unread message

Dennis Mnuskin

unread,
Jan 2, 2013, 5:12:49 AM1/2/13
to play-fr...@googlegroups.com
I'm working on an internal app and need to be able to upload data without it being saved to disk.  This is an internal API so I'm not as concerned with DoS attacks, and the other side may send up to 512KB of data in one request.

Is there a way to force Raw body parse to store the whole request in memory without writing it out to disk when size exceeds 100KB?

Nilanjan Raychaudhuri

unread,
Jan 2, 2013, 6:06:28 PM1/2/13
to play-fr...@googlegroups.com
The Play documentation have one example of passing max length as a parameter to the body parser

http://www.playframework.org/documentation/2.0.4/JavaBodyParsers

@BodyParser.Of(value = BodyParser.Text.class, maxLength = 10 * 1024)
pulic static Result index() {
  ....
}

Thanks
Nilanjan, Developer & Consultant
Typesafe Inc.

Dennis Mnuskin

unread,
Jan 2, 2013, 6:35:01 PM1/2/13
to play-fr...@googlegroups.com
Yes, play documentation does mention that. However, if that worked, I wouldn't be here asking this question.

So far I've tried setting:
* parsers.text.maxLength=512K
* parsers.raw.maxLength=512K
* parsers.raw.memoryThreshold=512K
* parsers.text.maxLength=524288
* parsers.raw.maxLength=524288
* parsers.raw.memoryThreshold=524288

I've also tried using the annotation the way that documentation page suggested. So far.... nothing.

I'm currently in the process of attempting to figure out how to actually debug Play via eclipse so I can step and see where this value gets read from.  However, that is proving to be a challenge all on its own.

-- Dennis

Nilanjan Raychaudhuri

unread,
Jan 2, 2013, 8:16:00 PM1/2/13
to play-fr...@googlegroups.com
Ok. I think now I understand the problem. We are trying to configure the wrong thing here. We don't care about the max length but instead in memory threshold size. I should have read the title of your question more carefully, my fault. Now coming back to your actually question. The default memory threshold is not configurable at this moment. As a workaround I think we can provide our own body parser that works completely in-memory by reusing the existing raw body parser. At this moment this is written in Scala but I am sure we can re-write this in Java as well.

//in memory raw body parser. Save it as InMemoryRawBodyParser.scala file in your play project

import play.api.mvc._
import play.mvc.Http.{ RequestBody }
import play.core.j.JavaParsers._

class InMemoryRawBodyParser extends play.mvc.BodyParser {
  val inMemoryBufferSize = 10 * 1024  //this is what you need to configure for the buffer size
  def parser(maxLength: Int): BodyParser[RequestBody] = {
    parse.maxLength(maxLength, parse.raw(inMemoryBufferSize)).map { body =>
      body
      .left.map(_ => DefaultRequestBody(isMaxSizeExceeded = true))
      .right.map { raw =>
        DefaultRequestBody(raw = Some(raw))
      }.fold(identity, identity)
    }
  }
}

And finally use it in your Java controller like following:

  @BodyParser.Of(value = InMemoryRawBodyParser.class)
  public static Result index() {
    System.out.println(">>>>>> " + request().body().asRaw().size());
    ...
  }

HTH


Nilanjan, Developer & Consultant
Typesafe Inc.

Dennis Mnuskin

unread,
Jan 3, 2013, 11:13:43 AM1/3/13
to play-fr...@googlegroups.com
Nilanjan,

Can't say I understand how exactly that Scala class does what it does, but it did work as expected.

Thank you

-- Dennis

Reply all
Reply to author
Forward
0 new messages