Image Hot Linking Work-Around

Downloadable Files

cfhttp_image.cfm1.txt ( 5,688 Bytes )

I didn't even know what "Hot Linking" was until recently when I was using CFHttp calls to help me practice my Java Regular Expressions. As an exercise, I was grabbing content off of random sites and using regular expressions to get the image and link tags. When I dumped out the results, only 50% of the images were showing up. Apparently, many servers block external linking to their local content. I suppose this makes sense both from a bandwidth and a business point of view.

I found this really interesting and wanted to try and work around it. I came up with a solution that works about 95% of the time. You have to "fake" the server into thinking that you are requesting the image from the originating page by setting the referer url to that of the originating page. It seems to fail some of the time. I guess some servers are using a more sophisticated method of blocking.

The following code requires the src of the image AND the original URL of the page that was used in the CFHttp:

  • <!--- Kill extra output. --->
  • <cfsilent>
  •  
  • <!--- Set page settings. --->
  • <cfsetting showdebugoutput="false" />
  •  
  • <!--- Param url variables. --->
  •  
  • <!--- This is the URL of the image that is being "grabbed". --->
  • <cfparam
  • name="URL.src"
  • type="string"
  • default=""
  • />
  •  
  • <!--- This is the URL of the original page where the graphic lives. --->
  • <cfparam
  • name="URL.referer"
  • type="string"
  • default=""
  • />
  •  
  • <!--- Set up a variable to hold the base64 encoding of our "no image" image. --->
  • <cfset strNoImage64 = ".....[ BASE 64 DATA HERE ]....." />
  •  
  • <!--- Check to see if we have any referer. --->
  • <cfif NOT Len(URL.referer)>
  •  
  • <!--- Get the referer based on the image. --->
  • <cfset URL.referer = REReplace( URL.src, "(/|\\)[^/\\]+$", "\1", "ONE" ) />
  •  
  • </cfif>
  •  
  • <!---
  • Grab the source image. Here we are sending the src of the image, the FireFox
  • user agent, and the referer url. We are grabbing the contetn as binary as it
  • should be an image.
  • --->
  • <cfhttp
  • url="#URL.src#"
  • method="GET"
  • useragent="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.2) Gecko/20060308 Firefox/1.5.0.2"
  • getasbinary="yes"
  • result="objHttp">
  •  
  • <!--- Set referrer params. --->
  • <cfhttpparam type="CGI" name="http_referer" value="#URL.referer#" encoded="false" />
  • </cfhttp>
  •  
  • <!--- Check to see if we found the image. --->
  • <cfif (
  • FindNoCase( "200", objHttp.Statuscode ) AND
  • FindNoCase( "image", objHttp.Responseheader["Content-Type"] )
  • )>
  •  
  • <!--- We have an image, so get its content. --->
  • <cfset binImage = objHttp.FileContent />
  •  
  • <cfelse>
  •  
  • <!--- We didn't find an image, so put in a not-found image. --->
  • <cfset binImage = ToBinary( strNoImage64 ) />
  •  
  • </cfif>
  •  
  • <!---
  • CODE ASSERTION
  • At this point, we will have a binary image object in the binImage variable. It may be the
  • image that we grabbed off the site, but it may be the image of the "no image". Either way,
  • we should have no problem at this point to return an image object to the content stream.
  • --->
  • </cfsilent>
  •  
  • <!---
  • Try to return the image. If there is any problem with the binary data, then we will
  • end up just streaming our no-image image.
  • --->
  • <cftry>
  •  
  • <!--- Clear the buffer and stream the content. --->
  • <cfset GetPageContext().GetOut().ClearBuffer()
  • /><cfcontent
  • type="image/jpg"
  • variable="#binImage#"
  • />
  •  
  • <cfcatch>
  •  
  • <!---
  • The returned image didn't work. So, return the no image found,
  • which should alway work.
  • --->
  • <cfset GetPageContext().GetOut().ClearBuffer()
  • /><cfcontent
  • type="image/jpg"
  • variable="#ToBinary( strNoImage64 )#"
  • />
  •  
  • </cfcatch>
  • </cftry>

Added April 28, 2006 / Updated July 13, 2006