Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 28x 28x 28x 9x 9x 2x 3x | /**
* @module
*
* @author Bayu Dwiyan Satria
* @version 1.0.0
* @since 1.3.0
*/
import { Binding } from '@/core/bindings/Binding'
import { lazySettings } from '@/utils/lazySettings'
import { VpcNetworkSettings } from '@/types/VpcNetworkSettings'
import type { VpcNetwork } from '@/types/VpcNetwork'
import type { CloudflareEnv } from '@/types/CloudflareEnv'
/**
* Accessor for a VPC Network binding.
*
* @remarks
* The broad half of Workers VPC. Where {@link VpcServiceBinding} is pinned to
* one private host and port at deploy time, this opens a whole network — a
* Cloudflare Tunnel by `tunnel_id`, or Cloudflare Mesh by `network_id` — and
* lets each call name its destination. Nothing has to be registered in advance,
* which is what makes it usable for a private network whose addresses are not
* known when the Worker ships.
*
* That reach is also the reason to prefer a VPC Service when one will do. A
* Worker holding this binding can reach anything on the network, so a request
* that influences the address it calls is a server-side request forgery with a
* private network behind it. Cloudflare's own answer to constraining that is a
* VPC Service per destination, not a filter — and see
* {@link VpcNetworkSettings} for why this package does not offer one.
*
* ## Two protocols
*
* {@link fetch} for HTTP, {@link connect} for everything that is not: Redis,
* Memcached, MQTT, anything speaking its own bytes. `connect` is plaintext TCP
* at the time of writing, so a private service expecting TLS needs it
* terminated on the private side.
*
* ## This one names a type this package declares
*
* Unique here, and not by preference. `@cloudflare/workers-types` declares
* nothing for Workers VPC at the pinned version, and unlike a VPC Service —
* which is `Fetcher` structurally — a network binding's `connect` has no
* existing type to borrow. {@link VpcNetwork} is therefore written here, kept
* to the two documented methods, and meant to be deleted when the real type
* ships. See that interface for what it costs.
*
* @example
* ```ts
* const network = new VpcNetworkBinding()
*
* const response = await network.fetch(env, 'http://10.0.1.50:8080/api/data')
* const socket = await network.connect(env, '10.0.1.50:6379')
* ```
*
* @class
*
* @author Bayu Dwiyan Satria
* @version 1.0.0
* @since 1.3.0
*/
export class VpcNetworkBinding<E extends CloudflareEnv = CloudflareEnv> extends Binding<VpcNetwork, E> {
/**
* Constructs a VpcNetworkBinding instance.
*
* @param settings Resolved settings. Defaults to `resolve('vpcNetwork')`, so callers
* normally construct this with no arguments at all.
*/
constructor(settings?: VpcNetworkSettings) {
const settle = lazySettings<VpcNetworkSettings>('vpcNetwork', settings)
super(() => settle().binding)
}
/**
* Sends a request to a destination on the private network.
*
* @remarks
* The URL decides the destination, so it is the argument that must never come
* from a request this Worker is serving. Any hostname or address reachable
* through the bound tunnel or mesh is in range.
*
* @param env The Worker environment.
* @param resource The private destination, as a URL, string, or `Request`.
* @param options Standard request options.
* @returns The response from the private service.
* @throws {@link MissingBindingError} When the VPC Network binding is absent.
*/
public async fetch(env: E, resource: string | URL | Request, options?: RequestInit): Promise<Response> {
return await this.resolve(env).fetch(resource, options)
}
/**
* Opens a TCP socket to a destination on the private network.
*
* @remarks
* The caller owns the socket from here — closing it, and draining both sides.
* Nothing in this package wraps that, because a socket's lifetime belongs to
* the protocol being spoken over it and this class knows no protocol.
*
* @param env The Worker environment.
* @param address The private destination, as `host:port` or a `SocketAddress`.
* @returns The connected socket.
* @throws {@link MissingBindingError} When the VPC Network binding is absent.
*/
public async connect(env: E, address: string | SocketAddress): Promise<Socket> {
return await this.resolve(env).connect(address)
}
}
|