]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
www: omit SERVER_PORT for standard port redirects
authorEric Wong <e@80x24.org>
Fri, 28 Mar 2025 10:34:09 +0000 (10:34 +0000)
committerEric Wong <e@80x24.org>
Sun, 30 Mar 2025 18:19:35 +0000 (18:19 +0000)
For HTTP requests without a `Host:' header, we can omit
the server port component of the URL if using port 443
for `https' or 80 for plain `http'.  We'll also consistently
use SCRIPT_NAME in all of our tests since Plack requires
it.

lib/PublicInbox/Git.pm
lib/PublicInbox/Hval.pm
lib/PublicInbox/WwwAttach.pm
lib/PublicInbox/WwwStatic.pm
t/feed.t
t/solver_git.t
xt/perf-msgview.t

index 9e0840ab5cbf0b426ce06ccaef69787d2802bf34..dcf79780ef6b9b11de8cba232aa4a1a0224eaa26 100644 (file)
@@ -509,10 +509,8 @@ sub local_nick ($) {
 sub host_prefix_url ($$) {
        my ($env, $url) = @_;
        return $url if index($url, '//') >= 0;
-       my $host_port = $env->{HTTP_HOST} //
-               "$env->{SERVER_NAME}:$env->{SERVER_PORT}";
-       my $sn = $env->{SCRIPT_NAME} // '';
-       "$env->{'psgi.url_scheme'}://\L$host_port\E$sn/$url";
+       require PublicInbox::Hval;
+       PublicInbox::Hval::psgi_base_url($env) . '/' . $url;
 }
 
 sub base_url { # for coderepos, PSGI-only
index 483ea70ef07511c91bb18fbdd552479e4c6e2134..b54b5cc5848672032f34a676335cb27dbf8a0b90 100644 (file)
@@ -11,7 +11,7 @@ use PublicInbox::MID qw/mid_clean mid_escape/;
 use base qw/Exporter/;
 our @EXPORT_OK = qw(ascii_html obfuscate_addrs to_filename src_escape
                to_attr prurl mid_href fmt_ts ts2str utf8_maybe
-               sanitize_local_paths);
+               sanitize_local_paths psgi_base_url);
 use POSIX qw(strftime);
 my $enc_ascii = find_encoding('us-ascii');
 use File::Spec::Functions qw(abs2rel);
@@ -84,6 +84,18 @@ sub prurl ($$) {
        }
 }
 
+sub psgi_base_url ($) {
+       my ($env) = @_;
+       my $scheme = $env->{'psgi.url_scheme'};
+       my $host_port = $env->{HTTP_HOST} // do {
+               my @h = ($env->{SERVER_NAME}, $env->{SERVER_PORT});
+               pop(@h) if (($h[1] == 443 && $scheme eq 'https') ||
+                               ($h[1] == 80 && $scheme eq 'http'));
+               join ':', @h;
+       };
+       $scheme . '://' . $host_port . $env->{SCRIPT_NAME};
+}
+
 # for misguided people who believe in this stuff, give them a
 # substitution for '.'
 # &#8228; &#183; and &#890; were also candidates:
index 87844bf3f0e466a1b686f4e54eb0a9a6d5dd60ad..d297ce7ac659fd9f6045031eba32a80ce4691164 100644 (file)
@@ -6,6 +6,7 @@ package PublicInbox::WwwAttach; # internal package
 use strict;
 use v5.10.1;
 use parent qw(PublicInbox::GzipFilter);
+use PublicInbox::Hval qw(psgi_base_url);
 use PublicInbox::Eml;
 
 sub referer_match ($) {
@@ -19,9 +20,7 @@ sub referer_match ($) {
        # n.b.: $ctx->{ibx}->base_url($env) with INBOX_URL won't work
        # with dillo, we can only match "$url_scheme://$HTTP_HOST/" without
        # path components
-       my $base_url = lc($env->{'psgi.url_scheme'} . '://' .
-                       ($env->{HTTP_HOST} //
-                        "$env->{SERVER_NAME}:$env->{SERVER_PORT}") . '/');
+       my $base_url = psgi_base_url($env).'/';
        index($referer, $base_url) == 0;
 }
 
index 7136f3cdedeb550dd8eb76f555c12c9094696308..37f95a11a426db86bf90a5c2917d1ba07acd8db8 100644 (file)
@@ -18,7 +18,7 @@ use HTTP::Status qw(status_message);
 use Errno qw(EACCES ENOTDIR ENOENT);
 use URI::Escape qw(uri_escape_utf8);
 use PublicInbox::GzipFilter qw(gzf_maybe);
-use PublicInbox::Hval qw(ascii_html fmt_ts);
+use PublicInbox::Hval qw(ascii_html fmt_ts psgi_base_url);
 use Plack::MIME;
 our @EXPORT_OK = qw(@NO_CACHE r path_info_raw);
 
@@ -227,10 +227,7 @@ sub path_info_raw ($) {
 
 sub redirect_slash ($) {
        my ($env) = @_;
-       my $url = $env->{'psgi.url_scheme'} . '://';
-       my $host_port = $env->{HTTP_HOST} //
-               "$env->{SERVER_NAME}:$env->{SERVER_PORT}";
-       $url .= $host_port . path_info_raw($env) . '/';
+       my $url = psgi_base_url($env) . path_info_raw($env) . '/';
        my $body = "Redirecting to $url\n";
        [ 302, [ qw(Content-Type text/plain), 'Location', $url,
                'Content-Length', length($body) ], [ $body ] ]
index 8e80b531e489b863a85a4159a15c33dd5c8f1858..eb5e360e08955ff6c38f622b9a0c2c720c02d12e 100644 (file)
--- a/t/feed.t
+++ b/t/feed.t
@@ -37,7 +37,11 @@ $ibx->{url} = [ 'http://example.com/test' ];
 $ibx->{feedmax} = 3;
 my $ctx = {
        ibx => $ibx,
-       env => { HTTP_HOST => 'example.com', 'psgi.url_scheme' => 'http' },
+       env => {
+               HTTP_HOST => 'example.com',
+               'psgi.url_scheme' => 'http',
+               SCRIPT_NAME => '',
+       },
 };
 my $string_feed = sub {
        my $res = PublicInbox::Feed::generate($ctx);
index 22d01d93ee129bc63802812ebf049314a7827e1c..9adf3e6bd917105af72becf7a6315cb54bd09922 100644 (file)
@@ -156,7 +156,7 @@ my $res;
 my $solver = PublicInbox::SolverGit->new($ibx, sub { $res = $_[0] });
 open my $log, '+>>', "$tmpdir/solve.log";
 my $psgi_env = { 'psgi.errors' => \*STDERR, 'psgi.url_scheme' => 'http',
-               'HTTP_HOST' => 'example.com' };
+               'HTTP_HOST' => 'example.com', SCRIPT_NAME => '' };
 $solver->solve($psgi_env, $log, '69df7d5', {});
 ok($res, 'solved a blob!');
 my $wt_git = $res->[0];
index ef261359bbc76e6281da091abf952e2c330918e7..b98f05df84b0851733d268655b2ac84a1afc1e12 100644 (file)
@@ -35,7 +35,11 @@ if ($fh) {
 }
 
 my $ctx = bless {
-       env => { HTTP_HOST => 'example.com', 'psgi.url_scheme' => 'https' },
+       env => {
+               HTTP_HOST => 'example.com',
+               'psgi.url_scheme' => 'https',
+               SCRIPT_NAME => ''
+       },
        ibx => $ibx,
        www => Plack::Util::inline_object(style => sub {''}),
        gz => PublicInbox::GzipFilter::gzip_or_die(),