httpdbg 0.18.0__tar.gz → 0.19.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.18.0 → httpdbg-0.19.0}/PKG-INFO +1 -1
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/__init__.py +1 -1
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/__main__.py +2 -2
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/socket.py +3 -3
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/records.py +28 -28
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/api.py +2 -1
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/app.py +2 -2
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/detail.css +2 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/index.htm +8 -2
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/PKG-INFO +1 -1
- {httpdbg-0.18.0 → httpdbg-0.19.0}/pyproject.toml +1 -1
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_cli.py +2 -2
- {httpdbg-0.18.0 → httpdbg-0.19.0}/LICENSE +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/README.md +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/args.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/__init__.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/aiohttp.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/all.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/external.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/generic.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/httpx.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/requests.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/urllib3.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/utils.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/initiator.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/mode_console.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/mode_module.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/mode_script.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/preview.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/server.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/utils.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/__init__.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/api.js +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/column.css +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/configuration.js +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/favicon.ico +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/filter.js +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/main.js +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/mustache.min.js +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/render.js +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/style.css +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/table.css +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/SOURCES.txt +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/dependency_links.txt +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/entry_points.txt +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/requires.txt +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/top_level.txt +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/setup.cfg +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_api.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_context_manager.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_hook_aiohttp.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_hook_httpx.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_hook_requests.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_hook_urllib3.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_initiator.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_mode_console.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_mode_module_pytest.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_mode_script.py +0 -0
- {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_preview.py +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import sys
|
|
3
3
|
import time
|
|
4
4
|
|
|
5
|
-
from httpdbg import
|
|
5
|
+
from httpdbg import __version__
|
|
6
6
|
from httpdbg.args import read_args
|
|
7
7
|
from httpdbg.hooks.all import httprecord
|
|
8
8
|
from httpdbg.server import httpdbg_srv
|
|
@@ -54,7 +54,7 @@ def pyhttpdbg(params, subparams, test_mode=False):
|
|
|
54
54
|
def pyhttpdbg_entry_point(test_mode=False):
|
|
55
55
|
params, subparams = read_args(sys.argv[1:])
|
|
56
56
|
if params.version:
|
|
57
|
-
print(
|
|
57
|
+
print(__version__)
|
|
58
58
|
else:
|
|
59
59
|
pyhttpdbg(params, subparams, test_mode=test_mode)
|
|
60
60
|
|
|
@@ -197,7 +197,7 @@ def set_hook_for_socket_sendall(records, method):
|
|
|
197
197
|
http_detected = socketdata.http_detected()
|
|
198
198
|
if http_detected:
|
|
199
199
|
logger.info("SENDALL - http detected")
|
|
200
|
-
socketdata.record = HTTPRecord()
|
|
200
|
+
socketdata.record = HTTPRecord(tbegin=socketdata.tbegin)
|
|
201
201
|
socketdata.record.initiator = records.get_initiator()
|
|
202
202
|
socketdata.record.address = socketdata.address
|
|
203
203
|
socketdata.record.ssl = socketdata.ssl
|
|
@@ -238,7 +238,7 @@ def set_hook_for_socket_send(records, method):
|
|
|
238
238
|
socketdata.rawdata += bytes[:size]
|
|
239
239
|
http_detected = socketdata.http_detected()
|
|
240
240
|
if http_detected:
|
|
241
|
-
socketdata.record = HTTPRecord()
|
|
241
|
+
socketdata.record = HTTPRecord(tbegin=socketdata.tbegin)
|
|
242
242
|
socketdata.record.initiator = records.get_initiator()
|
|
243
243
|
socketdata.record.address = socketdata.address
|
|
244
244
|
socketdata.record.ssl = socketdata.ssl
|
|
@@ -295,7 +295,7 @@ def set_hook_for_sslobject_write(records, method):
|
|
|
295
295
|
socketdata.rawdata += bytes(buf[:size])
|
|
296
296
|
http_detected = socketdata.http_detected()
|
|
297
297
|
if http_detected:
|
|
298
|
-
socketdata.record = HTTPRecord()
|
|
298
|
+
socketdata.record = HTTPRecord(tbegin=socketdata.tbegin)
|
|
299
299
|
socketdata.record.initiator = records.get_initiator()
|
|
300
300
|
socketdata.record.address = socketdata.address
|
|
301
301
|
socketdata.record.ssl = socketdata.ssl
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import asyncio
|
|
3
3
|
import asyncio.proactor_events
|
|
4
|
+
import datetime
|
|
4
5
|
import os
|
|
5
6
|
import socket
|
|
6
7
|
import ssl
|
|
7
|
-
import time
|
|
8
8
|
import traceback
|
|
9
9
|
from urllib.parse import urlparse
|
|
10
10
|
from typing import Dict, List, Tuple, Union
|
|
@@ -12,7 +12,6 @@ from typing import Dict, List, Tuple, Union
|
|
|
12
12
|
from httpdbg.utils import HTTPDBGCookie
|
|
13
13
|
from httpdbg.utils import HTTPDBGHeader
|
|
14
14
|
from httpdbg.initiator import in_lib
|
|
15
|
-
from httpdbg.initiator import compatible_path
|
|
16
15
|
from httpdbg.initiator import Initiator
|
|
17
16
|
from httpdbg.preview import generate_preview
|
|
18
17
|
from httpdbg.utils import get_new_uuid
|
|
@@ -23,12 +22,13 @@ from httpdbg.utils import logger
|
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
class SocketRawData(object):
|
|
26
|
-
def __init__(self, id:
|
|
25
|
+
def __init__(self, id: int, address: Tuple[str, int], ssl: bool) -> None:
|
|
27
26
|
self.id = id
|
|
28
27
|
self.address = address
|
|
29
28
|
self.ssl = ssl
|
|
30
29
|
self._rawdata = bytes()
|
|
31
30
|
self.record = None
|
|
31
|
+
self.tbegin: datetime.datetime = datetime.datetime.now(datetime.timezone.utc)
|
|
32
32
|
|
|
33
33
|
@property
|
|
34
34
|
def rawdata(self) -> bytes:
|
|
@@ -64,7 +64,9 @@ class HTTPRecordReqResp(object):
|
|
|
64
64
|
self.rawdata = bytes()
|
|
65
65
|
self._rawheaders = bytes()
|
|
66
66
|
self._headers: List[HTTPDBGHeader] = []
|
|
67
|
-
self.last_update =
|
|
67
|
+
self.last_update: datetime.datetime = datetime.datetime.now(
|
|
68
|
+
datetime.timezone.utc
|
|
69
|
+
)
|
|
68
70
|
|
|
69
71
|
def get_header(self, name: str, default: str = "") -> str:
|
|
70
72
|
for header in self.headers:
|
|
@@ -117,7 +119,7 @@ class HTTPRecordReqResp(object):
|
|
|
117
119
|
|
|
118
120
|
def __setattr__(self, name, value):
|
|
119
121
|
self.__dict__[name] = value
|
|
120
|
-
self.__dict__["last_update"] =
|
|
122
|
+
self.__dict__["last_update"] = datetime.datetime.now(datetime.timezone.utc)
|
|
121
123
|
|
|
122
124
|
@property
|
|
123
125
|
def preview(self):
|
|
@@ -199,15 +201,18 @@ class HTTPRecordResponse(HTTPRecordReqResp):
|
|
|
199
201
|
|
|
200
202
|
|
|
201
203
|
class HTTPRecord:
|
|
202
|
-
def __init__(self) -> None:
|
|
204
|
+
def __init__(self, tbegin: datetime.datetime = None) -> None:
|
|
203
205
|
self.id = get_new_uuid()
|
|
204
206
|
self.address: Tuple[str, int] = ("", 0)
|
|
205
207
|
self._url: Union[str, None] = None
|
|
206
208
|
self.initiator: Initiator = Initiator("", "", None, "", [])
|
|
207
|
-
self.exception = None
|
|
208
|
-
self.request = HTTPRecordRequest()
|
|
209
|
-
self.response = HTTPRecordResponse()
|
|
210
|
-
self.ssl = None
|
|
209
|
+
self.exception: Union[Exception, None] = None
|
|
210
|
+
self.request: HTTPRecordRequest = HTTPRecordRequest()
|
|
211
|
+
self.response: HTTPRecordResponse = HTTPRecordResponse()
|
|
212
|
+
self.ssl: Union[bool, None] = None
|
|
213
|
+
self.tbegin: datetime.datetime = datetime.datetime.now(datetime.timezone.utc)
|
|
214
|
+
if tbegin:
|
|
215
|
+
self.tbegin = tbegin
|
|
211
216
|
|
|
212
217
|
@property
|
|
213
218
|
def url(self) -> str:
|
|
@@ -271,7 +276,7 @@ class HTTPRecord:
|
|
|
271
276
|
return False
|
|
272
277
|
|
|
273
278
|
@property
|
|
274
|
-
def last_update(self) ->
|
|
279
|
+
def last_update(self) -> datetime.datetime:
|
|
275
280
|
return max(self.request.last_update, self.response.last_update)
|
|
276
281
|
|
|
277
282
|
|
|
@@ -284,7 +289,7 @@ class HTTPRecords:
|
|
|
284
289
|
self.requests: Dict[str, HTTPRecord] = {}
|
|
285
290
|
self.requests_already_loaded = 0
|
|
286
291
|
self._initiators: Dict[str, Initiator] = {}
|
|
287
|
-
self._sockets: Dict[
|
|
292
|
+
self._sockets: Dict[int, SocketRawData] = {}
|
|
288
293
|
|
|
289
294
|
@property
|
|
290
295
|
def unread(self) -> int:
|
|
@@ -303,21 +308,14 @@ class HTTPRecords:
|
|
|
303
308
|
initiator = self._initiators[os.environ[envname]]
|
|
304
309
|
else:
|
|
305
310
|
fullstack = traceback.format_stack()
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
long_label = stack[-1]
|
|
315
|
-
short_label = long_label.split("\n")[1]
|
|
316
|
-
initiator = Initiator(
|
|
317
|
-
get_new_uuid(), short_label, None, long_label, stack
|
|
318
|
-
)
|
|
319
|
-
else:
|
|
320
|
-
initiator = Initiator(f"console{self.id}", "console", None, "", [])
|
|
311
|
+
stack: List[str] = []
|
|
312
|
+
for line in fullstack[6:]:
|
|
313
|
+
if in_lib(line):
|
|
314
|
+
break
|
|
315
|
+
stack.append(line)
|
|
316
|
+
long_label = stack[-1]
|
|
317
|
+
short_label = long_label.split("\n")[1]
|
|
318
|
+
initiator = Initiator(get_new_uuid(), short_label, None, long_label, stack)
|
|
321
319
|
|
|
322
320
|
if ("PYTEST_CURRENT_TEST" in os.environ) and (
|
|
323
321
|
"HTTPDBG_PYTEST_PLUGIN" not in os.environ
|
|
@@ -334,7 +332,9 @@ class HTTPRecords:
|
|
|
334
332
|
|
|
335
333
|
return initiator
|
|
336
334
|
|
|
337
|
-
def get_socket_data(
|
|
335
|
+
def get_socket_data(
|
|
336
|
+
self, obj, extra_sock=None, force_new=False, request=None
|
|
337
|
+
) -> Union[SocketRawData, None]:
|
|
338
338
|
socketdata = None
|
|
339
339
|
|
|
340
340
|
if force_new:
|
|
@@ -76,7 +76,8 @@ class RequestListPayload(JSONEncoder):
|
|
|
76
76
|
"verb": req.method,
|
|
77
77
|
"initiator": req.initiator.to_json(full=False),
|
|
78
78
|
"in_progress": req.in_progress,
|
|
79
|
-
"
|
|
79
|
+
"tbegin": req.tbegin.isoformat(),
|
|
80
|
+
"last_update": req.last_update.isoformat(),
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
return payload
|
|
@@ -8,7 +8,7 @@ import os
|
|
|
8
8
|
import re
|
|
9
9
|
from urllib.parse import urlparse, parse_qs
|
|
10
10
|
|
|
11
|
-
from httpdbg import
|
|
11
|
+
from httpdbg import __version__
|
|
12
12
|
from httpdbg.utils import logger
|
|
13
13
|
from httpdbg.webapp.api import RequestListPayload, RequestPayload
|
|
14
14
|
|
|
@@ -92,7 +92,7 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
92
92
|
)
|
|
93
93
|
|
|
94
94
|
filecontent = filecontent.replace(
|
|
95
|
-
b"$**HTTPDBG_VERSION**$",
|
|
95
|
+
b"$**HTTPDBG_VERSION**$", __version__.encode("utf-8")
|
|
96
96
|
)
|
|
97
97
|
|
|
98
98
|
self.wfile.write(filecontent)
|
|
@@ -229,8 +229,14 @@
|
|
|
229
229
|
<script id="template_headers" type="x-tmpl-mustache">
|
|
230
230
|
<b>{{ method }}</b> <a href="{{ url }}">{{ url }}</a>
|
|
231
231
|
<hr>
|
|
232
|
-
|
|
233
|
-
|
|
232
|
+
<span class="header-cookie-key">status</span>:
|
|
233
|
+
<span class="header-cookie-value">{{ status_code }} {{ reason }}</span>
|
|
234
|
+
<br><br>
|
|
235
|
+
<span class="header-cookie-key">start</span>:
|
|
236
|
+
<span class="header-cookie-value">{{tbegin}}</span>
|
|
237
|
+
<br>
|
|
238
|
+
<span class="header-cookie-key">end</span>:
|
|
239
|
+
<span class="header-cookie-value">{{last_update}}</span>
|
|
234
240
|
<hr>
|
|
235
241
|
<h4>response headers</h4>
|
|
236
242
|
{{#response}}
|
|
@@ -34,7 +34,7 @@ packages = ["httpdbg", "httpdbg.hooks", "httpdbg.webapp"]
|
|
|
34
34
|
httpdbg = ["webapp/static/*", "webapp/static/icons/*"]
|
|
35
35
|
|
|
36
36
|
[tool.setuptools.dynamic]
|
|
37
|
-
version = {attr = "httpdbg.
|
|
37
|
+
version = {attr = "httpdbg.__version__"}
|
|
38
38
|
|
|
39
39
|
[tool.mypy]
|
|
40
40
|
no_implicit_optional = false
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import pytest
|
|
3
3
|
|
|
4
|
-
from httpdbg import
|
|
4
|
+
from httpdbg import __version__
|
|
5
5
|
from httpdbg.__main__ import pyhttpdbg_entry_point
|
|
6
6
|
|
|
7
7
|
|
|
@@ -11,4 +11,4 @@ def test_cli_version(monkeypatch, capsys):
|
|
|
11
11
|
|
|
12
12
|
pyhttpdbg_entry_point(test_mode=True)
|
|
13
13
|
|
|
14
|
-
assert
|
|
14
|
+
assert __version__ in capsys.readouterr().out.strip()
|
|
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.18.0 → httpdbg-0.19.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.18.0 → httpdbg-0.19.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|