AEM 6.3: Bad Request when replacing dot in selector for slash

Viewed 312

I am trying to make my product details page have the following format:

https://stage.aemsite.com/en/product-details/some-product

We use selectors for our product details so I understand AEM won't be able to interpret this, my idea was to use the dispatcher to allow a passthrough to the correct format https://stage.aemsite.com/en/product-details.some-product, but this is resulting in a bad request.

I tested this on https://technicalseo.com/tools/htaccess/ and it should technically work.

RewriteCond %{REQUEST_URI} ^/([a-z]{2})/product-details/([^?]*)(/?)$
RewriteRule ^ https://%{SERVER_NAME}/%1/product-details.%2 [PT,L,NC]

Any idea?

EDIT: As per the correct answer this was the format that worked for me, the reason being that AEM needs the path to be the path to the resource inside the content tree.

RewriteRule ^([a-z]{2})/product-details/([^?]*?)/?$ https://%{SERVER_NAME}/content/marketplace/$1/product-details.$2 [L]
1 Answers

I tested this on https://technicalseo.com/tools/htaccess/ and it should technically work.

FWIW, that tool looks wrong IMO. (I think it's ignoring the PT flag?)

RewriteCond %{REQUEST_URI} ^/([a-z]{2})/product-details/([^?]*)(/?)$
RewriteRule ^ https://%{SERVER_NAME}/%1/product-details.%2 [PT,L,NC]

The "400 Bad Request" is most certainly due to using the PT (passthrough) flag with an absolute URL. You should not be using an absolute URL here (unless you want to trigger an external redirect or proxy the request) and the PT flag is then not required in a .htaccess context, since this is the default action.

The trailing part of your regex ([^?]*)(/?)$, is arguably incorrect. It looks like you are trying to omit an optional trailing slash from the first captured subpattern. However, that is not what this regex does. Because the preceding quantifier (*) is greedy, this will also consume the optional trailing slash, so the /? that follows doesn't actually do anything. The regex ([^?]*)(/?)$ is the same as ([^?]*)$. (It's also unlikely that you have a %-encoded ? in the URL-path, so this is probably the same as (.*).) If you wanted to exclude an optional trailing slash from being captured, you would need to make the preceding pattern non-greedy, so that it doesn't consume the optional trailing slash. eg. ([^?]*?)/?$ (the capturing group at the end would seem to be superfluous). Or, use alternation, eg. ([^?]*)(?:/|)$. Or, make the preceding pattern more restrictive, so it won't match a slash. eg. ^([\w-]*)/?$. (Side note: making the trailing slash optional here, potentially creates a duplicate content issue.)

You also don't need the RewriteCond directive, as this check can be performed (more efficiently) in the RewriteRule pattern.

The NC flag on the RewriteRule does not apply to the condition anyway, so this flag is superfluous in the rule you posted. However, it would only serve to promote duplicate content.

So, taking the above points into consideration would result in the following:

RewriteRule ^([a-z]{2})/product-details/([^?]*?)/?$ $1/product-details.$2 [L]

HOWEVER, whether this works or not with AEM (or any CMS) is another matter, since AEM probably only "sees" the requested URL that contains a slash. The rewritten URL containing a dot is mostly hidden from the backend script unless it is expected and knows where to look. When the URL is rewritten like this, Apache sets the REDIRECT_URL server variable to the rewritten URL, but a CMS is unlikely to check this since it's not necessarily the URL being requested.

The order of these directives in .htaccess is also important. Presumably you have a front-controller pattern later in the file that routes the request?

Related