httpdbg 0.22.0__tar.gz → 0.24.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.22.0 → httpdbg-0.24.0}/PKG-INFO +4 -2
- {httpdbg-0.22.0 → httpdbg-0.24.0}/README.md +3 -1
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/__init__.py +1 -1
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/__main__.py +2 -2
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/args.py +6 -0
- httpdbg-0.24.0/httpdbg/env.py +4 -0
- httpdbg-0.24.0/httpdbg/exception.py +7 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/all.py +5 -3
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/external.py +4 -5
- httpdbg-0.24.0/httpdbg/hooks/pytest.py +51 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/initiator.py +17 -1
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/records.py +4 -1
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/server.py +11 -5
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/utils.py +3 -1
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/api.py +2 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/configuration.js +3 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/index.htm +11 -1
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/main.js +6 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/style.css +2 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/table.css +21 -4
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg.egg-info/PKG-INFO +4 -2
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg.egg-info/SOURCES.txt +5 -1
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_api.py +31 -31
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_mode_console.py +3 -3
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_mode_module_pytest.py +10 -10
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_mode_script.py +9 -9
- httpdbg-0.24.0/tests/test_server.py +40 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/LICENSE +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/__init__.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/aiohttp.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/generic.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/httpx.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/requests.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/socket.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/urllib3.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/hooks/utils.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/mode_console.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/mode_module.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/mode_script.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/preview.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/__init__.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/app.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/api.js +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/column.css +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/detail.css +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/favicon.ico +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/filter.js +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/mustache.min.js +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/render.js +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg.egg-info/dependency_links.txt +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg.egg-info/entry_points.txt +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg.egg-info/requires.txt +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/httpdbg.egg-info/top_level.txt +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/pyproject.toml +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/setup.cfg +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_cli.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_context_manager.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_hook_aiohttp.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_hook_httpx.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_hook_requests.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_hook_urllib3.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.0}/tests/test_initiator.py +0 -0
- {httpdbg-0.22.0 → httpdbg-0.24.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.24.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
|
|
@@ -125,13 +125,14 @@ No configuration is necessary to start but some few settings are available for p
|
|
|
125
125
|
### command line
|
|
126
126
|
|
|
127
127
|
```console
|
|
128
|
-
usage: pyhttpdbg [-h] [--port PORT] [--version] [--initiator INITIATOR] [--keep-up | --force-quit]
|
|
128
|
+
usage: pyhttpdbg [-h] [--host HOST] [--port PORT] [--version] [--initiator INITIATOR] [--keep-up | --force-quit]
|
|
129
129
|
[--console | --module MODULE | --script SCRIPT]
|
|
130
130
|
|
|
131
131
|
httdbg - a very simple tool to debug HTTP(S) client requests
|
|
132
132
|
|
|
133
133
|
options:
|
|
134
134
|
-h, --help show this help message and exit
|
|
135
|
+
--host HOST the web interface host IP address
|
|
135
136
|
--port PORT, -p PORT the web interface port
|
|
136
137
|
--version, -v print the httpdbg version
|
|
137
138
|
--initiator INITIATOR, -i INITIATOR
|
|
@@ -151,6 +152,7 @@ Clic on the **⚙** button on the top right of the page.
|
|
|
151
152
|
Some options are available:
|
|
152
153
|
* Hide the netloc in the url
|
|
153
154
|
* Hide the initiator rows
|
|
155
|
+
* Hide the tags
|
|
154
156
|
|
|
155
157
|
To keep your configuration, bookmark the page with the full search query.
|
|
156
158
|
|
|
@@ -97,13 +97,14 @@ No configuration is necessary to start but some few settings are available for p
|
|
|
97
97
|
### command line
|
|
98
98
|
|
|
99
99
|
```console
|
|
100
|
-
usage: pyhttpdbg [-h] [--port PORT] [--version] [--initiator INITIATOR] [--keep-up | --force-quit]
|
|
100
|
+
usage: pyhttpdbg [-h] [--host HOST] [--port PORT] [--version] [--initiator INITIATOR] [--keep-up | --force-quit]
|
|
101
101
|
[--console | --module MODULE | --script SCRIPT]
|
|
102
102
|
|
|
103
103
|
httdbg - a very simple tool to debug HTTP(S) client requests
|
|
104
104
|
|
|
105
105
|
options:
|
|
106
106
|
-h, --help show this help message and exit
|
|
107
|
+
--host HOST the web interface host IP address
|
|
107
108
|
--port PORT, -p PORT the web interface port
|
|
108
109
|
--version, -v print the httpdbg version
|
|
109
110
|
--initiator INITIATOR, -i INITIATOR
|
|
@@ -123,6 +124,7 @@ Clic on the **⚙** button on the top right of the page.
|
|
|
123
124
|
Some options are available:
|
|
124
125
|
* Hide the netloc in the url
|
|
125
126
|
* Hide the initiator rows
|
|
127
|
+
* Hide the tags
|
|
126
128
|
|
|
127
129
|
To keep your configuration, bookmark the page with the full search query.
|
|
128
130
|
|
|
@@ -18,13 +18,13 @@ def print_msg(msg):
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def pyhttpdbg(params, subparams, test_mode=False):
|
|
21
|
-
url = f"http://
|
|
21
|
+
url = f"http://{params.host}:{params.port}/{'?hi=on' if params.console else ''}"
|
|
22
22
|
|
|
23
23
|
print_msg(f" httpdbg - HTTP(S) requests available at {url}")
|
|
24
24
|
|
|
25
25
|
sys.path.insert(0, "") # to mimic the default python command behavior
|
|
26
26
|
|
|
27
|
-
with httpdbg_srv(params.port) as records:
|
|
27
|
+
with httpdbg_srv(params.host, params.port) as records:
|
|
28
28
|
with httprecord(records, params.initiator):
|
|
29
29
|
if params.module:
|
|
30
30
|
run_module(subparams)
|
|
@@ -15,6 +15,12 @@ def read_args(args: List[str]) -> Tuple[argparse.Namespace, List[str]]:
|
|
|
15
15
|
parser = argparse.ArgumentParser(
|
|
16
16
|
description="httdbg - a very simple tool to debug HTTP(S) client requests"
|
|
17
17
|
)
|
|
18
|
+
parser.add_argument(
|
|
19
|
+
"--host",
|
|
20
|
+
type=str,
|
|
21
|
+
default="localhost",
|
|
22
|
+
help="the web interface host IP address",
|
|
23
|
+
)
|
|
18
24
|
parser.add_argument(
|
|
19
25
|
"--port", "-p", type=int, default=4909, help="the web interface port"
|
|
20
26
|
)
|
|
@@ -5,11 +5,12 @@ from typing import List
|
|
|
5
5
|
from typing import Union
|
|
6
6
|
|
|
7
7
|
from httpdbg.hooks.aiohttp import hook_aiohttp
|
|
8
|
+
from httpdbg.hooks.external import watcher_external
|
|
8
9
|
from httpdbg.hooks.generic import hook_generic
|
|
9
10
|
from httpdbg.hooks.httpx import hook_httpx
|
|
11
|
+
from httpdbg.hooks.pytest import hook_pytest
|
|
10
12
|
from httpdbg.hooks.requests import hook_requests
|
|
11
13
|
from httpdbg.hooks.socket import hook_socket
|
|
12
|
-
from httpdbg.hooks.external import watcher_external
|
|
13
14
|
from httpdbg.hooks.urllib3 import hook_urllib3
|
|
14
15
|
from httpdbg.records import HTTPRecords
|
|
15
16
|
|
|
@@ -27,5 +28,6 @@ def httprecord(
|
|
|
27
28
|
with hook_requests(records):
|
|
28
29
|
with hook_urllib3(records):
|
|
29
30
|
with hook_aiohttp(records):
|
|
30
|
-
with
|
|
31
|
-
|
|
31
|
+
with hook_pytest(records):
|
|
32
|
+
with hook_generic(records, initiators):
|
|
33
|
+
yield records
|
|
@@ -8,17 +8,18 @@ import tempfile
|
|
|
8
8
|
import time
|
|
9
9
|
import threading
|
|
10
10
|
|
|
11
|
+
from httpdbg.env import HTTPDBG_SUBPROCESS_DIR
|
|
11
12
|
from httpdbg.records import HTTPRecords
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
@contextmanager
|
|
15
16
|
def watcher_external(records: HTTPRecords) -> Generator[HTTPRecords, None, None]:
|
|
16
17
|
try:
|
|
17
|
-
if
|
|
18
|
+
if HTTPDBG_SUBPROCESS_DIR not in os.environ:
|
|
18
19
|
with tempfile.TemporaryDirectory(
|
|
19
20
|
prefix="httpdbg"
|
|
20
21
|
) as httpdbg_subprocess_dir:
|
|
21
|
-
os.environ[
|
|
22
|
+
os.environ[HTTPDBG_SUBPROCESS_DIR] = httpdbg_subprocess_dir
|
|
22
23
|
|
|
23
24
|
watcher = WatcherSubprocessDirThread(records)
|
|
24
25
|
watcher.start()
|
|
@@ -43,9 +44,7 @@ class WatcherSubprocessDirThread(threading.Thread):
|
|
|
43
44
|
threading.Thread.__init__(self)
|
|
44
45
|
|
|
45
46
|
def load_dump(self):
|
|
46
|
-
for dump in glob.glob(
|
|
47
|
-
f"{os.environ['HTTPDBG_SUBPROCESS_DIR']}/*.httpdbgrecords"
|
|
48
|
-
):
|
|
47
|
+
for dump in glob.glob(f"{os.environ[HTTPDBG_SUBPROCESS_DIR]}/*.httpdbgrecords"):
|
|
49
48
|
with open(dump, "rb") as dumpfile:
|
|
50
49
|
newrecords = pickle.load(dumpfile)
|
|
51
50
|
self.records.requests.update(newrecords.requests)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
from typing import Generator
|
|
4
|
+
|
|
5
|
+
from httpdbg.hooks.utils import decorate
|
|
6
|
+
from httpdbg.hooks.utils import getcallargs
|
|
7
|
+
from httpdbg.hooks.utils import undecorate
|
|
8
|
+
from httpdbg.initiator import httpdbg_tag
|
|
9
|
+
from httpdbg.records import HTTPRecords
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def set_hook_for_pytest_fixture(_, method):
|
|
13
|
+
def hook(*args, **kwargs):
|
|
14
|
+
callargs = getcallargs(method, *args, **kwargs)
|
|
15
|
+
|
|
16
|
+
if "fixturefunc" in callargs:
|
|
17
|
+
with httpdbg_tag(getattr(callargs["fixturefunc"], "__name__", "fixture")):
|
|
18
|
+
return method(*args, **kwargs)
|
|
19
|
+
else:
|
|
20
|
+
return method(*args, **kwargs)
|
|
21
|
+
|
|
22
|
+
return hook
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@contextmanager
|
|
26
|
+
def hook_pytest(records: HTTPRecords) -> Generator[None, None, None]:
|
|
27
|
+
hooks = False
|
|
28
|
+
try:
|
|
29
|
+
import _pytest.fixtures
|
|
30
|
+
|
|
31
|
+
_pytest.fixtures.call_fixture_func = decorate(
|
|
32
|
+
records, _pytest.fixtures.call_fixture_func, set_hook_for_pytest_fixture
|
|
33
|
+
)
|
|
34
|
+
_pytest.fixtures._teardown_yield_fixture = decorate(
|
|
35
|
+
records,
|
|
36
|
+
_pytest.fixtures._teardown_yield_fixture,
|
|
37
|
+
set_hook_for_pytest_fixture,
|
|
38
|
+
)
|
|
39
|
+
hooks = True
|
|
40
|
+
except ImportError:
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
yield
|
|
44
|
+
|
|
45
|
+
if hooks:
|
|
46
|
+
_pytest.fixtures.call_fixture_func = undecorate(
|
|
47
|
+
_pytest.fixtures.call_fixture_func
|
|
48
|
+
)
|
|
49
|
+
_pytest.fixtures._teardown_yield_fixture = undecorate(
|
|
50
|
+
_pytest.fixtures._teardown_yield_fixture
|
|
51
|
+
)
|
|
@@ -8,6 +8,8 @@ from typing import List
|
|
|
8
8
|
from typing import Tuple
|
|
9
9
|
from typing import Union
|
|
10
10
|
|
|
11
|
+
from httpdbg.env import HTTPDBG_CURRENT_INITIATOR
|
|
12
|
+
from httpdbg.env import HTTPDBG_CURRENT_TAG
|
|
11
13
|
from httpdbg.hooks.utils import getcallargs
|
|
12
14
|
from httpdbg.utils import get_new_uuid
|
|
13
15
|
from httpdbg.utils import logger
|
|
@@ -181,7 +183,7 @@ def extract_short_stack_from_file(
|
|
|
181
183
|
def httpdbg_initiator(
|
|
182
184
|
records, extracted_stack: traceback.StackSummary, original_method, *args, **kwargs
|
|
183
185
|
) -> Generator[Union[Initiator, None], None, None]:
|
|
184
|
-
envname = f"
|
|
186
|
+
envname = f"{HTTPDBG_CURRENT_INITIATOR}_{records.id}"
|
|
185
187
|
|
|
186
188
|
if not os.environ.get(envname):
|
|
187
189
|
# temporary set a fake initiator env variable to avoid a recursion error
|
|
@@ -217,3 +219,17 @@ def httpdbg_initiator(
|
|
|
217
219
|
|
|
218
220
|
else:
|
|
219
221
|
yield None
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
@contextmanager
|
|
225
|
+
def httpdbg_tag(tag: str) -> Generator[None, None, None]:
|
|
226
|
+
|
|
227
|
+
os.environ[HTTPDBG_CURRENT_TAG] = tag
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
yield
|
|
231
|
+
except Exception:
|
|
232
|
+
del os.environ[HTTPDBG_CURRENT_TAG]
|
|
233
|
+
raise
|
|
234
|
+
|
|
235
|
+
del os.environ[HTTPDBG_CURRENT_TAG]
|
|
@@ -9,6 +9,8 @@ import traceback
|
|
|
9
9
|
from urllib.parse import urlparse
|
|
10
10
|
from typing import Dict, List, Tuple, Union
|
|
11
11
|
|
|
12
|
+
from httpdbg.env import HTTPDBG_CURRENT_INITIATOR
|
|
13
|
+
from httpdbg.env import HTTPDBG_CURRENT_TAG
|
|
12
14
|
from httpdbg.utils import HTTPDBGCookie
|
|
13
15
|
from httpdbg.utils import HTTPDBGHeader
|
|
14
16
|
from httpdbg.initiator import in_lib
|
|
@@ -211,6 +213,7 @@ class HTTPRecord:
|
|
|
211
213
|
self.response: HTTPRecordResponse = HTTPRecordResponse()
|
|
212
214
|
self.ssl: Union[bool, None] = None
|
|
213
215
|
self.tbegin: datetime.datetime = datetime.datetime.now(datetime.timezone.utc)
|
|
216
|
+
self.tag = os.environ.get(HTTPDBG_CURRENT_TAG)
|
|
214
217
|
if tbegin:
|
|
215
218
|
self.tbegin = tbegin
|
|
216
219
|
|
|
@@ -302,7 +305,7 @@ class HTTPRecords:
|
|
|
302
305
|
return len(self.requests)
|
|
303
306
|
|
|
304
307
|
def get_initiator(self) -> Initiator:
|
|
305
|
-
envname = f"
|
|
308
|
+
envname = f"{HTTPDBG_CURRENT_INITIATOR}_{self.id}"
|
|
306
309
|
|
|
307
310
|
if envname in os.environ:
|
|
308
311
|
initiator = self._initiators[os.environ[envname]]
|
|
@@ -4,17 +4,23 @@ from http.server import HTTPServer
|
|
|
4
4
|
import threading
|
|
5
5
|
from typing import Generator
|
|
6
6
|
|
|
7
|
+
from httpdbg.exception import HttpdbgException
|
|
7
8
|
from httpdbg.records import HTTPRecords
|
|
8
9
|
from httpdbg.webapp import HttpbgHTTPRequestHandler
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
@contextmanager
|
|
12
|
-
def httpdbg_srv(port: int) -> Generator[HTTPRecords, None, None]:
|
|
13
|
+
def httpdbg_srv(host: str, port: int) -> Generator[HTTPRecords, None, None]:
|
|
13
14
|
server = None
|
|
14
15
|
records = HTTPRecords()
|
|
15
16
|
try:
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
try:
|
|
18
|
+
server = ServerThread(host, port, records)
|
|
19
|
+
server.start()
|
|
20
|
+
except Exception as ex_server_start:
|
|
21
|
+
raise HttpdbgException(
|
|
22
|
+
f"An issue occurred while starting the httpdbg web interface: [{str(ex_server_start)}]"
|
|
23
|
+
)
|
|
18
24
|
|
|
19
25
|
yield records
|
|
20
26
|
|
|
@@ -26,14 +32,14 @@ def httpdbg_srv(port: int) -> Generator[HTTPRecords, None, None]:
|
|
|
26
32
|
|
|
27
33
|
|
|
28
34
|
class ServerThread(threading.Thread):
|
|
29
|
-
def __init__(self, port: int, records: HTTPRecords) -> None:
|
|
35
|
+
def __init__(self, host: str, port: int, records: HTTPRecords) -> None:
|
|
30
36
|
threading.Thread.__init__(self)
|
|
31
37
|
self.port = port
|
|
32
38
|
|
|
33
39
|
def http_request_handler(*args, **kwargs):
|
|
34
40
|
HttpbgHTTPRequestHandler(records, *args, **kwargs)
|
|
35
41
|
|
|
36
|
-
self.srv = HTTPServer((
|
|
42
|
+
self.srv = HTTPServer((host, port), http_request_handler)
|
|
37
43
|
|
|
38
44
|
def run(self):
|
|
39
45
|
self.srv.serve_forever()
|
|
@@ -6,9 +6,11 @@ import secrets
|
|
|
6
6
|
import string
|
|
7
7
|
from typing import List
|
|
8
8
|
|
|
9
|
+
from httpdbg.env import HTTPDBG_LOG
|
|
10
|
+
|
|
9
11
|
logger = logging.getLogger("httpdbg")
|
|
10
12
|
logger.setLevel(100)
|
|
11
|
-
log_level = os.environ.get(
|
|
13
|
+
log_level = os.environ.get(HTTPDBG_LOG)
|
|
12
14
|
if log_level is not None:
|
|
13
15
|
logging.basicConfig(level=int(log_level), format="%(message)s")
|
|
14
16
|
logger.setLevel(int(log_level))
|
|
@@ -20,6 +20,7 @@ class RequestPayload(JSONEncoder):
|
|
|
20
20
|
"request": None,
|
|
21
21
|
"response": None,
|
|
22
22
|
"exception": None,
|
|
23
|
+
"tag": req.tag,
|
|
23
24
|
"initiator": req.initiator.to_json(),
|
|
24
25
|
"in_progress": req.in_progress,
|
|
25
26
|
}
|
|
@@ -74,6 +75,7 @@ class RequestListPayload(JSONEncoder):
|
|
|
74
75
|
"status_code": req.status_code,
|
|
75
76
|
"reason": req.reason,
|
|
76
77
|
"verb": req.method,
|
|
78
|
+
"tag": req.tag,
|
|
77
79
|
"initiator": req.initiator.to_json(full=False),
|
|
78
80
|
"in_progress": req.in_progress,
|
|
79
81
|
"tbegin": req.tbegin.isoformat(),
|
|
@@ -34,6 +34,7 @@ function apply_config() {
|
|
|
34
34
|
|
|
35
35
|
apply_config_rule_css(httpdbgApp.config.hide_netloc, sheet);
|
|
36
36
|
apply_config_rule_css(httpdbgApp.config.hide_initiator, sheet);
|
|
37
|
+
apply_config_rule_css(httpdbgApp.config.hide_tag, sheet);
|
|
37
38
|
|
|
38
39
|
apply_config_rule_click(httpdbgApp.config.details_wrap_default);
|
|
39
40
|
apply_config_rule_click(httpdbgApp.config.details_raw_default);
|
|
@@ -48,6 +49,7 @@ function load_config_from_url(apply) {
|
|
|
48
49
|
|
|
49
50
|
load_config_rule_from_url(httpdbgApp.config.hide_netloc, params);
|
|
50
51
|
load_config_rule_from_url(httpdbgApp.config.hide_initiator, params);
|
|
52
|
+
load_config_rule_from_url(httpdbgApp.config.hide_tag, params);
|
|
51
53
|
load_config_rule_from_url(httpdbgApp.config.details_wrap_default, params);
|
|
52
54
|
load_config_rule_from_url(httpdbgApp.config.details_raw_default, params);
|
|
53
55
|
|
|
@@ -65,6 +67,7 @@ function load_config_from_form(apply) {
|
|
|
65
67
|
|
|
66
68
|
load_config_rule_from_form(httpdbgApp.config.hide_netloc);
|
|
67
69
|
load_config_rule_from_form(httpdbgApp.config.hide_initiator);
|
|
70
|
+
load_config_rule_from_form(httpdbgApp.config.hide_tag);
|
|
68
71
|
load_config_rule_from_form(httpdbgApp.config.details_wrap_default);
|
|
69
72
|
load_config_rule_from_form(httpdbgApp.config.details_raw_default);
|
|
70
73
|
|
|
@@ -68,6 +68,11 @@
|
|
|
68
68
|
|
|
69
69
|
<input type="checkbox" id="cinitiator" name="hi" onchange="load_config_from_form(true)">
|
|
70
70
|
<label for="cinitiator">Hide the initiator rows</label>
|
|
71
|
+
|
|
72
|
+
<br>
|
|
73
|
+
|
|
74
|
+
<input type="checkbox" id="ctag" name="ht" onchange="load_config_from_form(true)">
|
|
75
|
+
<label for="ctag">Hide the tags</label>
|
|
71
76
|
</fieldset>
|
|
72
77
|
</div>
|
|
73
78
|
<div>
|
|
@@ -179,7 +184,12 @@
|
|
|
179
184
|
</td>
|
|
180
185
|
<td class="status"><span title="{{reason}}" data-qa-request-status>{{{status_code_view}}}</span></td>
|
|
181
186
|
<td class="method"><span title="{{verb}}" data-qa-request-method>{{verb}}</span></td>
|
|
182
|
-
<td class="url" title="{{title}}"
|
|
187
|
+
<td class="url" title="{{title}}">
|
|
188
|
+
<span class="url-content" data-qa-request-url>
|
|
189
|
+
<span class="netloc">{{netloc}}</span><span>{{urlext}}</span>
|
|
190
|
+
</span>
|
|
191
|
+
{{#tag}}<span class="tag">{{tag}}</span>{{/tag}}
|
|
192
|
+
</td>
|
|
183
193
|
</tr>
|
|
184
194
|
</script>
|
|
185
195
|
|
|
@@ -14,6 +14,12 @@ let httpdbgApp = {
|
|
|
14
14
|
"css": ".netloc {display: none;}",
|
|
15
15
|
"value": false
|
|
16
16
|
},
|
|
17
|
+
"hide_tag": {
|
|
18
|
+
"checkbox": "ctag",
|
|
19
|
+
"param": "ht",
|
|
20
|
+
"css": ".tag {display: none;}",
|
|
21
|
+
"value": false
|
|
22
|
+
},
|
|
17
23
|
"details_wrap_default": {
|
|
18
24
|
"checkbox": "cwrap",
|
|
19
25
|
"param": "wl",
|
|
@@ -16,13 +16,30 @@
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
.url {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-wrap: wrap;
|
|
21
|
+
align-items: center;
|
|
19
22
|
text-align: left;
|
|
20
|
-
white-space: nowrap;
|
|
21
|
-
text-overflow: ellipsis;
|
|
22
23
|
overflow: hidden;
|
|
23
24
|
width: auto;
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
.url-content {
|
|
28
|
+
flex: 1;
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
text-overflow: ellipsis;
|
|
31
|
+
white-space: nowrap;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.tag {
|
|
35
|
+
margin-left: 6px;
|
|
36
|
+
color: var(--tag-text);
|
|
37
|
+
background-color: var(--tag-bg-color);
|
|
38
|
+
border-radius: 20%;
|
|
39
|
+
padding: 1px 2px;
|
|
40
|
+
font-size: 0.8em;
|
|
41
|
+
}
|
|
42
|
+
|
|
26
43
|
.initiator-label {
|
|
27
44
|
white-space: nowrap;
|
|
28
45
|
overflow: hidden;
|
|
@@ -75,7 +92,7 @@
|
|
|
75
92
|
}
|
|
76
93
|
|
|
77
94
|
.initiator {
|
|
78
|
-
background-color: var(--table-initiator);
|
|
95
|
+
background-color: var(--table-initiator);
|
|
79
96
|
}
|
|
80
97
|
|
|
81
98
|
.request {
|
|
@@ -119,7 +136,7 @@
|
|
|
119
136
|
width: 16px;
|
|
120
137
|
padding: 2px !important;
|
|
121
138
|
transform: rotate(180deg);
|
|
122
|
-
background-color: var(--table-initiator);
|
|
139
|
+
background-color: var(--table-initiator);
|
|
123
140
|
opacity: 0.4;
|
|
124
141
|
}
|
|
125
142
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: httpdbg
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.24.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
|
|
@@ -125,13 +125,14 @@ No configuration is necessary to start but some few settings are available for p
|
|
|
125
125
|
### command line
|
|
126
126
|
|
|
127
127
|
```console
|
|
128
|
-
usage: pyhttpdbg [-h] [--port PORT] [--version] [--initiator INITIATOR] [--keep-up | --force-quit]
|
|
128
|
+
usage: pyhttpdbg [-h] [--host HOST] [--port PORT] [--version] [--initiator INITIATOR] [--keep-up | --force-quit]
|
|
129
129
|
[--console | --module MODULE | --script SCRIPT]
|
|
130
130
|
|
|
131
131
|
httdbg - a very simple tool to debug HTTP(S) client requests
|
|
132
132
|
|
|
133
133
|
options:
|
|
134
134
|
-h, --help show this help message and exit
|
|
135
|
+
--host HOST the web interface host IP address
|
|
135
136
|
--port PORT, -p PORT the web interface port
|
|
136
137
|
--version, -v print the httpdbg version
|
|
137
138
|
--initiator INITIATOR, -i INITIATOR
|
|
@@ -151,6 +152,7 @@ Clic on the **⚙** button on the top right of the page.
|
|
|
151
152
|
Some options are available:
|
|
152
153
|
* Hide the netloc in the url
|
|
153
154
|
* Hide the initiator rows
|
|
155
|
+
* Hide the tags
|
|
154
156
|
|
|
155
157
|
To keep your configuration, bookmark the page with the full search query.
|
|
156
158
|
|
|
@@ -5,6 +5,8 @@ setup.cfg
|
|
|
5
5
|
httpdbg/__init__.py
|
|
6
6
|
httpdbg/__main__.py
|
|
7
7
|
httpdbg/args.py
|
|
8
|
+
httpdbg/env.py
|
|
9
|
+
httpdbg/exception.py
|
|
8
10
|
httpdbg/initiator.py
|
|
9
11
|
httpdbg/mode_console.py
|
|
10
12
|
httpdbg/mode_module.py
|
|
@@ -25,6 +27,7 @@ httpdbg/hooks/all.py
|
|
|
25
27
|
httpdbg/hooks/external.py
|
|
26
28
|
httpdbg/hooks/generic.py
|
|
27
29
|
httpdbg/hooks/httpx.py
|
|
30
|
+
httpdbg/hooks/pytest.py
|
|
28
31
|
httpdbg/hooks/requests.py
|
|
29
32
|
httpdbg/hooks/socket.py
|
|
30
33
|
httpdbg/hooks/urllib3.py
|
|
@@ -66,4 +69,5 @@ tests/test_initiator.py
|
|
|
66
69
|
tests/test_mode_console.py
|
|
67
70
|
tests/test_mode_module_pytest.py
|
|
68
71
|
tests/test_mode_script.py
|
|
69
|
-
tests/test_preview.py
|
|
72
|
+
tests/test_preview.py
|
|
73
|
+
tests/test_server.py
|
|
@@ -11,12 +11,12 @@ from utils import get_request_details
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
@pytest.mark.api
|
|
14
|
-
def test_api_requests_one_request(httpbin, httpdbg_port):
|
|
15
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
14
|
+
def test_api_requests_one_request(httpbin, httpdbg_host, httpdbg_port):
|
|
15
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
16
16
|
with httprecord(records):
|
|
17
17
|
requests.get(httpbin.url + "/get")
|
|
18
18
|
|
|
19
|
-
ret = requests.get(f"http://
|
|
19
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
20
20
|
|
|
21
21
|
reqs = ret.json()["requests"]
|
|
22
22
|
|
|
@@ -25,13 +25,13 @@ def test_api_requests_one_request(httpbin, httpdbg_port):
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
@pytest.mark.api
|
|
28
|
-
def test_api_requests_two_requests(httpbin, httpdbg_port):
|
|
29
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
28
|
+
def test_api_requests_two_requests(httpbin, httpdbg_host, httpdbg_port):
|
|
29
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
30
30
|
with httprecord(records):
|
|
31
31
|
requests.get(httpbin.url + "/get?abc")
|
|
32
32
|
requests.get(httpbin.url + "/get?def")
|
|
33
33
|
|
|
34
|
-
ret = requests.get(f"http://
|
|
34
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
35
35
|
|
|
36
36
|
reqs = ret.json()["requests"]
|
|
37
37
|
|
|
@@ -41,11 +41,11 @@ def test_api_requests_two_requests(httpbin, httpdbg_port):
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
@pytest.mark.api
|
|
44
|
-
def test_api_requests_netloc(httpbin, httpdbg_port):
|
|
45
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
44
|
+
def test_api_requests_netloc(httpbin, httpdbg_host, httpdbg_port):
|
|
45
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
46
46
|
with httprecord(records):
|
|
47
47
|
requests.get(httpbin.url + "/get?abc")
|
|
48
|
-
ret = requests.get(f"http://
|
|
48
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
49
49
|
|
|
50
50
|
reqs = ret.json()["requests"]
|
|
51
51
|
|
|
@@ -56,8 +56,8 @@ def test_api_requests_netloc(httpbin, httpdbg_port):
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
@pytest.mark.api
|
|
59
|
-
def test_api_request_by_id(httpbin, httpdbg_port):
|
|
60
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
59
|
+
def test_api_request_by_id(httpbin, httpdbg_host, httpdbg_port):
|
|
60
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
61
61
|
with httprecord(records):
|
|
62
62
|
requests.get(httpbin.url + "/get?abc")
|
|
63
63
|
requests.get(httpbin.url + "/get?def")
|
|
@@ -73,20 +73,20 @@ def test_api_request_by_id(httpbin, httpdbg_port):
|
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
@pytest.mark.api
|
|
76
|
-
def test_api_request_by_id_not_exists(httpbin, httpdbg_port):
|
|
77
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
76
|
+
def test_api_request_by_id_not_exists(httpbin, httpdbg_host, httpdbg_port):
|
|
77
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
78
78
|
with httprecord(records):
|
|
79
79
|
requests.get(httpbin.url + "/get?abc")
|
|
80
80
|
requests.get(httpbin.url + "/get?def")
|
|
81
81
|
|
|
82
|
-
ret = requests.get(f"http://
|
|
82
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/request/999")
|
|
83
83
|
|
|
84
84
|
assert ret.status_code == 404
|
|
85
85
|
|
|
86
86
|
|
|
87
87
|
@pytest.mark.api
|
|
88
|
-
def test_api_get_request_get(httpbin, httpdbg_port):
|
|
89
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
88
|
+
def test_api_get_request_get(httpbin, httpdbg_host, httpdbg_port):
|
|
89
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
90
90
|
with httprecord(records):
|
|
91
91
|
requests.get(httpbin.url + "/")
|
|
92
92
|
requests.get(httpbin.url + "/get")
|
|
@@ -95,7 +95,7 @@ def test_api_get_request_get(httpbin, httpdbg_port):
|
|
|
95
95
|
|
|
96
96
|
path_to_content = ret.json()["response"]["body"]["path"]
|
|
97
97
|
req_response_content = requests.get(
|
|
98
|
-
f"http://
|
|
98
|
+
f"http://{httpdbg_host}:{httpdbg_port}{path_to_content}"
|
|
99
99
|
)
|
|
100
100
|
|
|
101
101
|
# headers
|
|
@@ -122,8 +122,8 @@ def test_api_get_request_get(httpbin, httpdbg_port):
|
|
|
122
122
|
|
|
123
123
|
|
|
124
124
|
@pytest.mark.api
|
|
125
|
-
def test_api_get_request_post(httpbin, httpdbg_port):
|
|
126
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
125
|
+
def test_api_get_request_post(httpbin, httpdbg_host, httpdbg_port):
|
|
126
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
127
127
|
with httprecord(records):
|
|
128
128
|
requests.get(httpbin.url + "/")
|
|
129
129
|
requests.post(httpbin.url + "/post", data=b"data to post")
|
|
@@ -132,12 +132,12 @@ def test_api_get_request_post(httpbin, httpdbg_port):
|
|
|
132
132
|
|
|
133
133
|
path_to_content = ret.json()["request"]["body"]["path"]
|
|
134
134
|
req_request_content = requests.get(
|
|
135
|
-
f"http://
|
|
135
|
+
f"http://{httpdbg_host}:{httpdbg_port}{path_to_content}"
|
|
136
136
|
)
|
|
137
137
|
|
|
138
138
|
path_to_content = ret.json()["response"]["body"]["path"]
|
|
139
139
|
req_response_content = requests.get(
|
|
140
|
-
f"http://
|
|
140
|
+
f"http://{httpdbg_host}:{httpdbg_port}{path_to_content}"
|
|
141
141
|
)
|
|
142
142
|
|
|
143
143
|
# headers
|
|
@@ -167,8 +167,8 @@ def test_api_get_request_post(httpbin, httpdbg_port):
|
|
|
167
167
|
|
|
168
168
|
|
|
169
169
|
@pytest.mark.api
|
|
170
|
-
def test_api_get_request_get_status_404(httpbin, httpdbg_port):
|
|
171
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
170
|
+
def test_api_get_request_get_status_404(httpbin, httpdbg_host, httpdbg_port):
|
|
171
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
172
172
|
with httprecord(records):
|
|
173
173
|
ret = requests.get(httpbin.url + "/abc")
|
|
174
174
|
assert ret.status_code == 404
|
|
@@ -181,10 +181,10 @@ def test_api_get_request_get_status_404(httpbin, httpdbg_port):
|
|
|
181
181
|
|
|
182
182
|
|
|
183
183
|
@pytest.mark.api
|
|
184
|
-
def test_api_get_request_connection_error(httpbin, httpdbg_port):
|
|
184
|
+
def test_api_get_request_connection_error(httpbin, httpdbg_host, httpdbg_port):
|
|
185
185
|
url_with_unknown_host = "http://f.q.d.1234.n.t.n.e/hello?a=b"
|
|
186
186
|
|
|
187
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
187
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
188
188
|
with httprecord(records):
|
|
189
189
|
with pytest.raises(requests.exceptions.ConnectionError):
|
|
190
190
|
requests.get(url_with_unknown_host)
|
|
@@ -197,8 +197,8 @@ def test_api_get_request_connection_error(httpbin, httpdbg_port):
|
|
|
197
197
|
|
|
198
198
|
|
|
199
199
|
@pytest.mark.api
|
|
200
|
-
def test_api_get_request_content_up_text(httpbin, httpdbg_port):
|
|
201
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
200
|
+
def test_api_get_request_content_up_text(httpbin, httpdbg_host, httpdbg_port):
|
|
201
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
202
202
|
with httprecord(records):
|
|
203
203
|
requests.post(httpbin.url + "/post", data={"a": 1, "b": 2})
|
|
204
204
|
requests.post(httpbin.url + "/post", data="hello")
|
|
@@ -215,8 +215,8 @@ def test_api_get_request_content_up_text(httpbin, httpdbg_port):
|
|
|
215
215
|
|
|
216
216
|
@pytest.mark.api
|
|
217
217
|
@pytest.mark.cookies
|
|
218
|
-
def test_cookies_request(httpbin, httpdbg_port):
|
|
219
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
218
|
+
def test_cookies_request(httpbin, httpdbg_host, httpdbg_port):
|
|
219
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
220
220
|
with httprecord(records):
|
|
221
221
|
session = requests.session()
|
|
222
222
|
session.cookies.set("COOKIE_NAME", "the-cookie-works")
|
|
@@ -232,8 +232,8 @@ def test_cookies_request(httpbin, httpdbg_port):
|
|
|
232
232
|
|
|
233
233
|
@pytest.mark.api
|
|
234
234
|
@pytest.mark.cookies
|
|
235
|
-
def test_cookies_response(httpbin, httpdbg_port):
|
|
236
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
235
|
+
def test_cookies_response(httpbin, httpdbg_host, httpdbg_port):
|
|
236
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
237
237
|
with httprecord(records):
|
|
238
238
|
session = requests.session()
|
|
239
239
|
session.get(
|
|
@@ -33,8 +33,8 @@ def test_run_console_from_pyhttpdbg_entry_point_default(
|
|
|
33
33
|
assert "test_mode is on" in capsys.readouterr().out
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
def test_run_console(httpbin, httpdbg_port):
|
|
37
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
36
|
+
def test_run_console(httpbin, httpdbg_host, httpdbg_port):
|
|
37
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
38
38
|
with httprecord(records):
|
|
39
39
|
new_console = run_console(test_mode=True)
|
|
40
40
|
new_console.push("import requests")
|
|
@@ -42,7 +42,7 @@ def test_run_console(httpbin, httpdbg_port):
|
|
|
42
42
|
with pytest.raises(SystemExit):
|
|
43
43
|
new_console.push("exit()")
|
|
44
44
|
|
|
45
|
-
ret = requests.get(f"http://
|
|
45
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
46
46
|
|
|
47
47
|
reqs = ret.json()["requests"]
|
|
48
48
|
|
|
@@ -11,7 +11,7 @@ from httpdbg.server import httpdbg_srv
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
@pytest.mark.pytest
|
|
14
|
-
def test_run_pytest_from_pyhttpdbg_entry_point(httpbin,
|
|
14
|
+
def test_run_pytest_from_pyhttpdbg_entry_point(httpbin, monkeypatch):
|
|
15
15
|
os.environ["HTTPDBG_TEST_PYTEST_BASE_URL"] = httpbin.url
|
|
16
16
|
script_to_run = os.path.join(
|
|
17
17
|
os.path.dirname(os.path.realpath(__file__)), "demo_run_pytest.py"
|
|
@@ -29,8 +29,8 @@ def test_run_pytest_from_pyhttpdbg_entry_point(httpbin, httpdbg_port, monkeypatc
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
@pytest.mark.pytest
|
|
32
|
-
def test_run_pytest(httpbin, httpdbg_port):
|
|
33
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
32
|
+
def test_run_pytest(httpbin, httpdbg_host, httpdbg_port):
|
|
33
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
34
34
|
with httprecord(records):
|
|
35
35
|
os.environ["HTTPDBG_TEST_PYTEST_BASE_URL"] = httpbin.url
|
|
36
36
|
script_to_run = os.path.join(
|
|
@@ -38,7 +38,7 @@ def test_run_pytest(httpbin, httpdbg_port):
|
|
|
38
38
|
)
|
|
39
39
|
run_module(["pytest", f"{script_to_run}::test_demo_pytest"])
|
|
40
40
|
|
|
41
|
-
ret = requests.get(f"http://
|
|
41
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
42
42
|
|
|
43
43
|
reqs = ret.json()["requests"]
|
|
44
44
|
|
|
@@ -49,15 +49,15 @@ def test_run_pytest(httpbin, httpdbg_port):
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
@pytest.mark.pytest
|
|
52
|
-
def test_run_pytest_with_exception(httpdbg_port, capsys):
|
|
53
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
52
|
+
def test_run_pytest_with_exception(httpdbg_host, httpdbg_port, capsys):
|
|
53
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
54
54
|
with httprecord(records):
|
|
55
55
|
script_to_run = os.path.join(
|
|
56
56
|
os.path.dirname(os.path.realpath(__file__)), "demo_run_pytest.py"
|
|
57
57
|
)
|
|
58
58
|
run_module(["pytest", f"{script_to_run}::test_demo_raise_exception"])
|
|
59
59
|
|
|
60
|
-
ret = requests.get(f"http://
|
|
60
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
61
61
|
|
|
62
62
|
reqs = ret.json()["requests"]
|
|
63
63
|
|
|
@@ -68,8 +68,8 @@ def test_run_pytest_with_exception(httpdbg_port, capsys):
|
|
|
68
68
|
|
|
69
69
|
@pytest.mark.api
|
|
70
70
|
@pytest.mark.pytest
|
|
71
|
-
def test_run_pytest_initiator(httpbin, httpdbg_port):
|
|
72
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
71
|
+
def test_run_pytest_initiator(httpbin, httpdbg_host, httpdbg_port):
|
|
72
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
73
73
|
with httprecord(records):
|
|
74
74
|
os.environ["HTTPDBG_TEST_PYTEST_BASE_URL"] = httpbin.url
|
|
75
75
|
script_to_run = os.path.join(
|
|
@@ -77,7 +77,7 @@ def test_run_pytest_initiator(httpbin, httpdbg_port):
|
|
|
77
77
|
)
|
|
78
78
|
run_module(["pytest", f"{script_to_run}::test_demo_pytest"])
|
|
79
79
|
|
|
80
|
-
ret = requests.get(f"http://
|
|
80
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
81
81
|
|
|
82
82
|
reqs = ret.json()["requests"]
|
|
83
83
|
|
|
@@ -23,15 +23,15 @@ def test_run_script_from_pyhttpdbg_entry_point(httpbin, monkeypatch):
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
@pytest.mark.script
|
|
26
|
-
def test_run_script(httpbin, httpdbg_port):
|
|
27
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
26
|
+
def test_run_script(httpbin, httpdbg_host, httpdbg_port):
|
|
27
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
28
28
|
with httprecord(records):
|
|
29
29
|
script_to_run = os.path.join(
|
|
30
30
|
os.path.dirname(os.path.realpath(__file__)), "demo_run_script.py"
|
|
31
31
|
)
|
|
32
32
|
run_script([script_to_run, httpbin.url])
|
|
33
33
|
|
|
34
|
-
ret = requests.get(f"http://
|
|
34
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
35
35
|
|
|
36
36
|
reqs = ret.json()["requests"]
|
|
37
37
|
|
|
@@ -41,15 +41,15 @@ def test_run_script(httpbin, httpdbg_port):
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
@pytest.mark.script
|
|
44
|
-
def test_run_script_with_exception(httpbin, httpdbg_port, capsys):
|
|
45
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
44
|
+
def test_run_script_with_exception(httpbin, httpdbg_host, httpdbg_port, capsys):
|
|
45
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
46
46
|
with httprecord(records):
|
|
47
47
|
script_to_run = os.path.join(
|
|
48
48
|
os.path.dirname(os.path.realpath(__file__)), "demo_run_script.py"
|
|
49
49
|
)
|
|
50
50
|
run_script([script_to_run, httpbin.url, "raise_exception"])
|
|
51
51
|
|
|
52
|
-
ret = requests.get(f"http://
|
|
52
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
53
53
|
|
|
54
54
|
reqs = ret.json()["requests"]
|
|
55
55
|
|
|
@@ -73,15 +73,15 @@ def test_run_script_not_a_python_script(httpbin, capsys):
|
|
|
73
73
|
|
|
74
74
|
@pytest.mark.api
|
|
75
75
|
@pytest.mark.script
|
|
76
|
-
def test_run_script_initiator(httpbin, httpdbg_port):
|
|
77
|
-
with httpdbg_srv(httpdbg_port) as records:
|
|
76
|
+
def test_run_script_initiator(httpbin, httpdbg_host, httpdbg_port):
|
|
77
|
+
with httpdbg_srv(httpdbg_host, httpdbg_port) as records:
|
|
78
78
|
with httprecord(records):
|
|
79
79
|
script_to_run = os.path.join(
|
|
80
80
|
os.path.dirname(os.path.realpath(__file__)), "demo_run_script.py"
|
|
81
81
|
)
|
|
82
82
|
run_script([script_to_run, httpbin.url])
|
|
83
83
|
|
|
84
|
-
ret = requests.get(f"http://
|
|
84
|
+
ret = requests.get(f"http://{httpdbg_host}:{httpdbg_port}/requests")
|
|
85
85
|
|
|
86
86
|
reqs = ret.json()["requests"]
|
|
87
87
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import requests
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from httpdbg.exception import HttpdbgException
|
|
7
|
+
from httpdbg.hooks.all import httprecord
|
|
8
|
+
from httpdbg.server import httpdbg_srv
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.mark.server
|
|
12
|
+
@pytest.mark.parametrize("host", ["localhost", "0.0.0.0"])
|
|
13
|
+
def test_server_host(httpbin, host, httpdbg_port):
|
|
14
|
+
with httpdbg_srv(host, httpdbg_port) as records:
|
|
15
|
+
with httprecord(records):
|
|
16
|
+
requests.get(httpbin.url + "/get")
|
|
17
|
+
|
|
18
|
+
ret = requests.get(f"http://localhost:{httpdbg_port}/requests")
|
|
19
|
+
|
|
20
|
+
reqs = ret.json()["requests"]
|
|
21
|
+
|
|
22
|
+
assert len(reqs) == 1
|
|
23
|
+
assert reqs[list(reqs.keys())[0]]["url"] == httpbin.url + "/get"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.mark.server
|
|
27
|
+
def test_server_host_exception_host(httpdbg_port):
|
|
28
|
+
host = "1.2.3.4"
|
|
29
|
+
with pytest.raises(HttpdbgException):
|
|
30
|
+
with httpdbg_srv(host, httpdbg_port):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.mark.server
|
|
35
|
+
def test_server_host_exception_port():
|
|
36
|
+
host = "127.0.0.1"
|
|
37
|
+
port = 123456789
|
|
38
|
+
with pytest.raises(HttpdbgException):
|
|
39
|
+
with httpdbg_srv(host, port):
|
|
40
|
+
pass
|
|
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.22.0 → httpdbg-0.24.0}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg
RENAMED
|
File without changes
|
{httpdbg-0.22.0 → httpdbg-0.24.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
|
{httpdbg-0.22.0 → httpdbg-0.24.0}/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
|