0

I am trying to rewrite internally (not redirect) all traffic from api.domain.net to domain.net/api.

I've got one VHost handling the domain.net. This endpoint supports /api subdirectory as an entrypoint to API.

I would like to set up another endpoint api.domain.net, preferably in another VHost which would handle the API traffic. In that case I wouldn't like to use /api subdirectory, as domain implies that this is an API.

My project is already using .htaccess to rewrite all the traffic to index.php, as all requests are routed by PHP. Rule: RewriteRule ^(.*)$ /index.php [L,END]

Ideally I would like to add the new, API rewriting rule to the VHost config, as code (and the .htaccess) shall be the same both for API and non-API clients.

What would be the best way to address this?

I've tried to add a rule (before the index.php rule) in the .htaccess just for sake of testing: RewriteRule ^(.*)$ /api/$1, but for some reason it doesn't do anything. Once added I was expecting that all traffic e.g.: https://local.domain.net/api_method would be considered by PHP as originiated from https://local.domain.net/api/api_method therefore routed properly.

EDIT. The .htaccess looks like that (stripped unrelated stuff):

RewriteEngine on
# Allow the Let's Encrypt cert verification
RewriteRule ^.well-known/ - [L,NC]
Options +FollowSymlinks

RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

RewriteRule ^build/js/.*\.js$ - [NC,L]

# Run all non-file-asset requests through site entry point
RewriteCond %{REQUEST_URI} !^/resources/frontend/(images|swf|ttf) [NC]
RewriteRule ^(.*)$ /index.php [L,END]
Tom Raganowicz
  • 2,169
  • 5
  • 27
  • 41
  • If you are using a dedicated VHost for this, then why bother with rewriting in the first place - and not just set its DocumentRoot to the correct folder to begin with? – CBroe Mar 15 '18 at 09:33
  • This is because `DocumentRoot` is the same. The application entry point is exactly the same. – Tom Raganowicz Mar 15 '18 at 10:21
  • So `/api` isn’t an actual directory then, but just a made up route? – CBroe Mar 15 '18 at 10:43
  • @Cbroe it's route indeed. One of the rules above is to rewrite all routes to `index.php`, so the application can handle routing. – Tom Raganowicz Mar 15 '18 at 11:02
  • Can you show the full rewrite setup (at least the parts relevant for this)? If you rewrite to `/api/$1` internally in the `api.domain.net` vhost, then the task of rewriting that one again to some index.php would have to happen there as well, I think. If you only have it set up right now that requests for `domain.net` are rewritten, then an internal rewrite under a different vhost would never get to that. – CBroe Mar 15 '18 at 11:10
  • I've added the `.htaccess` file to my question. There are some rules which say: `don't rewrite` certain things and skip other rules (L flag). There is a rule to redirect `http` to `https`. Finally there is a rule to rewrite all, except few URLs to `index.php`. That happens on the code side. I believe that once we manage to internally rewrite all `/` traffic to `/api` in the API VHost, this `.htaccess` doesn't require changes and will be the same both for API and non-API traffic. I might be wrong though. – Tom Raganowicz Mar 15 '18 at 12:11
  • _“Once added I was expecting that all traffic [...] would be considered by PHP as originiated from `https://local.domain.net/api/api_method` therefore routed properly”_ - well that would first of all depend on what value you are actually accessing in your index.php then as the basis of your routing ... depending on what exactly you are fishing out of $_SERVER there (presumably?), it might not reflect any current internal rewriting status, but the original request URI only. – CBroe Mar 15 '18 at 12:15
  • My routing is based on `$_SERVER['REQUEST_URI']` and this is the one I would like to modify on the Apache2 side. – Tom Raganowicz Mar 15 '18 at 14:55
  • I don’t think you can do that with an internal redirect. This will always be what was originally requested by the client - if it wasn’t, you could not use it for your routing this way to begin with, because you would get `/index.php` all the time. – CBroe Mar 15 '18 at 15:03
  • It is easily possible using NginX and I remember doing it in the past: https://serverfault.com/questions/805881/nginx-populate-request-uri-with-rewritten-url Unfortunately my setup is Apache2 and I didn't want to invest time to migrate to NginX for no other reason. So far I've managed to set up rewrite with `PT, L` flags. In PHP I can see expected rewritten URL using the `$_SERVER['REDIRECT_URL']`, but I am still not satisfied. Probably going to modify the router, so it can detect it there is `api` in the `host` at the beginning and add the `/api` path. Thanks for help. – Tom Raganowicz Mar 15 '18 at 18:12
  • By the way there is a bug in Apache 2.4. First I've played with `.htaccess`, however it was ignored. Adding same redirect in VHost has helped. Link to bug: https://stackoverflow.com/questions/20023601/internal-url-rewrite-no-longer-working-after-upgrading-apache-to-2-4 – Tom Raganowicz Mar 15 '18 at 18:14
  • From the nginx solution, _"$request_uri has the value of the original URI and $uri has the value of the final URI"_ - matches what I meant here regarding Apache, REQUEST_URI will stay the initial value - so you would have to find whatever the equivalent in Apache is for that `$uri` variable. And while `PT` might work to achieve the desired thing, that's more than just a rewrite, with that you are _proxying_ the request from `api.domain.net` to `domain.net/api` internally - so roughly speaking that is two processes occupied to handle every single request instead of one. – CBroe Mar 15 '18 at 18:21

1 Answers1

0
<VirtualHost *>
  ServerName api.example.com
  Options +FollowSymLinks
  RewriteEngine On
  RewriteCond %{REQUEST_URI}/ api
  RewriteRule ^(.*) http://www.example.com/%{REQUEST_URI} [R=301,NC]
</VirtualHost>

This should do it

Diogo Jesus
  • 318
  • 4
  • 19