test/helper_tools/gen_sample_flows.py writes a flow file with one flow per type and state the mitmweb flow table can display, including the TCP, UDP, DNS and QUIC flows a regular HTTP proxy never sees.
This makes it possible to eyeball the whole table without having to capture the traffic first.
Passing --upload pushes the flows into a running mitmweb instead of writing a file.
* net.tls: handle SSL.Error from set_min/max_proto_version in is_supported_version
is_supported_version() built an SSL.Context, set the min/max protocol
version, then probed support with client_conn.recv(). Only the recv()
probe was wrapped in try/except SSL.Error.
On OpenSSL builds that have dropped a protocol version entirely (e.g.
SSLv3 after POODLE / CVE-2014-3566, see pyca/cryptography#9523),
set_min_proto_version(SSL3_VERSION) raises SSL.Error already at
context-setup time, before the guarded recv(). The exception then
propagated unhandled and crashed callers such as
TlsConfig._warn_unsupported_version, which iterates over every Version to
build the "supported versions" list.
Move the protocol-version setters and connection setup inside the
existing try, so a setup-time SSL.Error is treated the same as a
probe-time one: the version is reported as unsupported (return False)
instead of raising. Behavior for currently-supported versions is
unchanged.
Add a regression test that monkeypatches SSL.Context.set_min_proto_version
to raise SSL.Error, reproducing the crash path deterministically on any
OpenSSL build, and clear the is_supported_version LRU cache around it.
Closes#8264
* Remove test for SSL context setup error handling
---------
Co-authored-by: Maximilian Hils <git@maximilianhils.com>
The Windows installation instructions only pointed at the installer and
standalone binaries from mitmproxy.org, even though every release is also
published to the Microsoft Store by CI (release/deploy-microsoft-store.py).
Refs #6053.
* feat(web): replace flow table resource icons with lucide SVGs
The resource type icons were 32x32 PNGs, so they could not be recolored and stayed dark against the dark theme's background.
The SVG icons inherit currentColor and follow the active theme.
getIcon becomes getResourceType and returns a semantic resource type rather than a CSS class name, which keeps the icon choice in the view layer and out of the column's sort key.
Removing the last raster icons also drops the Chromium BSD notice that only covered the four DevTools PNGs.
* refactor(web): size flow rows from the rowHeight prop
Flow rows were 32px tall only as a side effect of the 32x32 icon bitmap, which the virtual scroller's hardcoded rowHeight silently depended on.
Pinning the height in CSS would have restated that number in a second place and would still break for any caller overriding the prop, so rows now take their height from rowHeight directly.
This also stops rows collapsing when the icon column is hidden via web_columns.
* docs(web): drop redundant comments on rowHeight and getResourceType
* docs: tighten the changelog entry for the SVG resource icons
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* feat(web): add status/method badges and flow-table tooltips
Replace the inline-colored status text with a colored status-code badge and render the request method as an outlined badge.
Both reuse the semantic state tokens, so they follow the dark theme automatically.
Add hover tooltips (via a new optional Icon `title` prop and a title on the TLS cell) to the TLS, replay, intercept, and error indicators.
Part of #7789.
* feat(web): tone down solid state fills in the dark theme
Add a soft variant of the state palette (`--mitmweb-<state>-soft-bg`/`-fg`) and use it for the status badges and the footer option labels.
A saturated fill glares against a dark surface once it is repeated across every row, so the soft fill sinks towards the background and the label text carries the hue.
The solid tokens stay vivid for the header connection label and `.btn-info`, which appear one at a time and are meant to draw the eye.
Light values alias the existing solid colors, so the light theme is unchanged.
* feat(web): drop the now-unused status-code color tokens
The status column renders a badge that reuses the semantic state tokens, so nothing consumes --mitmweb-status-1xx…5xx/-other any more.
* [autofix.ci] apply automated fixes
* refactor(web): unify the status and method badges into one component
The two components differed only in styling, so a single presentational Badge in common/ now carries the shared class and callers pass the variant class.
statusClass moves to flow/utils next to statusCode, mirroring getIcon which likewise returns a CSS class.
* fix(web): give the status and method badges the same height
The two badges sized themselves from their own font size, padding and border, so the outlined method badge came out about a pixel shorter than the filled status badge.
A fixed height on the shared base plus a transparent border makes the box identical regardless of the variant.
* fix(web): widen the status column so DNS codes fit
The badge's padding and border pushed word-shaped DNS response codes such as NOERROR past the 60px cell, where the table's overflow rule clipped them.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* fix(web): theme the sorted flow table header
The sorted column header and its chevron mask were the only colors left as literals after the semantic token layer landed, because LESS `lighten`/`fadeout` cannot operate on `var()`.
In dark mode this painted the sorted `th` near-white and hid the chevron, which is stroked in `--mitmweb-fg`, against its own mask.
Both now read `--mitmweb-th-sorted-bg`, with the mask deriving its alpha through `color-mix` instead.
The light value is byte-equal to what `lighten(#f2f2f2, 3%)` produced, so the light theme is unchanged.
No LESS color functions remain in the stylesheets, so the note about them in the token header comment goes away too.
* docs: add changelog entry for the sorted flow table header fix
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* feat(web): add dark theme and web_theme option
Add a `web_theme` mitmweb option (system/dark/light; default system) and apply it in the frontend by setting `data-theme` on the document root.
`system` follows the OS `prefers-color-scheme` and tracks live changes.
The dark palette overrides the semantic color tokens under `[data-theme="dark"]`, with targeted overrides for surfaces whose colors are consumed by LESS functions.
The CodeMirror content editor switches to the one-dark theme in dark mode.
Part of #7789.
* fix(web): theme native form controls for dark mode
Native selects, inputs, checkboxes and scrollbars ignored the semantic tokens and rendered with the browser's light defaults.
Set color-scheme per theme so they follow it, and replace the remaining literal black text colors on the local-applications input and the close-button hover states with tokens.
* fix(web): make search and close icons legible in dark mode
The search filter icon and the eventlog/flow-detail close icons were hardcoded to black/grey, which is hard to read on dark surfaces.
Route them through the foreground tokens instead.
* [autofix.ci] apply automated fixes
* fix(web): theme header and tab separators for dark mode
The header, nav-tab, and menu-group separator borders were computed with lighten(grey, ...), leaving them as bright literals that stayed light-grey on dark surfaces.
Route them through the border tokens instead so they follow the theme.
* feat(web): add a theme selector to the Options menu
The web_theme option was only reachable by scrolling to the bottom of the raw options list in the Edit Options modal.
Surface it as an Appearance dropdown (system/dark/light) in the header Options menu so the theme is discoverable and switchable in one click.
* refactor(web): drop the dark flow table rule override
The base branch tokenized every flow table row color, so the nested .flow-table tr block in the dark theme now duplicates rules that var() already resolves.
Override the --mitmweb-row-* tokens instead.
Base rows fall through to --mitmweb-bg / --mitmweb-bg-alt like they do in the light theme, rather than carrying their own near-identical literals.
* fix(web): give row hover a dark highlight color
--mitmweb-highlight kept its light value in dark mode, compositing a pale blue over the dark surface and leaving hovered header rows and command suggestions hard to read.
* fix(web): darken the first-line banner in dark mode
The request/response first line reused --mitmweb-accent, which is brightened for dark surfaces and left white monospace text at roughly 2.5:1 contrast.
Give the banner its own token pair so dark mode can use a deep blue with pale text without dragging the accent color along.
* fix(web): make status codes legible in dark mode
The status column painted itself with hardcoded CSS color names.
`darkgreen` and `darkred` are near-invisible against the dark surface, so route the colors through per-class tokens instead.
Light values are byte-equal to the literals they replace.
The shadow token added alongside them is consumed in the next commit.
* fix(web): stop footers casting a light halo in dark mode
Both footer shadows were hardcoded to a light gray, which on a dark surface reads as a thick white border rather than a shadow.
Route them through the shadow token so the dark theme casts black instead.
* fix(web): dim OS-supplied app icons in dark mode
The executable icons in the local-applications dropdown come from the OS as bitmaps, so we cannot recolor them.
macOS hands back a plain white square for the generic executable, which glares against the dark popover.
Dim them via a token so the white square reads as grey while colored app icons stay recognizable.
* fix(web): stop idle scrollbars showing as stray lines in dark mode
Panes such as the flow table reserve a scrollbar gutter permanently via `overflow-y: scroll`.
Under `color-scheme: dark` the UA paints that gutter light, so an idle scrollbar reads as a stray vertical line beside the pane divider rather than as a scrollbar.
Color the track to match the surface so it stays as invisible as it already is on light backgrounds.
* fix(web): blend the process-filter input into its dark header
Under color-scheme: dark the browser paints the native text field a lighter grey than the transparent dropdown header around it, so the input read lighter than the chevron beside it.
Making the field background transparent lets it blend with the header.
* fix(web): make the filter-docs row hover visible in dark mode
The dark highlight token was barely distinguishable from the popover surface, so a hovered suggestion row read as unhighlighted.
Brightening it makes the hovered row stand out.
The command-bar suggestion highlight shares this token and gains the same visibility.
* test(web): cover theme selector and status column colors
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* feat(web): add semantic CSS custom-property color layer
Introduce a :root set of semantic color tokens (surfaces, text, borders, accent, state) in global.less and route the recurring, directly-used colors across the LESS files through them.
Light-mode values are byte-equal to the literals they replace, so this is a visual no-op; it exists to give a future dark theme a single place to override.
Colors that LESS functions (lighten/darken/fadeout) consume, and one-off decorative colors, are intentionally left as literals because those functions cannot operate on var().
Part of #7789.
* [autofix.ci] apply automated fixes
* refactor(web): route remaining hardcoded colors through color tokens
Route the remaining directly-used background, text, and border literals across the LESS files through the existing semantic tokens introduced in the color layer, reusing tokens rather than adding new ones.
Light-mode colors stay visually unchanged; one-off decorative colors and LESS-function inputs are left as literals.
* refactor(web): tokenize recurring colors and drop dead styles
Add a --mitmweb-highlight token for the shared row-hover / suggestion-selection color (used in header.less and command.less) and a --mitmweb-gray token for the neutral gray reused across mode.less.
Remove the unused .command-suggestion rule and the dead rgba() border fallback in dropdown.less, which was overriding the tokenized border and rendering as translucent black.
* refactor(web): use the accent token for the first line and special tab
Replace the near-accent literals #428bca (flow detail first line) and #396cad (special tab) with --mitmweb-accent so the accent lives in exactly one place.
Both were within a few percent of the token, so this is a small deliberate light-theme shift rather than a visual no-op.
The special tab derived its hover from lighten(@special-color, 10%); since LESS functions cannot operate on var(), it now uses --mitmweb-accent-active, the same hover shade .btn-primary already uses.
* refactor(web): tokenize the mode green left border
Add a --mitmweb-green token for the #77c77a left border in mode.less, mirroring the --mitmweb-gray token already used by the neighbouring .gray-left-border.
* refactor(web): tokenize flow table row state colors
Add --mitmweb-row-* tokens for the highlighted, selected, and selected+highlighted row shades and route flowtable.less through them.
The base rows reuse the existing --mitmweb-bg / --mitmweb-bg-alt surfaces, whose values are byte-equal to the hsl() literals they replace.
Values are unchanged, so this is a visual no-op; it gives the dark theme one place to override the row states.
* docs: drop the changelog entry for the CSS color token layer
The entry conflicts with the upstream CHANGELOG.md on the PR.
Removing it for now; the entry will be re-added once the branch is rebased.
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
If allow_hosts or ignore_hosts was set, any QUIC connections would stall
forever after TLS handshake and never get assigned an HttpLayer or e.g.
appear in the flow list in mitmweb. The codepath goes like this:
1. After client TLS handshake completes, next layer hook is invoked with
data_client = b'', i.e. the data so far inside the QUIC stream
2. _next_layer first checks using _ignore_connection
3. _ignore_connection uses _get_client_hello, passing b'' data_client
4. quick_parse_client_hello_from_datagram raises a type of ValueError
because b'' is definitely not a valid QUIC packet
5. ValueError is skipped, so dtls_parse_client_hello is tried, which
also raises a type of ValueError for about the same reason
6. This is now converted into NeedsMoreData, which bails out of the
entire _next_layer process.
This repeats each time next_layer is called and never makes progress,
even if data is read on the QUIC stream, it's still not going to be a
valid QUIC or DTLS packet.
This fix matches the tcp case and only tries to parse the packet as quic
or dtls if it heuristically looks like that.
* proxy: bracket IPv6 literals in upstream CONNECT authority
When mitmproxy runs in upstream mode and the target server is an IPv6
literal, the CONNECT request and Host header sent to the upstream proxy
built the authority as `host:port` without bracketing the address, e.g.
`CONNECT 2001:db8::1:443` / `Host: 2001:db8::1:443`. That is a malformed
authority per RFC 3986 §3.2.2 / RFC 7230 §5.4, and downstream proxies
(e.g. Burp) reject it as an unparseable CONNECT target.
Bracket IPv6 literals so the authority is `[2001:db8::1]:443`. Hostnames
(still IDNA-encoded) and IPv4 addresses are unchanged.
Closes#8309
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* fix(web): avoid infinite componentDidUpdate loop in the event log
EventList.componentDidUpdate called this.onViewportUpdate() on every
update, even when the inputs to calcVScroll (the event list and the row
height) had not changed. onViewportUpdate reads the current scroll
position, recomputes vScroll, and setStates when the window shape
changes. Because the event log measures per-row heights, a setState it
produced could feed itself: rendering a new window remeasured rows,
which shifted the computed window, which setState again, so the cycle
never converged and surfaced as "Maximum update depth exceeded" while
scrolling the log.
Gate the call on prevProps.events !== this.props.events ||
prevProps.rowHeight !== this.props.rowHeight, mirroring the FlowTable fix
in #8233. The other call sites (componentDidMount, the resize listener,
the viewport onScroll, and setHeight when a row is first measured) still
drive updates as needed, so scrolling and autoscroll keep working.
Adds a regression test that fails without the gate.
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Hils <git@maximilianhils.com>
The msgpack contentview was rewritten in Rust and moved to mitmproxy_rs
in #7623, which deleted the only import of the msgpack package. The
pyproject entry survived, and the dependency-bump automation has been
dutifully maintaining the dead dependency ever since, most recently
resolving msgpack 1.1.2 in uv.lock. Dropping it removes a C-extension
wheel from every install, and users lose nothing because the Rust
contentview still provides msgpack rendering.
Discovered using `pyproject-udeps` [[1]].
[1]: https://github.com/lukehsiao/pyproject-udeps
Fixes: d0a35dcf9b ("introduce new contentview API (#7623)")
* mitmweb: honor view_order_reversed for live flows
mitmweb only applied view_order_reversed to the initial flow list it
fetches over HTTP. Flows delivered afterwards over the WebSocket were
always appended to the end of the table, so with the option enabled the
newest flow stayed off-screen at the bottom instead of appearing on top.
Track the option in the flows reducer and, when no column sort is active,
insert newly added flows at the front when view_order_reversed is set and
at the back otherwise. This matches the order the server already uses for
the initial list.
Closes#5520
* [autofix.ci] apply automated fixes
* mitmweb: destructure orderReversed in flows reducer for consistency
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>