Not just against the rules, it would require adding a dependency on
Servlet to Undertow core.
Yeah, fair enough. I'm sure there are very good reasons for the separation
of core and servlet, but I would like to just say this has certainly made a
good number of simple things much more complicated.
What you could do is have the notion of priority, like in
ExchangeAttributeBuilder, to allow Servlet to override the core
version.
Now, this is interesting and actually something I was wondering about.
Except, I'd like to be able to override core predicates or handlers with my
own. For instance, there's already a predicate naming the name "file" so
now I'd have to write my own called "is-file" or
"wish-this-was-called-file" or "almost-file". Same the idea of
overriding
the built in "rewrite" handler. Whether it's the servlet package or my own
package doing it.
From what I know about the service loader, it just grabs stuff in the
order
that the class loaders find them. I assume you'd need to modify the
builder interfaces to have a priority method where more than one builder
with the same name could be sorted and the highest priority taken? That
sounds like a compelling idea, but it also sounds like a lot of work and a
breaking API change unless you can use a default method implementation in
the interface for backwards compat.
I may be interested in working on that-- but I need to get the predicate
logging changes wrapped up first before I go down another rabbit trail.
Thanks!
~Brad
*Developer Advocate*
*Ortus Solutions, Corp *
E-mail: brad(a)coldbox.org
ColdBox Platform:
http://www.coldbox.org
Blog:
http://www.codersrevolution.com
On Thu, Jul 9, 2020 at 10:42 PM Stuart Douglas <sdouglas(a)redhat.com> wrote:
On Fri, 10 Jul 2020 at 13:02, Brad Wood <bdw429s(a)gmail.com> wrote:
> Thanks for the reply, this is helpful. I was thinking through this today
> and came to some of the same conclusions-- the issue of potentially more
> than one deployment and using a static variable for a custom predicate to
> "find" the servlet information.
>
> Here's a few brainstorms--
>
> Is there a programmatic way to access all of the servlet deployments that
> have been created? What if, in the event that there is no servlet context
> in the exchange, the file and directory predicates could check and see if
> only one servlet context existed, and if so, just grab that one? That
> doesn't solve the scenario where two or more deployments exist, but it
> would at least allow it to make a decent guess for single deployments.
>
Undertow does not really work like that. It does not really manage all the
Servlet deployments, it expects this to be manage by whatever system it is
embedded into (it does have the DeploymentManager concept that can managed
multiple Servlet deployments, but this is mostly just for cross context
forwards, and there can be multiple instances of the manager).
>
> Being able to specify a given deployment when creating a predicate
> handler chain is an interesting idea as well, but I'm not entirely sure how
> many things in the API would need to change to get it all the way down to
> the predicatebuilder's build() call. In my particular case, I'm using
> the PredicatedHandlersParser.
>
It would just be a Map<String, Object> to allow arbitrary values to be
passed in. Really though I think you just want a custom handler that can
access it through a static.
>
> And on the topic of using the dispatcher-- what if instead of writing a
> new handler, the existing handler detected if it was inside the servlet,
> and if so, it used the dispatcher, and if there was no servlet, it just
> fell back to its current behavior of using the SetAttribtueHandler to
> override the relative path? From an architectural standpoint, I don't know
> if it would be against "the rules" to have a handler in the core package
> touching stuff in the servlet package.
>
Not just against the rules, it would require adding a dependency on
Servlet to Undertow core. What you could do is have the notion of priority,
like in ExchangeAttributeBuilder, to allow Servlet to override the core
version.
Stuart
>
> Thanks!
>
> ~Brad
>
> *Developer Advocate*
> *Ortus Solutions, Corp *
>
> E-mail: brad(a)coldbox.org
> ColdBox Platform:
http://www.coldbox.org
> Blog:
http://www.codersrevolution.com
>
>
>
> On Thu, Jul 9, 2020 at 7:05 PM Stuart Douglas <sdouglas(a)redhat.com>
> wrote:
>
>>
>>
>> On Fri, 10 Jul 2020 at 02:44, Brad Wood <bdw429s(a)gmail.com> wrote:
>>
>>> So, in my bid to put the predicate language through the paces, I've
>>> been testing out all the rewrite rules I've ever used with mod_rewrite
or
>>> Tuckey Rewrite to see if Undertow's handlers are up to the task.
>>>
>>> I've run into an issue again with probably the most common rewrite rule
>>> of any CFML app using an MVC framework, which is a rule that creates
>>> so-called "SES" URLs and force all requests through a front
controller
>>> design pattern.
>>>
>>> Basically
>>>
>>>
site.com/home/about
>>>
>>>
>>> gets rewritten to
>>>
>>>
site.com/index.cfm/home/about
>>>
>>>
>>> Here you can see how this rule is typically accomplished in Apache
>>> httpd, Nginx, IIS, and Tuckey:
>>>
>>>
>>>
https://coldbox.ortusbooks.com/the-basics/routing/requirements/rewrite-rules
>>>
>>>
>>> The hang up is that* any incoming path that maps to an actual file*
>>> skips the rewrite rule. That way* /images/logo.jpg* doesn't get
>>> rewritten.
>>>
>>> So here was my first stab at it with Undertow's predicate language-- it
>>> seemed simple enough:
>>>
>>> not file and not directory ->
rewrite('/index.cfm/%{RELATIVE_PATH}')
>>>
>>>
>>> But our old friend the servlet of course is nowhere to be found since
>>> my "file" and "directory" predicates were executing in
the root handler
>>> chain so there is no concept of a servlet's context root with which to
>>> resolve file system paths.
>>>
>>> So basically, I understand exactly why this doesn't work, but I feel
>>> that we need to find a way to make this work. This is a feature that
>>> pretty much every rewrite engine I've ever used has-- the ability to
test
>>> the file system to see if a file or directory exists. Can we discuss the
>>> following options?
>>>
>>> - Find a way for the root handler chain to access the deployment's
>>> resource manager
>>>
>>>
>> The big conceptual problem here is that there can be multiple Servlet
>> deployments, and the rewrite could change which deployment actually gets
>> served by the request. You could write a custom predicate to handle this,
>> but you would need to stick the Servlet deployment in a static variable so
>> the PredicateBuilder has access to it. We could do it with some API changes
>> I guess, have the PredicateBuilder accept a Map<String, Object>, so you
>> could pass in the ServletContext as you are building the predicates.
>>
>>
>>>
>>> - Find a way for the rewrite handler to correctly affect not only
>>> the exchange but also (optionally) the HttpServletRequest so it's
possible
>>> to rewrite the URL inside of the servlet's handler chain. I know for
>>> certain this is possible because the Tuckey Rewrite engine is implemented
>>> as a servlet filter.
>>>
>>> This would be done using RequestDispatcher.forward(), you could write a
>> handler that uses this, or you could write one that uses the Undertow
>> specific io.undertow.servlet.api.Deployment#getServletDispatcher() to
>> re-dispatch without calling forward.
>>
>> Stuart
>>
>>
>>
>>> I would prefer the first option since I do like having the predicates
>>> in the root handler chain so it can run as early as possible.
>>>
>>> Thanks!
>>>
>>> ~Brad
>>>
>>> *Developer Advocate*
>>> *Ortus Solutions, Corp *
>>>
>>> E-mail: brad(a)coldbox.org
>>> ColdBox Platform:
http://www.coldbox.org
>>> Blog:
http://www.codersrevolution.com
>>>
>>> _______________________________________________
>>> undertow-dev mailing list
>>> undertow-dev(a)lists.jboss.org
>>>
https://lists.jboss.org/mailman/listinfo/undertow-dev
>>
>>