withSizeLimit and withoutSizeLimit directives added
This commit is contained in:
parent
e00a86271a
commit
72f8544efd
15 changed files with 487 additions and 1 deletions
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2016 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
package docs.http.javadsl.server.directives;
|
||||
|
||||
import akka.http.javadsl.model.HttpRequest;
|
||||
import akka.http.javadsl.model.StatusCodes;
|
||||
import akka.http.javadsl.server.Route;
|
||||
import akka.http.javadsl.server.Unmarshaller;
|
||||
import akka.http.javadsl.testkit.JUnitRouteTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class MiscDirectivesExamplesTest extends JUnitRouteTest {
|
||||
|
||||
@Test
|
||||
public void testWithSizeLimit() {
|
||||
//#withSizeLimitExample
|
||||
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.BAD_REQUEST);
|
||||
//#withSizeLimitExample
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithoutSizeLimit() {
|
||||
//#withoutSizeLimitExample
|
||||
final Route route = withoutSizeLimit(() ->
|
||||
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:
|
||||
// will work even if you have configured akka.http.parsing.max-content-length = 500
|
||||
testRoute(route).run(withEntityOfSize.apply(501))
|
||||
.assertStatusCode(StatusCodes.OK);
|
||||
//#withoutSizeLimitExample
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -139,6 +139,7 @@ Directive Description
|
|||
:ref:`-uploadedFile-java-` Streams one uploaded file from a multipart request to a file on disk
|
||||
:ref:`-validate-java-` Checks a given condition before running its inner route
|
||||
:ref:`-withoutRequestTimeout-java-` Disables :ref:`request timeouts <request-timeout-java>` for a given route.
|
||||
:ref:`-withoutSizeLimit-java-` Skips request entity size check
|
||||
:ref:`-withExecutionContext-java-` Runs its inner route with the given alternative ``ExecutionContext``
|
||||
:ref:`-withMaterializer-java-` Runs its inner route with the given alternative ``Materializer``
|
||||
:ref:`-withLog-java-` Runs its inner route with the given alternative ``LoggingAdapter``
|
||||
|
|
@ -146,5 +147,6 @@ Directive Description
|
|||
:ref:`-withRequestTimeout-java-` Configures the :ref:`request timeouts <request-timeout-java>` for a given route.
|
||||
:ref:`-withRequestTimeoutResponse-java-` Prepares the ``HttpResponse`` that is emitted if a request timeout is triggered. ``RequestContext => RequestContext`` function
|
||||
:ref:`-withSettings-java-` Runs its inner route with the given alternative ``RoutingSettings``
|
||||
:ref:`-withSizeLimit-java-` Applies request entity size check
|
||||
================================================ ============================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -12,3 +12,5 @@ MiscDirectives
|
|||
requestEntityPresent
|
||||
selectPreferredLanguage
|
||||
validate
|
||||
withoutSizeLimit
|
||||
withSizeLimit
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
.. _-withSizeLimit-java-:
|
||||
|
||||
withSizeLimit
|
||||
===============
|
||||
|
||||
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 :ref:`-withoutSizeLimit-java-` for skipping request entity size check.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. includecode:: ../../../../code/docs/http/javadsl/server/directives/MiscDirectivesExamplesTest.java#withSizeLimitExample
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
.. _-withoutSizeLimit-java-:
|
||||
|
||||
withoutSizeLimit
|
||||
================
|
||||
|
||||
Description
|
||||
-----------
|
||||
Skips request entity size verification.
|
||||
|
||||
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 ``withoutSizeLimit``
|
||||
directive just for endpoints for which size verification should not be performed.
|
||||
|
||||
See also :ref:`-withSizeLimit-java-` for setting request entity size limit.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. includecode:: ../../../../code/docs/http/javadsl/server/directives/MiscDirectivesExamplesTest.java#withSizeLimitExample
|
||||
|
|
@ -22,6 +22,7 @@ class MiscDirectivesExamplesSpec extends RoutingSpec {
|
|||
responseAs[String] shouldEqual "Client's ip is 192.168.3.12"
|
||||
}
|
||||
}
|
||||
|
||||
"rejectEmptyResponse-example" in {
|
||||
val route = rejectEmptyResponse {
|
||||
path("even" / IntNumber) { i =>
|
||||
|
|
@ -42,6 +43,7 @@ class MiscDirectivesExamplesSpec extends RoutingSpec {
|
|||
responseAs[String] shouldEqual "Number 28 is even."
|
||||
}
|
||||
}
|
||||
|
||||
"requestEntityEmptyPresent-example" in {
|
||||
val route =
|
||||
requestEntityEmpty {
|
||||
|
|
@ -59,6 +61,7 @@ class MiscDirectivesExamplesSpec extends RoutingSpec {
|
|||
responseAs[String] shouldEqual "request entity empty"
|
||||
}
|
||||
}
|
||||
|
||||
"selectPreferredLanguage-example" in {
|
||||
val request = Get() ~> `Accept-Language`(
|
||||
Language("en-US"),
|
||||
|
|
@ -78,6 +81,7 @@ class MiscDirectivesExamplesSpec extends RoutingSpec {
|
|||
}
|
||||
} ~> check { responseAs[String] shouldEqual "de-DE" }
|
||||
}
|
||||
|
||||
"validate-example" in {
|
||||
val route =
|
||||
extractUri { uri =>
|
||||
|
|
@ -94,4 +98,84 @@ class MiscDirectivesExamplesSpec extends RoutingSpec {
|
|||
rejection shouldEqual ValidationRejection("Path too long: '/abcdefghijkl'", None)
|
||||
}
|
||||
}
|
||||
|
||||
"withSizeLimit-example" in {
|
||||
val route = withSizeLimit(500) {
|
||||
entity(as[String]) { _ ⇒
|
||||
complete(HttpResponse())
|
||||
}
|
||||
}
|
||||
|
||||
// tests:
|
||||
def entityOfSize(size: Int) =
|
||||
HttpEntity(ContentTypes.`text/plain(UTF-8)`, "0" * size)
|
||||
|
||||
Post("/abc", entityOfSize(500)) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.OK
|
||||
}
|
||||
|
||||
Post("/abc", entityOfSize(501)) ~> Route.seal(route) ~> check {
|
||||
status shouldEqual StatusCodes.BadRequest
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
"withSizeLimit-execution-moment-example" in {
|
||||
val route = withSizeLimit(500) {
|
||||
complete(HttpResponse())
|
||||
}
|
||||
|
||||
// tests:
|
||||
def entityOfSize(size: Int) =
|
||||
HttpEntity(ContentTypes.`text/plain(UTF-8)`, "0" * size)
|
||||
|
||||
Post("/abc", entityOfSize(500)) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.OK
|
||||
}
|
||||
|
||||
Post("/abc", entityOfSize(501)) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.OK
|
||||
}
|
||||
}
|
||||
|
||||
"withSizeLimit-nested-example" in {
|
||||
val route =
|
||||
withSizeLimit(500) {
|
||||
withSizeLimit(800) {
|
||||
entity(as[String]) { _ ⇒
|
||||
complete(HttpResponse())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tests:
|
||||
def entityOfSize(size: Int) =
|
||||
HttpEntity(ContentTypes.`text/plain(UTF-8)`, "0" * size)
|
||||
Post("/abc", entityOfSize(800)) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.OK
|
||||
}
|
||||
|
||||
Post("/abc", entityOfSize(801)) ~> Route.seal(route) ~> check {
|
||||
status shouldEqual StatusCodes.BadRequest
|
||||
}
|
||||
}
|
||||
|
||||
"withoutSizeLimit-example" in {
|
||||
val route =
|
||||
withoutSizeLimit {
|
||||
entity(as[String]) { _ ⇒
|
||||
complete(HttpResponse())
|
||||
}
|
||||
}
|
||||
|
||||
// tests:
|
||||
def entityOfSize(size: Int) =
|
||||
HttpEntity(ContentTypes.`text/plain(UTF-8)`, "0" * size)
|
||||
|
||||
// will work even if you have configured akka.http.parsing.max-content-length = 500
|
||||
Post("/abc", entityOfSize(501)) ~> route ~> check {
|
||||
status shouldEqual StatusCodes.OK
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ Directive Description
|
|||
:ref:`-uploadedFile-` Streams one uploaded file from a multipart request to a file on disk
|
||||
:ref:`-validate-` Checks a given condition before running its inner route
|
||||
:ref:`-withoutRequestTimeout-` Disables :ref:`request timeouts <request-timeout-scala>` for a given route.
|
||||
:ref:`-withoutSizeLimit-` Skips request entity size check
|
||||
:ref:`-withExecutionContext-` Runs its inner route with the given alternative ``ExecutionContext``
|
||||
:ref:`-withMaterializer-` Runs its inner route with the given alternative ``Materializer``
|
||||
:ref:`-withLog-` Runs its inner route with the given alternative ``LoggingAdapter``
|
||||
|
|
@ -227,4 +228,5 @@ Directive Description
|
|||
:ref:`-withRequestTimeoutResponse-` Prepares the ``HttpResponse`` that is emitted if a request timeout is triggered.
|
||||
``RequestContext => RequestContext`` function
|
||||
:ref:`-withSettings-` Runs its inner route with the given alternative ``RoutingSettings``
|
||||
:ref:`-withSizeLimit-` Applies request entity size check
|
||||
=========================================== ============================================================================
|
||||
|
|
|
|||
|
|
@ -11,4 +11,6 @@ MiscDirectives
|
|||
requestEntityEmpty
|
||||
requestEntityPresent
|
||||
selectPreferredLanguage
|
||||
validate
|
||||
validate
|
||||
withoutSizeLimit
|
||||
withSizeLimit
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
.. _-withSizeLimit-:
|
||||
|
||||
withSizeLimit
|
||||
===============
|
||||
|
||||
Signature
|
||||
---------
|
||||
|
||||
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/MiscDirectives.scala
|
||||
:snippet: withSizeLimit
|
||||
|
||||
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 :ref:`-withoutSizeLimit-` for skipping request entity size check.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/MiscDirectivesExamplesSpec.scala
|
||||
:snippet: withSizeLimit-example
|
||||
|
||||
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):
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/MiscDirectivesExamplesSpec.scala
|
||||
:snippet: withSizeLimit-execution-moment-example
|
||||
|
||||
Directive ``withSizeLimit`` is implemented in terms of ``HttpEntity.withSizeLimit`` which means that in case of
|
||||
nested ``withSizeLimit`` directives the innermost is applied:
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/MiscDirectivesExamplesSpec.scala
|
||||
:snippet: withSizeLimit-nested-example
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
.. _-withoutSizeLimit-:
|
||||
|
||||
withoutSizeLimit
|
||||
================
|
||||
|
||||
Signature
|
||||
---------
|
||||
|
||||
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/MiscDirectives.scala
|
||||
:snippet: withoutSizeLimit
|
||||
|
||||
Description
|
||||
-----------
|
||||
Skips request entity size verification.
|
||||
|
||||
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 ``withoutSizeLimit``
|
||||
directive just for endpoints for which size verification should not be performed.
|
||||
|
||||
See also :ref:`-withSizeLimit-` for setting request entity size limit.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/MiscDirectivesExamplesSpec.scala
|
||||
:snippet: withoutSizeLimit-example
|
||||
Loading…
Add table
Add a link
Reference in a new issue