Learning ColdFusion 8: Ping - User Defined Function (Inspired By Ray Camden)

<cffunction
	name="Ping"
	access="public"
	returntype="void"
	output="false"
	hint="Pings the given URL in an asynchronous fashion. Will download the result if a file name is given.">
 
	<!--- Define arguments. --->
	<cfargument
		name="URL"
		type="string"
		required="true"
		hint="The URL to be called using CFHttp."
		/>
 
	<cfargument
		name="File"
		type="string"
		required="false"
		default=""
		hint="File to which the CFHttp binary result will be stored."
		/>
 
 
	<!--- Define the local scope. --->
	<cfset var LOCAL = {} />
 
 
	<!---
		Create the attributes collection that we are
		going to use when firing the CFHttp tag.
	--->
	<cfset LOCAL.Attributes = {} />
 
	<!--- Set the URL. --->
	<cfset LOCAL.Attributes.URL = ARGUMENTS.URL />
 
	<!---
		Set the method. In this case, we are going to default
		to HEAD since we don't care about the response body
		unless we are goint to download the file.
	--->
	<cfset LOCAL.Attributes.Method = "HEAD" />
 
	<!--- Set the user agent. --->
	<cfset LOCAL.Attributes.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4" />
 
 
	<!---
		Check to see if a file name was given for
		the binary download.
	--->
	<cfif ARGUMENTS.File.Length()>
 
		<!---
			Set the method to GET since we are going
			to be downloading the file - we need to
			have a response body.
		--->
		<cfset LOCAL.Attributes.Method = "GET" />
 
		<!--- Flag for the binary get. --->
		<cfset LOCAL.Attributes.GetAsBinary = "yes" />
 
		<!--- Give the path for the file. --->
		<cfset LOCAL.Attributes.Path = GetDirectoryFromPath(
			ARGUMENTS.File
			) />
 
		<!--- Give the file name to store. --->
		<cfset LOCAL.Attributes.File = GetFileFromPath(
			ARGUMENTS.File
			) />
 
 
		<!---
			There is a chance that only a directory was
			supplied. If this is the case, try to grab the
			file name from the URL as the target file.
		--->
		<cfif (
			(NOT LOCAL.Attributes.File.Length()) AND
			(GetFileFromPath( ARGUMENTS.URL ).Length())
			) >
 
			<!--- Grab the file name from the URL. --->
			<cfset LOCAL.Attributes.File = GetFileFromPath(
				ARGUMENTS.URL
				) />
 
		</cfif>
 
	</cfif>
 
 
 
	<!---
		When using the CFHttp tag, we are going to need to
		use a CFTry / CFCatch since we might be storing the
		result to a file (plus to catch any other error that
		might arise, like a timeout).
	--->
	<cftry>
 
		<!---
			When executing our CFHttp call, we are going to
			wrap it up in a CFThread tag to allow us to set
			it and forget it in an asynchronous manner.
 
			When launching the CFThread tag, we need to pass
			in any variables that are NOT stored in the
			VARIABLES scope. In this case, we need to pass
			in both the attribute collection structures as
			well as the referer that we want to use in the
			CFHttp call.
		--->
		<cfthread
			action="run"
			name="cfhttp_#CreateUUID()#"
			attributes="#LOCAL.Attributes#"
			referer="#ARGUMENTS.URL#">
 
			<!---
				Fire the CFHttp tag using our attributes
				collection. Remember, when we use the
				attributes collection, no other attributes
				can be used.
			--->
			<cfhttp
				attributecollection="#ATTRIBUTES.Attributes#">
 
				<!---
					Pass in the target as the referer. This
					will just help make sure no security
					issues block us.
				--->
				<cfhttpparam
					type="CGI"
					name="referer"
					value="#ATTRIBUTES.Referer#"
					/>
 
			</cfhttp>
 
		</cfthread>
 
		<cfcatch>
			<!--- An error occurred. --->
		</cfcatch>
	</cftry>
 
 
	<!--- Return out. --->
	<cfreturn />
</cffunction>

For Cut-and-Paste