Browse Source

Adds AddRequestParameter

pull/41/head
Spencer Gibb 8 years ago
parent
commit
5c5fbcab46
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 6
      src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
  2. 138
      src/main/java/org/springframework/cloud/gateway/filter/route/AddRequestParameterRouteFilter.java
  3. 53
      src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java
  4. 9
      src/test/resources/application.yml

6
src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@ -13,6 +13,7 @@ import org.springframework.cloud.gateway.filter.GlobalFilter; @@ -13,6 +13,7 @@ import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter;
import org.springframework.cloud.gateway.filter.WriteResponseFilter;
import org.springframework.cloud.gateway.filter.route.AddRequestHeaderRouteFilter;
import org.springframework.cloud.gateway.filter.route.AddRequestParameterRouteFilter;
import org.springframework.cloud.gateway.filter.route.AddResponseHeaderRouteFilter;
import org.springframework.cloud.gateway.filter.route.RemoveRequestHeaderRouteFilter;
import org.springframework.cloud.gateway.filter.route.RemoveResponseHeaderRouteFilter;
@ -130,6 +131,11 @@ public class GatewayAutoConfiguration { @@ -130,6 +131,11 @@ public class GatewayAutoConfiguration {
return new AddRequestHeaderRouteFilter();
}
@Bean(name = "AddRequestParameterRouteFilter")
public AddRequestParameterRouteFilter addRequestParameterRouteFilter() {
return new AddRequestParameterRouteFilter();
}
@Bean(name = "AddResponseHeaderRouteFilter")
public AddResponseHeaderRouteFilter addResponseHeaderRouteFilter() {
return new AddResponseHeaderRouteFilter();

138
src/main/java/org/springframework/cloud/gateway/filter/route/AddRequestParameterRouteFilter.java

@ -0,0 +1,138 @@ @@ -0,0 +1,138 @@
package org.springframework.cloud.gateway.filter.route;
import java.net.URI;
import java.net.URISyntaxException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.server.WebFilter;
/**
* @author Spencer Gibb
*/
public class AddRequestParameterRouteFilter implements RouteFilter {
@Override
public WebFilter apply(String parameter, String[] args) {
validate(args, 1);
//TODO: caching can happen here
return (exchange, chain) -> {
URI uri = exchange.getRequest().getURI();
StringBuilder query = new StringBuilder();
String originalQuery = uri.getQuery();
if (StringUtils.hasText(originalQuery)) {
query.append(originalQuery);
if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
query.append('&');
}
}
//TODO urlencode?
query.append(parameter);
query.append('=');
query.append(args[0]);
ServerHttpRequest request = new QueryParamServerHttpRequestBuilder(exchange.getRequest())
.query(query.toString())
.build();
return chain.filter(exchange.mutate().request(request).build());
};
}
class QueryParamServerHttpRequestBuilder implements ServerHttpRequest.Builder {
private final ServerHttpRequest delegate;
private String query;
public QueryParamServerHttpRequestBuilder(ServerHttpRequest delegate) {
Assert.notNull(delegate, "ServerHttpRequest delegate is required");
this.delegate = delegate;
}
@Override
public ServerHttpRequest.Builder method(HttpMethod httpMethod) {
throw new UnsupportedOperationException();
}
@Override
public ServerHttpRequest.Builder path(String path) {
throw new UnsupportedOperationException();
}
public ServerHttpRequest.Builder query(String query) {
this.query = query;
return this;
}
@Override
public ServerHttpRequest.Builder contextPath(String contextPath) {
throw new UnsupportedOperationException();
}
@Override
public ServerHttpRequest.Builder header(String key, String value) {
throw new UnsupportedOperationException();
}
@Override
public ServerHttpRequest build() {
URI uri = null;
if (this.query != null) {
uri = this.delegate.getURI();
try {
uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
uri.getPath(), this.query, uri.getFragment());
} catch (URISyntaxException ex) {
throw new IllegalStateException("Invalid URI query: \"" + this.query + "\"");
}
}
return new MutativeDecorator(this.delegate, uri);
}
/**
* An immutable wrapper of a request returning property overrides -- given
* to the constructor -- or original values otherwise.
*/
private class MutativeDecorator extends ServerHttpRequestDecorator {
private final URI uri;
public MutativeDecorator(ServerHttpRequest delegate, URI uri) {
super(delegate);
this.uri = uri;
}
@Override
public HttpMethod getMethod() {
return super.getMethod();
}
@Override
public URI getURI() {
return (this.uri != null ? this.uri : super.getURI());
}
@Override
public String getContextPath() {
return super.getContextPath();
}
@Override
public HttpHeaders getHeaders() {
return super.getHeaders();
}
}
}
}

