зеркало из https://github.com/microsoft/git.git
gitweb: Put all per-connection code in run() subroutine
All code that is run per-connection (as opposed to those parts of gitweb code that can be run once) is put into appropriate subroutines: - evaluate_uri - evaluate_gitweb_config - evaluate_git_version (here only because $GIT can be set in config) - check_loadavg (as soon as possible; $git_version must be defined) - evaluate_query_params (counterpart to evaluate_path_info) - evaluate_and_validate_params - evaluate_git_dir (requires $project) - configure_gitweb_features (@snapshot_fmts, $git_avatar) - dispatch (includes setting default $action) The difference is best viewed with '-w', '--ignore-all-space' option, because of reindent caused by putting code in subroutines. Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
c42b00c8f2
Коммит
c2394fe934
|
@ -28,34 +28,42 @@ BEGIN {
|
||||||
CGI->compile() if $ENV{'MOD_PERL'};
|
CGI->compile() if $ENV{'MOD_PERL'};
|
||||||
}
|
}
|
||||||
|
|
||||||
our $cgi = new CGI;
|
|
||||||
our $version = "++GIT_VERSION++";
|
our $version = "++GIT_VERSION++";
|
||||||
our $my_url = $cgi->url();
|
|
||||||
our $my_uri = $cgi->url(-absolute => 1);
|
|
||||||
|
|
||||||
# Base URL for relative URLs in gitweb ($logo, $favicon, ...),
|
our ($my_url, $my_uri, $base_url, $path_info, $home_link);
|
||||||
# needed and used only for URLs with nonempty PATH_INFO
|
sub evaluate_uri {
|
||||||
our $base_url = $my_url;
|
our $cgi;
|
||||||
|
|
||||||
# When the script is used as DirectoryIndex, the URL does not contain the name
|
our $my_url = $cgi->url();
|
||||||
# of the script file itself, and $cgi->url() fails to strip PATH_INFO, so we
|
our $my_uri = $cgi->url(-absolute => 1);
|
||||||
# have to do it ourselves. We make $path_info global because it's also used
|
|
||||||
# later on.
|
# Base URL for relative URLs in gitweb ($logo, $favicon, ...),
|
||||||
#
|
# needed and used only for URLs with nonempty PATH_INFO
|
||||||
# Another issue with the script being the DirectoryIndex is that the resulting
|
our $base_url = $my_url;
|
||||||
# $my_url data is not the full script URL: this is good, because we want
|
|
||||||
# generated links to keep implying the script name if it wasn't explicitly
|
# When the script is used as DirectoryIndex, the URL does not contain the name
|
||||||
# indicated in the URL we're handling, but it means that $my_url cannot be used
|
# of the script file itself, and $cgi->url() fails to strip PATH_INFO, so we
|
||||||
# as base URL.
|
# have to do it ourselves. We make $path_info global because it's also used
|
||||||
# Therefore, if we needed to strip PATH_INFO, then we know that we have
|
# later on.
|
||||||
# to build the base URL ourselves:
|
#
|
||||||
our $path_info = $ENV{"PATH_INFO"};
|
# Another issue with the script being the DirectoryIndex is that the resulting
|
||||||
if ($path_info) {
|
# $my_url data is not the full script URL: this is good, because we want
|
||||||
if ($my_url =~ s,\Q$path_info\E$,, &&
|
# generated links to keep implying the script name if it wasn't explicitly
|
||||||
$my_uri =~ s,\Q$path_info\E$,, &&
|
# indicated in the URL we're handling, but it means that $my_url cannot be used
|
||||||
defined $ENV{'SCRIPT_NAME'}) {
|
# as base URL.
|
||||||
$base_url = $cgi->url(-base => 1) . $ENV{'SCRIPT_NAME'};
|
# Therefore, if we needed to strip PATH_INFO, then we know that we have
|
||||||
|
# to build the base URL ourselves:
|
||||||
|
our $path_info = $ENV{"PATH_INFO"};
|
||||||
|
if ($path_info) {
|
||||||
|
if ($my_url =~ s,\Q$path_info\E$,, &&
|
||||||
|
$my_uri =~ s,\Q$path_info\E$,, &&
|
||||||
|
defined $ENV{'SCRIPT_NAME'}) {
|
||||||
|
$base_url = $cgi->url(-base => 1) . $ENV{'SCRIPT_NAME'};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# target of the home link on top of all pages
|
||||||
|
our $home_link = $my_uri || "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
# core git executable to use
|
# core git executable to use
|
||||||
|
@ -70,9 +78,6 @@ our $projectroot = "++GITWEB_PROJECTROOT++";
|
||||||
# the number is relative to the projectroot
|
# the number is relative to the projectroot
|
||||||
our $project_maxdepth = "++GITWEB_PROJECT_MAXDEPTH++";
|
our $project_maxdepth = "++GITWEB_PROJECT_MAXDEPTH++";
|
||||||
|
|
||||||
# target of the home link on top of all pages
|
|
||||||
our $home_link = $my_uri || "/";
|
|
||||||
|
|
||||||
# string of the home link on top of all pages
|
# string of the home link on top of all pages
|
||||||
our $home_link_str = "++GITWEB_HOME_LINK_STR++";
|
our $home_link_str = "++GITWEB_HOME_LINK_STR++";
|
||||||
|
|
||||||
|
@ -553,15 +558,18 @@ sub filter_snapshot_fmts {
|
||||||
!$known_snapshot_formats{$_}{'disabled'}} @fmts;
|
!$known_snapshot_formats{$_}{'disabled'}} @fmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
|
our ($GITWEB_CONFIG, $GITWEB_CONFIG_SYSTEM);
|
||||||
our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++";
|
sub evaluate_gitweb_config {
|
||||||
# die if there are errors parsing config file
|
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
|
||||||
if (-e $GITWEB_CONFIG) {
|
our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++";
|
||||||
do $GITWEB_CONFIG;
|
# die if there are errors parsing config file
|
||||||
die $@ if $@;
|
if (-e $GITWEB_CONFIG) {
|
||||||
} elsif (-e $GITWEB_CONFIG_SYSTEM) {
|
do $GITWEB_CONFIG;
|
||||||
do $GITWEB_CONFIG_SYSTEM;
|
die $@ if $@;
|
||||||
die $@ if $@;
|
} elsif (-e $GITWEB_CONFIG_SYSTEM) {
|
||||||
|
do $GITWEB_CONFIG_SYSTEM;
|
||||||
|
die $@ if $@;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get loadavg of system, to compare against $maxload.
|
# Get loadavg of system, to compare against $maxload.
|
||||||
|
@ -587,13 +595,16 @@ sub get_loadavg {
|
||||||
}
|
}
|
||||||
|
|
||||||
# version of the core git binary
|
# version of the core git binary
|
||||||
our $git_version = qx("$GIT" --version) =~ m/git version (.*)$/ ? $1 : "unknown";
|
our $git_version;
|
||||||
$number_of_git_cmds++;
|
sub evaluate_git_version {
|
||||||
|
our $git_version = qx("$GIT" --version) =~ m/git version (.*)$/ ? $1 : "unknown";
|
||||||
|
$number_of_git_cmds++;
|
||||||
|
}
|
||||||
|
|
||||||
$projects_list ||= $projectroot;
|
sub check_loadavg {
|
||||||
|
if (defined $maxload && get_loadavg() > $maxload) {
|
||||||
if (defined $maxload && get_loadavg() > $maxload) {
|
die_error(503, "The load average on the server is too high");
|
||||||
die_error(503, "The load average on the server is too high");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ======================================================================
|
# ======================================================================
|
||||||
|
@ -680,11 +691,15 @@ our %allowed_options = (
|
||||||
# should be single values, but opt can be an array. We should probably
|
# should be single values, but opt can be an array. We should probably
|
||||||
# build an array of parameters that can be multi-valued, but since for the time
|
# build an array of parameters that can be multi-valued, but since for the time
|
||||||
# being it's only this one, we just single it out
|
# being it's only this one, we just single it out
|
||||||
while (my ($name, $symbol) = each %cgi_param_mapping) {
|
sub evaluate_query_params {
|
||||||
if ($symbol eq 'opt') {
|
our $cgi;
|
||||||
$input_params{$name} = [ $cgi->param($symbol) ];
|
|
||||||
} else {
|
while (my ($name, $symbol) = each %cgi_param_mapping) {
|
||||||
$input_params{$name} = $cgi->param($symbol);
|
if ($symbol eq 'opt') {
|
||||||
|
$input_params{$name} = [ $cgi->param($symbol) ];
|
||||||
|
} else {
|
||||||
|
$input_params{$name} = $cgi->param($symbol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,149 +846,185 @@ sub evaluate_path_info {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
evaluate_path_info();
|
|
||||||
|
|
||||||
our $action = $input_params{'action'};
|
our ($action, $project, $file_name, $file_parent, $hash, $hash_parent, $hash_base,
|
||||||
if (defined $action) {
|
$hash_parent_base, @extra_options, $page, $searchtype, $search_use_regexp,
|
||||||
if (!validate_action($action)) {
|
$searchtext, $search_regexp);
|
||||||
die_error(400, "Invalid action parameter");
|
sub evaluate_and_validate_params {
|
||||||
|
our $action = $input_params{'action'};
|
||||||
|
if (defined $action) {
|
||||||
|
if (!validate_action($action)) {
|
||||||
|
die_error(400, "Invalid action parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# parameters which are pathnames
|
# parameters which are pathnames
|
||||||
our $project = $input_params{'project'};
|
our $project = $input_params{'project'};
|
||||||
if (defined $project) {
|
if (defined $project) {
|
||||||
if (!validate_project($project)) {
|
if (!validate_project($project)) {
|
||||||
undef $project;
|
undef $project;
|
||||||
die_error(404, "No such project");
|
die_error(404, "No such project");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
our $file_name = $input_params{'file_name'};
|
our $file_name = $input_params{'file_name'};
|
||||||
if (defined $file_name) {
|
if (defined $file_name) {
|
||||||
if (!validate_pathname($file_name)) {
|
if (!validate_pathname($file_name)) {
|
||||||
die_error(400, "Invalid file parameter");
|
die_error(400, "Invalid file parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
our $file_parent = $input_params{'file_parent'};
|
our $file_parent = $input_params{'file_parent'};
|
||||||
if (defined $file_parent) {
|
if (defined $file_parent) {
|
||||||
if (!validate_pathname($file_parent)) {
|
if (!validate_pathname($file_parent)) {
|
||||||
die_error(400, "Invalid file parent parameter");
|
die_error(400, "Invalid file parent parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# parameters which are refnames
|
# parameters which are refnames
|
||||||
our $hash = $input_params{'hash'};
|
our $hash = $input_params{'hash'};
|
||||||
if (defined $hash) {
|
if (defined $hash) {
|
||||||
if (!validate_refname($hash)) {
|
if (!validate_refname($hash)) {
|
||||||
die_error(400, "Invalid hash parameter");
|
die_error(400, "Invalid hash parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
our $hash_parent = $input_params{'hash_parent'};
|
our $hash_parent = $input_params{'hash_parent'};
|
||||||
if (defined $hash_parent) {
|
if (defined $hash_parent) {
|
||||||
if (!validate_refname($hash_parent)) {
|
if (!validate_refname($hash_parent)) {
|
||||||
die_error(400, "Invalid hash parent parameter");
|
die_error(400, "Invalid hash parent parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
our $hash_base = $input_params{'hash_base'};
|
our $hash_base = $input_params{'hash_base'};
|
||||||
if (defined $hash_base) {
|
if (defined $hash_base) {
|
||||||
if (!validate_refname($hash_base)) {
|
if (!validate_refname($hash_base)) {
|
||||||
die_error(400, "Invalid hash base parameter");
|
die_error(400, "Invalid hash base parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
our @extra_options = @{$input_params{'extra_options'}};
|
our @extra_options = @{$input_params{'extra_options'}};
|
||||||
# @extra_options is always defined, since it can only be (currently) set from
|
# @extra_options is always defined, since it can only be (currently) set from
|
||||||
# CGI, and $cgi->param() returns the empty array in array context if the param
|
# CGI, and $cgi->param() returns the empty array in array context if the param
|
||||||
# is not set
|
# is not set
|
||||||
foreach my $opt (@extra_options) {
|
foreach my $opt (@extra_options) {
|
||||||
if (not exists $allowed_options{$opt}) {
|
if (not exists $allowed_options{$opt}) {
|
||||||
die_error(400, "Invalid option parameter");
|
die_error(400, "Invalid option parameter");
|
||||||
|
}
|
||||||
|
if (not grep(/^$action$/, @{$allowed_options{$opt}})) {
|
||||||
|
die_error(400, "Invalid option parameter for this action");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (not grep(/^$action$/, @{$allowed_options{$opt}})) {
|
|
||||||
die_error(400, "Invalid option parameter for this action");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
our $hash_parent_base = $input_params{'hash_parent_base'};
|
our $hash_parent_base = $input_params{'hash_parent_base'};
|
||||||
if (defined $hash_parent_base) {
|
if (defined $hash_parent_base) {
|
||||||
if (!validate_refname($hash_parent_base)) {
|
if (!validate_refname($hash_parent_base)) {
|
||||||
die_error(400, "Invalid hash parent base parameter");
|
die_error(400, "Invalid hash parent base parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# other parameters
|
# other parameters
|
||||||
our $page = $input_params{'page'};
|
our $page = $input_params{'page'};
|
||||||
if (defined $page) {
|
if (defined $page) {
|
||||||
if ($page =~ m/[^0-9]/) {
|
if ($page =~ m/[^0-9]/) {
|
||||||
die_error(400, "Invalid page parameter");
|
die_error(400, "Invalid page parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
our $searchtype = $input_params{'searchtype'};
|
our $searchtype = $input_params{'searchtype'};
|
||||||
if (defined $searchtype) {
|
if (defined $searchtype) {
|
||||||
if ($searchtype =~ m/[^a-z]/) {
|
if ($searchtype =~ m/[^a-z]/) {
|
||||||
die_error(400, "Invalid searchtype parameter");
|
die_error(400, "Invalid searchtype parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
our $search_use_regexp = $input_params{'search_use_regexp'};
|
our $search_use_regexp = $input_params{'search_use_regexp'};
|
||||||
|
|
||||||
our $searchtext = $input_params{'searchtext'};
|
our $searchtext = $input_params{'searchtext'};
|
||||||
our $search_regexp;
|
our $search_regexp;
|
||||||
if (defined $searchtext) {
|
if (defined $searchtext) {
|
||||||
if (length($searchtext) < 2) {
|
if (length($searchtext) < 2) {
|
||||||
die_error(403, "At least two characters are required for search parameter");
|
die_error(403, "At least two characters are required for search parameter");
|
||||||
|
}
|
||||||
|
$search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext;
|
||||||
}
|
}
|
||||||
$search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# path to the current git repository
|
# path to the current git repository
|
||||||
our $git_dir;
|
our $git_dir;
|
||||||
$git_dir = "$projectroot/$project" if $project;
|
sub evaluate_git_dir {
|
||||||
|
our $git_dir = "$projectroot/$project" if $project;
|
||||||
|
}
|
||||||
|
|
||||||
# list of supported snapshot formats
|
our (@snapshot_fmts, $git_avatar);
|
||||||
our @snapshot_fmts = gitweb_get_feature('snapshot');
|
sub configure_gitweb_features {
|
||||||
@snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);
|
# list of supported snapshot formats
|
||||||
|
our @snapshot_fmts = gitweb_get_feature('snapshot');
|
||||||
|
@snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);
|
||||||
|
|
||||||
# check that the avatar feature is set to a known provider name,
|
# check that the avatar feature is set to a known provider name,
|
||||||
# and for each provider check if the dependencies are satisfied.
|
# and for each provider check if the dependencies are satisfied.
|
||||||
# if the provider name is invalid or the dependencies are not met,
|
# if the provider name is invalid or the dependencies are not met,
|
||||||
# reset $git_avatar to the empty string.
|
# reset $git_avatar to the empty string.
|
||||||
our ($git_avatar) = gitweb_get_feature('avatar');
|
our ($git_avatar) = gitweb_get_feature('avatar');
|
||||||
if ($git_avatar eq 'gravatar') {
|
if ($git_avatar eq 'gravatar') {
|
||||||
$git_avatar = '' unless (eval { require Digest::MD5; 1; });
|
$git_avatar = '' unless (eval { require Digest::MD5; 1; });
|
||||||
} elsif ($git_avatar eq 'picon') {
|
} elsif ($git_avatar eq 'picon') {
|
||||||
# no dependencies
|
# no dependencies
|
||||||
} else {
|
} else {
|
||||||
$git_avatar = '';
|
$git_avatar = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# dispatch
|
# dispatch
|
||||||
if (!defined $action) {
|
sub dispatch {
|
||||||
if (defined $hash) {
|
if (!defined $action) {
|
||||||
$action = git_get_type($hash);
|
if (defined $hash) {
|
||||||
} elsif (defined $hash_base && defined $file_name) {
|
$action = git_get_type($hash);
|
||||||
$action = git_get_type("$hash_base:$file_name");
|
} elsif (defined $hash_base && defined $file_name) {
|
||||||
} elsif (defined $project) {
|
$action = git_get_type("$hash_base:$file_name");
|
||||||
$action = 'summary';
|
} elsif (defined $project) {
|
||||||
} else {
|
$action = 'summary';
|
||||||
$action = 'project_list';
|
} else {
|
||||||
|
$action = 'project_list';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (!defined($actions{$action})) {
|
||||||
|
die_error(400, "Unknown action");
|
||||||
|
}
|
||||||
|
if ($action !~ m/^(?:opml|project_list|project_index)$/ &&
|
||||||
|
!$project) {
|
||||||
|
die_error(400, "Project needed");
|
||||||
|
}
|
||||||
|
$actions{$action}->();
|
||||||
}
|
}
|
||||||
if (!defined($actions{$action})) {
|
|
||||||
die_error(400, "Unknown action");
|
sub run {
|
||||||
|
our $t0 = [Time::HiRes::gettimeofday()]
|
||||||
|
if defined $t0;
|
||||||
|
|
||||||
|
evaluate_uri();
|
||||||
|
evaluate_gitweb_config();
|
||||||
|
evaluate_git_version();
|
||||||
|
check_loadavg();
|
||||||
|
|
||||||
|
# $projectroot and $projects_list might be set in gitweb config file
|
||||||
|
$projects_list ||= $projectroot;
|
||||||
|
|
||||||
|
evaluate_query_params();
|
||||||
|
evaluate_path_info();
|
||||||
|
evaluate_and_validate_params();
|
||||||
|
evaluate_git_dir();
|
||||||
|
|
||||||
|
configure_gitweb_features();
|
||||||
|
|
||||||
|
dispatch();
|
||||||
|
|
||||||
|
DONE_GITWEB:
|
||||||
|
1;
|
||||||
}
|
}
|
||||||
if ($action !~ m/^(?:opml|project_list|project_index)$/ &&
|
our $cgi = CGI->new();
|
||||||
!$project) {
|
run();
|
||||||
die_error(400, "Project needed");
|
|
||||||
}
|
|
||||||
$actions{$action}->();
|
|
||||||
DONE_GITWEB:
|
|
||||||
1;
|
|
||||||
|
|
||||||
## ======================================================================
|
## ======================================================================
|
||||||
## action links
|
## action links
|
||||||
|
|
Загрузка…
Ссылка в новой задаче