ExampleEngineering
ExampleEngineering

Reputation: 35

HTACCESS How to "cut" URL at one point

I am new to .htaccess and I don't understand it well. Recently I have built the following code:

RewriteEngine On
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1

This was in the root public folder (example.com/.htaccess). But now I have to create second Rewrite and I want to make .htaccess file in example.com/api/v2/ folder. I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.

What I want to achieve:

If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.

Upvotes: 1

Views: 82

Answers (1)

MrWhite
MrWhite

Reputation: 45948

Addressing your existing rule first:

RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1

The first RewriteCond (condition) is entirely superfluous and can simply be removed. The second condition simply asserts that there is a slash after the v2 and this can be merged with the RewritRule pattern. So, the above is equivalent to a single RewriteRule directive as follows:

RewriteRule ^api/v2(/.*) /api/v2/api.php?input=$1 [L]

This would internally rewrite the request from /api/v2/test/test/123 to /api/v2/api.php?input=/test/test/123 - note the slash prefix on the input URL parameter value.

However, unless you have another .htaccess file in a subdirectory that also contains mod_rewrite directives then this will create a rewrite loop (500 error).

Also note that you should probably include the L flag here to prevent the request being further rewritten (if you have other directives).

If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.

I assume /api? is a typo and this should be /api.php?. Note also that the slash is omitted from the start of the URL parameter value (different to the rule above).

I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.

This is the right idea, however, you need to be careful of rewrite loops (ie. 500 error response) since the rewritten URL is likely matching the regex you are trying to rewrite.

Try the following instead in the /api/v2/.htaccess file:

RewriteEngine On

RewriteCond %{REQUEST_URI} !api\.php$
RewriteRule (.*) api.php?input=$1 [L]

The preceding RewriteCond directive checks that the request is not already for api.php, thus avoiding a rewrite loop, since the pattern .* will naturally match anything, including api.php itself.

You could avoid the additional condition by making the regex more specific. For example, if the requested URL-path cannot contain a dot then the above RewriteCond and RewriteRule directives can be written as a single directive:

RewriteRule ^([^.]*)$ api.php?input=$1 [L]

The regex [^.]* matches anything except a dot, so avoids matching api.php.

Alternatively, only match the characters that are permitted. For example, lowercase a-z, digits and slashes (which naturally excludes the dot), which covers your test string test/test/123:

RewriteRule ^([a-z0-9/]*)$ api.php?input=$1 [L]

Or, if there should always be 3 path segments, /<letters>/<letters>/<digits>, then be specific:

RewriteRule ^([a-z]+/[a-z]+/\d+)$ api.php?input=$1 [L]

Upvotes: 1

Related Questions