MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / downloadHandler

Function downloadHandler

packages/server/src/routes/fs.ts:211–302  ·  view source on GitHub ↗
(
    req,
    reply,
  )

Source from the content-addressed store, hash-verified

209 );
210
211 const downloadHandler: Parameters<FsRouteHost['get']>[2] = async (
212 req,
213 reply,
214 ) => {
215 const { session_id } = req.params as { session_id: string };
216 const wildcard = (req.params as Record<string, unknown>)['*'] as string;
217
218 const DOWNLOAD_SUFFIX = ':download';
219 if (!wildcard.endsWith(DOWNLOAD_SUFFIX)) {
220 return reply.send(
221 errEnvelope(
222 ErrorCode.VALIDATION_FAILED,
223 `unsupported action: ${wildcard}`,
224 req.id,
225 ),
226 );
227 }
228 const relPath = wildcard.slice(0, -DOWNLOAD_SUFFIX.length);
229 if (relPath.length === 0) {
230 return reply.send(
231 errEnvelope(
232 ErrorCode.VALIDATION_FAILED,
233 'path is empty',
234 req.id,
235 ),
236 );
237 }
238
239 let resolved: import('@moonshot-ai/agent-core').FsDownloadResolved;
240 try {
241 resolved = await ix.invokeFunction((a) =>
242 a.get(IFsService).resolveDownload(session_id, relPath),
243 );
244 } catch (err) {
245 sendMappedError(reply, req.id, err);
246 return reply;
247 }
248
249 const ifNoneMatch = pickHeader(req.headers, 'if-none-match');
250 if (ifNoneMatch !== undefined && ifNoneMatch === resolved.etag) {
251 return reply.code(304).header('etag', resolved.etag).send('');
252 }
253
254 reply.header('etag', resolved.etag);
255 reply.header(
256 'last-modified',
257 resolved.modifiedAt.toUTCString(),
258 );
259 reply.header(
260 'content-disposition',
261 `attachment; filename="${sanitizeFilename(resolved.relative)}"`,
262 );
263 reply.type(resolved.mime);
264
265 const rangeHeader = pickHeader(req.headers, 'range');
266 const range = parseRangeHeader(rangeHeader, resolved.size);
267 if (range !== null) {
268 reply

Callers

nothing calls this directly

Calls 14

errEnvelopeFunction · 0.90
pickHeaderFunction · 0.85
sanitizeFilenameFunction · 0.85
parseRangeHeaderFunction · 0.85
destroyMethod · 0.80
sendMappedErrorFunction · 0.70
sendMethod · 0.65
invokeFunctionMethod · 0.65
resolveDownloadMethod · 0.65
getMethod · 0.65
headerMethod · 0.65
codeMethod · 0.65

Tested by

no test coverage detected