[Router] Define routes with subomains? #1762

Closed
dlsniper opened this Issue Jul 21, 2011 · 39 comments

Comments

Projects
None yet
Contributor

dlsniper commented Jul 21, 2011

Hello,

I've been trying to search for a way on how to define routes with subdomains that are different that the original host.

To be more clear, my application resides under acme.com and I'd like to have a route that points to demo.acme.com and one for admin.acme.com even if they are all pointing to the same directory in Apache.

I'm sorry if this has been answered somewhere else but I couldn't find any info about this.

Also if this is not implemented it, do you think such a patch with be included for final 2.0 release if I'll do it by weekend and submit it?

Regards.

Member

stof commented Jul 21, 2011

It is not implemented, and will not be part of a 2.0 release. We are in the RC state so we fix bugs but we don't add new features.
The handling of the domain in routing is scheduled for 2.1

Contributor

pminnieur commented Jul 22, 2011

A solution without the need to have support for subdomains in Symfony would be a simple URL-Rewrite in your webserver. demo.acme.com rewrites to /demo/{...}, admin.acme.com to /admin/{...} and acme.com to /public{...}. You could then simply prefix your routes with /demo, /admin and /public until subdomains are fully supported.

Contributor

dlsniper commented Jul 22, 2011

@pminnieur: thanks, I've been using this because of the lack of support for subdomains but fortunately our clients understand technical issues. Others might not be so lucky. Plus it's easier to have say: checkout.acme.com that's served from a different load-balancer that acme.com (as it's my case).

Contributor

henrikbjorn commented Jul 22, 2011

A another method could be to have a custom request listener that takes the subdomain and injects it as a prefix to the router before matching is done? Then i theory the urls should still be clean but the matched routed would use the prefix.

Thinking about it generating of routes might become an issue as the prefix would be added

Contributor

pminnieur commented Jul 22, 2011

Ahye, @henrikbjorn is right, I haven't considered route generation will be using these prefixes. I think you could use some kind of { defaults: { subdomain: demo.acme.com }} in your Routes and your custom listener translate this value for matching and maybe generation?

Contributor

breerly commented Aug 12, 2011

@pminnieur do you have a working example of the rewrite rule you mentioned?

Contributor

pminnieur commented Aug 12, 2011

I think something like that should work:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^admin\.example\.com
RewriteRule ^(.*)$ /admin/$1 [L]
Member

weaverryan commented Sep 7, 2011

This seems to relate to #187.

Matching the host in the route (and therefore generating the URL with the correct host when linking "across" hosts) doesn't necessarily seem like something that should be included in the core. A 3rd-party bundle would be perfectly adequate imo.

However, it seems that the router matcher and dumper are much too tight to allow anything to really "plug" into it. In order to make a "_host" requirement, the matcher would need to be rewritten (and the matcher dumper). In order for the URL's to generate across hosts, the generator (and the generator dumper) must be rewritten.

Knowing that the router is very "tight" in order to be very efficient, is this "fixable"? Is there a way to make the routing layer something that can be "plugged" into in order to modify matching and generation?

Thanks!

Contributor

lmcd commented Oct 6, 2011

+1 for core. Hacked around this for 3 large Symfony builds :-/

Contributor

stloyd commented Oct 6, 2011

@lmcd Some hints are also in #2206.

Contributor

lmcd commented Oct 6, 2011

@stloyd: The PR got rejected... this still on the radar?

Contributor

stloyd commented Oct 6, 2011

@lmcd Fabien was talking about that he is working on this issue but dunno there are some results of it available. @fabpot Can you say something more ?

Owner

fabpot commented Oct 6, 2011

I'm working on it. Something will probably be available in the coming weeks.

@ghost

ghost commented Oct 27, 2011

Hi... anything new regarding this?

Owner

fabpot commented Oct 28, 2011

@mheleniak: we will have something for 2.1.

Contributor

pulzarraider commented Oct 31, 2011

