I recently acquired a copy of Charles, the well-known Web Debugging Proxy Application. I’ve actually stumbled across this product on multiple occasions, but never bothered to actually try it… almost exclusively because I thought the website looked a little dated. In trying to suss out the root cause behind MM-19091, I needed a way to debug against our community servers but running with my local copy of the mattermost webapp. This would allow me to insert
console.log debugging statements and even use the React Developer Tools without the minified component names.
What follows is a brief how-to guide for replicating this setup on macOS. Charles is also available for Windows and Linux, but I imagine the configuration steps should be similar. Note too that unrestricted use of Charles requires a paid license, but if you want to experiment with these steps, the application will run for 30 minutes at a time for up to 30 days with all features enabled.
Start by downloading Charles. After you copy the tool to your Applications directory and run it, Charles will automatically start proxying:
Notice, however, that the contents of any SSL connections are initially opaque. The real power of Charles comes from being able to install root certificates and effectively man-in-the-middle your SSL connections.
Follow the help documentation to configure SSL Certificates, then open the
Proxy menu and choose
SSL Proxying Settings.... Select
Enable SSL Proxying and configure a wildcard to match our three community servers. Charles even proxies websocket connections!
After saving these settings and restarting your browser, you should be able to inspect all the traffic to and from community.mattermost.com (running our last stable release), community-release.mattermost.com (running our upcoming stable release), and community-daily.mattermost.com (running master):
Note that all three of our community server endpoints share the same database, allowing you to switch between the various branches using the same Mattermost account.
Debugging community using a local webapp involves redirecting requests for static frontend assets to a local directory (or a
localhost server), while leaving untouched any API calls and other programmatic interactions against the server backend.
There are effectively two kinds of static assets served by the Mattermost application:
Note that the server doesn’t actually expect a request for
/index.html, but serves up this file on any number of paths:
/landing on the site without any path
/loginfollowing a login link from an email, or just reloading the page
/<team>/any configured team, such as
coreor our internal
/<team>/<channel>a channel on any configured team
/<team>/pl/<post>a permalink to a post
Once the bootstrapping code is served, the application examines the current path and renders the appropriate part of the application.
In addition to the static assets, the server expects a number of programmatic interactions:
/api/*any REST API request
/login/sso/samllogin flows via SAML
/oauth/*OAuth application flows
Unfortunately, the overlap here between static assets and programmatic interactions makes splitting the routing slightly tricky when redirecting requests locally. For example:
/loginshould be redirected so as to serve the local
/login/sso/samlshould be sent to the server to avoid breaking SAML login
To configure Charles to redirect requests for static frontend assets, open the
Tools menu and choose
(To avoid having to configure these manually, you can also just download and import map-remote.xml.)
The rules above yield the following results:
/loginis sent to
localhost:8065/login, serving up
index.htmlduring the login flow
/static/*is sent to
localhost:8065/static/*, serving up all static assets
/core/*is sent to
localhost:8065/core/*, serving up
index.htmlfor any link on the core team
/private-core/*is sent to
localhost:8065/core/*, serving up
index.htmlfor any link on the private core team
To start your debugging session, first make sure your local Mattermost server is running by following the Developer Setup instructions. Then, browse to
/login against the community server of your choice. If you’re not already logged in, this will allow you to complete any necessary login flow (even through SAML!), but you’ll get sent back to
/ and what appears to just be a blank page with console errors. Manually head back to
/login and you’ll find yourself successfully logged in on community with all static assets being served up by your local development server instance:
There are a shortcomings with this configuration:
localhost:8065without also mapping
/*, breaking the programmatic endpoints. I’ve reached out to Charles support for help, but for now, it means that the
/loginflow will be interrupted as described above. Similarly, logging out triggers a blank page and requires manually heading back to
The configuration above is only the tip of the iceberg when it comes to using Charles for debugging. Think of Charles like an external
Network tab from the Chrome Developer Tools, but spanning all your tabs across all your applications. Should you run into any networking problems, or just want to stop using Charles altogether, it’s easy to turn off the proxy altogether by selecting the
Proxy menu and unchecking
If anyone has suggestions on this topic, please feel free to continue the conversation on this topic. I’d love to find a way to optimize the Charles configuration, and even find a way to enable proxying using open source tooling alone.