0

I am attempting to redirect

<VirtualHost *:5555>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteCond %{SERVER_PORT} =5555
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

However when I attempt to connect to via a web browser it is adding an extra / inbetween the %{HTTP_HOST}//%{REQUEST_URI}

How do I remove the extra / between the values?

MrWhite
  • 13,016
sroth79
  • 1
  • 1

3 Answers3

1

If the Redirect directive is used within a <Location> or <LocationMatch> section with the URL-path omitted, then the URL parameter will be interpreted using expression syntax.

This syntax is available in Apache 2.4.19 and later

This makes this, once again, a case of When not to use mod_rewrite.

<VirtualHost *:5555>
    <Location />
        Redirect permanent https://%{HTTP_HOST}/
    </Location>
</VirtualHost>
Esa Jokinen
  • 49,773
  • However, the HTTP_HOST server variable (the value of the Host HTTP request header) also includes the port number (if present on the request), so this would redirect to the same port, not port 80 as would seem to be the intention? (Although the same issue would affect the OPs code as well, but neither would the OPs code result in a double slash, so I suspect there is something else going on here?) – MrWhite Nov 10 '23 at 00:29
  • But also... when "the URL parameter is interpreted using expression syntax" is the source URL-path still appended to the target? I would think that would/could conflict with the "expression syntax"? The docs aren't clear, except for the similar case with the Alias directive, where the source URL-path is dropped (mapping to a single URL, as defined using the expression syntax). (There is a new directive AliasPreservePath in later version 2.5.1 that preserves the URL-path with regards to the Alias directive, default Off. Nothing similar for the Redirect directive though AFAICS.) – MrWhite Nov 10 '23 at 00:40
  • Ah, with regards to my first comment... since the redirect is to https (port 443 by default, not port 80 as I mentioned) then that may resolve the issue? (Although I'm not convinced it would?) – MrWhite Nov 10 '23 at 00:48
  • Haven't got time to test this. Is there a variable without the port number? Any suggestions on how to improve this? – Esa Jokinen Nov 10 '23 at 04:28
  • "Is there a variable without the port number?" - Unfortunately not. You would normally need to extract the hostname less the port number using a regex and RewriteCond directive, but then you are back to using mod_rewrite. I'm not sure how that could be written in expression-syntax suitable for a Redirect directive? (Aside: I wonder if a general solution is really necessary and the hostname could simply be hardcoded?) – MrWhite Nov 10 '23 at 19:31
  • Furthermore, I wonder why is this even wanted in the first place, because who would land on http://example.com:5555 anyway. – Esa Jokinen Nov 11 '23 at 07:54
  • Redirect can specify a path, no need to use Location, this is bad advice. – Daniel Ferradal Nov 12 '23 at 15:56
  • Path is required for using the expression syntax, as explained in the answer. – Esa Jokinen Nov 12 '23 at 16:14
  • 1
    Typo: "Path is required for using the expression syntax" - Should be "<Location> is required for using the expression syntax". This is neither good or "bad", it's simply the required syntax. @DanielFerradal – MrWhite Nov 12 '23 at 22:27
0

No need to check the port or if it is SSL, if a requests that is SSL lands here you will get an error since virtualhost won't be able to answer, and virtualhost is already specifying it is port 5555 the port this virtualhost is answering too, so you those redundand directives are not necessary.

If you insist on using mod rewrite and using variables this would be the most simple/correct way.

<VirtualHost *:5555>
    ServerName normallyouwantahostnamehere.example.com
    RewriteEngine On
    RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [R=301,L]
</VirtualHost>

If you know the hostname I would be inclined to define it correctly and use a simple redirect (which redirects everything without the need to capture):

<VirtualHost *:5555>
    ServerName hostname.example.com
    Redirect / https://hostname.example.com/
</VirtualHost
  • 1
    As mentioned in my comment on @Esa's answer, "the HTTP_HOST server variable also includes the port number (if present on the request)", so your RewriteRule would redirect back to port 5555, not port 443, which is presumably the intention. – MrWhite Nov 12 '23 at 22:39
-2

It looks like you're trying to redirect HTTP requests on port 5555 to HTTPS without an extra slash between the %{HTTP_HOST} and %{REQUEST_URI}. You can achieve this by modifying your RewriteRule slightly.

Here's the updated configuration:

<VirtualHost *:5555>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteCond %{SERVER_PORT} =5555
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

The key change here is in the RewriteRule. By using ^ before https://%{HTTP_HOST}, it anchors the rule to the beginning of the URL, ensuring that there won't be an extra slash inserted.

With this modification, the redirect should work without the extra slash between %{HTTP_HOST} and %{REQUEST_URI}.

Let us know if this works, or if you're still having problems!

Loni Venn
  • 1
  • 1
  • 1
    Sorry, but this is nonsense. You are simply changing the RewriteRule pattern (that matches against the requested URL-path) from (.*) to ^, which will make no difference at all in this context. "By using ^ before https://%{HTTP_HOST}, it anchors the rule to the beginning of the URL" - no it doesn't. The ^ simply asserts the start-of-string, which will be successful for everything (every URL-path). Whereas (.*) matches everything (and unnecessarily captures everything - the backreference is not used), so the result of ^ and (.*) is the same in this context. – MrWhite Nov 10 '23 at 00:56