# mainly for curl (no-'-L') users:
$body = "Redirecting to $redir\n";
} else {
- push @h, qw(Content-Type text/plain);
+ push @h, 'Content-Type', 'text/plain; charset=UTF-8';
}
[ $status, \@h, [ $body ] ]
}
+sub rt {
+ my ($self, $status, $t) = @_;
+ my $res = [ $status, [ 'Content-Type', "text/$t; charset=UTF-8" ] ];
+ $res->[2] = [ $_[3] ] if defined $_[3];
+ $res;
+}
+
1;
my $env = $req->{env};
if (!defined $r) {
my $git = $req->{-repo}->{git};
- return [ 400, [ 'Content-Type', 'text/plain' ],
- [ $git->err ] ];
+ return $self->rt(400, 'plain', $git->err);
}
$env->{'qspawn.filter'} = git_atom_sed($self, $req);
[ 200, [ 'Content-Type', 'application/atom+xml' ] ];
$qsp->psgi_return($env, undef, sub { # parse header
my ($r, $bref) = @_;
if (!defined $r) {
- my $errmsg = $git->err;
- [ 500, [ 'Content-Type', 'text/html' ], [ $errmsg ] ];
+ $self->rt(500, 'plain', $git->err);
} elsif ($r == 0) {
- git_commit_404($req);
+ git_commit_404($self, $req);
} else {
$env->{'qspawn.filter'} = git_commit_sed($self, $req);
- [ 200, [ 'Content-Type', 'text/html' ] ];
+ $self->rt(200, 'html');
}
});
}
sub git_commit_404 {
- my ($req) = @_;
+ my ($self, $req) = @_;
my $x = 'Missing commit or path';
my $pfx = "$req->{relcmd}commit";
$x .= "<a\nhref=\"$pfx\">$try the latest commit in HEAD</a>\n";
$x .= '</pre></body>';
- [404, ['Content-Type', 'text/html'], [ $x ]];
+ $self->rt(404, 'html', $x);
}
# FIXME: horrifically expensive...
$qsp->psgi_return($env, undef, sub { # parse header
my ($r) = @_;
if (!defined $r) {
- [ 500, [ 'Content-Type', 'text/plain' ], [ $git->err ]];
+ $self->rt(500, 'plain', $git->err);
} elsif ($r == 0) {
- [ 200, [ 'Content-Type', 'text/html' ], [
+ $self->rt(200, 'html',
delete($req->{dhtml}).
- 'No differences</pre></body></html>' ]
- ]
+ 'No differences</pre></body></html>');
} else {
$env->{'qspawn.filter'} = git_diff_sed($self, $req);
- [ 200, [ 'Content-Type', 'text/html' ] ];
+ $self->rt(200, 'html');
}
});
}
$qsp->psgi_return($env, undef, sub {
my ($r) = @_;
if (!defined $r) {
- [ 500, [ 'Content-Type', 'text/html' ], [ $git->err ] ];
+ $self->rt(500, 'html', $git->err);
} elsif ($r == 0) {
- [ 404, [ 'Content-Type', 'text/html' ], [ $git->err ] ];
+ $self->rt(404, 'html', $git->err);
} else {
$env->{'qspawn.filter'} = git_log_sed($self, $req);
- [ 200, [ 'Content-Type', 'text/html' ] ];
+ $self->rt(200, 'html');
}
});
}
my $qsp = PublicInbox::Qspawn->new($cmd);
$qsp->psgi_return($env, undef, sub {
my ($r) = @_;
- my $h = ['Content-Type', 'text/plain; charset=UTF-8'];
- $r ? [ 200, $h ] : [ 500, $h, [ "format-patch error\n" ] ];
+ $r ? $self->rt(200, 'plain') :
+ $self->rt(500, 'plain', "format-patch error\n");
});
}
if ($type eq 'blob') {
$type = git_blob_mime_type($self, $req, $cat, \$buf, \$left);
} elsif ($type eq 'commit' || $type eq 'tag') {
- $type = 'text/plain';
+ $type = 'text/plain; charset=UTF-8';
} elsif ($type eq 'tree') {
$git->cat_file_finish($left);
- return git_tree_raw($req, $git, $hex);
+ return git_tree_raw($self, $req, $git, $hex);
} else {
$type = 'application/octet-stream';
}
# This should follow the cgit DOM structure in case anybody depends on it,
# not using <pre> here as we don't expect people to actually view it much
sub git_tree_raw {
- my ($req, $git, $hex) = @_;
+ my ($self, $req, $git, $hex) = @_;
my @ex = @{$req->{extra}};
my $rel = $req->{relcmd};
$qsp->psgi_return($env, undef, sub {
my ($r) = @_;
if (!defined $r) {
- [ 500, [ 'Content-Type', 'text/plain' ], [ $git->err ]];
+ $self->rt(500, 'plain', $git->err);
} else {
$env->{'qspawn.filter'} = git_tree_sed($req);
- [ 200, [ 'Content-Type', 'text/html' ] ];
+ $self->rt(200, 'html');
}
});
}
my ($info) = @_;
my ($hex, $type, $size) = @$info;
unless (defined $type) {
- return $res->([404,
- ['Content-Type','text/plain'],
- ['Not Found']]);
+ $res->($self->rt(404, 'plain', 'Not Found'));
}
show_tree($self, $req, $res, $hex, $type, $size);
});
$req->{thtml} = $self->html_start($req, $title, $opts) . "\n";
if ($type eq 'tree') {
$opts->{noindex} = 1;
- git_tree_show($req, $res, $hex);
+ git_tree_show($self, $req, $res, $hex);
} elsif ($type eq 'blob') {
- git_blob_show($req, $res, $hex, $size);
+ git_blob_show($self, $req, $res, $hex, $size);
} else {
- $res->([404, ['Content-Type', 'text/plain; charset=UTF-8'],
- ["Unrecognized type ($type) for $hex\n"]]);
+ $res->($self->rt(404, 'plain',
+ "Unrecognized type ($type) for $hex\n"));
}
}
}
sub git_blob_show {
- my ($req, $res, $hex, $size) = @_;
+ my ($self, $req, $res, $hex, $size) = @_;
my $sed = git_blob_sed($req, $hex, $size);
my $git = $req->{-repo}->{git};
if ($size <= $MAX_ASYNC) {
if ($ref eq 'SCALAR') {
$buf .= $$r;
if (bytes::length($buf) == $size) {
- my $fh = $res->([200,
- ['Content-Type',
- 'text/html; charset=UTF-8']]);
+ my $fh = $res->($self->rt(200, 'html'));
$fh->write($sed->($buf));
$fh->write($sed->(undef));
$fh->close;
}
my $cb = $res or return;
$res = undef;
- $cb->([500,
- ['Content-Type', 'text/plain; charset=UTF-8'],
- [ 'Error' ]]);
+ $cb->($self->rt(500, 'plain', "Error\n"));
});
} else {
- $res->([200, ['Content-Type', 'text/plain; charset=UTF-8'],
- [ 'Too big' ]]);
+ $res->($self->rt(200, 'plain', "Too big\n"));
}
}
}
sub git_tree_show {
- my ($req, $res, $hex) = @_;
+ my ($self, $req, $res, $hex) = @_;
my $git = $req->{-repo}->{git};
my $cmd = $git->cmd(qw(ls-tree -l -z), $git->abbrev, $hex);
my $rdr = { 2 => $git->err_begin };
my ($r) = @_;
if (defined $r) {
$env->{'qspawn.filter'} = git_tree_sed($req);
- [ 200, [ 'Content-Type', 'text/html' ] ];
+ $self->rt(200, 'html');
} else {
- [ 500, [ 'Content-Type', 'text/plain' ], [ $git->err ]];
+ $self->rt(500, 'plain', $git->err);
}
});
}
my $refs = $git->popen(qw(for-each-ref --sort=-creatordate),
EACH_REF_FMT, "--count=$count",
qw(refs/heads/ refs/tags/));
- $fh = $res->([200, ['Content-Type', 'text/html; charset=UTF-8']]);
+ $fh = $res->($self->rt(200, 'html'));
# ref names are unpredictable in length and requires tables :<
$fh->write($self->html_start($req,
"$repo->{repo}: overview") .
my ($self, $req, $h, $res) = @_;
my $git = $req->{-repo}->{git};
my $fh;
- my $hdr = ['Content-Type', 'text/html; charset=UTF-8'];
# yes, this could still theoretically show anything,
# but a tag could also point to anything:
$git->cat_file("refs/tags/$h", sub {
my ($cat, $left, $type, $hex) = @_;
- $fh = $res->([200, $hdr]);
+ $fh = $res->($self->rt(200, 'html'));
$h = PublicInbox::Hval->utf8($h);
my $m = "git_show_${type}_as_tag";
}
});
unless ($fh) {
- $fh = $res->([404, $hdr]);
+ $fh = $res->($self->rt(404, 'html'));
$fh->write(invalid_tag_start($req, $h));
}
$fh->write('</pre></body></html>');
my $req = 'http://example.com/test.git/log';
my $res = $cb->(GET($req));
is($res->code, 200, 'got 200');
- is($res->header('Content-Type'), 'text/html',
+ is($res->header('Content-Type'), 'text/html; charset=UTF-8',
'got correct Content-Type');
my $body = dechunk($res);
like($body, qr!</html>!, 'valid HTML :)');