6

I'm trying to rewrite a subdomain to a folder/file like this:

  • name.example.com -> example.com/profile/name
  • foo.example.com -> example.com/profile/foo
  • xyzzy.example.com -> example.com/profile/xyzzy

This is a wildcard subdomain pointing to the same folder as the main domain.

I have this code in .htaccess on the main domain root:

RewriteEngine On
RewriteBase /

#force https and non-www
RewriteCond %{HTTP_HOST} ^(www\.)(.+) [OR]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)
RewriteRule ^ https://%2%{REQUEST_URI} [R=301,L]

# profile redirection
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com [NC]
RewriteRule (.*) https://example.com/profile/%1/ [L]

It works well but I want to keep the original URL: name.example.com

I have Internal Server Error when I try to change the last line to

RewriteRule (.*) /profile/%1/ [L]

I tried a couple different solutions without success. Obviously, I do it wrong.

How can I keep the original URL?

Edit:


This is a WordPress, so maybe the code after that is important:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

It is not optimized but the problem is that everything between # BEGIN WordPress and # END WordPress can be overwritten by Wordpress. This is why I don't want to put anything there.

  • I changed "redirect" to "rewrite" in a couple places in your question. Redirects change the URL while rewrites show the from a different URL without changing the current URL. – Stephen Ostermiller Mar 14 '18 at 15:23
  • 1
    And just to be clear, you have a wildcard virtual host configured such that the main domain and all the wildcard subdomains are hosted in the same folder on the server? – Stephen Ostermiller Mar 14 '18 at 15:25
  • It is profile, not agent. Sorry, my error. I changed that in the question. – aatanasow Mar 14 '18 at 16:23
  • 1
    Yes, main domain and the wildcard subdomain points to the same folder on the server. – aatanasow Mar 14 '18 at 16:36
2

I have Internal Server Error when I try to change the last line to

RewriteRule (.*) /agents/%1/ [L]

Because this will result in an internal rewrite loop. It looks like you also want to preserve the URL-path (which is presumably why you are capturing the RewriteRule pattern - but which is currently being discarded).

You need an additional condition to prevent a rewrite loop and modify the RewriteRule substitution. For example:

# profile redirection
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com [NC]
RewriteRule (.*) /profile/%1/$1 [L]

Checking against an empty REDIRECT_STATUS (environment variable) ensures that only the initial request is rewritten, not the rewritten request.

This also assumes that the subdomains and main domain all point to the same place on the file system (as @Stephen asked in comments).

$1 is a backreference to the captured group in the RewriteRule pattern.


Alternatively, you could use a negated RewriteRule pattern and only rewrite requests that don't already start /profile/ and use the REQUEST_URI server variable in the substitution instead (like you do in the canonical redirect). For example:

# profile redirection
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com [NC]
RewriteRule !^profile/ /profile/%1%{REQUEST_URI} [L]

The check against REDIRECT_STATUS is not required.

This behaves very similarly to the first rule block, except for one less RewriteCond directive. However, a slight caveat with this approach is that you couldn't have a requested URL-path that also starts /profile/ (ie. that maps to a filesystem path like /profile/profile/) - although I imagine this is unlikely.


UPDATE: Since you are using WordPress, it's likely that WordPress itself is triggering an external redirect back to the canonical domain, eg. example.com (as defined by the WP_HOME PHP constants). What you can try, to prevent this, is to set the WP_SITEURL and WP_HOME constants dynamically in wp-config.php to point to the hostname (ie. the subdomain) being requested, instead of being hardcoded to the main domain.

For example:

define('WP_SITEURL','http://'.$_SERVER['HTTP_HOST']);
define('WP_HOME','http://'.$_SERVER['HTTP_HOST']);

(NB: This assumes HTTP, rather than HTTPS.)

Reference:
https://codex.wordpress.org/Editing_wp-config.php#WP_SITEURL

  • 1
    Thank you for the fast answer. The agents is my error. I changed it to profile in my original question. Sorry for the confusion. – aatanasow Mar 14 '18 at 16:33
  • I've added an alternative solution. (Which you choose is up to you.) – MrWhite Mar 14 '18 at 16:45
  • The first solution end to the main domain: example.com. – aatanasow Mar 14 '18 at 16:47
  • The second solution return Internal Server Error. Maybe the WordPress cause the problem? – aatanasow Mar 14 '18 at 16:51
  • Ah, you've just mentioned that this is WordPress. The problem here is that WordPress itself will likely issue a redirect to example.com (the canonical domain). The directives I posted above are an internal rewrite - these would not trigger a redirect. What does the redirected URL-path look like? – MrWhite Mar 14 '18 at 16:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.