# cython: language_level=3 # cython: boundscheck=False # cython: wraparound=False # cython: cdivision=True """ Fast path matching module for PyServe. This Cython module provides optimized path matching operations for ASGI mount routing, significantly reducing overhead on hot paths. """ from cpython.object cimport PyObject cdef class FastMountedPath: cdef: str _path str _path_with_slash Py_ssize_t _path_len bint _is_root public str name public bint strip_path def __cinit__(self): self._path = "" self._path_with_slash = "/" self._path_len = 0 self._is_root = True self.name = "" self.strip_path = True def __init__(self, str path, str name="", bint strip_path=True): cdef Py_ssize_t path_len path_len = len(path) if path_len > 1 and path[path_len - 1] == '/': path = path[:path_len - 1] self._path = path self._path_len = len(path) self._is_root = (path == "" or path == "/") self._path_with_slash = path + "/" if not self._is_root else "/" self.name = name if name else path self.strip_path = strip_path @property def path(self) -> str: return self._path cpdef bint matches(self, str request_path): cdef Py_ssize_t req_len if self._is_root: return True req_len = len(request_path) if req_len < self._path_len: return False if req_len == self._path_len: return (request_path == self._path) if request_path[self._path_len] == '/': return (request_path[:self._path_len] == self._path) return False cpdef str get_modified_path(self, str original_path): cdef str new_path if not self.strip_path: return original_path if self._is_root: return original_path new_path = original_path[self._path_len:] if not new_path: return "/" return new_path def __repr__(self): return f"FastMountedPath(path={self._path!r}, name={self.name!r})" def _get_path_len_neg(mount): return -len(mount.path) cdef class FastMountManager: cdef: list _mounts int _mount_count def __cinit__(self): self._mounts = [] self._mount_count = 0 def __init__(self): self._mounts = [] self._mount_count = 0 cpdef void add_mount(self, FastMountedPath mount): self._mounts.append(mount) self._mounts = sorted(self._mounts, key=_get_path_len_neg, reverse=False) self._mount_count = len(self._mounts) cpdef object get_mount(self, str request_path): cdef: int i FastMountedPath mount for i in range(self._mount_count): mount = self._mounts[i] if mount.matches(request_path): return mount return None cpdef bint remove_mount(self, str path): cdef: int i Py_ssize_t path_len FastMountedPath mount path_len = len(path) if path_len > 1 and path[path_len - 1] == '/': path = path[:path_len - 1] for i in range(self._mount_count): mount = self._mounts[i] if mount._path == path: del self._mounts[i] self._mount_count -= 1 return True return False @property def mounts(self) -> list: return list(self._mounts) @property def mount_count(self) -> int: return self._mount_count cpdef list list_mounts(self): cdef: list result = [] FastMountedPath mount for mount in self._mounts: result.append({ "path": mount._path, "name": mount.name, "strip_path": mount.strip_path, }) return result cpdef bint path_matches_prefix(str request_path, str mount_path): cdef: Py_ssize_t mount_len = len(mount_path) Py_ssize_t req_len = len(request_path) if mount_len == 0 or mount_path == "/": return True if req_len < mount_len: return False if req_len == mount_len: return (request_path == mount_path) if request_path[mount_len] == '/': return (request_path[:mount_len] == mount_path) return False cpdef str strip_path_prefix(str original_path, str mount_path): cdef: Py_ssize_t mount_len = len(mount_path) str result if mount_len == 0 or mount_path == "/": return original_path result = original_path[mount_len:] if not result: return "/" return result cpdef tuple match_and_modify_path(str request_path, str mount_path, bint strip_path=True): cdef: Py_ssize_t mount_len = len(mount_path) Py_ssize_t req_len = len(request_path) bint is_root = (mount_len == 0 or mount_path == "/") str modified if is_root: return (True, request_path if strip_path else request_path) if req_len < mount_len: return (False, None) if req_len == mount_len: if request_path == mount_path: return (True, "/" if strip_path else request_path) return (False, None) if request_path[mount_len] == '/' and request_path[:mount_len] == mount_path: if strip_path: modified = request_path[mount_len:] return (True, modified if modified else "/") return (True, request_path) return (False, None)