Skip to content

Commit 5e44cae

Browse files
vietjtsegismont
andauthored
Unified head interception (#104)
* Unified head interception Motivation: The new interceptors for changing request/response head each do a separate change yet they only modify the request/response head. We should instead have a single interceptor that can implement all of them a batch the modification of the head in a single interceptor. The builder pattern can be used to build such interceptor with the desired modification of the developer Changes: A new HeadInterceptor with a builder that aggregates the existing head individual interceptors. * Make HeadInterceptor operations additive The builder configuration methods can be invoked several times. Signed-off-by: Thomas Segismont <tsegismont@gmail.com> * Add a note in the documentation about builder methods - Can be invoked several times - Operations are invoked in the order of configuration Signed-off-by: Thomas Segismont <tsegismont@gmail.com> --------- Signed-off-by: Thomas Segismont <tsegismont@gmail.com> Co-authored-by: Thomas Segismont <tsegismont@gmail.com>
1 parent 653f9a2 commit 5e44cae

16 files changed

+468
-332
lines changed

src/main/asciidoc/index.adoc

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,27 +143,41 @@ You can change the control, e.g you can send a response immediately to the user-
143143
{@link examples.HttpProxyExamples#immediateResponse}
144144
----
145145

146-
==== Header interceptor
146+
==== Head interceptor
147147

148-
You can apply header interceptors to change headers from the request and response with common operations:
148+
You can use the {@link io.vertx.httpproxy.interceptors.HeadInterceptor} to change HTTP request/response heads:
149+
150+
- request path
151+
- query params
152+
- request and response headers
153+
154+
A {@link io.vertx.httpproxy.interceptors.HeadInterceptor} is created and configured with a {@link io.vertx.httpproxy.interceptors.HeadInterceptorBuilder}.
155+
156+
The builder methods can be invoked several times.
157+
Operations on the path will be invoked in the order of configuration.
158+
That goes for operations on query parameters, request headers and response headers.
159+
160+
===== Headers interception
161+
162+
You can apply the interceptor to change headers from the request and response with common operations:
149163

150164
[source,java]
151165
----
152166
{@link examples.HttpProxyExamples#headerInterceptorFilter}
153167
----
154168

155-
Check out the {@link io.vertx.httpproxy.interceptors.HeadersInterceptor} class for details about the available methods.
169+
Check out {@link io.vertx.httpproxy.interceptors.HeadInterceptorBuilder} for details about the available methods.
156170

157-
==== Query interceptor
171+
===== Query params interception
158172

159-
You can use query interceptors to update or remove the query parameters:
173+
You can apply the interceptor to update or remove query parameters:
160174

161175
[source,java]
162176
----
163177
{@link examples.HttpProxyExamples#queryInterceptorAdd}
164178
----
165179

166-
You can also refer to {@link io.vertx.httpproxy.interceptors.QueryInterceptor} for more information.
180+
You can also refer to {@link io.vertx.httpproxy.interceptors.HeadInterceptorBuilder} for more information.
167181

168182
==== Body interceptor
169183

src/main/java/examples/HttpProxyExamples.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ public Future<Void> handleProxyResponse(ProxyContext context) {
109109
public void headerInterceptorFilter(HttpProxy proxy, Set<CharSequence> shouldRemove) {
110110
// remove a set of headers
111111
proxy.addInterceptor(
112-
HeadersInterceptor.filterResponseHeaders(shouldRemove));
112+
HeadInterceptor.builder().filteringResponseHeaders(shouldRemove).build());
113113
}
114114

115115
public void queryInterceptorAdd(HttpProxy proxy, String key, String value) {
116116
proxy.addInterceptor(
117-
QueryInterceptor.setQueryParam(key, value));
117+
HeadInterceptor.builder().settingQueryParam(key, value).build());
118118
}
119119

120120
public void bodyInterceptorJson(HttpProxy proxy) {
@@ -128,7 +128,7 @@ public void bodyInterceptorJson(HttpProxy proxy) {
128128

129129
public void webSocketInterceptorPath(HttpProxy proxy) {
130130
proxy.addInterceptor(
131-
WebSocketInterceptor.allow(PathInterceptor.addPrefix("/api"))
131+
WebSocketInterceptor.allow(HeadInterceptor.builder().addingPathPrefix("/api").build())
132132
);
133133
}
134134

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2011-2024 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
package io.vertx.httpproxy.interceptors;
12+
13+
import io.vertx.codegen.annotations.Unstable;
14+
import io.vertx.codegen.annotations.VertxGen;
15+
import io.vertx.httpproxy.ProxyInterceptor;
16+
import io.vertx.httpproxy.interceptors.impl.HeadInterceptorBuilderImpl;
17+
18+
/**
19+
* An interceptor updating HTTP request/response head attributes (headers, path, query params).
20+
*/
21+
@VertxGen
22+
@Unstable
23+
public interface HeadInterceptor extends ProxyInterceptor {
24+
25+
/**
26+
* @return a builder for head interception
27+
*/
28+
static HeadInterceptorBuilder builder() {
29+
return new HeadInterceptorBuilderImpl();
30+
}
31+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) 2011-2024 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
12+
package io.vertx.httpproxy.interceptors;
13+
14+
import io.vertx.codegen.annotations.Fluent;
15+
import io.vertx.codegen.annotations.GenIgnore;
16+
import io.vertx.codegen.annotations.Unstable;
17+
import io.vertx.codegen.annotations.VertxGen;
18+
import io.vertx.core.Handler;
19+
import io.vertx.core.MultiMap;
20+
21+
import java.util.Set;
22+
import java.util.function.Function;
23+
24+
import static io.vertx.codegen.annotations.GenIgnore.PERMITTED_TYPE;
25+
26+
/**
27+
* Configuration for an interceptor updating HTTP request/response head attributes (headers, path, query params).
28+
* <p>
29+
* All configuration methods can be invoked several times.
30+
* Operations on the path will be invoked in the order of configuration.
31+
* That goes for operations on request headers, response headers and query parameters.
32+
*/
33+
@VertxGen
34+
@Unstable
35+
public interface HeadInterceptorBuilder {
36+
37+
/**
38+
* @return an interceptor build according to builder requirements
39+
*/
40+
HeadInterceptor build();
41+
42+
/**
43+
* Apply modifications to the query parameters.
44+
*
45+
* @param updater the operation to apply to the request query parameters (can be null, but in this case nothing happens)
46+
* @return a reference to this, so the API can be used fluently
47+
*/
48+
@Fluent
49+
HeadInterceptorBuilder updatingQueryParams(Handler<MultiMap> updater);
50+
51+
/**
52+
* Add a query parameter to the request.
53+
*
54+
* @param name the parameter name (can be null, but in this case nothing happens)
55+
* @param value the parameter value (can be null, but in this case nothing happens)
56+
* @return a reference to this, so the API can be used fluently
57+
*/
58+
@Fluent
59+
HeadInterceptorBuilder settingQueryParam(String name, String value);
60+
61+
/**
62+
* Remove a query parameter from the request.
63+
*
64+
* @param name the parameter name (can be null, but in this case nothing happens)
65+
* @return a reference to this, so the API can be used fluently
66+
*/
67+
@Fluent
68+
HeadInterceptorBuilder removingQueryParam(String name);
69+
70+
/**
71+
* Apply a callback to change the request URI when the proxy receives it.
72+
*
73+
* @param mutator the operation that applied to the path (can be null, but in this case nothing happens)
74+
* @return a reference to this, so the API can be used fluently
75+
*/
76+
@Fluent
77+
HeadInterceptorBuilder updatingPath(Function<String, String> mutator);
78+
79+
/**
80+
* Add a prefix to the URI.
81+
*
82+
* @param prefix the prefix that need to be added (can be null, but in this case nothing happens)
83+
* @return a reference to this, so the API can be used fluently
84+
*/
85+
@Fluent
86+
HeadInterceptorBuilder addingPathPrefix(String prefix);
87+
88+
/**
89+
* Remove a prefix to the URI. Do nothing if it doesn't exist.
90+
*
91+
* @param prefix the prefix that need to be removed (can be null, but in this case nothing happens)
92+
* @return a reference to this, so the API can be used fluently
93+
*/
94+
@Fluent
95+
HeadInterceptorBuilder removingPathPrefix(String prefix);
96+
97+
/**
98+
* Apply callbacks to change the request headers when the proxy receives them.
99+
*
100+
* @param requestHeadersUpdater the operation to apply to the request headers (can be null, but in this case nothing happens)
101+
* @return a reference to this, so the API can be used fluently
102+
*/
103+
@Fluent
104+
HeadInterceptorBuilder updatingRequestHeaders(Handler<MultiMap> requestHeadersUpdater);
105+
106+
/**
107+
* Apply callbacks to change the response headers when the proxy receives them.
108+
*
109+
* @param responseHeadersUpdater the operation to apply to the response headers (can be null, but in this case nothing happens)
110+
* @return a reference to this, so the API can be used fluently
111+
*/
112+
@Fluent
113+
HeadInterceptorBuilder updatingResponseHeaders(Handler<MultiMap> responseHeadersUpdater);
114+
115+
/**
116+
* Filter the request headers in the given set.
117+
*
118+
* @param forbiddenRequestHeaders a set of the headers that need to be filtered (can be null, but in this case nothing happens)
119+
* @return a reference to this, so the API can be used fluently
120+
*/
121+
@GenIgnore(PERMITTED_TYPE)
122+
@Fluent
123+
HeadInterceptorBuilder filteringRequestHeaders(Set<CharSequence> forbiddenRequestHeaders);
124+
125+
/**
126+
* Filter the response headers in the given set.
127+
*
128+
* @param forbiddenResponseHeaders a set of the headers that need to be filtered (can be null, but in this case nothing happens)
129+
* @return a reference to this, so the API can be used fluently
130+
*/
131+
@GenIgnore(PERMITTED_TYPE)
132+
@Fluent
133+
HeadInterceptorBuilder filteringResponseHeaders(Set<CharSequence> forbiddenResponseHeaders);
134+
}

src/main/java/io/vertx/httpproxy/interceptors/HeadersInterceptor.java

Lines changed: 0 additions & 77 deletions
This file was deleted.

src/main/java/io/vertx/httpproxy/interceptors/PathInterceptor.java

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)