In one of my previous posts I’ve already shared with you how to get insights about tested mobile app with usage of proxy tools (please see again: Mobile app testing: underneath #1). Even without proxy tool in use by you, chances are quite high that between your app and the backend service your app communicate with, sit couple of different MITMs (man-in-the-middle), like api gateways, api proxies, etc. Each of it, as well as your proxy tool, can modify the request on the fly and you may even not know it.
Here is a simple example of header that your request can have included:
Accept-Encoding: gzip
In short it says:
Hey, I’m able to understand following encodings (e.g. compression algorithm like gzip, br, deflate, etc), so if you can, please compress it for me, to speed sending it over the network and save some network quota
szekar1
other possible values it can take (but not limited to) are:
Accept-Encoding: compress
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *
// Multiple algorithms
Accept-Encoding: gzip, compress, br
// and weighted with the quality value syntax:
Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5
Accept-Encoding: br;q=1.0, gzip;q=0.8, *;q=0.1
You may ask ‘why am I writing this?” this is well defined in http standard and this is nothing new.
Right, but …
(yeah, there always seems to be at least one “but”)
… there is also a chance that not all parties around you have implemented it properly or from ‘cover to cover’ or simply are doing some “defaulting” to their preferred values.
You don’t believe me?
Here is an example of very popular iOS elegant networking framework: Alamofire. By default, mentioned earlier, Accept-Encoding header is set to (based on the version of iOS):
if #available(iOS 11.0, *) {
encodings = ["br", "gzip", "deflate"]
} else {
encodings = ["gzip", "deflate"]
}
so far so good, nothing unexpected. But then there is one additional “cherry on top”:
return .acceptEncoding(encodings.qualityEncoded())
which assign (the qualityEncoded() function) different values to *q* values starting from 1.0, so at the end the header you are sending is something like:
Accept-Encoding: br;q=1.0, gzip;q=0.8, deflate;q=0.8
And here it starts tricky, as this requests goes through so many layers that one of them may have a bug? missed requirement? a feature? call it by your own words … that changes this header to something different or worst, ignoring it at all and instead of having back compressed data back you get it back in plain JSON, not compressed at all …
╭─szekar1@home ~/
╰─$ ll
-rw-r--r-- 3.1M Jul 15 22:22 response_api.json
-rw-r--r-- 509K Jul 15 22:22 response_api_gzip.json
do you see the difference between file sizes? and imagine your phone is getting uncompressed, 6 x times bigger, data each time … and now imagine you are abroad on low roaming data plan … ouch
and now you say, that of course you can check that via proxy tool, that expected compressed file is returned to your app, and you’re right, with one small catch – you need to know your proxy tool very well as there may be some tricky settings as this one:
If it is checked (and by default it is), then all you will see is the new shinny “Accept-Encoding: gzip” header, that is highly recognizable and should work in 99% cases, but is it your case as well? if your header contains *q* values or some old compression formats like ‘compress’ then I would not be so optimistic.
What I would like you take from this post is that one proxy tool sometimes is not enough if you are not aware of its ‘magic’ behind your backs (in the proxy tool you are seeing the same header as in the server logs, the size of the response in the tool seems to be compressed, all the dashboards are telling you that your backend service generated compressed data, etc, but still the client, your app, is consuming too much precious roaming data quota).
Pick tools to your toolbelt carefully and invest your time in finding what all these small checkboxes are for, compare it with another one and verify the results are the same and at the end study your app, frameworks and libraries you are adding to it to know what to expect from simple thing like getting compressed data back from your backend service.
Happy testing, happy learning!