Skip to content

Commit 473cdfd

Browse files
committed
customizable block size
1 parent fc99a65 commit 473cdfd

File tree

3 files changed

+9
-10
lines changed

3 files changed

+9
-10
lines changed
-14.6 KB
Binary file not shown.

src/py/reactpy/reactpy/backend/_common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def safe_join_path(root: str | Path, *unsafe: str | Path) -> Path:
8686
path = os.path.abspath(os.path.join(root, *unsafe))
8787

8888
if os.path.commonprefix([root, path]) != root:
89-
# If the common prefix is not root directory we resolved outside the root dir
89+
# We resolved outside the root dir, potential directory traversal attack.
9090
raise ValueError(
9191
f"Unsafe path detected. Path '{path}' is outside root directory '{root}'"
9292
)

src/py/reactpy/reactpy/backend/asgi.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
from reactpy.core.serve import serve_layout
2626
from reactpy.core.types import ComponentConstructor, VdomDict
2727

28-
DEFAULT_BLOCK_SIZE = 8192
2928
_logger = logging.getLogger(__name__)
3029
_backhaul_loop = asyncio.new_event_loop()
3130

@@ -50,6 +49,7 @@ def __init__(
5049
static_dir: Path | str | None = None,
5150
head: Sequence[VdomDict] | VdomDict | str = "",
5251
backhaul_thread: bool = True,
52+
block_size: int = 8192,
5353
) -> None:
5454
self.component = (
5555
app_or_component
@@ -78,6 +78,7 @@ def __init__(
7878
self._cached_index_html = ""
7979
self.connected = False
8080
self.backhaul_thread = backhaul_thread
81+
self.block_size = block_size
8182
self.dispatcher_future_or_task = None
8283
if self.backhaul_thread and not _backhaul_thread.is_alive():
8384
_backhaul_thread.start()
@@ -172,7 +173,7 @@ async def js_modules_app(self, scope, receive, send) -> None:
172173
return
173174

174175
# Serve the file
175-
await file_response(scope, send, abs_file_path)
176+
await file_response(scope, send, abs_file_path, self.block_size)
176177

177178
async def static_file_app(self, scope, receive, send) -> None:
178179
"""ASGI app for ReactPy static files."""
@@ -192,7 +193,7 @@ async def static_file_app(self, scope, receive, send) -> None:
192193
return
193194

194195
# Serve the file
195-
await file_response(scope, send, abs_file_path)
196+
await file_response(scope, send, abs_file_path, self.block_size)
196197

197198
async def standalone_app(self, scope, receive, send) -> None:
198199
"""ASGI app for ReactPy standalone mode."""
@@ -276,7 +277,7 @@ async def http_response(
276277
await send({"type": "http.response.body", "body": message.encode()})
277278

278279

279-
async def file_response(scope, send, file_path: Path) -> None:
280+
async def file_response(scope, send, file_path: Path, block_size: int) -> None:
280281
"""Send a file in chunks."""
281282
# Make sure the file exists
282283
if not await asyncio.to_thread(os.path.exists, file_path):
@@ -289,7 +290,7 @@ async def file_response(scope, send, file_path: Path) -> None:
289290
return
290291

291292
# Check if the file is already cached by the client
292-
etag = await get_val_from_header(scope, b"etag")
293+
etag = await header_val(scope, b"etag")
293294
modification_time = await asyncio.to_thread(os.path.getmtime, file_path)
294295
if etag and etag != modification_time:
295296
await http_response(scope, send, 304, "Not modified.")
@@ -325,7 +326,7 @@ async def file_response(scope, send, file_path: Path) -> None:
325326
# Head requests don't need a body
326327
if scope["method"] != "HEAD":
327328
while True:
328-
chunk = await file_handle.read(DEFAULT_BLOCK_SIZE)
329+
chunk = await file_handle.read(block_size)
329330
more_body = bool(chunk)
330331
await send(
331332
{
@@ -338,9 +339,7 @@ async def file_response(scope, send, file_path: Path) -> None:
338339
break
339340

340341

341-
async def get_val_from_header(
342-
scope: dict, key: str, default: str | None = None
343-
) -> str | None:
342+
async def header_val(scope: dict, key: str, default: str | int | None = None) -> str | int | None:
344343
"""Get a value from a scope's headers."""
345344
return await anext(
346345
(

0 commit comments

Comments
 (0)