So I was working with CFHTTP the other day and noticed a strange behavior. There are two attributes I want to focus on: resolveurl and redirect. When setting redirect equal to true, ColdFusion will follow up to four 30x redirects (if a location header is provided) the most common being 302 (moved temporarily) and 301 (moved permanently). Redirects actually happen more often than you probably think. Did you know every time you type in a URL like "www.server.com/folder" your browser has to make two requests to get the page. There might be a file called "folder", but if there isn't, a 302 comes back and says check out "www.server.com/folder/" (with the trailing slash). A very common example of the 301 redirect is when you type in "yahoo.com". The server comes back and says try "www.yahoo.com".The resolveurl attribute takes any relative URLs living in one of the following tags/attributes
  • img src
  • a href
  • form action
  • applet code
  • script src
  • embed src
  • embed pluginspace
  • body background
  • frame src
  • bgsound src
  • object data
  • object classid
  • object codebase
  • object usemap
and fully qualifies them absolute URLs so
[code]<img src="/modules/contentbox/content/blogImages/avitar.jpg">[/code]
becomes:
[code]<img src="/modules/contentbox/content/blogImages/avitar.jpg">[/code]
So far, so good. Now, here's the problem: When following one or more redirects ColdFusion will resolve any relative URLs in the final document to the original server/path. That means that if www.foo.com redirects to www.bar.com all of the images and links etc from bar.com will be incorrectly resolved to foo.com (where they probably don't exist). Furthermore, the cfhttp struct that is returned doesn't tell you if you followed a redirect or not, nor does it tell you what the final address was that it fetched for you. I get this with CF 7 and 8. I asked about this on the CF-Talk list and got a whole bunch of crickets so I finally submitted it as a bug at www.adobe.com/go/wish/. In the mean time, here's my work-around. This code tells ColdFusion not to follow redirects. Instead it loops itslef until it gets to the final page.
[code]
<cfset this_url = "http://www.server.com">
<cfset keep_looking = true>

<cfloop condition="keep_looking">

	<cfhttp 
		url="#this_url#"
		method="GET"
		redirect="no"
		resolveurl="true"
		timeout="10"
		userAgent="#cgi.HTTP_USER_AGENT#"
		charset="utf-8">
		<cfhttpparam type="Header" name="Accept-Encoding" value="deflate;q=0">
		<cfhttpparam type="Header" name="TE" value="deflate;q=0">
	</cfhttp>

	<cfif structkeyexists(cfhttp.responseheader,"status_code") and
		listfindnocase("301,302",cfhttp.responseheader.status_code)  
		and structkeyexists(cfhttp.responseheader,"location") 
		and len(trim(cfhttp.responseheader.location))>
		<cfset this_url = cfhttp.responseheader.location>
	<cfelse>
		<cfset keep_looking = false>
	</cfif>

</cfloop>
[/code]
Now this_url contains the final URL I hit, and since I resolved the URLs one step at a time, I know my images and links etc are resolved correctly. If you are wondering about the extra header values I have in there, it turns out Java (and therefore ColdFusion) can't handle HTTP compression. The the header info tells the remote server not to encode or compress the reply. Also I ask for it in UTF-8.