• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to Gzip the response from a web service

Explorer ,
Feb 23, 2010 Feb 23, 2010

Copy link to clipboard

Copied

I have the following code in my OnRequestEnd.cfm file to compress the response of most cfm/cfc requests.

<cfif cgi.HTTP_ACCEPT_ENCODING contains "gzip"
AND REFindNoCase("MSIE 6", CGI.HTTP_USER_AGENT) eq 0
AND NOT getPageContext().getResponse().isCommitted()>


    <cfscript>
         pageOut = getPageContext().getCFOutput().getString();
         fileOut = createobject("java", "java.io.ByteArrayOutputStream").init();
         out = createobject("java","java.util.zip.GZIPOutputStream").init(fileOut);
         out.write(variables.pageOut.getBytes(), 0, len(variables.pageOut.getBytes()));
         out.finish();
         out.close();
      </cfscript>


<cfheader name="Content-Encoding" value="gzip">


<cfcontent reset="true" variable="#fileOut.toByteArray()#">   
</cfif>

The first cfif makes sure the browser allows compressed responses.

The second cfif excludes IE 6 as some earlier versions (which some of our users have) have decompression bugs.

The third cfif generally prevents pages that have cfflush from being processed. It actually tells me if response headers have already been committed and written to the output stream.

This seems to work fine except for cfcs that have returnType as XML and which are requested from flex applications via SOAP. If I remove the getPageContext().getResponse().isCommitted() I receive this error:

Failed to add  HTML header.

ColdFusion was unable to add the header you specified to the output stream. This is probably because you have already used a cfflush tag in your template or buffered output is turned off

I know I don't have any cfflush tags in these cfcs so I suspect it's because the cfc already adds a "content-type: text/xml" header to the output. The cfc

is

<cfcomponent>
    <cffunction name="getHierarchyData" returntype="xml" access="remote">
        <cfxml variable="hierXML">
            <root>
                <labelAttribute>test</labelAttribute>
                <data>
                    <moredata>test</moredata>

                </data>
            </root>
        </cfxml>

    <cfreturn hierXML>
    </cffunction>
</cfcomponent>

The response is something like:

<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
  <ns1:getHierarchyDataResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://cfc.private">
   <getHierarchyData xsi:type="ns2:Document" xmlns:ns2="http://xml.apache.org/xml-soap">
    <root>
                    <labelAttribute>name</labelAttribute>

How can I gzip the final response before sending it to the client?

The response needs to be returned as as SOAP as these requests are from a Flex app that we cannot change at the moment.

We're on Windows 2003/CF 8.01. We cannot use the built in IIS compression as it does not have a way to filter our requests from IE 6 as far as I know. Port80's httpzip doesn't work on 64 bit Windows 2003.

Any suggestions? Has anyone used the built in compression in IIS successfully?

TOPICS
Advanced techniques

Views

2.5K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 23, 2010 Feb 23, 2010

Copy link to clipboard

Copied

Shouldn't the web server be automatically handling this already?  It's more a web server job than a CF job, I would think.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Feb 23, 2010 Feb 23, 2010

Copy link to clipboard

Copied

Couple of options:

  • Use Deflate only with IIS
  • http://sebduggan.com/posts/ie6-gzip-bug-solved-using-isapi-rewrite
  • http://www.webveteran.com/blog/index.php/web-coding/coldfusion/fix-for-ie6-and-gzip-compressed-javascripts/
  • Dont't use compression at all for JS, CSS

My personal favourite:

  • The IE bug is pre XP SP2, so stop flogging a dead horse and do nothing.  Build in a web browser dectection, anyone using IE should be asked to upgrade, ala youtube or various google products.

Web developers and the people paying them are only shooting themselves in the foot working around stupid IE 6 problems like this.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 23, 2010 Feb 23, 2010

Copy link to clipboard

Copied

LATEST

Thanks for the information. The ISAPI rewrite looks promising. We mostly need it to compress large web service request but I wish I could get something working with CF. I remember I tried getting IIS compression to work on our dev server for CF files and must have messed up the metabase.

As much as I would love to drop all support for IE 6, our clients pay for our service and work for huge corporations that are still stuck on IE 6. We cannot just say "upgrade IE 6 or you won't be able to use the product you've already paid for."

A lot of these corporations are stuck because they have apps either internally or externally developed that may not fully support later versions of IE. Testing or upgrading these apps takes time. Yeah, it blows.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation