DotNetZip – Solving Mac Decompression Issues
As part of a ASP.Net Web API service that I’m co-developing, I have gotten familiar with the DotNetZip Library. It’s fantastic. We’re using it to gather up a set of requested files from network storage, package them in a zip archive, and stream them back to a client via a web application.
During testing, things worked great on Windows machines, but the moment we tested using a Mac, we ran into issues.
Synopsis:
Problem: On a Mac, a zip file would be downloaded, but it could not be extracted. Double-clicking the zip file resulted in the creation of a .cpgz file.
Solution: In ASP.Net code, change
HttpContext.Current.Response.ContentType = “application/zip”
to
HttpContext.Current.Response.ContentType = “application/octet-stream”
Problem Details:
A zip archive would download as normal, but as things were wrapping up, Safari would try to decompress the file and it would fail.
Error from Safari’s download manager area:
Furthermore, when attempting to simply extract the files directly using the built in Mac Archive Utility (by double-clicking the zip file), the utility would actually re-archive the file, rather than extract it. The end result was the creation of a .cpgz file. Attempting to decompress that file would result in creating another .zip file, which, when double-clicked, created another .cpgz file, and so on, and so on.
Archive Utility re-archiving the zip file when double-clicked (rather than un-archiving it)
Creation of .cpgz file:
Needless to say, the solution to this problem, though somewhat mysterious, was quite simple for me.
In my ASP.Net code, I was writing the zip file to the Response OutputStream. I had added a content type of “application/zip” to the response. This is what was breaking the zip files on a Mac. Buried in the DotNetZip Library’s forum was a post recommending changing the content type to “application/octet-stream” instead. That single changed fixed the issue for standard zip files!
Solution Details:
Change
HttpContext.Current.Response.ContentType = “application/zip”
to
HttpContext.Current.Response.ContentType = “application/octet-stream”