Skip to content

Commit

Permalink
feat(api): Define response templates to override policy response
Browse files Browse the repository at this point in the history
  • Loading branch information
brasseld committed Apr 16, 2019
1 parent bcf670e commit 0ce8c75
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 16 deletions.
39 changes: 38 additions & 1 deletion README.adoc
Expand Up @@ -47,4 +47,41 @@ You can configure the policy with the following options :
"request-content-limit": {
"limit": 1000
}
----
----

== Errors

=== Default error
|===
|Code |Message

.^| ```400```
| The limit from the configuration is not correct.

.^| ```413```
| Incoming HTTP request payload exceed the size limit.

.^| ```411```
| The HTTP request is not chunked and does not specify the `Content-Length` header.

|===

=== Override errors
If you're looking to override the default response provided by the policy, you can do it
thanks to the response templates feature. These templates must be define at the API level (see `Response Templates`
from the `Proxy` menu).

Here are the error keys send by this policy:

[cols="2*", options="header"]
|===
^|Key
^|Parameters

.^|REQUEST_CONTENT_LIMIT_TOO_LARGE
^.^|length - limit

.^|REQUEST_CONTENT_LIMIT_LENGTH_REQUIRED
^.^|limit

|===
10 changes: 9 additions & 1 deletion pom.xml
Expand Up @@ -35,7 +35,8 @@

<properties>
<gravitee-gateway-api.version>1.14.0</gravitee-gateway-api.version>
<gravitee-policy-api.version>1.4.0</gravitee-policy-api.version>
<gravitee-policy-api.version>1.5.0-SNAPSHOT</gravitee-policy-api.version>
<gravitee-common.version>1.15.0-SNAPSHOT</gravitee-common.version>

<json-schema-generator-maven-plugin.version>1.1.0</json-schema-generator-maven-plugin.version>
<json-schema-generator-maven-plugin.outputDirectory>${project.build.directory}/schemas</json-schema-generator-maven-plugin.outputDirectory>
Expand All @@ -59,6 +60,13 @@
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.gravitee.common</groupId>
<artifactId>gravitee-common</artifactId>
<version>${gravitee-common.version}</version>
<scope>provided</scope>
</dependency>

<!-- Jackson dependencies -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
Expand Down
42 changes: 31 additions & 11 deletions src/main/java/io/gravitee/policy/rcl/RequestContentLimitPolicy.java
Expand Up @@ -17,6 +17,7 @@

import io.gravitee.common.http.HttpHeaders;
import io.gravitee.common.http.HttpStatusCode;
import io.gravitee.common.util.Maps;
import io.gravitee.gateway.api.Request;
import io.gravitee.gateway.api.Response;
import io.gravitee.gateway.api.buffer.Buffer;
Expand All @@ -42,6 +43,9 @@ public class RequestContentLimitPolicy {
*/
private final static Logger LOGGER = LoggerFactory.getLogger(RequestContentLimitPolicy.class);

private static final String REQUEST_CONTENT_LIMIT_TOO_LARGE = "REQUEST_CONTENT_LIMIT_TOO_LARGE";
private static final String REQUEST_CONTENT_LIMIT_LENGTH_REQUIRED = "REQUEST_CONTENT_LIMIT_LENGTH_REQUIRED";

/**
* Request content limit configuration
*/
Expand All @@ -61,9 +65,15 @@ public void onRequest(Request request, Response response, PolicyChain policyChai
int contentLength = Integer.parseInt(contentLengthHeader);

if (contentLength > requestContentLimitPolicyConfiguration.getLimit()) {
policyChain.failWith(PolicyResult.failure(
HttpStatusCode.REQUEST_ENTITY_TOO_LARGE_413,
"The request is larger than the server is willing or able to process."));
policyChain.failWith(
PolicyResult.failure(
REQUEST_CONTENT_LIMIT_TOO_LARGE,
HttpStatusCode.REQUEST_ENTITY_TOO_LARGE_413,
"The request is larger than the server is willing or able to process.",
Maps.<String, Object>builder()
.put("length", contentLength)
.put("limit", requestContentLimitPolicyConfiguration.getLimit())
.build()));
} else {
policyChain.doNext(request, response);
}
Expand All @@ -76,10 +86,15 @@ public void onRequest(Request request, Response response, PolicyChain policyChai
// Chunked transfer encoding, the content-length is not specified, just return the policy chain
policyChain.doNext(request, response);
} else {
policyChain.failWith(PolicyResult.failure(
HttpStatusCode.LENGTH_REQUIRED_411,
"The request did not specify the length of its content, which is required by the " +
"requested resource."));
policyChain.failWith(
PolicyResult.failure(
REQUEST_CONTENT_LIMIT_LENGTH_REQUIRED,
HttpStatusCode.LENGTH_REQUIRED_411,
"The request did not specify the length of its content, which is required by the " +
"requested resource.",
Maps.<String, Object>builder()
.put("limit", requestContentLimitPolicyConfiguration.getLimit())
.build()));
}
}

Expand All @@ -96,10 +111,15 @@ public SimpleReadWriteStream<Buffer> write(Buffer content) {
contentLength += content.length();

if (contentLength > requestContentLimitPolicyConfiguration.getLimit()) {
policyChain.streamFailWith(PolicyResult.failure(
HttpStatusCode.REQUEST_ENTITY_TOO_LARGE_413,
"The request is larger than the server is willing or able to process."
));
policyChain.streamFailWith(
PolicyResult.failure(
REQUEST_CONTENT_LIMIT_TOO_LARGE,
HttpStatusCode.REQUEST_ENTITY_TOO_LARGE_413,
"The request is larger than the server is willing or able to process.",
Maps.<String, Object>builder()
.put("length", contentLength)
.put("limit", requestContentLimitPolicyConfiguration.getLimit())
.build()));

return this;
} else {
Expand Down
Expand Up @@ -66,7 +66,7 @@ public void shouldReturn_411_length_required() {

ArgumentCaptor<PolicyResult> argument = ArgumentCaptor.forClass(PolicyResult.class);
verify(policyChain, times(1)).failWith(argument.capture());
Assert.assertEquals(HttpStatusCode.LENGTH_REQUIRED_411, argument.getValue().httpStatusCode());
Assert.assertEquals(HttpStatusCode.LENGTH_REQUIRED_411, argument.getValue().statusCode());
}

@Test
Expand All @@ -80,7 +80,7 @@ public void shouldReturn_400_bad_request() {

ArgumentCaptor<PolicyResult> argument = ArgumentCaptor.forClass(PolicyResult.class);
verify(policyChain, times(1)).failWith(argument.capture());
Assert.assertEquals(HttpStatusCode.BAD_REQUEST_400, argument.getValue().httpStatusCode());
Assert.assertEquals(HttpStatusCode.BAD_REQUEST_400, argument.getValue().statusCode());
}

@Test
Expand All @@ -107,7 +107,7 @@ public void shouldReturn_413_entity_too_large() {

ArgumentCaptor<PolicyResult> argument = ArgumentCaptor.forClass(PolicyResult.class);
verify(policyChain, times(1)).failWith(argument.capture());
Assert.assertEquals(HttpStatusCode.REQUEST_ENTITY_TOO_LARGE_413, argument.getValue().httpStatusCode());
Assert.assertEquals(HttpStatusCode.REQUEST_ENTITY_TOO_LARGE_413, argument.getValue().statusCode());
}

@Test
Expand Down

0 comments on commit 0ce8c75

Please sign in to comment.