Over the past few months, I have been giving some free time to exploring ColdFusion's GetPageContext() function. The data available through this function is maaaaassive in scope. I thought it would be a fun little project, but it is just overwhelming, and I fear, not that useful. There is some really cool stuff in there, but it's in the minority (at least from my standpoint).
I was originally going to do an exhaustive search before I posted any results, but I don't know if I am ever going to finish. As such, I have decided to post what I have so far; and then, as I have time to update this, I will update this post. If I find anything cool, I will post referencing back to this post, but mostly, I will just update this when I have a few free moments.
Stuff that has ".........." is just stuff I have not explored yet.
Searches for a built-in scope with the given name. If the scope can be found, it returns a reference to it. If it cannot be found it returns null.
Parameters: java.lang.String
Returns: java.util.Map (ie. ColdFusion Struct)
[[cfset objRequestScope = GetPageContext().SymTab_findBuiltinScope( "request" ) /]]
Searches "local" scopes to find a variable with the given simple name. Returns value of variable. This will not search scopes like APPLIACTION, SESSION, REQUEST.
Parameters: java.lang.String
Returns: java.lang.Object
[[cfset foo = "bar" /]]
##GetPageContext().SymTab_findSimpleName( "foo" )##
Outputs: "bar"
[[cfset foo = StructNew() /]]
##GetPageContext().SymTab_findSimpleName( "foo" )##
Outputs: [empty struct]
Gets the value of a variable at the given variable name using dot-notation.
Parameters: java.lang.String
Returns: java.lang.Object
[[cfset APPLICATION.Azure = "hottie" /]]
##GetPageContext().SymTab_resolveDottedName( "APPLICATION.Azure" )##
Outputs: hottie
Cannot determine use. Seems to act similar to SymTab_resolveDottedName but takes an array of strings rather than a simple string value. Seems to fail if array is more than one value.
Parameters: [ java.lang.String ]
Returns: java.lang.Object
[[cfset Girls = StructNew() /]]
##GetPageContext().SymTab_resolveSplitName( ListToArray( "Girls" ) )/]]
Outputs: [Empty Struct]
Adds a ColdFusion scope to the stack of scopes that will be searched when looking for a given value.
Parameters: coldfusion.runtime.Scope
Returns: void
[[cfset APPLICATION.Azure = "hottie" /]]
##GetPageContext().SymTab_setBuiltinCFScopes( "Azure" )##
##Azure##
Outputs: [empty string]
Outputs: [CFERROR: UNDEFINED VARIABLE]
[[cfset APPLICATION.Azure = "hottie" /]]
[[cfset GetPageContext().SymTab_setBuiltinCFScopes( APPLICATION ) /]]
##GetPageContext().SymTab_setBuiltinCFScopes( "Azure" )##
##Azure##
Outputs: hottie
Outputs: hottie
Sets the given variable name to the given value.
Parameters: java.lang.String, java.lang.Object
Returns: void
[[cfset GetPageContext().SymTab_setDottedName( "REQUEST.Libby", "sexy" ) /]]
##REQUEST.Libby##
Outputs: sexy
Seems to act the same as SymTab_setDottedName(). Sets a the given variable to the given value.
Parameters: java.lang.String, java.lang.Object
Returns: void
[[cfset GetPageContext().SymTab_setSimpleName( "REQUEST.Libby", "sexy" ) /]]
##REQUEST.Libby##
Outputs: sexy
Puts the value in the given map (ie. ColdFusion structure). Value is placed based on the key-chain defined by the given array.
Parameters: java.util.Map, [ java.lang.Object ], java.lang.Object
Returns: void
[[cfset Girls = StructNew() /]]
[[cfset GetPageContext().SymTab_setSplitNameInMap(
Girls,
ListToArray( "Libby,Hotness" ),
"8.0"
) /]]
[[cfdump var="##Girls##" /]]
Outputs: { Libby: { Hotness: 8.0 } }
Creates a struct at the given name (param 1) and sets the given value in the struct based on the path defined by the array.
Parameters: java.lang.String, [ java.lang.Object ], java.lang.Object
Returns: void
[[cfset GetPageContext().SymTab_setSplitNameInMap(
"Hotties",
ListToArray( "Libby,Hotness" ),
"8.0"
) /]]
[[cfdump var="##Hotties##" /]]
Outputs: { Libby: { Hotness: 8.0 } }
I did not bother playing around with this.
Parameters: java.io.Writer, java.lang.String
Returns: void
Test the equality of an object to the page context.
Parameters: java.lang.Object
Returns: boolean
[[cfset PageContext = GetPageContext() /]]
##PageContext.equals( GetPageContext() )##
Outputs: YES
Seems to search ColdFusion scopes for the variable with the given name. Seems very similar to SymTab_findSimpleName(). The searchable scopes is affected by SymTab_setBuiltinCFScopes().
Parameters: java.lang.String
Returns: java.lang.Object
[[cfset Anne = "saucy" /]]
##GetPageContext().findAttribute( "Anne" )##
Outputs: saucy
Flushs the content buffer to the output. (ie. CFFlush).
Parameters:
Returns:
This method is used to re-direct, or "forward" the current ServletRequest and ServletResponse to another active component in the application (source). This creates a "new" page request without refreshing the client page. Seems to maintain the REQUEST scope but clears all other non-persisting scopes.
Parameters: java.lang.String
Returns: void
Gets the local scope of the current function which contains var'd variables and the ARGUMENTS scope. Returns NULL if there is no local scope.
Parameters:
Returns: coldfusion.runtime.LocalScope
[[cffunction name="FN"]] [[cfset var Nicole = "very naught" /]]
[[cfdump var="##GetPageContext().getActiveFunctionLocalScope()##" /> /]]
[[/cffunction]]
[[cfset FN() /]]
Outputs: { ARGUMENTS: {}, Nicole: "very naughty" }
Return the object associated with the name in the page scope or null if not found. (source). Appears to only check the VARIABLES scope and is not affected by SymTab_setBuiltinCFScopes().
Parameters: java.lang.String
Returns: java.lang.Object
[[cfset VARIABLES.Fantacy = "Christina" /]]
##GetPageContext().getAttribute( "Fantasy" )##
Outputs: Christina
Return the object associated with the name in the specified scope or null if not found. (source). Scope index (param 2) is a constant of the Page Context (which I cannot seem to access).
Parameters: java.lang.String, int
Returns: java.lang.Object
Returns an enumeration of the keys in the given scope.
Parameters: int
Returns: java.util.Enumeration
[[cfset VARIABLES.Fantacy = "Christina" /]]
[[cfset objEnum = GetPageContext().getAttributeNamesInScope( JavaCast( "int", 1 ) ) /]]
[[cfloop condition="objEnum.HasMoreElements()"]]
##objEnum.NextElement()##
[[/cfloop]]
Outputs: Christina
Get the scope where a given attribute is defined. (source). Returns the index of the scope. Cannot seem to figure out which scopes it will or will not search. Returns zero if not found.
Parameters: java.lang.String
Returns: int
Returns a structure of all the built-in ColdFusion structures. CAUTION: If you CFDump this out, you might get HUGE HUGE HUGE and potentially circular results.
Parameters:
Returns: coldfusion.runtime.Scope
Returns the current JSP Writer??? CFOutput extends coldfusion.runtime.NeoJspWriter extends javax.servlet.jsp.JspWriter extends java.io.Writer
Parameters:
Returns: coldfusion.runtime.CFOutput
I could not figure out what this does.
Parameters: boolean
Returns: void
Clears the content buffer that has not yet been flushed to the client. Does not throw an error if content has already been flushed.
Parameters:
Returns: void
Clears the content buffer that has not yet been flushed to the client. Does not throw an error if content has already been flushed.Not sure how the "All" part comes into play.
Parameters:
Returns: void
Clears the content buffer that has not yet been flushed to the client. Does not throw an error if content has already been flushed.Not sure how the "All" part comes into play.
Parameters:
Returns: void
Could not figure out what this does. Supposed to close the output stream, but did not have any affect.
Parameters:
Returns: void
Turns off on (true) and off (false) the page setting for enabling CFOutput only.
Parameters: boolean
Returns: void
[[cfset GetPageContext().GetCFOutput().enablecfoutputonly( JavaCast( "boolean", true ) ) /]]
Hey, what's up?
[[cfoutput]]
Not much.
[[/cfoutput]]
Outputs: Not much.
Flushed the content buffer to the client. Seems to do the same thing as the CFFlush tag.
Parameters:
Returns: void
Gets the current content buffer. coldfusion.runtime.CharBuffer extends java.io.CharArrayWriter extends java.io.Writer
Parameters:
Returns: coldfusion.runtime.CharBuffer
Close the stream. This method does not release the buffer, since its contents might still be required. (source). I could not really get this to do anything.
Parameters:
Returns: void
This returns the (zero-based) index of the string in the existing buffer and -1 if the string is not found. This only checks buffer content that has not yet been flushed to the client.
Parameters: java.lang.String
Returns: int
This returns the (zero-based) index of the string in the existing buffer and -1 if the string is not found. The second argument is the index at which to start searching. This only checks buffer content that has not yet been flushed to the client.
Parameters: java.lang.String, int
Returns: int
This didn't seem to do anything. I could still set header values after this was called so apparently it didn't flush anything.
Parameters:
Returns: void
Gets the characters in the content buffer located at the given (zero-based) index value.
Parameters: int
Returns: char
I could not figure out how to call this properly.
Parameters: int, int, int, [ Char ]
Returns: void
This starts at the given (zero-based) buffer index (param 1) and writes X number of characters (param 2) from the given string (param 3) to the buffer. Param 2 CANNOT be longer than the given string.
Parameters: int, int, java.lang.String
Returns: void
This starts at the given (zero-based) buffer index (param 1) and overwrites the content buffer with the given string (param 2).
Parameters: int, java.lang.String
Returns: void
Resets the buffer so that you can use it again without throwing away the already allocated buffer. (source). Could not really figure out what this did. It didn't seem to clear the buffer or anything.
Parameters:
Returns: void
Set the character at the given index (param 1) to the character denoted by the given ASCII number (param 2).
Parameters: int, char
Returns: void
ABC [[cfset GetPageContext().getCFOutput().getBuffer().setCharAt( 0, Asc( "Z" ) ) /]]
Outputs: ZBC
Could not figure out what this does.
Parameters: int
Returns: void
This returns the current size of the content buffer.
Parameters:
Returns: int
12345#GetPageContext().getCFOutput().getBuffer().size()#
Outputs: 5
Gets the substring of the content buffer starting at the given index (param 1) and continuing to the second index (param 2).
Parameters: int, int
Returns: java.lang.String
Returns an array of Character objects reflective of the content buffer. This can be accessed as a ColdFusion array to get the individual characters.
Parameters:
Returns: [ Char ]
Returns a string of the content buffer data.
Parameters:
Returns: java.lang.String
I could not get this to work.
Parameters: [ Char ]
Returns: void
I could not get this to work.
Parameters: [ Char ], int, int
Returns: void
I could not get this to work.
Parameters: int
Returns: void
I could not get this to work.
Parameters: java.lang.String
Returns: void
I could not get this to work.
Parameters: java.lang.String, int, int
Returns: void
Writes the current buffer content to another writer. I did not mess with this.
Parameters: java.io.Writer
Returns:
I am guessing this writes the current buffer at the given offset for the given legnth to another writer. I did not mess with this.
Parameters: java.io.Writer, int, int
Returns:
Returns the size of the buffer in bytes, or 0 is unbuffered. (source)
Parameters:
Returns: int
Not sure what this is supposed to do.
Parameters:
Returns: int
Seems to get some sort of character index of the current buffer. If the content is flushed, this index is reset.
Parameters:
Returns: int
Gets the number of CFOuput tags that wrap this statement.
Parameters:
Returns: int
Returns the number of bytes unused in the buffer. (source).
Parameters: -
Returns: -
Returns the content of the current buffer as a string.
Parameters:
Returns: java.lang.String
Gets the current writer (that writes to the current buffer I assume).
Parameters:
Returns: javax.servlet.jsp.JspWriter
Returns whether or not the buffer will auto flush the buffer to the client before throwing an overlof exception.
Parameters:
Returns: boolean
Writes a new line character to the buffer.
Parameters:
Returns: void
Prints the given value to the content buffer.
Parameters: [ Char ] | boolean | char | double | float | int | java.lang.Object | java.lang.String | long
Returns: void
[[cfset GetPageContext().getCFOutput().print( "Hey there hot momma" ) /]]
Outputs: Hey there hot momma
Prints the given value to the content buffer and then terminates the line (prints a line break).
Parameters: [ Char ] | boolean | char | double | float | int | java.lang.Object | java.lang.String | long
Returns: void
I assume this sets the number of bytes the buffer will hold before it is flushed to the client. I did not mess with this.
Parameters: int
Returns: void
I could not figure out what this does.
Parameters: boolean
Returns: void
Sets some sort of internal index for the buffer. Messing with this value will cause some of the buffer to never be flushed. Couldn't figure out how it translated.
Parameters: int
Returns: void
Seems to set the flag for killing white space created by ColdFusion tags. Not really sure about that.
Parameters:
Returns: void
Write the character array to the content buffer.
Parameters: [ char ]
Returns: void
Writes the given character array to the buffer starting at the given offset (param 2) for the given length (param 3).
Parameters: [ char ], int, int
Returns: void
[[cfset GetPageContext().getCFOutput().write( "123456789", JavaCast( "int", 3 ), JavaCast( "int", 2 ) ) /]]
Outputs: 45
Not sure what this does.
Parameters: int
Returns: void
Writes the given string to the content buffer.
Parameters: java.lang.String
Returns:
Writes the given string to the content buffer starting at the given offset (param 2) for the given length (param 3).
Parameters: java.lang.String, int, int
Returns: void
Writes the given content to the output so long as no content has to be flushed to the client. Writes the content to beginning of the buffer even if the buffer has already been populated. I believe this is NOT actually writing to the buffer, but some sort of buffer-head. Writing values to the header seem NOT to affect other buffer-related manipulation (which is why I think it might not actually change the buffer itself).
Parameters: java.lang.String
Returns: boolean
START [[cfset GetPageContext().getCFOutput().writeHeader( "END" ) /]]
Outputs: END START
Returns an array of some of the ColdFusion scopes. Not sure exactly which it returns. Not all of them.
Parameters:
Returns: java.util.Vector
Returns the Java class of the current object.
Parameters:
Returns: java.lang.Class
Could not determine what this does.
Parameters:
Returns: coldfusion.runtime.QueryVector
Returns the current exception object. Could not figure how to get a value from this. CFTry / CFCatch did not allow any return value.
Parameters:
Returns: java.lang.Exception
Not exactly sure what a Fusion Context is. I suppose it is the context in which the current ColdFusion page request is executing (not that means much of anything either).
Parameters:
Returns: coldfusion.filter.FusionContext
Not sure what this does. Attempts to use it seemed to throw a 500 NULL error.
Parameters: boolean
Returns: void
Not sure what this does. Attempts to use it seemed to throw a 500 NULL error.
Parameters: boolean
Returns:
I assume this is used to manipulate the scope chain. I couldn't figure out how to mess with this.
Parameters:
Returns: void
I assume this is used to manipulate the scope chain. I couldn't figure out how to mess with this.
Parameters: coldfusion.runtime.Scope
Returns: void
I assume this is used to manipulate the scope chain. I couldn't figure out how to mess with this.
Parameters: coldfusion.runtime.VariableScope
Returns: void
Set's the given struct as the struct to be used as the APPLICATION scope.
Parameters: java.lang.Object
Returns: void
Set's the given struct as the struct to be used as the CLIENT scope.
Parameters: java.lang.Object
Returns: void
Set's the given struct as the struct to be used as the SESSION scope.
Parameters: java.lang.Object
Returns: void
I assume this addes a handler for a given exception type. Could not figure out even how to mess with this.
Parameters: java.lang.String, java.lang.Class, java.lang.String
Returns: void
Could not figure out how to use this.
Parameters: javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.io.OutputStream
Returns: coldfusion.filter.FusionContext$FusionContextData
No idea what this does.
Parameters:
Returns: boolean
Returns the name of the application as defined in the CFApplication tag or the ApplicationName value of the Application.cfc component.
Parameters:
Returns: java.lang.String
Returns the current fusion context reference.
Parameters:
Returns: coldfusion.filter.FusionContext
I could not figure out how to use this.
Parameters:
Returns: coldfusion.eventgateway.EventContext
Returns a reference to the current FORM scope (struct).
Parameters:
Returns: coldfusion.filter.FormScope
Returns the full template path of the executing page. Seems to be the same as GetBaseTemplatePath().
Parameters:
Returns: java.lang.String
Seems to simply append the given path to the web root's server path.
Parameters: java.lang.String
Returns: java.lang.String
Upon a cursory glance at the available methods, this seems to be the same thing as GetPageContext().GetRequest(), but I have not tested to see if it is going different things.
Parameters:
Returns: javax.servlet.http.HttpServletRequest
Could not figure out what this was doing. I assume it gets the binary data of the request?
Parameters:
Returns: [ B ]
Gets the page response object. javax.servlet.http.HttpServletResponseWrapper extends javax.servlet.ServletResponseWrapper extends java.lang.Object.
Upon a cursory glance of the available methods, this appears to be the same thing at GetPageContext().GetResponse(). I did not test to see if it functions any differently.
Parameters:
Returns: javax.servlet.http.HttpServletResponse
Could not figure out what this does.
Parameters:
Returns: java.lang.String
Could not figure out what this does.
Parameters: -
Returns: coldfusion.runtime.SecurityTable
Could not figure out what this does.
Parameters:
Returns: java.lang.String
coldfusion.CfmServlet extends javax.servlet.http.HttpServlet extends javax.servlet.GenericServlet extends java.lang.Object.
I did not bother checking to see what this does.
Parameters:
Returns: javax.servlet.Servlet
I did not bother checking to see what this does.
Parameters:
Returns: javax.servlet.ServletContext
Returns the Http session that binds the http client to the http server. jrun.servlet.session.JRunSession extends java.util.Hashtable extends java.util.Dictionary extends java.lang.Object ..............................
Parameters:
Returns: javax.servlet.http.HttpSession
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
.........................
Parameters: -
Returns: -
Returns the date/time stamp at which the page request started processing.
Parameters:
Returns: java.util.Date
No idea what this does.
Parameters:
Returns: boolean
Did not test this, but I assume this checks to see if the page is being run by a remote service (ie. Flash remoting, or web service)?
Parameters:
Returns: boolean
No idea what this does.
Parameters: boolean
Returns: void
Could not get this to work. Calling this did not seem to have any affect on the name stored in the APPLIACTION scope.
Parameters: java.lang.String
Returns: void
No idea what this does.
Parameters: coldfusion.filter.FusionContext
Returns: coldfusion.filter.FusionContext
No idea what this does.
Parameters: coldfusion.eventgateway.EventContext
Returns: void
Sets the flag that is returned by IsRemoting() method. Not sure what else this affects (if anything).
Parameters: boolean
Returns: boolean
Messing with this seemed to break the rest of the page processing. I could not even CFDump out CGI directly after setting this.
Parameters: java.lang.String
Returns: void
Not sure what this does.
Parameters: java.lang.String, java.lang.String
Returns: void
Not sure what this does.
Parameters: java.lang.String, java.lang.String
Returns: void
Not sure what this does.
Parameters: coldfusion.runtime.SecurityTable
Returns: void
Not sure what this does.
Parameters: javax.servlet.Servlet, javax.servlet.ServletRequest, javax.servlet.ServletResponse
Returns: void
Not sure what this does.
Parameters: boolean
Returns: void
Not sure what this does.
Parameters: java.lang.String
Returns: void
Returns the current value of the out object (a JspWriter). (source)
................................
Parameters:
Returns: javax.servlet.jsp.JspWriter
Returns the current value of the page object (a Servlet). (source). This seems to contain all the page-accessable values including all ColdFusion methods.
...................................
Parameters:
Returns: java.lang.Object
Returns a random number generator.
Parameters:
Returns: java.util.Random
This returns a cryptographically strong pseudo-random number generator. (source). Can provide the algorithm to be used.
Parameters: java.lang.String
Returns: java.security.SecureRandom
Return the current value of the request object (a ServletRequest). (source). javax.servlet.ServletRequest extends jrun.servlet.ForwardRequest extends jrun.servlet.RequestWrapper extends javax.servlet.http.HttpServletRequestWrapper extends javax.servlet.ServletRequestWrapper.
Parameters:
Returns: javax.servlet.ServletRequest
.........................
Parameters: java.lang.String
Returns: java.lang.Object
.........................
Parameters:
Returns: java.util.Enumeration
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: int
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: [ javax.servlet.http.Cookie ]
.........................
Parameters: java.lang.String
Returns: long
.........................
Parameters: java.lang.String
Returns: java.lang.String
.........................
Parameters:
Returns: java.util.Enumeration
.........................
Parameters: java.lang.String
Returns: java.util.Enumeration
.........................
Parameters:
Returns: javax.servlet.http.HttpServletRequest
.........................
Parameters:
Returns: javax.servlet.ServletInputStream
.........................
Parameters: java.lang.String
Returns: int
.........................
Parameters:
Returns: java.util.Locale
.........................
Parameters:
Returns: java.util.Enumeration
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters: java.lang.String
Returns: java.lang.String
.........................
Parameters:
Returns: java.util.Map
.........................
Parameters:
Returns: java.util.Enumeration
.........................
Parameters: java.lang.String
Returns: [ java.lang.String ]
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.io.BufferedReader
.........................
Parameters: java.lang.String
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters: java.lang.String
Returns: java.lang.String
.........................
Parameters:
Returns: javax.servlet.ServletRequest
.........................
Parameters: java.lang.String
Returns: javax.servlet.RequestDispatcher
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.StringBuffer
.........................
Parameters:
Returns: jrun.servlet.ForwardRequest
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: int
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: java.lang.String
.........................
Parameters:
Returns: javax.servlet.http.HttpSession
.........................
Parameters: boolean
Returns: javax.servlet.http.HttpSession
.........................
Parameters:
Returns: java.security.Principal
.........................
Parameters:
Returns: boolean
.........................
Parameters:
Returns: boolean
.........................
Parameters:
Returns: boolean
.........................
Parameters:
Returns: boolean
.........................
Parameters:
Returns: boolean
.........................
Parameters: java.lang.String
Returns: boolean
.........................
Parameters: java.lang.String
Returns: void
.........................
Parameters: java.lang.String, java.lang.Object
Returns: void
.........................
Parameters: java.lang.String
Returns: void
.........................
Parameters: javax.servlet.ServletRequest
Returns: void
.........................
Parameters: jrun.servlet.ForwardRequest
Returns: void
.........................
Parameters: java.lang.String
Returns: void
The current value of the response object (a ServletResponse). (source). javax.servlet.ServletResponse extends coldfusion.jsp.JspWriterIncludeResponse extends coldfusion.jsp.HttpServletResponseWrapper extends coldfusion.jsp.ServletResponseWrapper
.........................
Parameters:
Returns: javax.servlet.ServletResponse
Adds a cookie to the reponse. The cookie value will not show up in ColdFusion's COOKIE scope until the next page refresh (when the browser will send that cookie in the next request).
Parameters: javax.servlet.http.Cookie
Returns: void
Adds a response header with the given name and date-value. Not exactly sure what this means. This allows the response header to have multiple values. They will become a list of the sent in values.
Parameters: java.lang.String, long
Returns: void
Adds a response header with the given name and value. This allows the response header to have multiple values. They will become a list of the sent in values.
Parameters: java.lang.String, java.lang.String
Returns: void
Adds a response header with the given name and integer value. Not really sure what this does. This allows the response header to have multiple values. They will become a list of the sent in values.
Parameters: java.lang.String, int
Returns: void
Returns a boolean indicating whether the named response header has already been set.
Parameters: java.lang.String
Returns: boolean
Encodes the specified URL for use in the sendRedirect method or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL. Because the rules for making this determination can differ from those used to decide whether to encode a normal link, this method is seperate from the encodeURL method. (source)
Parameters: java.lang.String
Returns: java.lang.String
Encodes the specified URL for use in the sendRedirect method or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL. Because the rules for making this determination can differ from those used to decide whether to encode a normal link, this method is seperate from the encodeURL method. (source)
Parameters: java.lang.String
Returns: java.lang.String
Encodes the given URL if encoding is needed. (source)
Parameters: java.lang.String
Returns: java.lang.String
Encodes the given URL if encoding is needed. (source)
Parameters: java.lang.String
Returns: java.lang.String
Forces any content in the buffer to be written to the client. A call to this method automatically commits the response, meaning the status code and headers will be written.
Parameters:
Returns: void
Returns the actual buffer size used for the response. If no buffering is used, this method returns 0.
Parameters:
Returns: int
Returns the name of the charset used for the MIME body sent in this response.
Parameters:
Returns: java.lang.String
Returns the locale assigned to the response. If no locale has been set (such as with SetLocale()) then it returns null.
Parameters:
Returns: java.util.Locale
Returns a ServletOutputStream suitable for writing binary data in the response.
Parameters:
Returns: javax.servlet.ServletOutputStream
Return the wrapped ServletResponse object. I am not really sure how this differs from the wrapping response object in terms of functionality. (source)
Parameters:
Returns: javax.servlet.ServletResponse
Returns a PrintWriter object that can send character text to the client. This can write character data to the buffer unline GetOutputStream() which can only take binary data.
Parameters:
Returns: java.io.PrintWriter
Returns a boolean indicating if the response has been committed (as in, has anything been flushed to the client yet including header values).
Parameters:
Returns: boolean
Clears any data that exists in the buffer as well as the status code and headers. I could not actually get this to work. It didn't seem to reset the buffer even when nothing had yet been flushed. (source)
Parameters:
Returns: void
Clears the content of the underlying buffer in the response without clearing headers or status code. I could not get this one to work. (source)
Parameters:
Returns: void
Sends an error response to the client using the specified status code and clearing the buffer. The name of the error gets sent as "Unknown." (source)
Parameters: int
Returns: void
Sends an error response to the client using the specified status code and status message and clearing the buffer. This seemed to pass the value, but I don't know what meaning it has. (source)
Parameters: int, java.lang.String
Returns: void
Sends a temporary redirect response to the client using the specified redirect location URL. This will act just like the CFLocation tag.
Parameters: java.lang.String
Returns: void
Sets the preferred buffer size for the body of the response. The servlet container will use a buffer at least as large as the size requested. I did not bother messing with this.
Parameters: int
Returns: void
Sets the length of the content body in the response In HTTP servlets, this method sets the HTTP Content-Length header. If you set it too small, the content will be cut off. If you set it too big, the browser will keep waiting for more content to come.
Parameters: int
Returns: void
Sets the content type of the response being sent to the client. If obtaining a PrintWriter, this method should be called first. This works like the CFCotent tag / type variable.
Parameters: java.lang.String
Returns:
Sets a response header with the given name and date-value. I did not bother messing with this.
Parameters: java.lang.String, long
Returns: void
Sets a response header with the given name and value. If the header had already been set, the new value overwrites the previous one.
Parameters: java.lang.String, java.lang.String
Returns: void
Sets a response header with the given name and integer value. If the header had already been set, the new value overwrites the previous one.
Parameters: java.lang.String, int
Returns: void
Sets the locale of the response, setting the headers (including the Content-Type's charset) as appropriate. I did not bother messing with this one. (source)
Parameters: java.util.Locale
Returns: void
Sets the response being wrapped. I did not figure out how to mess with this one (nor did I try very hard). (source)
Parameters: javax.servlet.ServletResponse
Returns: void
Sets the status code for this response. This method is used to set the return status code when there is no error
Parameters: int
Returns: void
Sets the status code for this response. This method is used to set the return status code when there is no error
Parameters: int, java.lang.String
Returns: void
Returns the ServletConfig instance. (source).
Parameters:
Returns: javax.servlet.ServletConfig
Returns the ServletContext instance. (source).
Parameters:
Returns: javax.servlet.ServletContext
Returns the current value of the session object (an HttpSession). (source). I could not get this to work.
Parameters:
Returns: javax.servlet.http.HttpSession
I didn't bother messing with this.
Parameters:
Returns: coldfusion.runtime.LocalScope
Not sure what this does.
Parameters: java.lang.Class
Returns: java.lang.Object
Not sure what this does.
Parameters: java.lang.Class, int
Returns: java.lang.Object
Returns the page's VARIABLES scope. Not exactly sure what this is doing. I assume this changed from CFC to page scope.
Parameters:
Returns: coldfusion.runtime.VariableScope
This method is intended to process an unhandled "page" level exception by redirecting the exception to either the specified error page for this JSP, or if none was specified, to perform some implementation dependent action. (source) I could not figure out how to use this.
Parameters: java.lang.Exception
Returns: void
This method is identical to the handlePageException(Exception), except that it accepts a Throwable. This is the preferred method to use as it allows proper implementation of the errorpage semantics. (source) I could not figure out how to use this.
Parameters: java.lang.Throwable
Returns: void
Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable. (source)
Parameters:
Returns: int
Causes the resource specified to be processed as part of the current ServletRequest and ServletResponse being processed by the calling Thread. The output of the target resources processing of the request is written directly to the ServletResponse output stream. (source). Not exactly sure what this does. It appears to include a NEW page request. Cannot get it to stop having 500 NULL error.
Parameters: java.lang.String
Returns: void
[[cfset GetPageContext().include( "./test.cfm" ) /]]
I did NOT want to mess with this one. The initialize method is called to initialize an uninitialized PageContext so that it may be used by a JSP Implementation class to service an incoming request and response within it's _jspService() method. (source).
Parameters: javax.servlet.Servlet, javax.servlet.ServletRequest, javax.servlet.ServletResponse, java.lang.String, boolean, int, boolean
Returns: void
I did NOT want to mess with this one.
Parameters: java.lang.Object, javax.servlet.jsp.PageContext, coldfusion.runtime.VariableScope
Returns: void
I did NOT want to mess with this one.
Parameters: java.lang.Object, javax.servlet.jsp.PageContext, coldfusion.runtime.VariableScope
Returns: void
I did NOT want to mess with this one.
Parameters: javax.servlet.jsp.PageContext
Returns: void
I did NOT want to mess with this one.
Parameters: javax.servlet.jsp.PageContext, boolean
Returns:
Keep getting this CF error "current thread not owner null". Wakes up a single thread that is waiting on this object's monitor. (source)
Parameters:
Returns: void
Keep getting this CF error "current thread not owner null". Wakes up all threads that are waiting on this object's monitor. (source)
Parameters:
Returns: void
I did NOT want to mess with this one. Return the previous JspWriter "out" saved by the matching pushBody(), and update the value of the "out" attribute in the page scope attribute namespace of the PageConxtext. (source).
Parameters:
Returns: javax.servlet.jsp.JspWriter
I could not figure how to use this one. I assume this is how ColdFusion handles function scope chaining.
Parameters:
Returns: void
I could not figure how to use this one. I assume this is how ColdFusion handles nested query loops.
Parameters:
Returns: void
I could not figure how to use this one. I assume this is how ColdFusion handles nested CFC constructors.
Parameters:
Returns: void
I did NOT want to mess with this one.
Parameters:
Returns: void
I could not figure how to use this one.
Parameters: coldfusion.runtime.NeoPageContext
Returns: void
Return a new BodyContent object, save the current "out" JspWriter, and update the value of the "out" attribute in the page scope attribute namespace of the PageContext. (source).
Parameters:
Returns: javax.servlet.jsp.tagext.BodyContent
I did not want to mess with this one. I assume this is how ColdFusion handles local scope chains.
Parameters:
Returns: coldfusion.runtime.LocalScope
I did not want to mess with this one. I assume this is how ColdFusion handles local scope chains.
Parameters: coldfusion.runtime.LocalScope
Returns: void
I did not want to mess with this one. I assume this is how ColdFusion handles nexted query loops.
Parameters: coldfusion.sql.QueryTable
Returns: void
I did not want to mess with this one. I assume this is how ColdFusion handles construtor scope chains (CFC extension).
Parameters: coldfusion.runtime.Scope
Returns: void
No idea what this does.
Parameters: java.lang.Boolean
Returns: void
This method shall "reset" the internal state of a PageContext, releasing all internal references, and preparing the PageContext for potential reuse by a later invocation of initialize(). (source). I could not figure out how to use this.
Parameters:
Returns: void
Removes the given variable from the page scope. I am not sure which scopes it is searched. Definitely VARIABLES. Not sure what else.
Parameters: java.lang.String
Returns: void
Removes the given variable from the given scope. Cannot get this one to work. The scope constants are undefined in the page context.
Parameters: java.lang.String, int
Returns: void
I did not want to mess with this one.
Parameters:
Returns: void
Could not figure how to use this.
Parameters: coldfusion.runtime.ScopeSearchResult
Returns: boolean
Sets the given array (param 2) to a variable of the given name (param 1). Not sure how this is different from SymTab_setSimpleName() or setAttribute().
Parameters: java.lang.String, java.lang.Object
Returns: void
[[cfset GetPageContext().setArrayAttribute( "REQUEST.Nicole", "busty" ) /]]
##REQUEST.Nicole##
Outputs: busty
Sets the given value (param 2) to a variable of the given name (param 1). Not sure how this is different from SymTab_setSimpleName() or setArrayAttribute().
Parameters: java.lang.String, java.lang.Object
Returns: void
[[cfset GetPageContext().setAttribute( "REQUEST.Nicole", "very naughty" ) /]]
##REQUEST.Nicole##
Outputs: very naughty
Sets the given value (param 2) to a variable of the given name (param 1) within the given scope (param 3). Could not get this to work in any predictable way.
Parameters: java.lang.String, java.lang.Object, int
Returns:
Turns on (true) and off (false) the flushing of content to the client. If you set it to false, no more content will be flushed, however, actions will continue to be processed and an internal buffer is still be created.
Parameters: boolean
Returns:
Set the ColdFusion scopes that are automatically searched when scope-less variables are referenced. This seems to be the same as setBuiltinCFScopes().
Parameters: java.util.Vector
Returns: void
[[cfset REQUEST.Kim = "silly" /]]
##Kim##
Outputs: [CFERROR: UNDEFINED VARIABLE]
[[cfset REQUEST.Kim = "silly" /]]
[[cfset arrScopes = ArrayNew( 1 ) /]] [[cfset ArrayAppend( arrScopes, REQUEST ) /]] [[cfset GetPageContext().setImplicitCFScopes( arrScopes ) /]] ##Kim##
Outputs: silly
Set the VARIABLES scope for the page. Not sure exactly what this is doing; I assume it is how the VARIABLES scope is changed from CFC to page.
Parameters: coldfusion.runtime.VariableScope
Returns: void
Returns a string representation of the object. (source).
Parameters:
Returns: java.lang.String
I did not want to mess with this one.
Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. (source).
Parameters:
Returns: void
Causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed. (source). When I try to invoke this, I get a CF Error "current thread not owner".
Parameters: long
Returns: void
Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed. (source). When I try to invoke this, I get a CF Error "current thread not owner".
Parameters: long, int
Returns: void
Comments (18) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
Ben,
Congrats for making that HUGE list. This is some interesting information. Have you thought up any interesting tricks using the above functions, or was this an exercise in seeing how CF is put together?
DW
Posted by Dan Wilson on Jun 6, 2007 at 8:31 PM
Awesome list Ben! Here's one you can add:
""
getCFOutput().getDisableCount
Not sure what this is supposed to do.
""
This method is used for handling <cfsetting enablecfoutputonly="true">.
Whenever you use this tag the Output Disable Count increases by one, doing <cfsetting enablecfoutputonly="false"> decreases it by one.
This is used when the server tries to figure out if content outside a cfoutput should be output to the page. Output only happens outside a cfoutput if the Disable Count is 0.
This is actually very useful if you're trying to figure out why content isn't being output, and you want to search for that enablecfoutputonly="true" that has no matching enablecfoutputonly="false" :)
For an example see:
This behavior is also mentioned in the docs:
http://livedocs.adobe.com/coldfusion/6.1/htmldocs/tags-pc6.htm
""
If you nest cfsetting tags: to make HTML output visible, you must match each enableCFoutputOnly = "Yes" statement with an enableCFoutputOnly = "No" statement. For example, after five enableCFoutputOnly = "Yes" statements, to enable HTML output, you must have five corresponding enableCFoutputOnly = "No" statements.
""
(This is because the disable count must return to 0 for output outside cfoutput to work.)
""
If HTML output is enabled (no matter how many enableCFoutputOnly = "No" statements have been processed) the first enableCFoutputOnly = "Yes" statement blocks output.
""
(This is because you're just going from 0 to 1)
Posted by Elliott Sprehn on Jun 7, 2007 at 1:34 AM
Excellent work Ben.
I'm bookmarking this one.
Cheers.
--
Adam
Posted by Adam Cameron on Jun 7, 2007 at 4:50 AM
@Dan,
I did this cause GetPageContext() is not really documented very well anywhere and I really wanted to learn a little about, see if there is some cool stuff under here. A lot of the Java stuff is a little hard for me to wrap my head around. Like, I don't really understand what a Servlet is and things of that nature.
As far as cool stuff - there is some interesting things. The different buffers you can have access to - the character buffer and the binary buffer. Of course, that sort of stuff is nicely packaged by ColdFusion so you don't have to see it (ex. CFContent / VARIABLE attribute will write to the binary buffer (I assume)).
The things I like most:
getFusionContext().getStartTime
- Gets the date/time the page started processing
getResponse().isCommitted
- Determines if the headers have been flushed. I think Ray Camden uses that in his ColdFire code.
SymTab_setBuiltinCFScopes
- You can add scopes to the vactor of scops that ColdFusion will search for variable names. I would not suggest messing with it, but it's cool to see how that can be controlled.
@Elliot,
Thanks for the tip. I tried looking into it, but I had no idea what it was doing. I will update my post. I can see how something like that could be very useful, especially with something like my ColdFusion custom tag for CFSetting ( http://bennadel.com/index.cfm?dax=blog:297.view ).
@Adam,
Thanks. I hope to keep expanding on it as there are many parts of not looked at yet.
Posted by Ben Nadel on Jun 7, 2007 at 7:23 AM
Damn! Enough said.
Posted by Boyan on Jun 8, 2007 at 11:05 AM
Hi Ben,
Thanks for posting this list! I did not find what I was looking for though, which is: the methods that have to do with setting the cfhtmlhead's text into the output.
Did you perhaps find anything in getPageContext() that has to do with <cfhtmlhead> ?
The actual answer I'm searching for, is: how can the contents which are set with <cfhtmlhead> be reset / removed / suppressed?
Thanks anyway for the exploration. "I learned something today..." :)
Posted by Paul Klinkenberg on Jul 12, 2007 at 7:07 AM
@Paul,
While I am not exactly sure how the CFHtmlHead tag works, my guess is that it is just replacing the HTML </head> with [content]</head> in the current content buffer. Remember, the HTML really has nothing to do with ColdFusion, so it's not there are any special hooks that ColdFusion is using. The best it can really do is look at the content that has not yet been flushed to the screen.
When you say you want to suppress it or remove it, I am not sure what you mean. The CFHtmlHead content must be put in explicitly. If you don't want to use it, then just don't put it in your code.
If you tell me a bit more about your situation, maybe I can help you come up with a better solution.
Posted by Ben Nadel on Jul 12, 2007 at 8:58 AM
Hi Ben, thanks for your answer.
cfhtmlhead does not work the way you guessed in your answer.
If you create a cfm page with these 3 lines:
output 1<br />
<cfhtmlhead text="output 2 (with cfhtmlhead)<br />" />
output 3<br />
and then output it, you will see the second line (written with cfhtmlhead) is on top.
This is because CF checks, just before flushing the contents to the user, if a <head> tag exists, and if so, put the text inside the <head>. otherwise, the text will be placed at the beginning of the file.
CF does not check the existence of the <head> tag while the <cfhtmlhead> tag is executing, but only at the _end_ of the request (or while the first cfflush is done).
This can be tested by adding a 4th line to the test cfm page:
<head></head>
You will see the cfhtmlhead text will now be at the bottom of the output, because it is put inside the <head> section.
Okay, enough testing.
Because coldfusion saves up the cfhtmlhead text value untill the first output is sent to the browser, I figured there must be a way to get to that stored text. And more important, to manipulate that text.
A normal <cfcontent reset="yes" /> does not get rid of the text, nor does a clearBuffer() etc.
My reason for wanting to know is pure CF enthousiasm; off course we can write a cfif around the cfhtmlhead tag, but I would just like to find out how it is done. And I'm working with 4 other cf enthousiasts who also don't know the answer to this, so it's even a bigger challenge to find out :)
I stilll think it should be somewhere inside the getPageContext() env., but haven't found it.
Posted by Paul Klinkenberg on Jul 12, 2007 at 9:23 AM
Interesting. I see what you are saying now. Yeah, it must be held in some separate buffer because I think you can call CFHtmlHead several times before the flush and the result is the aggregate of the various calls.
I can't say that I know how to clear that buffer or even read it, off hand. GetPageContext() is so freakin' huge! I will let you know if I come across anything.
Posted by Ben Nadel on Jul 12, 2007 at 1:23 PM
Paul is right, it's buffered and then appended when the content is flushed to the client. If a <head> exists it's added to that, else it just ends up appended to the beginning of the buffer.
Unfortunately there is no real API for doing what you want, even in the internals of the CF engine. I guess they just didn't think we'd need to clear or get the head content? However, using reflection we can do everything you're looking to do.
I put together a simple API: http://enfinitystudios.thaposse.net/personal/coldfusion/cfhtmlhead-api.cfm
Enjoy. :)
Posted by Elliott Sprehn on Jul 12, 2007 at 2:17 PM
Elliott, wow, I'm impressed!
The function resetCfHtmlHead() is exactly what I was looking for! And I mean exactly!
Are you using these functions in dev environment, or did you just create them as an example for your post?
And especially, how did you know where to look, within the getPageContext()? Decompiled CF ;-) ? Or working at Adobe perhaps?
Anyway, thanks for the script, I really appreciate it!
btw: tested it on CF 8,0,0,165965 (beta 2), and works like a charm.
Posted by Paul Klinkenberg on Jul 13, 2007 at 4:48 AM
@Paul
It's not that easy to look into most Objects MetaData using the <cfdump...> Tag.
For example, you could dump the PageContext's MetaData:
<cfset pc = GetPageContext()>
<cfdump var="#pc#">
You can dump almost everything, but of course it will still remain basic meta data. You can guess what it actually does, and of course, call it and try it out.
Posted by Thomas on Jul 13, 2007 at 8:02 AM
@Thomas
Some of the mentioned functions (in the cfc) are not exposed by dumping them, they are typed as private.
Therefore I was wondering how Elliott found out about the function initHeaderBuffer(), and the field 'headerBuffer' etc.
Posted by Paul Klinkenberg on Jul 13, 2007 at 8:14 AM
DJ Java Decompiler FTW!
http://members.fortunecity.com/neshkov/dj.html
I used this neat program to find bugs, or actually work arounds of known bugs in ColdFusion.
Posted by Unknown on Jul 13, 2007 at 8:37 AM
There is also the rather useful ClassViewer.class floating around (well actually I've only eveer seen the .java file on the web, but it amounts to the same thing).
If passed an object, it will use reflection to output all the object's member variables, methods, expected arguments (and types), and return types, as text. Quite a bit easier to understand than a decomp-ed Java class.
I spent 5min googling for it and drew a blank... if anyone wants the source code and cannot find it, drop me a line at adam_junk@hotmail.com, and I'll flick it to you.
--
Adam
Posted by Adam Cameron on Jul 13, 2007 at 3:09 PM
@Elliot,
That's pretty nifty. I wish I understood the getCFHtmlHeadContent() method a bit better, but at that point, I think I just need to learn some Java goodness.
@Adam,
Yeah, some guy at my office was using some cool program to decompile Java files. I will talk to him next week see if he can remember what it was.
Posted by Ben Nadel on Jul 13, 2007 at 6:31 PM
@Ben
The field headerBuffer is where writeHeader() is appending when you call that method, which is really all <cfhtmlhead> does.
The field is declared as:
private CharArrayWriter headerBuffer;
in the class and it looks like CF lazy allocates that writer so it'll be null if you haven't called <cfhtmlhead> yet.
So the first thing I do is get a reference to the Field object that represents all "headerBuffer" fields (member variables) for NeoJspWriter objects.
Now we have a problem, the field is private so trying to use it directly will throw an access exception. Like calling a private function in CF on an instance of a component. So we setAccesible(true) so we can access it.
Now we can use the get( instance ) function on the Field object to get the private field.
Now we have another problem. If we haven't called <cfhtmlhead> yet we'd get an error when we try to return because the get() returned null. To work around this we can use isDefined() which effectively is a shortcut to check if a variable evaluates to null.
That allows us to get the field and then return an empty string if it's null. If it's not null then we have a CharArrayWriter that has the cfhtmlhead content in it. To make that useful in ColdFusion we call toString() on it which turns the array into a string (much like a StringBuffer).
And there you go! You can do some pretty wicked stuff with CF if you get down and dirty with the Java reflection API.
You might also want to see:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Field.html
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Method.html
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Class.html
On an interesting note today I figured out how to replicate the <cfdbinfo type="tables"> call in CF6 and CF7 using similar inspection techniques. I've also got adding mappings and custom tag paths worked out.
I'll blog about that soon and then people without the resources to upgrade to CF8 can realize many of the same benefits. Even more important using this technique we should be able to write frameworks that work with both CF8, CF7 and CF6 and still get the benefits of things like cfdbinfo!
ColdFusion rocks. I wish more people could see that. :)
Posted by Elliott Sprehn on Jul 13, 2007 at 9:03 PM
@Paul
Nope, I work for TeraTech, not Adobe. ;) Figuring out how CF works internally isn't terribly hard though. While you could decompile the classes, you can just use the java reflection API to learn a whole lot about what's really going on inside the engine.
I figured it out by deduction. If you were going to hold data to be output into the output buffer in a specific place (in the <head>) you'd want to store that data somewhere in the output buffer so when it was flushed it would get added. I know the NeoPageContext#flush() method is what is called when you do a cfflush, so that's where I started looking.
So I looked at getPageContext().getOut() and saw there was a writeHeader() method that took a string. So I tested that and found it was the same as cfhtmlhead.
The next step was looking for an API to get to whatever that thing changed. Unfortunately there isn't one so I looked at getDeclaredFields() to check the instance members. Fortunately there was one nicely named headerBuffer, so I checked the contents of that after I used writeHeader() and sure enough that's where the data was.
Next I played around with it and realized that I'd get a nasty null error if I hadn't called cfhtmlhead or writeHeader() when I tried to get the buffer so I knew I needed to add the null check to it.
I've not really tested that in a production environment, it was just a proof of concept I put together when I saw your comment. I can't imagine it should cause you any major problems though.
There is one side effect that I have noticed though. If you cfflush the output and then call cfhtmlhead you normally get an exception, even if the <head> hasn't been output yet. However, after you call resetCFHtmlHead() in my api you can cfhtmlhead again and not get an exception.
The writeCFHtmlHead() function also *never* throws an exception, even if a flush has already happened. It just fails silently. This seems to imply that the error that is usually thrown is from inside the coldfusion.tagext.html.HtmlHeadTag and not in the NeoJspWriter#writeHeader() function.
I guess these are kind of a features, right? :)
Posted by Elliott Sprehn on Jul 14, 2007 at 1:20 AM