Lucee, IIS, and Mura w/ FW/1 - URL Rendering Not Working Correctly

OS: Windows Server 2022
Java Version: 11.0.23 64-bit
Tomcat Version: 9.0.89
Lucee Version: Lucee 5.4.6.9 (LTS)

There are a lot of moving parts here, and I am not sure which community to ask about it. I am pretty sure the problem is not with Mura, but it it seems plausible it could be a problem with my config in Lucee or IIS or maybe even with how I am using FW/1 (for my Mura Plugin).

We are looking at moving to Lucee. I have set up a test instance of our website on a Lucee VM . I have several Mura plugins made with FW/1. They all work as expect in Adobe ColdFusion, but do not work properly in Lucee. The part that doesnā€™t work as expect is URL rendering.

Example:

I have a mura plugin that renders a form.

<form action="#buildURL('main.saveGraduationRequest')#" id="graduationForm" method="post">

If I put that form on a Mura page at Mura page at the SES URL /graduation/apply/ then the form URL renders as follows:

ACF: <form action="/graduation/apply/?DCTCOGAPluginaction=main.saveGraduationRequest" id="graduationForm" method="post">

Lucee: <form action="/?DCTCOGAPluginaction=main.saveGraduationRequest" id="graduationForm" method="post">

As you can see, in the Lucee instance, the path info is not being included in the rendered URL. Everything points back to / which breaks all of my forms.

The same thing seems to happen with FW/1 redirects, like this: fw.redirect(action=ā€˜admin:main.defaultā€™)

Instead of redirecting back to the page that the plugin is on, it redirects back to root.

I donā€™t know where the problem is. Does it have to do with how IIS is passing data to Lucee/Tomcat for rendering? Does it have to do with some setting in Lucee that I am missing? Or maybe a setting in FW/1ā€™s config?

Logic tells me the problem is with Lucee or IISā€™s connection to Tomcat, because those are the differences between this and my ACF server where all is working correctly.

Years ago, when I upgraded my ACF (possibly when switching from JRUN to Tomcat) I feel like I had this same problem, but that memory is hazy and I have no idea what I might have done to fix it.

Any help would be appreciated.

AFC does this under the hood, while in Lucee you need to configure this

Tomcat Docs:
https://tomcat.apache.org/tomcat-9.0-doc/rewrite.html

Or as you are using IIS, just enable the rewrite module and put this in your web.config

<rule name="Rewrite .cfm" enabled="true" stopProcessing="false">
          <match url="[^?]*" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern="^(.*).png" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern="^(.*).cfm" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern="^(.*).cfc" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern="^(.*).jpg" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern="^(.*).gif" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern="^(.*).mp4" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern="^(.*).mp3" negate="true" />
            <add input="{REQUEST_FILENAME}" pattern="^(.*).css" negate="true" />
          </conditions>
          <action type="Rewrite" url="{R:0}.cfm" />
        </rule>

A quick, just get it working

I am not sure this is what I am looking for. Adding that to my IIS rewrites only results in giving me 404s for pages that were working before.

What that accomplishes is for someone visiting /graduation/apply/ to get rewritten to /graduation/apply/.cfm, which doesnā€™t make sense to me, nor does it seem to address the issue that when I ask FW/1 to create a link, it doesnā€™t include the path info from the page it was requested from.

I am not having a problem with URLs coming into IIS getting to where they need to go, I am having a problem with URLs that are being generated with code having the path info they need to be valid URLs back to the page where the plugin app is hosted.

Here is the documentation on rewriting for IIS

My suggestion though, is use apache not IIS, even on Windows unless you specifically need features only available on IIS.

download and install the apache binary

set up the proxy module for lucee

ProxyPreserveHost On ProxyPassMatch ^/(.+\.cf[cm])(/.*)?$ http://127.0.0.1:8888/$1$2 ProxyPassMatch ^/(.+\.cfml)(/.*)?$ http://127.0.0.1:8888/$1$2 # optional mappings #ProxyPassMatch ^/flex2gateway/(.*)$ http://127.0.0.1:8888/flex2gateway/$1 #ProxyPassMatch ^/messagebroker/(.*)$ http://127.0.0.1:8888/messagebroker/$1 #ProxyPassMatch ^/flashservices/gateway(.*)$ http://127.0.0.1:8888/flashservices/gateway$1 #ProxyPassMatch ^/openamf/gateway/(.*)$ http://127.0.0.1:8888/openamf/gateway/$1 #ProxyPassMatch ^/rest/(.*)$ http://127.0.0.1:8888/rest/$1 ProxyPassReverse / http://127.0.0.1:8888/

then enable htaccess rewrite

Switching to Apache is not an option.

While I appreciate your attempt to help, I am not sure you are understanding the original problem. I am not getting 404s when trying to browse to pages. My existing rewrites are working correctly.

For example, when I visit (in the browser) /graduation/apply/, IIS is correctly rewriting to /index.cfm/graduation/apply/ and the page loads correctly.

The problem is when my plugin tries to generate a URL to go elsewhere [using the buildURL() function of the redirect() function] it does not create the correct URL. It does not include the /graduation/apply/ in the new URL, it only adds /, so then the URL does not go to the write place, and no amount of rewriting will fix that.

1 Like

What version of FW/1 is being used? Iā€™m not all that familiar with how itā€™s packaged/used with Mura, so canā€™t be of too much help there.

Offhand, nothing comes to mind as being an issue, but the version may give some more direction on things to look for.

Thanks, Tony.

variables._fw1_version = ā€œ4.3.0-SNAPSHOTā€;

Some additional information that Charlie Arehart encouraged me to provide.

1) It might help if you shared more about where the code was (relative to the web root of the iis site) and then what the url requesting the pages is. I realize youā€™ve been clear ā€œitā€™s not about the incoming url but instead whatā€™s being produced in your codeā€. But the codeā€™s creation of a path COULD be impacted by the url used to request that code.

The code itself sits in the Mura plugin directory, which is at the websiteā€™s root. BuildURL is called from a CFM in /plugins/FormsPlugin/public/views/main The plugin is added to the page /graduation/apply/ through Muraā€™s drag-and-drop modules UI.

2) Then it wasnā€™t clear what WAS the code behind that buildURL function: is it part of mura? Fw1? Or a udf of your own?

buildUrl() and redirect() are both methods of FW/1.

3) Then whatā€™s in that main.saveGraduationRequest? Is that a cfc?

main.saveGraduationRequest is the nomenclature we use in FW/1 to specify where we are going. In this case, we are going to the saveGraduationRequest method in the main controller (which is a CFC in the plugin).

4) Lastly, since this is iis, should we assume youā€™re using the boncode connector? Did you install and configure that? Or did you just install Lucee with the windows installer, which asked you whether it should configure the connection to iis? That, too, would implement boncode.

Yes, I am using the BonCode connector. Yes, I just told the Lucee installer to connect to IIS. I have not tried adding any other config.

Thanks.

While I suppose we canā€™t rule out IIS, I donā€™t have much knowledge with it these days, so I still question FW/1 playing nice with Lucee.

There were a handful of updates after the snapshot version of 4.3.0 that eventually led up to its full release - History for framework/one.cfc - framework-one/fw1 Ā· GitHub

Nothing in that list of changes jumps out as correcting any concerns here other than maybe the fix to redirect not preserving things, but while it was a Lucee specific issue, it seemed to only happen when local mode was set to modern, so that may not apply to this scenario unless you have that set as such.

It may be worth a shot updating the FW/1 core files to the latest stable versions of 4.3.0.

My only other thoughts are how Mura is using FW/1. Whether it makes use of the legacy subsystem workflow for its plugins, and the possibility of a bug with that setup.

Unfortunately, Iā€™m out of ideas beyond that at the moment. If you can share the FW/1 framework settings, it may also help in verifying some things.

I tried dropping in the newest 4.3.0 and the problem persists.

I canā€™t imagine I am the only one using Mura with a FW/1 plugin on Lucee. If there were problems with that combination, I suspect it would have long since been fixed. I think that is a pretty widely used combo.

I do have a ticket in with BlueRiver with my question to see what they know.

I really suspect this has to be a problem with my configuration vs something like Lucee and or Mura having an issue with FW/1.

I am not sure what " legacy subsystem workflow" is in the context of FW/1, but as far as I know, I am using the most modern version of FW/1 subsystems in my plugins.

As for my FW/1 settings:

<cfscript>
	variables.framework = StructNew();

	// !important: enter the plugin packageName here. must be the same as found in '{context}/plugin/config.xml.cfm'
	variables.framework.package = 'FormsPlugin';
	variables.framework.packageVersion = '4.1';

	
	// If true, then each subsystem is treated as its own, individual application, unaware of any other subsystem, and will not respond to requests for any other subsystem. For example, if a link in App2 points to 'buildURL('app3:main.form') as a 'href' tag and is clicked, then App2 will maintain its state and not respond. Only App3 will respond to that request. If false, then it is assumed that you will only have ONE display object on any page at any given time. If you have more than one, then as you interact with it, all of them will respond with the same view. You have been warned!
	variables.framework.siloSubsystems = false;

	variables.framework.debugMode = false; // if TRUE, then additional information is returned by the Application.onError() method

	variables.framework.reloadApplicationOnEveryRequest = true; // change to TRUE if you're developing the plugin so you can see changes in your controllers, etc. ... otherwise, set to FALSE for production

	variables.framework.trace = false; // if true, will print out debugging/tracing info at the bottom of ea. page (within the Plugin's Administration area only)
	

	// the 'action' defaults to your packageNameAction, i.e., 'muraFW1action' ... you may want to update this to something else.
	// please try to avoid using simply 'action' so as not to conflict with other FW1 plugins
	variables.framework.action = variables.framework.package & 'action';

	// less commonly modified
	variables.framework.defaultSection = 'main';
	variables.framework.defaultItem = 'default';
	variables.framework.usingSubSystems = true;
	variables.framework.defaultSubsystem = 'admin';

	// dependency injection framework
	variables.framework.diEngine = 'none';
	variables.framework.diLocations = 'model,controllers,services';
	variables.framework.diConfig = {};
	variables.framework.diComponent = variables.framework.package & '.includes.framework.ioc';

	// by default, fw1 uses 'fw1pk' ... however, to allow for plugin-specific keys, this plugin will use your packageName + 'pk'
	variables.framework.preserveKeyURLKey = variables.framework.package & 'pk';

	// ***** rarely modified *****
	variables.framework.applicationKey = variables.framework.package;
	variables.framework.base = '/' & variables.framework.package;
	variables.framework.reload = 'reload';
	variables.framework.password = 'redacted'; // IF you're NOT using the default reload key of 'appreload', then you'll need to update this!
	variables.framework.generateSES = false;
	variables.framework.SESOmitIndex = true;
	variables.framework.baseURL = 'useRequestURI';
	variables.framework.suppressImplicitService = true;
	variables.framework.unhandledExtensions = 'cfc';
	variables.framework.unhandledPaths = '/flex2gateway';
	variables.framework.maxNumContextsPreserved = 10;
	variables.framework.cacheFileExists = false;

	if ( variables.framework.usingSubSystems ) {
		variables.framework.subsystemDelimiter = ':';
		variables.framework.siteWideLayoutSubsystem = 'common';
		variables.framework.home = variables.framework.defaultSubsystem & variables.framework.subsystemDelimiter & variables.framework.defaultSection & '.' & variables.framework.defaultItem;
		variables.framework.error = variables.framework.defaultSubsystem & variables.framework.subsystemDelimiter & variables.framework.defaultSection & '.error';
	} else {
		variables.framework.home = variables.framework.defaultSection & '.' & variables.framework.defaultItem;
		variables.framework.error = variables.framework.defaultSection & '.error';
	};
</cfscript>

I def agree if it was something with FW/1 then surely someone else would have run into this or similar. The output from buildURL just seems so strange to me that it would differ from ACF to Lucee.

Regarding legacy subsystems, there was a shift in how they are set up in FW/1 some time ago. Iā€™m sure plenty of folks still use the ā€œoldā€ way, so whether thatā€™s actually a possible point of issue, Iā€™m not sure. It was mostly a thought of observation. Using Subsystems in FW/1 | FW/1 - The Invisible Framework

Thanks for sharing the config. Nothing is jumping out at me. If I think of anything else Iā€™ll chime in.

Hi,

In your application.cfc, there is this variable

variables.framework.baseURL = 'useRequestURI';

The function resolveBaseURL do this :

} else if ( path == 'useRequestURI' ) {
            path = getPageContext().getRequest().getRequestURI();

Can you dump getPageContext().getRequest().getRequestURI() on Lucee to see if itā€™s empty for the page /graduation/apply/?

Try it in a Mura CMS page AND try it too in another independant cfm page outside of the Mura CMS.

Sure enough, in Mura on ACF that value include the /graduation/apply/, on Lucee it does not.

I created a separate page in the folders/test/test2/ called test.cfm (outside of Mura, but on the Lucee server). When I write out #getPageContext().getRequest().getRequestURI()# in there I get:

/test/test2/test.cfm

So in that context it does include the path info of the page from which it is being executed.

In this case, it seems that Mura or FW/1 overwrites getPageContext().getRequest().getRequestURI() when running on Lucee. I havenā€™t used either one. Looking through the source code you should be able to find a reference to this. I will take a look.

I suspect even more strongly now that boncode could be at issue. Jason, please checkout:

https://boncode.net/connector/webdocs/Tomcat_Connector.htm#_Toc152686869

Then a subsequent question could be whether Lucee or mura might have handled this issue (or could be made to).

I could be barking up the wrong tree, of course.

1 Like

I saw that documentation yesterday, Charlie, and at first I said ā€œoh, this might be it!ā€, but then I read:

Several application servers Lucee (lucee.org), (Railo (getrailo.org), Adobe Coldfusion (www.adobe.com/products/coldfusion-family.html), and Open Blue Dragon (openBlueDragon.org) automatically look for this alternate value and place it correctly into the CGI scope PATH_INFO. Thus, using one of these application servers on top of Tomcat, will avoid code changes.

This suggest that BonCode and Lucee already do this for me. Unless for some reason (config perhaps) BonCode is not sending that xajp-path-info variable to Lucee, as is supposed to. If not, I have no idea how I would make it do so. I have looked at the BonCode documentation and have not seen anything that tells me how I would check that.

If Boncode is the problem, why does getPageContext().getRequest().getRequestURI() with Lucee return the correct path in a page outside of Mura, and return empty in a page inside Mura?

You may be right, but if Mura or FW/1 are the problem, why would it work fine in ACF but not in Lucee? Everything about Mura and FW/1 I am using are identical.

Something is different, and it is frustrating me to the point that we may just pay another $10k to Adobe.

I have not heard anything back from BlueRiver about this yet, maybe they will have an idea. I seem to recall they have not done much with FW/1 plugins in a long time, but maybe they will know something.

Fair enough, everyone, but he could still try looking at the headers discussed in the boncode docs as a sanity check. :slight_smile:

To be clear, Iā€™m just offering ideas.

My hypothesis is that your Mura with Lucee does not run in the same environment as your ACF version, right? Iā€™m talking about IIS and Tomcat. And in Mura and/or FW/1, there are special url rewriting rules and certain variables about the path are not returned to Lucee.

I would look at the URL rewriting rules first.

I would try to also dump the CGI scope to compare what I get with ACF (with and without Mura) vs Lucee (with and without Mura)

All ideas are welcome and you may be right too. This may be due to several things, like URL rewriting and Boncode, because when he tries a page outside of Mura, itā€™s in a directory and a file that really exists on the server, so the path is returned without a problem. But in Mura, itā€™s a path that doesnā€™t really exist without the rewrite rule.

1 Like