Unable to change hosts if SSL is involved

I’ve been trying to redirect specific urls from one host to another based on changes in the path. And for the most part, this works great when doing this over plain http.

def request(context, flow):
    if 'www.host.com/api/v2' in flow.request.url:
        flow.request.url = flow.request.url.replace('www.host.com', 'new_host.com')
        flow.request.host = 'new_host.com'
        flow.request.headers['Host'] = 'new_host.com'

However, if the requested traffic happens over TLS, I can’t seem to get the above to work. I can shape the traffic by changing the path and payload just fine, but I can’t switch servers.

I suspect it’s because the connection to the original server via TLS has already been established, but I’m unsure how to change this at the request hook when I know what the path to the request is.

Hi @ffernand,

Thanks for the report. Can you still reproduce the issue if you pass --no-http2 to mitmproxy?

Hi @mhils,

I can still reproduce the issue with the --no-http2 option. It just stalls on the request for a while before throwing the error…

Server connection to app.dev:443 failed: Error connecting to "app.dev": [Errno 110] Connection timed out

It doesn’t matter if I adjust the target host scheme to use http or https either (I’ve tried both).

As with the original message, if the source host scheme is plain http, it works without issue. To be clear, proxying requests on either host name (without trying to redirect request from one host to another) via mitmproxy and using TLS is no problem.

I should note that I’m currently running on Ubuntu 14.04 with mitmproxy 0.17

Much appreciated for your help!

Now this error message makes it a bit clearer. What happens if you pass --no-upstream-cert ?

Hi @mhils

That did the trick! It works great!

Much appreciated and thank you for the time to look into this!

1 Like