{"thread":{"id":"23728","subject":"[PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","startedAt":"2010-05-07T12:54:03Z","lastAt":"2010-05-18T01:06:25Z","messageCount":30,"participants":["Jakub Narebski","Eric Wong","Ævar Arnfjörð Bjarmason","Peter Vereshagin","Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"141121","messageId":"1273236845-6523-1-git-send-email-jnareb@gmail.com","threadId":"23728","inReplyTo":null,"subject":"[PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-07T12:54:03Z","receivedAt":"2010-05-07T12:54:03Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"This series requires the following patch:\n\n  [PATCH 3/5] gitweb: Use nonlocal jump instead of 'exit' in die_error\n  http://article.gmane.org/gmane.comp.version-control.git/145678\n\nwhich is present as c42b00c commit in 'pu', as part of\n'jn/gitweb-caching-prep' branch, which was merged into 'pu' at\n97153ab7.\n\n\nThis patch adds support for FastCGI directly to gitweb.perl (so it\nwould be present in gitweb.cgi); selecting between FastCGI and CGI\nis done via command-line switch (command-line option).  It uses\nCGI::Fast, which is core Perl module.\n\nIt is port of old patch by Sam Vilain from 2006 to new gitweb\nannounced in\n\n  \"Re: gitweb testing with non-apache web server\"\n  http://article.gmane.org/gmane.comp.version-control.git/24718\n\nThe preparatory patch is refactoring work, to not need to have request\nloop around large parts of code.  I think the preparatory patch makes\ngitweb code more clean.\n\n\nThe alternate solution would be to add gitweb.fcgi wrapper, like e.g.:\nin the following patch by Eric Wong\n\n  \"[PATCH 1/2] gitweb: add a simple wrapper for FCGI support\"\n  http://thread.gmane.org/gmane.comp.version-control.git/35920/focus=35921\n\nwhich was part of the \"[0/2 PATCH] FastCGI and nginx support for gitweb\"\nseries.  (Note that the patch does 'do $gitweb_cgi;' without checking for\nerrors, see the bottom of `perldoc -f do` documentation on how it should\nbe done).\n\n\nSome other references:\n* \"GitWeb in FastCGI\" by Peter Vereshagin\n  http://thread.gmane.org/gmane.comp.version-control.git/142132\n* \"FastCGI support in gitweb\" by Juan Jose Comellas\n  http://thread.gmane.org/gmane.comp.version-control.git/75704\n\nTable of contents:\n~~~~~~~~~~~~~~~~~~\n [PATCH/RFC 1/2] gitweb: Put all per-connection code in run() subroutine\n [PATCH/RFC 2/2] gitweb: Add support for FastCGI, using CGI::Fast\n\nJakub Narebski (1):\n  gitweb: Put all per-connection code in run() subroutine\n\nSam Vilain (1):\n  gitweb: Add support for FastCGI, using CGI::Fast\n\nDiffstat:\n~~~~~~~~~\n\n gitweb/gitweb.perl |  409 ++++++++++++++++++++++++++++++++--------------------\n 1 files changed, 255 insertions(+), 154 deletions(-)\n\nDiffstat -w:\n~~~~~~~~~~~~\nWhen ignoring whitespace change (reindenting)\n\n gitweb/gitweb.perl |  117 ++++++++++++++++++++++++++++++++++++++++++++++++----\n 1 files changed, 109 insertions(+), 8 deletions(-)\n\n-- \nJakub Narebski\n"},{"id":"141122","messageId":"1273236845-6523-2-git-send-email-jnareb@gmail.com","threadId":"23728","inReplyTo":"1273236845-6523-1-git-send-email-jnareb@gmail.com","subject":"[PATCH/RFC 1/2] gitweb: Put all per-connection code in run() subroutine","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-07T12:54:04Z","receivedAt":"2010-05-07T12:54:04Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"All code that is run per-connection (as opposed to those parts of gitweb\ncode that can be run once) is put into appropriate subroutines:\n - evaluate_uri\n - evaluate_gitweb_config\n - evaluate_git_version (here only because $GIT can be set in config)\n - check_loadavg (as soon as possible; $git_version must be defined)\n - evaluate_query_params (counterpart to evaluate_path_info)\n - evaluate_and_validate_params\n - evaluate_git_dir (requires $project)\n - configure_gitweb_features (@snapshot_fmts, $git_avatar)\n - dispatch (includes setting default $action)\n\nThe difference is best viewed with '-w', '--ignore-all-space' option,\nbecause of reindent caused by putting code in subroutines.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nThis patch requires the following commit from 'jn/gitweb-caching-prep' branch\nc42b00c (gitweb: Use nonlocal jump instead of 'exit' in die_error, 2010-04-24)\n\nThis is an RFC patch because selecting which parts of gitweb code are\nrun-once, and which parts are per-request (and are to be put into\nsubroutines and run from run() subroutine) is at, least in part, a bit\nsubjective.\n\n gitweb/gitweb.perl |  359 ++++++++++++++++++++++++++++++----------------------\n 1 files changed, 205 insertions(+), 154 deletions(-)\n\nWhen ignoring whitespace changes (reindenting):\n\n gitweb/gitweb.perl |   67 +++++++++++++++++++++++++++++++++++++++++++++------\n 1 files changed, 59 insertions(+), 8 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 4074300..41bf992 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -28,34 +28,42 @@ BEGIN {\n \tCGI->compile() if $ENV{'MOD_PERL'};\n }\n \n-our $cgi = new CGI;\n our $version = \"++GIT_VERSION++\";\n-our $my_url = $cgi->url();\n-our $my_uri = $cgi->url(-absolute => 1);\n \n-# Base URL for relative URLs in gitweb ($logo, $favicon, ...),\n-# needed and used only for URLs with nonempty PATH_INFO\n-our $base_url = $my_url;\n+our ($my_url, $my_uri, $base_url, $path_info, $home_link);\n+sub evaluate_uri {\n+\tour $cgi;\n \n-# When the script is used as DirectoryIndex, the URL does not contain the name\n-# of the script file itself, and $cgi->url() fails to strip PATH_INFO, so we\n-# have to do it ourselves. We make $path_info global because it's also used\n-# later on.\n-#\n-# Another issue with the script being the DirectoryIndex is that the resulting\n-# $my_url data is not the full script URL: this is good, because we want\n-# generated links to keep implying the script name if it wasn't explicitly\n-# indicated in the URL we're handling, but it means that $my_url cannot be used\n-# as base URL.\n-# Therefore, if we needed to strip PATH_INFO, then we know that we have\n-# to build the base URL ourselves:\n-our $path_info = $ENV{\"PATH_INFO\"};\n-if ($path_info) {\n-\tif ($my_url =~ s,\\Q$path_info\\E$,, &&\n-\t    $my_uri =~ s,\\Q$path_info\\E$,, &&\n-\t    defined $ENV{'SCRIPT_NAME'}) {\n-\t\t$base_url = $cgi->url(-base => 1) . $ENV{'SCRIPT_NAME'};\n+\tour $my_url = $cgi->url();\n+\tour $my_uri = $cgi->url(-absolute => 1);\n+\n+\t# Base URL for relative URLs in gitweb ($logo, $favicon, ...),\n+\t# needed and used only for URLs with nonempty PATH_INFO\n+\tour $base_url = $my_url;\n+\n+\t# When the script is used as DirectoryIndex, the URL does not contain the name\n+\t# of the script file itself, and $cgi->url() fails to strip PATH_INFO, so we\n+\t# have to do it ourselves. We make $path_info global because it's also used\n+\t# later on.\n+\t#\n+\t# Another issue with the script being the DirectoryIndex is that the resulting\n+\t# $my_url data is not the full script URL: this is good, because we want\n+\t# generated links to keep implying the script name if it wasn't explicitly\n+\t# indicated in the URL we're handling, but it means that $my_url cannot be used\n+\t# as base URL.\n+\t# Therefore, if we needed to strip PATH_INFO, then we know that we have\n+\t# to build the base URL ourselves:\n+\tour $path_info = $ENV{\"PATH_INFO\"};\n+\tif ($path_info) {\n+\t\tif ($my_url =~ s,\\Q$path_info\\E$,, &&\n+\t\t    $my_uri =~ s,\\Q$path_info\\E$,, &&\n+\t\t    defined $ENV{'SCRIPT_NAME'}) {\n+\t\t\t$base_url = $cgi->url(-base => 1) . $ENV{'SCRIPT_NAME'};\n+\t\t}\n \t}\n+\n+\t# target of the home link on top of all pages\n+\tour $home_link = $my_uri || \"/\";\n }\n \n # core git executable to use\n@@ -70,9 +78,6 @@ our $projectroot = \"++GITWEB_PROJECTROOT++\";\n # the number is relative to the projectroot\n our $project_maxdepth = \"++GITWEB_PROJECT_MAXDEPTH++\";\n \n-# target of the home link on top of all pages\n-our $home_link = $my_uri || \"/\";\n-\n # string of the home link on top of all pages\n our $home_link_str = \"++GITWEB_HOME_LINK_STR++\";\n \n@@ -566,15 +571,18 @@ sub filter_snapshot_fmts {\n \t\t!$known_snapshot_formats{$_}{'disabled'}} @fmts;\n }\n \n-our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || \"++GITWEB_CONFIG++\";\n-our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || \"++GITWEB_CONFIG_SYSTEM++\";\n-# die if there are errors parsing config file\n-if (-e $GITWEB_CONFIG) {\n-\tdo $GITWEB_CONFIG;\n-\tdie $@ if $@;\n-} elsif (-e $GITWEB_CONFIG_SYSTEM) {\n-\tdo $GITWEB_CONFIG_SYSTEM;\n-\tdie $@ if $@;\n+our ($GITWEB_CONFIG, $GITWEB_CONFIG_SYSTEM);\n+sub evaluate_gitweb_config {\n+\tour $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || \"++GITWEB_CONFIG++\";\n+\tour $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || \"++GITWEB_CONFIG_SYSTEM++\";\n+\t# die if there are errors parsing config file\n+\tif (-e $GITWEB_CONFIG) {\n+\t\tdo $GITWEB_CONFIG;\n+\t\tdie $@ if $@;\n+\t} elsif (-e $GITWEB_CONFIG_SYSTEM) {\n+\t\tdo $GITWEB_CONFIG_SYSTEM;\n+\t\tdie $@ if $@;\n+\t}\n }\n \n # Get loadavg of system, to compare against $maxload.\n@@ -600,13 +608,16 @@ sub get_loadavg {\n }\n \n # version of the core git binary\n-our $git_version = qx(\"$GIT\" --version) =~ m/git version (.*)$/ ? $1 : \"unknown\";\n-$number_of_git_cmds++;\n-\n-$projects_list ||= $projectroot;\n+our $git_version;\n+sub evaluate_git_version {\n+\tour $git_version = qx(\"$GIT\" --version) =~ m/git version (.*)$/ ? $1 : \"unknown\";\n+\t$number_of_git_cmds++;\n+}\n \n-if (defined $maxload && get_loadavg() > $maxload) {\n-\tdie_error(503, \"The load average on the server is too high\");\n+sub check_loadavg {\n+\tif (defined $maxload && get_loadavg() > $maxload) {\n+\t\tdie_error(503, \"The load average on the server is too high\");\n+\t}\n }\n \n # ======================================================================\n@@ -693,11 +704,15 @@ our %allowed_options = (\n # should be single values, but opt can be an array. We should probably\n # build an array of parameters that can be multi-valued, but since for the time\n # being it's only this one, we just single it out\n-while (my ($name, $symbol) = each %cgi_param_mapping) {\n-\tif ($symbol eq 'opt') {\n-\t\t$input_params{$name} = [ $cgi->param($symbol) ];\n-\t} else {\n-\t\t$input_params{$name} = $cgi->param($symbol);\n+sub evaluate_query_params {\n+\tour $cgi;\n+\n+\twhile (my ($name, $symbol) = each %cgi_param_mapping) {\n+\t\tif ($symbol eq 'opt') {\n+\t\t\t$input_params{$name} = [ $cgi->param($symbol) ];\n+\t\t} else {\n+\t\t\t$input_params{$name} = $cgi->param($symbol);\n+\t\t}\n \t}\n }\n \n@@ -844,149 +859,185 @@ sub evaluate_path_info {\n \t\t}\n \t}\n }\n-evaluate_path_info();\n \n-our $action = $input_params{'action'};\n-if (defined $action) {\n-\tif (!validate_action($action)) {\n-\t\tdie_error(400, \"Invalid action parameter\");\n+our ($action, $project, $file_name, $file_parent, $hash, $hash_parent, $hash_base,\n+     $hash_parent_base, @extra_options, $page, $searchtype, $search_use_regexp,\n+     $searchtext, $search_regexp);\n+sub evaluate_and_validate_params {\n+\tour $action = $input_params{'action'};\n+\tif (defined $action) {\n+\t\tif (!validate_action($action)) {\n+\t\t\tdie_error(400, \"Invalid action parameter\");\n+\t\t}\n \t}\n-}\n \n-# parameters which are pathnames\n-our $project = $input_params{'project'};\n-if (defined $project) {\n-\tif (!validate_project($project)) {\n-\t\tundef $project;\n-\t\tdie_error(404, \"No such project\");\n+\t# parameters which are pathnames\n+\tour $project = $input_params{'project'};\n+\tif (defined $project) {\n+\t\tif (!validate_project($project)) {\n+\t\t\tundef $project;\n+\t\t\tdie_error(404, \"No such project\");\n+\t\t}\n \t}\n-}\n \n-our $file_name = $input_params{'file_name'};\n-if (defined $file_name) {\n-\tif (!validate_pathname($file_name)) {\n-\t\tdie_error(400, \"Invalid file parameter\");\n+\tour $file_name = $input_params{'file_name'};\n+\tif (defined $file_name) {\n+\t\tif (!validate_pathname($file_name)) {\n+\t\t\tdie_error(400, \"Invalid file parameter\");\n+\t\t}\n \t}\n-}\n \n-our $file_parent = $input_params{'file_parent'};\n-if (defined $file_parent) {\n-\tif (!validate_pathname($file_parent)) {\n-\t\tdie_error(400, \"Invalid file parent parameter\");\n+\tour $file_parent = $input_params{'file_parent'};\n+\tif (defined $file_parent) {\n+\t\tif (!validate_pathname($file_parent)) {\n+\t\t\tdie_error(400, \"Invalid file parent parameter\");\n+\t\t}\n \t}\n-}\n \n-# parameters which are refnames\n-our $hash = $input_params{'hash'};\n-if (defined $hash) {\n-\tif (!validate_refname($hash)) {\n-\t\tdie_error(400, \"Invalid hash parameter\");\n+\t# parameters which are refnames\n+\tour $hash = $input_params{'hash'};\n+\tif (defined $hash) {\n+\t\tif (!validate_refname($hash)) {\n+\t\t\tdie_error(400, \"Invalid hash parameter\");\n+\t\t}\n \t}\n-}\n \n-our $hash_parent = $input_params{'hash_parent'};\n-if (defined $hash_parent) {\n-\tif (!validate_refname($hash_parent)) {\n-\t\tdie_error(400, \"Invalid hash parent parameter\");\n+\tour $hash_parent = $input_params{'hash_parent'};\n+\tif (defined $hash_parent) {\n+\t\tif (!validate_refname($hash_parent)) {\n+\t\t\tdie_error(400, \"Invalid hash parent parameter\");\n+\t\t}\n \t}\n-}\n \n-our $hash_base = $input_params{'hash_base'};\n-if (defined $hash_base) {\n-\tif (!validate_refname($hash_base)) {\n-\t\tdie_error(400, \"Invalid hash base parameter\");\n+\tour $hash_base = $input_params{'hash_base'};\n+\tif (defined $hash_base) {\n+\t\tif (!validate_refname($hash_base)) {\n+\t\t\tdie_error(400, \"Invalid hash base parameter\");\n+\t\t}\n \t}\n-}\n \n-our @extra_options = @{$input_params{'extra_options'}};\n-# @extra_options is always defined, since it can only be (currently) set from\n-# CGI, and $cgi->param() returns the empty array in array context if the param\n-# is not set\n-foreach my $opt (@extra_options) {\n-\tif (not exists $allowed_options{$opt}) {\n-\t\tdie_error(400, \"Invalid option parameter\");\n-\t}\n-\tif (not grep(/^$action$/, @{$allowed_options{$opt}})) {\n-\t\tdie_error(400, \"Invalid option parameter for this action\");\n+\tour @extra_options = @{$input_params{'extra_options'}};\n+\t# @extra_options is always defined, since it can only be (currently) set from\n+\t# CGI, and $cgi->param() returns the empty array in array context if the param\n+\t# is not set\n+\tforeach my $opt (@extra_options) {\n+\t\tif (not exists $allowed_options{$opt}) {\n+\t\t\tdie_error(400, \"Invalid option parameter\");\n+\t\t}\n+\t\tif (not grep(/^$action$/, @{$allowed_options{$opt}})) {\n+\t\t\tdie_error(400, \"Invalid option parameter for this action\");\n+\t\t}\n \t}\n-}\n \n-our $hash_parent_base = $input_params{'hash_parent_base'};\n-if (defined $hash_parent_base) {\n-\tif (!validate_refname($hash_parent_base)) {\n-\t\tdie_error(400, \"Invalid hash parent base parameter\");\n+\tour $hash_parent_base = $input_params{'hash_parent_base'};\n+\tif (defined $hash_parent_base) {\n+\t\tif (!validate_refname($hash_parent_base)) {\n+\t\t\tdie_error(400, \"Invalid hash parent base parameter\");\n+\t\t}\n \t}\n-}\n \n-# other parameters\n-our $page = $input_params{'page'};\n-if (defined $page) {\n-\tif ($page =~ m/[^0-9]/) {\n-\t\tdie_error(400, \"Invalid page parameter\");\n+\t# other parameters\n+\tour $page = $input_params{'page'};\n+\tif (defined $page) {\n+\t\tif ($page =~ m/[^0-9]/) {\n+\t\t\tdie_error(400, \"Invalid page parameter\");\n+\t\t}\n \t}\n-}\n \n-our $searchtype = $input_params{'searchtype'};\n-if (defined $searchtype) {\n-\tif ($searchtype =~ m/[^a-z]/) {\n-\t\tdie_error(400, \"Invalid searchtype parameter\");\n+\tour $searchtype = $input_params{'searchtype'};\n+\tif (defined $searchtype) {\n+\t\tif ($searchtype =~ m/[^a-z]/) {\n+\t\t\tdie_error(400, \"Invalid searchtype parameter\");\n+\t\t}\n \t}\n-}\n \n-our $search_use_regexp = $input_params{'search_use_regexp'};\n+\tour $search_use_regexp = $input_params{'search_use_regexp'};\n \n-our $searchtext = $input_params{'searchtext'};\n-our $search_regexp;\n-if (defined $searchtext) {\n-\tif (length($searchtext) < 2) {\n-\t\tdie_error(403, \"At least two characters are required for search parameter\");\n+\tour $searchtext = $input_params{'searchtext'};\n+\tour $search_regexp;\n+\tif (defined $searchtext) {\n+\t\tif (length($searchtext) < 2) {\n+\t\t\tdie_error(403, \"At least two characters are required for search parameter\");\n+\t\t}\n+\t\t$search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext;\n \t}\n-\t$search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext;\n }\n \n # path to the current git repository\n our $git_dir;\n-$git_dir = \"$projectroot/$project\" if $project;\n+sub evaluate_git_dir {\n+\tour $git_dir = \"$projectroot/$project\" if $project;\n+}\n \n-# list of supported snapshot formats\n-our @snapshot_fmts = gitweb_get_feature('snapshot');\n-@snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);\n+our (@snapshot_fmts, $git_avatar);\n+sub configure_gitweb_features {\n+\t# list of supported snapshot formats\n+\tour @snapshot_fmts = gitweb_get_feature('snapshot');\n+\t@snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);\n \n-# check that the avatar feature is set to a known provider name,\n-# and for each provider check if the dependencies are satisfied.\n-# if the provider name is invalid or the dependencies are not met,\n-# reset $git_avatar to the empty string.\n-our ($git_avatar) = gitweb_get_feature('avatar');\n-if ($git_avatar eq 'gravatar') {\n-\t$git_avatar = '' unless (eval { require Digest::MD5; 1; });\n-} elsif ($git_avatar eq 'picon') {\n-\t# no dependencies\n-} else {\n-\t$git_avatar = '';\n+\t# check that the avatar feature is set to a known provider name,\n+\t# and for each provider check if the dependencies are satisfied.\n+\t# if the provider name is invalid or the dependencies are not met,\n+\t# reset $git_avatar to the empty string.\n+\tour ($git_avatar) = gitweb_get_feature('avatar');\n+\tif ($git_avatar eq 'gravatar') {\n+\t\t$git_avatar = '' unless (eval { require Digest::MD5; 1; });\n+\t} elsif ($git_avatar eq 'picon') {\n+\t\t# no dependencies\n+\t} else {\n+\t\t$git_avatar = '';\n+\t}\n }\n \n # dispatch\n-if (!defined $action) {\n-\tif (defined $hash) {\n-\t\t$action = git_get_type($hash);\n-\t} elsif (defined $hash_base && defined $file_name) {\n-\t\t$action = git_get_type(\"$hash_base:$file_name\");\n-\t} elsif (defined $project) {\n-\t\t$action = 'summary';\n-\t} else {\n-\t\t$action = 'project_list';\n+sub dispatch {\n+\tif (!defined $action) {\n+\t\tif (defined $hash) {\n+\t\t\t$action = git_get_type($hash);\n+\t\t} elsif (defined $hash_base && defined $file_name) {\n+\t\t\t$action = git_get_type(\"$hash_base:$file_name\");\n+\t\t} elsif (defined $project) {\n+\t\t\t$action = 'summary';\n+\t\t} else {\n+\t\t\t$action = 'project_list';\n+\t\t}\n \t}\n+\tif (!defined($actions{$action})) {\n+\t\tdie_error(400, \"Unknown action\");\n+\t}\n+\tif ($action !~ m/^(?:opml|project_list|project_index)$/ &&\n+\t    !$project) {\n+\t\tdie_error(400, \"Project needed\");\n+\t}\n+\t$actions{$action}->();\n }\n-if (!defined($actions{$action})) {\n-\tdie_error(400, \"Unknown action\");\n-}\n-if ($action !~ m/^(?:opml|project_list|project_index)$/ &&\n-    !$project) {\n-\tdie_error(400, \"Project needed\");\n+\n+sub run {\n+\tour $t0 = [Time::HiRes::gettimeofday()]\n+\t\tif defined $t0;\n+\n+\tevaluate_uri();\n+\tevaluate_gitweb_config();\n+\tevaluate_git_version();\n+\tcheck_loadavg();\n+\n+\t# $projectroot and $projects_list might be set in gitweb config file\n+\t$projects_list ||= $projectroot;\n+\n+\tevaluate_query_params();\n+\tevaluate_path_info();\n+\tevaluate_and_validate_params();\n+\tevaluate_git_dir();\n+\n+\tconfigure_gitweb_features();\n+\n+\tdispatch();\n+\n+ DONE_GITWEB:\n+\t1;\n }\n-$actions{$action}->();\n-DONE_GITWEB:\n-1;\n+our $cgi = CGI->new();\n+run();\n \n ## ======================================================================\n ## action links\n-- \n1.7.0.1\n"},{"id":"141123","messageId":"1273236845-6523-3-git-send-email-jnareb@gmail.com","threadId":"23728","inReplyTo":"1273236845-6523-1-git-send-email-jnareb@gmail.com","subject":"[RFC/PATCH 2/2] gitweb: Add support for FastCGI, using CGI::Fast","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-07T12:54:05Z","receivedAt":"2010-05-07T12:54:05Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"From: Sam Vilain <sam.vilain@catalyst.net.nz>\n\nFormer run() subroutine got renamed to run_request().  The new run()\nsubroutine can run multiple requests at once if run as FastCGI script.\n\nTo run gitweb as FastCGI script you must specify '--fastcgi' / '-f'\ncommand line option to gitweb, otherwise it runs as an ordinary CGI\nscript.\n\n[jn: cherry picked from 56d7d436644ab296155a697552ea1345f2701620\n in http://utsl.gen.nz/gitweb/?p=gitweb which was originally based\n on v264 (2326acfa95ac86a53804ca8eeeb482c2f9265e34) by Kay Sievers;\n updated to reflect current gitweb code]\n\nTODO: update 'gitweb/README' and/or 'gitweb/INSTALL' files.\n\nSigned-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nThis is straighforward port of Sam Vilain patch to new gitweb code.\n\nIt is an RFC because while I have checked that it doesn't cause\nproblems when running without the '--fastcgi' parameter: \n* as CGI script (from mod_cgi), \n* as ModPerl::Registry script (from mod_perl), \n* as standalone script configured via gitweb_config.perl\n  (from command line),\n* as PSGI script via gitweb.psgi wrapper (from plackup,\n  using Plack::App::WrapCGI, which in turn uses CGI::Emulate::PSGI),\nI haven't actually checked that it runs correctly with *FastCGI server*\n(because I don't have one installed).\n\n gitweb/gitweb.perl |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 52 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 41bf992..a4194d7 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1012,7 +1012,7 @@ sub dispatch {\n \t$actions{$action}->();\n }\n \n-sub run {\n+sub run_request {\n \tour $t0 = [Time::HiRes::gettimeofday()]\n \t\tif defined $t0;\n \n@@ -1032,11 +1032,61 @@ sub run {\n \tconfigure_gitweb_features();\n \n \tdispatch();\n+}\n+\n+our $is_last_request = sub { 1 };\n+our ($pre_dispatch_hook, $post_dispatch_hook, $pre_listen_hook);\n+our $CGI = 'CGI';\n+our $cgi;\n+sub evaluate_argv {\n+\treturn unless (@ARGV);\n+\n+\trequire Getopt::Long;\n+\tGetopt::Long::GetOptions(\n+\t\t'fastcgi|fcgi|f' => sub {\n+\t\t\trequire CGI::Fast;\n+\t\t\tour $CGI = 'CGI::Fast';\n+\n+\t\t\tmy $request_number = 0;\n+\t\t\t# let each child service 100 requests\n+\t\t\tour $is_last_request = sub { ++$request_number > 100 };\n+\t\t},\n+\t\t'nproc|n=i' => sub {\n+\t\t\tmy ($arg, $val) = @_;\n+\t\t\treturn unless eval { require FCGI::ProcManager; 1; };\n+\t\t\tmy $proc_manager = FCGI::ProcManager->new({\n+\t\t\t\tn_processes => $val,\n+\t\t\t});\n+\t\t\tour $pre_listen_hook    = sub { $proc_manager->pm_manage()        };\n+\t\t\tour $pre_dispatch_hook  = sub { $proc_manager->pm_pre_dispatch()  };\n+\t\t\tour $post_dispatch_hook = sub { $proc_manager->pm_post_dispatch() };\n+\t\t},\n+\t);\n+}\n+\n+sub run {\n+\tevaluate_argv();\n+\n+\t$pre_listen_hook->()\n+\t\tif $pre_listen_hook;\n+\n+ REQUEST:\n+\twhile ($cgi = $CGI->new()) {\n+\t\t$pre_dispatch_hook->()\n+\t\t\tif $pre_dispatch_hook;\n+\n+\t\trun_request();\n+\n+\t\t$pre_dispatch_hook->()\n+\t\t\tif $post_dispatch_hook;\n+\n+\t\tlast REQUEST if ($is_last_request->());\n+\t}\n \n  DONE_GITWEB:\n \t1;\n }\n-our $cgi = CGI->new();\n+\n run();\n \n ## ======================================================================\n-- \n1.7.0.1\n"},{"id":"141235","messageId":"201005080959.01800.jnareb@gmail.com","threadId":"23728","inReplyTo":"1273236845-6523-3-git-send-email-jnareb@gmail.com","subject":"[RFC/PATCHv2 2/2] gitweb: Add support for FastCGI, using CGI::Fast","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-08T07:59:00Z","receivedAt":"2010-05-08T07:59:00Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"From: Sam Vilain <sam.vilain@catalyst.net.nz>\n\nFormer run() subroutine got renamed to run_request().  The new run()\nsubroutine can run multiple requests at once if run as FastCGI script.\n\nTo run gitweb as FastCGI script you must specify '--fastcgi' / '-f'\ncommand line option to gitweb, otherwise it runs as an ordinary CGI\nscript.\n\n[jn: cherry picked from 56d7d436644ab296155a697552ea1345f2701620\n in http://utsl.gen.nz/gitweb/?p=gitweb which was originally based\n on v264 (2326acfa95ac86a53804ca8eeeb482c2f9265e34) by Kay Sievers;\n updated to reflect current gitweb code]\n\nTODO: update 'gitweb/README' and/or 'gitweb/INSTALL' files.\n\nSigned-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nChanges since v1:\n* Fix $pre_dispatch_hook -> $post_dispatch_hook typo.\n\n* Leave DONE_GITWEB label in run_request() subroutine.  This way \"HTTP\n  exceptions\" thrown using die_error(), such as '404 Not Found', would\n  correctly end current request, instead of exiting FCGI script.\n\n  Note that in original patch by Sam Vilain \"HTTP exceptions\" would\n  not run $post_dispatch_hook.\n\n gitweb/gitweb.perl |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 52 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 41bf992..9a3eaf5 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1012,7 +1012,7 @@ sub dispatch {\n \t$actions{$action}->();\n }\n \n-sub run {\n+sub run_request {\n \tour $t0 = [Time::HiRes::gettimeofday()]\n \t\tif defined $t0;\n \n@@ -1036,7 +1036,57 @@ sub run {\n  DONE_GITWEB:\n \t1;\n }\n-our $cgi = CGI->new();\n+\n+our $is_last_request = sub { 1 };\n+our ($pre_dispatch_hook, $post_dispatch_hook, $pre_listen_hook);\n+our $CGI = 'CGI';\n+our $cgi;\n+sub evaluate_argv {\n+\treturn unless (@ARGV);\n+\n+\trequire Getopt::Long;\n+\tGetopt::Long::GetOptions(\n+\t\t'fastcgi|fcgi|f' => sub {\n+\t\t\trequire CGI::Fast;\n+\t\t\tour $CGI = 'CGI::Fast';\n+\n+\t\t\tmy $request_number = 0;\n+\t\t\t# let each child service 100 requests\n+\t\t\tour $is_last_request = sub { ++$request_number > 100 };\n+\t\t},\n+\t\t'nproc|n=i' => sub {\n+\t\t\tmy ($arg, $val) = @_;\n+\t\t\treturn unless eval { require FCGI::ProcManager; 1; };\n+\t\t\tmy $proc_manager = FCGI::ProcManager->new({\n+\t\t\t\tn_processes => $val,\n+\t\t\t});\n+\t\t\tour $pre_listen_hook    = sub { $proc_manager->pm_manage()        };\n+\t\t\tour $pre_dispatch_hook  = sub { $proc_manager->pm_pre_dispatch()  };\n+\t\t\tour $post_dispatch_hook = sub { $proc_manager->pm_post_dispatch() };\n+\t\t},\n+\t);\n+}\n+\n+sub run {\n+\tevaluate_argv();\n+\n+\t$pre_listen_hook->()\n+\t\tif $pre_listen_hook;\n+\n+ REQUEST:\n+\twhile ($cgi = $CGI->new()) {\n+\t\t$pre_dispatch_hook->()\n+\t\t\tif $pre_dispatch_hook;\n+\n+\t\trun_request();\n+\n+\t\t$post_dispatch_hook->()\n+\t\t\tif $post_dispatch_hook;\n+\n+\t\tlast REQUEST if ($is_last_request->());\n+\t}\n+}\n+\n run();\n \n ## ======================================================================\n-- \n1.7.0.1\n"},{"id":"141271","messageId":"201005090041.11864.jnareb@gmail.com","threadId":"23728","inReplyTo":"1273236845-6523-1-git-send-email-jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-08T22:41:06Z","receivedAt":"2010-05-08T22:41:06Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Fri, 7 May 2010, Jakub Narebski wrote:\n\n> The alternate solution would be to add gitweb.fcgi wrapper, like e.g.:\n> in the following patch by Eric Wong\n> \n>   \"[PATCH 1/2] gitweb: add a simple wrapper for FCGI support\"\n>   http://thread.gmane.org/gmane.comp.version-control.git/35920/focus=35921\n> \n> which was part of the \"[0/2 PATCH] FastCGI and nginx support for gitweb\"\n> series.  (Note that the patch does 'do $gitweb_cgi;' without checking for\n> errors, see the bottom of `perldoc -f do` documentation on how it should\n> be done).\n\nI think a better solution here would be to use CGI::Compile instead\nof 'do $gitweb_cgi;'.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"141304","messageId":"20100509093100.GA7641@dcvr.yhbt.net","threadId":"23728","inReplyTo":"201005090041.11864.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2010-05-09T09:31:00Z","receivedAt":"2010-05-09T09:31:00Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Jakub Narebski <jnareb@gmail.com> wrote:\n> On Fri, 7 May 2010, Jakub Narebski wrote:\n> \n> > The alternate solution would be to add gitweb.fcgi wrapper, like e.g.:\n> > in the following patch by Eric Wong\n> > \n> >   \"[PATCH 1/2] gitweb: add a simple wrapper for FCGI support\"\n> >   http://thread.gmane.org/gmane.comp.version-control.git/35920/focus=35921\n> > \n> > which was part of the \"[0/2 PATCH] FastCGI and nginx support for gitweb\"\n> > series.  (Note that the patch does 'do $gitweb_cgi;' without checking for\n> > errors, see the bottom of `perldoc -f do` documentation on how it should\n> > be done).\n> \n> I think a better solution here would be to use CGI::Compile instead\n> of 'do $gitweb_cgi;'.\n\nPossibly, now that CGI::Compile exists.  Can that be used with a\nstandalone Perl HTTP server?\n\nIt's 2010 now and I have long abandoned FastCGI in favor of using HTTP\nto the application backends.  In my experience, having only one\nplain-text protocol for both frontend web serving and backend\napplication RPC makes development/monitoring/testing much easier.\n\nI just use Ruby WEBrick nowadays for any instaweb instances I run to\nshare with a few cow-orkers.  I do a reasonable amount of development in\nRuby, so it's always installed and ready for me.  It would be nice if\nthere were something standalone and as ubiquitous as WEBrick in the Perl\nworld.\n\n-- \nEric Wong\n"},{"id":"141310","messageId":"AANLkTimq1d3xNota6XkpTv-bFxCIW1Jk-l6n5vcmV95R@mail.gmail.com","threadId":"23728","inReplyTo":"20100509093100.GA7641@dcvr.yhbt.net","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-09T11:48:30Z","receivedAt":"2010-05-09T11:48:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Sun, May 9, 2010 at 09:31, Eric Wong <normalperson@yhbt.net> wrote:\n> I just use Ruby WEBrick nowadays for any instaweb instances I run to\n> share with a few cow-orkers.  I do a reasonable amount of development in\n> Ruby, so it's always installed and ready for me.  It would be nice if\n> there were something standalone and as ubiquitous as WEBrick in the Perl\n> world.\n\nThere is: http://search.cpan.org/perldoc?Plack\n\nYou can run applications under everything from stand-alone webservers\nto cgi, fastcgi and mod_perl if you interface with Plack.\n"},{"id":"141311","messageId":"201005091439.26310.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100509093100.GA7641@dcvr.yhbt.net","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-09T12:39:23Z","receivedAt":"2010-05-09T12:39:23Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sun, 9 May 2010, Eric Wong wrote:\n> Jakub Narebski <jnareb@gmail.com> wrote:\n>> On Fri, 7 May 2010, Jakub Narebski wrote:\n>> \n>>> The alternate solution would be to add gitweb.fcgi wrapper, like e.g.:\n>>> in the following patch by Eric Wong\n>>> \n>>>   \"[PATCH 1/2] gitweb: add a simple wrapper for FCGI support\"\n>>>   http://thread.gmane.org/gmane.comp.version-control.git/35920/focus=35921\n>>> \n>>> which was part of the \"[0/2 PATCH] FastCGI and nginx support for gitweb\"\n>>> series.  (Note that the patch does 'do $gitweb_cgi;' without checking for\n>>> errors, see the bottom of `perldoc -f do` documentation on how it should\n>>> be done).\n>> \n>> I think a better solution here would be to use CGI::Compile instead\n>> of 'do $gitweb_cgi;'.\n> \n> Possibly, now that CGI::Compile exists.  Can that be used with a\n> standalone Perl HTTP server?\n\nYes, it can.  CGI::Compile is used for example by CGI::Emulate::PSGI,\nand you can run PSGI app on standalone Perl web server (pure Perl\nHTTP::Server::PSGI, or HTTP::Server::Simple::PSGI which in turn uses\nHTTP::Server::Simple, or Starman, or Twiggy, or Perlbal).  CGI::Compile\njust compiles given CGI script into a subroutine, which can be called\nmany times in a persistent web environment like FastCGI.\n\n> \n> It's 2010 now and I have long abandoned FastCGI in favor of using HTTP\n> to the application backends.  In my experience, having only one\n> plain-text protocol for both frontend web serving and backend\n> application RPC makes development/monitoring/testing much easier.\n\nDo you mean here standalone web server in the language of web application?\n\n>\n> I just use Ruby WEBrick nowadays for any instaweb instances I run to\n> share with a few cow-orkers.  I do a reasonable amount of development in\n> Ruby, so it's always installed and ready for me.  It would be nice if\n> there were something standalone and as ubiquitous as WEBrick in the Perl\n> world.\n\nModern Perl has PSGI/Plack (http://plackperl.org), which was inspired by\nPython's WSGI and Ruby's Rack.  The Plack reference implementation includes\n'plackup' tool (inspired by Ruby's 'rackup'), which can be used to run\na PSGI application on any supported web server (with Plackup's adapter),\nlike HTTP::Server::PSGI, HTTP::Server::Simple::PSGI, etc.\n\nPSGI/Plack goal is to be THE superglue interface between perl web \napplication frameworks and web servers.\n\n\nP.S. BTW, I use the following wrapper for gitweb.cgi (in gitweb.psgi)\n\n-- 8< --\n#!/usr/bin/env plackup\n\n# gitweb - simple web interface to track changes in git repositories\n#          PSGI wrapper (see http://plackperl.org)\n\nuse strict;\nuse warnings;\n\nuse Plack::Builder;\nuse Plack::App::WrapCGI;\nuse CGI::Emulate::PSGI 0.07; # minimum version required to work\n\nuse File::Spec;\n# __DIR__ is taken from Dir::Self __DIR__ fragment\nsub __DIR__ () {\n\tFile::Spec->rel2abs(join '', (File::Spec->splitpath(__FILE__))[0, 1]);\n}\n\nbuilder {\n\tenable 'Static',\n\t\tpath => sub { m!\\.(js|css|png)$! && s!^/gitweb/!! }, root => __DIR__.\"/\";\n\tPlack::App::WrapCGI->new(script => __DIR__.\"/gitweb.cgi\")->to_app;\n}\n\n__END__\n-- >8 --\n\nThanks to the she-bang line (I don't have plackup installed globally, \nbut it is in my $PATH) I can just run ./gitweb.psgi to start server\n(http://0:5000/) with gitweb running.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"141315","messageId":"20100509164723.GA4638@screwed.box","threadId":"23728","inReplyTo":"201005091439.26310.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-09T16:47:24Z","receivedAt":"2010-05-09T16:47:24Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"I'm face to face with Jakub who sold the world?\n2010/05/09 14:39:23 +0200 Jakub Narebski <jnareb@gmail.com> => To Eric Wong :\n\nJN> Yes, it can.  CGI::Compile is used for example by CGI::Emulate::PSGI,\nJN> and you can run PSGI app on standalone Perl web server (pure Perl\nJN> HTTP::Server::PSGI, or HTTP::Server::Simple::PSGI which in turn uses\nJN> HTTP::Server::Simple, or Starman, or Twiggy, or Perlbal).  CGI::Compile\nJN> just compiles given CGI script into a subroutine, which can be called\nJN> many times in a persistent web environment like FastCGI.\n\nThanks a lot about that!\nI took a quick look at the patches and see this:\n- FastCGI people are not always happy with CGI.pm anmd thus with CGI::Fast that\n  derives from it. They prefer CGI::Simple, e. g. for the Catalyst on fastcgi\nand other CGI.pm replacements. Despite the CGI::Fast is somehow the part of the\nperl core distribution the FCGI.pm and CGI.pm which are the required\ndependencies are not. Needless to say that the CGI.pm is not at all ( because\nit tries too much to be ) a 'killer app'. I myself is about to stop using\nCGI::Fast in FCGI::Spawn in favor of regular FCGI.pm and the CGI.pm variant\nchosen by the user. Needless to say that this can make the CGI.pm patching for\nFCGI::Spawn unecessary.\n- FCGI::ProcManager is a piece of cake in any way, but there are 'more than one\n  way to do it' (c) and it should be mentioned on a docs as a dependency since\nthere are modules on CPAN too for the same purpose but promiseful of features\nlike OO/etc.\n\nThe special thank for getting rid of exit()!\n\nI'd like to propose the Git to have the Perl interface for common functions\nthat can make it easy to create trhe bunch of tools like those made with\n(likely XS'ed) SVN:* namespace, e. g. git-svn. It makes me wonder why gitweb is\npackaged with Git but no Perl API seen: looks like its storage is simple enough\nto realize all of that in PP. Don't just disappoint me saying that git is used\nto be exec()'uted on some of the gitweb calls. ;)\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141323","messageId":"201005092018.54580.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100509164723.GA4638@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-09T18:18:52Z","receivedAt":"2010-05-09T18:18:52Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sun, 9 May 2010, Peter Vereshagin wrote:\n> I'm face to face with Jakub who sold the world?\n> 2010/05/09 14:39:23 +0200 Jakub Narebski <jnareb@gmail.com> => To Eric Wong :\n> \n> JN> Yes, it can.  CGI::Compile is used for example by CGI::Emulate::PSGI,\n> JN> and you can run PSGI app on standalone Perl web server (pure Perl\n> JN> HTTP::Server::PSGI, or HTTP::Server::Simple::PSGI which in turn uses\n> JN> HTTP::Server::Simple, or Starman, or Twiggy, or Perlbal).  CGI::Compile\n> JN> just compiles given CGI script into a subroutine, which can be called\n> JN> many times in a persistent web environment like FastCGI.\n> \n> Thanks a lot about that!\n>\n> I took a quick look at the patches and see this:\n> - FastCGI people are not always happy with CGI.pm and thus with CGI::Fast that\n>   derives from it. They prefer CGI::Simple, e. g. for the Catalyst on fastcgi\n>   and other CGI.pm replacements.\n\nCGI::Simple is not in core.  For Catalyst folks it is not a problem, \nbecause Catalyst (one of Perl MVC web frameworks) is not in core either.\n\n>   Despite the CGI::Fast is somehow the part of the perl core distribution\n>   the FCGI.pm and CGI.pm which are the required dependencies are not.\n\nActually both CGI and CGI::Fast are in Perl core distribution since \nperl 5.004 (Perl 5.4.0).  I assume that CGI::Fast simply degrades to CGI\nif FCGI module is not present.\n\nFCGI is the single non-core dependency of CGI, see \n  http://deps.cpantesters.org/?module=CGI;perl=latest\nso when I upgraded CGI (locally, using cpan client and local::lib), I also\ninstalled FCGI.\n\n>   Needless to say that the CGI.pm is not at all (because \n>   it tries too much to be) a 'killer app'. I myself is about to stop using\n>   CGI::Fast in FCGI::Spawn in favor of regular FCGI.pm and the CGI.pm variant\n>   chosen by the user. Needless to say that this can make the CGI.pm patching for\n>   FCGI::Spawn unecessary.\n\nThat's nice.\n\nWhat are required changes to gitweb to use FCGI::Spawn to run gitweb as\na FastCGI script?  Alternatively, how the wrapper script for gitweb \n(gitweb.fcgi) to be run as FastCGI should look like to use FCGI::Spawn?\n\n> - FCGI::ProcManager is a piece of cake in any way, but there are 'more than one\n>   way to do it' (c) and it should be mentioned on a docs as a dependency since\n>   there are modules on CPAN too for the same purpose but promiseful of features\n>   like OO/etc.\n\nAs PATCH 2/2 was straighforward port of Sam Vilain patch, I don't even\nknow what exactly the part containing FCGI::ProcManager does.\n\nNote however that FCGI::ProcManager is require'd on demand; you have to\nrun gitweb with '--nproc=<n>'.  Also if FCGI::ProcManager is not found,\nthen the '--nproc=<n>' command line option is a no-op (does nothing).\n\n>\n> The special thank for getting rid of exit()!\n\nYou are welcome.\n\n> \n> I'd like to propose the Git to have the Perl interface for common functions\n> that can make it easy to create the bunch of tools like those made with\n> (likely XS'ed) SVN::* namespace, e. g. git-svn.\n\n>From what I remember from watching questions and discussion here on git\nmailing list, the SVN::* Subversion bindings (from subversion-perl package)\nare serious PITA.\n\nGit.pm started (by Petr Baudis) with XS parts, but because of lack of\nPerl hacker their compilation was unportable (IIRC it required support\nfor -fPIC), and was therefore abandoned.  The difficulty of creating\nGit::XS is exacerbated by the fact that there is no libgit to make\nPerl bindings againts, although hopefully GSoC 2010 project \"Completing\nlibgit2\" would help.\n\n\nGit.pm currently wraps git commands in a *portable* way; that was the\nreason behind creating it, to e.g. not have to write the same workarounds\nfor ActiveState Perl.  The other reason was to have safe way of invoking\ngit commands.  There are some utility functions there, but not much.\n\nThe \"Gitweb caching\" GSoC 2008 project[1] by Lea Wiemann included \nimprovements to git Perl interface in the form of Git::Repo, Git::RepoRoot,\nGit::Object, Git::Commit and Git::Tag.  They are available in Lea's\nrepository[2], but were not merged into git core.\n\n[1]: http://git.wiki.kernel.org/index.php/SoC2008Projects#Gitweb_caching\n[2]: http://repo.or.cz/w/git/gitweb-caching.git\n\n>\n> It makes me wonder why gitweb is packaged with Git but no Perl API seen:\n\nIf you ask why gitweb does not use Git.pm, the reason is twofold.\n\nFirst, gitweb predates Git.pm.  It also used safe form of invokeing git\ncommands (list form of magic \"-|\" pipeline open) at least since b918298\n(gitweb: Use list for of open for running git commands..., 2006-07-30),\nand was intended to run on POSIX (like e.g. \"/\" as path separator) and\ntherefore ActiveState Perl workarounds were not needed.\n\nSecond, in a few places gitweb needs either to pipe output of git command\nto other command (to compressor in snapshot, and newly introduced to \nhighlighter when syntax highlighting is turned on), or silence errors\nredirecting STDERR to /dev/null (in 'object' action to check if object\nexists).  This is not yet supported in Git.pm.\n\nNote that using IPC::Run for piping git command output to other command\nwould be counter to gitweb's goal of minimal non-core dependencies.\n\n> looks like its storage is simple enough \n> to realize all of that in PP. Don't just disappoint me saying that git is used\n> to be exec()'uted on some of the gitweb calls. ;)\n\nGitalist[3], which started as port of gitweb to Catalyst web framework,\nuses Git::PurePerl, a pure Perl interface to Git repositories (which\nwas mostly based on Grit, a git Ruby library, which includes a partial\nnative Ruby implementation).  Or used to use; there was some discussion\nwhether to use Git::PurePerl or wrap git commands.\n\nNote that Gitalist was based on IIRC 2008 version of gitweb, so while\nit includes features that gitweb doesn't have, the opposite also might\nbe true (features in gitweb that Gitalist doesn't have).\n\nAlso performance matters for gitweb.\n\n[3]: https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools#Gitalist\n-- \nJakub Narebski\nPoland\n"},{"id":"141351","messageId":"20100510071340.GA3382@screwed.box","threadId":"23728","inReplyTo":"201005092018.54580.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-10T07:13:40Z","receivedAt":"2010-05-10T07:13:40Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"Hey Jakub don't wanna cause you pain but the big boys feel no sorrow!\n2010/05/09 20:18:52 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n\nGreat! I was just about to ask on caching, etc. What a complex history on all\nof that, will be on those tracks after some of my whiles. ;-)\n\nJN> What are required changes to gitweb to use FCGI::Spawn to run gitweb as\nJN> a FastCGI script?  Alternatively, how the wrapper script for gitweb \nJN> (gitweb.fcgi) to be run as FastCGI should look like to use FCGI::Spawn?\n\n\nBy far it's only an exit() of the what I use (1.6.0.6):\n\n--- /usr/local/share/examples/git/gitweb/gitweb.cgi     2010-02-25 13:49:30.068287112 +0300\n+++ www/gitweb.cgi      2010-03-13 14:28:45.326244103 +0300\n@@ -933,7 +933,7 @@\n        die_error(400, \"Project needed\");\n }\n $actions{$action}->();\n-exit;\n+#      exit;\n \n ## ======================================================================\n ## action links\n@@ -3371,7 +3371,7 @@\n </div>\n EOF\n        git_footer_html();\n-       exit;\n+#              exit;\n }\n \n ## ----------------------------------------------------------------------\n\n\nbut it's probably even not necessary with -e parameter:\nhttp://search.cpan.org/~veresc/FCGI-Spawn-0.16.1/fcgi_spawn#Command_line_options\nwhich is definitely required for bugzilla, the worst boy in that sandbox. The\nparameter does just this: \n===\nmy $cref = sub {\n  if( 'FCGI::ProcManager' eq scalar caller ){\n    CORE::exit @_;\n  } else {\n    no warnings;\n    last CALLED_OUT;\n  }\n};\n*CORE::GLOBAL::exit = $cref;\n*CORE::GLOBAL::exit;\n===\nso this requires configuration \n( $PREFIX/etc/fcgi_spawn/preload_nonprepared_01.pl, in my case ) for fcgi_spawn\ndaemon like this:\n===\n  $spawn->{ callout } =  sub{ do shift;\n  CALLED_OUT: \n  };\n===\nall of that is not needed without exit() in gitweb, now.\n\nI didn't mean FCGI::PM is a problem by itself. The standalone gitweb daemon is\ngreat thing for those who need such a choice. FCGI::Spawn is just for some\ndifferent task: to put several ( wish to say: any CGI app ) applications inside\nthe same fork()ed processes. It should be just obviously documented for a user\nas a dependency for implementation of a gitweb fastcgi daemon. Although I'm not\nsure if the FCGI::PM package should be a dependency for git package for any OS:\nfor those modules use()d in eval() my guess is: particular user's choice to be\noffered.\n\nSo FCGI::PM usage I think makes a flavor taste for any daemon and thus should\nbe explicit. YMMV for those uninvolved in daemonizing, of course. ;-)\n\nIs it probable that gitweb doesn't take any POSTs requests? The main trick\naround FCGI::Spawn is the need to patch the CGI.pm but if that is the case...\nI'd try to redefine the STDIN to /dev/null or zero so FCGI.Spawn.CGI.pm.patch\nshould be unnecessary for one who only wants to run the gitweb in FCGI::Spawn.\nIf switch to FCGI.pm will be way complicated to me.\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141405","messageId":"201005101729.07334.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100510071340.GA3382@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-10T15:29:03Z","receivedAt":"2010-05-10T15:29:03Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Mon, 10 May 2010, Peter Vereshagin wrote:\n> 2010/05/09 20:18:52 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n> \n> Great! I was just about to ask on caching, etc. What a complex history on all\n> of that, will be on those tracks after some of my whiles. ;-)\n\nYou can find current state of my take on gitweb output caching (based\non / inspired by work by John 'Warthog9' Hawley) in my repository on\nrepo.or.cz, in the 'gitweb/cache-kernel-pu' branch:\n\n  http://repo.or.cz/w/git/jnareb-git.git  gitweb/cache-kernel-pu\n \nYou can find progress reports (and what current show-stoppers are) in\ngit mailing list archives.\n\n\nNote that http://repo.or.cz does its own gitweb caching, IIRC by\ncaching Perl data, and only for 'projects_list' page (the most costly\none).\n\nThere was also \"Gitweb caching\" projects in GSoC 2008 by Lea Wiemann,\nwhich IIUC cached output of git commands. This project was, I think,\ncompleted but didn't get merged into git.\n\n> JN> What are required changes to gitweb to use FCGI::Spawn to run gitweb as\n> JN> a FastCGI script?  Alternatively, how the wrapper script for gitweb \n> JN> (gitweb.fcgi) to be run as FastCGI should look like to use FCGI::Spawn?\n> \n> By far it's only an exit() of the what I use (1.6.0.6):\n\nWhy so old git?  Current version is git version 1.7.1\n\n> \n> --- /usr/local/share/examples/git/gitweb/gitweb.cgi     2010-02-25 13:49:30.068287112 +0300\n> +++ www/gitweb.cgi                                      2010-03-13 14:28:45.326244103 +0300\n\nHrmph.  Why not use \"git diff --no-index <file1> <file2>\" here?\n\nThe Perl-aware equivalent of '-p' option of GNU diff, i.e. showing in\nwhich function we are in hunk headers, would help here.\n\n> @@ -933,7 +933,7 @@\n>         die_error(400, \"Project needed\");\n>  }\n>  $actions{$action}->();\n> -exit;\n> +#      exit;\n\nThis 'exit' was here just in case there were some forgotten code below\nthis line outside subroutines (that should not be run).  It can be\nsafely removed.\n\n>  \n>  ## ======================================================================\n>  ## action links\n> @@ -3371,7 +3371,7 @@ sub die_error {\n\nI have added my guess of in which subroutine this code is above.\n\n>  </div>\n>  EOF\n>         git_footer_html();\n> -       exit;\n> +#              exit;\n>  }\n\nErr... and gitweb works correctly with this change?  This 'exit' was\nrequired for die_error to function like 'die' in that it finishes\nserving request, and should not continue subroutine it was called\nfrom.\n\nI have changed this 'exit' to non-local goto to toplevel.  It could be\ndone instead by redefining 'exit' subroutine, like shown below, but I\nfeel that would be hacky if you can change gitweb code (it is not\nblack box you should not touch).\n\n>  \n>  ## ----------------------------------------------------------------------\n> \n> but it's probably even not necessary with -e parameter:\n> http://search.cpan.org/~veresc/FCGI-Spawn-0.16.1/fcgi_spawn#Command_line_options\n> which is definitely required for bugzilla, the worst boy in that sandbox. The\n> parameter does just this: \n> ===\n> my $cref = sub {\n>   if ('FCGI::ProcManager' eq scalar caller) {\n>     CORE::exit @_;\n>   } else {\n>     no warnings;\n>     last CALLED_OUT;\n>   }\n> };\n> *CORE::GLOBAL::exit = $cref;\n> *CORE::GLOBAL::exit;\n> ===\n\nThis is quite nice idea to replace 'exit' by subroutine that does\nnon-local jump to outside of application, at the end of request loop.\nSuch \"monkey patching\" is the only solution if you can't or shouldn't\nmodify application code (like FCGI::Spawn being generic solution).\n\n> so this requires configuration \n> ( $PREFIX/etc/fcgi_spawn/preload_nonprepared_01.pl, in my case ) for fcgi_spawn\n> daemon like this:\n> ===\n>   $spawn->{ callout } =  sub{ do shift;\n>   CALLED_OUT: \n>   };\n> ===\n\nHere\n\n   $spawn->{'callout'} = sub {\n   \tmy $cgi_app = shift;\n   \tdo $cgi_app;\n\n        # this is needed for sane error handling\n        die \"Couldn't parse $cgi_app: $@\" if $@;\n\n   CALLED_OUT: \n   };\n\ncould be simply replaced by\n\n  use CGI::Compile;\n\n  # ...\n\n  $spawn->{'callout'} = \\&{CGI::Compile->compile}\n\nor something like that.  See CGI::Compile manpage and CGI::Compile source:\nhttp://cpansearch.perl.org/src/MIYAGAWA/CGI-Compile-0.11/lib/CGI/Compile.pm\n\n>\n> All of that is not needed without exit() in gitweb, now.\n\nBTW I wonder what are the consequences for performance on replacing\n'exit' by non-local jump.  It can degrade performance a bit for gitweb\nrun as pure CGI (mod_cgi / mod_cgid), but should improve performance\nfor mod_perl, at least if there are more connections... unless\nModPerl::Registry does similar trick with exit().\n\n> \n> I didn't mean FCGI::PM is a problem by itself. The standalone gitweb daemon is\n> great thing for those who need such a choice. FCGI::Spawn is just for some\n> different task: to put several ( wish to say: any CGI app ) applications inside\n> the same fork()ed processes. It should be just obviously documented for a user\n> as a dependency for implementation of a gitweb fastcgi daemon. Although I'm not\n> sure if the FCGI::PM package should be a dependency for git package for any OS:\n> for those modules use()d in eval() my guess is: particular user's choice to be\n> offered.\n> \n> So FCGI::PM usage I think makes a flavor taste for any daemon and thus should\n> be explicit. YMMV for those uninvolved in daemonizing, of course. ;-)\n\nHmmm... is FCGI::Spawn really needed, or can it be replaced by simple\nPSGI wrapper using either Plack::App::CGIBin, \n\n  use Plack::App::CGIBin;\n  use Plack::Builder;\n\n  my $app = Plack::App::CGIBin->new(root => \"/path/to/cgi-bin\")->to_app;\n  builder {\n        mount \"/cgi-bin\" => $app;\n  };\n\nor Plack::App::WrapCGI plus Plack::App::URLMap, the last indirectly\nvia Plack::Builder DSL:\n\n  use Plack::Builder;\n  use Plack::App::WrapCGI;\n\n  builder {\n        mount \"/foo\" =>\n                Plack::App::WrapCGI->new(script => \"foo.cgi\")->to_app;\n        mount \"/bar\" =>\n                Plack::App::WrapCGI->new(script => \"bar.cgi\")->to_app;\n  };\n\n> \n> Is it probable that gitweb doesn't take any POSTs requests? The main trick\n> around FCGI::Spawn is the need to patch the CGI.pm but if that is the case...\n> I'd try to redefine the STDIN to /dev/null or zero so FCGI.Spawn.CGI.pm.patch\n> should be unnecessary for one who only wants to run the gitweb in FCGI::Spawn.\n> If switch to FCGI.pm will be way complicated to me.\n\nErrr... excuse me, what you wanted to say in the paragraph above?\n\nGitweb doesn't use no POST requests: it is read-only web repository\nbrowser... well, except for the 'show_ctags' action.\n-- \nJakub Narebski\nPoland\n"},{"id":"141455","messageId":"20100511062415.GA5220@screwed.box","threadId":"23728","inReplyTo":"201005101729.07334.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-11T06:24:15Z","receivedAt":"2010-05-11T06:24:15Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"I know St. Peter won't call your name, Jakub!\n2010/05/10 17:29:03 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nJN> On Mon, 10 May 2010, Peter Vereshagin wrote:\nJN> > 2010/05/09 20:18:52 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nJN> > \nJN> > Great! I was just about to ask on caching, etc. What a complex history on all\nJN> > of that, will be on those tracks after some of my whiles. ;-)\nJN> \nJN> You can find current state of my take on gitweb output caching (based\nJN> on / inspired by work by John 'Warthog9' Hawley) in my repository on\nJN> repo.or.cz, in the 'gitweb/cache-kernel-pu' branch:\nJN> \nJN>   http://repo.or.cz/w/git/jnareb-git.git  gitweb/cache-kernel-pu\nJN>  \nJN> You can find progress reports (and what current show-stoppers are) in\nJN> git mailing list archives.\n\nI will.\n\nJN> Note that http://repo.or.cz does its own gitweb caching, IIRC by\nJN> caching Perl data, and only for 'projects_list' page (the most costly\nJN> one).\nJN> \nJN> There was also \"Gitweb caching\" projects in GSoC 2008 by Lea Wiemann,\nJN> which IIUC cached output of git commands. This project was, I think,\nJN> completed but didn't get merged into git.\nJN> \nJN> > JN> What are required changes to gitweb to use FCGI::Spawn to run gitweb as\nJN> > JN> a FastCGI script?  Alternatively, how the wrapper script for gitweb \nJN> > JN> (gitweb.fcgi) to be run as FastCGI should look like to use FCGI::Spawn?\nJN> > \nJN> > By far it's only an exit() of the what I use (1.6.0.6):\nJN> \nJN> Why so old git?  Current version is git version 1.7.1\n\nUpdate or die sounds too consumerical to me ;-)\n\nJN> \nJN> > \nJN> > --- /usr/local/share/examples/git/gitweb/gitweb.cgi     2010-02-25 13:49:30.068287112 +0300\nJN> > +++ www/gitweb.cgi                                      2010-03-13 14:28:45.326244103 +0300\nJN> \nJN> Hrmph.  Why not use \"git diff --no-index <file1> <file2>\" here?\nJN> \nJN> The Perl-aware equivalent of '-p' option of GNU diff, i.e. showing in\nJN> which function we are in hunk headers, would help here.\n\nIt's obvious that I just made a more simple thing about this patch: grep exit\ngitweb.cgi. Meat and potatoes ;-)\n\nJN> \nJN> > @@ -933,7 +933,7 @@\nJN> >         die_error(400, \"Project needed\");\nJN> >  }\nJN> >  $actions{$action}->();\nJN> > -exit;\nJN> > +#      exit;\nJN> \nJN> This 'exit' was here just in case there were some forgotten code below\nJN> this line outside subroutines (that should not be run).  It can be\nJN> safely removed.\nJN> \nJN> >  \nJN> >  ## ======================================================================\nJN> >  ## action links\nJN> > @@ -3371,7 +3371,7 @@ sub die_error {\nJN> \nJN> I have added my guess of in which subroutine this code is above.\n\nRight.\n\nJN> \nJN> >  </div>\nJN> >  EOF\nJN> >         git_footer_html();\nJN> > -       exit;\nJN> > +#              exit;\nJN> >  }\nJN> \nJN> Err... and gitweb works correctly with this change?  This 'exit' was\nJN> required for die_error to function like 'die' in that it finishes\nJN> serving request, and should not continue subroutine it was called\nJN> from.\n\nDoes at least on 'non-existent diff' page:\n\nhttp://gitweb.vereshagin.org/fcgiproxy/commitdiff/abcd\n\nJN> I have changed this 'exit' to non-local goto to toplevel.  It could be\nJN> done instead by redefining 'exit' subroutine, like shown below, but I\nJN> feel that would be hacky if you can change gitweb code (it is not\nJN> black box you should not touch).\n\nRight, one shouldn't ever redefine perl built-in functions. I did only because\nof no other way to 'get things working'\n\nJN> \nJN> >  \nJN> >  ## ----------------------------------------------------------------------\nJN> > \nJN> > but it's probably even not necessary with -e parameter:\nJN> > http://search.cpan.org/~veresc/FCGI-Spawn-0.16.1/fcgi_spawn#Command_line_options\nJN> > which is definitely required for bugzilla, the worst boy in that sandbox. The\nJN> > parameter does just this: \nJN> > ===\nJN> > my $cref = sub {\nJN> >   if ('FCGI::ProcManager' eq scalar caller) {\nJN> >     CORE::exit @_;\nJN> >   } else {\nJN> >     no warnings;\nJN> >     last CALLED_OUT;\nJN> >   }\nJN> > };\nJN> > *CORE::GLOBAL::exit = $cref;\nJN> > *CORE::GLOBAL::exit;\nJN> > ===\nJN> \nJN> This is quite nice idea to replace 'exit' by subroutine that does\nJN> non-local jump to outside of application, at the end of request loop.\nJN> Such \"monkey patching\" is the only solution if you can't or shouldn't\nJN> modify application code (like FCGI::Spawn being generic solution).\n\nYes, this is quick-n-dirty to apply for those monkeys who are just busy to care\nabout re-writing CGI apps.\n\nJN> > so this requires configuration \nJN> > ( $PREFIX/etc/fcgi_spawn/preload_nonprepared_01.pl, in my case ) for fcgi_spawn\nJN> > daemon like this:\nJN> > ===\nJN> >   $spawn->{ callout } =  sub{ do shift;\nJN> >   CALLED_OUT: \nJN> >   };\nJN> > ===\nJN> \nJN> Here\nJN> \nJN>    $spawn->{'callout'} = sub {\nJN>    \tmy $cgi_app = shift;\nJN>    \tdo $cgi_app;\nJN> \nJN>         # this is needed for sane error handling\nJN>         die \"Couldn't parse $cgi_app: $@\" if $@;\nJN> \nJN>    CALLED_OUT: \nJN>    };\n\nin a forked application, die() is a PITA on any reasonable load. It makes the\nCoW-shared memory to be copied into separate area and being marked as unusable\nbefore the process is dead. This is the only case I saw load averages on the\nservers valued as crazy ~700.\nSo just exit there, not die. By far, die can not be redefined the same way as I\npropose for exit in FCGI::Spawn.\n\nJN> \nJN> could be simply replaced by\nJN> \nJN>   use CGI::Compile;\nJN> \nJN>   # ...\nJN> \nJN>   $spawn->{'callout'} = \\&{CGI::Compile->compile}\nJN> \nJN> or something like that.  See CGI::Compile manpage and CGI::Compile source:\nJN> http://cpansearch.perl.org/src/MIYAGAWA/CGI-Compile-0.11/lib/CGI/Compile.pm\nJN> \nJN> >\nJN> > All of that is not needed without exit() in gitweb, now.\nJN> \nJN> BTW I wonder what are the consequences for performance on replacing\nJN> 'exit' by non-local jump.  It can degrade performance a bit for gitweb\nJN> run as pure CGI (mod_cgi / mod_cgid), but should improve performance\nJN> for mod_perl, at least if there are more connections... unless\nJN> ModPerl::Registry does similar trick with exit().\n\nI knew out about such a trick somewhere in modperlbook. For mod_perl, this\nshould be done in startup.pl\n\nJN> > I didn't mean FCGI::PM is a problem by itself. The standalone gitweb daemon is\nJN> > great thing for those who need such a choice. FCGI::Spawn is just for some\nJN> > different task: to put several ( wish to say: any CGI app ) applications inside\nJN> > the same fork()ed processes. It should be just obviously documented for a user\nJN> > as a dependency for implementation of a gitweb fastcgi daemon. Although I'm not\nJN> > sure if the FCGI::PM package should be a dependency for git package for any OS:\nJN> > for those modules use()d in eval() my guess is: particular user's choice to be\nJN> > offered.\nJN> > \nJN> > So FCGI::PM usage I think makes a flavor taste for any daemon and thus should\nJN> > be explicit. YMMV for those uninvolved in daemonizing, of course. ;-)\nJN> \nJN> Hmmm... is FCGI::Spawn really needed, or can it be replaced by simple\nJN> PSGI wrapper using either Plack::App::CGIBin, \nJN> \nJN>   use Plack::App::CGIBin;\nJN>   use Plack::Builder;\nJN> \nJN>   my $app = Plack::App::CGIBin->new(root => \"/path/to/cgi-bin\")->to_app;\nJN>   builder {\nJN>         mount \"/cgi-bin\" => $app;\nJN>   };\n\nYou use the predefined paths here on initialization. FCGI::Spawn knows about\nthe CGI application's path at the right moment it takes the request.\n\nJN> or Plack::App::WrapCGI plus Plack::App::URLMap, the last indirectly\nJN> via Plack::Builder DSL:\nJN> \nJN>   use Plack::Builder;\nJN>   use Plack::App::WrapCGI;\nJN> \nJN>   builder {\nJN>         mount \"/foo\" =>\nJN>                 Plack::App::WrapCGI->new(script => \"foo.cgi\")->to_app;\nJN>         mount \"/bar\" =>\nJN>                 Plack::App::WrapCGI->new(script => \"bar.cgi\")->to_app;\nJN>   };\n\nSounds no more simple than simplicity of php deployment. That is whom the\nFCGI::Spawn combats for.\nProbably, 'the directories and scripts cache' should help to defer such an\ninitialization? like it is done about the DBI handles in Apache::DBI. You can\nperform that init on a first request per fork, and keep it built for all of the\nprocess lifetime for the requests coming next.\n\nJN> > Is it probable that gitweb doesn't take any POSTs requests? The main trick\nJN> > around FCGI::Spawn is the need to patch the CGI.pm but if that is the case...\nJN> > I'd try to redefine the STDIN to /dev/null or zero so FCGI.Spawn.CGI.pm.patch\nJN> > should be unnecessary for one who only wants to run the gitweb in FCGI::Spawn.\nJN> > If switch to FCGI.pm will be way complicated to me.\nJN> \nJN> Errr... excuse me, what you wanted to say in the paragraph above?\n\nCGI::Fast use CGI.pm for POST input. With FCGI.pm I'll use CGI.pm for POST\ninput only on an application's demand in FCGI::Spawn.\nIn case of gitweb.cgi POST is not used. This makes the CGI.pm patch supplied\nwith FCGI::Spawn not needed.\nBut web user may send the POST request and FCGI::Spawn should feed a dummy\ninput for CGI.pm in the CGI script waiting for input from STDIN when request\nmethod is POST.\nNot sure if this feature is needed at all for FCGI::Spawn though.\n\nJN> Gitweb doesn't use no POST requests: it is read-only web repository\nJN> browser... well, except for the 'show_ctags' action.\n\nTag cloud? Is there an example of usable tag cloud on any public gitweb out\nthere?\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141464","messageId":"20100511083508.GM1951@machine.or.cz","threadId":"23728","inReplyTo":"20100511062415.GA5220@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2010-05-11T08:35:08Z","receivedAt":"2010-05-11T08:35:08Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Tue, May 11, 2010 at 10:24:15AM +0400, Peter Vereshagin wrote:\n> JN> Gitweb doesn't use no POST requests: it is read-only web repository\n> JN> browser... well, except for the 'show_ctags' action.\n> \n> Tag cloud? Is there an example of usable tag cloud on any public gitweb out\n> there?\n\nSee http://repo.or.cz/ for an example.\n\nI don't think it's essential to support ctags under all configurations,\nif doing so is too troublesome. But I expect our current GSoC to want\nto add some more POST forms too.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nWhen I feel like exercising, I just lie down until the feeling\ngoes away.  -- xed_over\n"},{"id":"141469","messageId":"201005111258.53388.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100511062415.GA5220@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-11T10:58:50Z","receivedAt":"2010-05-11T10:58:50Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Tue, 11 May 2010, Peter Vereshagin <peter@vereshagin.org> wrote:\n> 2010/05/10 17:29:03 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n> > On Mon, 10 May 2010, Peter Vereshagin wrote:\n\n> > >  ## ======================================================================\n> > >  ## action links\n> > > @@ -3371,7 +3371,7 @@ sub die_error {\n> > \n> > I have added my guess of in which subroutine this code is above.\n\n[...]\n> > >         git_footer_html();\n> > > -       exit;\n> > > +#              exit;\n> > >  }\n> > \n> > Err... and gitweb works correctly with this change?  This 'exit' was\n> > required for die_error to function like 'die' in that it finishes\n> > serving request, and should not continue subroutine it was called\n> > from.\n> \n> Does at least on 'non-existent diff' page:\n> \n> http://gitweb.vereshagin.org/fcgiproxy/commitdiff/abcd\n\nHmmm... strange that it works.\n \n> > I have changed this 'exit' to non-local goto to toplevel.  It could be\n> > done instead by redefining 'exit' subroutine, like shown below, but I\n> > feel that would be hacky if you can change gitweb code (it is not\n> > black box you should not touch).\n> \n> Right, one shouldn't ever redefine perl built-in functions. I did only because\n> of no other way to 'get things working'\n\nWhy not?  For example CGI::Carp redefines 'die' to log errors.\n\n  BEGIN { \n    require Carp; \n    *CORE::GLOBAL::die = \\&CGI::Carp::die;\n  }\n\nSub::Uplevel and Test::Exception redefines 'caller' (perhaps locally).\nCGI::Compile redefines 'exit':\n\n  our $USE_REAL_EXIT;\n  BEGIN {\n      $USE_REAL_EXIT = 1;\n      *CORE::GLOBAL::exit = sub (;$) {\n          my $exit_code = shift;\n\n          CORE::exit(defined $exit_code ? $exit_code : 0) if $USE_REAL_EXIT;\n\n          die [ \"EXIT\\n\", $exit_code || 0 ]\n      };\n  }\n\n\n> > This is quite nice idea to replace 'exit' by subroutine that does\n> > non-local jump to outside of application, at the end of request loop.\n> > Such \"monkey patching\" is the only solution if you can't or shouldn't\n> > modify application code (like FCGI::Spawn being generic solution).\n> \n> Yes, this is quick-n-dirty to apply for those monkeys who are just busy to care\n> about re-writing CGI apps.\n\nErrr... \"monkey patching\" is the name of technique of extending and\nmodifying runtime code in dynamic languages, see\n\n  http://en.wikipedia.org/wiki/Monkey_patch\n \nAlthough I am not entirely sure if I correctly applied this name to\ndescribed (used) techique.\n\n> > Here\n> > \n> >    $spawn->{'callout'} = sub {\n> >    \tmy $cgi_app = shift;\n> >    \tdo $cgi_app;\n> > \n> >     # this is needed for sane error handling\n> >     die \"Couldn't parse $cgi_app: $@\" if $@;\n> > \n> >    CALLED_OUT: \n> >    };\n> \n> In a forked application, die() is a PITA on any reasonable load. It makes the\n> CoW-shared memory to be copied into separate area and being marked as unusable\n> before the process is dead. This is the only case I saw load averages on the\n> servers valued as crazy ~700.\n>\n> So just exit there, not die. \n\nWell, it might be 'exit' not 'die', but you really, really need to check\nif there were problems parsing file.  Otheriwse you can get error\nmessages somewhere further on that doesn't absolutely make sense.  \n\nI know this from painful experience of trying to find bug in a\ntest... when the error was in parsing file in 'do $file;'.\n\n> By far, die can not be redefined the same way as I propose for exit in\n> FCGI::Spawn.\n\nIt can't?  CGI::Carp redefines 'die'.\n \n> > > [...] FCGI::Spawn is just for some different task: to put several\n> > > (wish to say: any CGI app) applications inside the same fork()ed\n> > > processes. [...]\n> > \n> > Hmmm... is FCGI::Spawn really needed, or can it be replaced by simple\n> > PSGI wrapper using either Plack::App::CGIBin, \n> > \n> >   use Plack::App::CGIBin;\n> >   use Plack::Builder;\n> > \n> >   my $app = Plack::App::CGIBin->new(root => \"/path/to/cgi-bin\")->to_app;\n> >   builder {\n> >         mount \"/cgi-bin\" => $app;\n> >   };\n> \n> You use the predefined paths here on initialization. FCGI::Spawn knows about\n> the CGI application's path at the right moment it takes the request.\n\nNo, you need to provide only *root*, i.e. where Perl CGI applications\nare, so that e.g. accessing 'http://0:5000/cgi-bin/foo/bar.cgi' would\nrun PSGI-ized (via CGI::Emulate::PSGI) '/path/to/cgi-bin/foo/bar.cgi'\napplication.\n\nYou don't need to mount it at \"/cgi-bin\", you can just\n\n  builder {\n        $app;\n  }\n\nor even without it ($app should be the last expression).\n\n\nOr did you mean here something like mod_rewrite, or\nPlack::Middleware::Rewrite?\n\n[...]  \n> > Gitweb doesn't use no POST requests: it is read-only web repository\n> > browser... well, except for the 'show_ctags' action.\n> \n> Tag cloud? Is there an example of usable tag cloud on any public gitweb out\n> there?\n\nTag cloud are optional feature in stock gitweb, named 'ctag' in %feature\nhash.  It is disabled by default.  If I understand correctly POST is\nused here to populate which tags one wants to use... but perhaps GET\nrequest would be enough here (at the cost of less readable URL).\n\nSee http://repo.or.cz for example usage of this feature.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"141471","messageId":"20100511120924.GC5220@screwed.box","threadId":"23728","inReplyTo":"201005111258.53388.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-11T12:09:24Z","receivedAt":"2010-05-11T12:09:24Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"I know St. Peter won't call your name, Jakub!\n2010/05/11 12:58:50 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nJN> > > I have added my guess of in which subroutine this code is above.\nJN> \nJN> [...]\nJN> > > >         git_footer_html();\nJN> > > > -       exit;\nJN> > > > +#              exit;\nJN> > > >  }\nJN> > > \nJN> > > Err... and gitweb works correctly with this change?  This 'exit' was\nJN> > > required for die_error to function like 'die' in that it finishes\nJN> > > serving request, and should not continue subroutine it was called\nJN> > > from.\nJN> > \nJN> > Does at least on 'non-existent diff' page:\nJN> > \nJN> > http://gitweb.vereshagin.org/fcgiproxy/commitdiff/abcd\nJN> \nJN> Hmmm... strange that it works.\n\njust break it (c) ;-)\nThere are many other cases for this function to use, I just don't care. It's\nall yet readonly after all ;-)\n\nJN>  \nJN> > > I have changed this 'exit' to non-local goto to toplevel.  It could be\nJN> > > done instead by redefining 'exit' subroutine, like shown below, but I\nJN> > > feel that would be hacky if you can change gitweb code (it is not\nJN> > > black box you should not touch).\nJN> > \nJN> > Right, one shouldn't ever redefine perl built-in functions. I did only because\nJN> > of no other way to 'get things working'\nJN> \nJN> Why not?  For example CGI::Carp redefines 'die' to log errors.\n\nOuch, sorry, I meant last() or something like that.\nI just believe any non-system application development for end-user being a\nnon-developer doesn't need to redefine perl built-in functions. Just a sane\nbone tone for common functioning in a sandbox.\nFor example, I remember the Linux kernel  ( or Glibc? ) was criticised much of\nbeing possible to override the str*cmp() inside. Because most of the existing\ncommerceware were protected from copying by password, e. g. serial number, etc.\nsometimes by authors. So criticants supposed it's impossible to 'protect' their\nsoftware this way. And thus Linux was 'bad'. ;-)\nNowadays we have all of those possible actions ( trying to investigate and\nsubstitute the password hash in the str*cmp() called by user-space software )\nclassified by Crime Code and aoplied apparently widely. Kind of confessional\ndebates between those who suppose the potentially dangerous thing should be\nrestricted because it can be used as harm and those who use it regularly\nwithout any idea to use it in any different dangerous way. Last time I saw them\non bbc about islam - 'hey, your islam spells to cut thievs' arms' - 'hey islam\nof no danger, it's just very powerful and you shouldn't use it in dangerous\nway'.\nThis will last for ages, anyway. You may find them even in \"Just For Fun\",\nwhere the 'pubs' restricted topics' persist. Even there. \nSo one who use CORE:: namespace in their sources should always know it can be\ngrepped and considered as dangerous, especially if those are 3rd+ party\nsources, not approved by any reasonable authority, and there are lots of such a\nsoftware off the shelves to choose. And most of them doesn't use to override\nperl built-in functions. ;-)\n\nJN> \nJN>   BEGIN { \nJN>     require Carp; \nJN>     *CORE::GLOBAL::die = \\&CGI::Carp::die;\nJN>   }\nJN> \nJN> Sub::Uplevel and Test::Exception redefines 'caller' (perhaps locally).\nJN> CGI::Compile redefines 'exit':\nJN> \nJN>   our $USE_REAL_EXIT;\nJN>   BEGIN {\nJN>       $USE_REAL_EXIT = 1;\nJN>       *CORE::GLOBAL::exit = sub (;$) {\nJN>           my $exit_code = shift;\nJN> \nJN>           CORE::exit(defined $exit_code ? $exit_code : 0) if $USE_REAL_EXIT;\nJN> \nJN>           die [ \"EXIT\\n\", $exit_code || 0 ]\nJN>       };\nJN>   }\nJN> \nJN> \nJN> > > This is quite nice idea to replace 'exit' by subroutine that does\nJN> > > non-local jump to outside of application, at the end of request loop.\nJN> > > Such \"monkey patching\" is the only solution if you can't or shouldn't\nJN> > > modify application code (like FCGI::Spawn being generic solution).\nJN> > \nJN> > Yes, this is quick-n-dirty to apply for those monkeys who are just busy to care\nJN> > about re-writing CGI apps.\nJN> \nJN> Errr... \"monkey patching\" is the name of technique of extending and\nJN> modifying runtime code in dynamic languages, see\nJN> \nJN>   http://en.wikipedia.org/wiki/Monkey_patch\n\nWhat's about 'patching'? Mokeys I meant to be the OpenBSD ( or non-OpenBSD ) crowd ;-)\nhttp://article.gmane.org/gmane.linux.kernel/706950\n\nJN> Although I am not entirely sure if I correctly applied this name to\nJN> described (used) techique.\n\n\n'Replace methods/attributes/functions at runtime, e.g. to stub out a function\nduring testing;'\n\nsounds like 'dynamic modules reloading' to me. Yes, that is about FCGI::Spawn,\nits 'stats' disablable feature \n\n'Modify/extend behaviour of a third-party product without maintaining a private\ncopy of the source code; '\n\nsounds like 'run any 3rd-party CGI app in FCGI::Spawn'\n\nYep, uncle Darwin cries out loud. ;-)\n\nJN> \nJN> > > Here\nJN> > > \nJN> > >    $spawn->{'callout'} = sub {\nJN> > >    \tmy $cgi_app = shift;\nJN> > >    \tdo $cgi_app;\nJN> > > \nJN> > >     # this is needed for sane error handling\nJN> > >     die \"Couldn't parse $cgi_app: $@\" if $@;\nJN> > > \nJN> > >    CALLED_OUT: \nJN> > >    };\nJN> > \nJN> > In a forked application, die() is a PITA on any reasonable load. It makes the\nJN> > CoW-shared memory to be copied into separate area and being marked as unusable\nJN> > before the process is dead. This is the only case I saw load averages on the\nJN> > servers valued as crazy ~700.\nJN> >\nJN> > So just exit there, not die. \nJN> \nJN> Well, it might be 'exit' not 'die', but you really, really need to check\nJN> if there were problems parsing file.  Otheriwse you can get error\nJN> messages somewhere further on that doesn't absolutely make sense.  \n\nphp is very successful with this: it can put error messages to both STDOUT and\nSTDERR or separate log. FCGI::Spawn is the something about that because it's\nthe 'what the most people want' (c) Junio. ;-)\nAnyway, if the file was not parsed, it did not change anything in perl's\ncompile-cache/variables and therefore it's quite safe for any othe application\non the same sandbox. Why should the fork die if some file gets unparsed? \n\nJN> I know this from painful experience of trying to find bug in a\nJN> test... when the error was in parsing file in 'do $file;'.\n\nI handle them just fine like in any other CGI program using\nCGI::Carp:fatalsToBrowser. Are you about to 'make test' via the http? ;-)\n\n[...]\n\nJN>   builder {\nJN>         $app;\nJN>   }\n\nthat's the wow to try. I will after some of my whiles.\n\nJN> or even without it ($app should be the last expression).\nJN> Or did you mean here something like mod_rewrite, or\nJN> Plack::Middleware::Rewrite?\n\nNo, nginx rewrites just fine, it's a matter of another application level I\nbelieve.\nThe scoop is meat and potatoes: here is the cgi app, just do it over FastCGI.\nThere are no such a thing as a mandatory mounts and paths tweaks in php's\nfastcgi. Hope PSGI has no them either.\n\nJN> [...]  \nJN> > > Gitweb doesn't use no POST requests: it is read-only web repository\nJN> > > browser... well, except for the 'show_ctags' action.\nJN> > Tag cloud? Is there an example of usable tag cloud on any public gitweb out\nJN> > there?\nJN> \nJN> Tag cloud are optional feature in stock gitweb, named 'ctag' in %feature\nJN> hash.  It is disabled by default.  If I understand correctly POST is\nJN> used here to populate which tags one wants to use... but perhaps GET\nJN> request would be enough here (at the cost of less readable URL).\nJN> \nJN> See http://repo.or.cz for example usage of this feature.\n\nOuch, it was the first for me to look for them. It's just not named like that\nthere ( and looked like linkspam ;-. Anyway. user registration .cgi is a part\nof gitweb distribution? It contains POST form and it's not  preferable stuff to\nomit for too many cases to consider such a gitweb-based web site to be 'mostly\nread-only' for a user.\nOr those .cgi's are nothing in common with gitweb?\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141478","messageId":"201005111551.21316.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100511120924.GC5220@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-11T13:51:15Z","receivedAt":"2010-05-11T13:51:15Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Tue, 11 May 2010, Peter Vereshagin wrote:\n> 2010/05/11 12:58:50 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n\n> > > > I have changed this 'exit' to non-local goto to toplevel.  It could be\n> > > > done instead by redefining 'exit' subroutine, like shown below, but I\n> > > > feel that would be hacky if you can change gitweb code (it is not\n> > > > black box you should not touch).\n> > > \n> > > Right, one shouldn't ever redefine perl built-in functions. I did only because\n> > > of no other way to 'get things working'\n> > \n> > Why not?  For example CGI::Carp redefines 'die' to log errors.\n> \n> Ouch, sorry, I meant 'last' or something like that.\n\n\"last\" / \"last LABEL\" is a command, not a function, therefore you cannot\nredefine it.\n\nWell, perhaps you can with heavy hackery involving opcodes and the like,\nor something debugger-like, or/and something like B::* modules, taking\nover Perl parser.  See e.g. Devel::Declare or Template::Declare Perl\nmodules on CPAN. :-)\n\n> I just believe any non-system application development for end-user being a\n> non-developer doesn't need to redefine perl built-in functions. Just a sane\n> bone tone for common functioning in a sandbox.\n>\n> For example, I remember the Linux kernel  ( or Glibc? ) was criticised much of\n> being possible to override the str*cmp() inside. Because most of the existing\n> commerceware were protected from copying by password, e. g. serial number, etc.\n> sometimes by authors. So criticants supposed it's impossible to 'protect' their\n> software this way. And thus Linux was 'bad'. ;-)\n\nWhat about libsafe (?) and similar security solutions, which replace\nstr* functions from (g)libc with safer but slower counterparts?  What\nabout Dmalloc, Electric Fence and the like which replace malloc etc.?\n\n> So one who use CORE:: namespace in their sources should always know it can be\n> grepped and considered as dangerous, especially if those are 3rd+ party\n> sources, not approved by any reasonable authority, and there are lots of such a\n> software off the shelves to choose. And most of them doesn't use to override\n> perl built-in functions. ;-)\n\nIt is true that messing with / overriding things from CORE:: (or\nUNIVERSAL:: for OOP) namespace is dangerous, and should be avoided if\npossible... but well, sometimes it is a best solution.\n \n> > I know this from painful experience of trying to find bug in a\n> > test... when the error was in parsing file in 'do $file;'.\n> \n> I handle them just fine like in any other CGI program using\n> CGI::Carp:fatalsToBrowser. Are you about to 'make test' via the http? ;-)\n\nI don't think you understand what I wanted to say there.\n\nIf you don't check if there were parse errors from 'do $file;', you can\nget later some error message which is totally unrelated to the parsing\nerror.  If you don't know or forget that you should check $@ after \n'do $file;', and are unlucky, you can chase elusive error from there\nto kingdom come...\n\nFor example when debugging gitweb output caching code using automated\ntests, I got the following error:\n\n  'Undefined subroutine &GitwebCache::SimpleFileCache::compute called'\n\nThe subroutine was defined, but there was a bug in parsing included\nfile, so Perl didn't make it to definition of said compute() subroutine.\n\n> [...]\n> \n> >   builder {\n> >         $app;\n> >   }\n> \n> that's the wow to try. I will after some of my whiles.\n\nCheck out http://plackperl.org, especially presentations and Perl Advent\nCalendar which describes PSGI/Plack step by step (links at the bottom of\nthe page).\n \n> > or even without it ($app should be the last expression).\n> > Or did you mean here something like mod_rewrite, or\n> > Plack::Middleware::Rewrite?\n> \n> No, nginx rewrites just fine, it's a matter of another application level I\n> believe.\n>\n> The scoop is meat and potatoes: here is the CGI app, just do it over FastCGI.\n> There are no such a thing as a mandatory mounts and paths tweaks in PHP's\n> FastCGI. Hope PSGI has no them either.\n\nPSGI is interface, Plack is reference implementation.  You can run PSGI\napp on any supported web server; this includes running PSGI apps on\nFastCGI.\n\n> > > > Gitweb doesn't use no POST requests: it is read-only web repository\n> > > > browser... well, except for the 'show_ctags' action.\n> > >\n> > > Tag cloud? Is there an example of usable tag cloud on any public gitweb out\n> > > there?\n> > \n> > Tag cloud are optional feature in stock gitweb, named 'ctag' in %feature\n> > hash.  It is disabled by default.  If I understand correctly POST is\n> > used here to populate which tags one wants to use... but perhaps GET\n> > request would be enough here (at the cost of less readable URL).\n> > \n> > See http://repo.or.cz for example usage of this feature.\n> \n> Ouch, it was the first for me to look for them. It's just not named like that\n> there ( and looked like linkspam ;-. Anyway. user registration .cgi is a part\n> of gitweb distribution? It contains POST form and it's not  preferable stuff to\n> omit for too many cases to consider such a gitweb-based web site to be 'mostly\n> read-only' for a user.\n>\n> Or those .cgi's are nothing in common with gitweb?\n\nThe repository management part of http://repo.or.cz is not part of\ngitweb.  It is a separate tool, named Girocco.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"141586","messageId":"20100513131016.GA5250@screwed.box","threadId":"23728","inReplyTo":"201005111551.21316.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-13T13:10:16Z","receivedAt":"2010-05-13T13:10:16Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"Hey Mr(s) Jakub show some good to me!\n2010/05/11 15:51:15 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nJN> On Tue, 11 May 2010, Peter Vereshagin wrote:\nJN> > 2010/05/11 12:58:50 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nJN> \nJN> > > > > I have changed this 'exit' to non-local goto to toplevel.  It could be\nJN> > > > > done instead by redefining 'exit' subroutine, like shown below, but I\nJN> > > > > feel that would be hacky if you can change gitweb code (it is not\nJN> > > > > black box you should not touch).\nJN> > > > \nJN> > > > Right, one shouldn't ever redefine perl built-in functions. I did only because\nJN> > > > of no other way to 'get things working'\nJN> > > \nJN> > > Why not?  For example CGI::Carp redefines 'die' to log errors.\nJN> > \nJN> > Ouch, sorry, I meant 'last' or something like that.\nJN> \nJN> \"last\" / \"last LABEL\" is a command, not a function, therefore you cannot\nJN> redefine it.\n\nit's a flow control statement thus it is a built-in thing same way as any other\nfunctions are explained in a 'perldoc -f'\nTherefore it is treated by monkeys crowd as function. It's obvious for me to\nstay out here ( here != maillist ) yet in such an environment.\nAnyway, I compare last() here  with exit() and die() which look to user just\nlike the same kind of: the flow control statements. I guess any perl user who\nmakes things like gitweb ( at least as a CGI-only app ) shouldn't care about\nsuch an internal difference of flow control statements those are\nhidden/incapsulated inside the implementation of those statements?\nNeedless to mention that the 'last LABEL' ( goto, gosub, ... named them )  is a\nbad and a very deprecated style which is every schoolboy is aware about\nnowadays to keep from using in the application, not system, programming in imho\nevery language.\n\nJN> Well, perhaps you can with heavy hackery involving opcodes and the like,\nJN> or something debugger-like, or/and something like B::* modules, taking\nJN> over Perl parser.  See e.g. Devel::Declare or Template::Declare Perl\nJN> modules on CPAN. :-)\nJN> \nJN> > I just believe any non-system application development for end-user being a\nJN> > non-developer doesn't need to redefine perl built-in functions. Just a sane\nJN> > bone tone for common functioning in a sandbox.\nJN> >\nJN> > For example, I remember the Linux kernel  ( or Glibc? ) was criticised much of\nJN> > being possible to override the str*cmp() inside. Because most of the existing\nJN> > commerceware were protected from copying by password, e. g. serial number, etc.\nJN> > sometimes by authors. So criticants supposed it's impossible to 'protect' their\nJN> > software this way. And thus Linux was 'bad'. ;-)\nJN> \nJN> What about libsafe (?) and similar security solutions, which replace\nJN> str* functions from (g)libc with safer but slower counterparts?  What\n\nThat was bad sound for commerceware vendors. Because such a in-core functions\nsubstititions can make the user safer but not the investments ( targeted on\nsqueezing users' pursues).\n\nJN> about Dmalloc, Electric Fence and the like which replace malloc etc.?\n\nI think malloc implementation details cannot keep software's serial number from\nbeing verified. ;-)\nBack to perl built-ins: should it be normal if gitweb will be dependent on a\nusage of a particular malloc implementation? In my perl, I can have a choice of\nthem. ;-)\n\nJN> > So one who use CORE:: namespace in their sources should always know it can be\nJN> > grepped and considered as dangerous, especially if those are 3rd+ party\nJN> > sources, not approved by any reasonable authority, and there are lots of such a\nJN> > software off the shelves to choose. And most of them doesn't use to override\nJN> > perl built-in functions. ;-)\nJN> \nJN> It is true that messing with / overriding things from CORE:: (or\nJN> UNIVERSAL:: for OOP) namespace is dangerous, and should be avoided if\nJN> possible... but well, sometimes it is a best solution.\n\nI think the state line between area to avoid one and the area where it can ever\nhappen to be the best of the solutions is built socially: it is where system\ncoder's work about daemon interfaces like the FCGI/PSGI/SCGI/etc. and the\napplied coder one: the application architecture, used libraries, application\nlayers, etc.\nThis is just where FCGI::Spawn is about to help. Because 'regular system admin'\nis typically unaware of details of usage of system daemon interfaces in perl.\nBut (s)he could be the perl application coder since perl is that easy as a\nlanguage tool. This is just who and when, and thus in what parts of the code\nused by the same Perl interpreter shouldn't play with built-ins like the CORE::\nnamespace and thanks perl it can be easily grepped.\n\nJN> > > I know this from painful experience of trying to find bug in a\nJN> > > test... when the error was in parsing file in 'do $file;'.\nJN> > \nJN> > I handle them just fine like in any other CGI program using\nJN> > CGI::Carp:fatalsToBrowser. Are you about to 'make test' via the http? ;-)\nJN> \nJN> I don't think you understand what I wanted to say there.\nJN> \nJN> If you don't check if there were parse errors from 'do $file;', you can\nJN> get later some error message which is totally unrelated to the parsing\nJN> error.  If you don't know or forget that you should check $@ after \nJN> 'do $file;', and are unlucky, you can chase elusive error from there\nJN> to kingdom come...\n\nGot it, it's about the inclusion failure via the do() which is the development,\nnot a production, situation.\nI think this should be an adjective noun to use the both strict and the warnings?\nAnd yes, since it's about development but not production use, die is just fine\nin the inclusion code like this:\n\neval( 'use Module;' ); die $@ if $@;\n\nas always, require() can do the trick, not to mention usual \n\nuse Module;\n\nThis all will cause die() when it's necessary as only the application developer\nknows how strict is the dependence on the Module. In some cases, application\ncan work without some Module but it's just better with it.\n\nJN> For example when debugging gitweb output caching code using automated\nJN> tests, I got the following error:\nJN> \nJN>   'Undefined subroutine &GitwebCache::SimpleFileCache::compute called'\nJN> \nJN> The subroutine was defined, but there was a bug in parsing included\nJN> file, so Perl didn't make it to definition of said compute() subroutine.\n\nWhat is the code? Where and what file was included via the do()?\nInteresting situation. If the sub was compiled, was it present then in the\nsymbol table?\nI can't see the code of ... GitwebCache::SimpleFileCache package to contain the do()? \n\nJN> > [...]\nJN> > \nJN> > >   builder {\nJN> > >         $app;\nJN> > >   }\nJN> > \nJN> > that's the wow to try. I will after some of my whiles.\nJN> \nJN> Check out http://plackperl.org, especially presentations and Perl Advent\nJN> Calendar which describes PSGI/Plack step by step (links at the bottom of\nJN> the page).\nJN>  \nJN> > > or even without it ($app should be the last expression).\nJN> > > Or did you mean here something like mod_rewrite, or\nJN> > > Plack::Middleware::Rewrite?\nJN> > \nJN> > No, nginx rewrites just fine, it's a matter of another application level I\nJN> > believe.\nJN> >\nJN> > The scoop is meat and potatoes: here is the CGI app, just do it over FastCGI.\nJN> > There are no such a thing as a mandatory mounts and paths tweaks in PHP's\nJN> > FastCGI. Hope PSGI has no them either.\nJN> \nJN> PSGI is interface, Plack is reference implementation.  You can run PSGI\nJN> app on any supported web server; this includes running PSGI apps on\nJN> FastCGI.\n\nExisting problem FCGI::Spawn for is not the PSGI applications to be run as a\nFastCGI, but the bunch of existing CGI.pm applications ( even gitorious ) need\nto be more effective with the widest-spread protocol FastCGI. Best without any\npatching of the application, deployed the same simple way as with apache's cgi\nimplementation.\nWill check on this.\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141600","messageId":"AANLkTilnaHQ4Q8n3GOhYPcYAFi_tT8uSE_uTZhU_QYhK@mail.gmail.com","threadId":"23728","inReplyTo":"20100513131016.GA5250@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-13T17:13:12Z","receivedAt":"2010-05-13T17:13:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"2010/5/13 Peter Vereshagin <peter@vereshagin.org>:\n> Hey Mr(s) Jakub show some good to me!\n> 2010/05/11 15:51:15 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n> JN> On Tue, 11 May 2010, Peter Vereshagin wrote:\n> JN> > 2010/05/11 12:58:50 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n> JN>\n> JN> > > > > I have changed this 'exit' to non-local goto to toplevel.  It could be\n> JN> > > > > done instead by redefining 'exit' subroutine, like shown below, but I\n> JN> > > > > feel that would be hacky if you can change gitweb code (it is not\n> JN> > > > > black box you should not touch).\n> JN> > > >\n> JN> > > > Right, one shouldn't ever redefine perl built-in functions. I did only because\n> JN> > > > of no other way to 'get things working'\n> JN> > >\n> JN> > > Why not?  For example CGI::Carp redefines 'die' to log errors.\n> JN> >\n> JN> > Ouch, sorry, I meant 'last' or something like that.\n> JN>\n> JN> \"last\" / \"last LABEL\" is a command, not a function, therefore you cannot\n> JN> redefine it.\n>\n> it's a flow control statement thus it is a built-in thing same way as any other\n> functions are explained in a 'perldoc -f'\n> Therefore it is treated by monkeys crowd as function. It's obvious for me to\n> stay out here ( here != maillist ) yet in such an environment.\n\nThese things are called \"operators\" in Perl, some of them (like exit)\nyou can redefine. Some (like last) you can't. At least not without\nsome deep magic.\n\n> Anyway, I compare last() here  with exit() and die() which look to user just\n> like the same kind of: the flow control statements. I guess any perl user who\n> makes things like gitweb ( at least as a CGI-only app ) shouldn't care about\n> such an internal difference of flow control statements those are\n> hidden/incapsulated inside the implementation of those statements?\n> Needless to mention that the 'last LABEL' ( goto, gosub, ... named them )  is a\n> bad and a very deprecated style which is every schoolboy is aware about\n> nowadays to keep from using in the application, not system, programming in imho\n> every language.\n\n`last LABEL' is not bad or deprecated. It's what you use to get out of\nnested for-loops in Perl:\n\n    OUTER: for my $i (1 .. 10) {\n        for my $j (1 .. 10) {\n            last OUTER if $i == 5 and $j == 5;\n        }\n    }\n\ngoto is also recommended in some cases in Perl. That's because it\ndoesn't do the same thing as in C:\n\n    # Don't create a stack frame\n    sub foo { goto &bar }\n\nAnyway, arguing over which control flow operator is evil in an\nimperitive language is just splitting hairs. Certain uses of them are\na bad idea, not the operators themselves.\n"},{"id":"141662","messageId":"201005141253.46956.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100513131016.GA5250@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-14T10:53:42Z","receivedAt":"2010-05-14T10:53:42Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 13 May 2010, Peter Vereshagin wrote:\n> 2010/05/11 15:51:15 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n>> On Tue, 11 May 2010, Peter Vereshagin wrote:\n>>> 2010/05/11 12:58:50 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n \n>>>>>> I have changed this 'exit' to non-local goto to toplevel.  It could be\n>>>>>> done instead by redefining 'exit' subroutine, like shown below, but I\n>>>>>> feel that would be hacky if you can change gitweb code (it is not\n>>>>>> black box you should not touch).\n>>>>> \n>>>>> Right, one shouldn't ever redefine perl built-in functions. I did only because\n>>>>> of no other way to 'get things working'\n>>>> \n>>>> Why not?  For example CGI::Carp redefines 'die' to log errors.\n>>> \n>>> Ouch, sorry, I meant 'last' or something like that.\n>> \n>> \"last\" / \"last LABEL\" is a command, not a function, therefore you cannot\n>> redefine it.\n> \n> It's a flow control statement, thus it is a built-in thing; same way as any other\n> functions are explained in a 'perldoc -f'.\n\n`perldoc -f exit` says 'The exit() function ...', while `perldoc -f last`\nsays 'The \"last\" command is like the \"break\" statement in C ...'.\n\n> Therefore it is treated by monkeys crowd as function. It's obvious for me to\n> stay out here (here != maillist) yet in such an environment.\n\nSidenote: The 'Monkey patch' article on Wikipedia says that the\ntechnique of adding method dirctly to class instead of subclassing was\noriginally called \"guerilla patching\", then it mutated into \"gorilla\npatching\", and finally into \"monkey patching\".\n\n> Anyway, I compare \"last\" here  with exit() and die() which look to user just\n> like the same kind of: the flow control statements. I guess any Perl user who\n> makes things like gitweb (at least as a CGI-only app) shouldn't care about\n> such an internal difference of flow control statements those are\n> hidden/incapsulated inside the implementation of those statements?\n\nPerl hacker should know the difference between command such as \"last\"\nand \"next\", and functions such as exit() and die().  Just like C\nprogrammer should know the difference between \"break\" statement and\nexit() function.\n\n> Needless to mention that the 'last LABEL' ( goto, gosub, ... named them )  is a\n> bad and a very deprecated style which is every schoolboy is aware about\n> nowadays to keep from using in the application [...]\n\nNot true.  The 'last LABEL;' command is very useful to exit nested\nloops.  If used right it makes code much simpler (allowing to avoid\nextra flag variable and/or complicating loop conditional).  If I\nremember correctly in O.-J. Dahl, Edsger W. Dijkstra, C. A. R. Hoare\n\"Structured Programming\" the programming language described includes\n\"break <n>\" statement, with similar purpose as \"last LABEL\" in Perl.\n\nNote also that Dijkstra wrote in seminal article \"Go To Statement\nConsidered Harmful\" that the problem with abused 'goto' is that it\ncompilcates and muddles control flow of program.  But there are\nlegitimate uses of 'goto' that make the program simpler to understand,\nand not harder,... among those is handling exceptions.\n\n>>>> I know this from painful experience of trying to find bug in a\n>>>> test... when the error was in parsing file in 'do $file;'.\n>>> \n>>> I handle them just fine like in any other CGI program using\n>>> CGI::Carp:fatalsToBrowser. Are you about to 'make test' via the http? ;-)\n>> \n>> I don't think you understand what I wanted to say there.\n>> \n>> If you don't check if there were parse errors from 'do $file;', you can\n>> get later some error message which is totally unrelated to the parsing\n>> error.  If you don't know or forget that you should check $@ after \n>> 'do $file;', and are unlucky, you can chase elusive error from there\n>> to kingdom come...\n> \n> Got it, it's about the inclusion failure via the do() which is the\n> development, not a production, situation.\n\nYes, it is a problem mainly in developemtn, where changes to the file\nincluded via \"do <file>\" might introduce parsing errors.\n\n> I think this should be an adjective noun to use the both strict and\n> the warnings?\n\nThe problem is that \"do <file>;\" is similar to \"eval `cat <file>`;\"\n(except that it's more efficient and concise), it that it silences\nparsing errors.  From `perldoc -f do`:\n\n  If \"do\" cannot read the file, it returns undef and sets $! to the error.\n  If \"do\" can read the file but cannot compile it, it returns undef and sets\n  an error message in $@.   If the file is successfully compiled, \"do\"\n  returns the value of the last expression evaluated.\n\n> And yes, since it's about development but not production use, die is just fine\n> in the inclusion code like this:\n> \n> eval( 'use Module;' ); die $@ if $@;\n\nWrong!\n \n> as always, require() can do the trick, not to mention usual \n> \n> use Module;\n> \n> This all will cause die() when it's necessary as only the application developer\n> knows how strict is the dependence on the Module. In some cases, application\n> can work without some Module but it's just better with it.\n\nFirst, both \"use Module;\" and \"require Module;\" (and \"require '<file>';\")\ndo automatic error checking and raise an exception if there is problem.\n\nSecond, \"use Module <LIST>;\" is equivalent to\n\n  BEGIN { require Module; import Module <LIST>; }\n\nand therefore it doesn't make sense to use it for conditional inclusion.\n\n\nTherefore, to load Perl module / file, if you can 'die' you can simply\nuse\n\n  require \"<file>\";\n\nIf you don't want to die, but want to know if loading and parsing file\nsucceeded or not, you should use the following syntax:\n\n  if (eval { require \"<file>\"; 1 }) {\n    ...\n  } else {\n    ...\n  }\n\nIf you want to use 'do \"<file>\";' (it is preferred in some\ncircumstances), you really should check for error conditins:\n\n  unless (my $return = do \"<file>\") {\n    if ($@) {\n       # couldn't parse <file>\n    } elsif (!defined $return) {\n       # couldn't do <file> (e.g. couldn't find <file>)\n    }\n    ...\n  }\n\n[...]\n>> PSGI is interface, Plack is reference implementation.  You can run PSGI\n>> app on any supported web server; this includes running PSGI apps on\n>> FastCGI.\n> \n> Existing problem FCGI::Spawn for is not the PSGI applications to be run as a\n> FastCGI, but the bunch of existing CGI.pm applications (even gitorious) need\n> to be more effective with the widest-spread protocol FastCGI. Best without any\n> patching of the application, deployed the same simple way as with apache's cgi\n> implementation.\n\nGitorious is in Ruby, therefore is not a CGI.pm application, as it is\nnot even in Perl.\n\nBy using Plack::App::CGIBin you can load CGI scripts from a directory\nand convert them into a <persistent> PSGI application.  You can use\nPlack::App::WrapCGI to convert single CGI script into PSGI application.\nYou can use Plack::Buuilder's domain specific language to join (map)\ntogether a bunch of PSGI applications (in different paths) in a single\napp (via Plack::App::URLMap).\n\nYou can then run PSGI application (for example the PSGI app which loads\nCGI apps via Plack::App::CGIBin) on any supported web server, which\nincludes FCGI (FastCGI).\n\n-- \nJakub Narebski\nPoland\n"},{"id":"141675","messageId":"20100514153636.GB17443@screwed.box","threadId":"23728","inReplyTo":"201005141253.46956.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-14T15:36:36Z","receivedAt":"2010-05-14T15:36:36Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"God love is hard to find. You got lucky Jakub!\n2010/05/14 12:53:42 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nJN> legitimate uses of 'goto' that make the program simpler to understand,\nJN> and not harder,... among those is handling exceptions.\n\nso did you change the exception-related exit()s on your patch to the last()s ?\n\nJN> >>>> I know this from painful experience of trying to find bug in a\nJN> >>>> test... when the error was in parsing file in 'do $file;'.\nJN> >>> \nJN> >>> I handle them just fine like in any other CGI program using\nJN> >>> CGI::Carp:fatalsToBrowser. Are you about to 'make test' via the http? ;-)\nJN> >> \nJN> >> I don't think you understand what I wanted to say there.\nJN> >> \nJN> >> If you don't check if there were parse errors from 'do $file;', you can\nJN> >> get later some error message which is totally unrelated to the parsing\nJN> >> error.  If you don't know or forget that you should check $@ after \nJN> >> 'do $file;', and are unlucky, you can chase elusive error from there\nJN> >> to kingdom come...\nJN> > \nJN> > Got it, it's about the inclusion failure via the do() which is the\nJN> > development, not a production, situation.\nJN> \nJN> Yes, it is a problem mainly in developemtn, where changes to the file\nJN> included via \"do <file>\" might introduce parsing errors.\nJN> \nJN> > I think this should be an adjective noun to use the both strict and\nJN> > the warnings?\nJN> \nJN> The problem is that \"do <file>;\" is similar to \"eval `cat <file>`;\"\nJN> (except that it's more efficient and concise), it that it silences\nJN> parsing errors.  From `perldoc -f do`:\nJN> \nJN>   If \"do\" cannot read the file, it returns undef and sets $! to the error.\nJN>   If \"do\" can read the file but cannot compile it, it returns undef and sets\nJN>   an error message in $@.   If the file is successfully compiled, \"do\"\nJN>   returns the value of the last expression evaluated.\nJN> \nJN> > And yes, since it's about development but not production use, die is just fine\nJN> > in the inclusion code like this:\nJN> > \nJN> > eval( 'use Module;' ); die $@ if $@;\nJN> \nJN> Wrong!\n\nThe problem was you can't see the reason of the inclusion-via-do() parsing\nfailure.\nBut you may see it with use warnings; right?\nIs there any applied example of do()-caused failures?\n\nJN> > as always, require() can do the trick, not to mention usual \nJN> > \nJN> > use Module;\nJN> > \nJN> > This all will cause die() when it's necessary as only the application developer\nJN> > knows how strict is the dependence on the Module. In some cases, application\nJN> > can work without some Module but it's just better with it.\nJN> \nJN> First, both \"use Module;\" and \"require Module;\" (and \"require '<file>';\")\nJN> do automatic error checking and raise an exception if there is problem.\n\nfor web applications, half of exceptions or more are generated when the user\nisn't the develioper.\nNotifications() via the logs are just enough and more than it: should be the\nprefered way of exceptions' notifications in a production.\nWhy worry about return code then?\n\nJN> Second, \"use Module <LIST>;\" is equivalent to\nJN>   BEGIN { require Module; import Module <LIST>; }\nJN> and therefore it doesn't make sense to use it for conditional inclusion.\n\neval() is used there.\n\nJN> Therefore, to load Perl module / file, if you can 'die' you can simply\nJN> use\nJN> \nJN>   require \"<file>\";\nJN> \nJN> If you don't want to die, but want to know if loading and parsing file\nJN> succeeded or not, you should use the following syntax:\nJN> \nJN>   if (eval { require \"<file>\"; 1 }) {\nJN>     ...\nJN>   } else {\nJN>     ...\nJN>   }\nJN> \nJN> If you want to use 'do \"<file>\";' (it is preferred in some\nJN> circumstances), you really should check for error conditins:\nJN> \nJN>   unless (my $return = do \"<file>\") {\nJN>     if ($@) {\nJN>        # couldn't parse <file>\nJN>     } elsif (!defined $return) {\nJN>        # couldn't do <file> (e.g. couldn't find <file>)\nJN>     }\nJN>     ...\nJN>   }\n\nSo you propose to use the return code either way. Is it a key point?\nAnd what is the real difference from $@ usage?\nYou mention 'The subroutine was defined, but there was a bug in parsing\nincluded file' just where is the code? How come file was not parsed but sub was\ndefined?\n\nJN> [...]\nJN> >> PSGI is interface, Plack is reference implementation.  You can run PSGI\nJN> >> app on any supported web server; this includes running PSGI apps on\nJN> >> FastCGI.\nJN> > \nJN> > Existing problem FCGI::Spawn for is not the PSGI applications to be run as a\nJN> > FastCGI, but the bunch of existing CGI.pm applications (even gitorious) need\nJN> > to be more effective with the widest-spread protocol FastCGI. Best without any\nJN> > patching of the application, deployed the same simple way as with apache's cgi\nJN> > implementation.\nJN> \nJN> Gitorious is in Ruby, therefore is not a CGI.pm application, as it is\nJN> not even in Perl.\n\nIt was Girocco you mentioned earlier\n\nJN> By using Plack::App::CGIBin you can load CGI scripts from a directory\nJN> and convert them into a <persistent> PSGI application.  You can use\n\nSuch a conversion is more than a compilation? Does it mean converted CGI app\nshould be stored before to become a persistent application?\n\nJN> Plack::App::WrapCGI to convert single CGI script into PSGI application.\nJN> You can use Plack::Buuilder's domain specific language to join (map)\nJN> together a bunch of PSGI applications (in different paths) in a single\nJN> app (via Plack::App::URLMap).\n\nAnd can the same process of that application server run for the several\napplications depending on the FastCGI request?\n\nJN> You can then run PSGI application (for example the PSGI app which loads\nJN> CGI apps via Plack::App::CGIBin) on any supported web server, which\nJN> includes FCGI (FastCGI).\n\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141677","messageId":"20100514155806.GC17443@screwed.box","threadId":"23728","inReplyTo":"AANLkTilnaHQ4Q8n3GOhYPcYAFi_tT8uSE_uTZhU_QYhK@mail.gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-14T15:58:06Z","receivedAt":"2010-05-14T15:58:06Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"God love is hard to find. You got lucky ??var!\n2010/05/13 17:13:12 +0000 ??var Arnfj??r?? Bjarmason <avarab@gmail.com> => To Peter Vereshagin :\nvArB> 2010/5/13 Peter Vereshagin <peter@vereshagin.org>:\nvArB> > Hey Mr(s) Jakub show some good to me!\nvArB> > 2010/05/11 15:51:15 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nvArB> > JN> On Tue, 11 May 2010, Peter Vereshagin wrote:\nvArB> > JN> > 2010/05/11 12:58:50 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nvArB> > JN>\nvArB> > JN> > > > > I have changed this 'exit' to non-local goto to toplevel.  It could be\nvArB> > JN> > > > > done instead by redefining 'exit' subroutine, like shown below, but I\nvArB> > JN> > > > > feel that would be hacky if you can change gitweb code (it is not\nvArB> > JN> > > > > black box you should not touch).\nvArB> > JN> > > >\nvArB> > JN> > > > Right, one shouldn't ever redefine perl built-in functions. I did only because\nvArB> > JN> > > > of no other way to 'get things working'\nvArB> > JN> > >\nvArB> > JN> > > Why not?  For example CGI::Carp redefines 'die' to log errors.\nvArB> > JN> >\nvArB> > JN> > Ouch, sorry, I meant 'last' or something like that.\nvArB> > JN>\nvArB> > JN> \"last\" / \"last LABEL\" is a command, not a function, therefore you cannot\nvArB> > JN> redefine it.\nvArB> >\nvArB> > it's a flow control statement thus it is a built-in thing same way as any other\nvArB> > functions are explained in a 'perldoc -f'\nvArB> > Therefore it is treated by monkeys crowd as function. It's obvious for me to\nvArB> > stay out here ( here != maillist ) yet in such an environment.\nvArB> \nvArB> These things are called \"operators\" in Perl, some of them (like exit)\nvArB> you can redefine. Some (like last) you can't. At least not without\nvArB> some deep magic.\n\nproblem is not the naming, but that those are built-in and supposed to be used\n'as is'. Operators or functions are whatever, but for perldoc they are the '-f'\nso think not a big problem I named them functions.\n\nvArB> > Anyway, I compare last() here  with exit() and die() which look to user just\nvArB> > like the same kind of: the flow control statements. I guess any perl user who\nvArB> > makes things like gitweb ( at least as a CGI-only app ) shouldn't care about\nvArB> > such an internal difference of flow control statements those are\nvArB> > hidden/incapsulated inside the implementation of those statements?\nvArB> > Needless to mention that the 'last LABEL' ( goto, gosub, ... named them )  is a\nvArB> > bad and a very deprecated style which is every schoolboy is aware about\nvArB> > nowadays to keep from using in the application, not system, programming in imho\nvArB> > every language.\nvArB> \nvArB> `last LABEL' is not bad or deprecated. It's what you use to get out of\nvArB> nested for-loops in Perl:\nvArB> \nvArB>     OUTER: for my $i (1 .. 10) {\nvArB>         for my $j (1 .. 10) {\nvArB>             last OUTER if $i == 5 and $j == 5;\nvArB>         }\nvArB>     }\nvArB> \nvArB> goto is also recommended in some cases in Perl. That's because it\nvArB> doesn't do the same thing as in C:\nvArB> \nvArB>     # Don't create a stack frame\nvArB>     sub foo { goto &bar }\nvArB> \nvArB> Anyway, arguing over which control flow operator is evil in an\nvArB> imperitive language is just splitting hairs. Certain uses of them are\nvArB> a bad idea, not the operators themselves.\n\ncorrect, just use-cases are a thing to change like cgi to fastcgi environment,\nthis is where exit() is intended to be redefined for performance reasons. Thus\noriginal uses are not as certain as they were supposed to be at the moment of\napplications' coding: there were no idea why the END{}'s exit() is any better\nthan the explicit in-code one. It's just can cause the lack of the performance\nand should be avoided in persistent perl processes to serve such a CGI-like\napplications.\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141686","messageId":"201005141958.16469.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100514153636.GB17443@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-14T17:58:15Z","receivedAt":"2010-05-14T17:58:15Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Fri, 14 May 2010, Peter Vereshagin wrote:\n> 2010/05/14 12:53:42 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n\n>> legitimate uses of 'goto' that make the program simpler to understand,\n>> and not harder,... among those is handling exceptions.\n> \n> so did you change the exception-related exit()s on your patch to the\n> \"last\" ?\n\nYes, die_error(), which had \"exit\" that got replaced by non-local \"goto\"\nis exception-related subroutine.\n\n\n>> The problem is that \"do <file>;\" is similar to \"eval `cat <file>`;\"\n>> (except that it's more efficient and concise), it that it silences\n>> parsing errors.  From `perldoc -f do`:\n>> \n>>   If \"do\" cannot read the file, it returns undef and sets $! to the error.\n>>   If \"do\" can read the file but cannot compile it, it returns undef and sets\n>>   an error message in $@.   If the file is successfully compiled, \"do\"\n>>   returns the value of the last expression evaluated.\n>> \n>>> And yes, since it's about development but not production use, die is just fine\n>>> in the inclusion code like this:\n>>> \n>>> eval( 'use Module;' ); die $@ if $@;\n>> \n>> Wrong!\n> \n> The problem was you can't see the reason of the inclusion-via-do()\n> parsing failure.\n\nYou don't see the parsing failure because \"do <file>;\" functions like\n\"eval\", which traps exceptions.  You will see consequences of parsing\nfailure (like not defined subroutine).\n\n> But you may see it with \"use warnings;\" right?\n\n\"use warnings;\" pragma doesn't help, because of the 'trapping\nexceptions' part.  That is why \"require <file>\" is recommended over \n\"do <file>\".\n\n>>> as always, require() can do the trick, not to mention usual \n>>> \n>>> use Module;\n>>> \n>>> This all will cause die() when it's necessary as only the application developer\n>>> knows how strict is the dependence on the Module. In some cases, application\n>>> can work without some Module but it's just better with it.\n>> \n>> First, both \"use Module;\" and \"require Module;\" (and \"require '<file>';\")\n>> do automatic error checking and raise an exception if there is problem.\n> \n> for web applications, half of exceptions or more are generated when the user\n> isn't the develioper.\n> Notifications() via the logs are just enough and more than it: should be the\n> prefered way of exceptions' notifications in a production.\n> Why worry about return code then?\n\nChecking $@ after \"do <file>\" would cover the situation where there were\nparsing errors, but wouldn't cover situation where file was not found,\nor there was error in executing code (but parsing was O.K.).\n \n>> Second, \"use Module <LIST>;\" is equivalent to\n>>   BEGIN { require Module; import Module <LIST>; }\n>> and therefore it doesn't make sense to use it for conditional inclusion.\n> \n> eval() is used there.\n\nIt's the fact that \"use Module\" uses BEGIN block that is incompatibile\nwith *conditional* using it from eval.\n\n>>>> PSGI is interface, Plack is reference implementation.  You can run PSGI\n>>>> app on any supported web server; this includes running PSGI apps on\n>>>> FastCGI.\n>>> \n>>> Existing problem FCGI::Spawn for is not the PSGI applications to be run as a\n>>> FastCGI, but the bunch of existing CGI.pm applications (even gitorious) need\n>>> to be more effective with the widest-spread protocol FastCGI. Best without any\n>>> patching of the application, deployed the same simple way as with apache's cgi\n>>> implementation.\n>> \n>> Gitorious is in Ruby, therefore is not a CGI.pm application, as it is\n>> not even in Perl.\n> \n> It was Girocco you mentioned earlier\n\nGirocco is shell scripts, not Perl either, see\nhttp://repo.or.cz/w/girocco.git/tree\n\n>> By using Plack::App::CGIBin you can load CGI scripts from a directory\n>> and convert them into a <persistent> PSGI application.  You can use\n> \n> Such a conversion is more than a compilation? Does it mean converted CGI app\n> should be stored before to become a persistent application?\n\nThis convertion is \na.) compiling CGI file into subroutine (taking care of things like DATA\n    filehandle) using CGI::Compile\nb.) converting between CGI interface and PSGI interface, using\n    CGI::Emulate::PSGI\n\n\nCGI::Compile manpage includes this example:\n\n         use CGI::Emulate::PSGI;\n         use CGI::Compile;\n\n         my $cgi_script = \"/path/to/foo.cgi\";\n         my $sub = CGI::Compile->compile($cgi_script);\n         my $app = CGI::Emulate::PSGI->handler($sub);\n\n         # $app is a PSGI application\n\n>> Plack::App::WrapCGI to convert single CGI script into PSGI application.\n>> You can use Plack::Buuilder's domain specific language to join (map)\n>> together a bunch of PSGI applications (in different paths) in a single\n>> app (via Plack::App::URLMap).\n> \n> And can the same process of that application server run for the several\n> applications depending on the FastCGI request?\n\nYes, it can.  Depending on request it would run appropriate\nCGI-converted-to-PSGI application.\n\nI am not sure how Plack::App::CGIBin works internally; it migh cimpile\nall CGI applications upfront; but it might not.\n \n>> You can then run PSGI application (for example the PSGI app which loads\n>> CGI apps via Plack::App::CGIBin) on any supported web server, which\n>> includes FCGI (FastCGI).\n\n-- \nJakub Narebski\nPoland\n"},{"id":"141692","messageId":"201005142043.31468.jnareb@gmail.com","threadId":"23728","inReplyTo":"201005141958.16469.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-14T18:43:30Z","receivedAt":"2010-05-14T18:43:30Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Fri, 14 May 2010, Jakub Narebski wrote:\n\n> Girocco is shell scripts, not Perl either, see\n> http://repo.or.cz/w/girocco.git/tree\n\nI'm sorry, I stand corrected: the CGI scripts in Girocco are in Perl.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"141719","messageId":"20100515100615.GA3564@screwed.box","threadId":"23728","inReplyTo":"201005141958.16469.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-15T10:06:15Z","receivedAt":"2010-05-15T10:06:15Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"You're face to face with man who sold the world, Jakub!\n2010/05/14 19:58:15 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\nJN> You don't see the parsing failure because \"do <file>;\" functions like\nJN> \"eval\", which traps exceptions.  You will see consequences of parsing\nJN> failure (like not defined subroutine).\nJN> \nJN> > But you may see it with \"use warnings;\" right?\nJN> \nJN> \"use warnings;\" pragma doesn't help, because of the 'trapping\nJN> exceptions' part.  That is why \"require <file>\" is recommended over \nJN> \"do <file>\".\nJN> Checking $@ after \"do <file>\" would cover the situation where there were\nJN> parsing errors, but wouldn't cover situation where file was not found,\nJN> or there was error in executing code (but parsing was O.K.).\n\nI just use it like many others, here are the examples of the code\nhttp://www.jmarshall.com/tools/cgiproxy/ nph-proxy.cgi:\n===\n    if ($scheme eq 'https') {\n  eval { require Net::SSLeay } ;  # don't check during compilation\n  &no_SSL_warning($URL) if $@ ;\n===\nhttp://webgui.org lib/WebGUI/HTML.pm:\n===\n  } elsif ($type eq \"thumb-if-form-thumb\") {\n      eval \"use Image::Magick;\";\n      if ($@){\n        WebGUI::ErrorHandler::warn(\"Image::Magick not loaded: \".$@);\n===\n\nare those lemmings wrong?\nBy far, people don't use to want the application should be trapped as inclusion fails and they are just sure to deal with the consequences. This is where the php is successful to offer include/include_once as well as its require* counterparters to offer such a choice to a developer.\nAre those consequences any danger anyway for applications like a gitweb?\n\nWhatever, I almost forgot to ask you again about your mysterious 'The subroutine was defined, but there was a bug in parsing included file'. Does Perl parser has a bug ( about 'bug in parsing' )? file was not included but the sub from it was successfully defined? file was about to include inside a sub but Perl reported the 'sub undefined' instead of 'file has failed to be included by the sub'? All of those seem just incredible to me ;-)\n\nJN> >> Second, \"use Module <LIST>;\" is equivalent to\nJN> >>   BEGIN { require Module; import Module <LIST>; }\nJN> >> and therefore it doesn't make sense to use it for conditional inclusion.\nJN> > \nJN> > eval() is used there.\nJN> \nJN> It's the fact that \"use Module\" uses BEGIN block that is incompatibile\nJN> with *conditional* using it from eval.\n\nit works conditionally on those excerpts above.\nAt the moment of the compilation, Perl doesn't know in general case what code should be eval()'d as its argument may vary at the runtime.\nTherefore Perl do not parse eval() string argument even if it is a constant. And thus it doesn't appear at the BEGIN{} execution moment.\nThis is e.g.,  how the FCGI::Spawn works with CGI::Fast that defines the socket in its BEGIN{}. You may define your socket communications preference, the FCGI_SOCKET_PATH,  on a shell before to start perl, or in the perl, before to eval \"use CGI::Fast;\" or eval \"use FCGI::Spawn\"; Both work just fine.\n\nJN> This convertion is \nJN> a.) compiling CGI file into subroutine (taking care of things like DATA\nJN>     filehandle) using CGI::Compile\nJN> b.) converting between CGI interface and PSGI interface, using\nJN>     CGI::Emulate::PSGI\n\nSounds to me like all of that can happen in-memory. Great!\n\nJN> Yes, it can.  Depending on request it would run appropriate\nJN> CGI-converted-to-PSGI application.\nJN> I am not sure how Plack::App::CGIBin works internally; it migh cimpile\nJN> all CGI applications upfront; but it might not.\n\nWill challenge.\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141730","messageId":"20100515115108.GT1951@machine.or.cz","threadId":"23728","inReplyTo":"201005141253.46956.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2010-05-15T11:51:09Z","receivedAt":"2010-05-15T11:51:09Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, May 14, 2010 at 12:53:42PM +0200, Jakub Narebski wrote:\n> Note also that Dijkstra wrote in seminal article \"Go To Statement\n> Considered Harmful\" that the problem with abused 'goto' is that it\n> compilcates and muddles control flow of program.  But there are\n> legitimate uses of 'goto' that make the program simpler to understand,\n> and not harder,... among those is handling exceptions.\n\nAlso, Dijkstra is well-known for statements that were intentionally\nvery radical to stir a real debate in the sleepy academic circles and\nprobably even Dijkstra was not as radical as people would think based\non some of his statements.\n\nFor another side of the goto debate, I really recommend reading the\nsomewhat dated, but still interesting paper [Donald Knuth, \"Structured\nprogramming with goto statements,\" Computing Surveys, December 1974].\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nWhen I feel like exercising, I just lie down until the feeling\ngoes away.  -- xed_over\n"},{"id":"141733","messageId":"201005151558.12191.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100515100615.GA3564@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-15T13:58:11Z","receivedAt":"2010-05-15T13:58:11Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sat, 15 May 2010, Peter Vereshagin wrote:\n> 2010/05/14 19:58:15 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n> >\n> > You don't see the parsing failure because \"do <file>;\" functions like\n> > \"eval\", which traps exceptions.  You will see consequences of parsing\n> > failure (like not defined subroutine).\n> > \n> > > But you may see it with \"use warnings;\" right?\n> > \n> > \"use warnings;\" pragma doesn't help, because of the 'trapping\n> > exceptions' part.  That is why \"require <file>\" is recommended over \n> > \"do <file>\".\n> >\n> > Checking $@ after \"do <file>\" would cover the situation where there were\n> > parsing errors, but wouldn't cover situation where file was not found,\n> > or there was error in executing code (but parsing was O.K.).\n> \n> I just use it like many others, here are the examples of the code\n> http://www.jmarshall.com/tools/cgiproxy/ nph-proxy.cgi:\n> ===\n>     if ($scheme eq 'https') {\n>   eval { require Net::SSLeay } ;  # don't check during compilation\n>   &no_SSL_warning($URL) if $@ ;\n> ===\n> http://webgui.org lib/WebGUI/HTML.pm:\n> ===\n>   } elsif ($type eq \"thumb-if-form-thumb\") {\n>       eval \"use Image::Magick;\";\n>       if ($@){\n>         WebGUI::ErrorHandler::warn(\"Image::Magick not loaded: \".$@);\n> ===\n> \n> are those lemmings wrong?\n\nNo they are not.\n\nBut there are two things.  First, there is a difference between 'eval EXPR'\nand 'eval BLOCK' form, in that 'eval EXPR' is parsed (at execution time) and\nexecuted (and is slightly slower), while 'eval BLOCK' form is parsed only\nonce, at the time code surrounding eval is parsed (and is slightly faster).\n\nThis means that while 'use' in conditional 'eval EXPR' as below\n\n  if (<condition>) {\n      eval \"use Image::Magick;\"\n      ...\n  }\n\nwould work as expected, I think that 'use' in conditional 'eval BLOCK' would\nnot.\n\n  if (<condition>) {\n      eval { use Image::Magick; }\n      ...\n  }\n\nSo if you want to use 'eval BLOCK' form, you need to use 'require' and not\n'use':\n\n  if (<condition>) {\n      eval { require Image::Magick; import Image::Magick; }\n      ...\n  }\n\n\nSecond, if you are not interested in error condition, and only whether\nrequire'ing some module failed or not, then instead of\n\n  eval { require Net::SSLeay };\n  no_SSL_warning($URL) if $@;\n\nyou can use the 'eval { <sth>; 1 };' idiom, i.e.\n\n  eval { require Net::SSLeay; 1; }\n      or no_SSL_warning($URL);\n\n[...]  \n\n> Whatever, I almost forgot to ask you again about your mysterious 'The\n> subroutine was defined, but there was a bug in parsing included file'.\n> Does Perl parser has a bug (about 'bug in parsing')?  File was not\n> included but the sub from it was successfully defined?  File was about to\n> include inside a sub but Perl reported the 'sub undefined' instead of\n> 'file has failed to be included by the sub'?  All of those seem just\n> incredible to me ;-)\n\nThe situation looked like this.  The included file (via 'do') had a few\nsubroutines in it, looking roughly like this:\n\n  use strict;\n  use warnings;\n\n  sub foo {\n     # here was a syntax error\n  }\n\n  sub bar {\n     # ...\n  }\n\n  1; # last statement in file\n\nThe main file used 'do $file;' and then tried to use 'bar' subroutine,\nlooking like this:\n\n  use strict;\n  use warnings;\n\n  do $file;\n  # no checking for $@\n\n  ...\n\n  bar();\n\nAnd there Perl gives the following error:\n\n  'Undefined subroutine &bar called'\n\nThis is caused by the fact that there was a syntax error before definition\nof foo(), and Perl didn't make it to defining foo().\n\nWhen I added checking for $@ in the form of 'die $@ if $@', the error that\nPerl shown was the syntax error in the foo() subroutine in $file file.\n\n[...]\n\n> > This convertion is \n> > a.) compiling CGI file into subroutine (taking care of things like DATA\n> >     filehandle) using CGI::Compile\n> > b.) converting between CGI interface and PSGI interface, using\n> >     CGI::Emulate::PSGI\n> \n> Sounds to me like all of that can happen in-memory. Great!\n> \n> > Yes, it can.  Depending on request it would run appropriate\n> > CGI-converted-to-PSGI application.\n> > I am not sure how Plack::App::CGIBin works internally; it migh cimpile\n> > all CGI applications upfront; but it might not.\n> \n> Will challenge.\n\nI don't know if it would be complete replacement for FCGI::Spawn, but from\nyour description of it, using Plack::App::CGIBin middleware (+ plackup +\nPlack::Handler::FCGI wrapper) could be a valid alternative to it..\n\nP.S. About Girocco: instead of writing it as set of separate CGI scripts, it\ncould have been instead written as single app, loading its modules ('use\nlib' would help).\n-- \nJakub Narebski\nPoland\n"},{"id":"141762","messageId":"20100516101528.GA5761@screwed.box","threadId":"23728","inReplyTo":"201005151558.12191.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Peter Vereshagin","fromEmail":"peter@vereshagin.org","sentAt":"2010-05-16T10:15:28Z","receivedAt":"2010-05-16T10:15:28Z","isPatch":true,"sender":{"key":"peter@vereshagin.org","avatar":"https://gravatar.com/avatar/27a92b8c80743df8621433ca040657c4ac37a78497228d04f703e70731c5f30b?d=mp&s=160"},"body":"Be sure to wear flowers on your hat, Jakub!\n2010/05/15 15:58:11 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n===\nJN> >       eval \"use Image::Magick;\";\nJN> >       if ($@){\nJN> > ===\nJN> > \nJN> > are those lemmings wrong?\nJN> \nJN> No they are not.\n\nso that code is just right, and this:\n===\neval( 'use Module;' ); die $@ if $@;\n===\n\nis 'Wrong!'. And what is the difference?\n\nJN> would work as expected, I think that 'use' in conditional 'eval BLOCK' would\nJN> not.\n\nI think so too as I did never meant about eval BLOCK;\n\nJN>   if (<condition>) {\nJN>       eval { use Image::Magick; }\nJN>       ...\nJN>   }\nJN> \nJN> So if you want to use 'eval BLOCK' form, you need to use 'require' and not\nJN> 'use':\nJN> \nJN>   if (<condition>) {\nJN>       eval { require Image::Magick; import Image::Magick; }\nJN>       ...\nJN>   }\nJN> \nJN> \nJN> Second, if you are not interested in error condition, and only whether\nJN> require'ing some module failed or not, then instead of\nJN> \nJN>   eval { require Net::SSLeay };\nJN>   no_SSL_warning($URL) if $@;\nJN> \nJN> you can use the 'eval { <sth>; 1 };' idiom, i.e.\nJN> \nJN>   eval { require Net::SSLeay; 1; }\nJN>       or no_SSL_warning($URL);\n\n'eval BLOCK' versus 'eval EXPR' it's just better, but not a tabu. 'eval EXPR'\nwith $@ checking causes no any errors on the same runtime with the code to be\nexecuted later.\nFor most cases the modules are used, the read/parsing error can be the only\nerror possible as no run-time code happens out there but only the symbols\ndeclaration.\nTherefore checking $@ is just fine.\n\nJN> When I added checking for $@ in the form of 'die $@ if $@', the error that\nJN> Perl shown was the syntax error in the foo() subroutine in $file file.\n\nand this is where the $@ was sufficient, too.\n\nJN> I don't know if it would be complete replacement for FCGI::Spawn, but from\nJN> your description of it, using Plack::App::CGIBin middleware (+ plackup +\nJN> Plack::Handler::FCGI wrapper) could be a valid alternative to it..\n\nThere are some more features those are on by default in FCGI::Spawn if they are\nto be replaced, not sure if I will find them inside that framework.\n\nJN> P.S. About Girocco: instead of writing it as set of separate CGI scripts, it\nJN> could have been instead written as single app, loading its modules ('use\nJN> lib' would help).\n\n... and sharing them with gitweb, right. ;-)\n\n73! Peter pgp: A0E26627 (4A42 6841 2871 5EA7 52AB  12F8 0CE1 4AAC A0E2 6627)\n-- \nhttp://vereshagin.org\n"},{"id":"141763","messageId":"20100516102647.GB1951@machine.or.cz","threadId":"23728","inReplyTo":"201005151558.12191.jnareb@gmail.com","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2010-05-16T10:26:47Z","receivedAt":"2010-05-16T10:26:47Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Sat, May 15, 2010 at 03:58:11PM +0200, Jakub Narebski wrote:\n> P.S. About Girocco: instead of writing it as set of separate CGI scripts, it\n> could have been instead written as single app, loading its modules ('use\n> lib' would help).\n\nThat would be a relatively trivial change given how the simple CGI\nscripts are designed. The scripts share a common model and parts of view\nalready anyway.\n\nKind regards,\n\n\t\t\t\tPetr \"Pasky\" Baudis\n"},{"id":"141849","messageId":"201005180306.27279.jnareb@gmail.com","threadId":"23728","inReplyTo":"20100516101528.GA5761@screwed.box","subject":"Re: [PATCH 0/2] gitweb: Add support for running gitweb as FastCGI script","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-05-18T01:06:25Z","receivedAt":"2010-05-18T01:06:25Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sun, 16 May 2010, Peter Vereshagin wrote:\n> 2010/05/15 15:58:11 +0200 Jakub Narebski <jnareb@gmail.com> => To Peter Vereshagin :\n\n> ===\n> > >       eval \"use Image::Magick;\";\n> > >       if ($@){\n> > > ===\n> > > \n> > > are those lemmings wrong?\n> > \n> > No they are not.\n> \n> so that code is just right, and this:\n> ===\n> eval( 'use Module;' ); die $@ if $@;\n> ===\n> \n> is 'Wrong!'. And what is the difference?\n\nWhy use\n\n  eval('use Module;'); die $@ if $@;\n\ninstead of simply\n\n  use Module;\n\nor, if it is inside conditional,\n\n  require Module; import Module;\n\nor perhaps\n\n  use if ($enable_module) Module;\n\nif you 'die', like default, anyway?\n \n> > I don't know if it would be complete replacement for FCGI::Spawn, but from\n> > your description of it, using Plack::App::CGIBin middleware (+ plackup +\n> > Plack::Handler::FCGI wrapper) could be a valid alternative to it..\n> \n> There are some more features those are on by default in FCGI::Spawn if they are\n> to be replaced, not sure if I will find them inside that framework.\n\nNote that with Plack::Middleware::Static you can serve static files, like\nstylesheets and images, too.\n\nSee Plack::Handler::FCGI manpage for details on how to configure FastCGI\nbackend for a PSGI application.\n\n> > P.S. About Girocco: instead of writing it as set of separate CGI scripts, it\n> > could have been instead written as single app, loading its modules ('use\n> > lib' would help).\n> \n> ... and sharing them with gitweb, right. ;-)\n\nWell, no.  I'd rather the Gitweb::Admin / Girocco to remain\nseparate... perhaps with gitweb / git as submodule.\n\n-- \nJakub Narebski\nPoland\n"}]}