httpdbg 0.28.2__tar.gz → 0.28.3__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-0.28.2 → httpdbg-0.28.3}/PKG-INFO +1 -1
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/__init__.py +1 -1
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/aiohttp.py +5 -9
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/httpx.py +9 -17
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/requests.py +5 -9
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/socket.py +61 -41
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/urllib3.py +5 -9
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/records.py +13 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg.egg-info/PKG-INFO +1 -1
- {httpdbg-0.28.2 → httpdbg-0.28.3}/LICENSE +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/README.md +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/__main__.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/args.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/env.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/exception.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/__init__.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/all.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/external.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/generic.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/pytest.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/hooks/utils.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/initiator.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/log.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/mode_console.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/mode_module.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/mode_script.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/preview.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/server.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/utils.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/__init__.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/api.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/app.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/api.js +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/column.css +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/configuration.js +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/detail.css +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/favicon.ico +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/filter.js +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/index.htm +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/main.js +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/mustache.min.js +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/render.js +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/style.css +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/table.css +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg.egg-info/SOURCES.txt +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg.egg-info/dependency_links.txt +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg.egg-info/entry_points.txt +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg.egg-info/requires.txt +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg.egg-info/top_level.txt +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/pyproject.toml +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/setup.cfg +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_api.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_cli.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_context_manager.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_hook_aiohttp.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_hook_httpx.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_hook_requests.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_hook_urllib3.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_initiator.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_mode_console.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_mode_module_pytest.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_mode_script.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_preview.py +0 -0
- {httpdbg-0.28.2 → httpdbg-0.28.3}/tests/test_server.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
from collections.abc import Callable
|
|
2
3
|
from contextlib import contextmanager
|
|
3
4
|
import traceback
|
|
4
5
|
from typing import Generator
|
|
@@ -7,11 +8,10 @@ from httpdbg.hooks.utils import getcallargs
|
|
|
7
8
|
from httpdbg.hooks.utils import decorate
|
|
8
9
|
from httpdbg.hooks.utils import undecorate
|
|
9
10
|
from httpdbg.initiator import httpdbg_initiator
|
|
10
|
-
from httpdbg.records import HTTPRecord
|
|
11
11
|
from httpdbg.records import HTTPRecords
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def set_hook_for_aiohttp_async(records, method):
|
|
14
|
+
def set_hook_for_aiohttp_async(records: HTTPRecords, method: Callable):
|
|
15
15
|
async def hook(*args, **kwargs):
|
|
16
16
|
initiator = None
|
|
17
17
|
try:
|
|
@@ -25,13 +25,9 @@ def set_hook_for_aiohttp_async(records, method):
|
|
|
25
25
|
|
|
26
26
|
if "str_or_url" in callargs:
|
|
27
27
|
if initiator:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
record.url = str(callargs["str_or_url"])
|
|
32
|
-
record.exception = ex
|
|
33
|
-
|
|
34
|
-
records.requests[record.id] = record
|
|
28
|
+
records.add_new_record_exception(
|
|
29
|
+
initiator, str(callargs["str_or_url"]), ex
|
|
30
|
+
)
|
|
35
31
|
raise
|
|
36
32
|
|
|
37
33
|
return hook
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
from collections.abc import Callable
|
|
2
3
|
from contextlib import contextmanager
|
|
3
4
|
import traceback
|
|
4
5
|
from typing import Generator
|
|
@@ -7,11 +8,10 @@ from httpdbg.hooks.utils import getcallargs
|
|
|
7
8
|
from httpdbg.hooks.utils import decorate
|
|
8
9
|
from httpdbg.hooks.utils import undecorate
|
|
9
10
|
from httpdbg.initiator import httpdbg_initiator
|
|
10
|
-
from httpdbg.records import HTTPRecord
|
|
11
11
|
from httpdbg.records import HTTPRecords
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def set_hook_for_httpx_async(records, method):
|
|
14
|
+
def set_hook_for_httpx_async(records: HTTPRecords, method: Callable):
|
|
15
15
|
async def hook(*args, **kwargs):
|
|
16
16
|
initiator = None
|
|
17
17
|
try:
|
|
@@ -25,19 +25,15 @@ def set_hook_for_httpx_async(records, method):
|
|
|
25
25
|
|
|
26
26
|
if "url" in callargs:
|
|
27
27
|
if initiator:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
record.url = str(callargs["url"])
|
|
32
|
-
record.exception = ex
|
|
33
|
-
|
|
34
|
-
records.requests[record.id] = record
|
|
28
|
+
records.add_new_record_exception(
|
|
29
|
+
initiator, str(callargs["url"]), ex
|
|
30
|
+
)
|
|
35
31
|
raise
|
|
36
32
|
|
|
37
33
|
return hook
|
|
38
34
|
|
|
39
35
|
|
|
40
|
-
def set_hook_for_httpx(records, method):
|
|
36
|
+
def set_hook_for_httpx(records: HTTPRecords, method: Callable):
|
|
41
37
|
def hook(*args, **kwargs):
|
|
42
38
|
initiator = None
|
|
43
39
|
try:
|
|
@@ -51,13 +47,9 @@ def set_hook_for_httpx(records, method):
|
|
|
51
47
|
|
|
52
48
|
if "url" in callargs:
|
|
53
49
|
if initiator:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
record.url = str(callargs["url"])
|
|
58
|
-
record.exception = ex
|
|
59
|
-
|
|
60
|
-
records.requests[record.id] = record
|
|
50
|
+
records.add_new_record_exception(
|
|
51
|
+
initiator, str(callargs["url"]), ex
|
|
52
|
+
)
|
|
61
53
|
raise
|
|
62
54
|
|
|
63
55
|
return hook
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
from collections.abc import Callable
|
|
2
3
|
from contextlib import contextmanager
|
|
3
4
|
import traceback
|
|
4
5
|
from typing import Generator
|
|
@@ -7,11 +8,10 @@ from httpdbg.hooks.utils import getcallargs
|
|
|
7
8
|
from httpdbg.hooks.utils import decorate
|
|
8
9
|
from httpdbg.hooks.utils import undecorate
|
|
9
10
|
from httpdbg.initiator import httpdbg_initiator
|
|
10
|
-
from httpdbg.records import HTTPRecord
|
|
11
11
|
from httpdbg.records import HTTPRecords
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def set_hook_for_requests(records, method):
|
|
14
|
+
def set_hook_for_requests(records: HTTPRecords, method: Callable):
|
|
15
15
|
def hook(*args, **kwargs):
|
|
16
16
|
initiator = None
|
|
17
17
|
try:
|
|
@@ -25,13 +25,9 @@ def set_hook_for_requests(records, method):
|
|
|
25
25
|
|
|
26
26
|
if "url" in callargs:
|
|
27
27
|
if initiator:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
record.url = str(callargs["url"])
|
|
32
|
-
record.exception = ex
|
|
33
|
-
|
|
34
|
-
records.requests[record.id] = record
|
|
28
|
+
records.add_new_record_exception(
|
|
29
|
+
initiator, str(callargs["url"]), ex
|
|
30
|
+
)
|
|
35
31
|
raise
|
|
36
32
|
|
|
37
33
|
return hook
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import asyncio
|
|
3
3
|
import asyncio.proactor_events
|
|
4
|
+
from collections.abc import Callable
|
|
4
5
|
from contextlib import contextmanager
|
|
5
6
|
import platform
|
|
6
7
|
import socket
|
|
@@ -16,7 +17,10 @@ from httpdbg.records import HTTPRecords
|
|
|
16
17
|
from httpdbg.log import logger
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
# hook: socket.socket.__init__
|
|
21
|
+
# what: A new socket object is created.
|
|
22
|
+
# action: If an entry exists in the temporary raw socket storage list, it is removed.
|
|
23
|
+
def set_hook_for_socket_init(records: HTTPRecords, method: Callable):
|
|
20
24
|
def hook(self, *args, **kwargs):
|
|
21
25
|
records.del_socket_data(self)
|
|
22
26
|
|
|
@@ -25,27 +29,24 @@ def set_hook_for_socket_init(records, method):
|
|
|
25
29
|
return hook
|
|
26
30
|
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
# hook: socket.socket.connect, ssl.SSLSocket.connect
|
|
33
|
+
# what: A connection to a remote socket is initiated.
|
|
34
|
+
# action: A new entry is added to the temporary raw socket storage list.
|
|
35
|
+
def set_hook_for_socket_connect(records: HTTPRecords, method: Callable):
|
|
29
36
|
def hook(self, address):
|
|
30
37
|
socketdata = records.get_socket_data(self, force_new=True)
|
|
31
38
|
if socketdata:
|
|
32
39
|
logger().info(
|
|
33
40
|
f"CONNECT - self={self} id={id(self)} socketdata={socketdata} address={address}"
|
|
34
41
|
)
|
|
35
|
-
|
|
36
42
|
try:
|
|
37
43
|
r = method(self, address)
|
|
38
44
|
except Exception as ex:
|
|
39
45
|
if not isinstance(
|
|
40
46
|
ex, (BlockingIOError, OSError)
|
|
41
47
|
): # BlockingIOError for async, OSError for ipv6
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
record.exception = ex
|
|
46
|
-
|
|
47
|
-
records.requests[record.id] = record
|
|
48
|
-
|
|
48
|
+
initiator = records.get_initiator()
|
|
49
|
+
records.add_new_record_exception(initiator, "", ex)
|
|
49
50
|
raise
|
|
50
51
|
|
|
51
52
|
return r
|
|
@@ -53,18 +54,17 @@ def set_hook_for_socket_connect(records, method):
|
|
|
53
54
|
return hook
|
|
54
55
|
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
# hook: ssl.wrap_socket,
|
|
58
|
+
# what: Takes an instance sock of socket.socket, and returns an instance of ssl.SSLSocket.
|
|
59
|
+
# a subtype of socket.socket, which wraps the underlying socket in an SSL context.
|
|
60
|
+
# action: Link the socket and the sslsocket
|
|
61
|
+
def set_hook_for_ssl_wrap_socket(records: HTTPRecords, method: Callable):
|
|
57
62
|
def hook(sock, *args, **kwargs):
|
|
58
63
|
try:
|
|
59
64
|
sslsocket = method(sock, *args, **kwargs)
|
|
60
65
|
except Exception as ex:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
record.initiator = records.get_initiator()
|
|
64
|
-
record.exception = ex
|
|
65
|
-
|
|
66
|
-
records.requests[record.id] = record
|
|
67
|
-
|
|
66
|
+
initiator = records.get_initiator()
|
|
67
|
+
records.add_new_record_exception(initiator, "", ex)
|
|
68
68
|
raise
|
|
69
69
|
|
|
70
70
|
logger().info(
|
|
@@ -80,18 +80,16 @@ def set_hook_for_ssl_wrap_socket(records, method):
|
|
|
80
80
|
return hook
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
# hook: ssl.SSLContext.wrap_socket
|
|
84
|
+
# what: Wrap an existing Python socket sock and return an instance of SSLContext.sslsocket_class (default SSLSocket).
|
|
85
|
+
# action: Link the socket and the sslsocket
|
|
86
|
+
def set_hook_for_sslcontext_wrap_socket(records: HTTPRecords, method: Callable):
|
|
84
87
|
def hook(self, sock, *args, **kwargs):
|
|
85
88
|
try:
|
|
86
89
|
sslsocket = method(self, sock, *args, **kwargs)
|
|
87
90
|
except Exception as ex:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
record.initiator = records.get_initiator()
|
|
91
|
-
record.exception = ex
|
|
92
|
-
|
|
93
|
-
records.requests[record.id] = record
|
|
94
|
-
|
|
91
|
+
initiator = records.get_initiator()
|
|
92
|
+
records.add_new_record_exception(initiator, "", ex)
|
|
95
93
|
raise
|
|
96
94
|
|
|
97
95
|
logger().info(
|
|
@@ -107,18 +105,16 @@ def set_hook_for_sslcontext_wrap_socket(records, method):
|
|
|
107
105
|
return hook
|
|
108
106
|
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
# hook: ssl.SSLContext.wrap_bio
|
|
109
|
+
# what: Wrap the BIO objects incoming and outgoing and return an instance of SSLContext.sslobject_class (default SSLObject).
|
|
110
|
+
# action: Record a new SocketRawData if necessary
|
|
111
|
+
def set_hook_for_socket_wrap_bio(records: HTTPRecords, method: Callable):
|
|
111
112
|
def hook(self, *args, **kwargs):
|
|
112
113
|
try:
|
|
113
114
|
sslobject = method(self, *args, **kwargs)
|
|
114
115
|
except Exception as ex:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
record.exception = ex
|
|
119
|
-
|
|
120
|
-
records.requests[record.id] = record
|
|
121
|
-
|
|
116
|
+
initiator = records.get_initiator()
|
|
117
|
+
records.add_new_record_exception(initiator, "", ex)
|
|
122
118
|
raise
|
|
123
119
|
|
|
124
120
|
logger().info(
|
|
@@ -134,7 +130,10 @@ def set_hook_for_socket_wrap_bio(records, method):
|
|
|
134
130
|
return hook
|
|
135
131
|
|
|
136
132
|
|
|
137
|
-
|
|
133
|
+
# hook: socket.socket.recv_into, ssl.SSLSocket.recv_into, asyncio.proactor_events._ProactorReadPipeTransport._data_received
|
|
134
|
+
# what: Receive up to nbytes bytes from the socket, storing the data into a buffer rather than creating a new bytestring.
|
|
135
|
+
# action: Append the data to an existing SocketRawData
|
|
136
|
+
def set_hook_for_socket_recv_into(records: HTTPRecords, method: Callable):
|
|
138
137
|
def hook(self, buffer, *args, **kwargs):
|
|
139
138
|
socketdata = records.get_socket_data(self)
|
|
140
139
|
if socketdata:
|
|
@@ -160,7 +159,10 @@ def set_hook_for_socket_recv_into(records, method):
|
|
|
160
159
|
return hook
|
|
161
160
|
|
|
162
161
|
|
|
163
|
-
|
|
162
|
+
# hook: socket.socket.recv, ssl.SSLSocket.recv
|
|
163
|
+
# what: Receive data from the socket. The return value is a bytes object representing the data received.
|
|
164
|
+
# action: Append the data to an existing SocketRawData
|
|
165
|
+
def set_hook_for_socket_recv(records: HTTPRecords, method: Callable):
|
|
164
166
|
def hook(self, bufsize, *args, **kwargs):
|
|
165
167
|
socketdata = records.get_socket_data(self)
|
|
166
168
|
if socketdata:
|
|
@@ -183,7 +185,11 @@ def set_hook_for_socket_recv(records, method):
|
|
|
183
185
|
return hook
|
|
184
186
|
|
|
185
187
|
|
|
186
|
-
|
|
188
|
+
# hook: socket.socket.sendall
|
|
189
|
+
# what: Send data to the socket.
|
|
190
|
+
# action: Append the data to an existing SocketRawData. Check if this is an HTTP request.
|
|
191
|
+
# and record it if this is case, otherwise delete the temporay SocketRawData.
|
|
192
|
+
def set_hook_for_socket_sendall(records: HTTPRecords, method: Callable):
|
|
187
193
|
def hook(self, bytes, *args, **kwargs):
|
|
188
194
|
socketdata = records.get_socket_data(self, request=True)
|
|
189
195
|
if socketdata:
|
|
@@ -218,7 +224,11 @@ def set_hook_for_socket_sendall(records, method):
|
|
|
218
224
|
return hook
|
|
219
225
|
|
|
220
226
|
|
|
221
|
-
|
|
227
|
+
# hook: socket.socket.send, ssl.SSLSocket.send, asyncio.proactor_events._ProactorBaseWritePipeTransport.write
|
|
228
|
+
# what: Send data to the socket.
|
|
229
|
+
# action: Append the data to an existing SocketRawData. Check if this is an HTTP request.
|
|
230
|
+
# and record it if this is case, otherwise delete the temporay SocketRawData.
|
|
231
|
+
def set_hook_for_socket_send(records: HTTPRecords, method: Callable):
|
|
222
232
|
def hook(self, bytes, *args, **kwargs):
|
|
223
233
|
socketdata = records.get_socket_data(self, request=True)
|
|
224
234
|
if socketdata:
|
|
@@ -253,7 +263,10 @@ def set_hook_for_socket_send(records, method):
|
|
|
253
263
|
return hook
|
|
254
264
|
|
|
255
265
|
|
|
256
|
-
|
|
266
|
+
# hook: asyncio.BaseEventLoop.create_connection
|
|
267
|
+
# what: Open a streaming transport connection to a given address specified by host and port.
|
|
268
|
+
# action: Link the socket and the sslsocket
|
|
269
|
+
def set_hook_for_asyncio_create_connection(records: HTTPRecords, method: Callable):
|
|
257
270
|
async def hook(self, *args, **kwargs):
|
|
258
271
|
logger().info(
|
|
259
272
|
f"CREATE_CONNECTION - self={self} id={id(self)} args={args} kwargs={kwargs}"
|
|
@@ -276,7 +289,11 @@ def set_hook_for_asyncio_create_connection(records, method):
|
|
|
276
289
|
return hook
|
|
277
290
|
|
|
278
291
|
|
|
279
|
-
|
|
292
|
+
# hook: ssl.SSLObject.write
|
|
293
|
+
# what: Write buf to the SSL socket and return the number of bytes written.
|
|
294
|
+
# action: Append the data to an existing SocketRawData. Check if this is an HTTP request.
|
|
295
|
+
# and record it if this is case, otherwise delete the temporay SocketRawData.
|
|
296
|
+
def set_hook_for_sslobject_write(records: HTTPRecords, method: Callable):
|
|
280
297
|
def hook(self, buf, *args, **kwargs):
|
|
281
298
|
logger().info(f"WRITE - {type(self)}={id(self)} buf={(b'' + buf)[:20]}")
|
|
282
299
|
socketdata = records.get_socket_data(self, request=True)
|
|
@@ -310,7 +327,10 @@ def set_hook_for_sslobject_write(records, method):
|
|
|
310
327
|
return hook
|
|
311
328
|
|
|
312
329
|
|
|
313
|
-
|
|
330
|
+
# hook: ssl.SSLObject.read
|
|
331
|
+
# what: Read up to len bytes of data from the SSL socket and return the result as a bytes instance.
|
|
332
|
+
# action: Append the data to an existing SocketRawData.
|
|
333
|
+
def set_hook_for_sslobject_read(records: HTTPRecords, method: Callable):
|
|
314
334
|
def hook(self, *args, **kwargs):
|
|
315
335
|
logger().info(f"READ - {type(self)}={id(self)}")
|
|
316
336
|
socketdata = records.get_socket_data(self)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
from collections.abc import Callable
|
|
2
3
|
from contextlib import contextmanager
|
|
3
4
|
import traceback
|
|
4
5
|
from typing import Generator
|
|
@@ -7,11 +8,10 @@ from httpdbg.hooks.utils import getcallargs
|
|
|
7
8
|
from httpdbg.hooks.utils import decorate
|
|
8
9
|
from httpdbg.hooks.utils import undecorate
|
|
9
10
|
from httpdbg.initiator import httpdbg_initiator
|
|
10
|
-
from httpdbg.records import HTTPRecord
|
|
11
11
|
from httpdbg.records import HTTPRecords
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def set_hook_for_urllib3(records, method):
|
|
14
|
+
def set_hook_for_urllib3(records: HTTPRecords, method: Callable):
|
|
15
15
|
def hook(*args, **kwargs):
|
|
16
16
|
initiator = None
|
|
17
17
|
try:
|
|
@@ -25,13 +25,9 @@ def set_hook_for_urllib3(records, method):
|
|
|
25
25
|
|
|
26
26
|
if "url" in callargs:
|
|
27
27
|
if initiator:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
record.url = str(callargs["url"])
|
|
32
|
-
record.exception = ex
|
|
33
|
-
|
|
34
|
-
records.requests[record.id] = record
|
|
28
|
+
records.add_new_record_exception(
|
|
29
|
+
initiator, str(callargs["url"]), ex
|
|
30
|
+
)
|
|
35
31
|
raise
|
|
36
32
|
|
|
37
33
|
return hook
|
|
@@ -24,6 +24,8 @@ from httpdbg.log import logger
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class SocketRawData(object):
|
|
27
|
+
"""Store the request data without encryption, even when using an SSLSocket."""
|
|
28
|
+
|
|
27
29
|
def __init__(self, id: int, address: Tuple[str, int], ssl: bool) -> None:
|
|
28
30
|
self.id: int = id
|
|
29
31
|
self.address: Tuple[str, int] = address
|
|
@@ -343,6 +345,7 @@ class HTTPRecords:
|
|
|
343
345
|
def get_socket_data(
|
|
344
346
|
self, obj, extra_sock=None, force_new=False, request=None
|
|
345
347
|
) -> Union[SocketRawData, None]:
|
|
348
|
+
"""Record a new SocketRawData (or get an existing one) and return it."""
|
|
346
349
|
socketdata = None
|
|
347
350
|
|
|
348
351
|
if force_new:
|
|
@@ -410,3 +413,13 @@ class HTTPRecords:
|
|
|
410
413
|
logger().info(f"SocketRawData del id={id(obj)}")
|
|
411
414
|
self._sockets[id(obj)] = None
|
|
412
415
|
del self._sockets[id(obj)]
|
|
416
|
+
|
|
417
|
+
def add_new_record_exception(
|
|
418
|
+
self, initiator: Initiator, url: str, exception: Exception
|
|
419
|
+
) -> HTTPRecord:
|
|
420
|
+
new_record = HTTPRecord()
|
|
421
|
+
new_record.url = url
|
|
422
|
+
new_record.initiator = initiator
|
|
423
|
+
new_record.exception = exception
|
|
424
|
+
self.requests[new_record.id] = new_record
|
|
425
|
+
return new_record
|
|
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-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg
RENAMED
|
File without changes
|
{httpdbg-0.28.2 → httpdbg-0.28.3}/httpdbg/webapp/static/icons/download-install-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
|
{httpdbg-0.28.2 → httpdbg-0.28.3}/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
|