diff --git a/packages/pds/src/api/com/atproto/temp/importRepo.ts b/packages/pds/src/api/com/atproto/temp/importRepo.ts index ca7c03d8843..dfdcd31a4a4 100644 --- a/packages/pds/src/api/com/atproto/temp/importRepo.ts +++ b/packages/pds/src/api/com/atproto/temp/importRepo.ts @@ -15,6 +15,9 @@ import { AtprotoData } from '@atproto/identity' export default function (server: Server, ctx: AppContext) { server.com.atproto.temp.importRepo({ + opts: { + blobLimit: 5 * 1024 * 1024, // 5GB + }, handler: async ({ params, input, req }) => { const { did } = params const outBuffer = new AsyncBuffer() diff --git a/packages/pds/src/lexicon/index.ts b/packages/pds/src/lexicon/index.ts index ef20b83af05..b37c7a4f5c0 100644 --- a/packages/pds/src/lexicon/index.ts +++ b/packages/pds/src/lexicon/index.ts @@ -1614,6 +1614,7 @@ type HandlerRateLimitOpts = SharedRateLimitOpts | RouteRateLimitOpts type ConfigOf = | Handler | { + opts?: { blobLimit?: number } auth?: Auth rateLimit?: HandlerRateLimitOpts | HandlerRateLimitOpts[] handler: Handler diff --git a/packages/xrpc-server/src/server.ts b/packages/xrpc-server/src/server.ts index 1a258097d66..a9539545866 100644 --- a/packages/xrpc-server/src/server.ts +++ b/packages/xrpc-server/src/server.ts @@ -173,7 +173,7 @@ export class Server { this.routes[verb]( `/xrpc/${nsid}`, ...middleware, - this.createHandler(nsid, def, config.handler), + this.createHandler(nsid, def, config), ) } @@ -206,10 +206,13 @@ export class Server { createHandler( nsid: string, def: LexXrpcQuery | LexXrpcProcedure, - handler: XRPCHandler, + routeCfg: XRPCHandlerConfig, ): RequestHandler { + const routeOpts = { + blobLimit: routeCfg.opts?.blobLimit ?? this.options.payload?.blobLimit, + } const validateReqInput = (req: express.Request) => - validateInput(nsid, def, req, this.options, this.lex) + validateInput(nsid, def, req, routeOpts, this.lex) const validateResOutput = this.options.validateResponse === false ? (output?: HandlerSuccess) => output @@ -256,7 +259,7 @@ export class Server { } // run the handler - const outputUnvalidated = await handler(reqCtx) + const outputUnvalidated = await routeCfg.handler(reqCtx) if (isHandlerError(outputUnvalidated)) { throw XRPCError.fromError(outputUnvalidated) diff --git a/packages/xrpc-server/src/types.ts b/packages/xrpc-server/src/types.ts index dc75627a95f..35e88268975 100644 --- a/packages/xrpc-server/src/types.ts +++ b/packages/xrpc-server/src/types.ts @@ -143,7 +143,12 @@ export type RateLimiterStatus = { isFirstInDuration: boolean } +export type RouteOpts = { + blobLimit?: number +} + export type XRPCHandlerConfig = { + opts?: RouteOpts rateLimit?: HandlerRateLimitOpts | HandlerRateLimitOpts[] auth?: AuthVerifier handler: XRPCHandler diff --git a/packages/xrpc-server/src/util.ts b/packages/xrpc-server/src/util.ts index 730db950fbd..3c543d566e2 100644 --- a/packages/xrpc-server/src/util.ts +++ b/packages/xrpc-server/src/util.ts @@ -19,8 +19,8 @@ import { handlerSuccess, InvalidRequestError, InternalServerError, - Options, XRPCError, + RouteOpts, } from './types' export function decodeQueryParams( @@ -82,7 +82,7 @@ export function validateInput( nsid: string, def: LexXrpcProcedure | LexXrpcQuery, req: express.Request, - opts: Options, + opts: RouteOpts, lexicons: Lexicons, ): HandlerInput | undefined { // request expectation @@ -139,7 +139,7 @@ export function validateInput( if (req.readableEnded) { body = req.body } else { - body = decodeBodyStream(req, opts.payload?.blobLimit) + body = decodeBodyStream(req, opts.blobLimit) } return {