53
src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java

@ -45,6 +45,7 @@ public class GatewayIntegrationTests { @@ -45,6 +45,7 @@ public class GatewayIntegrationTests {
private static final String HANDLER_MAPPER_HEADER = "X-Gateway-Handler-Mapper-Class";
private static final String ROUTE_ID_HEADER = "X-Gateway-Route-Id";
public static final Duration DURATION = Duration.ofSeconds(3);
@LocalServerPort
private int port;
@ -100,7 +101,37 @@ public class GatewayIntegrationTests { @@ -100,7 +101,37 @@ public class GatewayIntegrationTests {
assertThat(headers).containsEntry("X-Request-Foo", "Bar");
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@Test
public void addRequestParameterFilterWorksBlankQuery() {
testRequestParameterFilter("");
}
@Test
public void addRequestParameterFilterWorksNonBlankQuery() {
testRequestParameterFilter("?baz=bam");
}
private void testRequestParameterFilter(String query) {
Mono<Map> result = webClient.exchange(
GET("http://localhost:" + port + "/get" + query)
.header("Host", "www.addrequestparameter.org")
.build()
).then(response -> response.body(toMono(Map.class)));
verify( () ->
StepVerifier.create(result)
.consumeNextWith(
response -> {
assertThat(response).containsKey("args").isInstanceOf(Map.class);
Map<String, Object> args = (Map<String, Object>) response.get("args");
assertThat(args).containsEntry("foo", "bar");
})
.expectComplete()
.verify(DURATION)
);
}
@ -121,7 +152,7 @@ public class GatewayIntegrationTests { @@ -121,7 +152,7 @@ public class GatewayIntegrationTests {
.isEqualTo("Bar");
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -175,7 +206,7 @@ public class GatewayIntegrationTests { @@ -175,7 +206,7 @@ public class GatewayIntegrationTests {
assertThat(statusCode).isEqualTo(HttpStatus.OK);
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -192,7 +223,7 @@ public class GatewayIntegrationTests { @@ -192,7 +223,7 @@ public class GatewayIntegrationTests {
StepVerifier.create(result)
.consumeNextWith(map -> assertThat(map).containsEntry("data", "testdata"))
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -215,7 +246,7 @@ public class GatewayIntegrationTests { @@ -215,7 +246,7 @@ public class GatewayIntegrationTests {
assertThat(headers).doesNotContainKey("X-Request-Foo");
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -235,7 +266,7 @@ public class GatewayIntegrationTests { @@ -235,7 +266,7 @@ public class GatewayIntegrationTests {
assertThat(httpHeaders).doesNotContainKey("X-Request-Foo");
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -255,7 +286,7 @@ public class GatewayIntegrationTests { @@ -255,7 +286,7 @@ public class GatewayIntegrationTests {
assertThat(statusCode).isEqualTo(HttpStatus.OK);
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -275,7 +306,7 @@ public class GatewayIntegrationTests { @@ -275,7 +306,7 @@ public class GatewayIntegrationTests {
assertThat(statusCode).isEqualTo(HttpStatus.OK);
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -296,7 +327,7 @@ public class GatewayIntegrationTests { @@ -296,7 +327,7 @@ public class GatewayIntegrationTests {
assertThat(httpHeaders.get("X-Request-Foo")).containsExactly("Bar");
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -325,7 +356,7 @@ public class GatewayIntegrationTests { @@ -325,7 +356,7 @@ public class GatewayIntegrationTests {
assertThat(statusCode).isEqualTo(status);
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}
@ -348,7 +379,7 @@ public class GatewayIntegrationTests { @@ -348,7 +379,7 @@ public class GatewayIntegrationTests {
assertThat(statusCode).isEqualTo(HttpStatus.OK);
})
.expectComplete()
.verify(Duration.ofSeconds(3))
.verify(DURATION)
);
}

9
src/test/resources/application.yml

@ -29,6 +29,15 @@ spring: @@ -29,6 +29,15 @@ spring:
filters:
- AddRequestHeader=X-Request-Foo, Bar
# =====================================
- id: add_request_parameter_test
uri: http://httpbin.org:80
predicates:
- Host=**.addrequestparameter.org
- Url=/get
filters:
- AddRequestParameter=foo, bar
# =====================================
- id: add_response_header_test
uri: http://httpbin.org:80

Loading…
Cancel
Save