Get a subdomain of a URL using ColdFusion - coldfusion

How can I get the subdomain of a URL using Coldfusion?
For example, say I had the following URL:
http://support.foo.com
How could I get 'support'?
Is there a built in function to do this?

Here's the basic idea:
<cfset domain = cgi.server_name>
<cfset subDomain = "">
<cfif ListFirst(domain, ".") neq "foo" and ListFirst(domain, ".") neq "www">
<cfset subDomain = ListFirst(domain, ".")>
</cfif>

Related

Converting an absolute path into a url

I have a path: c:\home\example.com\wwwroot\img\
I need to convert it into a url: https://example.com/img/
The thing is that the path is dynamic and therefore the url is dynamic. I have the path in a variable. I am NOT on the page in the path, otherwise I would easily be able to use ExpandPath().
What I have is the root url which I get like this:
<cfif isDefined("cgi.SERVER_PORT_SECURE") and cgi.SERVER_PORT_SECURE eq 1>
<cfset http_sec = "https://">
<cfelse>
<cfset http_sec = "http://">
</cfif>
<cfset websiteurl = "#http_sec##cgi.http_host#">
This gives me the root: https://example.com
This where I am stuck.
So if the path is "c:\home\example.com\wwwroot\folder\sub-folder\"
I need to convert it into a url: https://example.com/folder/sub-folder/
How about:
<Cfset path = "c:\home\example.com\wwwroot\folder\sub-folder\">
<cfif isDefined("cgi.SERVER_PORT_SECURE") and cgi.SERVER_PORT_SECURE eq 1>
<cfset http_sec = "https://">
<cfelse>
<cfset http_sec = "http://">
</cfif>
<cfset weburl = replacenocase(path,'c:\home\','','one')>
<cfset weburl = rereplacenocase(weburl,'(.*?)(wwwroot\\)(.*)','\1\3','one')>
<cfset weburl = replace(weburl,'\','/','all')>
<cfset weburl = "#http_sec##weburl#">
<Cfdump var=#weburl#>
Basically you need to strip the "c:\home\" and "wwwroot\" from the absolute path and convert the \ into a /. This is just one way to do this.
You can use these variables...
Protocol = #getPageContext().getRequest().getScheme()#;
Domain = #cgi.server_name#;
Template = #cgi.script_name#;
Variables = #cgi.query_string#;
So for example:
<cfset path = "c:\home\example.com\wwwroot\folder\sub-folder\">
<!--- remove the site loc on disk --->
<cfset path = replaceNoCase(path, 'c:\home\example.com\wwwroot\', '', 'all')>
<!--- convert slashes --->
<cfset path = replace(path, '\', '/', 'all')>
<!--- put it all together --->
<cfset myURL = '#getPageContext().getRequest().getScheme()#://#cgi.server_name#/#path#?#cgi.query_string#'>

How do you track templates calls in ColdFusion?

How do you track template path in ColdFusion?
I.E.
I have the following folder and file structure
index.cfm
<cfset ArrayAppend(request.Trace, '/')>
<cfdump var=#request.trace#>
foo
index.cfm
<cfset ArrayAppend(request.Trace, '/foo/')>
<cfinclude template='../'>
bar
index.cfm
ArrayAppend(request.Trace,'/foo/bar/')>
<cfinclude template='../'>
When I call foo/bar/index.cfm,
request.Trace equals:
'/foo/bar/'
'/foo/'
'/'
How could I do this without specifically declaring each folder name?
Have a look at:
expandPath(".")
getBaseTemplatePath()
getCurrentTemplatePath()
CGI.CF_TEMPLATE_PATH
CGI.PATH_TRANSLATED
CGI.SCRIPT_NAME
If you want the template stack trace, use this:
<cfset templateTrace = []>
<cfset tagTrace = createObject("java","java.lang.Exception").init().TagContext>
<cfloop array="#tagTrace#" index="tagInfo">
<cfset templateTrace.add(tagInfo.Template)>
</cfloop>
<cfdump var="#templateTrace#">
This will output all templates passed up to this call.
Not ideal but this worked for me.
<cfset currentFile = GetCurrentTemplatePath()>
<cfset currentDir = GetDirectoryFromPath(currentFile)>
<cfset webroot = expandPath("/")>
<cfset m_Trace = Replace(currentDir, webroot , '\')>
<cfset ArrayAppend (request.Trace, m_Trace )>

Invalid Component Definition

I'm having an issue in the logs I cannot replicate on the browser. I'm getting hundreds of these per day
invalid component definition, can't find component [cfc.udf]
The cfc are stored in a cfc folder one level above the app. This is so that many apps can use the same cfc.
Folder structure:
---- cfc
--------- udf.cfc
---- myApp
--------- application.cfc
In the application.cfc, I'm using application-specific mappings because this is set on a lot of different load-balanced-servers in production as well as a QA environment and local testing environment and keeping them all synced would be difficult.
At onRequestStart, I have a function that restarts the application every 5 minutes. It was supplied by a consultant. I suspect that this is the culprit because the logs show these errors coming in at exactly 5 minute intervals
<cfcomponent>
<cfset This.name = "myApp">
<cfset This.Sessionmanagement=true>
<cfset This.Sessiontimeout="#createtimespan(0,0,30,0)#">
<cfset this.mappings['/cfc'] = ExpandPath('../cfc')>
<cffunction name="onApplicationStart">
<cfset Application.udf = createObject("component", "cfc.udf").init()>
</cffunction>
<cffunction name="onRequestStart">
<cfset appRefreshMinutes = 5>
<cfif Not IsDefined("Application.refreshTime")>
<cfset currentMinute = Minute(Now())>
<cfset Application.refreshTime = DateAdd("n", -(currentMinute MOD appRefreshMinutes)+appRefreshMinutes, Now())>
<cfset Application.refreshTime = DateAdd("s", -(Second(Application.refreshTime)), Application.refreshTime)>
</cfif>
<cfif Now() GTE Application.refreshTime Or IsDefined("URL.reload")>
<cflock name="ApplicationInit" type="exclusive" timeout="5" throwontimeout="false">
<cfif Now() GTE Application.refreshTime Or IsDefined("URL.reload")>
<cfset OnApplicationStart()>
<cfset Application.refreshTime = DateAdd("n", appRefreshMinutes, Application.refreshTime)>
</cfif>
</cflock>
</cfif>
</cffunction>
</cfcomponent>
Promoted from the comments
Have you tried using a mapping name other than /cfc? Like:
<cfset this.mappings['/somethingelse'] = ExpandPath('../cfc')>
so that you can then call it like:
<cfset Application.udf = createObject("component", "somethingelse.udf").init()>
Maybe it just looks odd to me or maybe that is causing your issue (cfc being a reserved word or somehow getting special treatment in this case).

Evaluating Coldfusion directory path for file existence

I've been working on a script for a couple of weeks tweaking it as need be to track CGI.script_PATH and CGI.REFERER on an older coldfusion install which has over 500 .cfc and .cfm pages. I just hit a snag in my code. It doesn't capture a page name in the CGI.Referer variable when the referer is a folder. I'm sure it has something to do with Coldfusion automatically looking for an index.cfm even when the path doesn't include an actual file name.
How can I write an addition to my script where if there is no .cfm in the CGI.Referer, it can search the directory and capture the default file set to load or at least search for an occurrence of index.cfm or default.cfm?
Here is a block of code handling the referer element:
<!---Variable declared and set to empty--->
<cfset referer_path_and_file = "">
<cfset referer_path = "">
<cfset referer_file_name = "">
<cfset script_path_and_file = "">
<cfset script_path = "">
<cfset script_file_name = "">
<cfif cgi.HTTP_REFERER neq ''>
<!--- all of this will fail if there is no referer, for instance, if they bookmark the page --->
<!--- cgi.HTTP_REFERER may contain URL parameters, so let's strip those --->
<cfset referer_path_and_file = ListFirst(CGI.HTTP_REFERER, "?")>
<!--- now let's get just the path, stripping out the web server info --->
<cfset referer_path = ListDeleteAt(CGI.HTTP_REFERER, ListLen(CGI.HTTP_REFERER, "/"), "/")>
<cfset referer_path = ReplaceNoCase(referer_path, "https", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "http", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "://machine1.fss.com", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "://www_dev.fss.com", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "://www.fss.com", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "://10.11.2.60/", "", "All")>
<cfset referer_path = referer_path & "/">
<cfset referer_path = ReplaceNoCase(referer_path, "/", "\", "All")>
<!--- now let's remove everything but the file name --->
<cfset referer_file_name = ListLast(referer_path_and_file, "/")>
<!--- and that leaves us with these variables set --->
<!--- referer_path_and_file = "#referer_path_and_file#"<br />
referer_path = "#referer_path#"<br />
referer_file_name = "#referer_file_name#"<br />
<br />--->
</cfif>
<!---Directory Stripping And Modifier Block Goes Here--->
<!---Set CGI System Variables--->
<cfset currentHeader = CGI.HTTP_REFERER >
<cfset currentScriptPage = CGI.SCRIPT_NAME >
<!---Set currentScriptPage as command line directory string and delcare new variable "reverseScriptPage"--->
<cfset reverseScriptPage = ReReplace(#currentScriptPage#, "/", "\","ALL")>
<!---Set reverseScriptPage value as newly format command line directory structure--->
<cfset newScriptPage = ListSetAt(#reverseScriptPage#, 1, "#reverseScriptPage#") >
The code just strips the CGI script and referer variables of their http web references and then strips the directory structure portion and inserts the .cfm file name and original directory structure into the DB table, but not before reversing the / characters to \ because they want to be able to setup a script which will loop through the table and see something like "\admin\controls\" and auto create those directories, then copy the example.cfm page into that directory. The aim is to 1.) determine which of the 500 cfc/cfm files are still used in the application, then copy them and their directory structure to a new location, and redesign those files in a new technology that isn't Coldfusion.
Update: I'm running into an issue with my code. When I test it, it works well, truncating the http domain portion. However once its operating live under the web server, it doesn't truncate the url despite there being a ReplaceNoCase method to do so:
Under the web root in the wwwroot root, it works well giving this output:
refererPage: testFiles.cfm refererPath = testCodes\MVC
Under the live site I get this:
refererPage: client_display refererPath: **:\dev.fss.com\admin_area**
despite having this line in my code:
Any idea why?
If your cgi.http_referrer variable does not not contain .cfm, you can use the DirectoryExists function on your referer_path variable. If it returns true, you can use the DirectoryList function or cfdirectory tag to search for an occurrence of index.cfm or default.cfm.
they may have this going through a framework (like a model view controller). Without knowing more about the URL structures and the naming conventions.
And without knowing more I would say you are dealing with dynamic content (especially if it is going through index.cfm). Even in an engine with 500 pages, there is a unique identifier and that should be your target not a file. So we may assume there are no files at all and we are just calling parts and pieces from here and there to make a page based on your URL querystring, local variables and/or form variables.
So tables are your friends. Examine your URL structure, try to break down the parameters, search the code base for those parameters and once you have located the area that builds the pages then somewhere there set your tracking tools (a bit higher up stream in the page request stream).
Maybe with some code snippets we could give you a more precise answer but for now this should at least get you looking at your code base for clues.

Sharing login credentials between ColdFusion servers?

If I have multiple CF8 servers, can a user login on one server, but share the login credential among all servers (no re-login required)?
Maybe question is about sharing session? This can be done using serialized J2EE sessions or using shared client variables.
For example, this can be done in following way.
Create empty database on one of servers (I've created MySQL one). Create datasources pointing to this DB on all CF servers. Use this datasource as Server Settings > Client Variables > client sessions storage with name SharedSessions (we'll use it later).
If we're using cflogin in Application.cfm on all servers, it's code can look this (simplified) way:
<cfapplication
name="shared_session_test"
sessionManagement="true"
clientmanagement="true"
clientstorage="SharedSessions" />
<cflogin>
<cfif IsDefined( "cflogin" ) and cflogin.name eq "admin" and cflogin.password eq "admin">
<cfset user_roles = "administrators" />
<cfset user_name = cflogin.name />
<cfset user_password = cflogin.password />
</cfif>
<cfif IsDefined( "user_roles" )>
<!--- push login params into shared client scope --->
<cfset CLIENT.user_roles = user_roles />
<cfset CLIENT.user_name = user_name />
<cfset CLIENT.user_password = user_password />
<cfelseif IsDefined( "CLIENT.user_roles" )>
<!--- restore login params from shared client scope --->
<cfset user_roles = CLIENT.user_roles />
<cfset user_name = CLIENT.user_name />
<cfset user_password = CLIENT.user_password />
</cfif>
<cfif IsDefined( "user_roles" )>
<cfloginuser name="#user_name#" password="#user_password#" roles="#user_roles#">
<cfelse>
<!--- authentication failed - send back 401 --->
<cfsetting enablecfoutputonly="yes" showdebugoutput="no">
<cfheader statuscode="401">
<cfheader name="WWW-Authenticate" value="Basic realm=""MySecurity""">
<cfoutput>Not authorized</cfoutput>
<cfabort />
</cfif>
</cflogin>
<cfoutput><p>other.server.com</p></cfoutput>
Now these show the same on both servers:
<cfdump var="#getAuthUser()#">
<cfdump var="#CLIENT#">
Sure, there's much to do here to make process better and more secure, just described the general idea.
Hope this helps.