I think the hosts (domain/subdomains) should be flexible as routes are now. Some regex support will be fine. Here are some commonly used examples:

  • example.de, example.com, example.fr (same page, but differenet locale)...
  • de.example.com, fr.example.com, en-gb.example.com, en-us.example.com (same page, but different locale)
  • user defined subdomain names: absolutely-anything.example.com (different user content)
  • fixed subdomains: admin.example.com, demo.example.com

And to make it more complicated: (sub)domains are different in every environment (localhost, production, test server...) so should be probably set in parameters.ini.

Contributor

dlsniper commented Jan 6, 2012

Hello,

Any words for this?
If someone has a better idea about solving this issue please let me know and I'll gladly try to find a way to implement it so that it gets into Symfony 2.1

Regards.

Member

stof commented Jan 6, 2012

@fabpot any news about your work on it ?

Are there any news concerning this issue?

Member

stof commented Feb 2, 2012

@fabpot could you review #3002 and #3057 please ?

Contributor

gunnarlium commented Feb 4, 2012

I've haven't had time to update #3057, but thought I might have a go during the weekend. But if this will be worked on separately by @fabpot or the core team, I'm not sure it's worth the time. I already have solved my needs for my current application, but would of course like to contribute.

Not sure which direction you are thinking of going with this, but at least for my needs, being able to have a route match multiple domains is crucial. (ie. _host: domain.com|otherdomain.org)

Contributor

Koc commented Feb 6, 2012

support of multiple domains is really needed feature, +1

Contributor

ConneXNL commented Feb 6, 2012

I agree on this. When i started coding with Symfony, re-working one of my sites, i thought by the end of my release subdomains would be ready. Now i'm ready but the subdomains are not yet ^_^.

I will integrate one of the pull requests by hand i guess.

+1 !!!

THemming commented Feb 6, 2012

@ConneXNL Rather than moving away from the standard Symfony releases (could cause upgrade pains) maybe a solution such as the one mentioned in this StackOverflow question would suffice? http://stackoverflow.com/a/7056270/140985

Member

stof commented Mar 2, 2012

@fabpot ping. Can you review #3002 #3057 and #3378 and say which PR should be finalized to be merged ?

Contributor

Koc commented Mar 2, 2012

I'm vote on #3057 (multiple hostnames per route + preferred host) + #3378 (variables + regex rules)

joec4i commented Mar 10, 2012

@fabpot , any update on this? I just finish reading the symfony.com blog post "Towards Symfony 2.1" http://symfony.com/blog/towards-symfony-2-1-closing-tickets and notice that this ticket is not on the list. Will it still be included in 2.1 release?

Member

stof commented Mar 13, 2012

@fabpot @vicb ping

Contributor

vicb commented Mar 13, 2012

There will be something, see https://twitter.com/#!/fabpot/status/178502663690915840
The blog post only lists issues (not including PRs)

Member

stof commented Mar 13, 2012

@vicb Can you try to make @fabpot review the 3 PRs related to this issue ? I tried many times since a month but he never gave his mind about them

I've been hacking around this by using a different environment for each vhost, but this has made my Capistrano recipes a bit crazy. Is there an easy way to use another routing.yml based on vhost? The lack of progress on this for 2.1 has made me worry that I'll have to maintain my own tree with one of these pull requests.

sudent commented Apr 11, 2012

I share the same view with WIZARDISHUNGRY now that I hit a merge conflict with master on my own tree using one of the PR. Are there any indication which path we would take regarding this matter?

j commented May 8, 2012

ping!! has this been implemented yet and can this issue be closed if so? @vicb @stof. This seems like a useful feature. Currently I have listeners that do routing based on the domain... so I go even beyond the subdomain level.

Member

stof commented May 8, 2012

@jstout24 it is a WIP but it is not merged yet The PR is linked previously in the discussion

Pharkie commented Jun 18, 2012

+1 for Symfony2 having better handling of multiple domains with the same codebase. I've added a simple switch on HTTP_HOST to render different templates, but haven't been able to use a different database on the other URL because the cache dir is shared.

Contributor

patie commented Jun 25, 2012

+1, will be included in 2.1 ?

Member

stof commented Jun 25, 2012

no. The discussion was marked for 2.1 but the discussion on the pull request implementing it explicitly mentions 2.2. 2.1 is already in beta, which means that new features are not added anymore in it, only bug fixes.

I will update the milestone here too

pierre-b commented Jul 8, 2012

+1 for this feature too

Owner

fabpot commented Jul 11, 2012

Closing this ticket as the discussion now happens on PR #3378, which is scheduled for inclusion in Symfony 2.2.

fabpot closed this Jul 11, 2012

@fabpot fabpot added a commit that referenced this issue Nov 12, 2012

@fabpot fabpot merged branch arnaud-lb/hostname-routes (PR #3378)
This PR was merged into the master branch.

Commits
-------

17f51a1 Merge pull request #6 from Tobion/hostname-routes
e120a7a fix API of RouteCollection
26e5684 some type fixes
514e27a [Routing] fix PhpMatcherDumper that returned numeric-indexed params that are returned besides named placeholders by preg_match
7ed3013 switch to array_replace instead of array_merge
94ec653 removed irrelevant string case in XmlFileLoader
9ffe3de synchronize the fixtures in different formats and fix default for numeric requirement
6cd3457 fixed CS
8366b8a [Routing] fixed validity check for hostname params in UrlGenerator
a8ce621 [Routing] added support for hostname in the apache matcher dumper
562174a [Routing] fixed indentation of dumped collections
1489021 fixed CS
a270458 [Routing] added some more unit tests
153fcf2 [Routing] added some unit tests for the PHP loader
68da6ad [Routing] added support for hostname in the XML loader
3dfca47 [Routing] added some unit tests for the YAML loader
92f9c15 [Routing] changed CompiledRoute signature to be more consistent
d91e5a2 [Routing] fixed Route annotation for hostname (should be hostname_pattern instead of hostnamePattern)
62de881 [Routing] clarified a variable content
11b4378 [Routing] added hostname support in UrlMatcher
fc015d5 [Routing] fixed route generation with a hostname pattern when the hostname is the same as the current one (no need to force the generated URL to be absolute)
462999d [Routing] display hostname pattern in router:debug output
805806a [Routing] added hostname matching support to UrlGenerator
7a15e00 [Routing] added hostname matching support to AnnotationClassLoader
cab450c [Routing] added hostname matching support to YamlFileLoader
85d11af [Routing] added hostname matching support to PhpMatcherDumper
402359b [Routing] added hostname matching support to RouteCompiler
add3658 [Routing] added hostname matching support to Route and RouteCollection
23feb37 [Routing] added hostname matching support to CompiledRoute

Discussion
----------

[2.2][Routing] hostname pattern for routes

Bug fix: no
Feature addition: yes
Fixes the following tickets: #1762, #3276
Backwards compatibility break: no
Symfony2 tests pass: yes

This adds a hostname_pattern property to routes. It works like the pattern property (hostname_pattern can have variables, requirements, etc). The hostname_pattern property can be set on both routes and route collections.

Yaml example:

``` yaml
# Setting the hostname_pattern for a whole collection of routes

AcmeBundle:
    resource: "@AcmeBundle/Controller/"
    type: annotation
    prefix: /
    hostname_pattern: {locale}.example.com
    requirements:
        locale: en|fr

# Setting the hostname_pattern for single route

some_route:
    pattern: /hello/{name}
    hostname_pattern: {locale}.example.com
    requirements:
        locale: en|fr
        name: \w+
    defaults:
        _controller: Foo:bar:baz
```

Annotations example:

``` php
<?php

/**
 * Inherits requirements and hostname pattern from the collection
 * @Route("/foo")
 */
public function fooAction();

/**
 * Set a specific hostnamePattern for this route only
 * @Route("/foo", hostnamePattern="{_locale}.example.com", requirements={"_locale="fr|en"})
 */
public function fooAction();

```

Performance:

Consecutive routes with the same hostname pattern are grouped, and a single test is made against the hostname for this group, so the overhead is very low:

```
@Route("/foo", hostnamePattern="a.example.com")
@Route("/bar", hostnamePattern="a.example.com")
@Route("/baz", hostnamePattern="b.example.com")
```

is compiled like this:

```
if (hostname matches a.example.com) {
    // test route "/foo"
    // test route "/bar"
}
if (hostname matches b.example.com) {
    // test route "/baz"
}
```

The PR also tries harder to optimize routes sharing the same prefix:

```
@Route("/cafe")
@Route("/cacao")
@Route("/coca")
```

is compiled like this:

```
if (url starts with /c) {
    if (url starts with /ca) {
        // test route "/cafe"
        // test route "/cacao"
    }
    // test route "/coca"
}
```

---------------------------------------------------------------------------

by Koc at 2012-02-16T14:14:19Z

Interesting. Have you looked at #3057, #3002?

Killer feature of #3057 : multiple hostnames per route.

---------------------------------------------------------------------------

by arnaud-lb at 2012-02-16T14:21:28Z

@Koc yes, the main difference is that this PR allows variables in the hostname pattern, with requirements, etc just like the path pattern. The other PRs use a `_host` requirement, which works like the `_method` requirement (takes a list of allowed hostnames separated by `|`).

> Killer feature of #3057 : multiple hostnames per route.

If you have multiple tlds you can easily do it like this:

``` yaml
hostbased_route:
  pattern:  /
  hostname_pattern: symfony.{tld}
  requirements:
     tld: org|com
```

Or with completely different domain names:

``` yaml
hostbased_route:
  pattern:  /
  hostname_pattern: {domain}
  requirements:
     domain: example\.com|symfony\.com
```

Requirements allow DIC %parameters%, so you can also put you domains in your config.yml.

---------------------------------------------------------------------------

by Koc at 2012-02-16T15:52:16Z

wow, nice! So looks like this PR closes my #3276 ticket?

---------------------------------------------------------------------------

by arnaud-lb at 2012-02-16T15:53:55Z

Yes, apparently :)

