@meddleware/nft-gate-gateway 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meddleware/nft-gate-gateway",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "description": "Cloudflare Workers implementation of the nft-gate gateway: a wire-identical, drop-in sibling of the Rust gateway that gates any HTTP upstream behind an access_gate NFT.",
6
6
  "license": "0BSD",
package/src/proxy.ts CHANGED
@@ -42,16 +42,19 @@ export async function forward(cfg: Config, request: Request): Promise<Response>
42
42
  const pathAndQuery = url.pathname + url.search
43
43
  const upstreamUrl = cfg.upstreamUrl + pathAndQuery
44
44
 
45
- // Read + cap the body (a griefing guard) before forwarding.
46
- let body: ArrayBuffer | undefined
45
+ // Size guard: check Content-Length first (cheap, avoids buffering). Not authoritative
46
+ // (clients can lie) but protects against accidental oversized sends; the relay enforces
47
+ // its own hard limit. Stream the body directly — buffering 60+ MB encoded blobs into an
48
+ // ArrayBuffer would exhaust Worker memory for large Walrus uploads.
47
49
  const method = request.method.toUpperCase()
48
50
  if (method !== 'GET' && method !== 'HEAD') {
49
- const buf = await request.arrayBuffer()
50
- if (buf.byteLength > cfg.maxBodyBytes) {
51
+ const cl = parseInt(request.headers.get('content-length') ?? '', 10)
52
+ if (Number.isFinite(cl) && cl > cfg.maxBodyBytes) {
51
53
  return errorResponse(413, 'request body too large')
52
54
  }
53
- body = buf
54
55
  }
56
+ const body: ReadableStream | null | undefined =
57
+ method !== 'GET' && method !== 'HEAD' ? request.body : undefined
55
58
 
56
59
  const headers = new Headers(request.headers)
57
60
  headers.delete('host')
@@ -66,7 +69,13 @@ export async function forward(cfg: Config, request: Request): Promise<Response>
66
69
 
67
70
  let upstream: Response
68
71
  try {
69
- upstream = await fetch(upstreamUrl, { method: request.method, headers, body })
72
+ upstream = await fetch(upstreamUrl, {
73
+ method: request.method,
74
+ headers,
75
+ body: body ?? null,
76
+ // @ts-expect-error — CF Workers supports streaming body via ReadableStream without 'duplex'
77
+ duplex: 'half',
78
+ })
70
79
  } catch {
71
80
  return errorResponse(502, 'upstream error')
72
81
  }
package/wrangler.toml CHANGED
@@ -49,7 +49,7 @@ GATE_ID = "0x0485c1fa80e4c355c85ab99c0281a328d8fb5c60ac50ab64f10be0f8be792aba"
49
49
  SINGLE_USE = "true"
50
50
  PUBLIC_PATHS = "/v1/tip-config"
51
51
  RATE_LIMIT_PER_MIN = "30"
52
- MAX_BODY_BYTES = "262144"
52
+ MAX_BODY_BYTES = "104857600"
53
53
  CHALLENGE_TTL_SECS = "300"
54
54
  OWNERSHIP_CACHE_TTL_MS = "0"
55
55
  # Workers-specific: