Skip to content

Commit 2caae2c

Browse files
committed
Add an example that uses the Coraza waf.
- handle getting well known request/response headers. - encode source/destination ports as 8 bytes little endian. - better handle the case when jaxrs resource responds without a resource Signed-off-by: Hiram Chirino <hiram@hiramchirino.com>
1 parent 0569682 commit 2caae2c

File tree

26 files changed

+759
-56
lines changed

26 files changed

+759
-56
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ To build the project, you need to have Maven installed. You can build the projec
1010
mvn clean install
1111
```
1212

13-
## Quarkus Example
13+
## Quarkus Example
1414

1515
The `quarkus-proxy-wasm-example` directory contains a simple example of how to use the proxy-wasm Java host with Quarkus.
1616

@@ -35,7 +35,7 @@ public class Resources {
3535
}
3636
```
3737

38-
The `WasmPlugin` annotation is used to specify the name of the plugin to be used for filtering.
38+
The `WasmPlugin` annotation is used to specify the name of the plugin to be used for filtering.
3939

4040
```java
4141
package io.roastedroot.proxywasm.jaxrs.example;

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@
234234
<modules>
235235
<module>quarkus-proxy-wasm</module>
236236
<module>quarkus-proxy-wasm-example</module>
237+
<module>quarkus-x-corazawaf-example</module>
237238
</modules>
238239
</profile>
239240
</profiles>

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

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

33
import com.dylibso.chicory.runtime.HostFunction;
4+
import java.nio.ByteBuffer;
5+
import java.nio.ByteOrder;
46
import java.nio.charset.StandardCharsets;
57
import java.time.Duration;
68
import java.util.ArrayList;
@@ -45,20 +47,31 @@ public static byte[] bytes(Duration value) {
4547
}
4648

4749
public static byte[] bytes(int value) {
48-
// TODO: test to check byte order
49-
return new byte[] {
50-
(byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value
51-
};
50+
return ByteBuffer.allocate(Integer.BYTES)
51+
.order(ByteOrder.LITTLE_ENDIAN)
52+
.putInt(value)
53+
.array();
54+
}
55+
56+
public static byte[] bytes(long value) {
57+
return ByteBuffer.allocate(Long.BYTES)
58+
.order(ByteOrder.LITTLE_ENDIAN)
59+
.putLong(value)
60+
.array();
5261
}
5362

5463
public static int int32(byte[] bytes) {
5564
if (bytes == null || bytes.length != 4) {
5665
throw new IllegalArgumentException("Byte array must be exactly 4 bytes long");
5766
}
58-
return ((bytes[0] & 0xFF) << 24)
59-
| ((bytes[1] & 0xFF) << 16)
60-
| ((bytes[2] & 0xFF) << 8)
61-
| (bytes[3] & 0xFF);
67+
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt();
68+
}
69+
70+
public static long int64(byte[] bytes) {
71+
if (bytes == null || bytes.length != 8) {
72+
throw new IllegalArgumentException("Byte array must be exactly 8 bytes long");
73+
}
74+
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong();
6275
}
6376

6477
public static String string(byte[] value) {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ public interface LogHandler {
44

55
LogHandler DEFAULT = new LogHandler() {};
66

7+
LogHandler SYSTEM =
8+
new LogHandler() {
9+
@Override
10+
public void log(LogLevel level, String message) throws WasmException {
11+
System.out.println(level + ": " + message);
12+
}
13+
};
14+
715
default void log(LogLevel level, String message) throws WasmException {}
816

917
default LogLevel getLogLevel() throws WasmException {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package io.roastedroot.proxywasm;
2+
3+
import java.util.Map;
4+
import java.util.stream.Collectors;
5+
import java.util.stream.Stream;
6+
import java.util.stream.StreamSupport;
7+
8+
/**
9+
* A ProxyMap implementation that chains to another ProxyMap instance.
10+
*/
11+
public class SplitProxyMap implements ProxyMap {
12+
13+
private final ProxyMap primary;
14+
private final ProxyMap secondary;
15+
16+
public SplitProxyMap(ProxyMap primary, ProxyMap secondary) {
17+
this.primary = primary;
18+
this.secondary = secondary;
19+
}
20+
21+
@Override
22+
public int size() {
23+
return primary.size() + secondary.size();
24+
}
25+
26+
@Override
27+
public void add(String key, String value) {
28+
secondary.add(key, value);
29+
}
30+
31+
@Override
32+
public void put(String key, String value) {
33+
if (primary.get(key) != null) {
34+
primary.put(key, value);
35+
}
36+
secondary.put(key, value);
37+
}
38+
39+
@Override
40+
public Iterable<? extends Map.Entry<String, String>> entries() {
41+
return Stream.concat(
42+
StreamSupport.stream(primary.entries().spliterator(), false),
43+
StreamSupport.stream(secondary.entries().spliterator(), false))
44+
.collect(Collectors.toList());
45+
}
46+
47+
@Override
48+
public String get(String key) {
49+
String value = primary.get(key);
50+
if (value != null) {
51+
return value;
52+
}
53+
return secondary.get(key);
54+
}
55+
56+
@Override
57+
public void remove(String key) {
58+
secondary.remove(key);
59+
}
60+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ private WellKnownHeaders() {}
1010
public static final String AUTHORITY = ":authority";
1111
public static final String PATH = ":path";
1212
public static final String METHOD = ":method";
13+
public static final String STATUS = ":status";
1314
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,16 @@ public byte[] getHttpRequestBody() {
7979
return httpRequestBody;
8080
}
8181

82+
public void setHttpRequestBody(byte[] httpRequestBody) {
83+
this.httpRequestBody = httpRequestBody;
84+
}
85+
8286
public byte[] getHttpResponseBody() {
8387
return httpResponseBody;
8488
}
8589

86-
public void setHttpRequestBody(byte[] httpRequestBody) {
87-
this.httpRequestBody = httpRequestBody;
90+
public void setHttpResponseBody(byte[] httpResponseBody) {
91+
this.httpResponseBody = httpResponseBody;
8892
}
8993

9094
public byte[] getGrpcReceiveBuffer() {
@@ -111,10 +115,6 @@ public void setDownStreamData(byte[] downStreamData) {
111115
this.downStreamData = downStreamData;
112116
}
113117

114-
public void setHttpResponseBody(byte[] httpResponseBody) {
115-
this.httpResponseBody = httpResponseBody;
116-
}
117-
118118
public SendResponse getSendResponse() {
119119
return sendResponse;
120120
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ public interface HttpRequestAdaptor {
1212

1313
String remoteAddress();
1414

15-
String remotePort();
15+
int remotePort();
1616

1717
String localAddress();
1818

19-
String localPort();
19+
int localPort();
20+
21+
String protocol();
2022

2123
ProxyMap getHttpRequestHeaders();
2224

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import io.roastedroot.proxywasm.WasmException;
3030
import io.roastedroot.proxywasm.WasmResult;
3131
import java.net.URI;
32-
import java.net.URISyntaxException;
3332
import java.util.HashMap;
3433
import java.util.List;
3534
import java.util.Map;
@@ -418,11 +417,8 @@ public int httpCall(
418417

419418
URI uri = null;
420419
try {
421-
uri =
422-
URI.create(
423-
new URI(scheme, null, authority, connectPort, null, null, null)
424-
+ path);
425-
} catch (IllegalArgumentException | URISyntaxException e) {
420+
uri = URI.create(scheme + "://" + authority + path);
421+
} catch (IllegalArgumentException e) {
426422
throw new WasmException(WasmResult.BAD_ARGUMENT);
427423
}
428424

proxy-wasm-java-host/src/test/go-examples/unit_tester/http_call.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type httpCallTests struct {
3131
}
3232

3333
func (
34-
p *pluginContext) httpCallTests(contextID uint32) types.HttpContext {
34+
p *pluginContext) httpCallTests(contextID uint32) types.HttpContext {
3535
return &httpCallTests{
3636
DefaultHttpContext: types.DefaultHttpContext{},
3737
contextID: contextID,
@@ -42,12 +42,8 @@ func (
4242

4343
func (ctx *httpCallTests) OnHttpRequestHeaders(int, bool) types.Action {
4444
proxywasm.LogDebug("OnHttpRequestHeaders")
45-
var err error
46-
ctx.headers, err = proxywasm.GetHttpRequestHeaders()
47-
if err != nil {
48-
proxywasm.LogCriticalf("failed to get request headers: %v", err)
49-
}
5045

46+
ctx.headers = nil
5147
method, err := proxywasm.GetProperty([]string{"request", "method"})
5248
if err != nil {
5349
proxywasm.LogCriticalf("failed to get request method: %v", err)
@@ -63,6 +59,11 @@ func (ctx *httpCallTests) OnHttpRequestHeaders(int, bool) types.Action {
6359
path := gjson.Get(ctx.pluginContext.config, "path").Str
6460
ctx.headers = append(ctx.headers, [2]string{":path", path})
6561

62+
requestHeaders, err := proxywasm.GetHttpRequestHeaders()
63+
if err != nil {
64+
proxywasm.LogCriticalf("failed to get request headers: %v", err)
65+
}
66+
ctx.headers = append(ctx.headers, requestHeaders...)
6667
return types.ActionContinue
6768
}
6869

0 commit comments

Comments
 (0)