Skip to content

Commit 217508b

Browse files
committed
Fixes 2
1 parent 4f667a7 commit 217508b

File tree

4 files changed

+23
-11
lines changed

4 files changed

+23
-11
lines changed

app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
async def lifespan(app: FastAPI):
1616
setup_logging()
1717
sentry_sdk.init(release=os.getenv('DEPLOYMENT_ID', 'local'))
18-
app.state.redis = redis.asyncio.from_url(os.getenv('REDIS_URL', 'redis://localhost:6379'), decode_responses=True)
18+
app.state.redis = redis.asyncio.from_url(os.getenv('REDIS_URL', 'redis://localhost:6379'))
1919
yield
2020
await app.state.redis.aclose()
2121

lib/metadata.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from starlette.datastructures import Headers
2-
from pydantic import BaseModel, Field, StrictStr, field_validator, ByteSize, ConfigDict, AliasChoices
3-
from typing import Optional, Self, Annotated
2+
from pydantic import BaseModel, ByteSize, ConfigDict, Field, field_validator, StrictStr
3+
from typing import Annotated, Optional, Self
4+
import re
45

56

67
class FileMetadata(BaseModel):
@@ -13,8 +14,19 @@ class FileMetadata(BaseModel):
1314
@field_validator('name')
1415
@classmethod
1516
def validate_name(cls, v: str) -> str:
16-
safe_filename = str(v).translate(str.maketrans(':;|*@/\\', ' ')).strip()
17-
return safe_filename.encode('latin-1', 'ignore').decode('utf-8', 'ignore')
17+
if not v or not v.strip():
18+
raise ValueError("Filename cannot be empty")
19+
20+
safe_filename = re.sub(r'[<>:"/\\|?*\x00-\x1f]', ' ', str(v)).strip()
21+
if not safe_filename:
22+
raise ValueError("Filename contains only invalid characters")
23+
24+
try:
25+
safe_filename = safe_filename.encode('utf-8').decode('utf-8')
26+
except UnicodeError:
27+
safe_filename = safe_filename.encode('utf-8', 'ignore').decode('utf-8', 'ignore')
28+
29+
return safe_filename
1830

1931
@classmethod
2032
def from_json(cls, data: str) -> Self:

lib/store.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def __init__(self, transfer_id: str):
2323
self._k_metadata = self.key('metadata')
2424
self._k_position = self.key('position')
2525
self._k_progress = self.key('progress')
26+
self._k_receiver_active = self.key('receiver_active')
2627

2728
@classmethod
2829
def get_redis(cls) -> redis.Redis:
@@ -38,16 +39,15 @@ def key(self, name: str) -> str:
3839

3940
async def add_chunk(self, data: bytes) -> None:
4041
"""Add chunk to stream."""
41-
# No maxlen limit - streams auto-expire after 5 minutes
4242
await self.redis.xadd(self._k_stream, {'data': data})
4343

44-
async def stream_chunks(self, timeout_ms: int = 20000):
44+
async def stream_chunks(self, read_timeout: float = 20.0):
4545
"""Stream chunks from last position."""
4646
position = await self.redis.get(self._k_position)
4747
last_id = position.decode() if position else '0'
4848

4949
while True:
50-
result = await self.redis.xread({self._k_stream: last_id}, block=timeout_ms)
50+
result = await self.redis.xread({self._k_stream: last_id}, block=int(read_timeout*1000))
5151
if not result:
5252
raise TimeoutError("Stream read timeout")
5353

@@ -119,11 +119,11 @@ async def get_progress(self) -> int:
119119

120120
async def set_receiver_active(self) -> None:
121121
"""Mark receiver as actively downloading with TTL."""
122-
await self.redis.set(self.key('receiver_active'), '1', ex=5)
122+
await self.redis.set(self._k_receiver_active, '1', ex=5)
123123

124124
async def is_receiver_active(self) -> bool:
125125
"""Check if receiver is actively downloading."""
126-
return bool(await self.redis.exists(self.key('receiver_active')))
126+
return bool(await self.redis.exists(self._k_receiver_active))
127127

128128
async def cleanup(self) -> None:
129129
"""Delete all transfer data."""

static/js/file-transfer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const BUFFER_CHECK_INTERVAL = 200; // 200ms interval for buffer checks
99
const SHARE_LINK_FOCUS_DELAY = 300; // 300ms delay before focusing share link
1010
const TRANSFER_FINALIZE_DELAY = 1000; // 1000ms delay before finalizing transfer
1111
const MOBILE_BREAKPOINT = 768; // 768px mobile breakpoint
12-
const TRANSFER_ID_MAX_NUMBER = 999; // Maximum number for transfer ID generation
12+
const TRANSFER_ID_MAX_NUMBER = 1000; // Maximum number for transfer ID generation
1313

1414
const log = {
1515
debug: (...args) => DEBUG && console.debug(...args),

0 commit comments

Comments
 (0)