httpdbg 0.12.0__tar.gz → 0.13.0__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.12.0 → httpdbg-0.13.0}/PKG-INFO +3 -1
- {httpdbg-0.12.0 → httpdbg-0.13.0}/README.md +2 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/__init__.py +1 -1
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/urllib3.py +22 -10
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/initiator.py +1 -1
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/utils.py +2 -2
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/app.py +1 -1
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/api.js +9 -4
- httpdbg-0.13.0/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +1 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/index.htm +61 -21
- httpdbg-0.13.0/httpdbg/webapp/static/main.js +79 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/render.js +42 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/style.css +23 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg.egg-info/PKG-INFO +3 -1
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg.egg-info/SOURCES.txt +1 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_hook_httpx.py +0 -23
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_hook_requests.py +0 -25
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_hook_urllib3.py +58 -1
- httpdbg-0.12.0/httpdbg/webapp/static/main.js +0 -22
- {httpdbg-0.12.0 → httpdbg-0.13.0}/LICENSE +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/__main__.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/args.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/__init__.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/aiohttp.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/all.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/generic.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/httpx.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/requests.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/socket.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/hooks/utils.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/mode_console.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/mode_module.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/mode_script.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/preview.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/records.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/server.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/__init__.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/api.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/column.css +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/configuration.js +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/detail.css +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/favicon.ico +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/filter.js +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/mustache.min.js +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg/webapp/static/table.css +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg.egg-info/dependency_links.txt +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg.egg-info/entry_points.txt +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/httpdbg.egg-info/top_level.txt +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/pyproject.toml +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/setup.cfg +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_api.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_cli.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_context_manager.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_hook_aiohttp.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_initiator.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_mode_console.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_mode_module_pytest.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_mode_script.py +0 -0
- {httpdbg-0.12.0 → httpdbg-0.13.0}/tests/test_preview.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: httpdbg
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: A very simple tool to debug HTTP(S) client requests
|
|
5
5
|
Author-email: cle-b <cle@tictac.pm>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -22,6 +22,8 @@ License-File: LICENSE
|
|
|
22
22
|
|
|
23
23
|
A very simple tool to debug HTTP(S) client requests.
|
|
24
24
|
|
|
25
|
+

