Forum Moderators: phranque

Message Too Old, No Replies

Rewite to HTTPS and Redirect to REST Controller

Rest Https

         

wippel

8:11 pm on Nov 13, 2009 (gmt 0)

10+ Year Member



I want to implement a RESTful API on my site.

I would use [mysite...] or [mysite...] to access different resources in a RESTful way.

In order to do that I want to implement a REST controller by redirecting all URLs of the form [mysite...] to one file [mysite...] and that file will parse the full URL to determine if it is Car or Person or whatever.

I am able to do this mapping by using this:

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule /api/.*$ - [NC,L]
RewriteRule /api/.*$ /opt/app1/api/index.php [NC,L]

Where /opt/app1/api/index.php is the local path to the index.php file.

I also want the URLs [mysite...] to be handled by HTTPS, so remapping them to [mysite...]

I can get this to work on its own using the following rule

RewriteCond %{HTTPS} off
RewriteRule /api/(.*) [%{HTTP_HOST}...] [R]

What I can't do is get them to work together, i.e. turn the URL [mysite...] to [mysite...] and send it to /opt/app1/api/index.php

My best attempt is this:

RewriteCond %{HTTPS} off
RewriteRule /api/(.*) [%{HTTP_HOST}...] [R]

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule /api/.*$ - [NC,L]
RewriteRule /api/.*$ /opt/app1/api/index.php [NC,L]

But somehow the rewite log shows it going throug twice and the https doesn't get set to the calling URL

I am at a breaking point :)

Please help.

g1smd

9:24 pm on Nov 13, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The [R] gives a 302 redirect. I would change that to a 301 redirect.

You need to redirect only if the request was a direct client request, not when there was an internal rewrite.

When a URL request is connected to an internal filepath, that's a rewrite, not a redirect.

jdMorgan

11:01 pm on Nov 13, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Try these tweaks for robustness and speed:

RewriteCond %{SERVER_PORT} !=443
RewriteRule /api/(.*)$ https://%{HTTP_HOST}/api/$1 [R=301,L]
#
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule /api/ - [NC,L]
RewriteRule /api/ /opt/app1/api/index.php [NC,L]

Jim

wippel

3:45 am on Nov 17, 2009 (gmt 0)

10+ Year Member



I tried your solutions and it still doesn't seem to get to the second set of rules where the REST controller mapping is:

47.130.80.158 - - [16/Nov/2009:22:39:57 --0500] [47.135.81.214/sid#88783f0][rid#8ae85f8/initial] (2) init rewrite engine with requested uri /api/Person
47.130.80.158 - - [16/Nov/2009:22:39:57 --0500] [47.135.81.214/sid#88783f0][rid#8ae85f8/initial] (3) applying pattern '/api/(.*)$' to uri '/api/Person'
47.130.80.158 - - [16/Nov/2009:22:39:57 --0500] [47.135.81.214/sid#88783f0][rid#8ae85f8/initial] (4) RewriteCond: input='80' pattern='!=443' => matched
47.130.80.158 - - [16/Nov/2009:22:39:57 --0500] [47.135.81.214/sid#88783f0][rid#8ae85f8/initial] (2) rewrite '/api/Person' -> 'https://47.135.81.214/api/Person'
47.130.80.158 - - [16/Nov/2009:22:39:57 --0500] [47.135.81.214/sid#88783f0][rid#8ae85f8/initial] (2) explicitly forcing redirect with [47.135.81.214...]
47.130.80.158 - - [16/Nov/2009:22:39:57 --0500] [47.135.81.214/sid#88783f0][rid#8ae85f8/initial] (1) escaping [47.135.81.214...] for redirect
47.130.80.158 - - [16/Nov/2009:22:39:57 --0500] [47.135.81.214/sid#88783f0][rid#8ae85f8/initial] (1) redirect to [47.135.81.214...] [REDIRECT/301]

At this point the brower displays the HTTPS URL with error message:

Not Found
The requested URL /api/Person was not found on this server.

jdMorgan

4:08 am on Nov 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The ruleset for rewriting /api/Person to /opt/appl/api/index.php needs to go in the HTTPS server instance.

Because there is no rewritelog entry showing this ruleset being tested after the redirect, that must be a different server instance from this one, which is only serving/logging HTTP requests.

Jim

wippel

1:52 pm on Nov 17, 2009 (gmt 0)

10+ Year Member



Are you saying that the second set of rules needs to go with the default virtual host for port 443 in the ssl.conf file?

I may not always have permission to modify this site at a customer installation. Is there a way around that problem?

jdMorgan

1:58 pm on Nov 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The internal rewrite code needs to go into httpd.conf, conf.d, other config file, or any .htaccess file that will be traversed during the URL-to-filepath translation directory-walk phase of the Apache API -- IOW, it needs to go in some/any location where it will be executed for SSL requests.

The missing rewritelog file entries indicate that this is not the case right now.

Jim

wippel

4:31 pm on Nov 17, 2009 (gmt 0)

10+ Year Member



Getting closer thanks to your help. One final problem (I think) I have an alias which puts the api directory somwhere else other than the document root in other words

Alias /api/ /opt/app1/api/
RewriteEngine on
RewriteLog "/var/log/rewrite.log"
RewriteLogLevel 9

RewriteCond %{SERVER_PORT} !=443
RewriteRule /api/(.*)$ [%{HTTP_HOST}...] [R=301,L]
#
<Directory /opt/app1/api>
AllowOverride All
</Directory>

My rewrite rules in the .htaccess of /opt/app1/api are:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule .*$ - [NC,L]
RewriteRule .*$ /opt/app1/api/index.php [NC,L]

The problem is that when it forces to /opt/app1/api/index.php it wants to prefix it with the document root rather than relative to the alaised path

==> ../rewrite.log <==
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9be73f0][rid#9e57248/initial] (2) init rewrite engine with requested uri /api/Person
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9be73f0][rid#9e57248/initial] (3) applying pattern '/api/(.*)$' to uri '/api/Person'
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9be73f0][rid#9e57248/initial] (4) RewriteCond: input='80' pattern='!=443' => matched
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9be73f0][rid#9e57248/initial] (2) rewrite '/api/Person' -> 'https://47.135.81.214/api/Person'
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9be73f0][rid#9e57248/initial] (2) explicitly forcing redirect with [47.135.81.214...]
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9be73f0][rid#9e57248/initial] (1) escaping [47.135.81.214...] for redirect
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9be73f0][rid#9e57248/initial] (1) redirect to [47.135.81.214...] [REDIRECT/301]
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (3) [perdir /opt/app1/api/] strip per-dir prefix: /opt/app1/api/Person -> Person
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (3) [perdir /opt/app1/api/] applying pattern '.*$' to uri 'Person'
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (4) [perdir /opt/app1/api/] RewriteCond: input='/opt/app1/api/Person' pattern='-s' => not-matched
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (4) [perdir /opt/app1/api/] RewriteCond: input='/opt/app1/api/Person' pattern='-d' => not-matched
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (4) [perdir /opt/app1/api/] RewriteCond: input='/opt/app1/api/Person' pattern='-l' => not-matched
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (3) [perdir /opt/app1/api/] strip per-dir prefix: /opt/app1/api/Person -> Person
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (3) [perdir /opt/app1/api/] applying pattern '.*$' to uri 'Person'
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (2) [perdir /opt/app1/api/] rewrite 'Person' -> '/opt/app1/api/index.php'
47.130.80.158 - - [17/Nov/2009:11:19:32 --0500] [47.135.81.214/sid#9c7ed10][rid#9e5d738/initial] (1) [perdir /opt/app1/api/] internal redirect with /opt/app1/api/index.php [INTERNAL REDIRECT]

and I get an error in the ssl_error_log

[Tue Nov 17 11:19:32 2009] [error] [client 47.130.80.158] File does not exist: /var/www/html/opt

which presumably is an attemp to create the path /var/www/html/opt/app1/api/index.php rather than what I want which is just /opt/app1/api/index.php. Any ideas?

wippel

7:19 pm on Nov 17, 2009 (gmt 0)

10+ Year Member



Got it!

RewriteBase /api/

Thanks so much for all the help :)