Initial commit
This commit is contained in:
23
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__init__.py
vendored
Executable file
23
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__init__.py
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
"""Utilities for asyncio-friendly file handling."""
|
||||
|
||||
from . import tempfile
|
||||
from .threadpool import (
|
||||
open,
|
||||
stderr,
|
||||
stderr_bytes,
|
||||
stdin,
|
||||
stdin_bytes,
|
||||
stdout,
|
||||
stdout_bytes,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"open",
|
||||
"tempfile",
|
||||
"stdin",
|
||||
"stdout",
|
||||
"stderr",
|
||||
"stdin_bytes",
|
||||
"stdout_bytes",
|
||||
"stderr_bytes",
|
||||
]
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__pycache__/base.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__pycache__/base.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__pycache__/os.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__pycache__/os.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__pycache__/ospath.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/__pycache__/ospath.cpython-313.pyc
vendored
Executable file
Binary file not shown.
79
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/base.py
vendored
Executable file
79
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/base.py
vendored
Executable file
@@ -0,0 +1,79 @@
|
||||
from asyncio import get_running_loop
|
||||
from collections.abc import Awaitable
|
||||
from contextlib import AbstractAsyncContextManager
|
||||
from functools import partial, wraps
|
||||
|
||||
|
||||
def wrap(func):
|
||||
@wraps(func)
|
||||
async def run(*args, loop=None, executor=None, **kwargs):
|
||||
if loop is None:
|
||||
loop = get_running_loop()
|
||||
pfunc = partial(func, *args, **kwargs)
|
||||
return await loop.run_in_executor(executor, pfunc)
|
||||
|
||||
return run
|
||||
|
||||
|
||||
class AsyncBase:
|
||||
def __init__(self, file, loop, executor):
|
||||
self._file = file
|
||||
self._executor = executor
|
||||
self._ref_loop = loop
|
||||
|
||||
@property
|
||||
def _loop(self):
|
||||
return self._ref_loop or get_running_loop()
|
||||
|
||||
def __aiter__(self):
|
||||
"""We are our own iterator."""
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
return super().__repr__() + " wrapping " + repr(self._file)
|
||||
|
||||
async def __anext__(self):
|
||||
"""Simulate normal file iteration."""
|
||||
|
||||
if line := await self.readline():
|
||||
return line
|
||||
raise StopAsyncIteration
|
||||
|
||||
|
||||
class AsyncIndirectBase(AsyncBase):
|
||||
def __init__(self, name, loop, executor, indirect):
|
||||
self._indirect = indirect
|
||||
self._name = name
|
||||
super().__init__(None, loop, executor)
|
||||
|
||||
@property
|
||||
def _file(self):
|
||||
return self._indirect()
|
||||
|
||||
@_file.setter
|
||||
def _file(self, v):
|
||||
pass # discard writes
|
||||
|
||||
|
||||
class AiofilesContextManager(Awaitable, AbstractAsyncContextManager):
|
||||
"""An adjusted async context manager for aiofiles."""
|
||||
|
||||
__slots__ = ("_coro", "_obj")
|
||||
|
||||
def __init__(self, coro):
|
||||
self._coro = coro
|
||||
self._obj = None
|
||||
|
||||
def __await__(self):
|
||||
if self._obj is None:
|
||||
self._obj = yield from self._coro.__await__()
|
||||
return self._obj
|
||||
|
||||
async def __aenter__(self):
|
||||
return await self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
await get_running_loop().run_in_executor(
|
||||
None, self._obj._file.__exit__, exc_type, exc_val, exc_tb
|
||||
)
|
||||
self._obj = None
|
||||
61
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/os.py
vendored
Executable file
61
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/os.py
vendored
Executable file
@@ -0,0 +1,61 @@
|
||||
"""Async executor versions of file functions from the os module."""
|
||||
|
||||
import os
|
||||
|
||||
from . import ospath as path
|
||||
from .base import wrap
|
||||
|
||||
__all__ = [
|
||||
"path",
|
||||
"stat",
|
||||
"rename",
|
||||
"renames",
|
||||
"replace",
|
||||
"remove",
|
||||
"unlink",
|
||||
"mkdir",
|
||||
"makedirs",
|
||||
"rmdir",
|
||||
"removedirs",
|
||||
"symlink",
|
||||
"readlink",
|
||||
"listdir",
|
||||
"scandir",
|
||||
"access",
|
||||
"wrap",
|
||||
"getcwd",
|
||||
]
|
||||
|
||||
access = wrap(os.access)
|
||||
|
||||
getcwd = wrap(os.getcwd)
|
||||
|
||||
listdir = wrap(os.listdir)
|
||||
|
||||
makedirs = wrap(os.makedirs)
|
||||
mkdir = wrap(os.mkdir)
|
||||
|
||||
readlink = wrap(os.readlink)
|
||||
remove = wrap(os.remove)
|
||||
removedirs = wrap(os.removedirs)
|
||||
rename = wrap(os.rename)
|
||||
renames = wrap(os.renames)
|
||||
replace = wrap(os.replace)
|
||||
rmdir = wrap(os.rmdir)
|
||||
|
||||
scandir = wrap(os.scandir)
|
||||
stat = wrap(os.stat)
|
||||
symlink = wrap(os.symlink)
|
||||
|
||||
unlink = wrap(os.unlink)
|
||||
|
||||
|
||||
if hasattr(os, "link"):
|
||||
__all__ += ["link"]
|
||||
link = wrap(os.link)
|
||||
if hasattr(os, "sendfile"):
|
||||
__all__ += ["sendfile"]
|
||||
sendfile = wrap(os.sendfile)
|
||||
if hasattr(os, "statvfs"):
|
||||
__all__ += ["statvfs"]
|
||||
statvfs = wrap(os.statvfs)
|
||||
37
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/ospath.py
vendored
Executable file
37
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/ospath.py
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
"""Async executor versions of file functions from the os.path module."""
|
||||
|
||||
from os import path
|
||||
|
||||
from .base import wrap
|
||||
|
||||
__all__ = [
|
||||
"abspath",
|
||||
"getatime",
|
||||
"getctime",
|
||||
"getmtime",
|
||||
"getsize",
|
||||
"exists",
|
||||
"isdir",
|
||||
"isfile",
|
||||
"islink",
|
||||
"ismount",
|
||||
"samefile",
|
||||
"sameopenfile",
|
||||
]
|
||||
|
||||
abspath = wrap(path.abspath)
|
||||
|
||||
getatime = wrap(path.getatime)
|
||||
getctime = wrap(path.getctime)
|
||||
getmtime = wrap(path.getmtime)
|
||||
getsize = wrap(path.getsize)
|
||||
|
||||
exists = wrap(path.exists)
|
||||
|
||||
isdir = wrap(path.isdir)
|
||||
isfile = wrap(path.isfile)
|
||||
islink = wrap(path.islink)
|
||||
ismount = wrap(path.ismount)
|
||||
|
||||
samefile = wrap(path.samefile)
|
||||
sameopenfile = wrap(path.sameopenfile)
|
||||
357
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/tempfile/__init__.py
vendored
Executable file
357
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/tempfile/__init__.py
vendored
Executable file
@@ -0,0 +1,357 @@
|
||||
import asyncio
|
||||
import sys
|
||||
from functools import partial, singledispatch
|
||||
from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOBase
|
||||
from tempfile import NamedTemporaryFile as syncNamedTemporaryFile
|
||||
from tempfile import SpooledTemporaryFile as syncSpooledTemporaryFile
|
||||
from tempfile import TemporaryDirectory as syncTemporaryDirectory
|
||||
from tempfile import TemporaryFile as syncTemporaryFile
|
||||
from tempfile import _TemporaryFileWrapper as syncTemporaryFileWrapper
|
||||
|
||||
from ..base import AiofilesContextManager
|
||||
from ..threadpool.binary import AsyncBufferedIOBase, AsyncBufferedReader, AsyncFileIO
|
||||
from ..threadpool.text import AsyncTextIOWrapper
|
||||
from .temptypes import AsyncSpooledTemporaryFile, AsyncTemporaryDirectory
|
||||
|
||||
__all__ = [
|
||||
"NamedTemporaryFile",
|
||||
"TemporaryFile",
|
||||
"SpooledTemporaryFile",
|
||||
"TemporaryDirectory",
|
||||
]
|
||||
|
||||
|
||||
# ================================================================
|
||||
# Public methods for async open and return of temp file/directory
|
||||
# objects with async interface
|
||||
# ================================================================
|
||||
if sys.version_info >= (3, 12):
|
||||
|
||||
def NamedTemporaryFile(
|
||||
mode="w+b",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
newline=None,
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
delete=True,
|
||||
delete_on_close=True,
|
||||
loop=None,
|
||||
executor=None,
|
||||
):
|
||||
"""Async open a named temporary file"""
|
||||
return AiofilesContextManager(
|
||||
_temporary_file(
|
||||
named=True,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
delete=delete,
|
||||
delete_on_close=delete_on_close,
|
||||
loop=loop,
|
||||
executor=executor,
|
||||
)
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
def NamedTemporaryFile(
|
||||
mode="w+b",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
newline=None,
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
delete=True,
|
||||
loop=None,
|
||||
executor=None,
|
||||
):
|
||||
"""Async open a named temporary file"""
|
||||
return AiofilesContextManager(
|
||||
_temporary_file(
|
||||
named=True,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
delete=delete,
|
||||
loop=loop,
|
||||
executor=executor,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def TemporaryFile(
|
||||
mode="w+b",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
newline=None,
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
loop=None,
|
||||
executor=None,
|
||||
):
|
||||
"""Async open an unnamed temporary file"""
|
||||
return AiofilesContextManager(
|
||||
_temporary_file(
|
||||
named=False,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
loop=loop,
|
||||
executor=executor,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def SpooledTemporaryFile(
|
||||
max_size=0,
|
||||
mode="w+b",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
newline=None,
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
loop=None,
|
||||
executor=None,
|
||||
):
|
||||
"""Async open a spooled temporary file"""
|
||||
return AiofilesContextManager(
|
||||
_spooled_temporary_file(
|
||||
max_size=max_size,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
loop=loop,
|
||||
executor=executor,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def TemporaryDirectory(suffix=None, prefix=None, dir=None, loop=None, executor=None):
|
||||
"""Async open a temporary directory"""
|
||||
return AiofilesContextManagerTempDir(
|
||||
_temporary_directory(
|
||||
suffix=suffix, prefix=prefix, dir=dir, loop=loop, executor=executor
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# =========================================================
|
||||
# Internal coroutines to open new temp files/directories
|
||||
# =========================================================
|
||||
if sys.version_info >= (3, 12):
|
||||
|
||||
async def _temporary_file(
|
||||
named=True,
|
||||
mode="w+b",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
newline=None,
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
delete=True,
|
||||
delete_on_close=True,
|
||||
loop=None,
|
||||
executor=None,
|
||||
max_size=0,
|
||||
):
|
||||
"""Async method to open a temporary file with async interface"""
|
||||
if loop is None:
|
||||
loop = asyncio.get_running_loop()
|
||||
|
||||
if named:
|
||||
cb = partial(
|
||||
syncNamedTemporaryFile,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
delete=delete,
|
||||
delete_on_close=delete_on_close,
|
||||
)
|
||||
else:
|
||||
cb = partial(
|
||||
syncTemporaryFile,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
)
|
||||
|
||||
f = await loop.run_in_executor(executor, cb)
|
||||
|
||||
# Wrap based on type of underlying IO object
|
||||
if type(f) is syncTemporaryFileWrapper:
|
||||
# _TemporaryFileWrapper was used (named files)
|
||||
result = wrap(f.file, f, loop=loop, executor=executor)
|
||||
result._closer = f._closer
|
||||
return result
|
||||
# IO object was returned directly without wrapper
|
||||
return wrap(f, f, loop=loop, executor=executor)
|
||||
|
||||
else:
|
||||
|
||||
async def _temporary_file(
|
||||
named=True,
|
||||
mode="w+b",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
newline=None,
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
delete=True,
|
||||
loop=None,
|
||||
executor=None,
|
||||
max_size=0,
|
||||
):
|
||||
"""Async method to open a temporary file with async interface"""
|
||||
if loop is None:
|
||||
loop = asyncio.get_running_loop()
|
||||
|
||||
if named:
|
||||
cb = partial(
|
||||
syncNamedTemporaryFile,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
delete=delete,
|
||||
)
|
||||
else:
|
||||
cb = partial(
|
||||
syncTemporaryFile,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
)
|
||||
|
||||
f = await loop.run_in_executor(executor, cb)
|
||||
|
||||
# Wrap based on type of underlying IO object
|
||||
if type(f) is syncTemporaryFileWrapper:
|
||||
# _TemporaryFileWrapper was used (named files)
|
||||
result = wrap(f.file, f, loop=loop, executor=executor)
|
||||
# add delete property
|
||||
result.delete = f.delete
|
||||
return result
|
||||
# IO object was returned directly without wrapper
|
||||
return wrap(f, f, loop=loop, executor=executor)
|
||||
|
||||
|
||||
async def _spooled_temporary_file(
|
||||
max_size=0,
|
||||
mode="w+b",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
newline=None,
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
loop=None,
|
||||
executor=None,
|
||||
):
|
||||
"""Open a spooled temporary file with async interface"""
|
||||
if loop is None:
|
||||
loop = asyncio.get_running_loop()
|
||||
|
||||
cb = partial(
|
||||
syncSpooledTemporaryFile,
|
||||
max_size=max_size,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
newline=newline,
|
||||
suffix=suffix,
|
||||
prefix=prefix,
|
||||
dir=dir,
|
||||
)
|
||||
|
||||
f = await loop.run_in_executor(executor, cb)
|
||||
|
||||
# Single interface provided by SpooledTemporaryFile for all modes
|
||||
return AsyncSpooledTemporaryFile(f, loop=loop, executor=executor)
|
||||
|
||||
|
||||
async def _temporary_directory(
|
||||
suffix=None, prefix=None, dir=None, loop=None, executor=None
|
||||
):
|
||||
"""Async method to open a temporary directory with async interface"""
|
||||
if loop is None:
|
||||
loop = asyncio.get_running_loop()
|
||||
|
||||
cb = partial(syncTemporaryDirectory, suffix, prefix, dir)
|
||||
f = await loop.run_in_executor(executor, cb)
|
||||
|
||||
return AsyncTemporaryDirectory(f, loop=loop, executor=executor)
|
||||
|
||||
|
||||
class AiofilesContextManagerTempDir(AiofilesContextManager):
|
||||
"""With returns the directory location, not the object (matching sync lib)"""
|
||||
|
||||
async def __aenter__(self):
|
||||
self._obj = await self._coro
|
||||
return self._obj.name
|
||||
|
||||
|
||||
@singledispatch
|
||||
def wrap(base_io_obj, file, *, loop=None, executor=None):
|
||||
"""Wrap the object with interface based on type of underlying IO"""
|
||||
|
||||
msg = f"Unsupported IO type: {base_io_obj}"
|
||||
raise TypeError(msg)
|
||||
|
||||
|
||||
@wrap.register(TextIOBase)
|
||||
def _(base_io_obj, file, *, loop=None, executor=None):
|
||||
return AsyncTextIOWrapper(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(BufferedWriter)
|
||||
def _(base_io_obj, file, *, loop=None, executor=None):
|
||||
return AsyncBufferedIOBase(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(BufferedReader)
|
||||
@wrap.register(BufferedRandom)
|
||||
def _(base_io_obj, file, *, loop=None, executor=None):
|
||||
return AsyncBufferedReader(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(FileIO)
|
||||
def _(base_io_obj, file, *, loop=None, executor=None):
|
||||
return AsyncFileIO(file, loop=loop, executor=executor)
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/tempfile/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/tempfile/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/tempfile/__pycache__/temptypes.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/tempfile/__pycache__/temptypes.cpython-313.pyc
vendored
Executable file
Binary file not shown.
70
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/tempfile/temptypes.py
vendored
Executable file
70
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/tempfile/temptypes.py
vendored
Executable file
@@ -0,0 +1,70 @@
|
||||
"""Async wrappers for spooled temp files and temp directory objects"""
|
||||
|
||||
from functools import partial
|
||||
|
||||
from ..base import AsyncBase
|
||||
from ..threadpool.utils import (
|
||||
cond_delegate_to_executor,
|
||||
delegate_to_executor,
|
||||
proxy_property_directly,
|
||||
)
|
||||
|
||||
|
||||
@delegate_to_executor("fileno", "rollover")
|
||||
@cond_delegate_to_executor(
|
||||
"close",
|
||||
"flush",
|
||||
"isatty",
|
||||
"read",
|
||||
"readline",
|
||||
"readlines",
|
||||
"seek",
|
||||
"tell",
|
||||
"truncate",
|
||||
)
|
||||
@proxy_property_directly("closed", "encoding", "mode", "name", "newlines")
|
||||
class AsyncSpooledTemporaryFile(AsyncBase):
|
||||
"""Async wrapper for SpooledTemporaryFile class"""
|
||||
|
||||
async def _check(self):
|
||||
if self._file._rolled:
|
||||
return
|
||||
max_size = self._file._max_size
|
||||
if max_size and self._file.tell() > max_size:
|
||||
await self.rollover()
|
||||
|
||||
async def write(self, s):
|
||||
"""Implementation to anticipate rollover"""
|
||||
if self._file._rolled:
|
||||
cb = partial(self._file.write, s)
|
||||
return await self._loop.run_in_executor(self._executor, cb)
|
||||
|
||||
file = self._file._file # reference underlying base IO object
|
||||
rv = file.write(s)
|
||||
await self._check()
|
||||
return rv
|
||||
|
||||
async def writelines(self, iterable):
|
||||
"""Implementation to anticipate rollover"""
|
||||
if self._file._rolled:
|
||||
cb = partial(self._file.writelines, iterable)
|
||||
return await self._loop.run_in_executor(self._executor, cb)
|
||||
|
||||
file = self._file._file # reference underlying base IO object
|
||||
rv = file.writelines(iterable)
|
||||
await self._check()
|
||||
return rv
|
||||
|
||||
|
||||
@delegate_to_executor("cleanup")
|
||||
@proxy_property_directly("name")
|
||||
class AsyncTemporaryDirectory:
|
||||
"""Async wrapper for TemporaryDirectory class"""
|
||||
|
||||
def __init__(self, file, loop, executor):
|
||||
self._file = file
|
||||
self._loop = loop
|
||||
self._executor = executor
|
||||
|
||||
async def close(self):
|
||||
await self.cleanup()
|
||||
141
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__init__.py
vendored
Executable file
141
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__init__.py
vendored
Executable file
@@ -0,0 +1,141 @@
|
||||
"""Handle files using a thread pool executor."""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
from functools import partial, singledispatch
|
||||
from io import (
|
||||
BufferedIOBase,
|
||||
BufferedRandom,
|
||||
BufferedReader,
|
||||
BufferedWriter,
|
||||
FileIO,
|
||||
TextIOBase,
|
||||
)
|
||||
|
||||
from ..base import AiofilesContextManager
|
||||
from .binary import (
|
||||
AsyncBufferedIOBase,
|
||||
AsyncBufferedReader,
|
||||
AsyncFileIO,
|
||||
AsyncIndirectBufferedIOBase,
|
||||
)
|
||||
from .text import AsyncTextIndirectIOWrapper, AsyncTextIOWrapper
|
||||
|
||||
sync_open = open
|
||||
|
||||
__all__ = (
|
||||
"open",
|
||||
"stdin",
|
||||
"stdout",
|
||||
"stderr",
|
||||
"stdin_bytes",
|
||||
"stdout_bytes",
|
||||
"stderr_bytes",
|
||||
)
|
||||
|
||||
|
||||
def open(
|
||||
file,
|
||||
mode="r",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
errors=None,
|
||||
newline=None,
|
||||
closefd=True,
|
||||
opener=None,
|
||||
*,
|
||||
loop=None,
|
||||
executor=None,
|
||||
):
|
||||
return AiofilesContextManager(
|
||||
_open(
|
||||
file,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
errors=errors,
|
||||
newline=newline,
|
||||
closefd=closefd,
|
||||
opener=opener,
|
||||
loop=loop,
|
||||
executor=executor,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def _open(
|
||||
file,
|
||||
mode="r",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
errors=None,
|
||||
newline=None,
|
||||
closefd=True,
|
||||
opener=None,
|
||||
*,
|
||||
loop=None,
|
||||
executor=None,
|
||||
):
|
||||
"""Open an asyncio file."""
|
||||
if loop is None:
|
||||
loop = asyncio.get_running_loop()
|
||||
cb = partial(
|
||||
sync_open,
|
||||
file,
|
||||
mode=mode,
|
||||
buffering=buffering,
|
||||
encoding=encoding,
|
||||
errors=errors,
|
||||
newline=newline,
|
||||
closefd=closefd,
|
||||
opener=opener,
|
||||
)
|
||||
f = await loop.run_in_executor(executor, cb)
|
||||
|
||||
return wrap(f, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@singledispatch
|
||||
def wrap(file, *, loop=None, executor=None):
|
||||
msg = f"Unsupported io type: {file}."
|
||||
raise TypeError(msg)
|
||||
|
||||
|
||||
@wrap.register(TextIOBase)
|
||||
def _(file, *, loop=None, executor=None):
|
||||
return AsyncTextIOWrapper(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(BufferedWriter)
|
||||
@wrap.register(BufferedIOBase)
|
||||
def _(file, *, loop=None, executor=None):
|
||||
return AsyncBufferedIOBase(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(BufferedReader)
|
||||
@wrap.register(BufferedRandom)
|
||||
def _(file, *, loop=None, executor=None):
|
||||
return AsyncBufferedReader(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(FileIO)
|
||||
def _(file, *, loop=None, executor=None):
|
||||
return AsyncFileIO(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
stdin = AsyncTextIndirectIOWrapper("sys.stdin", None, None, indirect=lambda: sys.stdin)
|
||||
stdout = AsyncTextIndirectIOWrapper(
|
||||
"sys.stdout", None, None, indirect=lambda: sys.stdout
|
||||
)
|
||||
stderr = AsyncTextIndirectIOWrapper(
|
||||
"sys.stderr", None, None, indirect=lambda: sys.stderr
|
||||
)
|
||||
stdin_bytes = AsyncIndirectBufferedIOBase(
|
||||
"sys.stdin.buffer", None, None, indirect=lambda: sys.stdin.buffer
|
||||
)
|
||||
stdout_bytes = AsyncIndirectBufferedIOBase(
|
||||
"sys.stdout.buffer", None, None, indirect=lambda: sys.stdout.buffer
|
||||
)
|
||||
stderr_bytes = AsyncIndirectBufferedIOBase(
|
||||
"sys.stderr.buffer", None, None, indirect=lambda: sys.stderr.buffer
|
||||
)
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__pycache__/binary.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__pycache__/binary.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__pycache__/text.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__pycache__/text.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__pycache__/utils.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/__pycache__/utils.cpython-313.pyc
vendored
Executable file
Binary file not shown.
104
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/binary.py
vendored
Executable file
104
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/binary.py
vendored
Executable file
@@ -0,0 +1,104 @@
|
||||
from ..base import AsyncBase, AsyncIndirectBase
|
||||
from .utils import delegate_to_executor, proxy_method_directly, proxy_property_directly
|
||||
|
||||
|
||||
@delegate_to_executor(
|
||||
"close",
|
||||
"flush",
|
||||
"isatty",
|
||||
"read",
|
||||
"read1",
|
||||
"readinto",
|
||||
"readline",
|
||||
"readlines",
|
||||
"seek",
|
||||
"seekable",
|
||||
"tell",
|
||||
"truncate",
|
||||
"writable",
|
||||
"write",
|
||||
"writelines",
|
||||
)
|
||||
@proxy_method_directly("detach", "fileno", "readable")
|
||||
@proxy_property_directly("closed", "raw", "name", "mode")
|
||||
class AsyncBufferedIOBase(AsyncBase):
|
||||
"""The asyncio executor version of io.BufferedWriter and BufferedIOBase."""
|
||||
|
||||
|
||||
@delegate_to_executor("peek")
|
||||
class AsyncBufferedReader(AsyncBufferedIOBase):
|
||||
"""The asyncio executor version of io.BufferedReader and Random."""
|
||||
|
||||
|
||||
@delegate_to_executor(
|
||||
"close",
|
||||
"flush",
|
||||
"isatty",
|
||||
"read",
|
||||
"readall",
|
||||
"readinto",
|
||||
"readline",
|
||||
"readlines",
|
||||
"seek",
|
||||
"seekable",
|
||||
"tell",
|
||||
"truncate",
|
||||
"writable",
|
||||
"write",
|
||||
"writelines",
|
||||
)
|
||||
@proxy_method_directly("fileno", "readable")
|
||||
@proxy_property_directly("closed", "name", "mode")
|
||||
class AsyncFileIO(AsyncBase):
|
||||
"""The asyncio executor version of io.FileIO."""
|
||||
|
||||
|
||||
@delegate_to_executor(
|
||||
"close",
|
||||
"flush",
|
||||
"isatty",
|
||||
"read",
|
||||
"read1",
|
||||
"readinto",
|
||||
"readline",
|
||||
"readlines",
|
||||
"seek",
|
||||
"seekable",
|
||||
"tell",
|
||||
"truncate",
|
||||
"writable",
|
||||
"write",
|
||||
"writelines",
|
||||
)
|
||||
@proxy_method_directly("detach", "fileno", "readable")
|
||||
@proxy_property_directly("closed", "raw", "name", "mode")
|
||||
class AsyncIndirectBufferedIOBase(AsyncIndirectBase):
|
||||
"""The indirect asyncio executor version of io.BufferedWriter and BufferedIOBase."""
|
||||
|
||||
|
||||
@delegate_to_executor("peek")
|
||||
class AsyncIndirectBufferedReader(AsyncIndirectBufferedIOBase):
|
||||
"""The indirect asyncio executor version of io.BufferedReader and Random."""
|
||||
|
||||
|
||||
@delegate_to_executor(
|
||||
"close",
|
||||
"flush",
|
||||
"isatty",
|
||||
"read",
|
||||
"readall",
|
||||
"readinto",
|
||||
"readline",
|
||||
"readlines",
|
||||
"seek",
|
||||
"seekable",
|
||||
"tell",
|
||||
"truncate",
|
||||
"writable",
|
||||
"write",
|
||||
"writelines",
|
||||
)
|
||||
@proxy_method_directly("fileno", "readable")
|
||||
@proxy_property_directly("closed", "name", "mode")
|
||||
class AsyncIndirectFileIO(AsyncIndirectBase):
|
||||
"""The indirect asyncio executor version of io.FileIO."""
|
||||
64
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/text.py
vendored
Executable file
64
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/text.py
vendored
Executable file
@@ -0,0 +1,64 @@
|
||||
from ..base import AsyncBase, AsyncIndirectBase
|
||||
from .utils import delegate_to_executor, proxy_method_directly, proxy_property_directly
|
||||
|
||||
|
||||
@delegate_to_executor(
|
||||
"close",
|
||||
"flush",
|
||||
"isatty",
|
||||
"read",
|
||||
"readable",
|
||||
"readline",
|
||||
"readlines",
|
||||
"seek",
|
||||
"seekable",
|
||||
"tell",
|
||||
"truncate",
|
||||
"write",
|
||||
"writable",
|
||||
"writelines",
|
||||
)
|
||||
@proxy_method_directly("detach", "fileno", "readable")
|
||||
@proxy_property_directly(
|
||||
"buffer",
|
||||
"closed",
|
||||
"encoding",
|
||||
"errors",
|
||||
"line_buffering",
|
||||
"newlines",
|
||||
"name",
|
||||
"mode",
|
||||
)
|
||||
class AsyncTextIOWrapper(AsyncBase):
|
||||
"""The asyncio executor version of io.TextIOWrapper."""
|
||||
|
||||
|
||||
@delegate_to_executor(
|
||||
"close",
|
||||
"flush",
|
||||
"isatty",
|
||||
"read",
|
||||
"readable",
|
||||
"readline",
|
||||
"readlines",
|
||||
"seek",
|
||||
"seekable",
|
||||
"tell",
|
||||
"truncate",
|
||||
"write",
|
||||
"writable",
|
||||
"writelines",
|
||||
)
|
||||
@proxy_method_directly("detach", "fileno", "readable")
|
||||
@proxy_property_directly(
|
||||
"buffer",
|
||||
"closed",
|
||||
"encoding",
|
||||
"errors",
|
||||
"line_buffering",
|
||||
"newlines",
|
||||
"name",
|
||||
"mode",
|
||||
)
|
||||
class AsyncTextIndirectIOWrapper(AsyncIndirectBase):
|
||||
"""The indirect asyncio executor version of io.TextIOWrapper."""
|
||||
71
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/utils.py
vendored
Executable file
71
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiofiles/threadpool/utils.py
vendored
Executable file
@@ -0,0 +1,71 @@
|
||||
import functools
|
||||
|
||||
|
||||
def delegate_to_executor(*attrs):
|
||||
def cls_builder(cls):
|
||||
for attr_name in attrs:
|
||||
setattr(cls, attr_name, _make_delegate_method(attr_name))
|
||||
return cls
|
||||
|
||||
return cls_builder
|
||||
|
||||
|
||||
def proxy_method_directly(*attrs):
|
||||
def cls_builder(cls):
|
||||
for attr_name in attrs:
|
||||
setattr(cls, attr_name, _make_proxy_method(attr_name))
|
||||
return cls
|
||||
|
||||
return cls_builder
|
||||
|
||||
|
||||
def proxy_property_directly(*attrs):
|
||||
def cls_builder(cls):
|
||||
for attr_name in attrs:
|
||||
setattr(cls, attr_name, _make_proxy_property(attr_name))
|
||||
return cls
|
||||
|
||||
return cls_builder
|
||||
|
||||
|
||||
def cond_delegate_to_executor(*attrs):
|
||||
def cls_builder(cls):
|
||||
for attr_name in attrs:
|
||||
setattr(cls, attr_name, _make_cond_delegate_method(attr_name))
|
||||
return cls
|
||||
|
||||
return cls_builder
|
||||
|
||||
|
||||
def _make_delegate_method(attr_name):
|
||||
async def method(self, *args, **kwargs):
|
||||
cb = functools.partial(getattr(self._file, attr_name), *args, **kwargs)
|
||||
return await self._loop.run_in_executor(self._executor, cb)
|
||||
|
||||
return method
|
||||
|
||||
|
||||
def _make_proxy_method(attr_name):
|
||||
def method(self, *args, **kwargs):
|
||||
return getattr(self._file, attr_name)(*args, **kwargs)
|
||||
|
||||
return method
|
||||
|
||||
|
||||
def _make_proxy_property(attr_name):
|
||||
def proxy_property(self):
|
||||
return getattr(self._file, attr_name)
|
||||
|
||||
return property(proxy_property)
|
||||
|
||||
|
||||
def _make_cond_delegate_method(attr_name):
|
||||
"""For spooled temp files, delegate only if rolled to file object"""
|
||||
|
||||
async def method(self, *args, **kwargs):
|
||||
if self._file._rolled:
|
||||
cb = functools.partial(getattr(self._file, attr_name), *args, **kwargs)
|
||||
return await self._loop.run_in_executor(self._executor, cb)
|
||||
return getattr(self._file, attr_name)(*args, **kwargs)
|
||||
|
||||
return method
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/_cparser.pxd.hash
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/_cparser.pxd.hash
vendored
Executable file
@@ -0,0 +1 @@
|
||||
5276d46021e0e0d7577e0c9155800cbf62932d60a50783fec42aefb63febedec /Users/runner/work/aiohttp/aiohttp/aiohttp/_cparser.pxd
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/_find_header.pxd.hash
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/_find_header.pxd.hash
vendored
Executable file
@@ -0,0 +1 @@
|
||||
d067f01423cddb3c442933b5fcc039b18ab651fcec1bc91c577693aafc25cf78 /Users/runner/work/aiohttp/aiohttp/aiohttp/_find_header.pxd
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/_http_parser.pyx.hash
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/_http_parser.pyx.hash
vendored
Executable file
@@ -0,0 +1 @@
|
||||
f9823c608638b8a77fec1c2bd28dc5c043f08c775ec59e7e262dd74b4ebb7384 /Users/runner/work/aiohttp/aiohttp/aiohttp/_http_parser.pyx
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/_http_writer.pyx.hash
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/_http_writer.pyx.hash
vendored
Executable file
@@ -0,0 +1 @@
|
||||
56514404ce87a15bfc6b400026d73a270165b2fdbe70313cfa007de29ddd7e14 /Users/runner/work/aiohttp/aiohttp/aiohttp/_http_writer.pyx
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/hdrs.py.hash
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/.hash/hdrs.py.hash
vendored
Executable file
@@ -0,0 +1 @@
|
||||
dab8f933203eeb245d60f856e542a45b888d5a110094620e4811f90f816628d1 /Users/runner/work/aiohttp/aiohttp/aiohttp/hdrs.py
|
||||
278
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__init__.py
vendored
Executable file
278
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__init__.py
vendored
Executable file
@@ -0,0 +1,278 @@
|
||||
__version__ = "3.13.3"
|
||||
|
||||
from typing import TYPE_CHECKING, Tuple
|
||||
|
||||
from . import hdrs as hdrs
|
||||
from .client import (
|
||||
BaseConnector,
|
||||
ClientConnectionError,
|
||||
ClientConnectionResetError,
|
||||
ClientConnectorCertificateError,
|
||||
ClientConnectorDNSError,
|
||||
ClientConnectorError,
|
||||
ClientConnectorSSLError,
|
||||
ClientError,
|
||||
ClientHttpProxyError,
|
||||
ClientOSError,
|
||||
ClientPayloadError,
|
||||
ClientProxyConnectionError,
|
||||
ClientRequest,
|
||||
ClientResponse,
|
||||
ClientResponseError,
|
||||
ClientSession,
|
||||
ClientSSLError,
|
||||
ClientTimeout,
|
||||
ClientWebSocketResponse,
|
||||
ClientWSTimeout,
|
||||
ConnectionTimeoutError,
|
||||
ContentTypeError,
|
||||
Fingerprint,
|
||||
InvalidURL,
|
||||
InvalidUrlClientError,
|
||||
InvalidUrlRedirectClientError,
|
||||
NamedPipeConnector,
|
||||
NonHttpUrlClientError,
|
||||
NonHttpUrlRedirectClientError,
|
||||
RedirectClientError,
|
||||
RequestInfo,
|
||||
ServerConnectionError,
|
||||
ServerDisconnectedError,
|
||||
ServerFingerprintMismatch,
|
||||
ServerTimeoutError,
|
||||
SocketTimeoutError,
|
||||
TCPConnector,
|
||||
TooManyRedirects,
|
||||
UnixConnector,
|
||||
WSMessageTypeError,
|
||||
WSServerHandshakeError,
|
||||
request,
|
||||
)
|
||||
from .client_middleware_digest_auth import DigestAuthMiddleware
|
||||
from .client_middlewares import ClientHandlerType, ClientMiddlewareType
|
||||
from .compression_utils import set_zlib_backend
|
||||
from .connector import (
|
||||
AddrInfoType as AddrInfoType,
|
||||
SocketFactoryType as SocketFactoryType,
|
||||
)
|
||||
from .cookiejar import CookieJar as CookieJar, DummyCookieJar as DummyCookieJar
|
||||
from .formdata import FormData as FormData
|
||||
from .helpers import BasicAuth, ChainMapProxy, ETag
|
||||
from .http import (
|
||||
HttpVersion as HttpVersion,
|
||||
HttpVersion10 as HttpVersion10,
|
||||
HttpVersion11 as HttpVersion11,
|
||||
WebSocketError as WebSocketError,
|
||||
WSCloseCode as WSCloseCode,
|
||||
WSMessage as WSMessage,
|
||||
WSMsgType as WSMsgType,
|
||||
)
|
||||
from .multipart import (
|
||||
BadContentDispositionHeader as BadContentDispositionHeader,
|
||||
BadContentDispositionParam as BadContentDispositionParam,
|
||||
BodyPartReader as BodyPartReader,
|
||||
MultipartReader as MultipartReader,
|
||||
MultipartWriter as MultipartWriter,
|
||||
content_disposition_filename as content_disposition_filename,
|
||||
parse_content_disposition as parse_content_disposition,
|
||||
)
|
||||
from .payload import (
|
||||
PAYLOAD_REGISTRY as PAYLOAD_REGISTRY,
|
||||
AsyncIterablePayload as AsyncIterablePayload,
|
||||
BufferedReaderPayload as BufferedReaderPayload,
|
||||
BytesIOPayload as BytesIOPayload,
|
||||
BytesPayload as BytesPayload,
|
||||
IOBasePayload as IOBasePayload,
|
||||
JsonPayload as JsonPayload,
|
||||
Payload as Payload,
|
||||
StringIOPayload as StringIOPayload,
|
||||
StringPayload as StringPayload,
|
||||
TextIOPayload as TextIOPayload,
|
||||
get_payload as get_payload,
|
||||
payload_type as payload_type,
|
||||
)
|
||||
from .payload_streamer import streamer as streamer
|
||||
from .resolver import (
|
||||
AsyncResolver as AsyncResolver,
|
||||
DefaultResolver as DefaultResolver,
|
||||
ThreadedResolver as ThreadedResolver,
|
||||
)
|
||||
from .streams import (
|
||||
EMPTY_PAYLOAD as EMPTY_PAYLOAD,
|
||||
DataQueue as DataQueue,
|
||||
EofStream as EofStream,
|
||||
FlowControlDataQueue as FlowControlDataQueue,
|
||||
StreamReader as StreamReader,
|
||||
)
|
||||
from .tracing import (
|
||||
TraceConfig as TraceConfig,
|
||||
TraceConnectionCreateEndParams as TraceConnectionCreateEndParams,
|
||||
TraceConnectionCreateStartParams as TraceConnectionCreateStartParams,
|
||||
TraceConnectionQueuedEndParams as TraceConnectionQueuedEndParams,
|
||||
TraceConnectionQueuedStartParams as TraceConnectionQueuedStartParams,
|
||||
TraceConnectionReuseconnParams as TraceConnectionReuseconnParams,
|
||||
TraceDnsCacheHitParams as TraceDnsCacheHitParams,
|
||||
TraceDnsCacheMissParams as TraceDnsCacheMissParams,
|
||||
TraceDnsResolveHostEndParams as TraceDnsResolveHostEndParams,
|
||||
TraceDnsResolveHostStartParams as TraceDnsResolveHostStartParams,
|
||||
TraceRequestChunkSentParams as TraceRequestChunkSentParams,
|
||||
TraceRequestEndParams as TraceRequestEndParams,
|
||||
TraceRequestExceptionParams as TraceRequestExceptionParams,
|
||||
TraceRequestHeadersSentParams as TraceRequestHeadersSentParams,
|
||||
TraceRequestRedirectParams as TraceRequestRedirectParams,
|
||||
TraceRequestStartParams as TraceRequestStartParams,
|
||||
TraceResponseChunkReceivedParams as TraceResponseChunkReceivedParams,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# At runtime these are lazy-loaded at the bottom of the file.
|
||||
from .worker import (
|
||||
GunicornUVLoopWebWorker as GunicornUVLoopWebWorker,
|
||||
GunicornWebWorker as GunicornWebWorker,
|
||||
)
|
||||
|
||||
__all__: Tuple[str, ...] = (
|
||||
"hdrs",
|
||||
# client
|
||||
"AddrInfoType",
|
||||
"BaseConnector",
|
||||
"ClientConnectionError",
|
||||
"ClientConnectionResetError",
|
||||
"ClientConnectorCertificateError",
|
||||
"ClientConnectorDNSError",
|
||||
"ClientConnectorError",
|
||||
"ClientConnectorSSLError",
|
||||
"ClientError",
|
||||
"ClientHttpProxyError",
|
||||
"ClientOSError",
|
||||
"ClientPayloadError",
|
||||
"ClientProxyConnectionError",
|
||||
"ClientResponse",
|
||||
"ClientRequest",
|
||||
"ClientResponseError",
|
||||
"ClientSSLError",
|
||||
"ClientSession",
|
||||
"ClientTimeout",
|
||||
"ClientWebSocketResponse",
|
||||
"ClientWSTimeout",
|
||||
"ConnectionTimeoutError",
|
||||
"ContentTypeError",
|
||||
"Fingerprint",
|
||||
"FlowControlDataQueue",
|
||||
"InvalidURL",
|
||||
"InvalidUrlClientError",
|
||||
"InvalidUrlRedirectClientError",
|
||||
"NonHttpUrlClientError",
|
||||
"NonHttpUrlRedirectClientError",
|
||||
"RedirectClientError",
|
||||
"RequestInfo",
|
||||
"ServerConnectionError",
|
||||
"ServerDisconnectedError",
|
||||
"ServerFingerprintMismatch",
|
||||
"ServerTimeoutError",
|
||||
"SocketFactoryType",
|
||||
"SocketTimeoutError",
|
||||
"TCPConnector",
|
||||
"TooManyRedirects",
|
||||
"UnixConnector",
|
||||
"NamedPipeConnector",
|
||||
"WSServerHandshakeError",
|
||||
"request",
|
||||
# client_middleware
|
||||
"ClientMiddlewareType",
|
||||
"ClientHandlerType",
|
||||
# cookiejar
|
||||
"CookieJar",
|
||||
"DummyCookieJar",
|
||||
# formdata
|
||||
"FormData",
|
||||
# helpers
|
||||
"BasicAuth",
|
||||
"ChainMapProxy",
|
||||
"DigestAuthMiddleware",
|
||||
"ETag",
|
||||
"set_zlib_backend",
|
||||
# http
|
||||
"HttpVersion",
|
||||
"HttpVersion10",
|
||||
"HttpVersion11",
|
||||
"WSMsgType",
|
||||
"WSCloseCode",
|
||||
"WSMessage",
|
||||
"WebSocketError",
|
||||
# multipart
|
||||
"BadContentDispositionHeader",
|
||||
"BadContentDispositionParam",
|
||||
"BodyPartReader",
|
||||
"MultipartReader",
|
||||
"MultipartWriter",
|
||||
"content_disposition_filename",
|
||||
"parse_content_disposition",
|
||||
# payload
|
||||
"AsyncIterablePayload",
|
||||
"BufferedReaderPayload",
|
||||
"BytesIOPayload",
|
||||
"BytesPayload",
|
||||
"IOBasePayload",
|
||||
"JsonPayload",
|
||||
"PAYLOAD_REGISTRY",
|
||||
"Payload",
|
||||
"StringIOPayload",
|
||||
"StringPayload",
|
||||
"TextIOPayload",
|
||||
"get_payload",
|
||||
"payload_type",
|
||||
# payload_streamer
|
||||
"streamer",
|
||||
# resolver
|
||||
"AsyncResolver",
|
||||
"DefaultResolver",
|
||||
"ThreadedResolver",
|
||||
# streams
|
||||
"DataQueue",
|
||||
"EMPTY_PAYLOAD",
|
||||
"EofStream",
|
||||
"StreamReader",
|
||||
# tracing
|
||||
"TraceConfig",
|
||||
"TraceConnectionCreateEndParams",
|
||||
"TraceConnectionCreateStartParams",
|
||||
"TraceConnectionQueuedEndParams",
|
||||
"TraceConnectionQueuedStartParams",
|
||||
"TraceConnectionReuseconnParams",
|
||||
"TraceDnsCacheHitParams",
|
||||
"TraceDnsCacheMissParams",
|
||||
"TraceDnsResolveHostEndParams",
|
||||
"TraceDnsResolveHostStartParams",
|
||||
"TraceRequestChunkSentParams",
|
||||
"TraceRequestEndParams",
|
||||
"TraceRequestExceptionParams",
|
||||
"TraceRequestHeadersSentParams",
|
||||
"TraceRequestRedirectParams",
|
||||
"TraceRequestStartParams",
|
||||
"TraceResponseChunkReceivedParams",
|
||||
# workers (imported lazily with __getattr__)
|
||||
"GunicornUVLoopWebWorker",
|
||||
"GunicornWebWorker",
|
||||
"WSMessageTypeError",
|
||||
)
|
||||
|
||||
|
||||
def __dir__() -> Tuple[str, ...]:
|
||||
return __all__ + ("__doc__",)
|
||||
|
||||
|
||||
def __getattr__(name: str) -> object:
|
||||
global GunicornUVLoopWebWorker, GunicornWebWorker
|
||||
|
||||
# Importing gunicorn takes a long time (>100ms), so only import if actually needed.
|
||||
if name in ("GunicornUVLoopWebWorker", "GunicornWebWorker"):
|
||||
try:
|
||||
from .worker import GunicornUVLoopWebWorker as guv, GunicornWebWorker as gw
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
GunicornUVLoopWebWorker = guv # type: ignore[misc]
|
||||
GunicornWebWorker = gw # type: ignore[misc]
|
||||
return guv if name == "GunicornUVLoopWebWorker" else gw
|
||||
|
||||
raise AttributeError(f"module {__name__} has no attribute {name}")
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/_cookie_helpers.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/_cookie_helpers.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/abc.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/abc.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/base_protocol.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/base_protocol.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_exceptions.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_exceptions.cpython-313.pyc
vendored
Executable file
Binary file not shown.
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_middlewares.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_middlewares.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_proto.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_proto.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_reqrep.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_reqrep.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_ws.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/client_ws.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/compression_utils.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/compression_utils.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/connector.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/connector.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/cookiejar.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/cookiejar.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/formdata.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/formdata.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/hdrs.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/hdrs.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/helpers.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/helpers.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http_exceptions.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http_exceptions.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http_parser.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http_parser.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http_websocket.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http_websocket.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http_writer.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/http_writer.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/log.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/log.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/multipart.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/multipart.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/payload.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/payload.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/payload_streamer.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/payload_streamer.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/pytest_plugin.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/pytest_plugin.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/resolver.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/resolver.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/streams.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/streams.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/tcp_helpers.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/tcp_helpers.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/test_utils.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/test_utils.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/tracing.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/tracing.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/typedefs.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/typedefs.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_app.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_app.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_exceptions.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_exceptions.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_fileresponse.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_fileresponse.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_log.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_log.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_middlewares.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_middlewares.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_protocol.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_protocol.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_request.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_request.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_response.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_response.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_routedef.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_routedef.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_runner.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_runner.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_server.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_server.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_urldispatcher.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_urldispatcher.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_ws.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/web_ws.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/worker.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/__pycache__/worker.cpython-313.pyc
vendored
Executable file
Binary file not shown.
338
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_cookie_helpers.py
vendored
Executable file
338
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_cookie_helpers.py
vendored
Executable file
@@ -0,0 +1,338 @@
|
||||
"""
|
||||
Internal cookie handling helpers.
|
||||
|
||||
This module contains internal utilities for cookie parsing and manipulation.
|
||||
These are not part of the public API and may change without notice.
|
||||
"""
|
||||
|
||||
import re
|
||||
from http.cookies import Morsel
|
||||
from typing import List, Optional, Sequence, Tuple, cast
|
||||
|
||||
from .log import internal_logger
|
||||
|
||||
__all__ = (
|
||||
"parse_set_cookie_headers",
|
||||
"parse_cookie_header",
|
||||
"preserve_morsel_with_coded_value",
|
||||
)
|
||||
|
||||
# Cookie parsing constants
|
||||
# Allow more characters in cookie names to handle real-world cookies
|
||||
# that don't strictly follow RFC standards (fixes #2683)
|
||||
# RFC 6265 defines cookie-name token as per RFC 2616 Section 2.2,
|
||||
# but many servers send cookies with characters like {} [] () etc.
|
||||
# This makes the cookie parser more tolerant of real-world cookies
|
||||
# while still providing some validation to catch obviously malformed names.
|
||||
_COOKIE_NAME_RE = re.compile(r"^[!#$%&\'()*+\-./0-9:<=>?@A-Z\[\]^_`a-z{|}~]+$")
|
||||
_COOKIE_KNOWN_ATTRS = frozenset( # AKA Morsel._reserved
|
||||
(
|
||||
"path",
|
||||
"domain",
|
||||
"max-age",
|
||||
"expires",
|
||||
"secure",
|
||||
"httponly",
|
||||
"samesite",
|
||||
"partitioned",
|
||||
"version",
|
||||
"comment",
|
||||
)
|
||||
)
|
||||
_COOKIE_BOOL_ATTRS = frozenset( # AKA Morsel._flags
|
||||
("secure", "httponly", "partitioned")
|
||||
)
|
||||
|
||||
# SimpleCookie's pattern for parsing cookies with relaxed validation
|
||||
# Based on http.cookies pattern but extended to allow more characters in cookie names
|
||||
# to handle real-world cookies (fixes #2683)
|
||||
_COOKIE_PATTERN = re.compile(
|
||||
r"""
|
||||
\s* # Optional whitespace at start of cookie
|
||||
(?P<key> # Start of group 'key'
|
||||
# aiohttp has extended to include [] for compatibility with real-world cookies
|
||||
[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\[\]]+ # Any word of at least one letter
|
||||
) # End of group 'key'
|
||||
( # Optional group: there may not be a value.
|
||||
\s*=\s* # Equal Sign
|
||||
(?P<val> # Start of group 'val'
|
||||
"(?:[^\\"]|\\.)*" # Any double-quoted string (properly closed)
|
||||
| # or
|
||||
"[^";]* # Unmatched opening quote (differs from SimpleCookie - issue #7993)
|
||||
| # or
|
||||
# Special case for "expires" attr - RFC 822, RFC 850, RFC 1036, RFC 1123
|
||||
(\w{3,6}day|\w{3}),\s # Day of the week or abbreviated day (with comma)
|
||||
[\w\d\s-]{9,11}\s[\d:]{8}\s # Date and time in specific format
|
||||
(GMT|[+-]\d{4}) # Timezone: GMT or RFC 2822 offset like -0000, +0100
|
||||
# NOTE: RFC 2822 timezone support is an aiohttp extension
|
||||
# for issue #4493 - SimpleCookie does NOT support this
|
||||
| # or
|
||||
# ANSI C asctime() format: "Wed Jun 9 10:18:14 2021"
|
||||
# NOTE: This is an aiohttp extension for issue #4327 - SimpleCookie does NOT support this format
|
||||
\w{3}\s+\w{3}\s+[\s\d]\d\s+\d{2}:\d{2}:\d{2}\s+\d{4}
|
||||
| # or
|
||||
[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=\[\]]* # Any word or empty string
|
||||
) # End of group 'val'
|
||||
)? # End of optional value group
|
||||
\s* # Any number of spaces.
|
||||
(\s+|;|$) # Ending either at space, semicolon, or EOS.
|
||||
""",
|
||||
re.VERBOSE | re.ASCII,
|
||||
)
|
||||
|
||||
|
||||
def preserve_morsel_with_coded_value(cookie: Morsel[str]) -> Morsel[str]:
|
||||
"""
|
||||
Preserve a Morsel's coded_value exactly as received from the server.
|
||||
|
||||
This function ensures that cookie encoding is preserved exactly as sent by
|
||||
the server, which is critical for compatibility with old servers that have
|
||||
strict requirements about cookie formats.
|
||||
|
||||
This addresses the issue described in https://github.com/aio-libs/aiohttp/pull/1453
|
||||
where Python's SimpleCookie would re-encode cookies, breaking authentication
|
||||
with certain servers.
|
||||
|
||||
Args:
|
||||
cookie: A Morsel object from SimpleCookie
|
||||
|
||||
Returns:
|
||||
A Morsel object with preserved coded_value
|
||||
|
||||
"""
|
||||
mrsl_val = cast("Morsel[str]", cookie.get(cookie.key, Morsel()))
|
||||
# We use __setstate__ instead of the public set() API because it allows us to
|
||||
# bypass validation and set already validated state. This is more stable than
|
||||
# setting protected attributes directly and unlikely to change since it would
|
||||
# break pickling.
|
||||
mrsl_val.__setstate__( # type: ignore[attr-defined]
|
||||
{"key": cookie.key, "value": cookie.value, "coded_value": cookie.coded_value}
|
||||
)
|
||||
return mrsl_val
|
||||
|
||||
|
||||
_unquote_sub = re.compile(r"\\(?:([0-3][0-7][0-7])|(.))").sub
|
||||
|
||||
|
||||
def _unquote_replace(m: re.Match[str]) -> str:
|
||||
"""
|
||||
Replace function for _unquote_sub regex substitution.
|
||||
|
||||
Handles escaped characters in cookie values:
|
||||
- Octal sequences are converted to their character representation
|
||||
- Other escaped characters are unescaped by removing the backslash
|
||||
"""
|
||||
if m[1]:
|
||||
return chr(int(m[1], 8))
|
||||
return m[2]
|
||||
|
||||
|
||||
def _unquote(value: str) -> str:
|
||||
"""
|
||||
Unquote a cookie value.
|
||||
|
||||
Vendored from http.cookies._unquote to ensure compatibility.
|
||||
|
||||
Note: The original implementation checked for None, but we've removed
|
||||
that check since all callers already ensure the value is not None.
|
||||
"""
|
||||
# If there aren't any doublequotes,
|
||||
# then there can't be any special characters. See RFC 2109.
|
||||
if len(value) < 2:
|
||||
return value
|
||||
if value[0] != '"' or value[-1] != '"':
|
||||
return value
|
||||
|
||||
# We have to assume that we must decode this string.
|
||||
# Down to work.
|
||||
|
||||
# Remove the "s
|
||||
value = value[1:-1]
|
||||
|
||||
# Check for special sequences. Examples:
|
||||
# \012 --> \n
|
||||
# \" --> "
|
||||
#
|
||||
return _unquote_sub(_unquote_replace, value)
|
||||
|
||||
|
||||
def parse_cookie_header(header: str) -> List[Tuple[str, Morsel[str]]]:
|
||||
"""
|
||||
Parse a Cookie header according to RFC 6265 Section 5.4.
|
||||
|
||||
Cookie headers contain only name-value pairs separated by semicolons.
|
||||
There are no attributes in Cookie headers - even names that match
|
||||
attribute names (like 'path' or 'secure') should be treated as cookies.
|
||||
|
||||
This parser uses the same regex-based approach as parse_set_cookie_headers
|
||||
to properly handle quoted values that may contain semicolons. When the
|
||||
regex fails to match a malformed cookie, it falls back to simple parsing
|
||||
to ensure subsequent cookies are not lost
|
||||
https://github.com/aio-libs/aiohttp/issues/11632
|
||||
|
||||
Args:
|
||||
header: The Cookie header value to parse
|
||||
|
||||
Returns:
|
||||
List of (name, Morsel) tuples for compatibility with SimpleCookie.update()
|
||||
"""
|
||||
if not header:
|
||||
return []
|
||||
|
||||
cookies: List[Tuple[str, Morsel[str]]] = []
|
||||
morsel: Morsel[str]
|
||||
i = 0
|
||||
n = len(header)
|
||||
|
||||
invalid_names = []
|
||||
while i < n:
|
||||
# Use the same pattern as parse_set_cookie_headers to find cookies
|
||||
match = _COOKIE_PATTERN.match(header, i)
|
||||
if not match:
|
||||
# Fallback for malformed cookies https://github.com/aio-libs/aiohttp/issues/11632
|
||||
# Find next semicolon to skip or attempt simple key=value parsing
|
||||
next_semi = header.find(";", i)
|
||||
eq_pos = header.find("=", i)
|
||||
|
||||
# Try to extract key=value if '=' comes before ';'
|
||||
if eq_pos != -1 and (next_semi == -1 or eq_pos < next_semi):
|
||||
end_pos = next_semi if next_semi != -1 else n
|
||||
key = header[i:eq_pos].strip()
|
||||
value = header[eq_pos + 1 : end_pos].strip()
|
||||
|
||||
# Validate the name (same as regex path)
|
||||
if not _COOKIE_NAME_RE.match(key):
|
||||
invalid_names.append(key)
|
||||
else:
|
||||
morsel = Morsel()
|
||||
morsel.__setstate__( # type: ignore[attr-defined]
|
||||
{"key": key, "value": _unquote(value), "coded_value": value}
|
||||
)
|
||||
cookies.append((key, morsel))
|
||||
|
||||
# Move to next cookie or end
|
||||
i = next_semi + 1 if next_semi != -1 else n
|
||||
continue
|
||||
|
||||
key = match.group("key")
|
||||
value = match.group("val") or ""
|
||||
i = match.end(0)
|
||||
|
||||
# Validate the name
|
||||
if not key or not _COOKIE_NAME_RE.match(key):
|
||||
invalid_names.append(key)
|
||||
continue
|
||||
|
||||
# Create new morsel
|
||||
morsel = Morsel()
|
||||
# Preserve the original value as coded_value (with quotes if present)
|
||||
# We use __setstate__ instead of the public set() API because it allows us to
|
||||
# bypass validation and set already validated state. This is more stable than
|
||||
# setting protected attributes directly and unlikely to change since it would
|
||||
# break pickling.
|
||||
morsel.__setstate__( # type: ignore[attr-defined]
|
||||
{"key": key, "value": _unquote(value), "coded_value": value}
|
||||
)
|
||||
|
||||
cookies.append((key, morsel))
|
||||
|
||||
if invalid_names:
|
||||
internal_logger.debug(
|
||||
"Cannot load cookie. Illegal cookie names: %r", invalid_names
|
||||
)
|
||||
|
||||
return cookies
|
||||
|
||||
|
||||
def parse_set_cookie_headers(headers: Sequence[str]) -> List[Tuple[str, Morsel[str]]]:
|
||||
"""
|
||||
Parse cookie headers using a vendored version of SimpleCookie parsing.
|
||||
|
||||
This implementation is based on SimpleCookie.__parse_string to ensure
|
||||
compatibility with how SimpleCookie parses cookies, including handling
|
||||
of malformed cookies with missing semicolons.
|
||||
|
||||
This function is used for both Cookie and Set-Cookie headers in order to be
|
||||
forgiving. Ideally we would have followed RFC 6265 Section 5.2 (for Cookie
|
||||
headers) and RFC 6265 Section 4.2.1 (for Set-Cookie headers), but the
|
||||
real world data makes it impossible since we need to be a bit more forgiving.
|
||||
|
||||
NOTE: This implementation differs from SimpleCookie in handling unmatched quotes.
|
||||
SimpleCookie will stop parsing when it encounters a cookie value with an unmatched
|
||||
quote (e.g., 'cookie="value'), causing subsequent cookies to be silently dropped.
|
||||
This implementation handles unmatched quotes more gracefully to prevent cookie loss.
|
||||
See https://github.com/aio-libs/aiohttp/issues/7993
|
||||
"""
|
||||
parsed_cookies: List[Tuple[str, Morsel[str]]] = []
|
||||
|
||||
for header in headers:
|
||||
if not header:
|
||||
continue
|
||||
|
||||
# Parse cookie string using SimpleCookie's algorithm
|
||||
i = 0
|
||||
n = len(header)
|
||||
current_morsel: Optional[Morsel[str]] = None
|
||||
morsel_seen = False
|
||||
|
||||
while 0 <= i < n:
|
||||
# Start looking for a cookie
|
||||
match = _COOKIE_PATTERN.match(header, i)
|
||||
if not match:
|
||||
# No more cookies
|
||||
break
|
||||
|
||||
key, value = match.group("key"), match.group("val")
|
||||
i = match.end(0)
|
||||
lower_key = key.lower()
|
||||
|
||||
if key[0] == "$":
|
||||
if not morsel_seen:
|
||||
# We ignore attributes which pertain to the cookie
|
||||
# mechanism as a whole, such as "$Version".
|
||||
continue
|
||||
# Process as attribute
|
||||
if current_morsel is not None:
|
||||
attr_lower_key = lower_key[1:]
|
||||
if attr_lower_key in _COOKIE_KNOWN_ATTRS:
|
||||
current_morsel[attr_lower_key] = value or ""
|
||||
elif lower_key in _COOKIE_KNOWN_ATTRS:
|
||||
if not morsel_seen:
|
||||
# Invalid cookie string - attribute before cookie
|
||||
break
|
||||
if lower_key in _COOKIE_BOOL_ATTRS:
|
||||
# Boolean attribute with any value should be True
|
||||
if current_morsel is not None and current_morsel.isReservedKey(key):
|
||||
current_morsel[lower_key] = True
|
||||
elif value is None:
|
||||
# Invalid cookie string - non-boolean attribute without value
|
||||
break
|
||||
elif current_morsel is not None:
|
||||
# Regular attribute with value
|
||||
current_morsel[lower_key] = _unquote(value)
|
||||
elif value is not None:
|
||||
# This is a cookie name=value pair
|
||||
# Validate the name
|
||||
if key in _COOKIE_KNOWN_ATTRS or not _COOKIE_NAME_RE.match(key):
|
||||
internal_logger.warning(
|
||||
"Can not load cookies: Illegal cookie name %r", key
|
||||
)
|
||||
current_morsel = None
|
||||
else:
|
||||
# Create new morsel
|
||||
current_morsel = Morsel()
|
||||
# Preserve the original value as coded_value (with quotes if present)
|
||||
# We use __setstate__ instead of the public set() API because it allows us to
|
||||
# bypass validation and set already validated state. This is more stable than
|
||||
# setting protected attributes directly and unlikely to change since it would
|
||||
# break pickling.
|
||||
current_morsel.__setstate__( # type: ignore[attr-defined]
|
||||
{"key": key, "value": _unquote(value), "coded_value": value}
|
||||
)
|
||||
parsed_cookies.append((key, current_morsel))
|
||||
morsel_seen = True
|
||||
else:
|
||||
# Invalid cookie string - no value for non-attribute
|
||||
break
|
||||
|
||||
return parsed_cookies
|
||||
158
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_cparser.pxd
vendored
Executable file
158
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_cparser.pxd
vendored
Executable file
@@ -0,0 +1,158 @@
|
||||
from libc.stdint cimport int32_t, uint8_t, uint16_t, uint64_t
|
||||
|
||||
|
||||
cdef extern from "llhttp.h":
|
||||
|
||||
struct llhttp__internal_s:
|
||||
int32_t _index
|
||||
void* _span_pos0
|
||||
void* _span_cb0
|
||||
int32_t error
|
||||
const char* reason
|
||||
const char* error_pos
|
||||
void* data
|
||||
void* _current
|
||||
uint64_t content_length
|
||||
uint8_t type
|
||||
uint8_t method
|
||||
uint8_t http_major
|
||||
uint8_t http_minor
|
||||
uint8_t header_state
|
||||
uint8_t lenient_flags
|
||||
uint8_t upgrade
|
||||
uint8_t finish
|
||||
uint16_t flags
|
||||
uint16_t status_code
|
||||
void* settings
|
||||
|
||||
ctypedef llhttp__internal_s llhttp__internal_t
|
||||
ctypedef llhttp__internal_t llhttp_t
|
||||
|
||||
ctypedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length) except -1
|
||||
ctypedef int (*llhttp_cb)(llhttp_t*) except -1
|
||||
|
||||
struct llhttp_settings_s:
|
||||
llhttp_cb on_message_begin
|
||||
llhttp_data_cb on_url
|
||||
llhttp_data_cb on_status
|
||||
llhttp_data_cb on_header_field
|
||||
llhttp_data_cb on_header_value
|
||||
llhttp_cb on_headers_complete
|
||||
llhttp_data_cb on_body
|
||||
llhttp_cb on_message_complete
|
||||
llhttp_cb on_chunk_header
|
||||
llhttp_cb on_chunk_complete
|
||||
|
||||
llhttp_cb on_url_complete
|
||||
llhttp_cb on_status_complete
|
||||
llhttp_cb on_header_field_complete
|
||||
llhttp_cb on_header_value_complete
|
||||
|
||||
ctypedef llhttp_settings_s llhttp_settings_t
|
||||
|
||||
enum llhttp_errno:
|
||||
HPE_OK,
|
||||
HPE_INTERNAL,
|
||||
HPE_STRICT,
|
||||
HPE_LF_EXPECTED,
|
||||
HPE_UNEXPECTED_CONTENT_LENGTH,
|
||||
HPE_CLOSED_CONNECTION,
|
||||
HPE_INVALID_METHOD,
|
||||
HPE_INVALID_URL,
|
||||
HPE_INVALID_CONSTANT,
|
||||
HPE_INVALID_VERSION,
|
||||
HPE_INVALID_HEADER_TOKEN,
|
||||
HPE_INVALID_CONTENT_LENGTH,
|
||||
HPE_INVALID_CHUNK_SIZE,
|
||||
HPE_INVALID_STATUS,
|
||||
HPE_INVALID_EOF_STATE,
|
||||
HPE_INVALID_TRANSFER_ENCODING,
|
||||
HPE_CB_MESSAGE_BEGIN,
|
||||
HPE_CB_HEADERS_COMPLETE,
|
||||
HPE_CB_MESSAGE_COMPLETE,
|
||||
HPE_CB_CHUNK_HEADER,
|
||||
HPE_CB_CHUNK_COMPLETE,
|
||||
HPE_PAUSED,
|
||||
HPE_PAUSED_UPGRADE,
|
||||
HPE_USER
|
||||
|
||||
ctypedef llhttp_errno llhttp_errno_t
|
||||
|
||||
enum llhttp_flags:
|
||||
F_CHUNKED,
|
||||
F_CONTENT_LENGTH
|
||||
|
||||
enum llhttp_type:
|
||||
HTTP_REQUEST,
|
||||
HTTP_RESPONSE,
|
||||
HTTP_BOTH
|
||||
|
||||
enum llhttp_method:
|
||||
HTTP_DELETE,
|
||||
HTTP_GET,
|
||||
HTTP_HEAD,
|
||||
HTTP_POST,
|
||||
HTTP_PUT,
|
||||
HTTP_CONNECT,
|
||||
HTTP_OPTIONS,
|
||||
HTTP_TRACE,
|
||||
HTTP_COPY,
|
||||
HTTP_LOCK,
|
||||
HTTP_MKCOL,
|
||||
HTTP_MOVE,
|
||||
HTTP_PROPFIND,
|
||||
HTTP_PROPPATCH,
|
||||
HTTP_SEARCH,
|
||||
HTTP_UNLOCK,
|
||||
HTTP_BIND,
|
||||
HTTP_REBIND,
|
||||
HTTP_UNBIND,
|
||||
HTTP_ACL,
|
||||
HTTP_REPORT,
|
||||
HTTP_MKACTIVITY,
|
||||
HTTP_CHECKOUT,
|
||||
HTTP_MERGE,
|
||||
HTTP_MSEARCH,
|
||||
HTTP_NOTIFY,
|
||||
HTTP_SUBSCRIBE,
|
||||
HTTP_UNSUBSCRIBE,
|
||||
HTTP_PATCH,
|
||||
HTTP_PURGE,
|
||||
HTTP_MKCALENDAR,
|
||||
HTTP_LINK,
|
||||
HTTP_UNLINK,
|
||||
HTTP_SOURCE,
|
||||
HTTP_PRI,
|
||||
HTTP_DESCRIBE,
|
||||
HTTP_ANNOUNCE,
|
||||
HTTP_SETUP,
|
||||
HTTP_PLAY,
|
||||
HTTP_PAUSE,
|
||||
HTTP_TEARDOWN,
|
||||
HTTP_GET_PARAMETER,
|
||||
HTTP_SET_PARAMETER,
|
||||
HTTP_REDIRECT,
|
||||
HTTP_RECORD,
|
||||
HTTP_FLUSH
|
||||
|
||||
ctypedef llhttp_method llhttp_method_t;
|
||||
|
||||
void llhttp_settings_init(llhttp_settings_t* settings)
|
||||
void llhttp_init(llhttp_t* parser, llhttp_type type,
|
||||
const llhttp_settings_t* settings)
|
||||
|
||||
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len)
|
||||
|
||||
int llhttp_should_keep_alive(const llhttp_t* parser)
|
||||
|
||||
void llhttp_resume_after_upgrade(llhttp_t* parser)
|
||||
|
||||
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser)
|
||||
const char* llhttp_get_error_reason(const llhttp_t* parser)
|
||||
const char* llhttp_get_error_pos(const llhttp_t* parser)
|
||||
|
||||
const char* llhttp_method_name(llhttp_method_t method)
|
||||
|
||||
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled)
|
||||
void llhttp_set_lenient_optional_cr_before_lf(llhttp_t* parser, int enabled)
|
||||
void llhttp_set_lenient_spaces_after_chunk_size(llhttp_t* parser, int enabled)
|
||||
2
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_find_header.pxd
vendored
Executable file
2
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_find_header.pxd
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
cdef extern from "_find_header.h":
|
||||
int find_header(char *, int)
|
||||
83
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_headers.pxi
vendored
Executable file
83
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_headers.pxi
vendored
Executable file
@@ -0,0 +1,83 @@
|
||||
# The file is autogenerated from aiohttp/hdrs.py
|
||||
# Run ./tools/gen.py to update it after the origin changing.
|
||||
|
||||
from . import hdrs
|
||||
cdef tuple headers = (
|
||||
hdrs.ACCEPT,
|
||||
hdrs.ACCEPT_CHARSET,
|
||||
hdrs.ACCEPT_ENCODING,
|
||||
hdrs.ACCEPT_LANGUAGE,
|
||||
hdrs.ACCEPT_RANGES,
|
||||
hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS,
|
||||
hdrs.ACCESS_CONTROL_ALLOW_HEADERS,
|
||||
hdrs.ACCESS_CONTROL_ALLOW_METHODS,
|
||||
hdrs.ACCESS_CONTROL_ALLOW_ORIGIN,
|
||||
hdrs.ACCESS_CONTROL_EXPOSE_HEADERS,
|
||||
hdrs.ACCESS_CONTROL_MAX_AGE,
|
||||
hdrs.ACCESS_CONTROL_REQUEST_HEADERS,
|
||||
hdrs.ACCESS_CONTROL_REQUEST_METHOD,
|
||||
hdrs.AGE,
|
||||
hdrs.ALLOW,
|
||||
hdrs.AUTHORIZATION,
|
||||
hdrs.CACHE_CONTROL,
|
||||
hdrs.CONNECTION,
|
||||
hdrs.CONTENT_DISPOSITION,
|
||||
hdrs.CONTENT_ENCODING,
|
||||
hdrs.CONTENT_LANGUAGE,
|
||||
hdrs.CONTENT_LENGTH,
|
||||
hdrs.CONTENT_LOCATION,
|
||||
hdrs.CONTENT_MD5,
|
||||
hdrs.CONTENT_RANGE,
|
||||
hdrs.CONTENT_TRANSFER_ENCODING,
|
||||
hdrs.CONTENT_TYPE,
|
||||
hdrs.COOKIE,
|
||||
hdrs.DATE,
|
||||
hdrs.DESTINATION,
|
||||
hdrs.DIGEST,
|
||||
hdrs.ETAG,
|
||||
hdrs.EXPECT,
|
||||
hdrs.EXPIRES,
|
||||
hdrs.FORWARDED,
|
||||
hdrs.FROM,
|
||||
hdrs.HOST,
|
||||
hdrs.IF_MATCH,
|
||||
hdrs.IF_MODIFIED_SINCE,
|
||||
hdrs.IF_NONE_MATCH,
|
||||
hdrs.IF_RANGE,
|
||||
hdrs.IF_UNMODIFIED_SINCE,
|
||||
hdrs.KEEP_ALIVE,
|
||||
hdrs.LAST_EVENT_ID,
|
||||
hdrs.LAST_MODIFIED,
|
||||
hdrs.LINK,
|
||||
hdrs.LOCATION,
|
||||
hdrs.MAX_FORWARDS,
|
||||
hdrs.ORIGIN,
|
||||
hdrs.PRAGMA,
|
||||
hdrs.PROXY_AUTHENTICATE,
|
||||
hdrs.PROXY_AUTHORIZATION,
|
||||
hdrs.RANGE,
|
||||
hdrs.REFERER,
|
||||
hdrs.RETRY_AFTER,
|
||||
hdrs.SEC_WEBSOCKET_ACCEPT,
|
||||
hdrs.SEC_WEBSOCKET_EXTENSIONS,
|
||||
hdrs.SEC_WEBSOCKET_KEY,
|
||||
hdrs.SEC_WEBSOCKET_KEY1,
|
||||
hdrs.SEC_WEBSOCKET_PROTOCOL,
|
||||
hdrs.SEC_WEBSOCKET_VERSION,
|
||||
hdrs.SERVER,
|
||||
hdrs.SET_COOKIE,
|
||||
hdrs.TE,
|
||||
hdrs.TRAILER,
|
||||
hdrs.TRANSFER_ENCODING,
|
||||
hdrs.URI,
|
||||
hdrs.UPGRADE,
|
||||
hdrs.USER_AGENT,
|
||||
hdrs.VARY,
|
||||
hdrs.VIA,
|
||||
hdrs.WWW_AUTHENTICATE,
|
||||
hdrs.WANT_DIGEST,
|
||||
hdrs.WARNING,
|
||||
hdrs.X_FORWARDED_FOR,
|
||||
hdrs.X_FORWARDED_HOST,
|
||||
hdrs.X_FORWARDED_PROTO,
|
||||
)
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_http_parser.cpython-313-darwin.so
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_http_parser.cpython-313-darwin.so
vendored
Executable file
Binary file not shown.
835
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_http_parser.pyx
vendored
Executable file
835
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_http_parser.pyx
vendored
Executable file
@@ -0,0 +1,835 @@
|
||||
# Based on https://github.com/MagicStack/httptools
|
||||
#
|
||||
|
||||
from cpython cimport (
|
||||
Py_buffer,
|
||||
PyBUF_SIMPLE,
|
||||
PyBuffer_Release,
|
||||
PyBytes_AsString,
|
||||
PyBytes_AsStringAndSize,
|
||||
PyObject_GetBuffer,
|
||||
)
|
||||
from cpython.mem cimport PyMem_Free, PyMem_Malloc
|
||||
from libc.limits cimport ULLONG_MAX
|
||||
from libc.string cimport memcpy
|
||||
|
||||
from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy
|
||||
from yarl import URL as _URL
|
||||
|
||||
from aiohttp import hdrs
|
||||
from aiohttp.helpers import DEBUG, set_exception
|
||||
|
||||
from .http_exceptions import (
|
||||
BadHttpMessage,
|
||||
BadHttpMethod,
|
||||
BadStatusLine,
|
||||
ContentLengthError,
|
||||
InvalidHeader,
|
||||
InvalidURLError,
|
||||
LineTooLong,
|
||||
PayloadEncodingError,
|
||||
TransferEncodingError,
|
||||
)
|
||||
from .http_parser import DeflateBuffer as _DeflateBuffer
|
||||
from .http_writer import (
|
||||
HttpVersion as _HttpVersion,
|
||||
HttpVersion10 as _HttpVersion10,
|
||||
HttpVersion11 as _HttpVersion11,
|
||||
)
|
||||
from .streams import EMPTY_PAYLOAD as _EMPTY_PAYLOAD, StreamReader as _StreamReader
|
||||
|
||||
cimport cython
|
||||
|
||||
from aiohttp cimport _cparser as cparser
|
||||
|
||||
include "_headers.pxi"
|
||||
|
||||
from aiohttp cimport _find_header
|
||||
|
||||
ALLOWED_UPGRADES = frozenset({"websocket"})
|
||||
DEF DEFAULT_FREELIST_SIZE = 250
|
||||
|
||||
cdef extern from "Python.h":
|
||||
int PyByteArray_Resize(object, Py_ssize_t) except -1
|
||||
Py_ssize_t PyByteArray_Size(object) except -1
|
||||
char* PyByteArray_AsString(object)
|
||||
|
||||
__all__ = ('HttpRequestParser', 'HttpResponseParser',
|
||||
'RawRequestMessage', 'RawResponseMessage')
|
||||
|
||||
cdef object URL = _URL
|
||||
cdef object URL_build = URL.build
|
||||
cdef object CIMultiDict = _CIMultiDict
|
||||
cdef object CIMultiDictProxy = _CIMultiDictProxy
|
||||
cdef object HttpVersion = _HttpVersion
|
||||
cdef object HttpVersion10 = _HttpVersion10
|
||||
cdef object HttpVersion11 = _HttpVersion11
|
||||
cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1
|
||||
cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING
|
||||
cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD
|
||||
cdef object StreamReader = _StreamReader
|
||||
cdef object DeflateBuffer = _DeflateBuffer
|
||||
cdef bytes EMPTY_BYTES = b""
|
||||
|
||||
cdef inline object extend(object buf, const char* at, size_t length):
|
||||
cdef Py_ssize_t s
|
||||
cdef char* ptr
|
||||
s = PyByteArray_Size(buf)
|
||||
PyByteArray_Resize(buf, s + length)
|
||||
ptr = PyByteArray_AsString(buf)
|
||||
memcpy(ptr + s, at, length)
|
||||
|
||||
|
||||
DEF METHODS_COUNT = 46;
|
||||
|
||||
cdef list _http_method = []
|
||||
|
||||
for i in range(METHODS_COUNT):
|
||||
_http_method.append(
|
||||
cparser.llhttp_method_name(<cparser.llhttp_method_t> i).decode('ascii'))
|
||||
|
||||
|
||||
cdef inline str http_method_str(int i):
|
||||
if i < METHODS_COUNT:
|
||||
return <str>_http_method[i]
|
||||
else:
|
||||
return "<unknown>"
|
||||
|
||||
cdef inline object find_header(bytes raw_header):
|
||||
cdef Py_ssize_t size
|
||||
cdef char *buf
|
||||
cdef int idx
|
||||
PyBytes_AsStringAndSize(raw_header, &buf, &size)
|
||||
idx = _find_header.find_header(buf, size)
|
||||
if idx == -1:
|
||||
return raw_header.decode('utf-8', 'surrogateescape')
|
||||
return headers[idx]
|
||||
|
||||
|
||||
@cython.freelist(DEFAULT_FREELIST_SIZE)
|
||||
cdef class RawRequestMessage:
|
||||
cdef readonly str method
|
||||
cdef readonly str path
|
||||
cdef readonly object version # HttpVersion
|
||||
cdef readonly object headers # CIMultiDict
|
||||
cdef readonly object raw_headers # tuple
|
||||
cdef readonly object should_close
|
||||
cdef readonly object compression
|
||||
cdef readonly object upgrade
|
||||
cdef readonly object chunked
|
||||
cdef readonly object url # yarl.URL
|
||||
|
||||
def __init__(self, method, path, version, headers, raw_headers,
|
||||
should_close, compression, upgrade, chunked, url):
|
||||
self.method = method
|
||||
self.path = path
|
||||
self.version = version
|
||||
self.headers = headers
|
||||
self.raw_headers = raw_headers
|
||||
self.should_close = should_close
|
||||
self.compression = compression
|
||||
self.upgrade = upgrade
|
||||
self.chunked = chunked
|
||||
self.url = url
|
||||
|
||||
def __repr__(self):
|
||||
info = []
|
||||
info.append(("method", self.method))
|
||||
info.append(("path", self.path))
|
||||
info.append(("version", self.version))
|
||||
info.append(("headers", self.headers))
|
||||
info.append(("raw_headers", self.raw_headers))
|
||||
info.append(("should_close", self.should_close))
|
||||
info.append(("compression", self.compression))
|
||||
info.append(("upgrade", self.upgrade))
|
||||
info.append(("chunked", self.chunked))
|
||||
info.append(("url", self.url))
|
||||
sinfo = ', '.join(name + '=' + repr(val) for name, val in info)
|
||||
return '<RawRequestMessage(' + sinfo + ')>'
|
||||
|
||||
def _replace(self, **dct):
|
||||
cdef RawRequestMessage ret
|
||||
ret = _new_request_message(self.method,
|
||||
self.path,
|
||||
self.version,
|
||||
self.headers,
|
||||
self.raw_headers,
|
||||
self.should_close,
|
||||
self.compression,
|
||||
self.upgrade,
|
||||
self.chunked,
|
||||
self.url)
|
||||
if "method" in dct:
|
||||
ret.method = dct["method"]
|
||||
if "path" in dct:
|
||||
ret.path = dct["path"]
|
||||
if "version" in dct:
|
||||
ret.version = dct["version"]
|
||||
if "headers" in dct:
|
||||
ret.headers = dct["headers"]
|
||||
if "raw_headers" in dct:
|
||||
ret.raw_headers = dct["raw_headers"]
|
||||
if "should_close" in dct:
|
||||
ret.should_close = dct["should_close"]
|
||||
if "compression" in dct:
|
||||
ret.compression = dct["compression"]
|
||||
if "upgrade" in dct:
|
||||
ret.upgrade = dct["upgrade"]
|
||||
if "chunked" in dct:
|
||||
ret.chunked = dct["chunked"]
|
||||
if "url" in dct:
|
||||
ret.url = dct["url"]
|
||||
return ret
|
||||
|
||||
cdef _new_request_message(str method,
|
||||
str path,
|
||||
object version,
|
||||
object headers,
|
||||
object raw_headers,
|
||||
bint should_close,
|
||||
object compression,
|
||||
bint upgrade,
|
||||
bint chunked,
|
||||
object url):
|
||||
cdef RawRequestMessage ret
|
||||
ret = RawRequestMessage.__new__(RawRequestMessage)
|
||||
ret.method = method
|
||||
ret.path = path
|
||||
ret.version = version
|
||||
ret.headers = headers
|
||||
ret.raw_headers = raw_headers
|
||||
ret.should_close = should_close
|
||||
ret.compression = compression
|
||||
ret.upgrade = upgrade
|
||||
ret.chunked = chunked
|
||||
ret.url = url
|
||||
return ret
|
||||
|
||||
|
||||
@cython.freelist(DEFAULT_FREELIST_SIZE)
|
||||
cdef class RawResponseMessage:
|
||||
cdef readonly object version # HttpVersion
|
||||
cdef readonly int code
|
||||
cdef readonly str reason
|
||||
cdef readonly object headers # CIMultiDict
|
||||
cdef readonly object raw_headers # tuple
|
||||
cdef readonly object should_close
|
||||
cdef readonly object compression
|
||||
cdef readonly object upgrade
|
||||
cdef readonly object chunked
|
||||
|
||||
def __init__(self, version, code, reason, headers, raw_headers,
|
||||
should_close, compression, upgrade, chunked):
|
||||
self.version = version
|
||||
self.code = code
|
||||
self.reason = reason
|
||||
self.headers = headers
|
||||
self.raw_headers = raw_headers
|
||||
self.should_close = should_close
|
||||
self.compression = compression
|
||||
self.upgrade = upgrade
|
||||
self.chunked = chunked
|
||||
|
||||
def __repr__(self):
|
||||
info = []
|
||||
info.append(("version", self.version))
|
||||
info.append(("code", self.code))
|
||||
info.append(("reason", self.reason))
|
||||
info.append(("headers", self.headers))
|
||||
info.append(("raw_headers", self.raw_headers))
|
||||
info.append(("should_close", self.should_close))
|
||||
info.append(("compression", self.compression))
|
||||
info.append(("upgrade", self.upgrade))
|
||||
info.append(("chunked", self.chunked))
|
||||
sinfo = ', '.join(name + '=' + repr(val) for name, val in info)
|
||||
return '<RawResponseMessage(' + sinfo + ')>'
|
||||
|
||||
|
||||
cdef _new_response_message(object version,
|
||||
int code,
|
||||
str reason,
|
||||
object headers,
|
||||
object raw_headers,
|
||||
bint should_close,
|
||||
object compression,
|
||||
bint upgrade,
|
||||
bint chunked):
|
||||
cdef RawResponseMessage ret
|
||||
ret = RawResponseMessage.__new__(RawResponseMessage)
|
||||
ret.version = version
|
||||
ret.code = code
|
||||
ret.reason = reason
|
||||
ret.headers = headers
|
||||
ret.raw_headers = raw_headers
|
||||
ret.should_close = should_close
|
||||
ret.compression = compression
|
||||
ret.upgrade = upgrade
|
||||
ret.chunked = chunked
|
||||
return ret
|
||||
|
||||
|
||||
@cython.internal
|
||||
cdef class HttpParser:
|
||||
|
||||
cdef:
|
||||
cparser.llhttp_t* _cparser
|
||||
cparser.llhttp_settings_t* _csettings
|
||||
|
||||
bytes _raw_name
|
||||
object _name
|
||||
bytes _raw_value
|
||||
bint _has_value
|
||||
|
||||
object _protocol
|
||||
object _loop
|
||||
object _timer
|
||||
|
||||
size_t _max_line_size
|
||||
size_t _max_field_size
|
||||
size_t _max_headers
|
||||
bint _response_with_body
|
||||
bint _read_until_eof
|
||||
|
||||
bint _started
|
||||
object _url
|
||||
bytearray _buf
|
||||
str _path
|
||||
str _reason
|
||||
list _headers
|
||||
list _raw_headers
|
||||
bint _upgraded
|
||||
list _messages
|
||||
object _payload
|
||||
bint _payload_error
|
||||
object _payload_exception
|
||||
object _last_error
|
||||
bint _auto_decompress
|
||||
int _limit
|
||||
|
||||
str _content_encoding
|
||||
|
||||
Py_buffer py_buf
|
||||
|
||||
def __cinit__(self):
|
||||
self._cparser = <cparser.llhttp_t*> \
|
||||
PyMem_Malloc(sizeof(cparser.llhttp_t))
|
||||
if self._cparser is NULL:
|
||||
raise MemoryError()
|
||||
|
||||
self._csettings = <cparser.llhttp_settings_t*> \
|
||||
PyMem_Malloc(sizeof(cparser.llhttp_settings_t))
|
||||
if self._csettings is NULL:
|
||||
raise MemoryError()
|
||||
|
||||
def __dealloc__(self):
|
||||
PyMem_Free(self._cparser)
|
||||
PyMem_Free(self._csettings)
|
||||
|
||||
cdef _init(
|
||||
self, cparser.llhttp_type mode,
|
||||
object protocol, object loop, int limit,
|
||||
object timer=None,
|
||||
size_t max_line_size=8190, size_t max_headers=32768,
|
||||
size_t max_field_size=8190, payload_exception=None,
|
||||
bint response_with_body=True, bint read_until_eof=False,
|
||||
bint auto_decompress=True,
|
||||
):
|
||||
cparser.llhttp_settings_init(self._csettings)
|
||||
cparser.llhttp_init(self._cparser, mode, self._csettings)
|
||||
self._cparser.data = <void*>self
|
||||
self._cparser.content_length = 0
|
||||
|
||||
self._protocol = protocol
|
||||
self._loop = loop
|
||||
self._timer = timer
|
||||
|
||||
self._buf = bytearray()
|
||||
self._payload = None
|
||||
self._payload_error = 0
|
||||
self._payload_exception = payload_exception
|
||||
self._messages = []
|
||||
|
||||
self._raw_name = EMPTY_BYTES
|
||||
self._raw_value = EMPTY_BYTES
|
||||
self._has_value = False
|
||||
|
||||
self._max_line_size = max_line_size
|
||||
self._max_headers = max_headers
|
||||
self._max_field_size = max_field_size
|
||||
self._response_with_body = response_with_body
|
||||
self._read_until_eof = read_until_eof
|
||||
self._upgraded = False
|
||||
self._auto_decompress = auto_decompress
|
||||
self._content_encoding = None
|
||||
|
||||
self._csettings.on_url = cb_on_url
|
||||
self._csettings.on_status = cb_on_status
|
||||
self._csettings.on_header_field = cb_on_header_field
|
||||
self._csettings.on_header_value = cb_on_header_value
|
||||
self._csettings.on_headers_complete = cb_on_headers_complete
|
||||
self._csettings.on_body = cb_on_body
|
||||
self._csettings.on_message_begin = cb_on_message_begin
|
||||
self._csettings.on_message_complete = cb_on_message_complete
|
||||
self._csettings.on_chunk_header = cb_on_chunk_header
|
||||
self._csettings.on_chunk_complete = cb_on_chunk_complete
|
||||
|
||||
self._last_error = None
|
||||
self._limit = limit
|
||||
|
||||
cdef _process_header(self):
|
||||
cdef str value
|
||||
if self._raw_name is not EMPTY_BYTES:
|
||||
name = find_header(self._raw_name)
|
||||
value = self._raw_value.decode('utf-8', 'surrogateescape')
|
||||
|
||||
self._headers.append((name, value))
|
||||
|
||||
if name is CONTENT_ENCODING:
|
||||
self._content_encoding = value
|
||||
|
||||
self._has_value = False
|
||||
self._raw_headers.append((self._raw_name, self._raw_value))
|
||||
self._raw_name = EMPTY_BYTES
|
||||
self._raw_value = EMPTY_BYTES
|
||||
|
||||
cdef _on_header_field(self, char* at, size_t length):
|
||||
if self._has_value:
|
||||
self._process_header()
|
||||
|
||||
if self._raw_name is EMPTY_BYTES:
|
||||
self._raw_name = at[:length]
|
||||
else:
|
||||
self._raw_name += at[:length]
|
||||
|
||||
cdef _on_header_value(self, char* at, size_t length):
|
||||
if self._raw_value is EMPTY_BYTES:
|
||||
self._raw_value = at[:length]
|
||||
else:
|
||||
self._raw_value += at[:length]
|
||||
self._has_value = True
|
||||
|
||||
cdef _on_headers_complete(self):
|
||||
self._process_header()
|
||||
|
||||
should_close = not cparser.llhttp_should_keep_alive(self._cparser)
|
||||
upgrade = self._cparser.upgrade
|
||||
chunked = self._cparser.flags & cparser.F_CHUNKED
|
||||
|
||||
raw_headers = tuple(self._raw_headers)
|
||||
headers = CIMultiDictProxy(CIMultiDict(self._headers))
|
||||
|
||||
if self._cparser.type == cparser.HTTP_REQUEST:
|
||||
h_upg = headers.get("upgrade", "")
|
||||
allowed = upgrade and h_upg.isascii() and h_upg.lower() in ALLOWED_UPGRADES
|
||||
if allowed or self._cparser.method == cparser.HTTP_CONNECT:
|
||||
self._upgraded = True
|
||||
else:
|
||||
if upgrade and self._cparser.status_code == 101:
|
||||
self._upgraded = True
|
||||
|
||||
# do not support old websocket spec
|
||||
if SEC_WEBSOCKET_KEY1 in headers:
|
||||
raise InvalidHeader(SEC_WEBSOCKET_KEY1)
|
||||
|
||||
encoding = None
|
||||
enc = self._content_encoding
|
||||
if enc is not None:
|
||||
self._content_encoding = None
|
||||
if enc.isascii() and enc.lower() in {"gzip", "deflate", "br", "zstd"}:
|
||||
encoding = enc
|
||||
|
||||
if self._cparser.type == cparser.HTTP_REQUEST:
|
||||
method = http_method_str(self._cparser.method)
|
||||
msg = _new_request_message(
|
||||
method, self._path,
|
||||
self.http_version(), headers, raw_headers,
|
||||
should_close, encoding, upgrade, chunked, self._url)
|
||||
else:
|
||||
msg = _new_response_message(
|
||||
self.http_version(), self._cparser.status_code, self._reason,
|
||||
headers, raw_headers, should_close, encoding,
|
||||
upgrade, chunked)
|
||||
|
||||
if (
|
||||
ULLONG_MAX > self._cparser.content_length > 0 or chunked or
|
||||
self._cparser.method == cparser.HTTP_CONNECT or
|
||||
(self._cparser.status_code >= 199 and
|
||||
self._cparser.content_length == 0 and
|
||||
self._read_until_eof)
|
||||
):
|
||||
payload = StreamReader(
|
||||
self._protocol, timer=self._timer, loop=self._loop,
|
||||
limit=self._limit)
|
||||
else:
|
||||
payload = EMPTY_PAYLOAD
|
||||
|
||||
self._payload = payload
|
||||
if encoding is not None and self._auto_decompress:
|
||||
self._payload = DeflateBuffer(payload, encoding)
|
||||
|
||||
if not self._response_with_body:
|
||||
payload = EMPTY_PAYLOAD
|
||||
|
||||
self._messages.append((msg, payload))
|
||||
|
||||
cdef _on_message_complete(self):
|
||||
self._payload.feed_eof()
|
||||
self._payload = None
|
||||
|
||||
cdef _on_chunk_header(self):
|
||||
self._payload.begin_http_chunk_receiving()
|
||||
|
||||
cdef _on_chunk_complete(self):
|
||||
self._payload.end_http_chunk_receiving()
|
||||
|
||||
cdef object _on_status_complete(self):
|
||||
pass
|
||||
|
||||
cdef inline http_version(self):
|
||||
cdef cparser.llhttp_t* parser = self._cparser
|
||||
|
||||
if parser.http_major == 1:
|
||||
if parser.http_minor == 0:
|
||||
return HttpVersion10
|
||||
elif parser.http_minor == 1:
|
||||
return HttpVersion11
|
||||
|
||||
return HttpVersion(parser.http_major, parser.http_minor)
|
||||
|
||||
### Public API ###
|
||||
|
||||
def feed_eof(self):
|
||||
cdef bytes desc
|
||||
|
||||
if self._payload is not None:
|
||||
if self._cparser.flags & cparser.F_CHUNKED:
|
||||
raise TransferEncodingError(
|
||||
"Not enough data to satisfy transfer length header.")
|
||||
elif self._cparser.flags & cparser.F_CONTENT_LENGTH:
|
||||
raise ContentLengthError(
|
||||
"Not enough data to satisfy content length header.")
|
||||
elif cparser.llhttp_get_errno(self._cparser) != cparser.HPE_OK:
|
||||
desc = cparser.llhttp_get_error_reason(self._cparser)
|
||||
raise PayloadEncodingError(desc.decode('latin-1'))
|
||||
else:
|
||||
self._payload.feed_eof()
|
||||
elif self._started:
|
||||
self._on_headers_complete()
|
||||
if self._messages:
|
||||
return self._messages[-1][0]
|
||||
|
||||
def feed_data(self, data):
|
||||
cdef:
|
||||
size_t data_len
|
||||
size_t nb
|
||||
cdef cparser.llhttp_errno_t errno
|
||||
|
||||
PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE)
|
||||
data_len = <size_t>self.py_buf.len
|
||||
|
||||
errno = cparser.llhttp_execute(
|
||||
self._cparser,
|
||||
<char*>self.py_buf.buf,
|
||||
data_len)
|
||||
|
||||
if errno is cparser.HPE_PAUSED_UPGRADE:
|
||||
cparser.llhttp_resume_after_upgrade(self._cparser)
|
||||
|
||||
nb = cparser.llhttp_get_error_pos(self._cparser) - <char*>self.py_buf.buf
|
||||
|
||||
PyBuffer_Release(&self.py_buf)
|
||||
|
||||
if errno not in (cparser.HPE_OK, cparser.HPE_PAUSED_UPGRADE):
|
||||
if self._payload_error == 0:
|
||||
if self._last_error is not None:
|
||||
ex = self._last_error
|
||||
self._last_error = None
|
||||
else:
|
||||
after = cparser.llhttp_get_error_pos(self._cparser)
|
||||
before = data[:after - <char*>self.py_buf.buf]
|
||||
after_b = after.split(b"\r\n", 1)[0]
|
||||
before = before.rsplit(b"\r\n", 1)[-1]
|
||||
data = before + after_b
|
||||
pointer = " " * (len(repr(before))-1) + "^"
|
||||
ex = parser_error_from_errno(self._cparser, data, pointer)
|
||||
self._payload = None
|
||||
raise ex
|
||||
|
||||
if self._messages:
|
||||
messages = self._messages
|
||||
self._messages = []
|
||||
else:
|
||||
messages = ()
|
||||
|
||||
if self._upgraded:
|
||||
return messages, True, data[nb:]
|
||||
else:
|
||||
return messages, False, b""
|
||||
|
||||
def set_upgraded(self, val):
|
||||
self._upgraded = val
|
||||
|
||||
|
||||
cdef class HttpRequestParser(HttpParser):
|
||||
|
||||
def __init__(
|
||||
self, protocol, loop, int limit, timer=None,
|
||||
size_t max_line_size=8190, size_t max_headers=32768,
|
||||
size_t max_field_size=8190, payload_exception=None,
|
||||
bint response_with_body=True, bint read_until_eof=False,
|
||||
bint auto_decompress=True,
|
||||
):
|
||||
self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer,
|
||||
max_line_size, max_headers, max_field_size,
|
||||
payload_exception, response_with_body, read_until_eof,
|
||||
auto_decompress)
|
||||
|
||||
cdef object _on_status_complete(self):
|
||||
cdef int idx1, idx2
|
||||
if not self._buf:
|
||||
return
|
||||
self._path = self._buf.decode('utf-8', 'surrogateescape')
|
||||
try:
|
||||
idx3 = len(self._path)
|
||||
if self._cparser.method == cparser.HTTP_CONNECT:
|
||||
# authority-form,
|
||||
# https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.3
|
||||
self._url = URL.build(authority=self._path, encoded=True)
|
||||
elif idx3 > 1 and self._path[0] == '/':
|
||||
# origin-form,
|
||||
# https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.1
|
||||
idx1 = self._path.find("?")
|
||||
if idx1 == -1:
|
||||
query = ""
|
||||
idx2 = self._path.find("#")
|
||||
if idx2 == -1:
|
||||
path = self._path
|
||||
fragment = ""
|
||||
else:
|
||||
path = self._path[0: idx2]
|
||||
fragment = self._path[idx2+1:]
|
||||
|
||||
else:
|
||||
path = self._path[0:idx1]
|
||||
idx1 += 1
|
||||
idx2 = self._path.find("#", idx1+1)
|
||||
if idx2 == -1:
|
||||
query = self._path[idx1:]
|
||||
fragment = ""
|
||||
else:
|
||||
query = self._path[idx1: idx2]
|
||||
fragment = self._path[idx2+1:]
|
||||
|
||||
self._url = URL.build(
|
||||
path=path,
|
||||
query_string=query,
|
||||
fragment=fragment,
|
||||
encoded=True,
|
||||
)
|
||||
else:
|
||||
# absolute-form for proxy maybe,
|
||||
# https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.2
|
||||
self._url = URL(self._path, encoded=True)
|
||||
finally:
|
||||
PyByteArray_Resize(self._buf, 0)
|
||||
|
||||
|
||||
cdef class HttpResponseParser(HttpParser):
|
||||
|
||||
def __init__(
|
||||
self, protocol, loop, int limit, timer=None,
|
||||
size_t max_line_size=8190, size_t max_headers=32768,
|
||||
size_t max_field_size=8190, payload_exception=None,
|
||||
bint response_with_body=True, bint read_until_eof=False,
|
||||
bint auto_decompress=True
|
||||
):
|
||||
self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer,
|
||||
max_line_size, max_headers, max_field_size,
|
||||
payload_exception, response_with_body, read_until_eof,
|
||||
auto_decompress)
|
||||
# Use strict parsing on dev mode, so users are warned about broken servers.
|
||||
if not DEBUG:
|
||||
cparser.llhttp_set_lenient_headers(self._cparser, 1)
|
||||
cparser.llhttp_set_lenient_optional_cr_before_lf(self._cparser, 1)
|
||||
cparser.llhttp_set_lenient_spaces_after_chunk_size(self._cparser, 1)
|
||||
|
||||
cdef object _on_status_complete(self):
|
||||
if self._buf:
|
||||
self._reason = self._buf.decode('utf-8', 'surrogateescape')
|
||||
PyByteArray_Resize(self._buf, 0)
|
||||
else:
|
||||
self._reason = self._reason or ''
|
||||
|
||||
cdef int cb_on_message_begin(cparser.llhttp_t* parser) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
|
||||
pyparser._started = True
|
||||
pyparser._headers = []
|
||||
pyparser._raw_headers = []
|
||||
PyByteArray_Resize(pyparser._buf, 0)
|
||||
pyparser._path = None
|
||||
pyparser._reason = None
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_url(cparser.llhttp_t* parser,
|
||||
const char *at, size_t length) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
try:
|
||||
if length > pyparser._max_line_size:
|
||||
raise LineTooLong(
|
||||
'Status line is too long', pyparser._max_line_size, length)
|
||||
extend(pyparser._buf, at, length)
|
||||
except BaseException as ex:
|
||||
pyparser._last_error = ex
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_status(cparser.llhttp_t* parser,
|
||||
const char *at, size_t length) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
cdef str reason
|
||||
try:
|
||||
if length > pyparser._max_line_size:
|
||||
raise LineTooLong(
|
||||
'Status line is too long', pyparser._max_line_size, length)
|
||||
extend(pyparser._buf, at, length)
|
||||
except BaseException as ex:
|
||||
pyparser._last_error = ex
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_header_field(cparser.llhttp_t* parser,
|
||||
const char *at, size_t length) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
cdef Py_ssize_t size
|
||||
try:
|
||||
pyparser._on_status_complete()
|
||||
size = len(pyparser._raw_name) + length
|
||||
if size > pyparser._max_field_size:
|
||||
raise LineTooLong(
|
||||
'Header name is too long', pyparser._max_field_size, size)
|
||||
pyparser._on_header_field(at, length)
|
||||
except BaseException as ex:
|
||||
pyparser._last_error = ex
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_header_value(cparser.llhttp_t* parser,
|
||||
const char *at, size_t length) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
cdef Py_ssize_t size
|
||||
try:
|
||||
size = len(pyparser._raw_value) + length
|
||||
if size > pyparser._max_field_size:
|
||||
raise LineTooLong(
|
||||
'Header value is too long', pyparser._max_field_size, size)
|
||||
pyparser._on_header_value(at, length)
|
||||
except BaseException as ex:
|
||||
pyparser._last_error = ex
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_headers_complete(cparser.llhttp_t* parser) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
try:
|
||||
pyparser._on_status_complete()
|
||||
pyparser._on_headers_complete()
|
||||
except BaseException as exc:
|
||||
pyparser._last_error = exc
|
||||
return -1
|
||||
else:
|
||||
if pyparser._upgraded or pyparser._cparser.method == cparser.HTTP_CONNECT:
|
||||
return 2
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_body(cparser.llhttp_t* parser,
|
||||
const char *at, size_t length) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
cdef bytes body = at[:length]
|
||||
try:
|
||||
pyparser._payload.feed_data(body, length)
|
||||
except BaseException as underlying_exc:
|
||||
reraised_exc = underlying_exc
|
||||
if pyparser._payload_exception is not None:
|
||||
reraised_exc = pyparser._payload_exception(str(underlying_exc))
|
||||
|
||||
set_exception(pyparser._payload, reraised_exc, underlying_exc)
|
||||
|
||||
pyparser._payload_error = 1
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_message_complete(cparser.llhttp_t* parser) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
try:
|
||||
pyparser._started = False
|
||||
pyparser._on_message_complete()
|
||||
except BaseException as exc:
|
||||
pyparser._last_error = exc
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_chunk_header(cparser.llhttp_t* parser) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
try:
|
||||
pyparser._on_chunk_header()
|
||||
except BaseException as exc:
|
||||
pyparser._last_error = exc
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef int cb_on_chunk_complete(cparser.llhttp_t* parser) except -1:
|
||||
cdef HttpParser pyparser = <HttpParser>parser.data
|
||||
try:
|
||||
pyparser._on_chunk_complete()
|
||||
except BaseException as exc:
|
||||
pyparser._last_error = exc
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
cdef parser_error_from_errno(cparser.llhttp_t* parser, data, pointer):
|
||||
cdef cparser.llhttp_errno_t errno = cparser.llhttp_get_errno(parser)
|
||||
cdef bytes desc = cparser.llhttp_get_error_reason(parser)
|
||||
|
||||
err_msg = "{}:\n\n {!r}\n {}".format(desc.decode("latin-1"), data, pointer)
|
||||
|
||||
if errno in {cparser.HPE_CB_MESSAGE_BEGIN,
|
||||
cparser.HPE_CB_HEADERS_COMPLETE,
|
||||
cparser.HPE_CB_MESSAGE_COMPLETE,
|
||||
cparser.HPE_CB_CHUNK_HEADER,
|
||||
cparser.HPE_CB_CHUNK_COMPLETE,
|
||||
cparser.HPE_INVALID_CONSTANT,
|
||||
cparser.HPE_INVALID_HEADER_TOKEN,
|
||||
cparser.HPE_INVALID_CONTENT_LENGTH,
|
||||
cparser.HPE_INVALID_CHUNK_SIZE,
|
||||
cparser.HPE_INVALID_EOF_STATE,
|
||||
cparser.HPE_INVALID_TRANSFER_ENCODING}:
|
||||
return BadHttpMessage(err_msg)
|
||||
elif errno == cparser.HPE_INVALID_METHOD:
|
||||
return BadHttpMethod(error=err_msg)
|
||||
elif errno in {cparser.HPE_INVALID_STATUS,
|
||||
cparser.HPE_INVALID_VERSION}:
|
||||
return BadStatusLine(error=err_msg)
|
||||
elif errno == cparser.HPE_INVALID_URL:
|
||||
return InvalidURLError(err_msg)
|
||||
|
||||
return BadHttpMessage(err_msg)
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_http_writer.cpython-313-darwin.so
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_http_writer.cpython-313-darwin.so
vendored
Executable file
Binary file not shown.
162
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_http_writer.pyx
vendored
Executable file
162
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_http_writer.pyx
vendored
Executable file
@@ -0,0 +1,162 @@
|
||||
from cpython.bytes cimport PyBytes_FromStringAndSize
|
||||
from cpython.exc cimport PyErr_NoMemory
|
||||
from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc
|
||||
from cpython.object cimport PyObject_Str
|
||||
from libc.stdint cimport uint8_t, uint64_t
|
||||
from libc.string cimport memcpy
|
||||
|
||||
from multidict import istr
|
||||
|
||||
DEF BUF_SIZE = 16 * 1024 # 16KiB
|
||||
|
||||
cdef object _istr = istr
|
||||
|
||||
|
||||
# ----------------- writer ---------------------------
|
||||
|
||||
cdef struct Writer:
|
||||
char *buf
|
||||
Py_ssize_t size
|
||||
Py_ssize_t pos
|
||||
bint heap_allocated
|
||||
|
||||
cdef inline void _init_writer(Writer* writer, char *buf):
|
||||
writer.buf = buf
|
||||
writer.size = BUF_SIZE
|
||||
writer.pos = 0
|
||||
writer.heap_allocated = 0
|
||||
|
||||
|
||||
cdef inline void _release_writer(Writer* writer):
|
||||
if writer.heap_allocated:
|
||||
PyMem_Free(writer.buf)
|
||||
|
||||
|
||||
cdef inline int _write_byte(Writer* writer, uint8_t ch):
|
||||
cdef char * buf
|
||||
cdef Py_ssize_t size
|
||||
|
||||
if writer.pos == writer.size:
|
||||
# reallocate
|
||||
size = writer.size + BUF_SIZE
|
||||
if not writer.heap_allocated:
|
||||
buf = <char*>PyMem_Malloc(size)
|
||||
if buf == NULL:
|
||||
PyErr_NoMemory()
|
||||
return -1
|
||||
memcpy(buf, writer.buf, writer.size)
|
||||
else:
|
||||
buf = <char*>PyMem_Realloc(writer.buf, size)
|
||||
if buf == NULL:
|
||||
PyErr_NoMemory()
|
||||
return -1
|
||||
writer.buf = buf
|
||||
writer.size = size
|
||||
writer.heap_allocated = 1
|
||||
writer.buf[writer.pos] = <char>ch
|
||||
writer.pos += 1
|
||||
return 0
|
||||
|
||||
|
||||
cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol):
|
||||
cdef uint64_t utf = <uint64_t> symbol
|
||||
|
||||
if utf < 0x80:
|
||||
return _write_byte(writer, <uint8_t>utf)
|
||||
elif utf < 0x800:
|
||||
if _write_byte(writer, <uint8_t>(0xc0 | (utf >> 6))) < 0:
|
||||
return -1
|
||||
return _write_byte(writer, <uint8_t>(0x80 | (utf & 0x3f)))
|
||||
elif 0xD800 <= utf <= 0xDFFF:
|
||||
# surogate pair, ignored
|
||||
return 0
|
||||
elif utf < 0x10000:
|
||||
if _write_byte(writer, <uint8_t>(0xe0 | (utf >> 12))) < 0:
|
||||
return -1
|
||||
if _write_byte(writer, <uint8_t>(0x80 | ((utf >> 6) & 0x3f))) < 0:
|
||||
return -1
|
||||
return _write_byte(writer, <uint8_t>(0x80 | (utf & 0x3f)))
|
||||
elif utf > 0x10FFFF:
|
||||
# symbol is too large
|
||||
return 0
|
||||
else:
|
||||
if _write_byte(writer, <uint8_t>(0xf0 | (utf >> 18))) < 0:
|
||||
return -1
|
||||
if _write_byte(writer,
|
||||
<uint8_t>(0x80 | ((utf >> 12) & 0x3f))) < 0:
|
||||
return -1
|
||||
if _write_byte(writer,
|
||||
<uint8_t>(0x80 | ((utf >> 6) & 0x3f))) < 0:
|
||||
return -1
|
||||
return _write_byte(writer, <uint8_t>(0x80 | (utf & 0x3f)))
|
||||
|
||||
|
||||
cdef inline int _write_str(Writer* writer, str s):
|
||||
cdef Py_UCS4 ch
|
||||
for ch in s:
|
||||
if _write_utf8(writer, ch) < 0:
|
||||
return -1
|
||||
|
||||
|
||||
cdef inline int _write_str_raise_on_nlcr(Writer* writer, object s):
|
||||
cdef Py_UCS4 ch
|
||||
cdef str out_str
|
||||
if type(s) is str:
|
||||
out_str = <str>s
|
||||
elif type(s) is _istr:
|
||||
out_str = PyObject_Str(s)
|
||||
elif not isinstance(s, str):
|
||||
raise TypeError("Cannot serialize non-str key {!r}".format(s))
|
||||
else:
|
||||
out_str = str(s)
|
||||
|
||||
for ch in out_str:
|
||||
if ch == 0x0D or ch == 0x0A:
|
||||
raise ValueError(
|
||||
"Newline or carriage return detected in headers. "
|
||||
"Potential header injection attack."
|
||||
)
|
||||
if _write_utf8(writer, ch) < 0:
|
||||
return -1
|
||||
|
||||
|
||||
# --------------- _serialize_headers ----------------------
|
||||
|
||||
def _serialize_headers(str status_line, headers):
|
||||
cdef Writer writer
|
||||
cdef object key
|
||||
cdef object val
|
||||
cdef char buf[BUF_SIZE]
|
||||
|
||||
_init_writer(&writer, buf)
|
||||
|
||||
try:
|
||||
if _write_str(&writer, status_line) < 0:
|
||||
raise
|
||||
if _write_byte(&writer, b'\r') < 0:
|
||||
raise
|
||||
if _write_byte(&writer, b'\n') < 0:
|
||||
raise
|
||||
|
||||
for key, val in headers.items():
|
||||
if _write_str_raise_on_nlcr(&writer, key) < 0:
|
||||
raise
|
||||
if _write_byte(&writer, b':') < 0:
|
||||
raise
|
||||
if _write_byte(&writer, b' ') < 0:
|
||||
raise
|
||||
if _write_str_raise_on_nlcr(&writer, val) < 0:
|
||||
raise
|
||||
if _write_byte(&writer, b'\r') < 0:
|
||||
raise
|
||||
if _write_byte(&writer, b'\n') < 0:
|
||||
raise
|
||||
|
||||
if _write_byte(&writer, b'\r') < 0:
|
||||
raise
|
||||
if _write_byte(&writer, b'\n') < 0:
|
||||
raise
|
||||
|
||||
return PyBytes_FromStringAndSize(writer.buf, writer.pos)
|
||||
finally:
|
||||
_release_writer(&writer)
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/.hash/mask.pxd.hash
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/.hash/mask.pxd.hash
vendored
Executable file
@@ -0,0 +1 @@
|
||||
b01999d409b29bd916e067bc963d5f2d9ee63cfc9ae0bccb769910131417bf93 /Users/runner/work/aiohttp/aiohttp/aiohttp/_websocket/mask.pxd
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/.hash/mask.pyx.hash
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/.hash/mask.pyx.hash
vendored
Executable file
@@ -0,0 +1 @@
|
||||
0478ceb55d0ed30ef1a7da742cd003449bc69a07cf9fdb06789bd2b347cbfffe /Users/runner/work/aiohttp/aiohttp/aiohttp/_websocket/mask.pyx
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/.hash/reader_c.pxd.hash
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/.hash/reader_c.pxd.hash
vendored
Executable file
@@ -0,0 +1 @@
|
||||
9e5fe78ed0ebce5414d2b8e01868d90c1facc20b84d2d5ff6c23e86e44a155ae /Users/runner/work/aiohttp/aiohttp/aiohttp/_websocket/reader_c.pxd
|
||||
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__init__.py
vendored
Executable file
1
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__init__.py
vendored
Executable file
@@ -0,0 +1 @@
|
||||
"""WebSocket protocol versions 13 and 8."""
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/__init__.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/helpers.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/helpers.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/models.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/models.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/reader.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/reader.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/reader_c.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/reader_c.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/reader_py.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/reader_py.cpython-313.pyc
vendored
Executable file
Binary file not shown.
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/writer.cpython-313.pyc
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/__pycache__/writer.cpython-313.pyc
vendored
Executable file
Binary file not shown.
147
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/helpers.py
vendored
Executable file
147
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/helpers.py
vendored
Executable file
@@ -0,0 +1,147 @@
|
||||
"""Helpers for WebSocket protocol versions 13 and 8."""
|
||||
|
||||
import functools
|
||||
import re
|
||||
from struct import Struct
|
||||
from typing import TYPE_CHECKING, Final, List, Optional, Pattern, Tuple
|
||||
|
||||
from ..helpers import NO_EXTENSIONS
|
||||
from .models import WSHandshakeError
|
||||
|
||||
UNPACK_LEN3 = Struct("!Q").unpack_from
|
||||
UNPACK_CLOSE_CODE = Struct("!H").unpack
|
||||
PACK_LEN1 = Struct("!BB").pack
|
||||
PACK_LEN2 = Struct("!BBH").pack
|
||||
PACK_LEN3 = Struct("!BBQ").pack
|
||||
PACK_CLOSE_CODE = Struct("!H").pack
|
||||
PACK_RANDBITS = Struct("!L").pack
|
||||
MSG_SIZE: Final[int] = 2**14
|
||||
MASK_LEN: Final[int] = 4
|
||||
|
||||
WS_KEY: Final[bytes] = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
|
||||
|
||||
|
||||
# Used by _websocket_mask_python
|
||||
@functools.lru_cache
|
||||
def _xor_table() -> List[bytes]:
|
||||
return [bytes(a ^ b for a in range(256)) for b in range(256)]
|
||||
|
||||
|
||||
def _websocket_mask_python(mask: bytes, data: bytearray) -> None:
|
||||
"""Websocket masking function.
|
||||
|
||||
`mask` is a `bytes` object of length 4; `data` is a `bytearray`
|
||||
object of any length. The contents of `data` are masked with `mask`,
|
||||
as specified in section 5.3 of RFC 6455.
|
||||
|
||||
Note that this function mutates the `data` argument.
|
||||
|
||||
This pure-python implementation may be replaced by an optimized
|
||||
version when available.
|
||||
|
||||
"""
|
||||
assert isinstance(data, bytearray), data
|
||||
assert len(mask) == 4, mask
|
||||
|
||||
if data:
|
||||
_XOR_TABLE = _xor_table()
|
||||
a, b, c, d = (_XOR_TABLE[n] for n in mask)
|
||||
data[::4] = data[::4].translate(a)
|
||||
data[1::4] = data[1::4].translate(b)
|
||||
data[2::4] = data[2::4].translate(c)
|
||||
data[3::4] = data[3::4].translate(d)
|
||||
|
||||
|
||||
if TYPE_CHECKING or NO_EXTENSIONS: # pragma: no cover
|
||||
websocket_mask = _websocket_mask_python
|
||||
else:
|
||||
try:
|
||||
from .mask import _websocket_mask_cython # type: ignore[import-not-found]
|
||||
|
||||
websocket_mask = _websocket_mask_cython
|
||||
except ImportError: # pragma: no cover
|
||||
websocket_mask = _websocket_mask_python
|
||||
|
||||
|
||||
_WS_EXT_RE: Final[Pattern[str]] = re.compile(
|
||||
r"^(?:;\s*(?:"
|
||||
r"(server_no_context_takeover)|"
|
||||
r"(client_no_context_takeover)|"
|
||||
r"(server_max_window_bits(?:=(\d+))?)|"
|
||||
r"(client_max_window_bits(?:=(\d+))?)))*$"
|
||||
)
|
||||
|
||||
_WS_EXT_RE_SPLIT: Final[Pattern[str]] = re.compile(r"permessage-deflate([^,]+)?")
|
||||
|
||||
|
||||
def ws_ext_parse(extstr: Optional[str], isserver: bool = False) -> Tuple[int, bool]:
|
||||
if not extstr:
|
||||
return 0, False
|
||||
|
||||
compress = 0
|
||||
notakeover = False
|
||||
for ext in _WS_EXT_RE_SPLIT.finditer(extstr):
|
||||
defext = ext.group(1)
|
||||
# Return compress = 15 when get `permessage-deflate`
|
||||
if not defext:
|
||||
compress = 15
|
||||
break
|
||||
match = _WS_EXT_RE.match(defext)
|
||||
if match:
|
||||
compress = 15
|
||||
if isserver:
|
||||
# Server never fail to detect compress handshake.
|
||||
# Server does not need to send max wbit to client
|
||||
if match.group(4):
|
||||
compress = int(match.group(4))
|
||||
# Group3 must match if group4 matches
|
||||
# Compress wbit 8 does not support in zlib
|
||||
# If compress level not support,
|
||||
# CONTINUE to next extension
|
||||
if compress > 15 or compress < 9:
|
||||
compress = 0
|
||||
continue
|
||||
if match.group(1):
|
||||
notakeover = True
|
||||
# Ignore regex group 5 & 6 for client_max_window_bits
|
||||
break
|
||||
else:
|
||||
if match.group(6):
|
||||
compress = int(match.group(6))
|
||||
# Group5 must match if group6 matches
|
||||
# Compress wbit 8 does not support in zlib
|
||||
# If compress level not support,
|
||||
# FAIL the parse progress
|
||||
if compress > 15 or compress < 9:
|
||||
raise WSHandshakeError("Invalid window size")
|
||||
if match.group(2):
|
||||
notakeover = True
|
||||
# Ignore regex group 5 & 6 for client_max_window_bits
|
||||
break
|
||||
# Return Fail if client side and not match
|
||||
elif not isserver:
|
||||
raise WSHandshakeError("Extension for deflate not supported" + ext.group(1))
|
||||
|
||||
return compress, notakeover
|
||||
|
||||
|
||||
def ws_ext_gen(
|
||||
compress: int = 15, isserver: bool = False, server_notakeover: bool = False
|
||||
) -> str:
|
||||
# client_notakeover=False not used for server
|
||||
# compress wbit 8 does not support in zlib
|
||||
if compress < 9 or compress > 15:
|
||||
raise ValueError(
|
||||
"Compress wbits must between 9 and 15, zlib does not support wbits=8"
|
||||
)
|
||||
enabledext = ["permessage-deflate"]
|
||||
if not isserver:
|
||||
enabledext.append("client_max_window_bits")
|
||||
|
||||
if compress < 15:
|
||||
enabledext.append("server_max_window_bits=" + str(compress))
|
||||
if server_notakeover:
|
||||
enabledext.append("server_no_context_takeover")
|
||||
# if client_notakeover:
|
||||
# enabledext.append('client_no_context_takeover')
|
||||
return "; ".join(enabledext)
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/mask.cpython-313-darwin.so
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/mask.cpython-313-darwin.so
vendored
Executable file
Binary file not shown.
3
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/mask.pxd
vendored
Executable file
3
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/mask.pxd
vendored
Executable file
@@ -0,0 +1,3 @@
|
||||
"""Cython declarations for websocket masking."""
|
||||
|
||||
cpdef void _websocket_mask_cython(bytes mask, bytearray data)
|
||||
48
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/mask.pyx
vendored
Executable file
48
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/mask.pyx
vendored
Executable file
@@ -0,0 +1,48 @@
|
||||
from cpython cimport PyBytes_AsString
|
||||
|
||||
|
||||
#from cpython cimport PyByteArray_AsString # cython still not exports that
|
||||
cdef extern from "Python.h":
|
||||
char* PyByteArray_AsString(bytearray ba) except NULL
|
||||
|
||||
from libc.stdint cimport uint32_t, uint64_t, uintmax_t
|
||||
|
||||
|
||||
cpdef void _websocket_mask_cython(bytes mask, bytearray data):
|
||||
"""Note, this function mutates its `data` argument
|
||||
"""
|
||||
cdef:
|
||||
Py_ssize_t data_len, i
|
||||
# bit operations on signed integers are implementation-specific
|
||||
unsigned char * in_buf
|
||||
const unsigned char * mask_buf
|
||||
uint32_t uint32_msk
|
||||
uint64_t uint64_msk
|
||||
|
||||
assert len(mask) == 4
|
||||
|
||||
data_len = len(data)
|
||||
in_buf = <unsigned char*>PyByteArray_AsString(data)
|
||||
mask_buf = <const unsigned char*>PyBytes_AsString(mask)
|
||||
uint32_msk = (<uint32_t*>mask_buf)[0]
|
||||
|
||||
# TODO: align in_data ptr to achieve even faster speeds
|
||||
# does it need in python ?! malloc() always aligns to sizeof(long) bytes
|
||||
|
||||
if sizeof(size_t) >= 8:
|
||||
uint64_msk = uint32_msk
|
||||
uint64_msk = (uint64_msk << 32) | uint32_msk
|
||||
|
||||
while data_len >= 8:
|
||||
(<uint64_t*>in_buf)[0] ^= uint64_msk
|
||||
in_buf += 8
|
||||
data_len -= 8
|
||||
|
||||
|
||||
while data_len >= 4:
|
||||
(<uint32_t*>in_buf)[0] ^= uint32_msk
|
||||
in_buf += 4
|
||||
data_len -= 4
|
||||
|
||||
for i in range(0, data_len):
|
||||
in_buf[i] ^= mask_buf[i]
|
||||
84
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/models.py
vendored
Executable file
84
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/models.py
vendored
Executable file
@@ -0,0 +1,84 @@
|
||||
"""Models for WebSocket protocol versions 13 and 8."""
|
||||
|
||||
import json
|
||||
from enum import IntEnum
|
||||
from typing import Any, Callable, Final, NamedTuple, Optional, cast
|
||||
|
||||
WS_DEFLATE_TRAILING: Final[bytes] = bytes([0x00, 0x00, 0xFF, 0xFF])
|
||||
|
||||
|
||||
class WSCloseCode(IntEnum):
|
||||
OK = 1000
|
||||
GOING_AWAY = 1001
|
||||
PROTOCOL_ERROR = 1002
|
||||
UNSUPPORTED_DATA = 1003
|
||||
ABNORMAL_CLOSURE = 1006
|
||||
INVALID_TEXT = 1007
|
||||
POLICY_VIOLATION = 1008
|
||||
MESSAGE_TOO_BIG = 1009
|
||||
MANDATORY_EXTENSION = 1010
|
||||
INTERNAL_ERROR = 1011
|
||||
SERVICE_RESTART = 1012
|
||||
TRY_AGAIN_LATER = 1013
|
||||
BAD_GATEWAY = 1014
|
||||
|
||||
|
||||
class WSMsgType(IntEnum):
|
||||
# websocket spec types
|
||||
CONTINUATION = 0x0
|
||||
TEXT = 0x1
|
||||
BINARY = 0x2
|
||||
PING = 0x9
|
||||
PONG = 0xA
|
||||
CLOSE = 0x8
|
||||
|
||||
# aiohttp specific types
|
||||
CLOSING = 0x100
|
||||
CLOSED = 0x101
|
||||
ERROR = 0x102
|
||||
|
||||
text = TEXT
|
||||
binary = BINARY
|
||||
ping = PING
|
||||
pong = PONG
|
||||
close = CLOSE
|
||||
closing = CLOSING
|
||||
closed = CLOSED
|
||||
error = ERROR
|
||||
|
||||
|
||||
class WSMessage(NamedTuple):
|
||||
type: WSMsgType
|
||||
# To type correctly, this would need some kind of tagged union for each type.
|
||||
data: Any
|
||||
extra: Optional[str]
|
||||
|
||||
def json(self, *, loads: Callable[[Any], Any] = json.loads) -> Any:
|
||||
"""Return parsed JSON data.
|
||||
|
||||
.. versionadded:: 0.22
|
||||
"""
|
||||
return loads(self.data)
|
||||
|
||||
|
||||
# Constructing the tuple directly to avoid the overhead of
|
||||
# the lambda and arg processing since NamedTuples are constructed
|
||||
# with a run time built lambda
|
||||
# https://github.com/python/cpython/blob/d83fcf8371f2f33c7797bc8f5423a8bca8c46e5c/Lib/collections/__init__.py#L441
|
||||
WS_CLOSED_MESSAGE = tuple.__new__(WSMessage, (WSMsgType.CLOSED, None, None))
|
||||
WS_CLOSING_MESSAGE = tuple.__new__(WSMessage, (WSMsgType.CLOSING, None, None))
|
||||
|
||||
|
||||
class WebSocketError(Exception):
|
||||
"""WebSocket protocol parser error."""
|
||||
|
||||
def __init__(self, code: int, message: str) -> None:
|
||||
self.code = code
|
||||
super().__init__(code, message)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return cast(str, self.args[1])
|
||||
|
||||
|
||||
class WSHandshakeError(Exception):
|
||||
"""WebSocket protocol handshake error."""
|
||||
31
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/reader.py
vendored
Executable file
31
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/reader.py
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
"""Reader for WebSocket protocol versions 13 and 8."""
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ..helpers import NO_EXTENSIONS
|
||||
|
||||
if TYPE_CHECKING or NO_EXTENSIONS: # pragma: no cover
|
||||
from .reader_py import (
|
||||
WebSocketDataQueue as WebSocketDataQueuePython,
|
||||
WebSocketReader as WebSocketReaderPython,
|
||||
)
|
||||
|
||||
WebSocketReader = WebSocketReaderPython
|
||||
WebSocketDataQueue = WebSocketDataQueuePython
|
||||
else:
|
||||
try:
|
||||
from .reader_c import ( # type: ignore[import-not-found]
|
||||
WebSocketDataQueue as WebSocketDataQueueCython,
|
||||
WebSocketReader as WebSocketReaderCython,
|
||||
)
|
||||
|
||||
WebSocketReader = WebSocketReaderCython
|
||||
WebSocketDataQueue = WebSocketDataQueueCython
|
||||
except ImportError: # pragma: no cover
|
||||
from .reader_py import (
|
||||
WebSocketDataQueue as WebSocketDataQueuePython,
|
||||
WebSocketReader as WebSocketReaderPython,
|
||||
)
|
||||
|
||||
WebSocketReader = WebSocketReaderPython
|
||||
WebSocketDataQueue = WebSocketDataQueuePython
|
||||
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/reader_c.cpython-313-darwin.so
vendored
Executable file
BIN
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/aiohttp/_websocket/reader_c.cpython-313-darwin.so
vendored
Executable file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user