atomicshop 2.16.27__py3-none-any.whl → 2.16.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of atomicshop might be problematic. Click here for more details.

Files changed (31) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/archiver/zips.py +5 -6
  3. atomicshop/basics/strings.py +2 -2
  4. atomicshop/dns.py +8 -6
  5. atomicshop/file_io/file_io.py +7 -7
  6. atomicshop/filesystem.py +6 -7
  7. atomicshop/http_parse.py +12 -18
  8. atomicshop/mitm/connection_thread_worker.py +183 -227
  9. atomicshop/mitm/engines/__parent/parser___parent.py +1 -4
  10. atomicshop/mitm/engines/__parent/recorder___parent.py +1 -1
  11. atomicshop/mitm/message.py +0 -17
  12. atomicshop/mitm/mitm_main.py +29 -27
  13. atomicshop/print_api.py +13 -49
  14. atomicshop/system_resource_monitor.py +8 -8
  15. atomicshop/system_resources.py +8 -8
  16. atomicshop/web.py +10 -10
  17. atomicshop/wrappers/loggingw/filters.py +23 -0
  18. atomicshop/wrappers/loggingw/formatters.py +12 -0
  19. atomicshop/wrappers/loggingw/handlers.py +30 -0
  20. atomicshop/wrappers/loggingw/loggingw.py +135 -8
  21. atomicshop/wrappers/playwrightw/engine.py +6 -7
  22. atomicshop/wrappers/playwrightw/waits.py +9 -7
  23. atomicshop/wrappers/socketw/dns_server.py +1 -1
  24. atomicshop/wrappers/socketw/sender.py +36 -27
  25. atomicshop/wrappers/socketw/socket_client.py +6 -5
  26. atomicshop/wrappers/socketw/socket_wrapper.py +45 -7
  27. {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/METADATA +1 -1
  28. {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/RECORD +31 -31
  29. {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/LICENSE.txt +0 -0
  30. {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/WHEEL +0 -0
  31. {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
 
3
3
  from ..wrappers.socketw import receiver, sender, socket_client, base
4
4
  from ..http_parse import HTTPRequestParse, HTTPResponseParse
5
- from ..basics.threads import current_thread_id
5
+ from ..basics import threads, tracebacks
6
6
  from ..print_api import print_api
7
7
 
8
8
  from .message import ClientMessage
@@ -10,9 +10,8 @@ from .initialize_engines import assign_class_by_domain
10
10
  from . import config_static
11
11
 
12
12
 
13
- # Thread function on client connect.
14
13
  def thread_worker_main(
15
- function_client_socket_object,
14
+ client_socket,
16
15
  process_commandline: str,
17
16
  is_tls: bool,
18
17
  tls_type: str,
@@ -24,7 +23,7 @@ def thread_worker_main(
24
23
  reference_module
25
24
  ):
26
25
  def output_statistics_csv_row():
27
- # If there is no '.code' attribute in HTTPResponse, this means that this is not a HTTP message, so there is no
26
+ # If there is no '.code' attribute in HTTPResponse, this means that this is not an HTTP message, so there is no
28
27
  # status code.
29
28
  try:
30
29
  http_status_code: str = ','.join([str(x.code) for x in client_message.response_list_of_raw_decoded])
@@ -45,6 +44,15 @@ def thread_worker_main(
45
44
 
46
45
  response_size_bytes = ','.join([str(len(x)) for x in client_message.response_list_of_raw_bytes])
47
46
 
47
+ if statistics_error_list and len(statistics_error_list) > 1:
48
+ error_string = '||'.join(statistics_error_list)
49
+ elif statistics_error_list and len(statistics_error_list) == 1:
50
+ error_string = statistics_error_list[0]
51
+ elif not statistics_error_list:
52
+ error_string = str()
53
+ else:
54
+ raise ValueError(f"Error in statistics error list. Values: {statistics_error_list}")
55
+
48
56
  statistics_writer.write_row(
49
57
  host=client_message.server_name,
50
58
  tls_type=tls_type,
@@ -58,75 +66,129 @@ def thread_worker_main(
58
66
  response_size_bytes=response_size_bytes,
59
67
  recorded_file_path=client_message.recorded_file_path,
60
68
  process_cmd=process_commandline,
61
- error=str())
69
+ error=error_string
70
+ )
71
+
72
+ def record_and_statistics_write():
73
+ # If recorder wasn't executed before, then execute it now
74
+ if config_static.LogRec.enable_request_response_recordings_in_logs:
75
+ recorded_file = recorder(
76
+ class_client_message=client_message, record_path=config_static.LogRec.recordings_path).record()
77
+ client_message.recorded_file_path = recorded_file
78
+
79
+ # Save statistics file.
80
+ output_statistics_csv_row()
81
+
82
+ def parse_http():
83
+ nonlocal error_message
84
+ # Parsing the raw bytes as HTTP.
85
+ request_decoded = HTTPRequestParse(client_message.request_raw_bytes)
86
+ # Getting the status of http parsing
87
+ request_is_http, http_parsing_reason, http_parsing_error = request_decoded.check_if_http()
88
+
89
+ # Currently, we don't care if it's HTTP. If there was no error we can continue. Just log the reason.
90
+ if not http_parsing_error:
91
+ print_api(http_parsing_reason, logger=network_logger, logger_method='info')
92
+ # If there was error - the request is really HTTP, but there's a problem with its structure.
93
+ else:
94
+ client_message.error = http_parsing_reason
95
+ error_message = (
96
+ f'HTTP Parse Request Error: '
97
+ f'The request is HTTP protocol, but there was a problem with its structure: '
98
+ f'{http_parsing_error}')
99
+ print_api(error_message, logger=network_logger, logger_method='error', color='yellow')
100
+ statistics_error_list.append(error_message)
101
+
102
+ # If the request is HTTP protocol.
103
+ if request_is_http:
104
+ client_message.protocol = 'HTTP'
105
+ network_logger.info(f"Method: {request_decoded.command}")
106
+ network_logger.info(f"Path: {request_decoded.path}")
107
+ client_message.request_raw_decoded = request_decoded
108
+
109
+ def finish_thread():
110
+ # At this stage there could be several times that the same socket was used to the service server - we need to
111
+ # close this socket as well if it still opened.
112
+ if service_client:
113
+ if service_client.socket_instance:
114
+ service_client.close_socket()
115
+
116
+ # If client socket is still opened - close
117
+ if client_socket:
118
+ client_socket.close()
119
+ network_logger.info(f"Closed client socket [{client_message.client_ip}:{client_message.source_port}]...")
120
+
121
+ network_logger.info("Thread Finished. Will continue listening on the Main thread")
122
+
123
+ # Building client message object before the loop only for any exception to occurs, since we write it to
124
+ # recording file in its current state.
125
+ client_message: ClientMessage = ClientMessage()
126
+ # 'recorded' boolean is needed only to write the message in case of exception in the loop or before that.
127
+ recorded: bool = False
128
+ statistics_error_list: list[str] = list()
129
+
130
+ # Only protocols that are encrypted with TLS have the server name attribute.
131
+ if is_tls:
132
+ # Get current destination domain
133
+ server_name = client_socket.server_hostname
134
+ # client_message.server_name = domain_from_dns
135
+ # If the protocol is not TLS, then we'll use the domain from the DNS.
136
+ else:
137
+ server_name = domain_from_dns
138
+ client_message.server_name = server_name
139
+
140
+ thread_id = threads.current_thread_id()
141
+ client_message.thread_id = thread_id
142
+
143
+ # Loading parser by domain, if there is no parser for current domain - general reference parser is loaded.
144
+ # These should be outside any loop and initialized only once entering the thread.
145
+ parser, responder, recorder = assign_class_by_domain(
146
+ engines_usage=config_static.TCPServer.engines_usage,
147
+ engines_list=engines_list,
148
+ message_domain_name=server_name,
149
+ reference_module=reference_module,
150
+ logger=network_logger
151
+ )
62
152
 
63
153
  try:
64
- # Defining variables before assignment
65
- function_recorded: bool = False
66
- client_message: ClientMessage = ClientMessage()
67
- request_decoded = None
68
- service_client = None
154
+ client_ip, source_port = client_socket.getpeername()
155
+ client_message.client_ip = client_ip
156
+ client_message.source_port = source_port
69
157
 
70
- # Getting thread ID of the current thread and putting to the client message class
71
- client_message.thread_id = current_thread_id()
72
- # Get client ip and port
73
- client_message.client_ip, client_message.source_port = function_client_socket_object.getpeername()
74
- # Get destination port
75
- client_message.destination_port = function_client_socket_object.getsockname()[1]
76
- # Putting the process command line.
77
- client_message.process_name = process_commandline
78
-
79
- # Only protocols that are encrypted with TLS have the server name attribute.
80
- if is_tls:
81
- # Get current destination domain
82
- client_message.server_name = function_client_socket_object.server_hostname
83
- # client_message.server_name = domain_from_dns
84
- # If the protocol is not TLS, then we'll use the domain from the DNS.
85
- else:
86
- client_message.server_name = domain_from_dns
87
-
88
- network_logger.info(f"Thread Created - Client [{client_message.client_ip}:{client_message.source_port}] | "
89
- f"Destination service: [{client_message.server_name}:{client_message.destination_port}]")
90
-
91
- # Loading parser by domain, if there is no parser for current domain - general reference parser is loaded.
92
- # These should be outside any loop and initialized only once entering the thread.
93
- parser, responder, recorder = assign_class_by_domain(
94
- engines_usage=config_static.TCPServer.engines_usage,
95
- engines_list=engines_list,
96
- message_domain_name=client_message.server_name,
97
- reference_module=reference_module,
98
- logger=network_logger
99
- )
158
+ destination_port = client_socket.getsockname()[1]
159
+ client_message.destination_port = destination_port
100
160
 
101
- # Defining client connection boolean variable to enter the loop
102
- client_connection_boolean: bool = True
161
+ network_logger.info(f"Thread Created - Client [{client_ip}:{source_port}] | "
162
+ f"Destination service: [{server_name}:{destination_port}]")
103
163
 
164
+ service_client = None
104
165
  # Loop while received message is not empty, if so, close socket, since other side already closed.
105
- while client_connection_boolean:
106
- # Don't forget that 'ClientMessage' object is being reused at this step.
107
- # Meaning, that each list / dictionary that is used to update at
108
- # this loop section needs to be reinitialized.
109
- # Add any variables that need reinitializing in the 'ClientMessage' class 'reinitialize' function.
110
- client_message.reinitialize()
111
-
112
- # Initialize statistics_dict for the same reason as 'client_message.reinitialize()'.
113
- # statistics_dict: dict = dict()
114
- # statistics_dict['host'] = client_message.server_name
115
- # statistics_dict['path'] = str()
116
- # statistics_dict['status_code'] = str()
117
- # statistics_dict['command'] = str()
118
- # statistics_dict['request_time_sent'] = str()
119
- # statistics_dict['request_size_bytes'] = str()
120
- # # statistics_dict['response_time_sent'] = str()
121
- # statistics_dict['response_size_bytes'] = str()
122
- # statistics_dict['file_path'] = str()
123
- # statistics_dict['process_cmd'] = str()
124
- # statistics_dict['error'] = str()
125
-
126
- network_logger.info("Initializing Receiver")
166
+ # noinspection PyTypeChecker
167
+ cycle_count: int = None
168
+ while True:
169
+ # If cycle count is None, then it's the first cycle, else it's not.
170
+ # The cycle_count should be added 1 in the beginning of each cycle, and not in the end, since not always
171
+ # the cycle will be executed till the end.
172
+ if cycle_count is None:
173
+ cycle_count = 0
174
+ else:
175
+ cycle_count += 1
176
+
177
+ recorded: bool = False
178
+ statistics_error_list: list[str] = list()
179
+
180
+ client_message = ClientMessage()
181
+ client_message.thread_id = thread_id
182
+ client_message.client_ip = client_ip
183
+ client_message.source_port = source_port
184
+ client_message.destination_port = destination_port
185
+ client_message.process_name = process_commandline
186
+ client_message.server_name = server_name
187
+
188
+ network_logger.info(f"Initializing Receiver on cycle: {str(cycle_count+1)}")
127
189
  # Getting message from the client over the socket using specific class.
128
190
  client_received_raw_data = receiver.Receiver(
129
- ssl_socket=function_client_socket_object, logger=network_logger).receive()
191
+ ssl_socket=client_socket, logger=network_logger).receive()
130
192
 
131
193
  # If the message is empty, then the connection was closed already by the other side,
132
194
  # so we can close the socket as well.
@@ -137,67 +199,18 @@ def thread_worker_main(
137
199
  # Getting current time of message received from client.
138
200
  client_message.request_time_received = datetime.now()
139
201
 
140
- # HTTP Parsing section =================================================================================
141
- # Parsing the raw bytes as HTTP.
142
- try:
143
- request_decoded = HTTPRequestParse(client_message.request_raw_bytes)
144
- except Exception:
145
- message = "There was an exception in HTTP Parsing module!"
146
- print_api(
147
- message, error_type=True, logger=network_logger, logger_method='critical',
148
- traceback_string=True)
149
- # Socket connection can be closed since we have a problem in current thread and break the loop
150
- client_connection_boolean = False
151
- break
152
-
153
- # Getting the status of http parsing
154
- request_is_http, http_parsing_reason, http_parsing_error = request_decoded.check_if_http()
155
-
156
- # Currently, we don't care if it's HTTP. If there was no error we can continue. Just log the reason.
157
- if not http_parsing_error:
158
- network_logger.info(http_parsing_reason)
159
- # If there was error - the request is really HTTP, but there's a problem with its structure.
160
- # So, we'll stop the loop.
161
- else:
162
- client_message.error = http_parsing_reason
163
- network_logger.critical(client_message.error)
164
- break
202
+ parse_http()
165
203
 
166
- # If the request is HTTP protocol.
167
- if request_is_http:
168
- client_message.protocol = 'HTTP'
169
- network_logger.info(f"Method: {request_decoded.command}")
170
- network_logger.info(f"Path: {request_decoded.path}")
171
- # statistics.dict['path'] = request_decoded.path
172
- client_message.request_raw_decoded = request_decoded
173
- # HTTP Parsing section EOF =============================================================================
174
-
175
- # Catching exceptions in the parser
176
- try:
177
- parser(client_message).parse()
178
- except Exception:
179
- message = "Exception in Parser"
180
- print_api(
181
- message, error_type=True, logger=parser.logger, logger_method='critical',
182
- traceback_string=True)
183
- print_api(
184
- message, error_type=True, logger=network_logger, logger_method='critical',
185
- traceback_string=True)
186
- # At this point we can pass the exception and continue the script.
187
- pass
188
- # Socket connection can be closed since we have a problem in current thread and break the loop
189
- client_connection_boolean = False
190
- break
204
+ # Custom parser, should parse HTTP body or the whole message if not HTTP.
205
+ parser_instance = parser(client_message)
206
+ parser_instance.parse()
191
207
 
192
- # Converting body parsed to string, since there is no strict rule for the parameter to be string.
193
- # Still going to put exception on it, since it is not critical for the server.
194
- # Won't even log the exception.
195
- try:
196
- parser.logger.info(f"{str(client_message.request_body_parsed)[0: 100]}...")
197
- except Exception:
198
- pass
208
+ # Converting body parsed to string on logging, since there is no strict rule for the parameter
209
+ # to be string.
210
+ parser_instance.logger.info(f"{str(client_message.request_body_parsed)[0: 100]}...")
199
211
 
200
212
  # If we're in response mode, execute responder.
213
+ response_raw_bytes = None
201
214
  if config_static.TCPServer.server_response_mode:
202
215
  # Since we're in response mode, we'll record the request anyway, after the responder did its job.
203
216
  client_message.info = "In Server Response Mode"
@@ -206,20 +219,7 @@ def thread_worker_main(
206
219
  # new entries for empty list.
207
220
  client_message.response_list_of_raw_bytes = list()
208
221
  # Creating response for parsed message and printing
209
- try:
210
- responder.create_response(client_message)
211
- except Exception:
212
- message = "Exception in Responder"
213
- print_api(
214
- message, error_type=True, logger=responder.logger, logger_method='critical',
215
- traceback_string=True)
216
- print_api(
217
- message, error_type=True, logger=network_logger, logger_method='critical',
218
- traceback_string=True)
219
- pass
220
- # Socket connection can be closed since we have a problem in current thread and break the loop.
221
- client_connection_boolean = False
222
- break
222
+ responder.create_response(client_message)
223
223
 
224
224
  # Output first 100 characters of all the responses in the list.
225
225
  for response_raw_bytes in client_message.response_list_of_raw_bytes:
@@ -254,8 +254,11 @@ def thread_worker_main(
254
254
  # be passed.
255
255
  # If there was connection error or socket close, then "ssl_socket" of the "service_client"
256
256
  # will be empty.
257
- response_raw_bytes, client_message.error, client_message.server_ip, service_ssl_socket =\
258
- service_client.send_receive_to_service(client_message.request_raw_bytes)
257
+ response_raw_bytes, client_message.error, client_message.server_ip, service_ssl_socket = (
258
+ service_client.send_receive_to_service(client_message.request_raw_bytes))
259
+
260
+ if client_message.error is not None:
261
+ statistics_error_list.append(client_message.error)
259
262
 
260
263
  # Since we need a list for raw bytes, we'll add the 'response_raw_bytes' to our list object.
261
264
  # But we need to re-initiate it first.
@@ -272,100 +275,53 @@ def thread_worker_main(
272
275
  if not service_ssl_socket:
273
276
  break
274
277
 
275
- # This is the point after the response mode check was finished.
276
- # Recording the message, doesn't matter what type of mode this is.
277
- if config_static.LogRec.enable_request_response_recordings_in_logs:
278
- try:
279
- recorded_file = recorder(class_client_message=client_message,
280
- record_path=config_static.LogRec.recordings_path).record()
281
- client_message.recorded_file_path = recorded_file
282
- except Exception:
283
- message = "Exception in Recorder"
284
- print_api(
285
- message, error_type=True, logger=recorder.logger, logger_method='critical',
286
- traceback_string=True)
287
- print_api(
288
- message, error_type=True, logger=network_logger, logger_method='critical',
289
- traceback_string=True)
290
-
291
- function_recorded = True
292
-
293
- # Save statistics file.
294
- output_statistics_csv_row()
295
-
296
- try:
297
- # If there is a response, then send it.
298
- if response_raw_bytes:
299
- # Sending response/s to client no matter if in record mode or not.
300
- network_logger.info(
301
- f"Sending messages to client: {len(client_message.response_list_of_raw_bytes)}")
302
- function_data_sent = None
303
-
304
- # Iterate through the list of byte responses.
305
- for response_raw_bytes in client_message.response_list_of_raw_bytes:
306
- function_data_sent = sender.Sender(
307
- ssl_socket=function_client_socket_object, class_message=response_raw_bytes,
308
- logger=network_logger).send()
309
-
310
- # If there was problem with sending data, we'll break current loop.
311
- if not function_data_sent:
312
- break
313
- # If there is no response, close the socket.
314
- else:
315
- function_data_sent = None
316
- network_logger.info(f"Response empty, nothing to send to client.")
317
- except Exception:
318
- message = "Not sending anything to the client, since there is no response available"
319
- print_api(
320
- message, error_type=True, logger=network_logger, logger_method='critical',
321
- traceback_string=True)
322
- # Pass the exception
323
- pass
324
- # Break the while loop
325
- break
278
+ # If there is a response, then send it.
279
+ if response_raw_bytes:
280
+ # Sending response/s to client no matter if in record mode or not.
281
+ network_logger.info(
282
+ f"Sending messages to client: {len(client_message.response_list_of_raw_bytes)}")
326
283
 
327
- # If there was problem with sending data, we'll break the while loop
328
- if not function_data_sent:
284
+ # Iterate through the list of byte responses.
285
+ for response_raw_bytes in client_message.response_list_of_raw_bytes:
286
+ error_on_send: str = sender.Sender(
287
+ ssl_socket=client_socket, class_message=response_raw_bytes,
288
+ logger=network_logger).send()
289
+
290
+ # If there was problem with sending data, we'll break current loop.
291
+ if error_on_send:
292
+ statistics_error_list.append(error_on_send)
293
+ break
294
+ # If response from server came back empty, then the server has closed the connection,
295
+ # we will do the same.
296
+ else:
297
+ network_logger.info(f"Response empty, nothing to send to client.")
329
298
  break
299
+
300
+ record_and_statistics_write()
301
+ recorded = True
330
302
  else:
331
- # Ending the while loop, basically we can use 'break'
332
- client_connection_boolean = False
333
- # We don't need to record empty message so setting the recorder state to recorded
334
- function_recorded = True
303
+ # If it's the first cycle we will record the message from the client if it came empty.
304
+ if cycle_count == 0:
305
+ record_and_statistics_write()
306
+
307
+ # In other cases, we'll just break the loop, since empty message means that the other side closed the
308
+ # connection.
309
+ recorded = True
310
+ break
311
+
312
+ finish_thread()
313
+ except Exception as e:
314
+ exception_message = tracebacks.get_as_string(one_line=True)
315
+ error_message = f'Socket Thread [{str(thread_id)}] Exception: {exception_message}'
316
+ print_api(error_message, logger_method='critical', logger=network_logger)
317
+ statistics_error_list.append(error_message)
335
318
 
336
319
  # === At this point while loop of 'client_connection_boolean' was broken =======================================
337
320
  # If recorder wasn't executed before, then execute it now
338
- if not function_recorded:
339
- if config_static.LogRec.enable_request_response_recordings_in_logs:
340
- try:
341
- recorded_file = recorder(
342
- class_client_message=client_message, record_path=config_static.LogRec.recordings_path).record()
343
- client_message.recorded_file_path = recorded_file
344
- except Exception:
345
- message = "Exception in Recorder"
346
- print_api(
347
- message, error_type=True, logger=recorder.logger, logger_method='critical',
348
- traceback_string=True)
349
- print_api(
350
- message, error_type=True, logger=network_logger, logger_method='critical',
351
- traceback_string=True)
352
-
353
- # Save statistics file.
354
- output_statistics_csv_row()
321
+ if not recorded:
322
+ record_and_statistics_write()
355
323
 
356
- # At this stage there could be several times that the same socket was used to the service server - we need to
357
- # close this socket as well if it still opened.
358
- if service_client:
359
- if service_client.socket_instance:
360
- service_client.close_socket()
324
+ finish_thread()
361
325
 
362
- # If client socket is still opened - close
363
- if function_client_socket_object:
364
- function_client_socket_object.close()
365
- network_logger.info(f"Closed client socket [{client_message.client_ip}:{client_message.source_port}]...")
366
-
367
- network_logger.info("Thread Finished. Will continue listening on the Main thread")
368
- except Exception:
369
- message = "Undocumented exception in thread worker"
370
- print_api(
371
- message, error_type=True, logger=network_logger, logger_method='critical', traceback_string=True)
326
+ # After the socket clean up, we will still raise the exception to the main thread.
327
+ raise e
@@ -12,7 +12,4 @@ class ParserParent:
12
12
  # This is general parser, so we don't parse anything and 'request_body_parsed' gets empty byte string.
13
13
  self.class_client_message.request_body_parsed = b''
14
14
 
15
- try:
16
- self.logger.info(f"Parsed: {self.class_client_message.request_body_parsed[0: 100]}...")
17
- except Exception:
18
- pass
15
+ self.logger.info(f"Parsed: {self.class_client_message.request_body_parsed[0: 100]}...")
@@ -90,7 +90,7 @@ class RecorderParent:
90
90
  record_message = get_json(self.class_client_message)
91
91
 
92
92
  # Since we already dumped the object to dictionary string, we'll just save the object to regular file.
93
- file_io.write_file(record_message, self.record_file_path, enable_long_file_path=True)
93
+ file_io.write_file(record_message, self.record_file_path, enable_long_file_path=True, **{'logger': self.logger})
94
94
 
95
95
  self.logger.info(f"Recorded to file: {self.record_file_path}")
96
96
 
@@ -22,20 +22,3 @@ class ClientMessage:
22
22
  self.error: str = str()
23
23
  self.protocol: str = str()
24
24
  self.recorded_file_path: str = str()
25
-
26
- def reinitialize(self) -> None:
27
- """
28
- 'ClientMessage' is being reused, since connection is still established to the server and new requests
29
- are being processed on the same socket, so we need to reinitialize variables that are being updated, like
30
- lists and dictionaries. Added the rest pf the variables that are repopulated to be on the safe side.
31
- :return:
32
- """
33
-
34
- self.request_raw_bytes = bytearray()
35
- self.request_time_received = None
36
- self.request_raw_decoded = None
37
- self.request_body_parsed = None
38
- self.response_list_of_raw_bytes = list()
39
- self.request_raw_hex = None
40
- self.response_list_of_raw_hex = list()
41
- self.response_list_of_raw_decoded = list()