a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(xrpc-server): ignore body if content-length is 0

Mary 4e2306dc 14083b43

+33 -3
+5
.changeset/lazy-worms-care.md
··· 1 + --- 2 + "@atcute/xrpc-server": patch 3 + --- 4 + 5 + ignore body if content-length is 0
+3 -3
packages/servers/xrpc-server/lib/main/router.ts
··· 18 18 import { encodeErrorFrame, encodeMessageFrame, extractMessageType, omitMessageType } from './utils/frames.ts'; 19 19 import { createAsyncMiddlewareRunner, type Middleware } from './utils/middlewares.ts'; 20 20 import { unwrapLxm, type Namespaced } from './utils/namespaced.ts'; 21 - import { constructMimeValidator } from './utils/request-input.ts'; 21 + import { constructMimeValidator, hasRequestBody } from './utils/request-input.ts'; 22 22 import { constructParamsHandler } from './utils/request-params.ts'; 23 23 import { invalidRequest, validationError } from './utils/response.ts'; 24 24 import { XRPCError, XRPCSubscriptionError } from './xrpc-error.ts'; ··· 236 236 } 237 237 238 238 if (requiresInput) { 239 - if (request.body === null) { 239 + if (!hasRequestBody(request)) { 240 240 return invalidRequest(`request body is expected but none was provided`); 241 241 } 242 242 ··· 263 263 input = result.value; 264 264 } 265 265 } else { 266 - if (request.body !== null) { 266 + if (hasRequestBody(request)) { 267 267 return invalidRequest(`request body is provided when none was expected`); 268 268 } 269 269 }
+25
packages/servers/xrpc-server/lib/main/utils/request-input.ts
··· 2 2 3 3 import type { Result } from '../../types/misc.ts'; 4 4 5 + /** 6 + * checks whether a request has a meaningful body. 7 + * 8 + * Node.js HTTP-to-fetch adapters always provide a `ReadableStream` for 9 + * `request.body`, even when no body content was sent. this function 10 + * uses `content-length` to handle that case while still respecting the 11 + * web `Request` API where `body === null` signals no body. 12 + * 13 + * @param request incoming request to check 14 + * @returns whether the request has body content 15 + */ 16 + export const hasRequestBody = (request: Request): boolean => { 17 + if (request.body === null) { 18 + return false; 19 + } 20 + 21 + // Node.js adapters set content-length: 0 for bodiless requests while 22 + // still providing a ReadableStream body; treat this as no body. 23 + if (request.headers.get('content-length') === '0') { 24 + return false; 25 + } 26 + 27 + return true; 28 + }; 29 + 5 30 const jsonMimeValidator = (() => { 6 31 const JSON_RE = /^\s*application\/json\s*(?:$|;)/; 7 32