---------------------------------------------------------------------------

by Koc at 2012-02-16T15:56:53Z

I cann't find method `ParameterBag::resolveValue` calling in this PR, like here https://github.com/symfony/symfony/pull/3316/files

---------------------------------------------------------------------------

by arnaud-lb at 2012-02-16T16:03:48Z

I think it's in core already

---------------------------------------------------------------------------

by Koc at 2012-02-16T16:11:38Z

looks like yes
https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php#L81

---------------------------------------------------------------------------

by dlsniper at 2012-02-16T19:37:57Z

This PR looks great, it's something like this I've been waiting for.

I know @fabpot said he's working on something similar but I think if he agrees with this it could be a great addition to the core.

@fabpot , @stof any objections about this PR if gets fully done?

---------------------------------------------------------------------------

by stof at 2012-02-16T20:00:21Z

Well, we already have 2 other implementations for this stuff in the PRs. @fabpot please take time to look at them

---------------------------------------------------------------------------

by stof at 2012-02-16T20:03:17Z

This one is absolutely not tested and seems to break the existing tests according to the description. So it cannot be reviewed as is.

---------------------------------------------------------------------------

by dlsniper at 2012-02-16T22:00:24Z

@stof I understand it's a WIP but the other PRs where ignored as well and like you've said, there's a bunch of PRs already on this issue all doing a thing or another. So an early feedback on this, or any other, could lead it to the right path in order to finally solve this issue.

---------------------------------------------------------------------------

by arnaud-lb at 2012-02-17T23:57:28Z

Added tests; others are passing now

---------------------------------------------------------------------------

by arnaud-lb at 2012-02-22T21:10:20Z

