MCPcopy
hub / github.com/encode/starlette / __call__

Method __call__

starlette/responses.py:340–382  ·  starlette/responses.py::FileResponse.__call__
(self, scope: Scope, receive: Receive, send: Send)

Source from the content-addressed store, hash-verified

338 self.headers.setdefault(class="st">"etag", etag)
339
340 async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
341 scope_type = scope[class="st">"type"]
342 send_header_only = scope_type == class="st">"http" and scope[class="st">"method"].upper() == class="st">"HEAD"
343 send_pathsend = scope_type == class="st">"http" and class="st">"http.response.pathsend" in scope.get(class="st">"extensions", {})
344 if scope_type == class="st">"websocket":
345 send = self._wrap_websocket_denial_send(send)
346
347 if self.stat_result is None:
348 try:
349 stat_result = await anyio.to_thread.run_sync(os.stat, self.path)
350 self.set_stat_headers(stat_result)
351 except FileNotFoundError:
352 raise RuntimeError(fclass="st">"File at path {self.path} does not exist.")
353 else:
354 mode = stat_result.st_mode
355 if not stat.S_ISREG(mode):
356 raise RuntimeError(fclass="st">"File at path {self.path} is not a file.")
357 else:
358 stat_result = self.stat_result
359
360 headers = Headers(scope=scope)
361 http_range = headers.get(class="st">"range")
362 http_if_range = headers.get(class="st">"if-range")
363
364 if http_range is None or (http_if_range is not None and not self._should_use_range(http_if_range)):
365 await self._handle_simple(send, send_header_only, send_pathsend)
366 else:
367 try:
368 ranges = self._parse_range_header(http_range, stat_result.st_size)
369 except MalformedRangeHeader as exc:
370 return await PlainTextResponse(exc.content, status_code=400)(scope, receive, send)
371 except RangeNotSatisfiable as exc:
372 response = PlainTextResponse(status_code=416, headers={class="st">"Content-Range": fclass="st">"bytes */{exc.max_size}"})
373 return await response(scope, receive, send)
374
375 if len(ranges) == 1:
376 start, end = ranges[0]
377 await self._handle_single_range(send, start, end, stat_result.st_size, send_header_only)
378 else:
379 await self._handle_multiple_ranges(send, ranges, stat_result.st_size, send_header_only)
380
381 if self.background is not None:
382 await self.background()
383
384 async def _handle_simple(self, send: Send, send_header_only: bool, send_pathsend: bool) -> None:
385 await send({class="st">"type": class="st">"http.response.start", class="st">"status": self.status_code, class="st">"headers": self.raw_headers})

Callers

nothing calls this directly

Calls 11

set_stat_headersMethod · 0.95
_should_use_rangeMethod · 0.95
_handle_simpleMethod · 0.95
_parse_range_headerMethod · 0.95
_handle_single_rangeMethod · 0.95
HeadersClass · 0.90
PlainTextResponseClass · 0.85
backgroundMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected