15

I'm trying to redirect all users coming to a URL "http://example.com/something" to a URL like "http://answares.com/examples_com/something".

I'm trying with code like this:

server {
  listen 1.2.3.4:80;
  server_name "example.com";
  rewrite ^(.*) http://answares.com/examples_com$1 permanent;
}

By accessing "http://example.com/" I get redirected to "http://answares.com/examples_com/", but by accessing "http://example.com/something" I get redirected to: "http://answares.com/something".

I tried to do it in different ways but the best I got was:

http://answares.com/examples_com//something

Which because of the two slashes looks lame. I'm using Nginx 0.7.65 on Ubuntu 10.4

kmindi
  • 1,441
  • 1
  • 10
  • 17
user93656
  • 253
  • 1
  • 2
  • 5

4 Answers4

17

If you just want to redirect /something, and no other URL, then:

rewrite ^(/something.*) http://answares.com/examples_com$1 permanent;

That'll send a request for http://example.com/something/ to http://answares.com/examples_com/something/,

and, say, http://example.com/something/somewhere/page.html to http://answares.com/examples_com/something/somewhere/page.html

Shane Madden
  • 112,982
  • 12
  • 174
  • 248
8

The fastest way is to do a return instead of a rewrite. see here:

nginx redirect to www.domain

I just answered the linked question and tumbled upon this one.

moestly
  • 1,138
  • 8
  • 10
7

You can do either:

 rewrite ^/(.*)$ http://answares.com/examples_com/$1 permanent;

That brings you:

$ curl -I http://xxxxx.com/some/example/url/here.html

HTTP/1.1 301 Moved Permanently
Server: nginx/0.8.53
Date: Mon, 05 Sep 2011 13:48:23 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: http://answares.com/examples_com/some/example/url/here.html

or

rewrite ^(/.*)$ http://answares.com/examples_com$1 permanent;

You can see that it also works:

$ curl -I http://xxxxxx.com/some/example/url/here.html

HTTP/1.1 301 Moved Permanently
Server: nginx/0.8.53
Date: Mon, 05 Sep 2011 13:47:09 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: http://answares.com/examples_com/some/example/url/here.html

The difference between nginx redirect and mod_rewrite redirects is that nginx doesn't remove the slash(/) after the server name before matching.

In order to remove the double slashes you have, you sould first match the slash in the regexp withouth the parenthesis, and then apply the match; or match everything and apply the match without parenthesis. Using one way or another is just a matter of taste ;-)

  • 1
    Good explanation, and exactly right on how the rule should be laid out - but, your examples are functionally identical to the rewrite in the question, except that they won't tolerate a lack of a trailing slash on a request for just the domain. `.*` matches the slash, and is greedy so it'll take the full string (`$` is implied). To clarify on Apache, it only strips the slash based on current context when in a `Directory` block or `.htaccess` file, or if a `RewriteBase` is used to modify the path. – Shane Madden Sep 06 '11 at 19:11
  • Thanks for the curl -I flag. Viewing request header information can be very useful. – raksheetbhat Jan 22 '20 at 06:36
0

If you're using NGINX with http2 - IP's can support more than one SSL certificate. Create a configuration for the old domain and use it's valid SSL redirecting to the new domain.

In this example, I'm redirecting http and https separately using a permanent 301 redirect to the new domain ;-)

Be sure to change the SSL block there to your own SSL certificate and settings.

server {

   listen 80;
   server_name old-domain.com;

   location / {
    return 301 https://new-domain.com;
   }

}
server {
    listen 443 ssl http2;
    server_name old-domain.com;

    ssl on;

    #Certificate here
    ssl_certificate /etc/letsencrypt/live/old-domain.com/fullchain.pem;t
    ssl_certificate_key /etc/letsencrypt/live/old-domain.com/privkey.pem;

    ssl_session_timeout 5m;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK;

    location / {
        return 301 https://new-domain.com;
    }

}

This will avoid any privacy warnings about mismatched SSL certificates during the redirect.