Skip to content

Commit 8c029b5

Browse files
authored
Merge pull request #139 from fastly/dgryski/origin-addr-port
fsthttp, internal: add get_addr_dest_ip/port hostcalls
2 parents 6c328bd + c9e934c commit 8c029b5

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

fsthttp/response.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package fsthttp
55
import (
66
"fmt"
77
"io"
8+
"net"
9+
"strconv"
810
"sync"
911

1012
"github.com/fastly/compute-sdk-go/internal/abi/fastly"
@@ -32,13 +34,51 @@ type Response struct {
3234

3335
// Body of the response.
3436
Body io.ReadCloser
37+
38+
abi struct {
39+
resp *fastly.HTTPResponse
40+
}
3541
}
3642

3743
// Cookies parses and returns the cookies set in the Set-Cookie headers.
3844
func (resp *Response) Cookies() []*Cookie {
3945
return readSetCookies(resp.Header)
4046
}
4147

48+
// RemoteAddr returns the address of the server that provided the response.
49+
func (resp *Response) RemoteAddr() (net.Addr, error) {
50+
51+
var addr netaddr
52+
var err error
53+
54+
addr.ip, err = resp.abi.resp.GetAddrDestIP()
55+
if err != nil {
56+
return nil, fmt.Errorf("get addr dest ip: %w", err)
57+
}
58+
59+
addr.port, err = resp.abi.resp.GetAddrDestPort()
60+
if err != nil {
61+
return nil, fmt.Errorf("get addr dest port: %w", err)
62+
}
63+
64+
return &addr, nil
65+
}
66+
67+
type netaddr struct {
68+
ip net.IP
69+
port uint16
70+
}
71+
72+
var _ net.Addr = (*netaddr)(nil)
73+
74+
func (n *netaddr) Network() string {
75+
return "tcp"
76+
}
77+
78+
func (n *netaddr) String() string {
79+
return net.JoinHostPort(n.ip.String(), strconv.Itoa(int(n.port)))
80+
}
81+
4282
func newResponse(req *Request, backend string, abiResp *fastly.HTTPResponse, abiBody *fastly.HTTPBody) (*Response, error) {
4383
code, err := abiResp.GetStatusCode()
4484
if err != nil {

internal/abi/fastly/hostcalls_noguest.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ func (r *HTTPRequest) SetFramingHeadersMode(manual bool) error {
177177
return fmt.Errorf("not implemented")
178178
}
179179

180+
func (r *HTTPResponse) GetAddrDestIP() (net.IP, error) {
181+
return nil, fmt.Errorf("not implemented")
182+
}
183+
184+
func (r *HTTPResponse) GetAddrDestPort() (uint16, error) {
185+
return 0, fmt.Errorf("not implemented")
186+
}
187+
180188
func HandoffWebsocket(backend string) error {
181189
return fmt.Errorf("not implemented")
182190
}

internal/abi/fastly/http_guest.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,70 @@ func (r *HTTPResponse) SetFramingHeadersMode(manual bool) error {
18691869
).toError()
18701870
}
18711871

1872+
// witx:
1873+
//
1874+
// ;;; Hostcall for getting the destination IP used for this request.
1875+
// ;;;
1876+
// ;;; The buffer for the IP address must be 16 bytes.
1877+
// ;;; syntax used in URLs as specified in RFC 3986 section 3.
1878+
// (@interface func (export "get_addr_dest_ip")
1879+
// (param $h $response_handle)
1880+
// ;; must be a 16-byte array
1881+
// (param $addr_octets_out (@witx pointer (@witx char8)))
1882+
// (result $err (expected $num_bytes (error $fastly_status)))
1883+
// )
1884+
//
1885+
//go:wasmimport fastly_http_resp get_addr_dest_ip
1886+
//go:noescape
1887+
func fastlyHTTPRespGetAddrDestIP(
1888+
h responseHandle,
1889+
addr prim.Pointer[prim.Char8],
1890+
nWritten prim.Pointer[prim.Usize],
1891+
) FastlyStatus
1892+
1893+
// GetAddrDestIP
1894+
func (r *HTTPResponse) GetAddrDestIP() (net.IP, error) {
1895+
buf := prim.NewWriteBuffer(ipBufLen)
1896+
1897+
if err := fastlyHTTPRespGetAddrDestIP(
1898+
r.h,
1899+
prim.ToPointer(buf.Char8Pointer()),
1900+
prim.ToPointer(buf.NPointer()),
1901+
).toError(); err != nil {
1902+
return nil, err
1903+
}
1904+
1905+
return net.IP(buf.AsBytes()), nil
1906+
}
1907+
1908+
// witx:
1909+
//
1910+
// ;;; Hostcall for getting the destination port used for this request.
1911+
// (@interface func (export "get_addr_dest_port")
1912+
// (param $h $response_handle)
1913+
// (result $err (expected $port (error $fastly_status)))
1914+
// )
1915+
//
1916+
//go:wasmimport fastly_http_resp get_addr_dest_port
1917+
//go:noescape
1918+
func fastlyHTTPRespGetAddrDestPort(
1919+
h responseHandle,
1920+
port prim.Pointer[prim.U16],
1921+
) FastlyStatus
1922+
1923+
// GetAddrDestPort
1924+
func (r *HTTPResponse) GetAddrDestPort() (uint16, error) {
1925+
var port prim.U16
1926+
1927+
if err := fastlyHTTPRespGetAddrDestPort(
1928+
r.h, prim.ToPointer(&port),
1929+
).toError(); err != nil {
1930+
return 0, err
1931+
}
1932+
1933+
return uint16(port), nil
1934+
}
1935+
18721936
// witx:
18731937
//
18741938
// (module $fastly_uap

0 commit comments

Comments
 (0)