Pat Hickey
2 years ago
15 changed files with 0 additions and 832 deletions
@ -1,24 +0,0 @@ |
|||
// The `wasi:http/incoming-handler` interface is meant to be exported by |
|||
// components and called by the host in response to a new incoming HTTP |
|||
// response. |
|||
// |
|||
// NOTE: in Preview3, this interface will be merged with |
|||
// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface |
|||
// that takes a `request` parameter and returns a `response` result. |
|||
// |
|||
default interface incoming-handler { |
|||
use pkg.types.{incoming-request, response-outparam} |
|||
|
|||
// The `handle` function takes an outparam instead of returning its response |
|||
// so that the component may stream its response while streaming any other |
|||
// request or response bodies. The callee MUST write a response to the |
|||
// `response-out` and then finish the response before returning. The `handle` |
|||
// function is allowed to continue execution after finishing the response's |
|||
// output stream. While this post-response execution is taken off the |
|||
// critical path, since there is no return value, there is no way to report |
|||
// its success or failure. |
|||
handle: func( |
|||
request: incoming-request, |
|||
response-out: response-outparam |
|||
) |
|||
} |
@ -1,18 +0,0 @@ |
|||
// The `wasi:http/outgoing-handler` interface is meant to be imported by |
|||
// components and implemented by the host. |
|||
// |
|||
// NOTE: in Preview3, this interface will be merged with |
|||
// `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface |
|||
// that takes a `request` parameter and returns a `response` result. |
|||
// |
|||
default interface outgoing-handler { |
|||
use pkg.types.{outgoing-request, request-options, future-incoming-response} |
|||
|
|||
// The parameter and result types of the `handle` function allow the caller |
|||
// to concurrently stream the bodies of the outgoing request and the incoming |
|||
// response. |
|||
handle: func( |
|||
request: outgoing-request, |
|||
options: option<request-options> |
|||
) -> future-incoming-response |
|||
} |
@ -1,157 +0,0 @@ |
|||
// The `wasi:http/types` interface is meant to be imported by components to |
|||
// define the HTTP resource types and operations used by the component's |
|||
// imported and exported interfaces. |
|||
default interface types { |
|||
use io.streams.{input-stream, output-stream} |
|||
use poll.poll.{pollable} |
|||
|
|||
// This type corresponds to HTTP standard Methods. |
|||
variant method { |
|||
get, |
|||
head, |
|||
post, |
|||
put, |
|||
delete, |
|||
connect, |
|||
options, |
|||
trace, |
|||
patch, |
|||
other(string) |
|||
} |
|||
|
|||
// This type corresponds to HTTP standard Related Schemes. |
|||
variant scheme { |
|||
HTTP, |
|||
HTTPS, |
|||
other(string) |
|||
} |
|||
|
|||
// TODO: perhaps better align with HTTP semantics? |
|||
// This type enumerates the different kinds of errors that may occur when |
|||
// initially returning a response. |
|||
variant error { |
|||
invalid-url(string), |
|||
timeout-error(string), |
|||
protocol-error(string), |
|||
unexpected-error(string) |
|||
} |
|||
|
|||
// This following block defines the `fields` resource which corresponds to |
|||
// HTTP standard Fields. Soon, when resource types are added, the `type |
|||
// fields = u32` type alias can be replaced by a proper `resource fields` |
|||
// definition containing all the functions using the method syntactic sugar. |
|||
type fields = u32 |
|||
drop-fields: func(fields: fields) |
|||
new-fields: func(entries: list<tuple<string,string>>) -> fields |
|||
fields-get: func(fields: fields, name: string) -> list<string> |
|||
fields-set: func(fields: fields, name: string, value: list<string>) |
|||
fields-delete: func(fields: fields, name: string) |
|||
fields-append: func(fields: fields, name: string, value: string) |
|||
fields-entries: func(fields: fields) -> list<tuple<string,string>> |
|||
fields-clone: func(fields: fields) -> fields |
|||
|
|||
type headers = fields |
|||
type trailers = fields |
|||
|
|||
// The following block defines stream types which corresponds to the HTTP |
|||
// standard Contents and Trailers. With Preview3, all of these fields can be |
|||
// replaced by a stream<u8, option<trailers>>. In the interim, we need to |
|||
// build on separate resource types defined by `wasi:io/streams`. The |
|||
// `finish-` functions emulate the stream's result value and MUST be called |
|||
// exactly once after the final read/write from/to the stream before dropping |
|||
// the stream. |
|||
type incoming-stream = input-stream |
|||
type outgoing-stream = output-stream |
|||
finish-incoming-stream: func(s: incoming-stream) -> option<trailers> |
|||
finish-outgoing-stream: func(s: outgoing-stream, trailers: option<trailers>) |
|||
|
|||
// The following block defines the `incoming-request` and `outgoing-request` |
|||
// resource types that correspond to HTTP standard Requests. Soon, when |
|||
// resource types are added, the `u32` type aliases can be replaced by |
|||
// proper `resource` type definitions containing all the functions as |
|||
// methods. Later, Preview2 will allow both types to be merged together into |
|||
// a single `request` type (that uses the single `stream` type mentioned |
|||
// above). The `consume` and `write` methods may only be called once (and |
|||
// return failure thereafter). |
|||
type incoming-request = u32 |
|||
type outgoing-request = u32 |
|||
drop-incoming-request: func(request: incoming-request) |
|||
drop-outgoing-request: func(request: outgoing-request) |
|||
incoming-request-method: func(request: incoming-request) -> method |
|||
incoming-request-path: func(request: incoming-request) -> string |
|||
incoming-request-query: func(request: incoming-request) -> string |
|||
incoming-request-scheme: func(request: incoming-request) -> option<scheme> |
|||
incoming-request-authority: func(request: incoming-request) -> string |
|||
incoming-request-headers: func(request: incoming-request) -> headers |
|||
incoming-request-consume: func(request: incoming-request) -> result<incoming-stream> |
|||
new-outgoing-request: func( |
|||
method: method, |
|||
path: string, |
|||
query: string, |
|||
scheme: option<scheme>, |
|||
authority: string, |
|||
headers: headers |
|||
) -> outgoing-request |
|||
outgoing-request-write: func(request: outgoing-request) -> result<outgoing-stream> |
|||
|
|||
// Additional optional parameters that can be set when making a request. |
|||
record request-options { |
|||
// The following timeouts are specific to the HTTP protocol and work |
|||
// independently of the overall timeouts passed to `io.poll.poll-oneoff`. |
|||
|
|||
// The timeout for the initial connect. |
|||
connect-timeout-ms: option<u32>, |
|||
|
|||
// The timeout for receiving the first byte of the response body. |
|||
first-byte-timeout-ms: option<u32>, |
|||
|
|||
// The timeout for receiving the next chunk of bytes in the response body |
|||
// stream. |
|||
between-bytes-timeout-ms: option<u32> |
|||
} |
|||
|
|||
// The following block defines a special resource type used by the |
|||
// `wasi:http/incoming-handler` interface. When resource types are added, this |
|||
// block can be replaced by a proper `resource response-outparam { ... }` |
|||
// definition. Later, with Preview3, the need for an outparam goes away entirely |
|||
// (the `wasi:http/handler` interface used for both incoming and outgoing can |
|||
// simply return a `stream`). |
|||
type response-outparam = u32 |
|||
drop-response-outparam: func(response: response-outparam) |
|||
set-response-outparam: func(response: result<outgoing-response, error>) -> result |
|||
|
|||
// This type corresponds to the HTTP standard Status Code. |
|||
type status-code = u16 |
|||
|
|||
// The following block defines the `incoming-response` and `outgoing-response` |
|||
// resource types that correspond to HTTP standard Responses. Soon, when |
|||
// resource types are added, the `u32` type aliases can be replaced by proper |
|||
// `resource` type definitions containing all the functions as methods. Later, |
|||
// Preview2 will allow both types to be merged together into a single `response` |
|||
// type (that uses the single `stream` type mentioned above). The `consume` and |
|||
// `write` methods may only be called once (and return failure thereafter). |
|||
type incoming-response = u32 |
|||
type outgoing-response = u32 |
|||
drop-incoming-response: func(response: incoming-response) |
|||
drop-outgoing-response: func(response: outgoing-response) |
|||
incoming-response-status: func(response: incoming-response) -> status-code |
|||
incoming-response-headers: func(response: incoming-response) -> headers |
|||
incoming-response-consume: func(response: incoming-response) -> result<incoming-stream> |
|||
new-outgoing-response: func( |
|||
status-code: status-code, |
|||
headers: headers |
|||
) -> outgoing-response |
|||
outgoing-response-write: func(response: outgoing-response) -> result<outgoing-stream> |
|||
|
|||
// The following block defines a special resource type used by the |
|||
// `wasi:http/outgoing-handler` interface to emulate |
|||
// `future<result<response, error>>` in advance of Preview3. Given a |
|||
// `future-incoming-response`, the client can call the non-blocking `get` |
|||
// method to get the result if it is available. If the result is not available, |
|||
// the client can call `listen` to get a `pollable` that can be passed to |
|||
// `io.poll.poll-oneoff`. |
|||
type future-incoming-response = u32 |
|||
drop-future-incoming-response: func(f: future-incoming-response) |
|||
future-incoming-response-get: func(f: future-incoming-response) -> option<result<incoming-response, error>> |
|||
listen-to-future-incoming-response: func(f: future-incoming-response) -> pollable |
|||
} |
@ -1,32 +0,0 @@ |
|||
/// WASI Logging is a logging API intended to let users emit log messages with |
|||
/// simple priority levels and context values. |
|||
default interface handler { |
|||
/// A log level, describing a kind of message. |
|||
enum level { |
|||
/// Describes messages about the values of variables and the flow of |
|||
/// control within a program. |
|||
trace, |
|||
|
|||
/// Describes messages likely to be of interest to someone debugging a |
|||
/// program. |
|||
debug, |
|||
|
|||
/// Describes messages likely to be of interest to someone monitoring a |
|||
/// program. |
|||
info, |
|||
|
|||
/// Describes messages indicating hazardous situations. |
|||
warn, |
|||
|
|||
/// Describes messages indicating serious errors. |
|||
error, |
|||
} |
|||
|
|||
/// Emit a log message. |
|||
/// |
|||
/// A log message has a `level` describing what kind of message is being |
|||
/// sent, a context, which is an uninterpreted string meant to help |
|||
/// consumers group similar messages, and a string containing the message |
|||
/// text. |
|||
log: func(level: level, context: string, message: string) |
|||
} |
@ -1,29 +0,0 @@ |
|||
default world command-extended { |
|||
import wall-clock: clocks.wall-clock |
|||
import monotonic-clock: clocks.monotonic-clock |
|||
import timezone: clocks.timezone |
|||
import filesystem: filesystem.filesystem |
|||
import instance-network: sockets.instance-network |
|||
import ip-name-lookup: sockets.ip-name-lookup |
|||
import network: sockets.network |
|||
import tcp-create-socket: sockets.tcp-create-socket |
|||
import tcp: sockets.tcp |
|||
import udp-create-socket: sockets.udp-create-socket |
|||
import udp: sockets.udp |
|||
import random: random.random |
|||
import poll: poll.poll |
|||
import streams: io.streams |
|||
import environment: wasi-cli-base.environment |
|||
import preopens: wasi-cli-base.preopens |
|||
import exit: wasi-cli-base.exit |
|||
|
|||
// We should replace all others with `include self.command` |
|||
// as soon as the unioning of worlds is available: |
|||
// https://github.com/WebAssembly/component-model/issues/169 |
|||
import console: logging.handler |
|||
import default-outgoing-HTTP: http.outgoing-handler |
|||
|
|||
export run: func( |
|||
args: list<string>, |
|||
) -> result |
|||
} |
@ -1,21 +0,0 @@ |
|||
default world command { |
|||
import wall-clock: clocks.wall-clock |
|||
import monotonic-clock: clocks.monotonic-clock |
|||
import timezone: clocks.timezone |
|||
import filesystem: filesystem.filesystem |
|||
import instance-network: sockets.instance-network |
|||
import ip-name-lookup: sockets.ip-name-lookup |
|||
import network: sockets.network |
|||
import tcp-create-socket: sockets.tcp-create-socket |
|||
import tcp: sockets.tcp |
|||
import udp-create-socket: sockets.udp-create-socket |
|||
import udp: sockets.udp |
|||
import random: random.random |
|||
import poll: poll.poll |
|||
import streams: io.streams |
|||
import environment: wasi-cli-base.environment |
|||
import preopens: wasi-cli-base.preopens |
|||
import exit: wasi-cli-base.exit |
|||
|
|||
export run: func() -> result |
|||
} |
@ -1,6 +0,0 @@ |
|||
default world proxy { |
|||
import random: random.random |
|||
import console: logging.handler |
|||
import default-outgoing-HTTP: http.outgoing-handler |
|||
export HTTP: http.incoming-handler |
|||
} |
@ -1,21 +0,0 @@ |
|||
default world reactor { |
|||
import wall-clock: clocks.wall-clock |
|||
import monotonic-clock: clocks.monotonic-clock |
|||
import timezone: clocks.timezone |
|||
import filesystem: filesystem.filesystem |
|||
import instance-network: sockets.instance-network |
|||
import ip-name-lookup: sockets.ip-name-lookup |
|||
import network: sockets.network |
|||
import tcp-create-socket: sockets.tcp-create-socket |
|||
import tcp: sockets.tcp |
|||
import udp-create-socket: sockets.udp-create-socket |
|||
import udp: sockets.udp |
|||
import random: random.random |
|||
import poll: poll.poll |
|||
import streams: io.streams |
|||
import console: logging.handler |
|||
import default-outgoing-HTTP: http.outgoing-handler |
|||
import environment: wasi-cli-base.environment |
|||
import preopens: wasi-cli-base.preopens |
|||
import exit: wasi-cli-base.exit |
|||
} |
@ -1,9 +0,0 @@ |
|||
|
|||
/// This interface provides a value-export of the default network handle.. |
|||
default interface instance-network { |
|||
use pkg.network.{network} |
|||
|
|||
/// Get a handle to the default network. |
|||
instance-network: func() -> network |
|||
|
|||
} |
@ -1,71 +0,0 @@ |
|||
|
|||
default interface ip-name-lookup { |
|||
use poll.poll.{pollable} |
|||
use pkg.network.{network, error, ip-address, ip-address-family} |
|||
|
|||
|
|||
/// Resolve an internet host name to a list of IP addresses. |
|||
/// |
|||
/// See the wasi-socket proposal README.md for a comparison with getaddrinfo. |
|||
/// |
|||
/// Parameters: |
|||
/// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted |
|||
/// to ASCII using IDNA encoding. |
|||
/// - `address-family`: If provided, limit the results to addresses of this specific address family. |
|||
/// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime |
|||
/// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on |
|||
/// systems without an active IPv6 interface. Notes: |
|||
/// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. |
|||
/// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. |
|||
/// |
|||
/// This function never blocks. It either immediately returns successfully with a `resolve-address-stream` |
|||
/// that can be used to (asynchronously) fetch the results. |
|||
/// Or it immediately fails whenever `name` is: |
|||
/// - empty |
|||
/// - an IP address |
|||
/// - a syntactically invalid domain name in another way |
|||
/// |
|||
/// References: |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html> |
|||
/// - <https://man7.org/linux/man-pages/man3/getaddrinfo.3.html> |
|||
/// |
|||
resolve-addresses: func(network: network, name: string, address-family: option<ip-address-family>, include-unavailable: bool) -> result<resolve-address-stream, error> |
|||
|
|||
|
|||
|
|||
type resolve-address-stream = u32 |
|||
|
|||
/// Returns the next address from the resolver. |
|||
/// |
|||
/// This function should be called multiple times. On each call, it will |
|||
/// return the next address in connection order preference. If all |
|||
/// addresses have been exhausted, this function returns `none`. |
|||
/// After which, you should release the stream with `drop-resolve-address-stream`. |
|||
/// |
|||
/// This function never returns IPv4-mapped IPv6 addresses. |
|||
resolve-next-address: func(this: resolve-address-stream) -> result<option<ip-address>, error> |
|||
|
|||
|
|||
|
|||
/// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. |
|||
/// |
|||
/// Note: this function is scheduled to be removed when Resources are natively supported in Wit. |
|||
drop-resolve-address-stream: func(this: resolve-address-stream) |
|||
|
|||
/// Get/set the blocking mode of the stream. |
|||
/// |
|||
/// By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. |
|||
/// When switched to "non-blocking" mode, operations that would block return an `again` error. After which |
|||
/// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. |
|||
/// |
|||
/// Note: these functions are here for WASI Preview2 only. |
|||
/// They're planned to be removed when `future` is natively supported in Preview3. |
|||
non-blocking: func(this: resolve-address-stream) -> result<bool, error> |
|||
set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error> |
|||
|
|||
/// Create a `pollable` which will resolve once the stream is ready for I/O. |
|||
/// |
|||
/// Note: this function is here for WASI Preview2 only. |
|||
/// It's planned to be removed when `future` is natively supported in Preview3. |
|||
subscribe: func(this: resolve-address-stream) -> pollable |
|||
} |
@ -1,56 +0,0 @@ |
|||
|
|||
default interface network { |
|||
/// An opaque resource that represents access to (a subset of) the network. |
|||
/// This enables context-based security for networking. |
|||
/// There is no need for this to map 1:1 to a physical network interface. |
|||
/// |
|||
/// FYI, In the future this will be replaced by handle types. |
|||
type network = u32 |
|||
|
|||
/// Dispose of the specified `network`, after which it may no longer be used. |
|||
/// |
|||
/// Note: this function is scheduled to be removed when Resources are natively supported in Wit. |
|||
drop-network: func(this: network) |
|||
|
|||
|
|||
|
|||
enum error { |
|||
unknown, |
|||
again, |
|||
// TODO ... |
|||
} |
|||
|
|||
enum ip-address-family { |
|||
/// Similar to `AF_INET` in POSIX. |
|||
ipv4, |
|||
|
|||
/// Similar to `AF_INET6` in POSIX. |
|||
ipv6, |
|||
} |
|||
|
|||
type ipv4-address = tuple<u8, u8, u8, u8> |
|||
type ipv6-address = tuple<u16, u16, u16, u16, u16, u16, u16, u16> |
|||
|
|||
variant ip-address { |
|||
ipv4(ipv4-address), |
|||
ipv6(ipv6-address), |
|||
} |
|||
|
|||
record ipv4-socket-address { |
|||
port: u16, // sin_port |
|||
address: ipv4-address, // sin_addr |
|||
} |
|||
|
|||
record ipv6-socket-address { |
|||
port: u16, // sin6_port |
|||
flow-info: u32, // sin6_flowinfo |
|||
address: ipv6-address, // sin6_addr |
|||
scope-id: u32, // sin6_scope_id |
|||
} |
|||
|
|||
variant ip-socket-address { |
|||
ipv4(ipv4-socket-address), |
|||
ipv6(ipv6-socket-address), |
|||
} |
|||
|
|||
} |
@ -1,19 +0,0 @@ |
|||
|
|||
default interface tcp-create-socket { |
|||
use pkg.network.{network, error, ip-address-family} |
|||
use pkg.tcp.{tcp-socket} |
|||
|
|||
/// Create a new TCP socket. |
|||
/// |
|||
/// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. |
|||
/// |
|||
/// This function does not require a network capability handle. This is considered to be safe because |
|||
/// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`listen`/`connect` |
|||
/// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. |
|||
/// |
|||
/// References: |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/socket.2.html> |
|||
/// |
|||
create-tcp-socket: func(address-family: ip-address-family) -> result<tcp-socket, error> |
|||
} |
@ -1,188 +0,0 @@ |
|||
|
|||
default interface tcp { |
|||
use io.streams.{input-stream, output-stream} |
|||
use poll.poll.{pollable} |
|||
use pkg.network.{network, error, ip-socket-address, ip-address-family} |
|||
|
|||
/// A TCP socket handle. |
|||
type tcp-socket = u32 |
|||
|
|||
|
|||
enum shutdown-type { |
|||
/// Similar to `SHUT_RD` in POSIX. |
|||
receive, |
|||
|
|||
/// Similar to `SHUT_WR` in POSIX. |
|||
send, |
|||
|
|||
/// Similar to `SHUT_RDWR` in POSIX. |
|||
both, |
|||
} |
|||
|
|||
|
|||
/// Bind the socket to a specific network on the provided IP address and port. |
|||
/// |
|||
/// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which |
|||
/// network interface(s) to bind to. |
|||
/// If the TCP/UDP port is zero, the socket will be bound to a random free port. |
|||
/// |
|||
/// When a socket is not explicitly bound, the first invocation to a listen or connect operation will |
|||
/// implicitly bind the socket. |
|||
/// |
|||
/// Fails when: |
|||
/// - the socket is already bound. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/bind.2.html> |
|||
bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error> |
|||
|
|||
/// Connect to a remote endpoint. |
|||
/// |
|||
/// On success: |
|||
/// - the socket is transitioned into the Connection state |
|||
/// - a pair of streams is returned that can be used to read & write to the connection |
|||
/// |
|||
/// Fails when: |
|||
/// - the socket is already bound to a different network. |
|||
/// - the provided network does not allow connections to the specified endpoint. |
|||
/// - the socket is already in the Connection or Listener state. |
|||
/// - either the remote IP address or port is 0. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/connect.2.html> |
|||
connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<tuple<input-stream, output-stream>, error> |
|||
|
|||
/// Start listening for new connections. |
|||
/// |
|||
/// Transitions the socket into the Listener state. |
|||
/// |
|||
/// Fails when: |
|||
/// - the socket is already bound to a different network. |
|||
/// - the provided network does not allow listening on the specified address. |
|||
/// - the socket is already in the Connection or Listener state. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/listen.2.html> |
|||
listen: func(this: tcp-socket, network: network) -> result<_, error> |
|||
|
|||
/// Accept a new client socket. |
|||
/// |
|||
/// The returned socket is bound and in the Connection state. |
|||
/// |
|||
/// On success, this function returns the newly accepted client socket along with |
|||
/// a pair of streams that can be used to read & write to the connection. |
|||
/// |
|||
/// Fails when this socket is not in the Listening state. |
|||
/// |
|||
/// References: |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/accept.2.html> |
|||
accept: func(this: tcp-socket) -> result<tuple<tcp-socket, input-stream, output-stream>, error> |
|||
|
|||
/// Get the bound local address. |
|||
/// |
|||
/// Returns an error if the socket is not bound. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/getsockname.2.html> |
|||
local-address: func(this: tcp-socket) -> result<ip-socket-address, error> |
|||
|
|||
/// Get the bound remote address. |
|||
/// |
|||
/// Fails when the socket is not in the Connection state. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/getpeername.2.html> |
|||
remote-address: func(this: tcp-socket) -> result<ip-socket-address, error> |
|||
|
|||
/// Whether this is a IPv4 or IPv6 socket. |
|||
/// |
|||
/// Equivalent to the SO_DOMAIN socket option. |
|||
address-family: func(this: tcp-socket) -> result<ip-address-family, error> |
|||
|
|||
/// Whether IPv4 compatibility (dual-stack) mode is disabled or not. |
|||
/// Implementations are not required to support dual-stack mode. Calling `set-ipv6-only(false)` might fail. |
|||
/// |
|||
/// Fails when called on an IPv4 socket. |
|||
/// |
|||
/// Equivalent to the IPV6_V6ONLY socket option. |
|||
ipv6-only: func(this: tcp-socket) -> result<bool, error> |
|||
set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> |
|||
|
|||
/// Hints the desired listen queue size. Implementations are free to ignore this. |
|||
set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error> |
|||
|
|||
/// Equivalent to the SO_KEEPALIVE socket option. |
|||
keep-alive: func(this: tcp-socket) -> result<bool, error> |
|||
set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> |
|||
|
|||
/// Equivalent to the TCP_NODELAY socket option. |
|||
no-delay: func(this: tcp-socket) -> result<bool, error> |
|||
set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> |
|||
|
|||
/// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. |
|||
unicast-hop-limit: func(this: tcp-socket) -> result<u8, error> |
|||
set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> |
|||
|
|||
/// The kernel buffer space reserved for sends/receives on this socket. |
|||
/// |
|||
/// Note #1: an implementation may choose to cap or round the buffer size when setting the value. |
|||
/// In other words, after setting a value, reading the same setting back may return a different value. |
|||
/// |
|||
/// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of |
|||
/// actual data to be sent/received by the application, because the kernel might also use the buffer space |
|||
/// for internal metadata structures. |
|||
/// |
|||
/// Fails when this socket is in the Listening state. |
|||
/// |
|||
/// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. |
|||
receive-buffer-size: func(this: tcp-socket) -> result<u64, error> |
|||
set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> |
|||
send-buffer-size: func(this: tcp-socket) -> result<u64, error> |
|||
set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> |
|||
|
|||
/// Get/set the blocking mode of the socket. |
|||
/// |
|||
/// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. |
|||
/// When switched to "non-blocking" mode, operations that would block return an `again` error. After which |
|||
/// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. |
|||
/// |
|||
/// Note: these functions are here for WASI Preview2 only. |
|||
/// They're planned to be removed when `future` is natively supported in Preview3. |
|||
non-blocking: func(this: tcp-socket) -> result<bool, error> |
|||
set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> |
|||
|
|||
/// Create a `pollable` which will resolve once the socket is ready for I/O. |
|||
/// |
|||
/// Note: this function is here for WASI Preview2 only. |
|||
/// It's planned to be removed when `future` is natively supported in Preview3. |
|||
subscribe: func(this: tcp-socket) -> pollable |
|||
|
|||
/// Gracefully shut down the connection. |
|||
/// |
|||
/// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read |
|||
/// operations on the `input-stream` associated with this socket will return an End Of Stream indication. |
|||
/// Any data still in the receive queue at time of calling `shutdown` will be discarded. |
|||
/// - send: the socket is not expecting to send any more data to the peer. All subsequent write |
|||
/// operations on the `output-stream` associated with this socket will return an error. |
|||
/// - both: same effect as receive & send combined. |
|||
/// |
|||
/// The shutdown function does not close the socket. |
|||
/// |
|||
/// Fails when the socket is not in the Connection state. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/shutdown.2.html> |
|||
shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> |
|||
|
|||
/// Dispose of the specified `tcp-socket`, after which it may no longer be used. |
|||
/// |
|||
/// Note: this function is scheduled to be removed when Resources are natively supported in Wit. |
|||
drop-tcp-socket: func(this: tcp-socket) |
|||
} |
@ -1,19 +0,0 @@ |
|||
|
|||
default interface udp-create-socket { |
|||
use pkg.network.{network, error, ip-address-family} |
|||
use pkg.udp.{udp-socket} |
|||
|
|||
/// Create a new UDP socket. |
|||
/// |
|||
/// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. |
|||
/// |
|||
/// This function does not require a network capability handle. This is considered to be safe because |
|||
/// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` is called, |
|||
/// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. |
|||
/// |
|||
/// References: |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/socket.2.html> |
|||
/// |
|||
create-udp-socket: func(address-family: ip-address-family) -> result<udp-socket, error> |
|||
} |
@ -1,162 +0,0 @@ |
|||
|
|||
default interface udp { |
|||
use poll.poll.{pollable} |
|||
use pkg.network.{network, error, ip-socket-address, ip-address-family} |
|||
|
|||
|
|||
/// A UDP socket handle. |
|||
type udp-socket = u32 |
|||
|
|||
|
|||
record datagram { |
|||
data: list<u8>, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. |
|||
remote-address: ip-socket-address, |
|||
|
|||
/// Possible future additions: |
|||
/// local-address: ip-socket-address, // IP_PKTINFO / IP_RECVDSTADDR / IPV6_PKTINFO |
|||
/// local-interface: u32, // IP_PKTINFO / IP_RECVIF |
|||
/// ttl: u8, // IP_RECVTTL |
|||
/// dscp: u6, // IP_RECVTOS |
|||
/// ecn: u2, // IP_RECVTOS |
|||
} |
|||
|
|||
|
|||
|
|||
/// Bind the socket to a specific network on the provided IP address and port. |
|||
/// |
|||
/// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which |
|||
/// network interface(s) to bind to. |
|||
/// If the TCP/UDP port is zero, the socket will be bound to a random free port. |
|||
/// |
|||
/// When a socket is not explicitly bound, the first invocation to a connect, send or receive operation will |
|||
/// implicitly bind the socket. |
|||
/// |
|||
/// Fails when: |
|||
/// - the socket is already bound. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/bind.2.html> |
|||
bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error> |
|||
|
|||
/// Set the destination address. |
|||
/// |
|||
/// The local-address is updated based on the best network path to `remote-address`. |
|||
/// |
|||
/// When a destination address is set: |
|||
/// - all receive operations will only return datagrams sent from the provided `remote-address`. |
|||
/// - the `send` function can only be used to send to this destination. |
|||
/// |
|||
/// Note that this function does not generate any network traffic and the peer is not aware of this "connection". |
|||
/// |
|||
/// Fails when: |
|||
/// - the socket is already bound to a different network. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/connect.2.html> |
|||
connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error> |
|||
|
|||
/// Receive a message. |
|||
/// |
|||
/// Returns: |
|||
/// - The sender address of the datagram |
|||
/// - The number of bytes read. |
|||
/// |
|||
/// Fails when: |
|||
/// - the socket is not bound. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html> |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/recv.2.html> |
|||
receive: func(this: udp-socket) -> result<datagram, error> |
|||
|
|||
/// Send a message to a specific destination address. |
|||
/// |
|||
/// The remote address option is required. To send a message to the "connected" peer, |
|||
/// call `remote-address` to get their address. |
|||
/// |
|||
/// Fails when: |
|||
/// - the socket is not bound. Unlike POSIX, this function does not perform an implicit bind. |
|||
/// - the socket is in "connected" mode and the `datagram.remote-address` does not match the address passed to `connect`. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html> |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendmsg.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/send.2.html> |
|||
send: func(this: udp-socket, datagram: datagram) -> result<_, error> |
|||
|
|||
/// Get the current bound address. |
|||
/// |
|||
/// Returns an error if the socket is not bound. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/getsockname.2.html> |
|||
local-address: func(this: udp-socket) -> result<ip-socket-address, error> |
|||
|
|||
/// Get the address set with `connect`. |
|||
/// |
|||
/// References |
|||
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html> |
|||
/// - <https://man7.org/linux/man-pages/man2/getpeername.2.html> |
|||
remote-address: func(this: udp-socket) -> result<ip-socket-address, error> |
|||
|
|||
/// Whether this is a IPv4 or IPv6 socket. |
|||
/// |
|||
/// Equivalent to the SO_DOMAIN socket option. |
|||
address-family: func(this: udp-socket) -> result<ip-address-family, error> |
|||
|
|||
/// Whether IPv4 compatibility (dual-stack) mode is disabled or not. |
|||
/// Implementations are not required to support dual-stack mode, so calling `set-ipv6-only(false)` might fail. |
|||
/// |
|||
/// Fails when called on an IPv4 socket. |
|||
/// |
|||
/// Equivalent to the IPV6_V6ONLY socket option. |
|||
ipv6-only: func(this: udp-socket) -> result<bool, error> |
|||
set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error> |
|||
|
|||
/// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. |
|||
unicast-hop-limit: func(this: udp-socket) -> result<u8, error> |
|||
set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error> |
|||
|
|||
/// The kernel buffer space reserved for sends/receives on this socket. |
|||
/// |
|||
/// Note #1: an implementation may choose to cap or round the buffer size when setting the value. |
|||
/// In other words, after setting a value, reading the same setting back may return a different value. |
|||
/// |
|||
/// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of |
|||
/// actual data to be sent/received by the application, because the kernel might also use the buffer space |
|||
/// for internal metadata structures. |
|||
/// |
|||
/// Fails when this socket is in the Listening state. |
|||
/// |
|||
/// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. |
|||
receive-buffer-size: func(this: udp-socket) -> result<u64, error> |
|||
set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> |
|||
send-buffer-size: func(this: udp-socket) -> result<u64, error> |
|||
set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error> |
|||
|
|||
/// Get/set the blocking mode of the socket. |
|||
/// |
|||
/// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. |
|||
/// When switched to "non-blocking" mode, operations that would block return an `again` error. After which |
|||
/// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. |
|||
/// |
|||
/// Note: these functions are here for WASI Preview2 only. |
|||
/// They're planned to be removed when `future` is natively supported in Preview3. |
|||
non-blocking: func(this: udp-socket) -> result<bool, error> |
|||
set-non-blocking: func(this: udp-socket, value: bool) -> result<_, error> |
|||
|
|||
/// Create a `pollable` which will resolve once the socket is ready for I/O. |
|||
/// |
|||
/// Note: this function is here for WASI Preview2 only. |
|||
/// It's planned to be removed when `future` is natively supported in Preview3. |
|||
subscribe: func(this: udp-socket) -> pollable |
|||
|
|||
/// Dispose of the specified `udp-socket`, after which it may no longer be used. |
|||
/// |
|||
/// Note: this function is scheduled to be removed when Resources are natively supported in Wit. |
|||
drop-udp-socket: func(this: udp-socket) |
|||
} |
Loading…
Reference in new issue