From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 7F3621F8C6 for ; Sun, 8 Aug 2021 01:03:50 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH] httpd: set psgi.url_scheme to 'https' for TLS listeners Date: Sun, 8 Aug 2021 01:03:50 +0000 Message-Id: <20210808010350.26700-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: For users using the native TLS functionality of -httpd (instead of using nginx + Plack::Middleware::ReverseProxy), psgi.url_scheme=http was wrong and would lead to improper redirects. --- lib/PublicInbox/HTTPD.pm | 5 +++-- script/public-inbox-httpd | 7 ++++--- t/httpd-corner.psgi | 4 +++- t/httpd-https.t | 7 ++++--- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/PublicInbox/HTTPD.pm b/lib/PublicInbox/HTTPD.pm index fb683f74..02f424c6 100644 --- a/lib/PublicInbox/HTTPD.pm +++ b/lib/PublicInbox/HTTPD.pm @@ -13,7 +13,7 @@ use PublicInbox::Daemon; sub pi_httpd_async { PublicInbox::HTTPD::Async->new(@_) } sub new { - my ($class, $sock, $app) = @_; + my ($class, $sock, $app, $client) = @_; my $n = getsockname($sock) or die "not a socket: $sock $!\n"; my ($host, $port) = PublicInbox::Daemon::host_with_port($n); @@ -23,7 +23,8 @@ sub new { SCRIPT_NAME => '', 'psgi.version' => [ 1, 1 ], 'psgi.errors' => \*STDERR, - 'psgi.url_scheme' => 'http', + 'psgi.url_scheme' => $client->can('accept_SSL') ? + 'https' : 'http', 'psgi.nonblocking' => Plack::Util::TRUE, 'psgi.streaming' => Plack::Util::TRUE, 'psgi.run_once' => Plack::Util::FALSE, diff --git a/script/public-inbox-httpd b/script/public-inbox-httpd index 7b0ec560..a4dd8099 100755 --- a/script/public-inbox-httpd +++ b/script/public-inbox-httpd @@ -42,9 +42,10 @@ my $refresh = sub { }; PublicInbox::Daemon::run('0.0.0.0:8080', $refresh, - sub ($$$) { # post_accept - my ($client, $addr, $srv) = @_; + sub ($$$) { # Listener->{post_accept} + my ($client, $addr, $srv, $tls_wrap) = @_; my $fd = fileno($srv); - my $h = $httpds{$fd} //= PublicInbox::HTTPD->new($srv, $app); + my $h = $httpds{$fd} //= + PublicInbox::HTTPD->new($srv, $app, $client); PublicInbox::HTTP->new($client, $addr, $h), }); diff --git a/t/httpd-corner.psgi b/t/httpd-corner.psgi index 5fab2ba4..e9a3a6b7 100644 --- a/t/httpd-corner.psgi +++ b/t/httpd-corner.psgi @@ -111,8 +111,10 @@ my $app = sub { } elsif ($path eq '/pid') { $code = 200; push @$body, "$$\n"; + } elsif ($path eq '/url_scheme') { + $code = 200; + push @$body, $env->{'psgi.url_scheme'} } - [ $code, $h, $body ] }; diff --git a/t/httpd-https.t b/t/httpd-https.t index b37492eb..bf7d3f94 100644 --- a/t/httpd-https.t +++ b/t/httpd-https.t @@ -53,11 +53,12 @@ for my $args ( # normal HTTPS my $c = tcp_connect($https); IO::Socket::SSL->start_SSL($c, %o); - ok($c->print("GET /empty HTTP/1.1\r\n\r\nHost: example.com\r\n\r\n"), - 'wrote HTTP request'); + $c->print("GET /url_scheme HTTP/1.1\r\n\r\nHost: example.com\r\n\r\n") + or xbail "failed to write HTTP request: $!"; my $buf = ''; - sysread($c, $buf, 2007, length($buf)) until $buf =~ /\r\n\r\n/; + sysread($c, $buf, 2007, length($buf)) until $buf =~ /\r\n\r\nhttps?/; like($buf, qr!\AHTTP/1\.1 200!, 'read HTTP response'); + like($buf, qr!\r\nhttps\z!, "psgi.url_scheme is 'https'"); # HTTPS with bad hostname $c = tcp_connect($https);