Skip to content

Commit 23a8706

Browse files
authored
Merge pull request #14 from Code-Partners/feat-pipe-protocol
Feat pipe protocol
2 parents 35de586 + 5f729fa commit 23a8706

File tree

5 files changed

+93
-11
lines changed

5 files changed

+93
-11
lines changed

protocols/pipe_protocol/__init__.py

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

protocols/protocol_factory.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from protocols.cloud.cloud_protocol import CloudProtocol
55
from protocols.file_protocol.file_protocol import FileProtocol
66
from protocols.memory_protocol import MemoryProtocol
7+
from protocols.pipe_protocol.pipe_protocol import PipeProtocol
78
from protocols.protocol import Protocol
89
from common.exceptions import SmartInspectError
910
from protocols.tcp_protocol import TcpProtocol
@@ -18,6 +19,7 @@ class ProtocolFactory:
1819
"file": FileProtocol,
1920
"text": TextProtocol,
2021
"mem": MemoryProtocol,
22+
"pipe": PipeProtocol,
2123
}
2224
__PROTOCOL_NOT_FOUND = "The requested protocol is unknown"
2325
__lock = threading.Lock()

protocols/tcp_protocol.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@
1212

1313

1414
class TcpProtocol(Protocol):
15-
__BUFFER_SIZE = 0x2000
16-
__CLIENT_BANNER = bytearray(f"SmartInspect Python Library v\n", encoding="UTF-8")
17-
# __CLIENT_BANNER = bytearray(f"SmartInspect Python Library v{SmartInspect.get_version()}\n", encoding="UTF-8")
18-
__ANSWER_BUFFER_SIZE = 0x2000
19-
_hostname = "127.0.0.1"
20-
_timeout = 30000
21-
_port = 4228
15+
__BUFFER_SIZE: int = 0x2000
16+
__CLIENT_BANNER_TEMPLATE: str = "SmartInspect Python Library v{}\n"
17+
__ANSWER_BUFFER_SIZE: int = 0x2000
18+
_hostname: str = "127.0.0.1"
19+
_timeout: int = 30000
20+
_port: int = 4228
2221

2322
def __init__(self):
2423
super().__init__()
@@ -59,7 +58,9 @@ def _read_server_banner(self) -> None:
5958
"Connection has been closed unexpectedly")
6059

6160
def _send_client_banner(self) -> None:
62-
self.__stream.write(self.__CLIENT_BANNER)
61+
from smartinspect import SmartInspect
62+
si_version = SmartInspect.get_version()
63+
self.__stream.write(self.__CLIENT_BANNER_TEMPLATE.format(si_version).encode("UTF-8"))
6364
self.__stream.flush()
6465

6566
def _internal_connect(self):

smartinspect.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ def set_resolution(self, resolution: ClockResolution) -> None:
6868
if isinstance(resolution, ClockResolution):
6969
self.__resolution = resolution
7070

71-
@property
72-
def version(self) -> str:
73-
return self.__VERSION
71+
@classmethod
72+
def get_version(cls) -> str:
73+
return cls.__VERSION
7474

7575
@property
7676
def hostname(self) -> str:

0 commit comments

Comments
 (0)