mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 17:20:30 +08:00
pikvm/pikvm#92: attempt to fix "Multiple access in eof state"
This commit is contained in:
parent
ada307c624
commit
cc6f7c417e
@ -20,6 +20,8 @@
|
|||||||
# ========================================================================== #
|
# ========================================================================== #
|
||||||
|
|
||||||
|
|
||||||
|
import types
|
||||||
|
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import AsyncGenerator
|
from typing import AsyncGenerator
|
||||||
@ -35,6 +37,20 @@ class StreamerError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
# =====
|
# =====
|
||||||
|
def _patch_stream_reader(reader: aiohttp.StreamReader) -> None:
|
||||||
|
# https://github.com/pikvm/pikvm/issues/92
|
||||||
|
# Infinite looping in BodyPartReader.read() because _at_eof flag.
|
||||||
|
|
||||||
|
orig_read = reader.read
|
||||||
|
|
||||||
|
async def read(self: aiohttp.StreamReader, n: int=-1) -> bytes: # pylint: disable=invalid-name
|
||||||
|
if self.is_eof():
|
||||||
|
raise StreamerError("StreamReader.read(): Reached EOF")
|
||||||
|
return (await orig_read(n))
|
||||||
|
|
||||||
|
reader.read = types.MethodType(read, reader) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class StreamerClient:
|
class StreamerClient:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -61,15 +77,13 @@ class StreamerClient:
|
|||||||
) as response:
|
) as response:
|
||||||
htclient.raise_not_200(response)
|
htclient.raise_not_200(response)
|
||||||
reader = aiohttp.MultipartReader.from_response(response)
|
reader = aiohttp.MultipartReader.from_response(response)
|
||||||
|
_patch_stream_reader(reader.resp.content)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
frame = await reader.next() # pylint: disable=not-callable
|
frame = await reader.next() # pylint: disable=not-callable
|
||||||
if not isinstance(frame, aiohttp.BodyPartReader):
|
if not isinstance(frame, aiohttp.BodyPartReader):
|
||||||
raise RuntimeError("Expected body part")
|
raise StreamerError("Expected body part")
|
||||||
|
|
||||||
if hasattr(frame, "_content"):
|
|
||||||
if frame._content.is_eof(): # pylint: disable=protected-access
|
|
||||||
break
|
|
||||||
data = bytes(await frame.read())
|
data = bytes(await frame.read())
|
||||||
if not data:
|
if not data:
|
||||||
break
|
break
|
||||||
@ -80,7 +94,9 @@ class StreamerClient:
|
|||||||
int(frame.headers["X-UStreamer-Height"]),
|
int(frame.headers["X-UStreamer-Height"]),
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
except Exception as err: # Тут бывают и ассерты, и KeyError, и прочая херня из-за корявых исключений в MultipartReader
|
except Exception as err: # Тут бывают и ассерты, и KeyError, и прочая херня
|
||||||
|
if isinstance(err, StreamerError):
|
||||||
|
raise
|
||||||
raise StreamerError(f"{type(err).__name__}: {err}")
|
raise StreamerError(f"{type(err).__name__}: {err}")
|
||||||
raise StreamerError("Reached EOF")
|
raise StreamerError("Reached EOF")
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user