I'm going to add support for the Apache dumper and the XML loader; does this PR have a chance to be merged ? cc @fabpot @stof

---------------------------------------------------------------------------

by stof at 2012-02-22T22:05:23Z

@arnaud-lb We need to wait @fabpot's mind about the way he prefers to implement it to know which one can be merged.

---------------------------------------------------------------------------

by IjinPL at 2012-02-27T02:01:57Z

Forked @arnaud-lb *hostname_pattern* to add XML parasing support.

---------------------------------------------------------------------------

by stof at 2012-04-03T23:59:12Z

@arnaud-lb Please rebase your branch. It conflicts with master because of the move of the tests

@fabpot @vicb ping

---------------------------------------------------------------------------

by dlsniper at 2012-04-13T19:52:23Z

Hi,

If @arnaud-lb won't be able to rebase this I could help with some work on this but there's still the problem of actually choosing the right PR(s) for this issue. @blogsh says in his last commit that this PR is a bit better in his opinion but @fabpot needs to decide in the end.

---------------------------------------------------------------------------

by arnaud-lb at 2012-04-14T17:26:55Z

@stof rebased

---------------------------------------------------------------------------

by nomack84 at 2012-04-20T13:01:00Z

@fabpot Any final word about this pull request? It would be nice to have this feature ready for 2.1.

---------------------------------------------------------------------------

by asm89 at 2012-04-24T21:27:50Z

Using the `{_locale}` placeholder in the host would set the locale for the request just like it does now?

Another thing I'm wondering is how/if it should be possible to set the hostname pattern for all your routes, or at least when importing routes? Otherwise you'll end up repeating the same host pattern over and over again. I think this is also important when importing routes from third party bundles.

---------------------------------------------------------------------------

by fabpot at 2012-04-25T01:17:51Z

I'm reviewing this PR and I'm going to make some modifications. I will send a PR to @arnaud-lb soon.

---------------------------------------------------------------------------

by fabpot at 2012-04-25T03:10:18Z

I've sent a PR to @arnaud-lb arnaud-lb/symfony#3 that fixes some minor bugs and add support in more classes.

---------------------------------------------------------------------------

by fabpot at 2012-04-25T03:12:52Z

@asm89:

Placeholders in the hostname are managed in the same way as the ones from the URL pattern.

You can set a hostname pattern for a collection (like the prefix for URL patterns).

---------------------------------------------------------------------------

by Tobion at 2012-04-25T09:31:19Z

I think we need to change the contents of $variables, $tokens, and $hostnameTokens in the CompiledRoute. They contain redundant information and the content structure of these variables ist not documentation in any way. If we remove duplicated content and put it in a (single) well defined variable, it would also reduce the information that need to be saved in the generated class by the UrlGeneratorDumper.

---------------------------------------------------------------------------

by arnaud-lb at 2012-04-26T08:54:21Z

@fabpot thanks :) I've merged it

---------------------------------------------------------------------------

by stof at 2012-04-26T12:08:40Z

A rebase is needed

---------------------------------------------------------------------------

by fabpot at 2012-04-26T13:28:08Z

no need to rebase, I will resolve the conflicts when merging. I've still have some minor changes to do before merging though. Anyone willing to have a look at implementing the Apache dumper part?

---------------------------------------------------------------------------

by Tobion at 2012-04-26T14:59:00Z

@fabpot you want to merge this for 2.1 although it introduces big changes that need extensive review and testing? But #3958 is not considered for 2.1? I thought we are in some sort of feature freeze for the components in order to not postpone the release.

---------------------------------------------------------------------------

by fabpot at 2012-04-26T17:21:09Z

@Tobion: I never said it will be in 2.1. The plan is to create a 2.1 branch soon so that we can continue working on 2.2.

---------------------------------------------------------------------------

by Koc at 2012-04-26T19:46:43Z

https://twitter.com/#!/fabpot/status/178502663690915840
c94bdf6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment