Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions blacksheep/contents.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ cdef class StreamedContent(Content):
cdef readonly object generator


cdef class FilepathContent(Content):
cdef readonly str path


cdef class ASGIContent(Content):
cdef readonly object receive
cpdef void dispose(self)
Expand Down
8 changes: 8 additions & 0 deletions blacksheep/contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ async def get_parts(self):
yield chunk


class FilepathContent(Content):
def __init__(self, content_type: bytes, path: str):
self.type = content_type
self.body = None
self.length = 0
self.path = path


class ASGIContent(Content):
def __init__(self, receive):
self.type = None
Expand Down
11 changes: 11 additions & 0 deletions blacksheep/contents.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ class StreamedContent(Content):

async def get_parts(self) -> AsyncIterable[bytes]: ...

class FilepathContent(Content):
def __init__(
self,
content_type: bytes,
path: str,
) -> None:
self.type = content_type
self.body = None
self.length = 0
self.path = path

class ASGIContent(Content):
def __init__(self, receive: Callable[[], Awaitable[dict]]):
self.type = None
Expand Down
13 changes: 13 additions & 0 deletions blacksheep/contents.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ cdef class StreamedContent(Content):
yield chunk


cdef class FilepathContent(Content):

def __init__(
self,
bytes content_type,
str path
):
self.type = content_type
self.body = None
self.length = 0
self.path = path


cdef class ASGIContent(Content):

def __init__(self, object receive):
Expand Down
6 changes: 6 additions & 0 deletions blacksheep/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,12 @@ async def is_disconnected(self):
self._is_disconnected = True
return self._is_disconnected

@property
def accept_pathsend(self):
if not isinstance(self.content, ASGIContent) or self.scope is None:
return False
return "http.response.pathsend" in self.scope.get("extensions", {})


class Response(Message):
def __init__(self, status: int, headers=None, content: Content = None):
Expand Down
3 changes: 3 additions & 0 deletions blacksheep/messages.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ class Request(Message):
detect if the client closed the original connection.
"""

@property
def accept_pathsend(self) -> bool: ...

class Response(Message):
def __init__(
self,
Expand Down
5 changes: 5 additions & 0 deletions blacksheep/messages.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,11 @@ cdef class Request(Message):

return self._is_disconnected

@property
def accept_pathsend(self):
if not isinstance(self.content, ASGIContent) or self.scope is None:
return False
return "http.response.pathsend" in self.scope.get("extensions", {})

cdef class Response(Message):

Expand Down
4 changes: 3 additions & 1 deletion blacksheep/scribe.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import http
import re

from .contents import Content, StreamedContent
from .contents import Content, FilepathContent, StreamedContent
from .cookies import Cookie, write_cookie_for_response
from .messages import Request, Response

Expand Down Expand Up @@ -288,6 +288,8 @@ async def send_asgi_response(response: Response, send):
await send(
{"type": "http.response.body", "body": b"", "more_body": False}
)
elif isinstance(content, FilepathContent):
await send({"type": "http.response.pathsend", "path": content.path})
else:
if content.length > MAX_RESPONSE_CHUNK_SIZE:
for chunk in get_chunks(content.body):
Expand Down
3 changes: 3 additions & 0 deletions blacksheep/server/files/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from blacksheep.common.files.asyncfs import FilesHandler
from blacksheep.common.files.info import FileInfo
from blacksheep.common.files.pathsutils import get_mime_type_from_name
from blacksheep.contents import FilepathContent
from blacksheep.exceptions import BadRequest, InvalidArgument, RangeNotSatisfiable
from blacksheep.ranges import InvalidRangeValue, Range, RangePart
from blacksheep.server.headers.cache import CacheControlHeaderValue
Expand Down Expand Up @@ -289,6 +290,8 @@ def get_response_for_file(
file_type=file_type,
),
)
elif request.accept_pathsend:
content = FilepathContent(mime, resource_path)
else:
content = StreamedContent(
mime, get_file_getter(files_handler, resource_path, info.size)
Expand Down
Loading