{"id":277,"date":"2007-02-12T10:05:51","date_gmt":"2007-02-12T17:05:51","guid":{"rendered":"http:\/\/www.red-sweater.com\/blog\/277\/caught-with-my-bytes-unzipped"},"modified":"2007-02-12T10:09:38","modified_gmt":"2007-02-12T17:09:38","slug":"caught-with-my-bytes-unzipped","status":"publish","type":"post","link":"https:\/\/redsweater.com\/blog\/277\/caught-with-my-bytes-unzipped","title":{"rendered":"Caught With My Bytes Unzipped"},"content":{"rendered":"<p>I&#8217;m working on an application that has some simple networking needs, among them fetching small bits of data off of a variety of user-configured web sites. Since the needs are so straight-forward I thought using NSURL and its &#8220;resourceDataUsingCache:&#8221; method would be the way to go. It so happens that this application already has a separate thread running when the data is needed, so the synchronous call is fine:<\/p>\n<pre>\n<code>\nNSData* myWebData = [myURL resourceDataUsingCache:NO];\n<\/code>\n<\/pre>\n<p>This works amazingly well and reliably returns the contents of the specified URL, exactly as you&#8217;d expect. <em>Unless the server decided to zip encode the data!<\/em> In this case, you&#8217;ll get back data that for all intents and purposes looks completely wacked. <\/p>\n<p>\nThe problem stems from the fact that NSURL&#8217;s data loading mechanism passes the following header to the server when requesting the URL:\n<\/p>\n<p><pre>\nAccept-Encoding: gzip, deflate\n<\/pre>\n<\/p>\n<p>\nBut when the server complies and returns the data, NSURL shrugs and passes it straight back to the caller, without doing us the favor of unzipping it.\n<\/p>\n<p>\nBecky Willrich <a href=\"http:\/\/www.cocoabuilder.com\/archive\/message\/cocoa\/2004\/4\/5\/103434\">acknowledged the bug<\/a> in NSURL a few years ago, and suggested using a lower level API to work around the problem. She also identified an insidious aspect to the bug, which is that a server won&#8217;t necessarily give you zipped data just because you offered to handle it. In fact, a server that is in the habit of giving zipped data may choose not to if there doesn&#8217;t seem to be a benefit to doing so. In particular, if the cargo is so small that it would be more trouble to zip it than to just send it.\n<\/p>\n<p>\nSo why am I writing about this? Mainly to publish a simple workaround to the problem, using a slightly more complicated set of classes and parameter values, but ultimately being almost as simple as the original:\n<\/p>\n<p><pre>\n<code>\nNSError* theError;\nNSURLResponse* theResponse;\nNSURLRequest* urlRequest =\n\t[NSURLRequest requestWithURL:myURL\n\t\tcachePolicy:NSURLRequestReloadIgnoringCacheData\n\t\ttimeoutInterval:60.0];\nNSData* myWebData =\n\t[NSURLConnection sendSynchronousRequest:urlRequest\n\t\treturningResponse:&theResponse\n\t\terror:&theError];\n<\/code>\n<\/pre>\n<\/p>\n<p>\nMonitoring the situation with tcpdump from the command line, I see that the same zipped content is being requested and received, but evidently NSURLConnection is kind enough to perform the extra step of unzipping it for me. Whoo!\n<\/p>\n<p>Note that the methods used require 10.2 with Safari 1.0 installed, or 10.2.7 or later.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m working on an application that has some simple networking needs, among them fetching small bits of data off of a variety of user-configured web sites. Since the needs are so straight-forward I thought using NSURL and its &#8220;resourceDataUsingCache:&#8221; method would be the way to go. It so happens that this application already has a [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,11,15],"tags":[],"class_list":["post-277","post","type-post","status-publish","format-standard","hentry","category-apple","category-cocoa","category-programming"],"_links":{"self":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/277","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/comments?post=277"}],"version-history":[{"count":0,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/277\/revisions"}],"wp:attachment":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/media?parent=277"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/categories?post=277"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/tags?post=277"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}