<cfcomponent
output="false"
hint="Handles a CFHTTP session by sending an receving cookies behind the scenes.">
<cfset VARIABLES.Instance = {} />
<cfset VARIABLES.Instance.Cookies = {} />
<cfset VARIABLES.Instance.RequestData = {} />
<cfset VARIABLES.Instance.RequestData.Url = "" />
<cfset VARIABLES.Instance.RequestData.Referer = "" />
<cfset VARIABLES.Instance.RequestData.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6" />
<cfset VARIABLES.Instance.RequestData.Params = [] />
<cffunction
name="Init"
access="public"
returntype="any"
output="false"
hint="Returns an initialized component.">
<cfargument
name="UserAgent"
type="string"
required="false"
hint="The user agent that will be used on the subseqent page requests."
/>
<cfif StructKeyExists( ARGUMENTS, "UserAgent" )>
<cfset THIS.SetUserAgent( ARGUMENTS.UserAgent ) />
</cfif>
<cfreturn THIS />
</cffunction>
<cffunction
name="AddCGI"
access="public"
returntype="any"
output="false"
hint="Adds a CGI value. Returns THIS scope for method chaining.">
<cfargument
name="Name"
type="string"
required="true"
hint="The name of the CGI value."
/>
<cfargument
name="Value"
type="string"
required="true"
hint="The CGI value."
/>
<cfargument
name="Encoded"
type="string"
required="false"
default="yes"
hint="Determins whether or not to encode the CGI value."
/>
<cfreturn THIS.AddParam(
Type = "CGI",
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value,
Encoded = ARGUMENTS.Encoded
) />
</cffunction>
<cffunction
name="AddCookie"
access="public"
returntype="any"
output="false"
hint="Adds a cookie value. Returns THIS scope for method chaining.">
<cfargument
name="Name"
type="string"
required="true"
hint="The name of the CGI value."
/>
<cfargument
name="Value"
type="string"
required="true"
hint="The CGI value."
/>
<cfreturn THIS.AddParam(
Type = "Cookie",
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value
) />
</cffunction>
<cffunction
name="AddFile"
access="public"
returntype="any"
output="false"
hint="Adds a file value. Returns THIS scope for method chaining.">
<cfargument
name="Name"
type="string"
required="true"
hint="The name of the form field for the posted file."
/>
<cfargument
name="Path"
type="string"
required="true"
hint="The expanded path to the file."
/>
<cfargument
name="MimeType"
type="string"
required="false"
default="application/octet-stream"
hint="The mime type of the posted file. Defaults to *unknown* mime type."
/>
<cfreturn THIS.AddParam(
Type = "Cookie",
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value
) />
</cffunction>
<cffunction
name="AddFormField"
access="public"
returntype="any"
output="false"
hint="Adds a form value. Returns THIS scope for method chaining.">
<cfargument
name="Name"
type="string"
required="true"
hint="The name of the form field."
/>
<cfargument
name="Value"
type="string"
required="true"
hint="The form field value."
/>
<cfargument
name="Encoded"
type="string"
required="false"
default="yes"
hint="Determins whether or not to encode the form value."
/>
<cfreturn THIS.AddParam(
Type = "FormField",
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value,
Encoded = ARGUMENTS.Encoded
) />
</cffunction>
<cffunction
name="AddHeader"
access="public"
returntype="any"
output="false"
hint="Adds a header value. Returns THIS scope for method chaining.">
<cfargument
name="Name"
type="string"
required="true"
hint="The name of the header value."
/>
<cfargument
name="Value"
type="string"
required="true"
hint="The header value."
/>
<cfreturn THIS.AddParam(
Type = "Header",
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value
) />
</cffunction>
<cffunction
name="AddParam"
access="public"
returntype="any"
output="false"
hint="Adds a CFHttpParam data point. Returns THIS scope for method chaining.">
<cfargument
name="Type"
type="string"
required="true"
hint="The type of data point."
/>
<cfargument
name="Name"
type="string"
required="true"
hint="The name of the data point."
/>
<cfargument
name="Value"
type="any"
required="true"
hint="The value of the data point."
/>
<cfargument
name="File"
type="string"
required="false"
default=""
hint="The expanded path to be used if the data piont is a file."
/>
<cfargument
name="MimeType"
type="string"
required="false"
default=""
hint="The mime type of the file being passed (if file is being passed)."
/>
<cfargument
name="Encoded"
type="string"
required="false"
default="yes"
hint="The determines whether or not to encode Form Field and CGI values."
/>
<cfset var LOCAL = {} />
<cfswitch expression="#ARGUMENTS.Type#">
<cfcase value="Body">
<cfset LOCAL.Param = {
Type = ARGUMENTS.Type,
Value = ARGUMENTS.Value
} />
</cfcase>
<cfcase value="CGI">
<cfset LOCAL.Param = {
Type = ARGUMENTS.Type,
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value,
Encoded = ARGUMENTS.Encoded
} />
</cfcase>
<cfcase value="Cookie">
<cfset LOCAL.Param = {
Type = ARGUMENTS.Type,
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value
} />
</cfcase>
<cfcase value="File">
<cfset LOCAL.Param = {
Type = ARGUMENTS.Type,
Name = ARGUMENTS.Name,
File = ARGUMENTS.File,
MimeType = ARGUMENTS.MimeType
} />
</cfcase>
<cfcase value="FormField">
<cfset LOCAL.Param = {
Type = ARGUMENTS.Type,
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value,
Encoded = ARGUMENTS.Encoded
} />
</cfcase>
<cfcase value="Header">
<cfset LOCAL.Param = {
Type = ARGUMENTS.Type,
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value
} />
</cfcase>
<cfcase value="Url">
<cfset LOCAL.Param = {
Type = ARGUMENTS.Type,
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value
} />
</cfcase>
<cfcase value="Xml">
<cfset LOCAL.Param = {
Type = ARGUMENTS.Type,
Value = ARGUMENTS.Value
} />
</cfcase>
</cfswitch>
<cfset ArrayAppend(
VARIABLES.Instance.RequestData.Params,
LOCAL.Param
) />
<cfreturn THIS />
</cffunction>
<cffunction
name="AddUrl"
access="public"
returntype="any"
output="false"
hint="Adds a url value. Returns THIS scope for method chaining.">
<cfargument
name="Name"
type="string"
required="true"
hint="The name of the header value."
/>
<cfargument
name="Value"
type="string"
required="true"
hint="The header value."
/>
<cfreturn THIS.AddParam(
Type = "Url",
Name = ARGUMENTS.Name,
Value = ARGUMENTS.Value
) />
</cffunction>
<cffunction
name="Get"
access="public"
returntype="struct"
output="false"
hint="Uses the GET method to place the next request. Returns the CFHttp response.">
<cfargument
name="GetAsBinary"
type="string"
required="false"
default="auto"
hint="Determines how to return the file content - return as binary value."
/>
<cfargument
name="Debug"
type="boolean"
required="false"
default="false"
hint="If this is true, then the response object will be dumped out and the page will be aborted."
/>
<cfreturn THIS.Request(
Method = "get",
GetAsBinary = ARGUMENTS.GetAsBinary,
Debug = ARGUMENTS.Debug
) />
</cffunction>
<cffunction
name="GetCookies"
access="public"
returntype="struct"
output="false"
hint="Returns the internal session cookies.">
<cfreturn VARIABLES.Instance.Cookies />
</cffunction>
<cffunction
name="NewRequest"
access="public"
returntype="any"
output="false"
hint="Sets up the object for a new request. Returns THIS scope for method chaining.">
<cfargument
name="Url"
type="string"
required="true"
hint="The URL for the new request."
/>
<cfargument
name="Referer"
type="string"
required="false"
default=""
hint="The referring URL for the request. By default, it will be the same directory as the target URL."
/>
<cfif Len( VARIABLES.Instance.RequestData.Url )>
<cfset VARIABLES.Instance.RequestData.Referer = VARIABLES.Instance.RequestData.Url />
</cfif>
<cfset VARIABLES.Instance.RequestData.Url = ARGUMENTS.Url />
<cfif Len( ARGUMENTS.Referer )>
<cfset VARIABLES.Instance.RequestData.Referer = ARGUMENTS.Referer />
</cfif>
<cfset VARIABLES.Instance.RequestData.Params = [] />
<cfreturn THIS />
</cffunction>
<cffunction
name="Post"
access="public"
returntype="struct"
output="false"
hint="Uses the POST method to place the next request. Returns the CFHttp response.">
<cfargument
name="GetAsBinary"
type="string"
required="false"
default="auto"
hint="Determines how to return the file content - return as binary value."
/>
<cfargument
name="Debug"
type="boolean"
required="false"
default="false"
hint="If this is true, then the response object will be dumped out and the page will be aborted."
/>
<cfreturn THIS.Request(
Method = "post",
GetAsBinary = ARGUMENTS.GetAsBinary,
Debug = ARGUMENTS.Debug
) />
</cffunction>
<cffunction
name="Request"
access="public"
returntype="struct"
output="false"
hint="Performs the CFHttp request and returns the response.">
<cfargument
name="Method"
type="string"
required="false"
default="get"
hint="The type of request to make."
/>
<cfargument
name="GetAsBinary"
type="string"
required="false"
default="auto"
hint="Determines how to return body."
/>
<cfargument
name="Debug"
type="boolean"
required="false"
default="false"
hint="If this is true, then the response object will be dumped out and the page will be aborted."
/>
<cfset var LOCAL = {} />
<cfhttp
url="#VARIABLES.Instance.RequestData.Url#"
method="#ARGUMENTS.Method#"
useragent="#VARIABLES.Instance.RequestData.UserAgent#"
getasbinary="#ARGUMENTS.GetAsBinary#"
redirect="no"
result="LOCAL.Get">
<cfloop
item="LOCAL.Key"
collection="#VARIABLES.Instance.Cookies#">
<cfhttpparam
type="cookie"
name="#LOCAL.Key#"
value="#VARIABLES.Instance.Cookies[ LOCAL.Key ].Value#"
/>
</cfloop>
<cfhttpparam
type="header"
name="referer"
value="#VARIABLES.Instance.RequestData.Referer#"
/>
<cfloop
index="LOCAL.Param"
array="#VARIABLES.Instance.RequestData.Params#">
<cfhttpparam
attributecollection="#LOCAL.Param#"
/>
</cfloop>
</cfhttp>
<cfif ARGUMENTS.Debug>
<cfdump var="#VARIABLES.Instance.RequestData#" />
<cfset WriteOutput( LOCAL.Get.FileContent ) />
<cfdump var="#LOCAL.Get#" />
<cfabort />
</cfif>
<cfset StoreResponseCookies( LOCAL.Get ) />
<cfif StructKeyExists( LOCAL.Get.ResponseHeader, "Location" )>
<cfif REFindNoCase(
"^http",
LOCAL.Get.ResponseHeader.Location
)>
<cfreturn THIS
.NewRequest( LOCAL.Get.ResponseHeader.Location )
.Get()
/>
<cfelse>
<cfreturn THIS
.NewRequest(
GetDirectoryFromPath( VARIABLES.Instance.RequestData.Url ) &
LOCAL.Get.ResponseHeader.Location
)
.Get()
/>
</cfif>
<cfelse>
<cfreturn LOCAL.Get />
</cfif>
</cffunction>
<cffunction
name="SetBody"
access="public"
returntype="any"
output="false"
hint="Sets the body data of next request. Returns THIS scope for method chaining.">
<cfargument
name="Value"
type="any"
required="false"
hint="The data body."
/>
<cfreturn THIS.AddParam(
Type = "Body",
Name = "",
Value = ARGUMENTS.Value
) />
</cffunction>
<cffunction
name="SetUserAgent"
access="public"
returntype="any"
output="false"
hint="Sets the user agent for next request. Returns THIS scope for method chaining.">
<cfargument
name="Value"
type="string"
required="false"
hint="The user agent that will be used on the subseqent page requests."
/>
<cfset VARIABLES.Instance.RequestData.UserAgent = ARGUMENTS.UserAgent />
<cfreturn THIS />
</cffunction>
<cffunction
name="SetXml"
access="public"
returntype="any"
output="false"
hint="Sets the XML body data of next request. Returns THIS scope for method chaining.">
<cfargument
name="Value"
type="any"
required="false"
hint="The data body."
/>
<cfreturn THIS.AddParam(
Type = "Xml",
Name = "",
Value = ARGUMENTS.Value
) />
</cffunction>
<cffunction
name="StoreResponseCookies"
access="public"
returntype="void"
output="false"
hint="This parses the response of a CFHttp call and puts the cookies into a struct.">
<cfargument
name="Response"
type="struct"
required="true"
hint="The response of a CFHttp call."
/>
<cfset var LOCAL = StructNew() />
<cfset LOCAL.Cookies = StructNew() />
<cfif NOT StructKeyExists(
ARGUMENTS.Response.ResponseHeader,
"Set-Cookie"
)>
<cfreturn />
</cfif>
<cfif IsSimpleValue( ARGUMENTS.Response.ResponseHeader[ "Set-Cookie" ] )>
<cfset LOCAL.ReturnedCookies = {} />
<cfset LOCAL.ReturnedCookies[ 1 ] = ARGUMENTS.Response.ResponseHeader[ "Set-Cookie" ] />
<cfelse>
<cfset LOCAL.ReturnedCookies = ARGUMENTS.Response.ResponseHeader[ "Set-Cookie" ] />
</cfif>
<cfloop
item="LOCAL.CookieIndex"
collection="#LOCAL.ReturnedCookies#">
<cfset LOCAL.CookieString = LOCAL.ReturnedCookies[ LOCAL.CookieIndex ] />
<cfloop
index="LOCAL.Index"
from="1"
to="#ListLen( LOCAL.CookieString, ';' )#"
step="1">
<cfset LOCAL.Pair = ListGetAt(
LOCAL.CookieString,
LOCAL.Index,
";"
) />
<cfset LOCAL.Name = ListFirst( LOCAL.Pair, "=" ) />
<cfif (ListLen( LOCAL.Pair, "=" ) GT 1)>
<cfset LOCAL.Value = ListRest( LOCAL.Pair, "=" ) />
<cfelse>
<cfset LOCAL.Value = "" />
</cfif>
<cfif (LOCAL.Index EQ 1)>
<cfset LOCAL.Cookies[ LOCAL.Name ] = StructNew() />
<cfset LOCAL.Cookie = LOCAL.Cookies[ LOCAL.Name ] />
<cfset LOCAL.Cookie.Value = LOCAL.Value />
<cfset LOCAL.Cookie.Attributes = StructNew() />
<cfelse>
<cfset LOCAL.Cookie.Attributes[ LOCAL.Name ] = LOCAL.Value />
</cfif>
</cfloop>
</cfloop>
<cfset StructAppend(
VARIABLES.Instance.Cookies,
LOCAL.Cookies
) />
<cfreturn />
</cffunction>
</cfcomponent>