|
|
26
|
+
|
|
25
27
|
## installation
|
|
26
28
|
|
|
27
29
|
```
|
|
@@ -43,12 +43,18 @@ def hook_urllib3(records: HTTPRecords) -> Generator[None, None, None]:
|
|
|
43
43
|
try:
|
|
44
44
|
import urllib3
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
46
|
+
# v1
|
|
47
|
+
if hasattr(urllib3, "PoolManager"):
|
|
48
|
+
urllib3.PoolManager.request = decorate(
|
|
49
|
+
records, urllib3.PoolManager.request, set_hook_for_urllib3
|
|
50
|
+
)
|
|
51
|
+
if hasattr(urllib3, "HTTPConnectionPool"):
|
|
52
|
+
urllib3.HTTPConnectionPool.request = decorate(
|
|
53
|
+
records, urllib3.HTTPConnectionPool.request, set_hook_for_urllib3
|
|
54
|
+
)
|
|
55
|
+
# v2
|
|
56
|
+
if hasattr(urllib3, "request"):
|
|
57
|
+
urllib3.request = decorate(records, urllib3.request, set_hook_for_urllib3)
|
|
52
58
|
|
|
53
59
|
hooks = True
|
|
54
60
|
except ImportError:
|
|
@@ -57,7 +63,13 @@ def hook_urllib3(records: HTTPRecords) -> Generator[None, None, None]:
|
|
|
57
63
|
yield
|
|
58
64
|
|
|
59
65
|
if hooks:
|
|
60
|
-
|
|
61
|
-
urllib3
|
|
62
|
-
urllib3.
|
|
63
|
-
)
|
|
66
|
+
# v1
|
|
67
|
+
if hasattr(urllib3, "PoolManager"):
|
|
68
|
+
urllib3.PoolManager.request = undecorate(urllib3.PoolManager.request)
|
|
69
|
+
if hasattr(urllib3, "HTTPConnectionPool"):
|
|
70
|
+
urllib3.HTTPConnectionPool.request = undecorate(
|
|
71
|
+
urllib3.HTTPConnectionPool.request
|
|
72
|
+
)
|
|
73
|
+
# v2
|
|
74
|
+
if hasattr(urllib3, "request"):
|
|
75
|
+
urllib3.request = undecorate(urllib3.request)
|
|
@@ -50,7 +50,7 @@ class HTTPDBGCookie(object):
|
|
|
50
50
|
return {"name": self.name, "value": self.value, "attributes": self.attributes}
|
|
51
51
|
|
|
52
52
|
def __eq__(self, other) -> bool:
|
|
53
|
-
if type(other)
|
|
53
|
+
if type(other) is HTTPDBGCookie:
|
|
54
54
|
return (
|
|
55
55
|
(self.name == other.name)
|
|
56
56
|
and (self.value == other.value)
|
|
@@ -78,7 +78,7 @@ class HTTPDBGHeader(object):
|
|
|
78
78
|
return {"name": self.name, "value": self.value}
|
|
79
79
|
|
|
80
80
|
def __eq__(self, other) -> bool:
|
|
81
|
-
if type(other)
|
|
81
|
+
if type(other) is HTTPDBGHeader:
|
|
82
82
|
return (self.name == other.name) and (self.value == other.value)
|
|
83
83
|
else:
|
|
84
84
|
return False
|
|
@@ -85,7 +85,7 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
85
85
|
os.path.realpath(base_path) + "/static/icons/*.svg"
|
|
86
86
|
):
|
|
87
87
|
icon_path = icon.replace(os.path.realpath(base_path) + "/", "")
|
|
88
|
-
icons += f"<link rel='preload' href='{icon_path}-+-$**HTTPDBG_VERSION**$' as='image' type='image/svg+xml' />\n"
|
|
88
|
+
icons += f" <link rel='preload' href='{icon_path}-+-$**HTTPDBG_VERSION**$' as='image' type='image/svg+xml' />\n"
|
|
89
89
|
|
|
90
90
|
filecontent = filecontent.replace(
|
|
91
91
|
b"$**PRELOAD_ICONS**$", icons.encode("utf-8")
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
const global = {
|
|
4
4
|
"k7": null,
|
|
5
5
|
"requests": {},
|
|
6
|
-
"connected": false
|
|
6
|
+
"connected": false,
|
|
7
|
+
"tabindex": 100
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
function save_request(request_id, request) {
|
|
@@ -12,16 +13,20 @@ function save_request(request_id, request) {
|
|
|
12
13
|
if (request.pin == undefined) {
|
|
13
14
|
request.pin = "";
|
|
14
15
|
}
|
|
16
|
+
if (request.tabindex == undefined) {
|
|
17
|
+
global.tabindex += 1;
|
|
18
|
+
request.tabindex = global.tabindex;
|
|
19
|
+
}
|
|
15
20
|
global.requests[request_id] = request;
|
|
16
21
|
if (global.requests[request_id].in_progress) {
|
|
17
|
-
global.requests[request_id].status_code_view = '<img class="icon" src="static/icons/wait-sandclock-icon.svg-+-$**HTTPDBG_VERSION**$" />';
|
|
22
|
+
global.requests[request_id].status_code_view = '<img class="icon" src="static/icons/wait-sandclock-icon.svg-+-$**HTTPDBG_VERSION**$" alt="loading"/>';
|
|
18
23
|
} else {
|
|
19
24
|
switch (global.requests[request_id].status_code) {
|
|
20
25
|
case 0:
|
|
21
|
-
global.requests[request_id].status_code_view = '<img class="icon" src="static/icons/wait-sandclock-icon.svg-+-$**HTTPDBG_VERSION**$/" />';
|
|
26
|
+
global.requests[request_id].status_code_view = '<img class="icon" src="static/icons/wait-sandclock-icon.svg-+-$**HTTPDBG_VERSION**$/" alt="loading"/>';
|
|
22
27
|
break;
|
|
23
28
|
case -1:
|
|
24
|
-
global.requests[request_id].status_code_view = '<img class="icon" src="static/icons/math-multiplication-icon.svg-+-$**HTTPDBG_VERSION**$/" />';
|
|
29
|
+
global.requests[request_id].status_code_view = '<img class="icon" src="static/icons/math-multiplication-icon.svg-+-$**HTTPDBG_VERSION**$/" alt="load failed"/>';
|
|
25
30
|
break;
|
|
26
31
|
default:
|
|
27
32
|
global.requests[request_id].status_code_view = global.requests[request_id].status_code;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 122.88 122.88" style="enable-background:new 0 0 122.88 122.88" xml:space="preserve"><g><path d="M109.72,61.44v-0.01h0.02c0-13.31-5.42-25.38-14.17-34.13c-8.75-8.74-20.81-14.16-34.1-14.16v0.02h-0.03h-0.01v-0.02 c-13.3,0-25.38,5.42-34.13,14.17c-8.74,8.75-14.16,20.81-14.16,34.11h0.02v0.03v0.01h-0.02c0,8.88,2.41,17.22,6.59,24.36 c8.38,14.31,23.92,23.92,41.68,23.93v-0.02h0.03h0.01v0.02c13.31,0,25.38-5.42,34.13-14.17c1.44-1.44,2.78-2.95,4-4.52 C105.93,82.88,109.72,72.6,109.72,61.44L109.72,61.44z M68.38,73.86H51.86v-1.65c0-2.8,0.3-5.09,0.94-6.85 c0.64-1.77,1.59-3.35,2.85-4.81c1.27-1.45,4.11-4,8.51-7.66c2.34-1.92,3.52-3.67,3.52-5.25c0-1.61-0.48-2.84-1.41-3.73 c-0.94-0.88-2.37-1.33-4.3-1.33c-2.07,0-3.76,0.69-5.1,2.04c-1.35,1.36-2.21,3.75-2.58,7.14l-16.89-2.1 c0.58-6.2,2.84-11.2,6.76-14.98C48.1,30.89,54.12,29,62.24,29c6.32,0,11.43,1.33,15.32,3.95c5.29,3.57,7.92,8.33,7.92,14.26 c0,2.48-0.69,4.86-2.04,7.15c-1.36,2.3-4.15,5.09-8.36,8.39c-2.92,2.34-4.77,4.19-5.54,5.6C68.77,69.76,68.38,71.6,68.38,73.86 L68.38,73.86z M51.27,78.26h17.72v15.61H51.27V78.26L51.27,78.26z M122.85,61.43h0.03v0.01c0,14.19-4.82,27.27-12.92,37.68 c-1.59,2.04-3.29,3.97-5.08,5.76c-11.1,11.1-26.45,17.97-43.43,17.98v0.03h-0.01h-0.03v-0.03c-22.59-0.01-42.34-12.22-52.99-30.4 c-5.33-9.1-8.39-19.7-8.39-31H0v-0.01v-0.03h0.03C0.03,44.44,6.9,29.09,18,18C29.09,6.9,44.45,0.03,61.43,0.03V0h0.01h0.03v0.03 c16.97,0.01,32.32,6.87,43.41,17.97C115.98,29.09,122.85,44.45,122.85,61.43L122.85,61.43z"/></g></svg>
|
|
@@ -29,16 +29,22 @@
|
|
|
29
29
|
<header>
|
|
30
30
|
<nav id="navbar">
|
|
31
31
|
<div class="menu-left">
|
|
32
|
-
<button id="trash" onclick="clean(true)">
|
|
33
|
-
<img class="icon" src="static/icons/recycle-bin-line-icon.svg-+-$**HTTPDBG_VERSION**$"
|
|
32
|
+
<button id="trash" type="button" onclick="clean(true)">
|
|
33
|
+
<img class="icon" src="static/icons/recycle-bin-line-icon.svg-+-$**HTTPDBG_VERSION**$"
|
|
34
|
+
alt="clean the requests list" />
|
|
34
35
|
</button>
|
|
35
36
|
<input type="checkbox" id="onlynew" name="cleannew" checked>
|
|
36
|
-
<label for="
|
|
37
|
+
<label for="onlynew">force clean for new session</label>
|
|
37
38
|
</div>
|
|
38
39
|
<div class="menu-right">
|
|
39
40
|
httpdbg
|
|
40
|
-
<button
|
|
41
|
-
<img class="icon" src="static/icons/engine-gears-icon.svg-+-$**HTTPDBG_VERSION**$"
|
|
41
|
+
<button onclick="config()" title="open configuration">
|
|
42
|
+
<img class="icon" src="static/icons/engine-gears-icon.svg-+-$**HTTPDBG_VERSION**$"
|
|
43
|
+
alt="open configuration" />
|
|
44
|
+
</button>
|
|
45
|
+
<button onclick="help()" title="open help">
|
|
46
|
+
<img class="icon" src="static/icons/question-mark-round-line-icon.svg-+-$**HTTPDBG_VERSION**$"
|
|
47
|
+
alt="open help" />
|
|
42
48
|
</button>
|
|
43
49
|
</div>
|
|
44
50
|
</nav>
|
|
@@ -65,6 +71,37 @@
|
|
|
65
71
|
<br>
|
|
66
72
|
</div>
|
|
67
73
|
|
|
74
|
+
<div id="help">
|
|
75
|
+
<h4>Help</h4>
|
|
76
|
+
|
|
77
|
+
<h5>Shorcuts</h5>
|
|
78
|
+
<ul>
|
|
79
|
+
<li>Press <kbd>O</kbd> <kbd>C</kbd> to open the configuration panel.</li>
|
|
80
|
+
<li>Press <kbd>O</kbd> <kbd>H</kbd> to open this help.</li>
|
|
81
|
+
</ul>
|
|
82
|
+
|
|
83
|
+
<h5>List of requests</h5>
|
|
84
|
+
Use <kbd>Tab</kbd> to browser the list of requests.
|
|
85
|
+
<ul>
|
|
86
|
+
<li>Press <kbd>Enter</kbd> or <kbd>S</kbd> to select a request.</li>
|
|
87
|
+
<li>Press <kbd>C</kbd> to compare this request to the select one.</li>
|
|
88
|
+
</ul>
|
|
89
|
+
|
|
90
|
+
<h5>Request panel</h5>
|
|
91
|
+
<ul>
|
|
92
|
+
<li>Press <kbd>R</kbd> <kbd>H</kbd> to open the headers tab.</li>
|
|
93
|
+
<li>Press <kbd>R</kbd> <kbd>C</kbd> to open the cookies tab.</li>
|
|
94
|
+
<li>Press <kbd>R</kbd> <kbd>P</kbd> to open the request tab.</li>
|
|
95
|
+
<li>Press <kbd>R</kbd> <kbd>T</kbd> to open the response tab.</li>
|
|
96
|
+
<li>Press <kbd>R</kbd> <kbd>E</kbd> to open the exception tab.</li>
|
|
97
|
+
<li>Press <kbd>R</kbd> <kbd>S</kbd> to open the stack tab.</li>
|
|
98
|
+
</ul>
|
|
99
|
+
|
|
100
|
+
<h4>About</h4>
|
|
101
|
+
httpdbg v$**HTTPDBG_VERSION**$ - <a href="https://pypi.org/project/httpdbg/">PyPI</a> <a
|
|
102
|
+
href="https://github.com/cle-b/httpdbg">Source code</a>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
68
105
|
<div class="grid-container">
|
|
69
106
|
|
|
70
107
|
<div class="grid-column grid-column-left">
|
|
@@ -78,9 +115,13 @@
|
|
|
78
115
|
<th class="method" title="method"></th>
|
|
79
116
|
<th class="url">
|
|
80
117
|
url
|
|
81
|
-
<img class="icon" src="static/icons/filter-outline-icon.svg-+-$**HTTPDBG_VERSION**$"
|
|
82
|
-
|
|
83
|
-
|
|
118
|
+
<img class="icon" src="static/icons/filter-outline-icon.svg-+-$**HTTPDBG_VERSION**$"
|
|
119
|
+
alt="filter for url" />
|
|
120
|
+
<label for="filter-url" class="visuallyhidden">
|
|
121
|
+
filter for url
|
|
122
|
+
</label>
|
|
123
|
+
<input type="text" value="" id="filter-url" title="filter for url"
|
|
124
|
+
onkeyup="update_filter_url()" oncut="update_filter_url()" onpaste="update_filter_url()"
|
|
84
125
|
onchange="update_filter_url()">
|
|
85
126
|
</th>
|
|
86
127
|
</tr>
|
|
@@ -100,11 +141,14 @@
|
|
|
100
141
|
<tr id="request-{{id}}"
|
|
101
142
|
data-filter-url="{{url}}"
|
|
102
143
|
onclick="select_request(arguments[0], '{{id}}')"
|
|
144
|
+
onkeypress="shortcut_request(event, '{{id}}')"
|
|
103
145
|
class="request"
|
|
104
|
-
data-qa-request="{{id}}"
|
|
146
|
+
data-qa-request="{{id}}"
|
|
147
|
+
tabindex="{{tabindex}}">
|
|
105
148
|
<td class="pin" onclick="event.stopPropagation();">
|
|
149
|
+
<label for="pin{{id}}" class="visuallyhidden"pin request</label>
|
|
106
150
|
<input class="pin-checkbox" type="checkbox" id="pin{{id}}" onclick="pin_request('{{id}}',this.checked)" {{pin}}>
|
|
107
|
-
<label class="pin-icon" for="pin{{id}}"><img class="icon" src="static/icons/push-pin-green-icon.svg-+-$**HTTPDBG_VERSION**$"/></label>
|
|
151
|
+
<label class="pin-icon" for="pin{{id}}"><img class="icon" src="static/icons/push-pin-green-icon.svg-+-$**HTTPDBG_VERSION**$" alt="click to pin"/></label>
|
|
108
152
|
</td>
|
|
109
153
|
<td class="status"><span title="{{reason}}" data-qa-request-status>{{{status_code_view}}}</span></td>
|
|
110
154
|
<td class="method"><span title="{{verb}}" data-qa-request-method>{{verb}}</span></td>
|
|
@@ -125,17 +169,16 @@
|
|
|
125
169
|
<th>
|
|
126
170
|
<div class="tab">
|
|
127
171
|
<button id="btn-tab-headers" class="tablinks"
|
|
128
|
-
onclick="
|
|
172
|
+
onclick="opentab_headers()">headers</button>
|
|
129
173
|
<button id="btn-tab-cookies" class="tablinks"
|
|
130
|
-
onclick="
|
|
174
|
+
onclick="opentab_cookies()">cookies</button>
|
|
131
175
|
<button id="btn-tab-request" class="tablinks"
|
|
132
|
-
onclick="
|
|
176
|
+
onclick="opentab_request()">request</button>
|
|
133
177
|
<button id="btn-tab-response" class="tablinks"
|
|
134
|
-
onclick="
|
|
178
|
+
onclick="opentab_response()">response</button>
|
|
135
179
|
<button id="btn-tab-exception" class="tablinks"
|
|
136
|
-
onclick="
|
|
137
|
-
<button id="btn-tab-stack" class="tablinks"
|
|
138
|
-
onclick="opentab(event.currentTarget, 'tabStack')">stack</button>
|
|
180
|
+
onclick="opentab_exception()">exception</button>
|
|
181
|
+
<button id="btn-tab-stack" class="tablinks" onclick="opentab_stack()">stack</button>
|
|
139
182
|
</div>
|
|
140
183
|
</th>
|
|
141
184
|
</tr>
|
|
@@ -225,9 +268,6 @@
|
|
|
225
268
|
<script id="template_body" type="x-tmpl-mustache">
|
|
226
269
|
{{^body}}
|
|
227
270
|
-- no content --
|
|
228
|
-
{{#stream}}
|
|
229
|
-
(because stream mode on)
|
|
230
|
-
{{/stream}}
|
|
231
271
|
{{/body}}
|
|
232
272
|
|
|
233
273
|
{{#body}}
|
|
@@ -307,7 +347,7 @@
|
|
|
307
347
|
update_filter_url();
|
|
308
348
|
pol_new_data();
|
|
309
349
|
enable_refresh();
|
|
310
|
-
|
|
350
|
+
opentab_headers();
|
|
311
351
|
</script>
|
|
312
352
|
</body>
|
|
313
353
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
let httpdbgApp = {
|
|
4
|
+
"config": {
|
|
5
|
+
"hide_initiator": {
|
|
6
|
+
"checkbox": "cinitiator",
|
|
7
|
+
"param": "hi",
|
|
8
|
+
"css": ".initiator {display: none;}",
|
|
9
|
+
"value": false
|
|
10
|
+
},
|
|
11
|
+
"hide_netloc": {
|
|
12
|
+
"checkbox": "curl",
|
|
13
|
+
"param": "hn",
|
|
14
|
+
"css": ".netloc {display: none;}",
|
|
15
|
+
"value": false
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function wait_for(ms) {
|
|
21
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// use keys sequences as shortcut
|
|
25
|
+
var keys_history= "";
|
|
26
|
+
window.addEventListener('keydown', (event) => {
|
|
27
|
+
|
|
28
|
+
if (document.activeElement) {
|
|
29
|
+
if (document.activeElement.tagName.toLowerCase() === "input") {
|
|
30
|
+
if (document.activeElement.getAttribute("type").toLowerCase() === "text") {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
keys_history += event.key.toLowerCase();
|
|
37
|
+
|
|
38
|
+
if (keys_history.endsWith("rh")) {
|
|
39
|
+
opentab_headers();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (keys_history.endsWith("rc")) {
|
|
43
|
+
opentab_cookies();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (keys_history.endsWith("rp")) {
|
|
47
|
+
opentab_request();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (keys_history.endsWith("rt")) {
|
|
51
|
+
opentab_response();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (keys_history.endsWith("re")) {
|
|
55
|
+
opentab_exception();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (keys_history.endsWith("rs")) {
|
|
59
|
+
opentab_stack();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (keys_history.endsWith("oc")) {
|
|
63
|
+
config();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (keys_history.endsWith("oh")) {
|
|
67
|
+
help();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
keys_history = keys_history.substr(-8, 8)
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
function help() {
|
|
74
|
+
if (document.getElementById("help").style.display == "block") {
|
|
75
|
+
document.getElementById("help").style.display = "none";
|
|
76
|
+
} else {
|
|
77
|
+
document.getElementById("help").style.display = "block";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -64,6 +64,23 @@ function unselect_request(request_id) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
function shortcut_request(event, request_id) {
|
|
68
|
+
var key_pressed = event.key.toLowerCase()
|
|
69
|
+
// select the request
|
|
70
|
+
if ((key_pressed === "s") || (key_pressed === "enter")) {
|
|
71
|
+
show_request(request_id);
|
|
72
|
+
}
|
|
73
|
+
// compare the request to the one already selected
|
|
74
|
+
if (key_pressed === "c") {
|
|
75
|
+
if ((document.getElementsByClassName("active-row").length > 0)) {
|
|
76
|
+
compare_to_request(request_id);
|
|
77
|
+
} else {
|
|
78
|
+
// if no request is already selected, just select the new one
|
|
79
|
+
show_request(request_id);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
67
84
|
function remove_class(classname) {
|
|
68
85
|
var elts = document.getElementsByClassName(classname);
|
|
69
86
|
[].forEach.call(elts, function (el) {
|
|
@@ -154,6 +171,31 @@ function opentab(btn, tabname) {
|
|
|
154
171
|
btn.className += " active";
|
|
155
172
|
}
|
|
156
173
|
|
|
174
|
+
function opentab_headers() {
|
|
175
|
+
opentab(document.getElementById("btn-tab-headers"), "tabHeaders");
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function opentab_cookies() {
|
|
179
|
+
opentab(document.getElementById("btn-tab-cookies"), "tabCookies");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function opentab_request() {
|
|
183
|
+
opentab(document.getElementById("btn-tab-request"), "tabRequest");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function opentab_response() {
|
|
187
|
+
opentab(document.getElementById("btn-tab-response"), "tabResponse");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function opentab_exception() {
|
|
191
|
+
opentab(document.getElementById("btn-tab-exception"), "tabException");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function opentab_stack() {
|
|
195
|
+
opentab(document.getElementById("btn-tab-stack"), "tabStack");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
157
199
|
async function disable_link_if_server_disconnected() {
|
|
158
200
|
var sheet = document.getElementById("serverstatuscss").sheet;
|
|
159
201
|
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
--link-server-disconnected: #444444;
|
|
20
20
|
--preview-code-border: #777777;
|
|
21
21
|
--column-border: #dadada;
|
|
22
|
+
--kdb-border: #000000;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
body {
|
|
@@ -58,6 +59,10 @@ a:link {
|
|
|
58
59
|
display: none;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
#help {
|
|
63
|
+
display: none;
|
|
64
|
+
}
|
|
65
|
+
|
|
61
66
|
.previewcode {
|
|
62
67
|
display: block;
|
|
63
68
|
overflow-x: scroll;
|
|
@@ -78,4 +83,22 @@ a:link {
|
|
|
78
83
|
width: 16px;
|
|
79
84
|
height: 16px;
|
|
80
85
|
vertical-align: middle;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.visuallyhidden {
|
|
89
|
+
border: 0;
|
|
90
|
+
clip: rect(0 0 0 0);
|
|
91
|
+
height: 1px;
|
|
92
|
+
margin: -1px;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
padding: 0;
|
|
95
|
+
position: absolute;
|
|
96
|
+
width: 1px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
kbd {
|
|
100
|
+
padding: 1px 2px 0;
|
|
101
|
+
border-radius: 3px;
|
|
102
|
+
border: 1px solid black;
|
|
103
|
+
font-family: monospace;
|
|
81
104
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: httpdbg
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: A very simple tool to debug HTTP(S) client requests
|
|
5
5
|
Author-email: cle-b <cle@tictac.pm>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -22,6 +22,8 @@ License-File: LICENSE
|
|
|
22
22
|
|
|
23
23
|
A very simple tool to debug HTTP(S) client requests.
|
|
24
24
|
|
|
25
|
+

|
|
26
|
+
|
|
25
27
|
## installation
|
|
26
28
|
|
|
27
29
|
```
|
|
@@ -49,6 +49,7 @@ httpdbg/webapp/static/icons/filter-outline-icon.svg
|
|
|
49
49
|
httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg
|
|
50
50
|
httpdbg/webapp/static/icons/math-multiplication-icon.svg
|
|
51
51
|
httpdbg/webapp/static/icons/push-pin-green-icon.svg
|
|
52
|
+
httpdbg/webapp/static/icons/question-mark-round-line-icon.svg
|
|
52
53
|
httpdbg/webapp/static/icons/recycle-bin-line-icon.svg
|
|
53
54
|
httpdbg/webapp/static/icons/wait-sandclock-icon.svg
|
|
54
55
|
tests/test_api.py
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
import platform
|
|
3
2
|
import sys
|
|
4
3
|
import urllib.parse
|
|
5
4
|
|
|
@@ -125,28 +124,6 @@ def test_httpx_cookies_secure(httpbin_secure):
|
|
|
125
124
|
)
|
|
126
125
|
|
|
127
126
|
|
|
128
|
-
@pytest.mark.httpx
|
|
129
|
-
@pytest.mark.xfail(
|
|
130
|
-
platform.system().lower() == "windows",
|
|
131
|
-
reason="An established connection was aborted by the software in your host machine",
|
|
132
|
-
)
|
|
133
|
-
def test_httpx_stream(httpbin):
|
|
134
|
-
request_content = b"key=value"
|
|
135
|
-
response_content = bytes()
|
|
136
|
-
with httpdbg() as records:
|
|
137
|
-
with httpx.stream("POST", f"{httpbin.url}", data={"key": "value"}) as r:
|
|
138
|
-
for data in r.iter_bytes():
|
|
139
|
-
response_content += data
|
|
140
|
-
|
|
141
|
-
assert response_content != bytes()
|
|
142
|
-
|
|
143
|
-
assert len(records) == 1
|
|
144
|
-
|
|
145
|
-
http_record = records[0]
|
|
146
|
-
assert http_record.request.content == request_content
|
|
147
|
-
assert http_record.response.content == response_content
|
|
148
|
-
|
|
149
|
-
|
|
150
127
|
@pytest.mark.httpx
|
|
151
128
|
def test_httpx_redirect(httpbin_both):
|
|
152
129
|
redirect_url = f"{httpbin_both.url}/redirect-to?{urllib.parse.urlencode({'url': httpbin_both.url})}/get"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
import platform
|
|
3
2
|
import pytest
|
|
4
3
|
import requests
|
|
5
4
|
|
|
@@ -125,30 +124,6 @@ def test_requests_cookies_secure(httpbin_secure):
|
|
|
125
124
|
)
|
|
126
125
|
|
|
127
126
|
|
|
128
|
-
@pytest.mark.requests
|
|
129
|
-
@pytest.mark.xfail(
|
|
130
|
-
platform.system().lower() == "windows",
|
|
131
|
-
reason="An established connection was aborted by the software in your host machine",
|
|
132
|
-
)
|
|
133
|
-
def test_requests_stream(httpbin_both):
|
|
134
|
-
request_content = b"key=value"
|
|
135
|
-
response_content = bytes()
|
|
136
|
-
with httpdbg() as records:
|
|
137
|
-
with requests.post(
|
|
138
|
-
f"{httpbin_both.url}", data={"key": "value"}, verify=False
|
|
139
|
-
) as r:
|
|
140
|
-
for data in r.iter_content():
|
|
141
|
-
response_content += data
|
|
142
|
-
|
|
143
|
-
assert response_content != bytes()
|
|
144
|
-
|
|
145
|
-
assert len(records) == 1
|
|
146
|
-
|
|
147
|
-
http_record = records[0]
|
|
148
|
-
assert http_record.request.content == request_content
|
|
149
|
-
assert http_record.response.content == response_content
|
|
150
|
-
|
|
151
|
-
|
|
152
127
|
@pytest.mark.requests
|
|
153
128
|
def test_requests_redirect(httpbin_both):
|
|
154
129
|
with httpdbg() as records:
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
from packaging import version
|
|
3
|
+
import pkg_resources
|
|
4
|
+
|
|
2
5
|
import pytest
|
|
3
6
|
import urllib3
|
|
4
7
|
|
|
@@ -28,7 +31,7 @@ def test_urllib3_initiator(httpbin, monkeypatch):
|
|
|
28
31
|
with monkeypatch.context() as m:
|
|
29
32
|
m.delenv("PYTEST_CURRENT_TEST")
|
|
30
33
|
with httpdbg() as records:
|
|
31
|
-
with urllib3.PoolManager(
|
|
34
|
+
with urllib3.PoolManager() as http:
|
|
32
35
|
http.request("GET", f"{httpbin.url}/get")
|
|
33
36
|
with urllib3.HTTPConnectionPool(f"{httpbin.url[7:]}") as http:
|
|
34
37
|
http.request("GET", "/get")
|
|
@@ -48,6 +51,35 @@ def test_urllib3_initiator(httpbin, monkeypatch):
|
|
|
48
51
|
assert 'http.request("GET", "/get") <===' in "".join(records[1].initiator.stack)
|
|
49
52
|
|
|
50
53
|
|
|
54
|
+
@pytest.mark.initiator
|
|
55
|
+
@pytest.mark.urllib3
|
|
56
|
+
def test_urllib3_initiator_secure(httpbin_secure, monkeypatch):
|
|
57
|
+
with monkeypatch.context() as m:
|
|
58
|
+
m.delenv("PYTEST_CURRENT_TEST")
|
|
59
|
+
with httpdbg() as records:
|
|
60
|
+
with urllib3.PoolManager(cert_reqs="CERT_NONE") as http:
|
|
61
|
+
http.request("GET", f"{httpbin_secure.url}/get")
|
|
62
|
+
with urllib3.HTTPSConnectionPool(
|
|
63
|
+
f"{httpbin_secure.url[8:]}", cert_reqs="CERT_NONE"
|
|
64
|
+
) as http:
|
|
65
|
+
http.request("GET", "/get")
|
|
66
|
+
|
|
67
|
+
assert len(records) == 2
|
|
68
|
+
|
|
69
|
+
assert (
|
|
70
|
+
records[0].initiator.short_label
|
|
71
|
+
== 'http.request("GET", f"{httpbin_secure.url}/get")'
|
|
72
|
+
)
|
|
73
|
+
assert records[0].initiator.long_label is None
|
|
74
|
+
assert 'http.request("GET", f"{httpbin_secure.url}/get") <===' in "".join(
|
|
75
|
+
records[0].initiator.stack
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
assert records[1].initiator.short_label == 'http.request("GET", "/get")'
|
|
79
|
+
assert records[1].initiator.long_label is None
|
|
80
|
+
assert 'http.request("GET", "/get") <===' in "".join(records[1].initiator.stack)
|
|
81
|
+
|
|
82
|
+
|
|
51
83
|
@pytest.mark.urllib3
|
|
52
84
|
def test_urllib3_request(httpbin_both):
|
|
53
85
|
with httpdbg() as records:
|
|
@@ -201,3 +233,28 @@ def test_urllib3_get_empty_request_content(httpbin_both):
|
|
|
201
233
|
|
|
202
234
|
assert http_record.url == f"{httpbin_both.url}/get"
|
|
203
235
|
assert http_record.request.content == b""
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@pytest.mark.initiator
|
|
239
|
+
@pytest.mark.urllib3
|
|
240
|
+
@pytest.mark.skipif(
|
|
241
|
+
version.parse(pkg_resources.get_distribution("urllib3").version)
|
|
242
|
+
< version.parse("2.0.0"),
|
|
243
|
+
reason="only urllib3 v2",
|
|
244
|
+
)
|
|
245
|
+
def test_urllib3_v2_request(httpbin, monkeypatch):
|
|
246
|
+
with monkeypatch.context() as m:
|
|
247
|
+
m.delenv("PYTEST_CURRENT_TEST")
|
|
248
|
+
with httpdbg() as records:
|
|
249
|
+
urllib3.request("GET", f"{httpbin.url}/get")
|
|
250
|
+
|
|
251
|
+
assert len(records) == 1
|
|
252
|
+
|
|
253
|
+
assert (
|
|
254
|
+
records[0].initiator.short_label
|
|
255
|
+
== 'urllib3.request("GET", f"{httpbin.url}/get")'
|
|
256
|
+
)
|
|
257
|
+
assert records[0].initiator.long_label is None
|
|
258
|
+
assert 'urllib3.request("GET", f"{httpbin.url}/get") <===' in "".join(
|
|
259
|
+
records[0].initiator.stack
|
|
260
|
+
)
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
let httpdbgApp = {
|
|
4
|
-
"config": {
|
|
5
|
-
"hide_initiator": {
|
|
6
|
-
"checkbox": "cinitiator",
|
|
7
|
-
"param": "hi",
|
|
8
|
-
"css": ".initiator {display: none;}",
|
|
9
|
-
"value": false
|
|
10
|
-
},
|
|
11
|
-
"hide_netloc": {
|
|
12
|
-
"checkbox": "curl",
|
|
13
|
-
"param": "hn",
|
|
14
|
-
"css": ".netloc {display: none;}",
|
|
15
|
-
"value": false
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function wait_for(ms) {
|
|
21
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
22
|
-
}
|
|
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.12.0 → httpdbg-0.13.0}/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
|
|
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
|