httpdbg 1.1.0__tar.gz → 1.1.2__tar.gz
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.
- {httpdbg-1.1.0 → httpdbg-1.1.2}/PKG-INFO +3 -2
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/__init__.py +1 -1
- httpdbg-1.1.2/httpdbg/env.py +4 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/http.py +10 -4
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/pytest.py +4 -2
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/socket.py +28 -5
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/unittest.py +3 -3
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/initiator.py +41 -68
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/records.py +20 -10
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg.egg-info/PKG-INFO +3 -2
- httpdbg-1.1.0/httpdbg/env.py +0 -7
- {httpdbg-1.1.0 → httpdbg-1.1.2}/LICENSE +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/README.md +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/__main__.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/args.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/exception.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/__init__.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/aiohttp.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/all.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/external.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/flask.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/generic.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/httpx.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/requests.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/template_sitecustomize.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/urllib3.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/hooks/utils.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/log.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/mode_console.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/mode_module.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/mode_script.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/preview.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/server.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/utils.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/__init__.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/api.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/app.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/api.js +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/column.css +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/configuration.css +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/configuration.js +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/detail.css +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/favicon.ico +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/filter.js +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/eye-blind-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/eye-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/lock-line-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/lock-open-line-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/index.htm +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/main.js +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/mustache.min.js +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/render.js +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/style.css +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/table.css +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg.egg-info/SOURCES.txt +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg.egg-info/dependency_links.txt +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg.egg-info/entry_points.txt +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg.egg-info/top_level.txt +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/pyproject.toml +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/setup.cfg +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_api.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_cli.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_context_manager.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_hook_aiohttp.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_hook_flask.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_hook_httpx.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_hook_pytest.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_hook_requests.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_hook_unittest.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_hook_urllib3.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_initiator.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_mode_console.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_mode_module_pytest.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_mode_script.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_multiprocess.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_preview.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_pyhttpdbg_server.py +0 -0
- {httpdbg-1.1.0 → httpdbg-1.1.2}/tests/test_server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: httpdbg
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: A very simple tool to debug HTTP(S) client and server requests.
|
|
5
5
|
Author-email: cle-b <cle@tictac.pm>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -23,6 +23,7 @@ Classifier: Topic :: Utilities
|
|
|
23
23
|
Requires-Python: >=3.9
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
25
25
|
License-File: LICENSE
|
|
26
|
+
Dynamic: license-file
|
|
26
27
|
|
|
27
28
|
# httpdbg
|
|
28
29
|
|
|
@@ -11,11 +11,17 @@ from httpdbg.records import HTTPRecords
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def set_hook_for_http_server_handle_one_request(records: HTTPRecords, method: Callable):
|
|
14
|
-
def hook(*args, **kwargs):
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
def hook(self, *args, **kwargs):
|
|
16
|
+
from httpdbg.webapp.app import HttpbgHTTPRequestHandler
|
|
17
|
+
|
|
18
|
+
if isinstance(self, HttpbgHTTPRequestHandler):
|
|
19
|
+
# this request is for the httpdbg web server itself, we do not have to create a group
|
|
20
|
+
ret = method(self, *args, **kwargs)
|
|
21
|
+
else:
|
|
22
|
+
# the group label/full_label will be updated when the endpoint method will be called
|
|
23
|
+
with httpdbg_group(records, "one request", ""):
|
|
24
|
+
ret = method(self, *args, **kwargs)
|
|
19
25
|
|
|
20
26
|
return ret
|
|
21
27
|
|
|
@@ -12,13 +12,15 @@ from httpdbg.log import logger
|
|
|
12
12
|
from httpdbg.records import HTTPRecords
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def set_hook_for_pytest_fixture(
|
|
15
|
+
def set_hook_for_pytest_fixture(records: HTTPRecords, method: Callable):
|
|
16
16
|
def hook(*args, **kwargs):
|
|
17
17
|
logger().info("SET_HOOK_FOR_PYTEST_FIXTURE")
|
|
18
18
|
callargs = getcallargs(method, *args, **kwargs)
|
|
19
19
|
|
|
20
20
|
if "fixturefunc" in callargs:
|
|
21
|
-
with httpdbg_tag(
|
|
21
|
+
with httpdbg_tag(
|
|
22
|
+
records, getattr(callargs["fixturefunc"], "__name__", "fixture")
|
|
23
|
+
):
|
|
22
24
|
return method(*args, **kwargs)
|
|
23
25
|
else:
|
|
24
26
|
return method(*args, **kwargs)
|
|
@@ -217,7 +217,11 @@ def set_hook_for_socket_recv_into(records: HTTPRecords, method: Callable):
|
|
|
217
217
|
initiator.tbegin = tbegin
|
|
218
218
|
group.tbegin = tbegin
|
|
219
219
|
socketdata.record = HTTPRecord(
|
|
220
|
-
|
|
220
|
+
records.current_initiator,
|
|
221
|
+
records.current_group,
|
|
222
|
+
records.current_tag,
|
|
223
|
+
tbegin=socketdata.tbegin,
|
|
224
|
+
is_client=False,
|
|
221
225
|
)
|
|
222
226
|
socketdata.record.address = socketdata.address
|
|
223
227
|
socketdata.record.ssl = socketdata.ssl
|
|
@@ -270,7 +274,11 @@ def set_hook_for_socket_recv(records: HTTPRecords, method: Callable):
|
|
|
270
274
|
initiator.tbegin = tbegin
|
|
271
275
|
group.tbegin = tbegin
|
|
272
276
|
socketdata.record = HTTPRecord(
|
|
273
|
-
|
|
277
|
+
records.current_initiator,
|
|
278
|
+
records.current_group,
|
|
279
|
+
records.current_tag,
|
|
280
|
+
tbegin=socketdata.tbegin,
|
|
281
|
+
is_client=False,
|
|
274
282
|
)
|
|
275
283
|
socketdata.record.address = socketdata.address
|
|
276
284
|
socketdata.record.ssl = socketdata.ssl
|
|
@@ -320,7 +328,12 @@ def set_hook_for_socket_sendall(records: HTTPRecords, method: Callable):
|
|
|
320
328
|
)
|
|
321
329
|
initiator.tbegin = tbegin
|
|
322
330
|
group.tbegin = tbegin
|
|
323
|
-
socketdata.record = HTTPRecord(
|
|
331
|
+
socketdata.record = HTTPRecord(
|
|
332
|
+
records.current_initiator,
|
|
333
|
+
records.current_group,
|
|
334
|
+
records.current_tag,
|
|
335
|
+
tbegin=socketdata.tbegin,
|
|
336
|
+
)
|
|
324
337
|
socketdata.record.address = socketdata.address
|
|
325
338
|
socketdata.record.ssl = socketdata.ssl
|
|
326
339
|
socketdata.record.send_data(socketdata.rawdata)
|
|
@@ -371,7 +384,12 @@ def set_hook_for_socket_send(records: HTTPRecords, method: Callable):
|
|
|
371
384
|
)
|
|
372
385
|
initiator.tbegin = tbegin
|
|
373
386
|
group.tbegin = tbegin
|
|
374
|
-
socketdata.record = HTTPRecord(
|
|
387
|
+
socketdata.record = HTTPRecord(
|
|
388
|
+
records.current_initiator,
|
|
389
|
+
records.current_group,
|
|
390
|
+
records.current_tag,
|
|
391
|
+
tbegin=socketdata.tbegin,
|
|
392
|
+
)
|
|
375
393
|
socketdata.record.address = socketdata.address
|
|
376
394
|
socketdata.record.ssl = socketdata.ssl
|
|
377
395
|
socketdata.record.send_data(socketdata.rawdata)
|
|
@@ -446,7 +464,12 @@ def set_hook_for_sslobject_write(records: HTTPRecords, method: Callable):
|
|
|
446
464
|
)
|
|
447
465
|
initiator.tbegin = tbegin
|
|
448
466
|
group.tbegin = tbegin
|
|
449
|
-
socketdata.record = HTTPRecord(
|
|
467
|
+
socketdata.record = HTTPRecord(
|
|
468
|
+
records.current_initiator,
|
|
469
|
+
records.current_group,
|
|
470
|
+
records.current_tag,
|
|
471
|
+
tbegin=socketdata.tbegin,
|
|
472
|
+
)
|
|
450
473
|
socketdata.record.address = socketdata.address
|
|
451
474
|
socketdata.record.ssl = socketdata.ssl
|
|
452
475
|
socketdata.record.send_data(socketdata.rawdata)
|
|
@@ -45,15 +45,15 @@ def set_hook_for_unittest_run(records: HTTPRecords, method: Callable):
|
|
|
45
45
|
return hook
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def set_hook_for_unittest_fixture(
|
|
48
|
+
def set_hook_for_unittest_fixture(records: HTTPRecords, method: Callable):
|
|
49
49
|
|
|
50
50
|
def hook(*args, **kwargs):
|
|
51
51
|
|
|
52
52
|
if getattr(method, "__name__") == "_callSetUp":
|
|
53
|
-
with httpdbg_tag("setUp"):
|
|
53
|
+
with httpdbg_tag(records, "setUp"):
|
|
54
54
|
return method(*args, **kwargs)
|
|
55
55
|
elif getattr(method, "__name__") == "_callTearDown":
|
|
56
|
-
with httpdbg_tag("tearDown"):
|
|
56
|
+
with httpdbg_tag(records, "tearDown"):
|
|
57
57
|
return method(*args, **kwargs)
|
|
58
58
|
else:
|
|
59
59
|
return method(*args, **kwargs)
|
|
@@ -15,9 +15,6 @@ from typing import TYPE_CHECKING
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
16
|
from httpdbg.records import HTTPRecords
|
|
17
17
|
|
|
18
|
-
from httpdbg.env import HTTPDBG_CURRENT_GROUP
|
|
19
|
-
from httpdbg.env import HTTPDBG_CURRENT_INITIATOR
|
|
20
|
-
from httpdbg.env import HTTPDBG_CURRENT_TAG
|
|
21
18
|
from httpdbg.hooks.utils import getcallargs
|
|
22
19
|
from httpdbg.utils import get_new_uuid
|
|
23
20
|
from httpdbg.log import logger
|
|
@@ -244,26 +241,16 @@ def httpdbg_initiator(
|
|
|
244
241
|
*args,
|
|
245
242
|
**kwargs,
|
|
246
243
|
) -> Generator[Union[Tuple[Initiator, Group, bool], None], None, None]:
|
|
247
|
-
# An initiator is considered set if the environment variable exists and the initiator
|
|
248
|
-
# is recorded.If the environment variable exists but the initiatir is not recorded,
|
|
249
|
-
# it means httpdbg was called reentrantly, and we need to record the initiator again
|
|
250
|
-
# using the same id.
|
|
251
|
-
initiator_already_set = (HTTPDBG_CURRENT_INITIATOR in os.environ) and (
|
|
252
|
-
os.environ[HTTPDBG_CURRENT_INITIATOR] in records.initiators
|
|
253
|
-
)
|
|
254
|
-
try:
|
|
255
|
-
if not initiator_already_set:
|
|
256
|
-
original_initiator_id = None
|
|
257
|
-
if HTTPDBG_CURRENT_INITIATOR not in os.environ:
|
|
258
|
-
# temporary set a fake initiator env variable to avoid a recursion error
|
|
259
|
-
# RecursionError: maximum recursion depth exceeded while calling a Python object
|
|
260
|
-
# TL;DR When we construct the short_stack string, a recursion error occurs if there
|
|
261
|
-
# is an object from a class where a hooked method is called in __repr__ or __str__.
|
|
262
|
-
os.environ[HTTPDBG_CURRENT_INITIATOR] = "blabla"
|
|
263
|
-
else:
|
|
264
|
-
original_initiator_id = os.environ[HTTPDBG_CURRENT_INITIATOR]
|
|
265
244
|
|
|
266
|
-
|
|
245
|
+
try:
|
|
246
|
+
if records.current_initiator is None:
|
|
247
|
+
initiator_already_set = False
|
|
248
|
+
|
|
249
|
+
# temporary set a fake initiator env variable to avoid a recursion error
|
|
250
|
+
# RecursionError: maximum recursion depth exceeded while calling a Python object
|
|
251
|
+
# TL;DR When we construct the short_stack string, a recursion error occurs if there
|
|
252
|
+
# is an object from a class where a hooked method is called in __repr__ or __str__.
|
|
253
|
+
records.current_initiator = "--fakeinitiator--"
|
|
267
254
|
instruction, short_stack, stack = get_current_instruction(extracted_stack)
|
|
268
255
|
short_stack += "----------\n" + construct_call_str(
|
|
269
256
|
original_method, *args, **kwargs
|
|
@@ -271,51 +258,48 @@ def httpdbg_initiator(
|
|
|
271
258
|
|
|
272
259
|
current_initiator = Initiator(instruction, short_stack, stack)
|
|
273
260
|
|
|
274
|
-
|
|
275
|
-
# if we already have an initiator id (reentrant call) we change the initiator id
|
|
276
|
-
# to keep the same
|
|
277
|
-
current_initiator.id = original_initiator_id
|
|
278
|
-
|
|
279
|
-
records.initiators[current_initiator.id] = current_initiator
|
|
280
|
-
|
|
281
|
-
os.environ[HTTPDBG_CURRENT_INITIATOR] = current_initiator.id
|
|
282
|
-
|
|
261
|
+
records.add_initiator(current_initiator)
|
|
283
262
|
else:
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
263
|
+
initiator_already_set = True
|
|
264
|
+
if records.current_initiator != "--fakeinitiator--":
|
|
265
|
+
current_initiator = records.initiators[records.current_initiator]
|
|
266
|
+
else:
|
|
267
|
+
# this fake initiator does not need to be recorded
|
|
268
|
+
current_initiator = Initiator("", "", [])
|
|
287
269
|
|
|
288
270
|
with httpdbg_group(
|
|
289
271
|
records, current_initiator.label, current_initiator.short_stack
|
|
290
272
|
) as group: # by default we group the requests by initiator
|
|
291
273
|
yield current_initiator, group, initiator_already_set is False
|
|
292
274
|
except Exception:
|
|
293
|
-
if
|
|
294
|
-
|
|
275
|
+
if not initiator_already_set:
|
|
276
|
+
records.current_initiator = None
|
|
295
277
|
raise
|
|
296
278
|
|
|
297
|
-
if
|
|
298
|
-
|
|
279
|
+
if not initiator_already_set:
|
|
280
|
+
records.current_initiator = None
|
|
299
281
|
|
|
300
282
|
|
|
301
283
|
@contextmanager
|
|
302
|
-
def httpdbg_tag(tag: str) -> Generator[None, None, None]:
|
|
303
|
-
|
|
304
|
-
tag_already_set = HTTPDBG_CURRENT_TAG in os.environ
|
|
284
|
+
def httpdbg_tag(records: "HTTPRecords", tag: str) -> Generator[None, None, None]:
|
|
305
285
|
|
|
306
|
-
if
|
|
307
|
-
|
|
286
|
+
if records.current_tag is None:
|
|
287
|
+
tag_already_set = False
|
|
288
|
+
logger().info("httpdbg_tag (new)")
|
|
289
|
+
records.current_tag = tag
|
|
290
|
+
else:
|
|
291
|
+
tag_already_set = True
|
|
308
292
|
|
|
309
293
|
try:
|
|
310
294
|
logger().info(f"httpdbg_tag {tag}")
|
|
311
295
|
yield
|
|
312
296
|
except Exception:
|
|
313
|
-
if
|
|
314
|
-
|
|
297
|
+
if not tag_already_set:
|
|
298
|
+
records.current_tag = None
|
|
315
299
|
raise
|
|
316
300
|
|
|
317
|
-
if
|
|
318
|
-
|
|
301
|
+
if not tag_already_set:
|
|
302
|
+
records.current_tag = None
|
|
319
303
|
|
|
320
304
|
|
|
321
305
|
@contextmanager
|
|
@@ -327,25 +311,14 @@ def httpdbg_group(
|
|
|
327
311
|
updatable: bool = True,
|
|
328
312
|
) -> Generator[Group, None, None]:
|
|
329
313
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
# it means httpdbg was called reentrantly, and we need to record the group again
|
|
333
|
-
# using the same id.
|
|
334
|
-
group_already_set = (HTTPDBG_CURRENT_GROUP in os.environ) and (
|
|
335
|
-
os.environ[HTTPDBG_CURRENT_GROUP] in records.groups
|
|
336
|
-
)
|
|
337
|
-
|
|
338
|
-
if not group_already_set:
|
|
314
|
+
if records.current_group is None:
|
|
315
|
+
group_already_set = False
|
|
339
316
|
logger().info("httpdbg_group (new)")
|
|
340
317
|
group = Group(label, full_label, updatable=updatable)
|
|
341
|
-
|
|
342
|
-
if HTTPDBG_CURRENT_GROUP in os.environ:
|
|
343
|
-
group.id = os.environ[HTTPDBG_CURRENT_GROUP]
|
|
344
|
-
logger().info("httpdbg_group (reentrant) keep id {group.id}")
|
|
345
|
-
records.groups[group.id] = group
|
|
346
|
-
os.environ[HTTPDBG_CURRENT_GROUP] = group.id
|
|
318
|
+
records.add_group(group)
|
|
347
319
|
else:
|
|
348
|
-
|
|
320
|
+
group_already_set = True
|
|
321
|
+
group = records.groups[records.current_group]
|
|
349
322
|
|
|
350
323
|
if update and group.updatable:
|
|
351
324
|
# Update the label and full_label of an existing group, in case of endpoint.
|
|
@@ -353,16 +326,16 @@ def httpdbg_group(
|
|
|
353
326
|
group.full_label = full_label
|
|
354
327
|
try:
|
|
355
328
|
logger().info(
|
|
356
|
-
f"httpdbg_group {group} group_id={
|
|
329
|
+
f"httpdbg_group {group} group_id={records.current_group} label={label} full_label={full_label}"
|
|
357
330
|
)
|
|
358
331
|
yield group
|
|
359
332
|
except Exception:
|
|
360
|
-
if
|
|
361
|
-
|
|
333
|
+
if not group_already_set:
|
|
334
|
+
records.current_group = None
|
|
362
335
|
raise
|
|
363
336
|
|
|
364
|
-
if
|
|
365
|
-
|
|
337
|
+
if not group_already_set:
|
|
338
|
+
records.current_group = None
|
|
366
339
|
|
|
367
340
|
|
|
368
341
|
@contextmanager
|
|
@@ -2,16 +2,12 @@
|
|
|
2
2
|
import asyncio
|
|
3
3
|
import asyncio.proactor_events
|
|
4
4
|
import datetime
|
|
5
|
-
import os
|
|
6
5
|
import socket
|
|
7
6
|
import ssl
|
|
8
7
|
import sys
|
|
9
8
|
from urllib.parse import urlparse
|
|
10
9
|
from typing import Dict, List, Tuple, Union
|
|
11
10
|
|
|
12
|
-
from httpdbg.env import HTTPDBG_CURRENT_GROUP
|
|
13
|
-
from httpdbg.env import HTTPDBG_CURRENT_INITIATOR
|
|
14
|
-
from httpdbg.env import HTTPDBG_CURRENT_TAG
|
|
15
11
|
from httpdbg.utils import HTTPDBGCookie
|
|
16
12
|
from httpdbg.utils import HTTPDBGHeader
|
|
17
13
|
from httpdbg.initiator import Group
|
|
@@ -212,21 +208,24 @@ class HTTPRecordResponse(HTTPRecordReqResp):
|
|
|
212
208
|
|
|
213
209
|
class HTTPRecord:
|
|
214
210
|
def __init__(
|
|
215
|
-
self,
|
|
211
|
+
self,
|
|
212
|
+
initiator_id: str = None,
|
|
213
|
+
group_id: str = None,
|
|
214
|
+
tag: str = None,
|
|
215
|
+
tbegin: datetime.datetime = None,
|
|
216
|
+
is_client: bool = True,
|
|
216
217
|
) -> None:
|
|
217
218
|
self.id = get_new_uuid()
|
|
218
219
|
self.address: Tuple[str, int] = ("", 0)
|
|
219
220
|
self._url: Union[str, None] = None
|
|
220
|
-
self.initiator_id: Union[str, None] =
|
|
221
|
-
f"{HTTPDBG_CURRENT_INITIATOR}"
|
|
222
|
-
)
|
|
221
|
+
self.initiator_id: Union[str, None] = initiator_id
|
|
223
222
|
self.exception: Union[Exception, None] = None
|
|
224
223
|
self.request: HTTPRecordRequest = HTTPRecordRequest()
|
|
225
224
|
self.response: HTTPRecordResponse = HTTPRecordResponse()
|
|
226
225
|
self.ssl: Union[bool, None] = None
|
|
227
226
|
self.tbegin: datetime.datetime = datetime.datetime.now(datetime.timezone.utc)
|
|
228
|
-
self.tag: Union[str, None] =
|
|
229
|
-
self.group_id: Union[str, None] =
|
|
227
|
+
self.tag: Union[str, None] = tag
|
|
228
|
+
self.group_id: Union[str, None] = group_id
|
|
230
229
|
self.is_client: bool = is_client
|
|
231
230
|
if tbegin:
|
|
232
231
|
self.tbegin = tbegin
|
|
@@ -337,7 +336,10 @@ class HTTPRecords:
|
|
|
337
336
|
self.requests: Dict[str, HTTPRecord] = {}
|
|
338
337
|
self.requests_already_loaded = 0
|
|
339
338
|
self.initiators: Dict[str, Initiator] = {}
|
|
339
|
+
self.current_initiator: Union[str, None] = None
|
|
340
340
|
self.groups: Dict[str, Group] = {}
|
|
341
|
+
self.current_group: Union[str, None] = None
|
|
342
|
+
self.current_tag: Union[str, None] = None
|
|
341
343
|
self._sockets: Dict[int, SocketRawData] = {}
|
|
342
344
|
|
|
343
345
|
@property
|
|
@@ -443,3 +445,11 @@ class HTTPRecords:
|
|
|
443
445
|
new_record.exception = exception
|
|
444
446
|
self.requests[new_record.id] = new_record
|
|
445
447
|
return new_record
|
|
448
|
+
|
|
449
|
+
def add_initiator(self, initiator: Initiator):
|
|
450
|
+
self.initiators[initiator.id] = initiator
|
|
451
|
+
self.current_initiator = initiator.id
|
|
452
|
+
|
|
453
|
+
def add_group(self, group: Group):
|
|
454
|
+
self.groups[group.id] = group
|
|
455
|
+
self.current_group = group.id
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: httpdbg
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: A very simple tool to debug HTTP(S) client and server requests.
|
|
5
5
|
Author-email: cle-b <cle@tictac.pm>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -23,6 +23,7 @@ Classifier: Topic :: Utilities
|
|
|
23
23
|
Requires-Python: >=3.9
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
25
25
|
License-File: LICENSE
|
|
26
|
+
Dynamic: license-file
|
|
26
27
|
|
|
27
28
|
# httpdbg
|
|
28
29
|
|
httpdbg-1.1.0/httpdbg/env.py
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
HTTPDBG_CURRENT_GROUP = "HTTPDBG_CURRENT_GROUP"
|
|
2
|
-
HTTPDBG_CURRENT_INITIATOR = "HTTPDBG_CURRENT_INITIATOR"
|
|
3
|
-
HTTPDBG_CURRENT_TAG = "HTTPDBG_CURRENT_TAG"
|
|
4
|
-
HTTPDBG_MULTIPROCESS_DIR = "HTTPDBG_MULTIPROCESS_DIR"
|
|
5
|
-
|
|
6
|
-
HTTPDBG_LOG_LEVEL = "HTTPDBG_LOG_LEVEL"
|
|
7
|
-
HTTPDBG_LOG_PATH = "HTTPDBG_LOG_PATH"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{httpdbg-1.1.0 → httpdbg-1.1.2}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|