Jetty

Support wildcard in VirtualHosts configuration

Details

  • Type: New Feature New Feature
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 7.0.0pre3, 6.1.12.rc2
  • Fix Version/s: 7.0.0pre4, 6.1.12.rc3
  • Component/s: None
  • Labels:
    None
  • Number of attachments :
    3

Description

it should be great if we could use wildcard to define virtual host.

<Configure class="org.mortbay.jetty.webapp.WebAppContext">
    <Set name="VirtualHosts">
        <Array type="java.lang.String">
            <Item>*.mydomain.com</Item>

I presume it is technically quite easy to implement. but we need to decide whether we'll it's simple wildcard or a full regex, e.g.

  • only support wildcard at the beginning and end, when * is detected, if it's in the first character, then use startsWith and endsWith to match, or
  • it's even better if any regex character is detected, including +,*,?,{,}, then treat the string as regex to match

the relevant discuss as as follow:
http://archive.codehaus.org/lists/org.codehaus.jetty.user/msg/bc1833ba0809151359v674995bdj943502c26a9ac06e@mail.gmail.com

  1. jetty721.diff
    24/Sep/08 4:58 AM
    4 kB
    Athena Yao
  2. jetty-721-6.diff
    28/Sep/08 11:42 PM
    9 kB
    Athena Yao
  3. jetty-721-7.diff
    28/Sep/08 11:42 PM
    6 kB
    Athena Yao

Activity

Hide
Athena Yao added a comment -

Wildcard would lead to easier syntax than regex;

".mydomain.com" versus "(.)
.mydomain.com" for (I believe) the most common case.

I think it would be good to follow it the way that DNS does, so wildcard only applies leftmost, and only for subdomains, but not subdomains of subdomains. So ".mydomain.com" would match "foo.mydomain.com" but not "foo.bar.mydomain.com". If you want to match that, you'll need ".bar.mydomain.com".

What use case do you have in mind for a wildcard at the end?

Show
Athena Yao added a comment - Wildcard would lead to easier syntax than regex; ".mydomain.com" versus "(.)
.mydomain.com" for (I believe) the most common case. I think it would be good to follow it the way that DNS does, so wildcard only applies leftmost, and only for subdomains, but not subdomains of subdomains. So ".mydomain.com" would match "foo.mydomain.com" but not "foo.bar.mydomain.com". If you want to match that, you'll need ".bar.mydomain.com". What use case do you have in mind for a wildcard at the end?
Hide
Athena Yao added a comment -

Wow, let me try that again:

Wildcard would lead to easier syntax than regex;

"*.mydomain.com" versus "(.*)\\.mydomain.com" 

for (I believe) the most common case.

I think it would be good to follow it the way that DNS does, so wildcard only applies leftmost, and only for subdomains, but not subdomains of subdomains. So "*.mydomain.com" would match "foo.mydomain.com" but not "foo.bar.mydomain.com". If you want to match that, you'll need "*.bar.mydomain.com". And "mydomain.*.com" wouldn't work either.

What use case do you have in mind for a wildcard at the end?

Show
Athena Yao added a comment - Wow, let me try that again: Wildcard would lead to easier syntax than regex;
"*.mydomain.com" versus "(.*)\\.mydomain.com" 
for (I believe) the most common case. I think it would be good to follow it the way that DNS does, so wildcard only applies leftmost, and only for subdomains, but not subdomains of subdomains. So "*.mydomain.com" would match "foo.mydomain.com" but not "foo.bar.mydomain.com". If you want to match that, you'll need "*.bar.mydomain.com". And "mydomain.*.com" wouldn't work either. What use case do you have in mind for a wildcard at the end?
Hide
Mingfai Ma added a comment -

I think leftmost wildcard could meet 90% of needs. Pls disregard the rightmost one

If the virtual list is checked dynamically without any URL cache(e.g. a matched or non-matched URL will not be checked again before the cache is expired), then many ppl may not want to use regex that will add more overhead to every request

Show
Mingfai Ma added a comment - I think leftmost wildcard could meet 90% of needs. Pls disregard the rightmost one If the virtual list is checked dynamically without any URL cache(e.g. a matched or non-matched URL will not be checked again before the cache is expired), then many ppl may not want to use regex that will add more overhead to every request
Hide
Athena Yao added a comment -

Patch for review. If this is accepted, I'll convert VirtualHostRuleContainer to use this wildcard handling as well.

Notes:

  • *.example.com will match "x.example.com" and ".example.com", but not "example.com", "y.x.example.com", or "a.badexample.com"
  • *.x.example.com will match "y.x.example.com" and ".x.example.com", but not "x.example.com" or "z.y.x.example.com"
  • only .example.com is valid as a wildcard. *example.com (note the lack of the "." after the "") is not, nor is "example.*", etc
Show
Athena Yao added a comment - Patch for review. If this is accepted, I'll convert VirtualHostRuleContainer to use this wildcard handling as well. Notes:
  • *.example.com will match "x.example.com" and ".example.com", but not "example.com", "y.x.example.com", or "a.badexample.com"
  • *.x.example.com will match "y.x.example.com" and ".x.example.com", but not "x.example.com" or "z.y.x.example.com"
  • only .example.com is valid as a wildcard. *example.com (note the lack of the "." after the "") is not, nor is "example.*", etc
Hide
Greg Wilkins added a comment -

Athena, this looks good and I'll apply to jetty 7.
But don't forget to update javadoc and VERSION.txt in your patches.

Can you prepare a jetty-6 patch

thanks

Show
Greg Wilkins added a comment - Athena, this looks good and I'll apply to jetty 7. But don't forget to update javadoc and VERSION.txt in your patches. Can you prepare a jetty-6 patch thanks
Hide
Athena Yao added a comment -

Ported the changes to ContextHandler to Jetty6, plus patch for VirtualHostRuleContainer, which should take care of enabling wildcard for any virtual hosts handling we do.

I noticed an inconsistency, though: when you have a null virtual host, the ContextHandler considers it a non-match it while the VirtualHostRuleContainer considers it a match. (See second test for both ContextHandler and VirtualHostRuleContainer in this patch). This inconsistency was present in the original (non-wildcard) code, and I carried it over.

VirtualHostRuleContainer javadoc indicates this is deliberate behavior, but ContextHandler has been doing it its way for much longer.

Show
Athena Yao added a comment - Ported the changes to ContextHandler to Jetty6, plus patch for VirtualHostRuleContainer, which should take care of enabling wildcard for any virtual hosts handling we do. I noticed an inconsistency, though: when you have a null virtual host, the ContextHandler considers it a non-match it while the VirtualHostRuleContainer considers it a match. (See second test for both ContextHandler and VirtualHostRuleContainer in this patch). This inconsistency was present in the original (non-wildcard) code, and I carried it over. VirtualHostRuleContainer javadoc indicates this is deliberate behavior, but ContextHandler has been doing it its way for much longer.
Hide
Greg Wilkins added a comment -

good work athena!

Show
Greg Wilkins added a comment - good work athena!
Hide
Michael Tkachev added a comment -

Hi!

I've tried this feature and it seems to me that it is not working. After debugging I think there should be fix in org.mortbay.jetty.handler.ContextHandlerCollection class. If, for example, your've configured foo.bar and *.foo.bar context and request is for http://baz.foo.bar then in method
public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) (line 164) on line (184)

list=hosts.get(request.getServerName());

request.getServerName() will be "baz.foo.bar" but the right entry for handling this request is keeped in hosts map with key "*.foo.bar", so the list variable will be null after assignment and request is not handled.

Thanks,
Michael.

Show
Michael Tkachev added a comment - Hi! I've tried this feature and it seems to me that it is not working. After debugging I think there should be fix in org.mortbay.jetty.handler.ContextHandlerCollection class. If, for example, your've configured foo.bar and *.foo.bar context and request is for http://baz.foo.bar then in method public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) (line 164) on line (184) list=hosts.get(request.getServerName()); request.getServerName() will be "baz.foo.bar" but the right entry for handling this request is keeped in hosts map with key "*.foo.bar", so the list variable will be null after assignment and request is not handled. Thanks, Michael.
Hide
Athena Yao added a comment -

Michael,

Thanks for pointing that out! I noticed one other issue while working on ContextHandlerCollection, so I opened another bug to separate out the concerns and attached a patch there:

http://jira.codehaus.org/browse/JETTY-760

Show
Athena Yao added a comment - Michael, Thanks for pointing that out! I noticed one other issue while working on ContextHandlerCollection, so I opened another bug to separate out the concerns and attached a patch there: http://jira.codehaus.org/browse/JETTY-760

People

Vote (1)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: