[undertow-dev] More rewrite handler testing and questions

Stuart Douglas sdouglas at redhat.com
Fri Jul 10 01:19:47 EDT 2020


On Fri, 10 Jul 2020 at 15:00, Brad Wood <bdw429s at gmail.com> wrote:

> 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.
>

You would just have a default that returns 0, so it would not be breaking.

Stuart


>
> 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 at 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 at redhat.com>
> wrote:
>
>>
>>
>> On Fri, 10 Jul 2020 at 13:02, Brad Wood <bdw429s at 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 at 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 at redhat.com>
>>> wrote:
>>>
>>>>
>>>>
>>>> On Fri, 10 Jul 2020 at 02:44, Brad Wood <bdw429s at 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 at coldbox.org
>>>>> ColdBox Platform: http://www.coldbox.org
>>>>> Blog: http://www.codersrevolution.com
>>>>>
>>>>> _______________________________________________
>>>>> undertow-dev mailing list
>>>>> undertow-dev at lists.jboss.org
>>>>> https://lists.jboss.org/mailman/listinfo/undertow-dev
>>>>
>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20200710/fdd6d922/attachment.html 


More information about the undertow-dev mailing list