Skip to content

Commit da4363d

Browse files
committed
Implement getting well known properties in the jaxrs filter.
Signed-off-by: Hiram Chirino <hiram@hiramchirino.com>
1 parent c7c08ba commit da4363d

File tree

8 files changed

+266
-16
lines changed

8 files changed

+266
-16
lines changed

proxy-wasm-java-host/src/main/java/io/roastedroot/proxywasm/WellKnownProperties.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
import java.util.List;
44

5+
/**
6+
* Holds constants for the well-known properties defined by the Proxy-Wasm ABI.
7+
*
8+
* see: <a href="https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.1.0#well-known-properties">spec</a>
9+
*/
510
public final class WellKnownProperties {
611
private WellKnownProperties() {}
712

proxy-wasm-jaxrs/pom.xml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,30 @@
2626
</dependencyManagement>
2727

2828
<dependencies>
29+
<dependency>
30+
<groupId>io.quarkus</groupId>
31+
<artifactId>quarkus-arc</artifactId>
32+
<optional>true</optional>
33+
</dependency>
2934

3035
<dependency>
3136
<groupId>io.roastedroot</groupId>
3237
<artifactId>proxy-wasm-java-host</artifactId>
3338
<version>1.0-SNAPSHOT</version>
3439
</dependency>
40+
41+
<dependency>
42+
<groupId>io.vertx</groupId>
43+
<artifactId>vertx-core</artifactId>
44+
<optional>true</optional>
45+
</dependency>
46+
<dependency>
47+
<groupId>jakarta.servlet</groupId>
48+
<artifactId>jakarta.servlet-api</artifactId>
49+
<optional>true</optional>
50+
</dependency>
51+
52+
<!-- Depend on a minimal set of jakarta/jaxrs apis -->
3553
<dependency>
3654
<groupId>jakarta.enterprise</groupId>
3755
<artifactId>jakarta.enterprise.cdi-api</artifactId>
@@ -42,20 +60,13 @@
4260
<artifactId>jakarta.inject-api</artifactId>
4361
<scope>provided</scope>
4462
</dependency>
45-
46-
<!-- Depend on a minimal set of jakarta/jaxrs apis -->
4763
<dependency>
4864
<groupId>jakarta.ws.rs</groupId>
4965
<artifactId>jakarta.ws.rs-api</artifactId>
5066
<scope>provided</scope>
5167
</dependency>
5268

5369
<!-- Let's test with Quarkus -->
54-
<dependency>
55-
<groupId>io.quarkus</groupId>
56-
<artifactId>quarkus-arc</artifactId>
57-
<scope>test</scope>
58-
</dependency>
5970
<dependency>
6071
<groupId>io.quarkus</groupId>
6172
<artifactId>quarkus-junit5</artifactId>

proxy-wasm-jaxrs/src/main/java/io/roastedroot/proxywasm/jaxrs/HttpHandler.java

Lines changed: 135 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
11
package io.roastedroot.proxywasm.jaxrs;
22

3+
import static io.roastedroot.proxywasm.Helpers.bytes;
34
import static io.roastedroot.proxywasm.Helpers.string;
5+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_DNS_SAN_LOCAL_CERTIFICATE;
6+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_DNS_SAN_PEER_CERTIFICATE;
7+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_ID;
8+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_MTLS;
9+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_REQUESTED_SERVER_NAME;
10+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_SHA256_PEER_CERTIFICATE_DIGEST;
11+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_SUBJECT_LOCAL_CERTIFICATE;
12+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_SUBJECT_PEER_CERTIFICATE;
13+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_TLS_VERSION;
14+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_URI_SAN_LOCAL_CERTIFICATE;
15+
import static io.roastedroot.proxywasm.WellKnownProperties.CONNECTION_URI_SAN_PEER_CERTIFICATE;
16+
import static io.roastedroot.proxywasm.WellKnownProperties.DESTINATION_ADDRESS;
17+
import static io.roastedroot.proxywasm.WellKnownProperties.DESTINATION_PORT;
18+
import static io.roastedroot.proxywasm.WellKnownProperties.REQUEST_DURATION;
19+
import static io.roastedroot.proxywasm.WellKnownProperties.REQUEST_PROTOCOL;
20+
import static io.roastedroot.proxywasm.WellKnownProperties.REQUEST_SIZE;
21+
import static io.roastedroot.proxywasm.WellKnownProperties.REQUEST_TIME;
22+
import static io.roastedroot.proxywasm.WellKnownProperties.REQUEST_TOTAL_SIZE;
23+
import static io.roastedroot.proxywasm.WellKnownProperties.RESPONSE_SIZE;
24+
import static io.roastedroot.proxywasm.WellKnownProperties.RESPONSE_TOTAL_SIZE;
25+
import static io.roastedroot.proxywasm.WellKnownProperties.SOURCE_ADDRESS;
26+
import static io.roastedroot.proxywasm.WellKnownProperties.SOURCE_PORT;
427

528
import io.roastedroot.proxywasm.Action;
629
import io.roastedroot.proxywasm.ChainedHandler;
@@ -10,18 +33,24 @@
1033
import io.roastedroot.proxywasm.StreamType;
1134
import io.roastedroot.proxywasm.WasmException;
1235
import io.roastedroot.proxywasm.WasmResult;
36+
import io.roastedroot.proxywasm.jaxrs.spi.HttpServer;
1337
import jakarta.ws.rs.container.ContainerRequestContext;
1438
import jakarta.ws.rs.container.ContainerResponseContext;
1539
import jakarta.ws.rs.core.Response;
40+
import java.util.Date;
1641
import java.util.HashMap;
1742
import java.util.List;
1843

1944
class HttpHandler extends ChainedHandler {
2045

2146
private final PluginHandler next;
47+
private final HttpServer httpServer;
48+
private final long startedAt;
2249

23-
HttpHandler(PluginHandler pluginHandler) {
50+
HttpHandler(PluginHandler pluginHandler, HttpServer httpServer) {
2451
this.next = pluginHandler;
52+
this.httpServer = httpServer;
53+
this.startedAt = System.currentTimeMillis();
2554
}
2655

2756
@Override
@@ -237,11 +266,113 @@ public Action getAction() {
237266

238267
@Override
239268
public byte[] getProperty(List<String> path) throws WasmException {
269+
270+
// Check to see if it's a well known property
271+
272+
// Downstream connection properties
273+
if (CONNECTION_ID.equals(path)) {
274+
// Do we need to generate one?
275+
return null;
276+
} else if (SOURCE_ADDRESS.equals(path)) {
277+
return bytes(httpServer.remoteAddress());
278+
} else if (SOURCE_PORT.equals(path)) {
279+
return bytes(httpServer.remotePort());
280+
} else if (DESTINATION_ADDRESS.equals(path)) {
281+
return bytes(httpServer.localAddress());
282+
} else if (DESTINATION_PORT.equals(path)) {
283+
return bytes(httpServer.localPort());
284+
}
285+
286+
// TLS connection properties
287+
else if (CONNECTION_TLS_VERSION.equals(path)) {
288+
return null;
289+
} else if (CONNECTION_REQUESTED_SERVER_NAME.equals(path)) {
290+
return null;
291+
} else if (CONNECTION_MTLS.equals(path)) {
292+
return null;
293+
} else if (CONNECTION_SUBJECT_LOCAL_CERTIFICATE.equals(path)) {
294+
return null;
295+
} else if (CONNECTION_SUBJECT_PEER_CERTIFICATE.equals(path)) {
296+
return null;
297+
} else if (CONNECTION_DNS_SAN_LOCAL_CERTIFICATE.equals(path)) {
298+
return null;
299+
} else if (CONNECTION_DNS_SAN_PEER_CERTIFICATE.equals(path)) {
300+
return null;
301+
} else if (CONNECTION_URI_SAN_LOCAL_CERTIFICATE.equals(path)) {
302+
return null;
303+
} else if (CONNECTION_URI_SAN_PEER_CERTIFICATE.equals(path)) {
304+
return null;
305+
} else if (CONNECTION_SHA256_PEER_CERTIFICATE_DIGEST.equals(path)) {
306+
return null;
307+
}
308+
309+
// Upstream connection properties: we are not directly connecting to an upstream server, so
310+
// these are not implemented.
311+
// else if (UPSTREAM_ADDRESS.equals(path)) {
312+
// return null;
313+
// } else if (UPSTREAM_PORT.equals(path)) {
314+
// return null;
315+
// } else if (UPSTREAM_LOCAL_ADDRESS.equals(path)) {
316+
// return null;
317+
// } else if (UPSTREAM_LOCAL_PORT.equals(path)) {
318+
// return null;
319+
// } else if (UPSTREAM_TLS_VERSION.equals(path)) {
320+
// return null;
321+
// } else if (UPSTREAM_SUBJECT_LOCAL_CERTIFICATE.equals(path)) {
322+
// return null;
323+
// } else if (UPSTREAM_SUBJECT_PEER_CERTIFICATE.equals(path)) {
324+
// return null;
325+
// } else if (UPSTREAM_DNS_SAN_LOCAL_CERTIFICATE.equals(path)) {
326+
// return null;
327+
// } else if (UPSTREAM_DNS_SAN_PEER_CERTIFICATE.equals(path)) {
328+
// return null;
329+
// } else if (UPSTREAM_URI_SAN_LOCAL_CERTIFICATE.equals(path)) {
330+
// return null;
331+
// } else if (UPSTREAM_URI_SAN_PEER_CERTIFICATE.equals(path)) {
332+
// return null;
333+
// } else if (UPSTREAM_SHA256_PEER_CERTIFICATE_DIGEST.equals(path)) {
334+
// return null;
335+
// }
336+
337+
// HTTP request properties
338+
else if (REQUEST_PROTOCOL.equals(path)) {
339+
if (requestContext == null) {
340+
return null;
341+
}
342+
return bytes(requestContext.getUriInfo().getRequestUri().getScheme());
343+
} else if (REQUEST_TIME.equals(path)) {
344+
// TODO: check encoding /w other impls
345+
return bytes(new Date(startedAt).toString());
346+
} else if (REQUEST_DURATION.equals(path)) {
347+
// TODO: check encoding /w other impls
348+
return bytes("" + (System.currentTimeMillis() - startedAt));
349+
} else if (REQUEST_SIZE.equals(path)) {
350+
if (httpRequestBody == null) {
351+
return null;
352+
}
353+
// TODO: check encoding /w other impls
354+
return bytes("" + httpRequestBody.length);
355+
} else if (REQUEST_TOTAL_SIZE.equals(path)) {
356+
return null;
357+
}
358+
359+
// HTTP response properties
360+
else if (RESPONSE_SIZE.equals(path)) {
361+
if (httpResponseBody == null) {
362+
return null;
363+
}
364+
// TODO: check encoding /w other impls
365+
return bytes("" + httpResponseBody.length);
366+
} else if (RESPONSE_TOTAL_SIZE.equals(path)) {
367+
// TODO: how can we do this?
368+
return null;
369+
}
370+
240371
byte[] result = properties.get(path);
241-
if (result == null) {
242-
return next().getProperty(path);
372+
if (result != null) {
373+
return result;
243374
}
244-
return result;
375+
return next().getProperty(path);
245376
}
246377

247378
@Override

proxy-wasm-jaxrs/src/main/java/io/roastedroot/proxywasm/jaxrs/ProxyWasmFilter.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import io.roastedroot.proxywasm.Action;
44
import io.roastedroot.proxywasm.HttpContext;
55
import io.roastedroot.proxywasm.StartException;
6+
import io.roastedroot.proxywasm.jaxrs.spi.HttpServer;
7+
import jakarta.enterprise.inject.Instance;
68
import jakarta.inject.Inject;
79
import jakarta.ws.rs.WebApplicationException;
810
import jakarta.ws.rs.container.ContainerRequestContext;
@@ -28,9 +30,12 @@ public class ProxyWasmFilter
2830

2931
private final WasmPluginFactory pluginFactory;
3032

33+
Instance<HttpServer> httpServer;
34+
3135
@Inject
32-
public ProxyWasmFilter(WasmPluginFactory pluginFactory) {
36+
public ProxyWasmFilter(WasmPluginFactory pluginFactory, Instance<HttpServer> httpServer) {
3337
this.pluginFactory = pluginFactory;
38+
this.httpServer = httpServer;
3439
}
3540

3641
// TODO: the HttpContext and ProxyWasm object's should be closed once the request is done.
@@ -40,9 +45,9 @@ static class WasmHttpFilterContext {
4045
final HttpHandler handler;
4146
final HttpContext wasm;
4247

43-
public WasmHttpFilterContext(WasmPlugin plugin) {
48+
public WasmHttpFilterContext(WasmPlugin plugin, HttpServer httpServer) {
4449
this.pluginHandler = plugin.pluginHandler();
45-
this.handler = new HttpHandler(plugin.pluginHandler());
50+
this.handler = new HttpHandler(plugin.pluginHandler(), httpServer);
4651
this.wasm = plugin.proxyWasm().createHttpContext(this.handler);
4752
}
4853
}
@@ -58,7 +63,7 @@ public void filter(ContainerRequestContext requestContext) throws IOException {
5863
Response.status(Response.Status.INTERNAL_SERVER_ERROR).build());
5964
}
6065

61-
var wasmHttpFilterContext = new WasmHttpFilterContext(plugin);
66+
var wasmHttpFilterContext = new WasmHttpFilterContext(plugin, this.httpServer.get());
6267
requestContext.setProperty(FILTER_CONTEXT_PROPERTY_NAME, wasmHttpFilterContext);
6368

6469
// the plugin may not be interested in the request headers.

proxy-wasm-jaxrs/src/main/java/io/roastedroot/proxywasm/jaxrs/WasmPluginFeature.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.roastedroot.proxywasm.jaxrs;
22

33
import io.roastedroot.proxywasm.StartException;
4+
import io.roastedroot.proxywasm.jaxrs.spi.HttpServer;
45
import jakarta.enterprise.inject.Any;
56
import jakarta.enterprise.inject.Instance;
67
import jakarta.inject.Inject;
@@ -15,6 +16,8 @@ public class WasmPluginFeature implements DynamicFeature {
1516

1617
private HashMap<String, WasmPluginFactory> plugins = new HashMap<>();
1718

19+
@Inject @Any Instance<HttpServer> requestAdaptor;
20+
1821
@Inject
1922
public WasmPluginFeature(@Any Instance<WasmPluginFactory> factories) throws StartException {
2023
for (var factory : factories) {
@@ -41,7 +44,7 @@ public void configure(ResourceInfo resourceInfo, FeatureContext context) {
4144
if (pluignNameAnnotation != null) {
4245
WasmPluginFactory factory = plugins.get(pluignNameAnnotation.value());
4346
if (factory != null) {
44-
context.register(new ProxyWasmFilter(factory));
47+
context.register(new ProxyWasmFilter(factory, requestAdaptor));
4548
}
4649
}
4750
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.roastedroot.proxywasm.jaxrs.servlet;
2+
3+
import io.roastedroot.proxywasm.jaxrs.spi.HttpServer;
4+
import jakarta.annotation.Priority;
5+
import jakarta.enterprise.inject.Alternative;
6+
import jakarta.enterprise.inject.Instance;
7+
import jakarta.servlet.http.HttpServletRequest;
8+
import jakarta.ws.rs.core.Context;
9+
10+
@Alternative
11+
@Priority(100)
12+
public class ServletHttpServer implements HttpServer {
13+
14+
private final HttpServletRequest request;
15+
16+
public ServletHttpServer(@Context Instance<HttpServletRequest> request) {
17+
this.request = request.get();
18+
}
19+
20+
@Override
21+
public String remoteAddress() {
22+
return request.getRemoteAddr();
23+
}
24+
25+
@Override
26+
public String remotePort() {
27+
return "" + request.getRemotePort();
28+
}
29+
30+
@Override
31+
public String localAddress() {
32+
return request.getLocalAddr();
33+
}
34+
35+
@Override
36+
public String localPort() {
37+
return "" + request.getLocalPort();
38+
}
39+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.roastedroot.proxywasm.jaxrs.spi;
2+
3+
/**
4+
* This interface will help us deal with differences in the http server impl.
5+
*/
6+
public interface HttpServer {
7+
8+
String remoteAddress();
9+
10+
String remotePort();
11+
12+
String localAddress();
13+
14+
String localPort();
15+
}

0 commit comments

Comments
 (0)