1.0.0 reworks the keyword surface once, deliberately, and then freezes it: from this
release onwards keyword names, argument names and their order will not change within 1.x.
See "API stability" in the README.
Changed - breaking
Every kind of manipulation used to have its own list, its own remove keyword and its own
log keyword, and the blocklist had no alias at all. They are now one rule model, which
means one way to address a rule, the same matching options everywhere, and a defined order
when several rules match the same request. Migrating is a rename plus, for blocking, an
alias:
| Before | Now |
|---|---|
Add To Blocklist url |
Block Requests alias url |
Add Custom Response alias url overwrite_headers= overwrite_body= |
Set Response alias url headers= body= |
Add Custom Response Status Code alias url status_code |
Set Response Status alias url status_code |
Remove Url From Blocklist url |
Remove Rule alias |
Remove Custom Response alias |
Remove Rule alias |
Remove Custom Status Code alias |
Remove Rule alias |
Clear All Proxy Items |
Clear All Rules |
Log Blocked Urls, Log Delayed Responses, Log Custom Response Items, Log Custom Status Items |
Log Proxy Rules |
Add Response Delay keeps its name and arguments.
Two behaviour changes come with it:
- A blocked request is answered with
403instead of having its connection dropped.
The documentation always said it was a 403; the code killed the connection. Answering
is now the default because every HTTP client reports it the same way, where a dropped
connection surfaces as a different exception in each of them. Passmode=RESETfor the
old behaviour. - All matching rules are applied, in a defined order. A blocking rule ends the
request and nothing after it runs. OtherwiseSet Responseruns before rules that
change part of a response, which run before delays, and delays add up. Previously a
later custom response could silently throw away an earlier status change.
Added
-
Every rule keyword takes
method,matchandtimes.matchisSUBSTRING(the
default, and what the library did before),REGEXorGLOB.methodrestricts a rule
to one HTTP method.timeslimits how often a rule may be applied, and an exhausted
rule stays visible inGet Proxy Ruleswithremaining=0rather than disappearing.
An unusable regular expression fails the keyword that configured it, not the proxy
later. -
Request-side manipulation, which the library could not do at all before: it could
change what came back but never what was sent.Set Request HeadersandSet Response Headersset and remove named headers,
merging rather than replacing, so adding one header does not mean restating the
others.Set Request BodyandSet Response Bodyreplace a body and update its
content-lengthto match.Rewrite Request Urlsends a request to a different url entirely.Redirect Requests To Hostsends it to a different host, keeping the path and
query, and updates theHostheader so the receiving server is addressed by a name
it answers to.
-
Traffic can be recorded and asserted on, which the library could not do at all before:
it could change what came back but never report what the application actually sent.
Start Recording, orrecord=TrueonStart Mitm Proxy, turns it on, and
Get Recorded Requests,Get Request Count,Request Should Have Been Made,
Request Should Not Have Been MadeandWait Until Request Is Madeask about it.
Recording is off by default and capped in two directions - how many requests are kept
and how many bytes of each body - so a long run does not quietly grow without limit.
When the first cap is reached the oldest request is dropped and the number dropped is
reported in assertion failures rather than hidden, so an assertion against a shortened
recording cannot look complete. Requests that failed are recorded too, so a blocked
call can be asserted on. -
Start Mitm Proxytakesmode, so the proxy can be something other than a forward
proxy:reverse:puts it in front of one server, so a client needs no proxy settings
at all;upstream:sends everything on through another proxy, which is what a
corporate network needs;transparentandsocks5are passed through as well. A mode
that cannot be understood fails the keyword with mitmproxy's own explanation, rather
than leaving the proxy to fail to start for an unstated reason. -
Start Mitm Proxytakesproxy_auth, requiring clients to authenticate before the
proxy serves them. -
Failure simulation, for the paths an application exercises least.
Simulate Timeout
holds a request and then drops it without contacting the server, which is what a client
sees when a service accepts a connection and says nothing - a different test from a
service that answers with an error.Simulate Truncated Responsecuts an answer short
while it still claims its full length, which is what a connection dropped mid-answer
looks like. A dropped connection isBlock Requestswithmode=RESETrather than a
keyword of its own.Bandwidth throttling is deliberately not supported: mitmproxy hands a response body to
a synchronous callback with no way to wait between chunks, so the only implementable
version would delay the whole body and deliver it in one piece, which is
Add Response Delayunder a name that would promise more than it does. -
Get Proxy Rulesreturns the loaded rules in the order they are applied. -
Blocking rules have an alias, like every other rule, so they are removed the same way.
-
Rules survive a restart of the proxy: the registry outlives it, and only the addon
reading it is rebuilt. -
Get Proxy Addressreturns the host, port and url the proxy is actually listening on.
It reads the address from the running proxy rather than echoing back the arguments,
which is what makeslisten_port=0usable: the operating system picks a free port and
this keyword reports which one, so suites can run in parallel without agreeing on a
port in advance. -
The proxy is released when the suite that started it ends, even if the suite never
calledStop Mitm Proxy. A forgotten teardown used to leave the port bound for the
rest of the run, failing the next suite that wanted it. -
The package now ships a
py.typedmarker, so type checkers in projects that depend on
MitmLibrary use its annotations instead of treating it as untyped.
Fixed
- A proxy no longer dies because something unrelated logged an error. mitmproxy's
errorcheckaddon watches the root logger and exits the process when an error was
logged while a master starts, which in a library means a proxy could be killed by a
message from a proxy that had already stopped. The addon is now removed; startup
failures were already detected separately, and are reported with their own reason. - A proxy that fails to start no longer leaves its request logger behind, where the next
keyword would have used it while no proxy was running.
Changed
- The proxy lifecycle moved to
MitmLibrary.proxy_controller, which is now the only
module that reaches into mitmproxy's internals. This is internal, but it does move
MitmLibrary.STARTUP_TIMEOUTandMitmLibrary.SHUTDOWN_TIMEOUTto that module.