Skip to content

Commit 0f3ddd4

Browse files
committed
Merge branch 'wk/gitweb-snapshot-use-if-modified-since'
Makes 'snapshot' request to "gitweb" honor If-Modified-Since: header, based on the commit date. By W. Trevor King * wk/gitweb-snapshot-use-if-modified-since: gitweb: add If-Modified-Since handling to git_snapshot(). gitweb: refactor If-Modified-Since handling gitweb: add `status` headers to git_feed() responses.
2 parents 11047e0 + 8745db6 commit 0f3ddd4

File tree

2 files changed

+98
-27
lines changed

2 files changed

+98
-27
lines changed

gitweb/gitweb.perl

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7004,6 +7004,28 @@ sub snapshot_name {
70047004
return wantarray ? ($name, $name) : $name;
70057005
}
70067006

7007+
sub exit_if_unmodified_since {
7008+
my ($latest_epoch) = @_;
7009+
our $cgi;
7010+
7011+
my $if_modified = $cgi->http('IF_MODIFIED_SINCE');
7012+
if (defined $if_modified) {
7013+
my $since;
7014+
if (eval { require HTTP::Date; 1; }) {
7015+
$since = HTTP::Date::str2time($if_modified);
7016+
} elsif (eval { require Time::ParseDate; 1; }) {
7017+
$since = Time::ParseDate::parsedate($if_modified, GMT => 1);
7018+
}
7019+
if (defined $since && $latest_epoch <= $since) {
7020+
my %latest_date = parse_date($latest_epoch);
7021+
print $cgi->header(
7022+
-last_modified => $latest_date{'rfc2822'},
7023+
-status => '304 Not Modified');
7024+
goto DONE_GITWEB;
7025+
}
7026+
}
7027+
}
7028+
70077029
sub git_snapshot {
70087030
my $format = $input_params{'snapshot_format'};
70097031
if (!@snapshot_fmts) {
@@ -7030,6 +7052,10 @@ sub git_snapshot {
70307052

70317053
my ($name, $prefix) = snapshot_name($project, $hash);
70327054
my $filename = "$name$known_snapshot_formats{$format}{'suffix'}";
7055+
7056+
my %co = parse_commit($hash);
7057+
exit_if_unmodified_since($co{'committer_epoch'}) if %co;
7058+
70337059
my $cmd = quote_command(
70347060
git_cmd(), 'archive',
70357061
"--format=$known_snapshot_formats{$format}{'format'}",
@@ -7039,9 +7065,15 @@ sub git_snapshot {
70397065
}
70407066

70417067
$filename =~ s/(["\\])/\\$1/g;
7068+
my %latest_date;
7069+
if (%co) {
7070+
%latest_date = parse_date($co{'committer_epoch'}, $co{'committer_tz'});
7071+
}
7072+
70427073
print $cgi->header(
70437074
-type => $known_snapshot_formats{$format}{'type'},
70447075
-content_disposition => 'inline; filename="' . $filename . '"',
7076+
%co ? (-last_modified => $latest_date{'rfc2822'}) : (),
70457077
-status => '200 OK');
70467078

70477079
open my $fd, "-|", $cmd
@@ -7821,33 +7853,14 @@ sub git_feed {
78217853
if (defined($commitlist[0])) {
78227854
%latest_commit = %{$commitlist[0]};
78237855
my $latest_epoch = $latest_commit{'committer_epoch'};
7824-
%latest_date = parse_date($latest_epoch, $latest_commit{'comitter_tz'});
7825-
my $if_modified = $cgi->http('IF_MODIFIED_SINCE');
7826-
if (defined $if_modified) {
7827-
my $since;
7828-
if (eval { require HTTP::Date; 1; }) {
7829-
$since = HTTP::Date::str2time($if_modified);
7830-
} elsif (eval { require Time::ParseDate; 1; }) {
7831-
$since = Time::ParseDate::parsedate($if_modified, GMT => 1);
7832-
}
7833-
if (defined $since && $latest_epoch <= $since) {
7834-
print $cgi->header(
7835-
-type => $content_type,
7836-
-charset => 'utf-8',
7837-
-last_modified => $latest_date{'rfc2822'},
7838-
-status => '304 Not Modified');
7839-
return;
7840-
}
7841-
}
7842-
print $cgi->header(
7843-
-type => $content_type,
7844-
-charset => 'utf-8',
7845-
-last_modified => $latest_date{'rfc2822'});
7846-
} else {
7847-
print $cgi->header(
7848-
-type => $content_type,
7849-
-charset => 'utf-8');
7856+
exit_if_unmodified_since($latest_epoch);
7857+
%latest_date = parse_date($latest_epoch, $latest_commit{'comitter_tz'});
78507858
}
7859+
print $cgi->header(
7860+
-type => $content_type,
7861+
-charset => 'utf-8',
7862+
%latest_date ? (-last_modified => $latest_date{'rfc2822'}) : (),
7863+
-status => '200 OK');
78517864

78527865
# Optimization: skip generating the body if client asks only
78537866
# for Last-Modified date.

t/t9501-gitweb-standalone-http-status.sh

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ test_debug 'cat gitweb.output'
9292
test_expect_success 'snapshots: bad tree-ish id (tagged object)' '
9393
echo object > tag-object &&
9494
git add tag-object &&
95-
git commit -m "Object to be tagged" &&
95+
test_tick && git commit -m "Object to be tagged" &&
9696
git tag tagged-object `git hash-object tag-object` &&
9797
gitweb_run "p=.git;a=snapshot;h=tagged-object;sf=tgz" &&
9898
grep "400 - Object is not a tree-ish" gitweb.output
@@ -112,6 +112,64 @@ test_expect_success 'snapshots: bad object id' '
112112
'
113113
test_debug 'cat gitweb.output'
114114

115+
# ----------------------------------------------------------------------
116+
# modification times (Last-Modified and If-Modified-Since)
117+
118+
test_expect_success 'modification: feed last-modified' '
119+
gitweb_run "p=.git;a=atom;h=master" &&
120+
grep "Status: 200 OK" gitweb.headers &&
121+
grep "Last-modified: Thu, 7 Apr 2005 22:14:13 +0000" gitweb.headers
122+
'
123+
test_debug 'cat gitweb.headers'
124+
125+
test_expect_success 'modification: feed if-modified-since (modified)' '
126+
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
127+
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
128+
gitweb_run "p=.git;a=atom;h=master" &&
129+
grep "Status: 200 OK" gitweb.headers
130+
'
131+
test_debug 'cat gitweb.headers'
132+
133+
test_expect_success 'modification: feed if-modified-since (unmodified)' '
134+
export HTTP_IF_MODIFIED_SINCE="Thu, 7 Apr 2005 22:14:13 +0000" &&
135+
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
136+
gitweb_run "p=.git;a=atom;h=master" &&
137+
grep "Status: 304 Not Modified" gitweb.headers
138+
'
139+
test_debug 'cat gitweb.headers'
140+
141+
test_expect_success 'modification: snapshot last-modified' '
142+
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
143+
grep "Status: 200 OK" gitweb.headers &&
144+
grep "Last-modified: Thu, 7 Apr 2005 22:14:13 +0000" gitweb.headers
145+
'
146+
test_debug 'cat gitweb.headers'
147+
148+
test_expect_success 'modification: snapshot if-modified-since (modified)' '
149+
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
150+
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
151+
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
152+
grep "Status: 200 OK" gitweb.headers
153+
'
154+
test_debug 'cat gitweb.headers'
155+
156+
test_expect_success 'modification: snapshot if-modified-since (unmodified)' '
157+
export HTTP_IF_MODIFIED_SINCE="Thu, 7 Apr 2005 22:14:13 +0000" &&
158+
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
159+
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
160+
grep "Status: 304 Not Modified" gitweb.headers
161+
'
162+
test_debug 'cat gitweb.headers'
163+
164+
test_expect_success 'modification: tree snapshot' '
165+
ID=`git rev-parse --verify HEAD^{tree}` &&
166+
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
167+
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
168+
gitweb_run "p=.git;a=snapshot;h=$ID;sf=tgz" &&
169+
grep "Status: 200 OK" gitweb.headers &&
170+
! grep -i "last-modified" gitweb.headers
171+
'
172+
test_debug 'cat gitweb.headers'
115173

116174
# ----------------------------------------------------------------------
117175
# load checking

0 commit comments

Comments
 (0)