Dealing with the header buffer and proxy requests

So I'm having one of those random brainstorm kind of days and I wanted
to test the waters to get an idea of what Team Coldbox (or anyone
else) thoughtgetpagecontext of functionality related to clearing
ColdFusion's header buffer on proxy request.

The header buffer is available via CF's getPageContext() method and is
is what tags liks cfHTMLHead and cfAjaxProxy dump into. There are
slight differences between Adobe, Railo, and OpenBD and a little Java
is required to access it. It mostly rears its ugly head the first time
someone tries to expose part of their application a web service that
returns SOAP or JSON and it keeps erroring. Eventually they will
check FireBug or Fiddler and see that random bit of CSS or XML doc
type wrapped in a cfHTMLHead hiding in their application.cfc is being
pre-pended to each response even if they use <cfcontent reset="yes">.

So, the usual obvious answer is to simply not use tags such as
cfHTMLHead for any request that will be returning JSON or SOAP to the
client. Today I came across an exception that I think is technically
a bug but never-the-less would be nice to have a work-around. It is
the JavaScript generated by the cfAjaxProxy tag which cannot be
captured with cfsavecontent. It goes straight to the header buffer,
where it is pre-pended to your page response and there is no
documented way to get rid of it.

In our scenario we had a generic form that would innerHTML an
additional section of the form with JSON-encoded HTML retrieved from a
ColdBox Proxy after the page had loaded based on the selections of the
user at the top of the page. The innerHTML'ed portion of the form had
it own use of cfAjaxProxy inside of it. As you can imagine, there was
a decode JSON error since the JSON coming back from the ColdBox proxy
was incorrectly appended with the ajax proxy JS which is generated by
the cfAjaxProxy tag.

Now I know some of you are already reaching or your keyboards to tell
me all the ways I can circumvent the issue, but I'm already aware of a
number of ways to side-step the problem. I'm really more concerned
with an academic discussion on how to solve it when it is unavoidable
or simply the preferred method.

Elliott Sprehn originally threw some code out on a blog post of Ben
Nadel's with the necessary means to clear out anything in the
headerBuffer.
http://www.bennadel.com/blog/758-ColdFusion-GetPageContext-Massive-Exploration.htm

Let me pause here and point out that the Model Glue frameworks already
employs this function (as well as a BlueDragon and Railo version) in
their Abstract Remoting Service to ensure there is no content laying
around in the header buffer that will screw up the remoting request.
http://svn.model-glue.com/trunk/ModelGlue/gesture/remoting/AbstractRemotingService.cfc

While that approach is probably useful to strip out accidental header
content you didn't want, it also assumes anything in the header is
junk. While that is probably a safe assumption if you are returning a
naked array, or result set, I often return the HTML my view generates
and innerHTML it into the page and in those instances-- SPECIFICALLY
those instances where the ajaxed page wants to use functionality like
cfAjaxProxy which is going to cram stuff into the header, I actually
NEED to capture the text in the Header buffer(s) and prepend it in to
the HTML being generated by my views so it can be returned completely
and correctly.

Enter a snippet of code posted on Ben Nadel's blog by David Boyer:

It contains a function that will retrieve the contents of the
headerBuffer out of the page context. (Note, it only works on CF7.
CF8 introduced a prependHeaderBuffer and appendHeaderBuffer to
accommodate the automatic generation of JavaScript from CF's Ajax
functions verses the arbitrary stuff you place in cfHTMLHead. This is
easily fixed though. )

( My apologies for the growing length of this post, but I hate it
when people don't flesh out a complex question... )

Using modified versions of the functions I have linked to, I played
around with a proof of concept today that would grab any content in
the header buffers of proxy request and inject it into the rendered
response of that ColdBox event before it was returned thus allowing
you to still use CF tags that insist on using the header for content
without breaking your response.

So, I've said all that to say this: What is the perceived value of
some out-of-the-box ColdBox functionality to handle this for you? I
think it would need to come in two forms:
1 ) Discard Header content (Like Model Glue does)
2) Append header content into the response, then discard.

It could be triggered by setting a variable in the request collection,
or a method built in to the request context (like event.noRender())
It could be part of the base ColdboxProxy.process() component, or it
could probably be implemented as a postProcess interceptor.
One drawback is that the code would rely on undocumented parts of the
page context, and would need custom versions to support all versions
of ColdFusion from each vendor.

Or perhaps you think all of this is a rather contrived edge-case and
doesn't belong in the framework at all. (A perfectly acceptable
opinion).

Please do share.

~Brad

Hi Brad,

very interesting read indeed. I kind of feel hesitant to include undocumented features especialy on internal CF classes and not normal JDK classes. If we where just talking to the page context and clearing the buffers and headers, then for sure. But we are really tackliing into each engine’s implementation to achieve this.

Althought, the question remains, how do we tackle it?

My first jerk reaction is an interceptor. Why? well, it is decoupled from the core, your code and any future code. You can just declare it and it will wrap the requests. To me, that would be more the approach I would take on this. Why? Not everybody does what you are trying to do and everybody has different use cases.

Also, I never use CFAjaxProxy, because I always retrieve my JSON or HTML via normal event routing and just using event.renderdate(). I take the complexity away from cfajaxproxy and creating proxy objects for json or html data.

So in summary, I would say that having something that cleans the buffer every time on remote calls, to me is adding some extra that might or might never be used. So I would love to see this as a preProcess() interceptor, that can do this cleanup beforehand. We can even include it in the plugin/interceptors pack and document it on the wiki.

Ideas, thoughts?