{"thread":{"id":"25718","subject":"[PATCH/RFC] gitweb: selectable configurations that change with each request","startedAt":"2010-11-11T21:36:37Z","lastAt":"2010-11-25T18:43:59Z","messageCount":7,"participants":["Jakub Narebski","Jonathan Nieder","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"155738","messageId":"20101111213456.21127.36449.stgit@localhost.localdomain","threadId":"25718","inReplyTo":null,"subject":"[PATCH/RFC] gitweb: selectable configurations that change with each request","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-11-11T21:36:37Z","receivedAt":"2010-11-11T21:36:37Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Allow selecting whether configuration file should be (re)parsed on each\nrequest (the default, for backward compatibility with configurations that\nchange per session, see commit 7f425db (gitweb: allow configurations that\nchange with each request, 2010-07-30)), or whether should it be parsed only\nonce (for performance speedup for persistent environments, though currently\nonly FastCGI is able to make use of it, when flexibility is not important).\nYou can also have configuration file parsed only once, but have parts of\nconfiguration (re)evaluated once per each request.\n\nThis is done by introducing $per_request_config variable: if set to code\nreference, this code would be run once per request, while config file would\nbe parsed only once.  For example gitolite's contrib/gitweb/gitweb.conf\nfragment mentioned in 7f425db could be rewritten as\n\n  our $per_request_config = sub {\n  \t$ENV{GL_USER} = ($cgi && $cgi->remote_user) || \"gitweb\";\n  };\n\nto make use of this feature.\n\nIf $per_request_config is not a code reference, it is taken to be boolean\nvariable, to choose between running config file for each request\n(flexibility), and running config file only once (performance in\npersistent environments).\n\nThe default value for $per_request_config is 1 (true), which means that\nold configuration that require to change per session (like gitolite's)\nwill keep working.\n\n\nBecause there is a call to evaluate_gitweb_config() in the run() subroutine\n(the call in run_config() is not invoked at first request to avoid double\nrunning it), therefore evaluate_git_version() could be moved back there, and\nis now evaluated only once.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nCommit 7f425db914 says: \n\n    Probably in the end there should be a way to specify in the\n    configuration whether a particular installation wants the speedup or\n    the flexibility.  But for now it is easier to just undo the relevant\n    change.\n\nThis is the way... well, at least a proposal.\n\n gitweb/README      |    7 +++++++\n gitweb/gitweb.perl |   23 +++++++++++++++++++++--\n 2 files changed, 28 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/README b/gitweb/README\nindex bf3664f..6646fda 100644\n--- a/gitweb/README\n+++ b/gitweb/README\n@@ -246,6 +246,13 @@ not include variables usually directly set during build):\n    http://www.andre-simon.de due to assumptions about parameters and output).\n    Useful if highlight is not installed on your webserver's PATH.\n    [Default: highlight]\n+ * $per_request_config\n+   If set to code reference, it would be run once per each request.  You can\n+   set parts of configuration that change per session, e.g. by setting it to\n+     sub { $ENV{GL_USER} = $cgi->remote_user || \"gitweb\"; }\n+   Otherwise it is treated as boolean value: if true gitweb would process\n+   config file once per request, if false it would process config file only\n+   once.  The default is true.\n \n Projects list file format\n ~~~~~~~~~~~~~~~~~~~~~~~~~\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 7dbaf0c..c3cfefb 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -599,6 +599,14 @@ sub filter_snapshot_fmts {\n \t\t!$known_snapshot_formats{$_}{'disabled'}} @fmts;\n }\n \n+# If it is set to code reference, it is code that it is to be run once per\n+# request, allowing updating configurations that change with each request,\n+# while running other code in config file only once.\n+#\n+# Otherwise, if it is false then gitweb would process config file only once;\n+# if it is true then gitweb config would be run for each request.\n+our $per_request_config = 1;\n+\n our ($GITWEB_CONFIG, $GITWEB_CONFIG_SYSTEM);\n sub evaluate_gitweb_config {\n \tour $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || \"++GITWEB_CONFIG++\";\n@@ -1068,12 +1076,18 @@ sub reset_timer {\n \tour $number_of_git_cmds = 0;\n }\n \n+our $first_request = 1;\n sub run_request {\n \treset_timer();\n \n \tevaluate_uri();\n-\tevaluate_gitweb_config();\n-\tevaluate_git_version();\n+\tif ($per_request_config) {\n+\t\tif (ref($per_request_config) eq 'CODE') {\n+\t\t\t$per_request_config->();\n+\t\t} elsif (!$first_request) {\n+\t\t\tevaluate_gitweb_config();\n+\t\t}\n+\t}\n \tcheck_loadavg();\n \n \t# $projectroot and $projects_list might be set in gitweb config file\n@@ -1126,6 +1140,10 @@ sub evaluate_argv {\n \n sub run {\n \tevaluate_argv();\n+\tevaluate_gitweb_config();\n+\tevaluate_git_version();\n+\n+\t$first_request = 1;\n \n \t$pre_listen_hook->()\n \t\tif $pre_listen_hook;\n@@ -1139,6 +1157,7 @@ sub run {\n \n \t\t$post_dispatch_hook->()\n \t\t\tif $post_dispatch_hook;\n+\t\t$first_request = 0;\n \n \t\tlast REQUEST if ($is_last_request->());\n \t}\n"},{"id":"155739","messageId":"20101111214250.GA27048@burratino","threadId":"25718","inReplyTo":"20101111213456.21127.36449.stgit@localhost.localdomain","subject":"Re: [PATCH/RFC] gitweb: selectable configurations that change with each request","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-11T21:42:50Z","receivedAt":"2010-11-11T21:42:50Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jakub Narebski wrote:\n\n> This is done by introducing $per_request_config variable: if set to code\n> reference, this code would be run once per request, while config file would\n> be parsed only once.  For example gitolite's contrib/gitweb/gitweb.conf\n> fragment mentioned in 7f425db could be rewritten as\n> \n>   our $per_request_config = sub {\n>   \t$ENV{GL_USER} = ($cgi && $cgi->remote_user) || \"gitweb\";\n>   };\n> \n> to make use of this feature.\n> \n> If $per_request_config is not a code reference, it is taken to be boolean\n> variable, to choose between running config file for each request\n> (flexibility), and running config file only once (performance in\n> persistent environments).\n> \n> The default value for $per_request_config is 1 (true)\n\nFlexible, fast, backward-compatible.  Nice.\n"},{"id":"156490","messageId":"7vhbf6txi9.fsf@alter.siamese.dyndns.org","threadId":"25718","inReplyTo":"20101111213456.21127.36449.stgit@localhost.localdomain","subject":"Re: [PATCH/RFC] gitweb: selectable configurations that change with each request","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-11-24T17:57:50Z","receivedAt":"2010-11-24T17:57:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> The default value for $per_request_config is 1 (true), which means that\n> old configuration that require to change per session (like gitolite's)\n> will keep working.\n>\n> Because there is a call to evaluate_gitweb_config() in the run() subroutine\n> (the call in run_config() is not invoked at first request to avoid double\n> running it), therefore evaluate_git_version() could be moved back there, and\n> is now evaluated only once.\n>\n> Signed-off-by: Jakub Narebski <jnareb@gmail.com>\n\nI like the \"we can keep the old behaviour by default, but you can go\nfancier if you wanted to\" attitude of this patch.\n\nI however am not sure if this particular implementation is regression\nfree.  People who wanted the per-request configuration used to be able to\naccess what evaluate_uri() did while running evaluate_gitweb_config(),\nwhich in turn means that their custom configuration could take things like\nmy-url and path-info into account, but now for the first invocation they\ncannot.  It probably is just the matter of moving some code around from\ntheir old custom gitweb-config to a per_request_config sub they need to\nwrite and point $per_request_config variable at, but that makes \"setting 1\nwill keep the old behaviour\" a false promise, no?\n\n> @@ -1068,12 +1076,18 @@ sub reset_timer {\n>  \tour $number_of_git_cmds = 0;\n>  }\n>  \n> +our $first_request = 1;\n>  sub run_request {\n>  \treset_timer();\n>  \n>  \tevaluate_uri();\n> -\tevaluate_gitweb_config();\n> -\tevaluate_git_version();\n> +\tif ($per_request_config) {\n> +\t\tif (ref($per_request_config) eq 'CODE') {\n> +\t\t\t$per_request_config->();\n> +\t\t} elsif (!$first_request) {\n> +\t\t\tevaluate_gitweb_config();\n> +\t\t}\n> +\t}\n>  \tcheck_loadavg();\n>  \n>  \t# $projectroot and $projects_list might be set in gitweb config file\n> @@ -1126,6 +1140,10 @@ sub evaluate_argv {\n>  \n>  sub run {\n>  \tevaluate_argv();\n> +\tevaluate_gitweb_config();\n> +\tevaluate_git_version();\n> +\n> +\t$first_request = 1;\n>  \n>  \t$pre_listen_hook->()\n>  \t\tif $pre_listen_hook;\n> @@ -1139,6 +1157,7 @@ sub run {\n>  \n>  \t\t$post_dispatch_hook->()\n>  \t\t\tif $post_dispatch_hook;\n> +\t\t$first_request = 0;\n>  \n>  \t\tlast REQUEST if ($is_last_request->());\n>  \t}\n"},{"id":"156507","messageId":"201011242243.20545.jnareb@gmail.com","threadId":"25718","inReplyTo":"7vhbf6txi9.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH/RFC] gitweb: selectable configurations that change with each request","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-11-24T21:43:20Z","receivedAt":"2010-11-24T21:43:20Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Wed, 24 Nov 2010, Junio C Hamano wrote:\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n> > The default value for $per_request_config is 1 (true), which means that\n> > old configuration that require to change per session (like gitolite's)\n> > will keep working.\n> >\n> > Because there is a call to evaluate_gitweb_config() in the run() subroutine\n> > (the call in run_config() is not invoked at first request to avoid double\n> > running it), therefore evaluate_git_version() could be moved back there, and\n> > is now evaluated only once.\n> >\n> > Signed-off-by: Jakub Narebski <jnareb@gmail.com>\n> \n> I like the \"we can keep the old behaviour by default, but you can go\n> fancier if you wanted to\" attitude of this patch.\n\nThanks.\n\n> I however am not sure if this particular implementation is regression\n> free.  People who wanted the per-request configuration used to be able to\n> access what evaluate_uri() did while running evaluate_gitweb_config(),\n> which in turn means that their custom configuration could take things like\n> my-url and path-info into account, but now for the first invocation they\n> cannot.  It probably is just the matter of moving some code around from\n> their old custom gitweb-config to a per_request_config sub they need to\n> write and point $per_request_config variable at, but that makes \"setting 1\n> will keep the old behaviour\" a false promise, no?\n\nThanks for catching this; I forgot to take into account the fact that\ngitweb config changing with request would need request-related variables.\n\nSo instead of code flow looking like this\n\n  evaluate_gitweb_config();\n  $first_request = 1;\n\n  while (...) {\n\n  \tif ($per_request_config) {\n\t\tif (ref($per_request_config) eq 'CODE') {\n\t\t\t$per_request_config->();\n\t\t} elsif (!$first_request) {\n\t\t\tevaluate_gitweb_config();\n\t\t}\n\t}\n\n\t$first_request = 0;\n\n  }\n\n\nwe would move to\n\n  $first_request = 1;\n  while (...) {\n\n  \tif ($first_request) {\n\t\tevaluate_gitweb_config();\n\t} elsif ($per_request_config) {\n\t\tif (ref($per_request_config) eq 'CODE') {\n\t\t\t$per_request_config->();\n\t\t} else {\n  \t\t\tevaluate_gitweb_config();\n  \t\t}\n\t}\n\t$first_request = 0;\n\n  }\n\n\nI'll send new version soon.\n\n\nP.S. if we could assume that nobody ever edits gitweb.cgi directly\nto set $per_request_config to non-default value, we could probably\nget rid of $first_request variable...\n \n> > @@ -1068,12 +1076,18 @@ sub reset_timer {\n> >  \tour $number_of_git_cmds = 0;\n> >  }\n> >  \n> > +our $first_request = 1;\n> >  sub run_request {\n> >  \treset_timer();\n> >  \n> >  \tevaluate_uri();\n> > -\tevaluate_gitweb_config();\n> > -\tevaluate_git_version();\n> > +\tif ($per_request_config) {\n> > +\t\tif (ref($per_request_config) eq 'CODE') {\n> > +\t\t\t$per_request_config->();\n> > +\t\t} elsif (!$first_request) {\n> > +\t\t\tevaluate_gitweb_config();\n> > +\t\t}\n> > +\t}\n> >  \tcheck_loadavg();\n> >  \n> >  \t# $projectroot and $projects_list might be set in gitweb config file\n> > @@ -1126,6 +1140,10 @@ sub evaluate_argv {\n> >  \n> >  sub run {\n> >  \tevaluate_argv();\n> > +\tevaluate_gitweb_config();\n> > +\tevaluate_git_version();\n> > +\n> > +\t$first_request = 1;\n> >  \n> >  \t$pre_listen_hook->()\n> >  \t\tif $pre_listen_hook;\n> > @@ -1139,6 +1157,7 @@ sub run {\n> >  \n> >  \t\t$post_dispatch_hook->()\n> >  \t\t\tif $post_dispatch_hook;\n> > +\t\t$first_request = 0;\n> >  \n> >  \t\tlast REQUEST if ($is_last_request->());\n> >  \t}\n> \n\n-- \nJakub Narebski\nPoland\n"},{"id":"156546","messageId":"201011251318.31235.jnareb@gmail.com","threadId":"25718","inReplyTo":"201011242243.20545.jnareb@gmail.com","subject":"[PATCHv2] gitweb: selectable configurations that change with each request","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-11-25T12:18:28Z","receivedAt":"2010-11-25T12:18:28Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Allow selecting whether configuration file should be (re)parsed on each\nrequest (the default, for backward compatibility with configurations that\nchange per session, see commit 7f425db (gitweb: allow configurations that\nchange with each request, 2010-07-30)), or whether should it be parsed only\nonce (for performance speedup for persistent environments, though currently\nonly FastCGI is able to make use of it, when flexibility is not important).\n\nYou can also have configuration file parsed only once, but have parts of\nconfiguration (re)evaluated once per each request.\n\nThis is done by introducing $per_request_config variable: if set to code\nreference, this code would be run once per request, while config file would\nbe parsed only once.  For example gitolite's contrib/gitweb/gitweb.conf\nfragment mentioned in 7f425db could be rewritten as\n\n  our $per_request_config = sub {\n  \t$ENV{GL_USER} = ($cgi && $cgi->remote_user) || \"gitweb\";\n  };\n\nto make use of this feature.\n\nIf $per_request_config is not a code reference, it is taken to be boolean\nvariable, to choose between running config file for each request\n(flexibility), and running config file only once (performance in\npersistent environments).\n\nThe default value for $per_request_config is 1 (true), which means that\nold configuration that require to change per session (like gitolite's)\nwill keep working.\n\n\nWhile at it, make it so evaluate_git_version() is run only once.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nOn Wed, 24 Nov 2010, Jakub Narebski wrote:\n\n> I'll send new version soon.\n> \n\nAnd here it is, rebased on top of current 'master'.\n\n gitweb/README      |    7 +++++++\n gitweb/gitweb.perl |   23 +++++++++++++++++++++--\n 2 files changed, 28 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/README b/gitweb/README\nindex bf3664f..6646fda 100644\n--- a/gitweb/README\n+++ b/gitweb/README\n@@ -246,6 +246,13 @@ not include variables usually directly set during build):\n    http://www.andre-simon.de due to assumptions about parameters and output).\n    Useful if highlight is not installed on your webserver's PATH.\n    [Default: highlight]\n+ * $per_request_config\n+   If set to code reference, it would be run once per each request.  You can\n+   set parts of configuration that change per session, e.g. by setting it to\n+     sub { $ENV{GL_USER} = $cgi->remote_user || \"gitweb\"; }\n+   Otherwise it is treated as boolean value: if true gitweb would process\n+   config file once per request, if false it would process config file only\n+   once.  The default is true.\n \n Projects list file format\n ~~~~~~~~~~~~~~~~~~~~~~~~~\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 7dbaf0c..ac38a92 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -599,6 +599,14 @@ sub filter_snapshot_fmts {\n \t\t!$known_snapshot_formats{$_}{'disabled'}} @fmts;\n }\n \n+# If it is set to code reference, it is code that it is to be run once per\n+# request, allowing updating configurations that change with each request,\n+# while running other code in config file only once.\n+#\n+# Otherwise, if it is false then gitweb would process config file only once;\n+# if it is true then gitweb config would be run for each request.\n+our $per_request_config = 1;\n+\n our ($GITWEB_CONFIG, $GITWEB_CONFIG_SYSTEM);\n sub evaluate_gitweb_config {\n \tour $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || \"++GITWEB_CONFIG++\";\n@@ -1068,12 +1076,21 @@ sub reset_timer {\n \tour $number_of_git_cmds = 0;\n }\n \n+our $first_request = 1;\n sub run_request {\n \treset_timer();\n \n \tevaluate_uri();\n-\tevaluate_gitweb_config();\n-\tevaluate_git_version();\n+\tif ($first_request) {\n+\t\tevaluate_gitweb_config();\n+\t\tevaluate_git_version();\n+\t} elsif ($per_request_config) {\n+\t\tif (ref($per_request_config) eq 'CODE') {\n+\t\t\t$per_request_config->();\n+\t\t} else {\n+\t\t\tevaluate_gitweb_config();\n+\t\t}\n+\t}\n \tcheck_loadavg();\n \n \t# $projectroot and $projects_list might be set in gitweb config file\n@@ -1127,6 +1144,7 @@ sub evaluate_argv {\n sub run {\n \tevaluate_argv();\n \n+\t$first_request = 1;\n \t$pre_listen_hook->()\n \t\tif $pre_listen_hook;\n \n@@ -1139,6 +1157,7 @@ sub run {\n \n \t\t$post_dispatch_hook->()\n \t\t\tif $post_dispatch_hook;\n+\t\t$first_request = 0;\n \n \t\tlast REQUEST if ($is_last_request->());\n \t}\n-- \n1.7.3\n"},{"id":"156566","messageId":"20101125182314.GA17261@burratino","threadId":"25718","inReplyTo":"201011251318.31235.jnareb@gmail.com","subject":"Re: [PATCHv2] gitweb: selectable configurations that change with each request","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-25T18:23:14Z","receivedAt":"2010-11-25T18:23:14Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jakub Narebski wrote:\n\n> --- a/gitweb/gitweb.perl\n> +++ b/gitweb/gitweb.perl\n[...]\n> @@ -1068,12 +1076,21 @@ sub reset_timer {\n>  \tour $number_of_git_cmds = 0;\n>  }\n>  \n> +our $first_request = 1;\n>  sub run_request {\n>  \treset_timer();\n>  \n>  \tevaluate_uri();\n> -\tevaluate_gitweb_config();\n> -\tevaluate_git_version();\n> +\tif ($first_request) {\n> +\t\tevaluate_gitweb_config();\n> +\t\tevaluate_git_version();\n> +\t} elsif ($per_request_config) {\n> +\t\tif (ref($per_request_config) eq 'CODE') {\n> +\t\t\t$per_request_config->();\n> +\t\t} else {\n> +\t\t\tevaluate_gitweb_config();\n> +\t\t}\n> +\t}\n\nShould per_request_config() be run for the first request, too?  Maybe:\n\n\tif ($first_request) {\n\t\tevaluate_gitweb_config();\n\t\tevaluate_git_version();\n\t}\n\tif ($per_request_config) {\n\t\tif (ref($per_request_config) eq 'CODE') {\n\t\t\t$per_request_config->();\n\t\t} elsif (!$first_request) {\n\t\t\tevaluate_gitweb_config();\n\t\t}\n\t}\n"},{"id":"156567","messageId":"201011251944.01423.jnareb@gmail.com","threadId":"25718","inReplyTo":"20101125182314.GA17261@burratino","subject":"[PATCHv3] gitweb: selectable configurations that change with each request","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-11-25T18:43:59Z","receivedAt":"2010-11-25T18:43:59Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Allow selecting whether configuration file should be (re)parsed on each\nrequest (the default, for backward compatibility with configurations that\nchange per session, see commit 7f425db (gitweb: allow configurations that\nchange with each request, 2010-07-30)), or whether should it be parsed only\nonce (for performance speedup for persistent environments, though currently\nonly FastCGI is able to make use of it, when flexibility is not important).\n\nYou can also have configuration file parsed only once, but have parts of\nconfiguration (re)evaluated once per each request.\n\nThis is done by introducing $per_request_config variable: if set to code\nreference, this code would be run once per request, while config file would\nbe parsed only once.  For example gitolite's contrib/gitweb/gitweb.conf\nfragment mentioned in 7f425db could be rewritten as\n\n  our $per_request_config = sub {\n  \t$ENV{GL_USER} = ($cgi && $cgi->remote_user) || \"gitweb\";\n  };\n\nto make use of this feature.\n\nIf $per_request_config is not a code reference, it is taken to be boolean\nvariable, to choose between running config file for each request\n(flexibility), and running config file only once (performance in\npersistent environments).\n\nThe default value for $per_request_config is 1 (true), which means that\nold configuration that require to change per session (like gitolite's)\nwill keep working.\n\n\nWhile at it, make it so evaluate_git_version() is run only once.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nOn Thu, 25 Nov 2010, Jonathan Nieder wrote:\n> Should per_request_config() be run for the first request, too?  Maybe:\n> \n>         if ($first_request) {\n>                 evaluate_gitweb_config();\n>                 evaluate_git_version();\n>         }\n>         if ($per_request_config) {\n>                 if (ref($per_request_config) eq 'CODE') {\n>                         $per_request_config->();\n>                 } elsif (!$first_request) {\n>                         evaluate_gitweb_config();\n>                 }\n>         }\n\nYou are right, thanks for pointing that out.  I'm sorry for my mistake.\n\n gitweb/README      |    7 +++++++\n gitweb/gitweb.perl |   24 ++++++++++++++++++++++--\n 2 files changed, 29 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/README b/gitweb/README\nindex bf3664f..6646fda 100644\n--- a/gitweb/README\n+++ b/gitweb/README\n@@ -246,6 +246,13 @@ not include variables usually directly set during build):\n    http://www.andre-simon.de due to assumptions about parameters and output).\n    Useful if highlight is not installed on your webserver's PATH.\n    [Default: highlight]\n+ * $per_request_config\n+   If set to code reference, it would be run once per each request.  You can\n+   set parts of configuration that change per session, e.g. by setting it to\n+     sub { $ENV{GL_USER} = $cgi->remote_user || \"gitweb\"; }\n+   Otherwise it is treated as boolean value: if true gitweb would process\n+   config file once per request, if false it would process config file only\n+   once.  The default is true.\n \n Projects list file format\n ~~~~~~~~~~~~~~~~~~~~~~~~~\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 7dbaf0c..1d94718 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -599,6 +599,14 @@ sub filter_snapshot_fmts {\n \t\t!$known_snapshot_formats{$_}{'disabled'}} @fmts;\n }\n \n+# If it is set to code reference, it is code that it is to be run once per\n+# request, allowing updating configurations that change with each request,\n+# while running other code in config file only once.\n+#\n+# Otherwise, if it is false then gitweb would process config file only once;\n+# if it is true then gitweb config would be run for each request.\n+our $per_request_config = 1;\n+\n our ($GITWEB_CONFIG, $GITWEB_CONFIG_SYSTEM);\n sub evaluate_gitweb_config {\n \tour $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || \"++GITWEB_CONFIG++\";\n@@ -1068,12 +1076,22 @@ sub reset_timer {\n \tour $number_of_git_cmds = 0;\n }\n \n+our $first_request = 1;\n sub run_request {\n \treset_timer();\n \n \tevaluate_uri();\n-\tevaluate_gitweb_config();\n-\tevaluate_git_version();\n+\tif ($first_request) {\n+\t\tevaluate_gitweb_config();\n+\t\tevaluate_git_version();\n+\t}\n+\tif ($per_request_config) {\n+\t\tif (ref($per_request_config) eq 'CODE') {\n+\t\t\t$per_request_config->();\n+\t\t} elsif (!$first_request) {\n+\t\t\tevaluate_gitweb_config();\n+\t\t}\n+\t}\n \tcheck_loadavg();\n \n \t# $projectroot and $projects_list might be set in gitweb config file\n@@ -1127,6 +1145,7 @@ sub evaluate_argv {\n sub run {\n \tevaluate_argv();\n \n+\t$first_request = 1;\n \t$pre_listen_hook->()\n \t\tif $pre_listen_hook;\n \n@@ -1139,6 +1158,7 @@ sub run {\n \n \t\t$post_dispatch_hook->()\n \t\t\tif $post_dispatch_hook;\n+\t\t$first_request = 0;\n \n \t\tlast REQUEST if ($is_last_request->());\n \t}\n-- \n1.7.3\n"}]}