From: Eric Wong Date: Fri, 28 Mar 2025 10:34:09 +0000 (+0000) Subject: www: omit SERVER_PORT for standard port redirects X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1b130400c05d3aad532cf1a397468a8a5ebf93a7;p=thirdparty%2Fpublic-inbox.git www: omit SERVER_PORT for standard port redirects 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. --- diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm index 9e0840ab5..dcf79780e 100644 --- a/lib/PublicInbox/Git.pm +++ b/lib/PublicInbox/Git.pm @@ -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 diff --git a/lib/PublicInbox/Hval.pm b/lib/PublicInbox/Hval.pm index 483ea70ef..b54b5cc58 100644 --- a/lib/PublicInbox/Hval.pm +++ b/lib/PublicInbox/Hval.pm @@ -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 '.' # ․ · and ͺ were also candidates: diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm index 87844bf3f..d297ce7ac 100644 --- a/lib/PublicInbox/WwwAttach.pm +++ b/lib/PublicInbox/WwwAttach.pm @@ -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; } diff --git a/lib/PublicInbox/WwwStatic.pm b/lib/PublicInbox/WwwStatic.pm index 7136f3cde..37f95a11a 100644 --- a/lib/PublicInbox/WwwStatic.pm +++ b/lib/PublicInbox/WwwStatic.pm @@ -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 ] ] diff --git a/t/feed.t b/t/feed.t index 8e80b531e..eb5e360e0 100644 --- 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); diff --git a/t/solver_git.t b/t/solver_git.t index 22d01d93e..9adf3e6bd 100644 --- a/t/solver_git.t +++ b/t/solver_git.t @@ -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]; diff --git a/xt/perf-msgview.t b/xt/perf-msgview.t index ef261359b..b98f05df8 100644 --- a/xt/perf-msgview.t +++ b/xt/perf-msgview.t @@ -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(),