Can you give a bigger picture of exactly what you are trying to solve?
Hi Bill. I know I've talked with Stuart about my use of Undertow in the past and he's even helped review our code. It's understandable you probably don't know where I'm coming from :) I typically don't get into the weeds of exactly how I'm using Undertow since it's a long story, but since you asked I'll fill you in. I'm the lead developer on a tool called CommandBox which is a
- CLI
- REPL
- package manager
- scaffold
- server for CFML applications (powered under the hood using pre-packaged WARs and Undertow
Undertow is packaged quite nicely inside of a black box and frankly, my users don't know or care that it's there. We use a custom resource manager that allows us to serve JIT'd CFML templates from a separate web root outside the WAR while powering the servlet from a pre-packaged WAR in a manner that is the same as Adobe ColdFusion or Lucee Server's Tomcat-based installations. Overall, that works great and has been in use for 5-6 years now, powering roughly 50% of the docker usage in the CF community.
All a CommandBox user needs to do to start up a CF server is (box has a built in interactive shell based on JLine)
CommandBox> echo "Hello world" > index.cfm
CommandBox> server start port=8080
And boom, a browser window opens up serving their hello world message. They can even use CommandBox/Undertow to serve up a static HTML server just like the "npm serve" command, but with no Node :) CommandBox also has a singular JSON file that allows users to control every aspect of their server
- JRE - auto installed from the AdoptOpenJDK API
- CF engine/version - auto installed from Forgebox.io
-
Ports (HTTP/HTTPS/AJP)
- SSL Certs
- virtual directories
- Lib directories to class load jars from for the app
- welcome pages
- Basic auth
- heap size
- URL rewrites (Currently powered by Tuckey)
- Error pages
- And coming soon-- rules defined in Undertow's predicate language placed right into an array in the JSON file.
Doc Reference for all configuration options:
So to review, my users spin up servers externally controlled by CLI parameters, local JSON files shipped with the app, or even global default settings they've baked into their CLI. My users don't know or care about Undertow, it "just works" for them.
The addition of the predicate language will give my users an option other than Tuckey to accomplish the following
- Add rewrites to their app
- Block common administrator paths from prying eyes
- Secure sensitive configuration files they don't want served from the web root
- Configure reverse proxies and load balanced proxies on the fly
I even plan on baking some of these security rules into the CommandBox core so their servers are better secured by default.
So here is a totally realistic example of how I envision a server being started (The "server set" command simply modifies the server.json files for you)
CommandBox> server set web.errorPages.404=notfound.html
CommandBox> server set web.rules = '[ "path(/box.json)->response-code(404)" ]'
CommandBox> server start
So, in that user's mind, they just
- Configured all 404 requests to use a custom notfound.html file
- Placed a predicate rule that responds with a 404 to any request to the secret file box.json
- It would be the completely reasonable expectation of that user that if they slap /box.json in their browser, they will see the contents of their notFound.html error page
However, number 3 won't/doesn't happen for various behind-the-scenes technical reasons. I get those reasons, but at the end of the day I need this behavior to be consistent in my usage of undertow. I can't just tell people, "Oh yeah, your error pages don't work half the time, but don't worry, there's a really good reason for it!", lol. The error pages in the JSON configuration for CommandBox are fed directly to the servlet's error pages deployment info and the web.rules are parsed into a PredicatesHandler. But again, this is a black box so it needs to "just work" like people will expect. That's what I'm after.
So, now that the background stuff is out of the way, allow me also address the rest of your questions categorically:
Where will your actual routing logic live?
I'm not quite sure if you're asking where the actual text-based predicate language will be stored or if you're asking where in the handler chain the PredicatesHandler will be processed. If you're asking about the rules, they will be provided by the users of my tool and can literally come from anywhere based on their needs. If you're asking where in the handler chain I'll process them, I've covered previously in this thread having them "inside" the servlet initial handler and "outside" the servlet and both approaches have had issues. Perhaps the short answer is, I'm willing to put it wherever the heck it needs to be in order to make this work :)
What types of things are you expecting the predicate language to accomplish for you?
Everything. Literally everything. I am exposing Undertow's predicate language directly to the end users (developers, sysops guys, etc) for them to tap into and add whatever rules they deem necessary for rewrites, security, or even reverse proxies in their app. I'm not even sure why this matters to the conversation. But suffice it to say, I need Undertow's predicate language to be capable of doing everything it does, but I need consistency in how error status codes are handled in a manner that matches the rest of the server.
Why do you need to be tied to servlets?
I don't. Quite frankly, I couldn't care less what it's tied to. That said, servlets already have the ability to control error pages. CommandBox will parse the web.xml in the WAR to look for any configured error pages (since user's can supply a custom WAR) as well as combine the configuration in the user's server.json file. Right now we tap into the error pages functionality of the servlet because it's simple, it's built in, and it just makes sense. I need an error page functionality that is consistent across all uses of Undertow. Not just firing in some scenarios on Tuesdays after 3pm depending on a complex internal routing of your handler chain. Again, my users don't know or care how this works, if they configure a custom 404 page, they expect it to be used by default for all 404s that don't otherwise return content.
path(/box.json)->response-code(404)
This example seems pretty impractical because if you just left the line out entirely then wouldn't your router decide this route doesn't exist and handle the 404 in your servlet code?
Sorry, but I'm not quite following you. That line is a prime example of what I expect people to use the predicate language for in securing parts of their app they don't want served. The way CFML apps work is you place all files in your web root (images, jss, css, html, and CFMs). There is a default static handler that just serves up whatever files you request, and a servlet mapping for *.cfm files that route them through the CF servlet (which JIT compiles and processes them). If I don't have the predicate rule above, a user would be able to directly hit that configuration file in the web root-- and being just a normal JSON file, it would be served up no problem. The request would not be a 404 in the servlet because that file actually exists on disk and would be served. Which, of course, is the entire purpose of this feature!
With attributes and custom HttpHandlers you should be able to accomplish pretty much anything you want
Yes, I know. Undertow is very powerful. My questions here are two fold
- How in the heck do we accomplish it??
- Can Undertow be made better? The default behavior of the response-code handler in this case seems ... not useful. I mean, in what universe is it ok to respond to a request with a 404 status code but no response body. Surely we can agree, this stands to be improved. But the predicate language doesn't seem to provide a consistent way to tap into the error pages in the deployment.
is there a specific need to have some of this logic live in servlets?
Like I said above, not really -- other than the fact that this is a servlet deployment making use of servlet features such as error pages.
Thanks!
~Brad
Developer Advocate
Ortus Solutions, Corp