Skip to content

Commit 6e96a18

Browse files
authored
Add SourceAddr support (#82)
* Add RemoteAddr support * add port to example * use SourceAddr * add tests
1 parent b2a065a commit 6e96a18

File tree

11 files changed

+86
-3
lines changed

11 files changed

+86
-3
lines changed

api/handler/handler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ type Host interface {
161161
// FuncRemoveHeader with HeaderKindResponseTrailers. This panics if
162162
// FeatureTrailers is not supported.
163163
RemoveResponseTrailer(ctx context.Context, name string)
164+
165+
// GetSourceAddr supports the WebAssembly function export FuncGetSourceAddr.
166+
GetSourceAddr(ctx context.Context) string
164167
}
165168

166169
// eofReader is safer than reading from os.DevNull as it can never overrun
@@ -206,3 +209,4 @@ func (UnimplementedHost) GetResponseTrailerValues(context.Context, string) (valu
206209
func (UnimplementedHost) SetResponseTrailerValue(context.Context, string, string) {}
207210
func (UnimplementedHost) AddResponseTrailerValue(context.Context, string, string) {}
208211
func (UnimplementedHost) RemoveResponseTrailer(context.Context, string) {}
212+
func (UnimplementedHost) GetSourceAddr(context.Context) string { return "1.1.1.1:12345" }

api/handler/wasm.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,10 @@ const (
316316
//
317317
// TODO: document on http-wasm-abi
318318
FuncSetStatusCode = "set_status_code"
319+
320+
// FuncGetSourceAddr writes the SourceAddr to memory if it isn't larger than BufLimit.
321+
// The result is its length in bytes. Ex. "1.1.1.1:12345" or "[fe80::101e:2bdf:8bfb:b97e]:12345"
322+
//
323+
// TODO: document on http-wasm-abi
324+
FuncGetSourceAddr = "get_source_addr"
319325
)

handler/middleware.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,17 @@ func (m *middleware) writeBody(ctx context.Context, mod wazeroapi.Module, params
565565
writeBody(mod, buf, bufLen, w)
566566
}
567567

568+
// getSourceAddr implements the WebAssembly host function handler.FuncGetSourceAddr.
569+
func (m *middleware) getSourceAddr(ctx context.Context, mod wazeroapi.Module, stack []uint64) {
570+
buf := uint32(stack[0])
571+
bufLimit := handler.BufLimit(stack[1])
572+
573+
method := m.host.GetSourceAddr(ctx)
574+
methodLen := writeStringIfUnderLimit(mod.Memory(), buf, bufLimit, method)
575+
576+
stack[0] = uint64(methodLen)
577+
}
578+
568579
func writeBody(mod wazeroapi.Module, buf, bufLen uint32, w io.Writer) {
569580
// buf_len 0 means to overwrite with nothing
570581
var b []byte
@@ -694,6 +705,9 @@ func (m *middleware) instantiateHost(ctx context.Context) (wazeroapi.Module, err
694705
WithGoModuleFunction(wazeroapi.GoModuleFunc(m.writeBody), []wazeroapi.ValueType{i32, i32, i32}, []wazeroapi.ValueType{}).
695706
WithParameterNames("kind", "body", "body_len").Export(handler.FuncWriteBody).
696707
NewFunctionBuilder().
708+
WithGoModuleFunction(wazeroapi.GoModuleFunc(m.getSourceAddr), []wazeroapi.ValueType{i32, i32}, []wazeroapi.ValueType{i32}).
709+
WithParameterNames("buf", "buf_limit").Export(handler.FuncGetSourceAddr).
710+
NewFunctionBuilder().
697711
WithGoFunction(wazeroapi.GoFunc(m.getStatusCode), []wazeroapi.ValueType{}, []wazeroapi.ValueType{i32}).
698712
WithParameterNames().Export(handler.FuncGetStatusCode).
699713
NewFunctionBuilder().

handler/nethttp/host.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,3 +346,9 @@ func addTrailer(header http.Header, name string, value string) {
346346
func removeTrailer(header http.Header, name string) {
347347
header.Del(http.TrailerPrefix + name)
348348
}
349+
350+
// GetSourceAddr implements the same method as documented on handler.Host.
351+
func (host) GetSourceAddr(ctx context.Context) string {
352+
r := requestStateFromContext(ctx).r
353+
return r.RemoteAddr
354+
}

handler/nethttp/host_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func Test_host(t *testing.T) {
1717
newCtx := func(features handler.Features) (context.Context, handler.Features) {
1818
// The below configuration supports all features.
1919
r, _ := http.NewRequest("GET", "", bytes.NewReader(nil))
20+
r.RemoteAddr = "1.2.3.4:12345"
2021
w := &bufferingResponseWriter{delegate: &httptest.ResponseRecorder{HeaderMap: map[string][]string{}}}
2122
return context.WithValue(testCtx, requestStateKey{}, &requestState{r: r, w: w}), features
2223
}

tck/guest/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ module github.com/anuraaga/http-wasm-tck/guest
22

33
go 1.19
44

5-
require github.com/http-wasm/http-wasm-guest-tinygo v0.1.1
5+
require github.com/http-wasm/http-wasm-guest-tinygo v0.3.1-0.20231031134125-487a6e2eec5e

tck/guest/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
github.com/http-wasm/http-wasm-guest-tinygo v0.1.1 h1:7L+MhMNDVsUAqmElG64JEZ0n1yGCKTx0w01N1b08Xhc=
2-
github.com/http-wasm/http-wasm-guest-tinygo v0.1.1/go.mod h1:roTs1mkyGDe1CUzrL8JUXSbPNYUHnnWKMCG6epmRAZY=
1+
github.com/http-wasm/http-wasm-guest-tinygo v0.3.1-0.20231031134125-487a6e2eec5e h1:mUEuIuH+XAtp5tkJPpwN5ZAtgvt64tYaYsk/KoK42lQ=
2+
github.com/http-wasm/http-wasm-guest-tinygo v0.3.1-0.20231031134125-487a6e2eec5e/go.mod h1:zcKr7h/t5ha2ZWIMwV4iOqhfC/qno/tNPYgybVkn/MQ=

tck/guest/main.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ func (h *handler) handleRequest(req api.Request, resp api.Response) (next bool,
104104
next, reqCtx = h.testReadBody(req, resp, strings.Repeat("a", 4096))
105105
case "read_body/request/xlarge":
106106
next, reqCtx = h.testReadBody(req, resp, strings.Repeat("a", 5000))
107+
case "get_source_addr":
108+
next, reqCtx = h.testGetSourceAddr(req, resp, "127.0.0.1")
107109
default:
108110
fail(resp, "unknown x-httpwasm-test-id")
109111
}
@@ -214,6 +216,24 @@ func (h *handler) testReadBody(req api.Request, resp api.Response, expectedBody
214216
return true, 0
215217
}
216218

219+
func (h *handler) testGetSourceAddr(req api.Request, resp api.Response, expectedAddr string) (next bool, reqCtx uint32) {
220+
addr := req.GetSourceAddr()
221+
raw := strings.Split(addr, ":")
222+
if len(raw) != 2 {
223+
fail(resp, fmt.Sprintf("get_source_addr: unknown colon count %s", req.GetSourceAddr()))
224+
return
225+
}
226+
if raw[0] != expectedAddr {
227+
fail(resp, fmt.Sprintf("get_source_addr: want %s, have %s", expectedAddr, req.GetSourceAddr()))
228+
return
229+
}
230+
if len(raw[1]) <= 0 || len(raw[1]) > 5 {
231+
fail(resp, fmt.Sprintf("get_source_addr: could not find port number '%s' from %s", raw[1], req.GetSourceAddr()))
232+
return
233+
}
234+
return true, 0
235+
}
236+
217237
func fail(resp api.Response, msg string) {
218238
resp.SetStatusCode(500)
219239
resp.Headers().Set("x-httpwasm-tck-failed", msg)

tck/run.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func Run(t *testing.T, client *http.Client, url string) {
5353
r.testAddHeaderValueRequest()
5454
r.testRemoveHeaderRequest()
5555
r.testReadBodyRequest()
56+
r.testGetSourceAddr()
5657
}
5758

5859
type testRunner struct {
@@ -493,6 +494,24 @@ func (r *testRunner) testRemoveHeaderRequest() {
493494
}
494495
}
495496

497+
func (r *testRunner) testGetSourceAddr() {
498+
hostFn := handler.FuncGetSourceAddr
499+
500+
r.t.Run(hostFn, func(t *testing.T) {
501+
req, err := http.NewRequest("GET", r.url, nil)
502+
if err != nil {
503+
t.Fatal(err)
504+
}
505+
506+
req.Header.Set("x-httpwasm-tck-testid", hostFn)
507+
resp, err := r.client.Do(req)
508+
if err != nil {
509+
t.Error(err)
510+
}
511+
checkResponse(t, resp)
512+
})
513+
}
514+
496515
func checkResponse(t *testing.T, resp *http.Response) string {
497516
t.Helper()
498517

tck/tck.wasm

2.39 KB
Binary file not shown.

0 commit comments

Comments
 (0)