Sometimes when you’re debugging a problem with a remote server, only seeing the actual bits on the wire is good enough. Recently I needed to do this to confirm whether it was my app or the server that was causing a bug.
My new go-to tool is Charles. This is a great cross-platform (Mac, Windows, Linux) logging HTTP proxy with all sorts of nice features – including SSL proxying, so you can see what’s going to/from Facebook or other web services over https!
Here’s a step by step on getting Charles working with your iOS or Android phone, including the SSL proxying.
- Install Charles on your Mac (or Linux/Windows – I’m using Mac, but most of this is the same), then run it
- Check the Proxy Settings (Proxy | Proxy Settings…) to find out what port it is listening on. For me, that’s port 8888
- Find your Mac’s IP address: at a command prompt, run
The output I get looks like below – the IP address I want is 10.0.0.249
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether 58:b0:35:72:e6:6f inet6 fe80::5ab0:35ff:fe72:e66f%en1 prefixlen 64 scopeid 0x6 inet 10.0.0.249 netmask 0xffffff00 broadcast 10.0.0.255 media: autoselect status: active
You now have a proxy running on your Mac. Now to configure your iOS or Android phone to talk to it.
For iOS (works on iPhone, iPad and iPod Touch)
- Go to Settings | WiFi
- Tap on the blue disclosure arrow at the right of your WiFi network
- Scroll down to the HTTP Proxy section
- Select Manual, then enter the IP address and port from above into the settings
- Switch over to Safari, and try browsing somewhere. You should see packets showing up in Charles – you may see a security prompt from Charles first. If you don’t, then double check the settings to make sure you’ve got the IP address and port right
- Go to Settings, WiFi to see a list of networks
- Tap and hold on your active WiFi network until a dialog comes up
- Select “Modify Network”
- Scroll down, and tick “Show Advanced options”
- Scroll down again, and select “Manual” under “Proxy settings”
- Enter the IP address from above as the Proxy hostname
- Enter the port (8888) as the Proxy port
- Tap Save
- Navigate to your browser, and load a page e.g. http://www.google.com. You should see packets showing up in Charles. If not, double check the settings to make sure the port and IP address are correct
You should now have a window in Charles that looks a bit like this:
Setting up SSL Proxying
You’re now able to see all the HTTP traffic flowing to and from your device – except for anything that’s going over https (SSL). Luckily Charles includes a handy SSL proxy.
Setting up Charles to SSL Proxy
This bit is easy – go to Proxy | Proxy Settings | SSL and add the domain names you want to proxy for. Wildcards work, so you can use things like “*.facebook.com” or “*.s3.amazonaws.com”.
There’s more details in the Charles documentation here.
Setting up iOS to use the SSL Proxy
If you now try browsing to a secure site that is being proxied, you’ll find it won’t work. This is because Charles uses its own certificate to intercept the SSL traffic – and since Charles’ certificate isn’t trusted, iOS refuses to use it.
Here’s how to make it work: go to http://charlesproxy.com/charles.crt in your iOS browser and accept the certificate install.
Once that’s done, you should see proxied traffic showing up in Charles
Setting up Android to use the SSL Proxy
On Android, instead of just failing, the browser pops up a security warning:
To avoid, just browse to http://charlesproxy.com/charles.crt and install the certificate.
Happy debugging! Oh, and don’t forget to switch off the proxying on your phone when you’re done, otherwise you’ll end up wondering why nothing’s working when you close Charles!