Length-prefixed binary framing for OCaml↔Python pipe
Replace newline-delimited text protocol with length-prefixed blobs for all response data (send_ok_string, send_ok_raw). The OCaml side sends (ok-len N)\n followed by exactly N raw bytes + \n. Python reads the length, then readexactly(N). This eliminates all pipe desync issues: - No escaping needed for any content (HTML, SX with newlines, quotes) - No size limits (1MB+ responses work cleanly) - No multi-line response splitting - No double-escaping bugs The old (ok "...") and (ok-raw ...) formats are still parsed as fallbacks for backward compatibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -497,6 +497,13 @@ class OcamlBridge:
|
||||
Returns (kind, value) where kind is "ok" or "error".
|
||||
"""
|
||||
line = await self._readline()
|
||||
# Length-prefixed blob
|
||||
if line.startswith("(ok-len "):
|
||||
n = int(line[8:-1])
|
||||
assert self._proc and self._proc.stdout
|
||||
data = await self._proc.stdout.readexactly(n)
|
||||
await self._proc.stdout.readline() # trailing newline
|
||||
return ("ok", data.decode())
|
||||
return _parse_response(line)
|
||||
|
||||
async def _read_until_ok(
|
||||
@@ -547,6 +554,15 @@ class OcamlBridge:
|
||||
pending_batch = []
|
||||
continue
|
||||
|
||||
# Length-prefixed blob: (ok-len N)
|
||||
if line.startswith("(ok-len "):
|
||||
n = int(line[8:-1])
|
||||
assert self._proc and self._proc.stdout
|
||||
data = await self._proc.stdout.readexactly(n)
|
||||
# Read trailing newline
|
||||
await self._proc.stdout.readline()
|
||||
return data.decode()
|
||||
|
||||
kind, value = _parse_response(line)
|
||||
if kind == "error":
|
||||
raise OcamlBridgeError(value or "Unknown error")
|
||||
|
||||
Reference in New Issue
Block a user