withSizeLimit • Akka HTTP (original) (raw)
Signature
def withSizeLimit(maxBytes: Long): Directive0
Description
Fails the stream with EntityStreamSizeException
if its request entity size exceeds given limit. Limit given as parameter overrides limit configured with akka.http.parsing.max-content-length
.
The whole mechanism of entity size checking is intended to prevent certain Denial-of-Service attacks. So suggested setup is to have akka.http.parsing.max-content-length
relatively low and use withSizeLimit
directive for endpoints which expects bigger entities.
See also withoutSizeLimit for skipping request entity size check.
Examples
Scala
source`` val route = withSizeLimit(500) { entity(as[String]) { _ => complete(HttpResponse()) } }
// tests:
def entityOfSize(size: Int) =
HttpEntity(ContentTypes.text/plain(UTF-8)
, List.fill(size)('0').mkString)
Post("/abc", entityOfSize(500)) ~> route ~> check { status shouldEqual StatusCodes.OK }
Post("/abc", entityOfSize(501)) ~> Route.seal(route) ~> check { status shouldEqual StatusCodes.ContentTooLarge } ``
Java
source`import static akka.http.javadsl.server.Directives.complete; import static akka.http.javadsl.server.Directives.entity; import static akka.http.javadsl.server.Directives.withSizeLimit;
final Route route = withSizeLimit(500, () -> entity(Unmarshaller.entityToString(), (entity) -> complete("ok") ) );
Function<Integer, HttpRequest> withEntityOfSize = (sizeLimit) -> { char[] charArray = new char[sizeLimit]; Arrays.fill(charArray, '0'); return HttpRequest.POST("/").withEntity(new String(charArray)); };
// tests: testRoute(route).run(withEntityOfSize.apply(500)) .assertStatusCode(StatusCodes.OK);
testRoute(route).run(withEntityOfSize.apply(501)) .assertStatusCode(StatusCodes.CONTENT_TOO_LARGE);`
Beware that request entity size check is executed when entity is consumed. Therefore in the following example even request with entity greater than argument to withSizeLimit
will succeed (because this route does not consume entity):
source`` val route = withSizeLimit(500) { complete(HttpResponse()) }
// tests:
def entityOfSize(size: Int) =
HttpEntity(ContentTypes.text/plain(UTF-8)
, List.fill(size)('0').mkString)
Post("/abc", entityOfSize(500)) ~> route ~> check { status shouldEqual StatusCodes.OK }
Post("/abc", entityOfSize(501)) ~> route ~> check { status shouldEqual StatusCodes.OK } ``
Directive withSizeLimit
is implemented in terms of HttpEntity.withSizeLimit
which means that in case of nested withSizeLimit
directives the innermost is applied:
Scala
source`` val route = withSizeLimit(500) { withSizeLimit(800) { entity(as[String]) { _ => complete(HttpResponse()) } } }
// tests:
def entityOfSize(size: Int) =
HttpEntity(ContentTypes.text/plain(UTF-8)
, List.fill(size)('0').mkString)
Post("/abc", entityOfSize(800)) ~> route ~> check {
status shouldEqual StatusCodes.OK
}
Post("/abc", entityOfSize(801)) ~> Route.seal(route) ~> check { status shouldEqual StatusCodes.ContentTooLarge } ``
Java
source`import static akka.http.javadsl.server.Directives.complete; import static akka.http.javadsl.server.Directives.entity; import static akka.http.javadsl.server.Directives.withSizeLimit;
final Route route = withSizeLimit(500, () -> withSizeLimit(800, () -> entity(Unmarshaller.entityToString(), (entity) -> complete("ok") )) );
Function<Integer, HttpRequest> withEntityOfSize = (sizeLimit) -> { char[] charArray = new char[sizeLimit]; Arrays.fill(charArray, '0'); return HttpRequest.POST("/").withEntity(new String(charArray)); };
// tests: testRoute(route).run(withEntityOfSize.apply(800)) .assertStatusCode(StatusCodes.OK);
testRoute(route).run(withEntityOfSize.apply(801)) .assertStatusCode(StatusCodes.CONTENT_TOO_LARGE);`
Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.