Skip to content

Commit 31fd0cd

Browse files
committed
feat: add PipeProtocol/
1 parent 600ac4a commit 31fd0cd

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

protocols/pipe_protocol/__init__.py

Whitespace-only changes.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import io
2+
import typing
3+
4+
from common.exceptions import SmartInspectError
5+
from connections.builders import ConnectionsBuilder
6+
from formatters import BinaryFormatter
7+
from packets.packet import Packet
8+
from protocols.protocol import Protocol
9+
10+
11+
class PipeProtocol(Protocol):
12+
_BUFFER_SIZE: int = 0x2000
13+
_CLIENT_BANNER_TEMPLATE: str = "SmartInspect Python Library v{}\n"
14+
_PIPE_NAME_PREFIX: str = "\\\\.\\pipe\\"
15+
16+
def __init__(self):
17+
super().__init__()
18+
self._formatter: BinaryFormatter = BinaryFormatter()
19+
self._stream: typing.Optional[io.RawIOBase, io.BufferedIOBase] = None
20+
self._pipe_name: str = ""
21+
self._load_options()
22+
23+
@staticmethod
24+
def _get_name() -> str:
25+
return "pipe"
26+
27+
def _do_handshake(self) -> None:
28+
self._read_server_banner()
29+
self._send_client_banner()
30+
31+
def _read_server_banner(self) -> None:
32+
answer = self._stream.readline().strip()
33+
if not answer:
34+
raise SmartInspectError("Could not read server banner correctly: " +
35+
"Connection has been closed unexpectedly")
36+
37+
def _send_client_banner(self) -> None:
38+
from smartinspect import SmartInspect
39+
si_version = SmartInspect.get_version()
40+
self._stream.write(self._CLIENT_BANNER_TEMPLATE.format(si_version).encode("UTF-8"))
41+
self._stream.flush()
42+
43+
def _is_valid_option(self, option_name: str) -> bool:
44+
return (option_name == "pipename"
45+
or super()._is_valid_option(option_name))
46+
47+
def _build_options(self, builder: ConnectionsBuilder) -> None:
48+
super()._build_options(builder)
49+
builder.add_option("pipename", self._pipe_name)
50+
51+
def _load_options(self) -> None:
52+
super()._load_options()
53+
self._pipe_name = self._get_string_option("pipename", "smartinspect")
54+
55+
def _internal_connect(self) -> None:
56+
filename = self._PIPE_NAME_PREFIX + self._pipe_name
57+
try:
58+
self._stream = open(filename, "w+b", buffering=self._BUFFER_SIZE)
59+
except Exception as e:
60+
raise SmartInspectError(f"\nThere was a connection error. \n"
61+
f"Check if pipe with name <{filename}> exists\n"
62+
f"Your system returned: {type(e).__name__} - {str(e)}")
63+
self._do_handshake()
64+
self._internal_write_log_header()
65+
66+
def _internal_write_packet(self, packet: Packet) -> None:
67+
self._formatter.format(packet, self._stream)
68+
self._stream.flush()
69+
70+
def _internal_disconnect(self) -> None:
71+
if self._stream:
72+
try:
73+
self._stream.close()
74+
finally:
75+
self._stream = None

0 commit comments

Comments
 (0)