Reputation: 401
I've written a CF10 RESTful web service that accepts a POST from a third party. The POST comes in with successfully with proper headers showing that it's content-type is application/json and content-encoding is gzip.
The body however comes in like this
??VJ.-.??M-?LQ?R22?0W?Q??Os-????b??????_?ZT??175 ????T?E???r??KKJ??3??S]A?@u??%??`?f??FJ???`?
The issue is that in the receiving function the cfargument
for body
is set to type="string"
when really what it should be is type="binary"
. Unfortunately setting the type to binary causes the call to fail. The calling server receives the following:
Notification response HTTP/1.1 500 Internal Server Error Content-Length: 41 Content-Type: text/plain Server: Microsoft-IIS/7.5 CF_TOMCAT_REUSE_THIS_CONNECTION: FALSE X-Powered-By: ASP.NET Date: Thu, 30 May 2013 19:53:17 GMT Connection: close
{"Message":"Variable BODY is undefined."}
I have no control of the third party call to my REST endpoint.
Does anyone have any ideas that would allow my REST endpoint to receive this gzipped (binary) body? Alternatively, does anyone know how to convert the string representation back into a gzip'd binary that can then be inflated and I can then recover the json packet?
My code looks like this:
<cffunction name="trigger" access="remote" returntype="string" httpmethod="POST">
<cfargument name="body" type="any" >
<cfargument name="Length" type="String" restArgsource="Header" restargname="Content-Length" >
<cfargument name="Type" type="String" restArgsource="Header" restargname="Content-Type">
<cfargument name="Encoding" type="String" restArgsource="Header" restargname="Content-Encoding" >
<cfset var result = "HTTP/1.1 200 OK" >
<!--- Do some processing here --->
<cfreturn result>
</cffunction>
Thank you all in advance.
Upvotes: 3
Views: 711
Reputation: 32885
GZip encoding support added in CF11: https://wikidocs.adobe.com/wiki/display/coldfusionen/RESTful+Web+Services+in+ColdFusion#RESTfulWebServicesinColdFusion-SupportforGZipencoding
Upvotes: 0
Reputation: 31
Just to add some additional input here, I did submit a bug request as attempting to change the web.xml configuration file did not initially work for me. I had added additional entries into configuration file for the GZIP decoding and instead what needed to be done was to add to the existing entries the parameter value for the GZIP encoding filters.
The original-unchanged file in web.xml should show entries such as this, found under the servlet named CFRestServlet:
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>coldfusion.rest.servlet.CFUriConnegFilter;coldfusion.rest.servlet.CFRequestFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>coldfusion.rest.servlet.CFResponseFilter</param-value>
</init-param>
In order to enable the gzip filters, update these two parameters to have them to appear this way instead:
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>coldfusion.rest.servlet.CFUriConnegFilter;com.sun.jersey.api.container.filter.GZIPContentEncodingFilter;coldfusion.rest.servlet.CFRequestFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>coldfusion.rest.servlet.CFResponseFilter;com.sun.jersey.api.container.filter.GZIPContentEncodingFilter</param-value>
</init-param>
As you'll see, you simply need to add the "com.sun.jersey.api.container.filter.GZIPContentEncodingFilter" as another value to the semi-colon separated list of values. Once you've made the changes, restart your CF server and then your REST based services will properly and automatically decode any GZip encoded data they receive.
For reference, my bug request can be read here: https://bugbase.adobe.com/index.cfm?event=bug&id=3694176
Thanks.
Upvotes: 3
Reputation: 361
If I understand your problem correctly, this can be done with GZIPContentEncodingFilter
In short CF's rest support is built upon JERSEY APIs. When a request comes to a rest endpoint (defined in the URL), a series of jersey filters execute before invoking the actual function. This is where this filter would execute and handle GZIP compression for you.
You may configure only the request filter (In case the library is not expecting a gzipped response back). Just add following in web.xml and hopefully will be done.
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.GZIPContentEncodingFilter</param-value>
</init-param>
CF already has one filter added for handling *.json & *.xml requests.
HTH, Chandan Kumar
Upvotes: 2