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.
Files changed (69) hide show
  1. {httpdbg-0.18.0 → httpdbg-0.19.0}/PKG-INFO +1 -1
  2. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/__init__.py +1 -1
  3. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/__main__.py +2 -2
  4. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/socket.py +3 -3
  5. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/records.py +28 -28
  6. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/api.py +2 -1
  7. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/app.py +2 -2
  8. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/detail.css +2 -0
  9. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/index.htm +8 -2
  10. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/PKG-INFO +1 -1
  11. {httpdbg-0.18.0 → httpdbg-0.19.0}/pyproject.toml +1 -1
  12. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_cli.py +2 -2
  13. {httpdbg-0.18.0 → httpdbg-0.19.0}/LICENSE +0 -0
  14. {httpdbg-0.18.0 → httpdbg-0.19.0}/README.md +0 -0
  15. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/args.py +0 -0
  16. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/__init__.py +0 -0
  17. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/aiohttp.py +0 -0
  18. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/all.py +0 -0
  19. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/external.py +0 -0
  20. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/generic.py +0 -0
  21. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/httpx.py +0 -0
  22. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/requests.py +0 -0
  23. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/urllib3.py +0 -0
  24. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/hooks/utils.py +0 -0
  25. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/initiator.py +0 -0
  26. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/mode_console.py +0 -0
  27. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/mode_module.py +0 -0
  28. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/mode_script.py +0 -0
  29. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/preview.py +0 -0
  30. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/server.py +0 -0
  31. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/utils.py +0 -0
  32. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/__init__.py +0 -0
  33. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/api.js +0 -0
  34. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/column.css +0 -0
  35. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/configuration.js +0 -0
  36. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/favicon.ico +0 -0
  37. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/filter.js +0 -0
  38. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
  39. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
  40. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
  41. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
  42. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
  43. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
  44. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
  45. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
  46. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
  47. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
  48. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/main.js +0 -0
  49. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/mustache.min.js +0 -0
  50. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/render.js +0 -0
  51. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/style.css +0 -0
  52. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg/webapp/static/table.css +0 -0
  53. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/SOURCES.txt +0 -0
  54. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/dependency_links.txt +0 -0
  55. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/entry_points.txt +0 -0
  56. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/requires.txt +0 -0
  57. {httpdbg-0.18.0 → httpdbg-0.19.0}/httpdbg.egg-info/top_level.txt +0 -0
  58. {httpdbg-0.18.0 → httpdbg-0.19.0}/setup.cfg +0 -0
  59. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_api.py +0 -0
  60. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_context_manager.py +0 -0
  61. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_hook_aiohttp.py +0 -0
  62. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_hook_httpx.py +0 -0
  63. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_hook_requests.py +0 -0
  64. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_hook_urllib3.py +0 -0
  65. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_initiator.py +0 -0
  66. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_mode_console.py +0 -0
  67. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_mode_module_pytest.py +0 -0
  68. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_mode_script.py +0 -0
  69. {httpdbg-0.18.0 → httpdbg-0.19.0}/tests/test_preview.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: httpdbg
3
- Version: 0.18.0
3
+ Version: 0.19.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
@@ -3,6 +3,6 @@ from httpdbg.hooks.all import httprecord
3
3
  from httpdbg.records import HTTPRecords
4
4
 
5
5
 
6
- VERSION = "0.18.0"
6
+ __version__ = "0.19.0"
7
7
 
8
8
  __all__ = ["httprecord", "HTTPRecords"]
@@ -2,7 +2,7 @@
2
2
  import sys
3
3
  import time
4
4
 
5
- from httpdbg import VERSION
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(VERSION)
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: str, address: Tuple[str, int], ssl: bool) -> None:
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 = 0
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"] = int(time.time() * 1000)
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) -> int:
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[str, SocketRawData] = {}
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
- if compatible_path("httpdbg/mode_script.py") in "".join(
307
- fullstack
308
- ): # TODO: find another way the detect the mode
309
- stack: List[str] = []
310
- for line in fullstack[6:]:
311
- if in_lib(line):
312
- break
313
- stack.append(line)
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(self, obj, extra_sock=None, force_new=False, request=None):
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
- "last_update": req.last_update,
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 VERSION
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**$", VERSION.encode("utf-8")
95
+ b"$**HTTPDBG_VERSION**$", __version__.encode("utf-8")
96
96
  )
97
97
 
98
98
  self.wfile.write(filecontent)
@@ -28,10 +28,12 @@
28
28
 
29
29
  .header-cookie-key {
30
30
  color: var(--header-cookie-key-text);
31
+ font-family: monospace;
31
32
  }
32
33
 
33
34
  .header-cookie-value {
34
35
  color: var(--header-cookie-value-text);
36
+ font-family: monospace;
35
37
  }
36
38
 
37
39
  .tab {
@@ -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
- <h4>status</h4>
233
- {{ status_code }} {{ reason }}
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>:&nbsp;&nbsp;&nbsp;
239
+ <span class="header-cookie-value">{{last_update}}</span>
234
240
  <hr>
235
241
  <h4>response headers</h4>
236
242
  {{#response}}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: httpdbg
3
- Version: 0.18.0
3
+ Version: 0.19.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
@@ -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.VERSION"}
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 VERSION
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 VERSION in capsys.readouterr().out.strip()
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