fix: sign /upload with empty body — API skips body parsing for streams
The upload endpoint streams the request body in chunks without buffering, so raw_body stays empty on the server side. The HMAC must sign against an empty body string to match. _sign_from_disk (which hashed file contents) produced signatures the server could never verify — every upload got 401.
This commit is contained in:
parent
c3072c2a6e
commit
94166be988
1 changed files with 5 additions and 16 deletions
|
|
@ -41,32 +41,21 @@ def _sign_body(secret_key, timestamp, method, path, body_bytes):
|
|||
return h.hexdigest()
|
||||
|
||||
|
||||
def _sign_from_disk(secret_key, timestamp, method, path, file_path):
|
||||
"""Incremental HMAC-SHA256 matching un._sign_request but reading from disk.
|
||||
|
||||
Produces: HMAC(key, "ts:METHOD:path:" + <file contents>)
|
||||
"""
|
||||
h = hmac.new(secret_key.encode(), digestmod=hashlib.sha256)
|
||||
h.update(f"{timestamp}:{method}:{path}:".encode())
|
||||
with open(file_path, "rb") as f:
|
||||
while True:
|
||||
chunk = f.read(_READ_CHUNK)
|
||||
if not chunk:
|
||||
break
|
||||
h.update(chunk)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def _upload_file(file_path, filename, public_key, secret_key):
|
||||
"""Upload a file via POST /upload (streaming, constant memory).
|
||||
|
||||
Returns the upload_id string.
|
||||
|
||||
Note: the API skips body parsing for /upload (body streams in chunks),
|
||||
so the HMAC signs against an empty body — not the file content.
|
||||
"""
|
||||
timestamp = int(time.time())
|
||||
method = "POST"
|
||||
path = "/upload"
|
||||
|
||||
signature = _sign_from_disk(secret_key, timestamp, method, path, file_path)
|
||||
# API doesn't buffer upload bodies for HMAC — sign with empty body
|
||||
signature = _sign_body(secret_key, timestamp, method, path, "")
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {public_key}",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue