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.

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.