httpdbg 0.30.0__tar.gz → 0.31.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.30.0 → httpdbg-0.31.0}/PKG-INFO +10 -7
- {httpdbg-0.30.0 → httpdbg-0.31.0}/README.md +9 -6
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/__init__.py +1 -1
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/initiator.py +18 -3
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/records.py +11 -2
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/api.py +8 -3
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/app.py +15 -15
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/api.js +27 -23
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/column.css +0 -8
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/configuration.js +31 -17
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/index.htm +45 -63
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/main.js +44 -31
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/render.js +97 -28
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/style.css +4 -4
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg.egg-info/PKG-INFO +10 -7
- {httpdbg-0.30.0 → httpdbg-0.31.0}/LICENSE +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/__main__.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/args.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/env.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/exception.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/__init__.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/aiohttp.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/all.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/external.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/generic.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/httpx.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/pytest.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/requests.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/socket.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/unittest.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/urllib3.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/hooks/utils.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/log.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/mode_console.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/mode_module.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/mode_script.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/preview.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/server.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/utils.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/__init__.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/detail.css +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/favicon.ico +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/filter.js +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/mustache.min.js +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg/webapp/static/table.css +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg.egg-info/SOURCES.txt +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg.egg-info/dependency_links.txt +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg.egg-info/entry_points.txt +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg.egg-info/requires.txt +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/httpdbg.egg-info/top_level.txt +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/pyproject.toml +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/setup.cfg +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_api.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_cli.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_context_manager.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_hook_aiohttp.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_hook_httpx.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_hook_pytest.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_hook_requests.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_hook_unittest.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_hook_urllib3.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_initiator.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_mode_console.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_mode_module_pytest.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_mode_script.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_preview.py +0 -0
- {httpdbg-0.30.0 → httpdbg-0.31.0}/tests/test_server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: httpdbg
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.31.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
|
|
@@ -148,16 +148,19 @@ options:
|
|
|
148
148
|
|
|
149
149
|
### web interace
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
Some options are available to customize the UI:
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
* Hide the
|
|
155
|
-
* Hide the
|
|
156
|
-
* Hide the tags
|
|
153
|
+
* Change the strategy to group the requests.
|
|
154
|
+
* Hide the scheme and the network location in the url.
|
|
155
|
+
* Hide the group rows.
|
|
156
|
+
* Hide the tags.
|
|
157
|
+
* ...
|
|
158
|
+
|
|
159
|
+
You can also pin a request or delete all unpinned requests.
|
|
157
160
|
|
|
158
161
|
To keep your configuration, bookmark the page with the full search query.
|
|
159
162
|
|
|
160
|
-
Fox example, if you want to hide the
|
|
163
|
+
Fox example, if you want to hide the group rows by default, the url will be:
|
|
161
164
|
```
|
|
162
165
|
http://localhost:4909/?hi=on
|
|
163
166
|
```
|
|
@@ -120,16 +120,19 @@ options:
|
|
|
120
120
|
|
|
121
121
|
### web interace
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
Some options are available to customize the UI:
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
* Hide the
|
|
127
|
-
* Hide the
|
|
128
|
-
* Hide the tags
|
|
125
|
+
* Change the strategy to group the requests.
|
|
126
|
+
* Hide the scheme and the network location in the url.
|
|
127
|
+
* Hide the group rows.
|
|
128
|
+
* Hide the tags.
|
|
129
|
+
* ...
|
|
130
|
+
|
|
131
|
+
You can also pin a request or delete all unpinned requests.
|
|
129
132
|
|
|
130
133
|
To keep your configuration, bookmark the page with the full search query.
|
|
131
134
|
|
|
132
|
-
Fox example, if you want to hide the
|
|
135
|
+
Fox example, if you want to hide the group rows by default, the url will be:
|
|
133
136
|
```
|
|
134
137
|
http://localhost:4909/?hi=on
|
|
135
138
|
```
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
from collections.abc import Callable
|
|
2
3
|
from contextlib import contextmanager
|
|
4
|
+
import datetime
|
|
3
5
|
import os
|
|
4
6
|
import platform
|
|
5
7
|
import traceback
|
|
@@ -31,6 +33,7 @@ class Initiator:
|
|
|
31
33
|
self.label = label
|
|
32
34
|
self.short_stack = short_stack
|
|
33
35
|
self.stack = stack
|
|
36
|
+
self.tbegin: datetime.datetime = datetime.datetime.now(datetime.timezone.utc)
|
|
34
37
|
|
|
35
38
|
def __eq__(self, other) -> bool:
|
|
36
39
|
if type(other) is Initiator:
|
|
@@ -49,12 +52,14 @@ class Initiator:
|
|
|
49
52
|
"label": self.label,
|
|
50
53
|
"short_stack": self.short_stack,
|
|
51
54
|
"stack": "\n".join(self.stack),
|
|
55
|
+
"tbegin": self.tbegin.isoformat(),
|
|
52
56
|
}
|
|
53
57
|
else:
|
|
54
58
|
json = {
|
|
55
59
|
"id": self.id,
|
|
56
60
|
"label": self.label,
|
|
57
61
|
"short_stack": self.short_stack,
|
|
62
|
+
"tbegin": self.tbegin.isoformat(),
|
|
58
63
|
}
|
|
59
64
|
return json
|
|
60
65
|
|
|
@@ -64,9 +69,15 @@ class Group:
|
|
|
64
69
|
self.id: str = get_new_uuid()
|
|
65
70
|
self.label: str = label
|
|
66
71
|
self.full_label: str = full_label
|
|
72
|
+
self.tbegin: datetime.datetime = datetime.datetime.now(datetime.timezone.utc)
|
|
67
73
|
|
|
68
74
|
def to_json(self) -> dict:
|
|
69
|
-
return {
|
|
75
|
+
return {
|
|
76
|
+
"id": self.id,
|
|
77
|
+
"label": self.label,
|
|
78
|
+
"full_label": self.full_label,
|
|
79
|
+
"tbegin": self.tbegin.isoformat(),
|
|
80
|
+
}
|
|
70
81
|
|
|
71
82
|
|
|
72
83
|
def compatible_path(path: str) -> str:
|
|
@@ -193,9 +204,13 @@ def extract_short_stack_from_file(
|
|
|
193
204
|
|
|
194
205
|
@contextmanager
|
|
195
206
|
def httpdbg_initiator(
|
|
196
|
-
records
|
|
207
|
+
records: "HTTPRecords",
|
|
208
|
+
extracted_stack: traceback.StackSummary,
|
|
209
|
+
original_method: Callable,
|
|
210
|
+
*args,
|
|
211
|
+
**kwargs,
|
|
197
212
|
) -> Generator[Union[Tuple[Initiator, Group], None], None, None]:
|
|
198
|
-
envname = f"{HTTPDBG_CURRENT_INITIATOR}_{records.id}"
|
|
213
|
+
envname = f"{HTTPDBG_CURRENT_INITIATOR}_{records.session.id}"
|
|
199
214
|
|
|
200
215
|
if not os.environ.get(envname):
|
|
201
216
|
# temporary set a fake initiator env variable to avoid a recursion error
|
|
@@ -5,6 +5,7 @@ import datetime
|
|
|
5
5
|
import os
|
|
6
6
|
import socket
|
|
7
7
|
import ssl
|
|
8
|
+
import sys
|
|
8
9
|
import traceback
|
|
9
10
|
from urllib.parse import urlparse
|
|
10
11
|
from typing import Dict, List, Tuple, Union
|
|
@@ -293,13 +294,21 @@ class HTTPRecord:
|
|
|
293
294
|
return max(self.request.last_update, self.response.last_update)
|
|
294
295
|
|
|
295
296
|
|
|
297
|
+
class HTTPRecordsSessionInfo:
|
|
298
|
+
|
|
299
|
+
def __init__(self):
|
|
300
|
+
self.id: str = get_new_uuid()
|
|
301
|
+
self.command_line: str = " ".join(sys.argv[1:]) if sys.argv[1:] else "console"
|
|
302
|
+
self.tbegin: datetime.datetime = datetime.datetime.now(datetime.timezone.utc)
|
|
303
|
+
|
|
304
|
+
|
|
296
305
|
class HTTPRecords:
|
|
297
306
|
def __init__(self) -> None:
|
|
298
307
|
self.reset()
|
|
299
308
|
|
|
300
309
|
def reset(self) -> None:
|
|
301
310
|
logger().info("HTTPRecords.reset")
|
|
302
|
-
self.
|
|
311
|
+
self.session: HTTPRecordsSessionInfo = HTTPRecordsSessionInfo()
|
|
303
312
|
self.requests: Dict[str, HTTPRecord] = {}
|
|
304
313
|
self.requests_already_loaded = 0
|
|
305
314
|
self.initiators: Dict[str, Initiator] = {}
|
|
@@ -317,7 +326,7 @@ class HTTPRecords:
|
|
|
317
326
|
return len(self.requests)
|
|
318
327
|
|
|
319
328
|
def get_initiator(self) -> str:
|
|
320
|
-
envname = f"{HTTPDBG_CURRENT_INITIATOR}_{self.id}"
|
|
329
|
+
envname = f"{HTTPDBG_CURRENT_INITIATOR}_{self.session.id}"
|
|
321
330
|
|
|
322
331
|
if envname in os.environ:
|
|
323
332
|
initiator = self.initiators[os.environ[envname]]
|
|
@@ -3,6 +3,7 @@ from json import JSONEncoder
|
|
|
3
3
|
import traceback
|
|
4
4
|
from typing import Any
|
|
5
5
|
from typing import Dict
|
|
6
|
+
from typing import Union
|
|
6
7
|
|
|
7
8
|
from httpdbg.records import HTTPRecords
|
|
8
9
|
from httpdbg.records import HTTPRecord
|
|
@@ -65,13 +66,17 @@ class RequestPayload(JSONEncoder):
|
|
|
65
66
|
|
|
66
67
|
|
|
67
68
|
class RequestListPayload(JSONEncoder):
|
|
68
|
-
def default(self, records):
|
|
69
|
+
def default(self, records: HTTPRecords):
|
|
69
70
|
assert isinstance(
|
|
70
71
|
records, HTTPRecords
|
|
71
72
|
), "This encoder works only for HTTPRecords object."
|
|
72
73
|
|
|
73
|
-
payload = {
|
|
74
|
-
"
|
|
74
|
+
payload: Dict[str, Dict[str, Union[str, dict]]] = {
|
|
75
|
+
"session": {
|
|
76
|
+
"id": records.session.id,
|
|
77
|
+
"command_line": records.session.command_line,
|
|
78
|
+
"tbegin": records.session.tbegin.isoformat(),
|
|
79
|
+
},
|
|
75
80
|
"requests": {},
|
|
76
81
|
"initiators": {},
|
|
77
82
|
"groups": {},
|
|
@@ -11,6 +11,7 @@ from urllib.parse import urlparse, parse_qs
|
|
|
11
11
|
from httpdbg import __version__
|
|
12
12
|
from httpdbg.log import logger
|
|
13
13
|
from httpdbg.webapp.api import RequestListPayload, RequestPayload
|
|
14
|
+
from httpdbg.records import HTTPRecords
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
@contextmanager
|
|
@@ -22,7 +23,10 @@ def silently_catch_error():
|
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
25
|
-
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self: "HttpbgHTTPRequestHandler", records: HTTPRecords, *args, **kwargs
|
|
29
|
+
):
|
|
26
30
|
self.records = records
|
|
27
31
|
super().__init__(*args, **kwargs)
|
|
28
32
|
|
|
@@ -42,7 +46,7 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
42
46
|
if serve(url):
|
|
43
47
|
break
|
|
44
48
|
|
|
45
|
-
def serve_static(self, url):
|
|
49
|
+
def serve_static(self: "HttpbgHTTPRequestHandler", url):
|
|
46
50
|
base_path = os.path.dirname(os.path.realpath(__file__))
|
|
47
51
|
|
|
48
52
|
if not (
|
|
@@ -99,13 +103,13 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
99
103
|
|
|
100
104
|
return True
|
|
101
105
|
|
|
102
|
-
def serve_requests(self, url):
|
|
106
|
+
def serve_requests(self: "HttpbgHTTPRequestHandler", url):
|
|
103
107
|
if not (url.path.lower() == "/requests"):
|
|
104
108
|
return False
|
|
105
109
|
|
|
106
110
|
query = parse_qs(url.query)
|
|
107
111
|
|
|
108
|
-
if query.get("id", [""])[0] == self.records.id:
|
|
112
|
+
if query.get("id", [""])[0] == self.records.session.id:
|
|
109
113
|
self.records.requests_already_loaded = int(
|
|
110
114
|
query.get("requests_already_loaded", [0])[0]
|
|
111
115
|
)
|
|
@@ -122,7 +126,7 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
122
126
|
|
|
123
127
|
return True
|
|
124
128
|
|
|
125
|
-
def serve_request(self, url):
|
|
129
|
+
def serve_request(self: "HttpbgHTTPRequestHandler", url):
|
|
126
130
|
regexp = r"/request/([\w\-]+)"
|
|
127
131
|
|
|
128
132
|
if re.fullmatch(regexp, url.path) is None:
|
|
@@ -145,7 +149,7 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
145
149
|
|
|
146
150
|
return True
|
|
147
151
|
|
|
148
|
-
def serve_request_content_up(self, url):
|
|
152
|
+
def serve_request_content_up(self: "HttpbgHTTPRequestHandler", url):
|
|
149
153
|
regexp = r"/request/([\w\-]+)/up"
|
|
150
154
|
|
|
151
155
|
if re.fullmatch(regexp, url.path) is None:
|
|
@@ -162,15 +166,11 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
162
166
|
self.send_header("Content-type", "application/octet-stream")
|
|
163
167
|
self.send_header_no_cache()
|
|
164
168
|
self.end_headers()
|
|
165
|
-
self.wfile.write(
|
|
166
|
-
req.request.content.encode("utf-8")
|
|
167
|
-
if isinstance(req.request.content, str)
|
|
168
|
-
else req.request.content
|
|
169
|
-
)
|
|
169
|
+
self.wfile.write(req.request.content)
|
|
170
170
|
|
|
171
171
|
return True
|
|
172
172
|
|
|
173
|
-
def serve_request_content_down(self, url):
|
|
173
|
+
def serve_request_content_down(self: "HttpbgHTTPRequestHandler", url):
|
|
174
174
|
regexp = r"/request/([\w\-]+)/down"
|
|
175
175
|
|
|
176
176
|
if re.fullmatch(regexp, url.path) is None:
|
|
@@ -191,7 +191,7 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
191
191
|
|
|
192
192
|
return True
|
|
193
193
|
|
|
194
|
-
def serve_not_found(self, *kwargs):
|
|
194
|
+
def serve_not_found(self: "HttpbgHTTPRequestHandler", *kwargs):
|
|
195
195
|
self.send_response(404)
|
|
196
196
|
self.send_header_no_cache()
|
|
197
197
|
self.end_headers()
|
|
@@ -199,11 +199,11 @@ class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
|
199
199
|
|
|
200
200
|
return True
|
|
201
201
|
|
|
202
|
-
def log_message(self, format, *args):
|
|
202
|
+
def log_message(self: "HttpbgHTTPRequestHandler", format, *args):
|
|
203
203
|
pass
|
|
204
204
|
|
|
205
205
|
def send_header_no_cache(self):
|
|
206
206
|
self.send_header("Cache-Control", "max-age=0, no-cache, no-store, private")
|
|
207
207
|
|
|
208
|
-
def send_header_with_cache(self, seconds):
|
|
208
|
+
def send_header_with_cache(self: "HttpbgHTTPRequestHandler", seconds):
|
|
209
209
|
self.send_header("Cache-Control", f"max-age={seconds}")
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const global = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
session: null,
|
|
5
|
+
sessions: {},
|
|
6
|
+
requests: {},
|
|
7
|
+
initiators: {},
|
|
8
|
+
groups: {},
|
|
9
|
+
connected: false,
|
|
10
|
+
group_collapse: [],
|
|
11
|
+
groupby: "default"
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
function save_request(request_id, request) {
|
|
14
|
+
function save_request(request_id, request, session_id) {
|
|
13
15
|
request.loaded = false;
|
|
14
16
|
request.to_refresh = true;
|
|
15
17
|
if (request.pin == undefined) {
|
|
@@ -18,26 +20,27 @@ function save_request(request_id, request) {
|
|
|
18
20
|
if (request.filter == undefined) {
|
|
19
21
|
request.filter = "---";
|
|
20
22
|
}
|
|
21
|
-
|
|
23
|
+
request.session_id = session_id;
|
|
24
|
+
request.initiator = global.initiators[request.initiator_id];
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (global.requests[request_id].in_progress) {
|
|
26
|
-
global.requests[request_id].status_code_view = '<img class="icon" src="static/icons/wait-sandclock-icon.svg-+-$**HTTPDBG_VERSION**$" alt="loading"/>';
|
|
26
|
+
if (request.in_progress) {
|
|
27
|
+
request.status_code_view = '<img class="icon" src="static/icons/wait-sandclock-icon.svg-+-$**HTTPDBG_VERSION**$" alt="loading"/>';
|
|
27
28
|
} else {
|
|
28
|
-
switch (
|
|
29
|
+
switch (request.status_code) {
|
|
29
30
|
case 0:
|
|
30
|
-
|
|
31
|
+
request.status_code_view = '<img class="icon" src="static/icons/wait-sandclock-icon.svg-+-$**HTTPDBG_VERSION**$/" alt="loading"/>';
|
|
31
32
|
break;
|
|
32
33
|
case -1:
|
|
33
|
-
|
|
34
|
+
request.status_code_view = '<img class="icon" src="static/icons/math-multiplication-icon.svg-+-$**HTTPDBG_VERSION**$/" alt="load failed"/>';
|
|
34
35
|
break;
|
|
35
36
|
default:
|
|
36
|
-
|
|
37
|
+
request.status_code_view = request.status_code;
|
|
37
38
|
break;
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
global.requests[request_id] = request;
|
|
43
|
+
|
|
41
44
|
if (!request.pin) {
|
|
42
45
|
get_request(request_id);
|
|
43
46
|
}
|
|
@@ -47,12 +50,12 @@ async function get_all_requests() {
|
|
|
47
50
|
|
|
48
51
|
var requests_already_loaded = 0
|
|
49
52
|
for (const [request_id, request] of Object.entries(global.requests)) {
|
|
50
|
-
if (request.loaded) {
|
|
53
|
+
if (request.loaded && (global.session == request.session_id)) {
|
|
51
54
|
requests_already_loaded += 1;
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
var url = "/requests?" + new URLSearchParams({
|
|
55
|
-
"id": global.
|
|
58
|
+
"id": global.session,
|
|
56
59
|
"requests_already_loaded": requests_already_loaded,
|
|
57
60
|
})
|
|
58
61
|
|
|
@@ -61,9 +64,10 @@ async function get_all_requests() {
|
|
|
61
64
|
.then(data => {
|
|
62
65
|
global.connected = true;
|
|
63
66
|
|
|
64
|
-
if (data.id != global.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
if (data.session.id != global.session) {
|
|
68
|
+
clean();
|
|
69
|
+
global.session = data.session.id;
|
|
70
|
+
global.sessions[data.session.id] = data.session;
|
|
67
71
|
};
|
|
68
72
|
|
|
69
73
|
// for the initiators and the groups, we can just save them without any verification
|
|
@@ -74,11 +78,11 @@ async function get_all_requests() {
|
|
|
74
78
|
for (const [request_id, request] of Object.entries(data.requests)) {
|
|
75
79
|
if (!(request_id in global.requests)) {
|
|
76
80
|
// this is a new request
|
|
77
|
-
save_request(request_id, request);
|
|
81
|
+
save_request(request_id, request, data.session.id);
|
|
78
82
|
} else {
|
|
79
83
|
if (global.requests[request_id].last_update < request.last_update) {
|
|
80
84
|
// this request has been updated (probably a "big" file)
|
|
81
|
-
save_request(request_id, request);
|
|
85
|
+
save_request(request_id, request, data.session.id);
|
|
82
86
|
}
|
|
83
87
|
};
|
|
84
88
|
};
|
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
function config() {
|
|
4
|
-
if (document.getElementById("configuration").style.display == "block") {
|
|
5
|
-
document.getElementById("configuration").style.display = "none";
|
|
6
|
-
} else {
|
|
7
|
-
document.getElementById("configuration").style.display = "block";
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
3
|
function apply_config_rule_css(a_config, sheet) {
|
|
12
|
-
document.getElementById(a_config.
|
|
4
|
+
document.getElementById(a_config.id).checked = a_config.value;
|
|
13
5
|
if (a_config.value) {
|
|
14
6
|
sheet.insertRule(a_config.css);
|
|
15
7
|
}
|
|
16
8
|
}
|
|
17
9
|
|
|
18
10
|
function apply_config_rule_click(a_config) {
|
|
19
|
-
document.getElementById(a_config.
|
|
11
|
+
document.getElementById(a_config.id).checked = a_config.value;
|
|
20
12
|
document.getElementsByName(a_config.elt_name).forEach(element => {
|
|
21
13
|
if (element.checked != a_config.value) {
|
|
22
14
|
element.click();
|
|
@@ -25,6 +17,14 @@ function apply_config_rule_click(a_config) {
|
|
|
25
17
|
|
|
26
18
|
}
|
|
27
19
|
|
|
20
|
+
function apply_config_rule(a_config, sheet) {
|
|
21
|
+
document.getElementById(a_config.id).checked = a_config.value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function apply_config_rule_select(a_config, sheet) {
|
|
25
|
+
document.getElementById(a_config.id).value = a_config.value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
28
|
function apply_config() {
|
|
29
29
|
var sheet = document.getElementById("configurationcss").sheet;
|
|
30
30
|
|
|
@@ -32,6 +32,10 @@ function apply_config() {
|
|
|
32
32
|
sheet.deleteRule(0);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
apply_config_rule(httpdbgApp.config.keep_previous_sessions);
|
|
36
|
+
|
|
37
|
+
apply_config_rule_select(httpdbgApp.config.group_by);
|
|
38
|
+
|
|
35
39
|
apply_config_rule_css(httpdbgApp.config.hide_netloc, sheet);
|
|
36
40
|
apply_config_rule_css(httpdbgApp.config.hide_group, sheet);
|
|
37
41
|
apply_config_rule_css(httpdbgApp.config.hide_tag, sheet);
|
|
@@ -41,12 +45,18 @@ function apply_config() {
|
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
function load_config_rule_from_url(a_config, params) {
|
|
44
|
-
|
|
48
|
+
if (a_config.type === "select") {
|
|
49
|
+
a_config.value = params.get(a_config.param) || "default";
|
|
50
|
+
} else {
|
|
51
|
+
a_config.value = (params.get(a_config.param) || "off") == "on";
|
|
52
|
+
}
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
function load_config_from_url(apply) {
|
|
48
56
|
const params = new URLSearchParams(window.location.search);
|
|
49
57
|
|
|
58
|
+
load_config_rule_from_url(httpdbgApp.config.keep_previous_sessions, params);
|
|
59
|
+
load_config_rule_from_url(httpdbgApp.config.group_by, params);
|
|
50
60
|
load_config_rule_from_url(httpdbgApp.config.hide_netloc, params);
|
|
51
61
|
load_config_rule_from_url(httpdbgApp.config.hide_group, params);
|
|
52
62
|
load_config_rule_from_url(httpdbgApp.config.hide_tag, params);
|
|
@@ -59,12 +69,18 @@ function load_config_from_url(apply) {
|
|
|
59
69
|
}
|
|
60
70
|
|
|
61
71
|
function load_config_rule_from_form(a_config) {
|
|
62
|
-
a_config.
|
|
72
|
+
if (a_config.type === "select") {
|
|
73
|
+
a_config.value = document.getElementById(a_config.id).value;
|
|
74
|
+
} else {
|
|
75
|
+
a_config.value = document.getElementById(a_config.id).checked;
|
|
76
|
+
}
|
|
63
77
|
}
|
|
64
78
|
|
|
65
79
|
function load_config_from_form(apply) {
|
|
66
80
|
const params = new URLSearchParams(window.location.search);
|
|
67
81
|
|
|
82
|
+
load_config_rule_from_form(httpdbgApp.config.keep_previous_sessions);
|
|
83
|
+
load_config_rule_from_form(httpdbgApp.config.group_by);
|
|
68
84
|
load_config_rule_from_form(httpdbgApp.config.hide_netloc);
|
|
69
85
|
load_config_rule_from_form(httpdbgApp.config.hide_group);
|
|
70
86
|
load_config_rule_from_form(httpdbgApp.config.hide_tag);
|
|
@@ -74,14 +90,12 @@ function load_config_from_form(apply) {
|
|
|
74
90
|
if (apply) {
|
|
75
91
|
apply_config();
|
|
76
92
|
}
|
|
93
|
+
|
|
94
|
+
save_config_to_url();
|
|
77
95
|
}
|
|
78
96
|
|
|
79
|
-
function save_config_to_url(
|
|
97
|
+
function save_config_to_url() {
|
|
80
98
|
const formData = new FormData(document.forms[0]);
|
|
81
99
|
const params = (new URLSearchParams(formData)).toString();
|
|
82
100
|
history.replaceState("", "", "?" + params)
|
|
83
|
-
|
|
84
|
-
if (hide_config_panel) {
|
|
85
|
-
config();
|
|
86
|
-
}
|
|
87
101
|
}
|