Skip to content

Commit b7d565e

Browse files
W. Trevor Kinggitster
authored andcommitted
gitweb: refactor If-Modified-Since handling
The current gitweb only generates Last-Modified and handles If-Modified-Since headers for the git_feed action. This patch breaks the Last-Modified and If-Modified-Since handling code out from git_feed into a new function exit_if_unmodified_since. This makes the code easy to reuse for other actions. Only gitweb actions which can easily calculate a modification time should use exit_if_unmodified_since, as the goal is to balance local processing time vs. upload bandwidth. Signed-off-by: W Trevor King <[email protected]> Acked-by: Jakub Narebski <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e1c3643 commit b7d565e

File tree

2 files changed

+55
-29
lines changed

2 files changed

+55
-29
lines changed

gitweb/gitweb.perl

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

7006+
sub exit_if_unmodified_since {
7007+
my ($latest_epoch) = @_;
7008+
our $cgi;
7009+
7010+
my $if_modified = $cgi->http('IF_MODIFIED_SINCE');
7011+
if (defined $if_modified) {
7012+
my $since;
7013+
if (eval { require HTTP::Date; 1; }) {
7014+
$since = HTTP::Date::str2time($if_modified);
7015+
} elsif (eval { require Time::ParseDate; 1; }) {
7016+
$since = Time::ParseDate::parsedate($if_modified, GMT => 1);
7017+
}
7018+
if (defined $since && $latest_epoch <= $since) {
7019+
my %latest_date = parse_date($latest_epoch);
7020+
print $cgi->header(
7021+
-last_modified => $latest_date{'rfc2822'},
7022+
-status => '304 Not Modified');
7023+
goto DONE_GITWEB;
7024+
}
7025+
}
7026+
}
7027+
70067028
sub git_snapshot {
70077029
my $format = $input_params{'snapshot_format'};
70087030
if (!@snapshot_fmts) {
@@ -7820,35 +7842,14 @@ sub git_feed {
78207842
if (defined($commitlist[0])) {
78217843
%latest_commit = %{$commitlist[0]};
78227844
my $latest_epoch = $latest_commit{'committer_epoch'};
7823-
%latest_date = parse_date($latest_epoch, $latest_commit{'comitter_tz'});
7824-
my $if_modified = $cgi->http('IF_MODIFIED_SINCE');
7825-
if (defined $if_modified) {
7826-
my $since;
7827-
if (eval { require HTTP::Date; 1; }) {
7828-
$since = HTTP::Date::str2time($if_modified);
7829-
} elsif (eval { require Time::ParseDate; 1; }) {
7830-
$since = Time::ParseDate::parsedate($if_modified, GMT => 1);
7831-
}
7832-
if (defined $since && $latest_epoch <= $since) {
7833-
print $cgi->header(
7834-
-type => $content_type,
7835-
-charset => 'utf-8',
7836-
-last_modified => $latest_date{'rfc2822'},
7837-
-status => '304 Not Modified');
7838-
return;
7839-
}
7840-
}
7841-
print $cgi->header(
7842-
-type => $content_type,
7843-
-charset => 'utf-8',
7844-
-last_modified => $latest_date{'rfc2822'},
7845-
-status => '200 OK');
7846-
} else {
7847-
print $cgi->header(
7848-
-type => $content_type,
7849-
-charset => 'utf-8',
7850-
-status => '200 OK');
7845+
exit_if_unmodified_since($latest_epoch);
7846+
%latest_date = parse_date($latest_epoch, $latest_commit{'comitter_tz'});
78517847
}
7848+
print $cgi->header(
7849+
-type => $content_type,
7850+
-charset => 'utf-8',
7851+
%latest_date ? (-last_modified => $latest_date{'rfc2822'}) : (),
7852+
-status => '200 OK');
78527853

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

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

Lines changed: 26 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,31 @@ 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'
115140

116141
# ----------------------------------------------------------------------
117142
# load checking

0 commit comments

Comments
 (0)