Accessing environment variables prior to invoking the contenthandler.
Hi Group, I have a need to access all the %ENV (cgi,mod_perl sent by the client) variables prior to invoking the content handler. I am using the modperl environment by running the cgi scripts under Perl::Registry. I wish to use the PerlTransHandler to check if the request for page A has orginated from page B. If it did then redirect to page C. I have used the following code in the in my handler and I still do not get the values. This was recommended by the Writing Apache Modules by Doug M and Lincoln S. sub handler { my $r=shift; my $env=$r-subprocess_env; %ENV=%$senv; my $referer=$ENV{'HTTP_REFERER'}; x } Thank you for the help in advance. Mark
Re: Accessing environment variables prior to invoking the contenthandler.
On Thu, 2003-07-31 at 15:44, Mark Deepak Puttnam wrote: I have used the following code in the in my handler and I still do not get the values. Do you get anything at all? HTTP_REFERER is not always sent by browsers. - Perrin
Accessing environment variables prior to invoking thecontenthandler.
Only PERL_SEND_HEADER=On. No other env. variables. I did run tests by clicking on links to check to see if the HTTP_REFERER is being set. Mark.
Re: Accessing environment variables prior to invoking thecontenthandler.
On Thu, 2003-07-31 at 16:15, Mark Deepak Puttnam wrote: Only PERL_SEND_HEADER=On. No other env. variables. And you haven't turned off PerlSetupEnv in your httpd.conf? - Perrin
Re: Accessing environment variables prior to invoking the contenthandler.
On Thu, 2003-07-31 at 15:44, Mark Deepak Puttnam wrote: sub handler { my $r=shift; my $env=$r-subprocess_env; %ENV=%$senv; my $referer=$ENV{'HTTP_REFERER'}; x } Come to think of it, you should just use the Apache API for this: my $referer = $r-header_in(Referer); - Perrin
Accessing environment variables prior to invoking the contenthandler.
I did not have that directive in my config before. But now,I set it explicitly to PerlSetupEnv On , still no env variables other than the PERL_SEND_HEADER=On. Mark
Accessing environment variables prior to invoking thecontenthandler.
Hi Perrin, my $referer = $r-header_in(Referer); Thanks, the above statement did give me the value. Mark
Database Connections Global Variables
Hello, I have a question. If I have a $dbh global variable in a particular module that I 'use'. I know that Apache::DBI will give a cached connection to the module to use. But what if I do something like $dbh-commit(); Is it possible that I am committing data for another session by accident? Any thoughts on this are appreciated. (Including RTFM (but tell me where in the FMTR)) Cheers, Levon Barker attachment: winmail.dat
Re: Database Connections Global Variables
On Fri, 2003-07-25 at 14:55, Levon Barker wrote: If I have a $dbh global variable in a particular module that I 'use'. I know that Apache::DBI will give a cached connection to the module to use. There is no need to use a global. Apache::DBI caches it for you. If you put it in a global, then Apache::DBI doesn't get to do its ping. But what if I do something like $dbh-commit(); Is it possible that I am committing data for another session by accident? At the end of each request, Apache::DBI issues a rollback for any uncommitted transactions. That means that the only things that could be committed are things that you did earlier in the current request. And remember, these are not shared between processes, so there's no need to be worried about interference from other requests. - Perrin
Variables
In this project I'm making (database), I have several variables with a potential for a large amount of information to be held in them. They're all hashes. Some are hashes of hashes... There is a tech_list, which holds information about each technician. There is a queue_list which holds an ID and a queue name (to interact with a db) There is a list of ISP's (we're the help desk for 3, and constantly looking for more) There is a list of service plans (dialup, 256k/512k/768k dsl..) There is a list of operating systems.. A list of browsers... All the lists have an ID component and a name component, so it's used in the context of DEFANGED_select name=osDEFANGED_option value=$_$list{$_}/DEFANGED_option/DEFANGED_select (where $_ is the current iteration of a foreach loop and everything in the option tags is created as it iterates...) Is there a way I could get these variables populated on server start and never loaded again unless the database was changed? So in my subroutine for posting an event that changed it I could call repopulate_queue_hash and have it redo the hash, so changes still happened without a restart, but the hash itself is just passed from the root apache process to the children? I know this means that each child would retain the old hash util it died and another one respawned, meaning some people would see the change and others wouldn't until it fully propogated, but I can make that happen easily enough by decreasing the number of requests per child... I know that happens at some performance loss, but I think the loss of performance in Apache would be less than the loss of performance generating the same hash over and over again, which will grow to be huge after time. Consider 350 users using this thing for a solid 16 hours a day, and a hundred or so using it the other 8. Thanks Dennis
Re: Variables
Dennis Stout wrote: Is there a way I could get these variables populated on server start and never loaded again unless the database was changed? So in my subroutine for posting an event that changed it I could call repopulate_queue_hash and have it redo the hash, so changes still happened without a restart, but the hash itself is just passed from the root apache process to the children? You can load it into globals at startup and their values will be shared by all children until you write to them. You could also load it separately in each child process in the init hook. However, you'd probably be better off using MLDBM::Sync, so that all changes are shared immediately. It's quite fast, and since it uses a tied interface it would be easy to switch your code to use globals if it turns out not be fast enough. - Perrin
Re: Variables
Is there a way I could get these variables populated on server start and never loaded again unless the database was changed? So in my subroutine for posting an event that changed it I could call repopulate_queue_hash and have it redo the hash, so changes still happened without a restart, but the hash itself is just passed from the root apache process to the children? You can load it into globals at startup and their values will be shared by all children until you write to them. You could also load it So in startup.perl put my %queue_list = list_queues; my %tech_list = list_techs; and so on? Then each process would get a copy of the hash? separately in each child process in the init hook. However, you'd If I did that, then I'd want a few children processes at a time and also with a few amount of requests per child... Boy am I ever glad this'll be moved off my box once it's finsihed ;) probably be better off using MLDBM::Sync, so that all changes are shared immediately. It's quite fast, and since it uses a tied interface it would be easy to switch your code to use globals if it turns out not be fast enough. After reading the perldoc for MLDBM, and reviewing my deadline for the project of today, I think I'll just use globals for now. But once I meet get the management satisified, I'll be moved into a enhancment phase of hte project, instead of a devel phase, and I'll implement it then to see how well it works. Thanks :)
Re: Variables
Dennis Stout wrote: So in startup.perl put my %queue_list = list_queues; my %tech_list = list_techs; and so on? Then each process would get a copy of the hash? No, those are lexicals, not globals. Something like this: package MyCompany::Globals; use vars qw(%queue_list %tech_list); %queue_list = list_queues; %tech_list = list_techs; Then from other code you can use them as %MyCompany::Globals::queue_list. After reading the perldoc for MLDBM, and reviewing my deadline for the project of today, I think I'll just use globals for now. MLDBM::Sync is really easy to use, but if its okay for the data to be out of date then the globals thing is fine. I suggest you avoid shenanigans with killing off processes quickly, since your performance would be terrible. Instead, create a cleanup handler which runs after each request. Keep a timestamp (a global variable that will persist) in each handler of how long it's been since you last updated the data. If it's longer than 5 minutes, refresh the data. The cleanup handler runs after the client is disconnected, so it doesn't matter if it takes a few seconds. - Perrin
getting *any* variables out of the server environment
I'm not able to get *any* variables out from the apache server environment. As you might be able to imagine, this is extremely frustrating, and inhibits my ability to do anything of use with mod_perl. My basic technique has been: my $uri = $r-uri; return unless $r-is_main(); my $subr = $r-lookup_uri($uri); my $apachecertcomp = $subr-subprocess_env($certcomponent); But this doesn't work. I also tried my $var = $r-subprocess_env(VARIABLE_NAME); And this does not work either. I really need to be able to use environment variables that mod_ssl sets in my authentication handler. Any ideas? Thanks! --Ryan
Re: getting *any* variables out of the server environment
On Mon, 2003-06-09 at 14:29, Ryan Muldoon wrote: I'm not able to get *any* variables out from the apache server environment. Did you try the normal $ENV{'VARIABLE'} approach? - Perrin
Re: getting *any* variables out of the server environment
I tried that as well (and just re-tried). My understanding is that the %ENV hash only gets updated in the fixup stage, so the mod_ssl environment variables can't be accessed that way. Thanks for the suggestion though! --Ryan On Mon, 2003-06-09 at 13:41, Perrin Harkins wrote: On Mon, 2003-06-09 at 14:29, Ryan Muldoon wrote: I'm not able to get *any* variables out from the apache server environment. Did you try the normal $ENV{'VARIABLE'} approach? - Perrin
RE: getting *any* variables out of the server environment
IF you're using mp2...in your httpd.conf are you setting up the handlers with modperl or perl-script? The former doesn't provide any environment variables: http://perl.apache.org/docs/2.0/user/config/config.html#C_SetHandler_ I don't believe this applies to mp1. mma -Original Message- From: Ryan Muldoon [mailto:[EMAIL PROTECTED] Sent: Monday, June 09, 2003 11:30 AM To: [EMAIL PROTECTED] Subject: getting *any* variables out of the server environment I'm not able to get *any* variables out from the apache server environment. As you might be able to imagine, this is extremely frustrating, and inhibits my ability to do anything of use with mod_perl. My basic technique has been: my $uri = $r-uri; return unless $r-is_main(); my $subr = $r-lookup_uri($uri); my $apachecertcomp = $subr-subprocess_env($certcomponent); But this doesn't work. I also tried my $var = $r-subprocess_env(VARIABLE_NAME); And this does not work either. I really need to be able to use environment variables that mod_ssl sets in my authentication handler. Any ideas? Thanks! --Ryan
RE: getting *any* variables out of the server environment
I'm using mod_perl 1. But I'm setting the handlers in httpd.conf. I sent a message to the list on thursday (problem with pulling variables from mod_ssl) that more fully describes my situtation. --Ryan On Mon, 2003-06-09 at 14:31, Marc M. Adkins wrote: IF you're using mp2...in your httpd.conf are you setting up the handlers with modperl or perl-script? The former doesn't provide any environment variables: http://perl.apache.org/docs/2.0/user/config/config.html#C_SetHandler_ I don't believe this applies to mp1. mma -Original Message- From: Ryan Muldoon [mailto:[EMAIL PROTECTED] Sent: Monday, June 09, 2003 11:30 AM To: [EMAIL PROTECTED] Subject: getting *any* variables out of the server environment I'm not able to get *any* variables out from the apache server environment. As you might be able to imagine, this is extremely frustrating, and inhibits my ability to do anything of use with mod_perl. My basic technique has been: my $uri = $r-uri; return unless $r-is_main(); my $subr = $r-lookup_uri($uri); my $apachecertcomp = $subr-subprocess_env($certcomponent); But this doesn't work. I also tried my $var = $r-subprocess_env(VARIABLE_NAME); And this does not work either. I really need to be able to use environment variables that mod_ssl sets in my authentication handler. Any ideas? Thanks! --Ryan
Re: getting *any* variables out of the server environment
On Mon, 2003-06-09 at 14:49, Ryan Muldoon wrote: I tried that as well (and just re-tried). My understanding is that the %ENV hash only gets updated in the fixup stage, so the mod_ssl environment variables can't be accessed that way. Thanks for the suggestion though! Okay. And you're certain that a simple $r-subprocess_env('VARIABLE') doesn't work? Have you tried setting a variable yourself as a test with PerlSetEnv in httpd.conf? - Perrin
Re: getting *any* variables out of the server environment
Geoffrey, Thanks for the explanation. Unfortunately, I think I am still a little unclear as to how to proceed. If I understand you correctly, my first method is completely wrongheaded. (I tried this because it is how the Writing Apache Modules with Perl and C does it. p.327) So it sounds like the second way is the appropriate usage for subprocess_env(). But it seems like you're saying that I shouldn't be using that at all. Specifically, here is what I'd like to get out of the environment: SSL_CLIENT_S_DN_CN SSL_CLIENT_S_DN_O and things of that nature. According to mod_ssl's documentation, these are put in ENV upon processing of a client certificate. Ideally, I'd like to make which fields to extract configurable, so I don't want to hard-code. Currently, I have PerlPassEnv SSL_CLIENT_S_DN_O PerlPassEnv SSL_CLIENT_S_DN_CN in my httpd.conf, but it doesn't seem to make any kind of difference. To make sure it isn't just mod_ssl being lame for some reason, I've tried it with DOCUMENT_ROOT and other standard ENV variables. But to no avail. :( --Ryan On Mon, 2003-06-09 at 13:59, Geoffrey Young wrote: Ryan Muldoon wrote: I'm not able to get *any* variables out from the apache server environment. ok, first off, this is a two step process for Apache. the first step is that modules (like mod_ssl) populate the subprocess_env table with various values. then, modules like mod_cgi and mod_perl come along and populate %ENV with the values from subprocess_env as well as various other CGI specific variables (like DOCUMENT_ROOT or whatever else there is). the point is that you're really not after environment variables if you want to test for something like $r-subprocess_env('HTTPS') - that it ends up as $ENV{HTTPS} is a byproduct of modules like mod_cgi and mod_perl. just for your own edification :) As you might be able to imagine, this is extremely frustrating, and inhibits my ability to do anything of use with mod_perl. My basic technique has been: my $uri = $r-uri; return unless $r-is_main(); my $subr = $r-lookup_uri($uri); my $apachecertcomp = $subr-subprocess_env($certcomponent); I don't understand the need for a subrequest to the same URI - subprocess_env has nothing to do with an actual subprocess. each request (including subrequests) have their own subprocess_env table attached to $r. in many cases, modules are coded to behave differently for subrequests than for the main request, so something you may see in $r-subprocess_env() could not be in $r-lookup_uri($uri)-subprocess_env(). But this doesn't work. I also tried my $var = $r-subprocess_env(VARIABLE_NAME); And this does not work either. I really need to be able to use environment variables that mod_ssl sets in my authentication handler. a few things here too. for the reasons described above, subprocess_env() is not a substitute for %ENV, so if what you want is a true %ENV value (such as those from PerlPassEnv), you will not be able to get to it via $r-subprocess_env(). Any ideas? Thanks! HTH --Geoff
Re: getting *any* variables out of the server environment
PerlSetEnv works fine. I can't, however, put PerlPassEnv inside either a Location or Directory block, if that makes any difference. Apache says it is a configuration error to do so (though PerlSetEnv works fine). I've tried every way that I can think of to do $r-subprocess_env('VARIABLE'), and it definitely does not work. :( --Ryan On Mon, 2003-06-09 at 14:04, Perrin Harkins wrote: On Mon, 2003-06-09 at 14:49, Ryan Muldoon wrote: I tried that as well (and just re-tried). My understanding is that the %ENV hash only gets updated in the fixup stage, so the mod_ssl environment variables can't be accessed that way. Thanks for the suggestion though! Okay. And you're certain that a simple $r-subprocess_env('VARIABLE') doesn't work? Have you tried setting a variable yourself as a test with PerlSetEnv in httpd.conf? - Perrin
Re: getting *any* variables out of the server environment
Ryan, Ust out of curiosity, at what stage in the request chain are you doing this? If you are doing anything before mod_ssl populates its environment variables (which I seem to rembmer being at Fixup, although I may be confusing with something else), you wouldn't be able to access them. You *should* still be able to get to other Apache environment variables. Try an easy one: test for mod_perl. If that works, your environment variables are OK, and it's likely a mod_ssl problem that you're having. Issac - Original Message - From: Ryan Muldoon [EMAIL PROTECTED] To: Geoffrey Young [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Sent: Monday, June 09, 2003 10:13 PM Subject: Re: getting *any* variables out of the server environment Geoffrey, Thanks for the explanation. Unfortunately, I think I am still a little unclear as to how to proceed. If I understand you correctly, my first method is completely wrongheaded. (I tried this because it is how the Writing Apache Modules with Perl and C does it. p.327) So it sounds like the second way is the appropriate usage for subprocess_env(). But it seems like you're saying that I shouldn't be using that at all. Specifically, here is what I'd like to get out of the environment: SSL_CLIENT_S_DN_CN SSL_CLIENT_S_DN_O and things of that nature. According to mod_ssl's documentation, these are put in ENV upon processing of a client certificate. Ideally, I'd like to make which fields to extract configurable, so I don't want to hard-code. Currently, I have PerlPassEnv SSL_CLIENT_S_DN_O PerlPassEnv SSL_CLIENT_S_DN_CN in my httpd.conf, but it doesn't seem to make any kind of difference. To make sure it isn't just mod_ssl being lame for some reason, I've tried it with DOCUMENT_ROOT and other standard ENV variables. But to no avail. :( --Ryan On Mon, 2003-06-09 at 13:59, Geoffrey Young wrote: Ryan Muldoon wrote: I'm not able to get *any* variables out from the apache server environment. ok, first off, this is a two step process for Apache. the first step is that modules (like mod_ssl) populate the subprocess_env table with various values. then, modules like mod_cgi and mod_perl come along and populate %ENV with the values from subprocess_env as well as various other CGI specific variables (like DOCUMENT_ROOT or whatever else there is). the point is that you're really not after environment variables if you want to test for something like $r-subprocess_env('HTTPS') - that it ends up as $ENV{HTTPS} is a byproduct of modules like mod_cgi and mod_perl. just for your own edification :) As you might be able to imagine, this is extremely frustrating, and inhibits my ability to do anything of use with mod_perl. My basic technique has been: my $uri = $r-uri; return unless $r-is_main(); my $subr = $r-lookup_uri($uri); my $apachecertcomp = $subr-subprocess_env($certcomponent); I don't understand the need for a subrequest to the same URI - subprocess_env has nothing to do with an actual subprocess. each request (including subrequests) have their own subprocess_env table attached to $r. in many cases, modules are coded to behave differently for subrequests than for the main request, so something you may see in $r-subprocess_env() could not be in $r-lookup_uri($uri)-subprocess_env(). But this doesn't work. I also tried my $var = $r-subprocess_env(VARIABLE_NAME); And this does not work either. I really need to be able to use environment variables that mod_ssl sets in my authentication handler. a few things here too. for the reasons described above, subprocess_env() is not a substitute for %ENV, so if what you want is a true %ENV value (such as those from PerlPassEnv), you will not be able to get to it via $r-subprocess_env(). Any ideas? Thanks! HTH --Geoff
Re: getting *any* variables out of the server environment
On Mon, 9 Jun 2003, Ryan Muldoon wrote: Geoffrey, Thanks for the explanation. Unfortunately, I think I am still a little unclear as to how to proceed. If I understand you correctly, my first method is completely wrongheaded. (I tried this because it is how the Writing Apache Modules with Perl and C does it. p.327) So it sounds like the second way is the appropriate usage for subprocess_env(). But it seems like you're saying that I shouldn't be using that at all. Specifically, here is what I'd like to get out of the environment: SSL_CLIENT_S_DN_CN SSL_CLIENT_S_DN_O and things of that nature. According to mod_ssl's documentation, these are put in ENV upon processing of a client certificate. Ideally, I'd like to make which fields to extract configurable, so I don't want to hard-code. Currently, I have PerlPassEnv SSL_CLIENT_S_DN_O PerlPassEnv SSL_CLIENT_S_DN_CN in my httpd.conf, but it doesn't seem to make any kind of difference. To make sure it isn't just mod_ssl being lame for some reason, I've tried it with DOCUMENT_ROOT and other standard ENV variables. But to no avail. :( Do you have a SSLOptions +StdEnvVars directive inside the relevant location of your httpd.conf? -- best regards, randy kobes
Re: getting *any* variables out of the server environment
Ryan Muldoon wrote: Geoffrey, Thanks for the explanation. Unfortunately, I think I am still a little unclear as to how to proceed. If I understand you correctly, my first method is completely wrongheaded. :) (I tried this because it is how the Writing Apache Modules with Perl and C does it. p.327) don't have my book handy to check that. So it sounds like the second way is the appropriate usage for subprocess_env(). But it seems like you're saying that I shouldn't be using that at all. no, I wasn't saying that :) subprocess_env() from the main request is the right way to go. I was just trying to let you know that it has nothing to do with %ENV really. Specifically, here is what I'd like to get out of the environment: SSL_CLIENT_S_DN_CN SSL_CLIENT_S_DN_O and things of that nature. ok, those are definitely setup in the subprocess_env table according to the code I just took a look at. however... According to mod_ssl's documentation, these are put in ENV upon processing of a client certificate. from what I can see, that's not entirely true. they are set in subprocess_env where they sit and wait, presumably for somebody else to call add_cgi_vars since mod_ssl does not (but mod_cgi and mod_perl both do). the problem you're seeing is that these variables are setup during the fixup phase, so in using a PerlAuthenHandler you're trying to see them too early. int ssl_hook_Fixup(request_rec *r) { SSLSrvConfigRec *sc = mySrvConfig(r-server); SSLDirConfigRec *dc = myDirConfig(r); table *e = r-subprocess_env; ... /* * Annotate the SSI/CGI environment with standard SSL information */ /* the always present HTTPS (=HTTP over SSL) flag! */ ap_table_set(e, HTTPS, on); /* standard SSL environment variables */ if (dc-nOptions SSL_OPT_STDENVVARS) { for (i = 0; ssl_hook_Fixup_vars[i] != NULL; i++) { var = (char *)ssl_hook_Fixup_vars[i]; val = ssl_var_lookup(r-pool, r-server, r-connection, r, var); if (!strIsEmpty(val)) ap_table_set(e, var, val); } } in other words, you're SOL from the current request. perhaps this is why the eagle book said to get them from a subrequest - presumably the subrequest would have them, since it runs through the fixup phase and SSL stuff is per-connection and not per-request. Ideally, I'd like to make which fields to extract configurable, so I don't want to hard-code. Currently, I have PerlPassEnv SSL_CLIENT_S_DN_O PerlPassEnv SSL_CLIENT_S_DN_CN in my httpd.conf, but it doesn't seem to make any kind of difference. don't do that. PerlPassEnv is for passing variables such as those from /etc/profile to the %ENV of the Apache child processes. --Geoff
Re: getting *any* variables out of the server environment
I didn't. But I just set that, and it didn't seem to make a difference --Ryan On Mon, 2003-06-09 at 14:16, Randy Kobes wrote: On Mon, 9 Jun 2003, Ryan Muldoon wrote: Geoffrey, Thanks for the explanation. Unfortunately, I think I am still a little unclear as to how to proceed. If I understand you correctly, my first method is completely wrongheaded. (I tried this because it is how the Writing Apache Modules with Perl and C does it. p.327) So it sounds like the second way is the appropriate usage for subprocess_env(). But it seems like you're saying that I shouldn't be using that at all. Specifically, here is what I'd like to get out of the environment: SSL_CLIENT_S_DN_CN SSL_CLIENT_S_DN_O and things of that nature. According to mod_ssl's documentation, these are put in ENV upon processing of a client certificate. Ideally, I'd like to make which fields to extract configurable, so I don't want to hard-code. Currently, I have PerlPassEnv SSL_CLIENT_S_DN_O PerlPassEnv SSL_CLIENT_S_DN_CN in my httpd.conf, but it doesn't seem to make any kind of difference. To make sure it isn't just mod_ssl being lame for some reason, I've tried it with DOCUMENT_ROOT and other standard ENV variables. But to no avail. :( Do you have a SSLOptions +StdEnvVars directive inside the relevant location of your httpd.conf?
Re: getting *any* variables out of the server environment
I'm trying to do this as a PerlAuthenHandler, so it should be well past mod_ssl's involvement, but before the fixup stage. Trying to print out MOD_PERL either through a subprocess or ENV fails. So maybe I'm in bigger trouble than I thought? --Ryan On Mon, 2003-06-09 at 14:26, Issac Goldstand wrote: Ryan, Ust out of curiosity, at what stage in the request chain are you doing this? If you are doing anything before mod_ssl populates its environment variables (which I seem to rembmer being at Fixup, although I may be confusing with something else), you wouldn't be able to access them. You *should* still be able to get to other Apache environment variables. Try an easy one: test for mod_perl. If that works, your environment variables are OK, and it's likely a mod_ssl problem that you're having. Issac - Original Message - From: Ryan Muldoon [EMAIL PROTECTED] To: Geoffrey Young [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Sent: Monday, June 09, 2003 10:13 PM Subject: Re: getting *any* variables out of the server environment Geoffrey, Thanks for the explanation. Unfortunately, I think I am still a little unclear as to how to proceed. If I understand you correctly, my first method is completely wrongheaded. (I tried this because it is how the Writing Apache Modules with Perl and C does it. p.327) So it sounds like the second way is the appropriate usage for subprocess_env(). But it seems like you're saying that I shouldn't be using that at all. Specifically, here is what I'd like to get out of the environment: SSL_CLIENT_S_DN_CN SSL_CLIENT_S_DN_O and things of that nature. According to mod_ssl's documentation, these are put in ENV upon processing of a client certificate. Ideally, I'd like to make which fields to extract configurable, so I don't want to hard-code. Currently, I have PerlPassEnv SSL_CLIENT_S_DN_O PerlPassEnv SSL_CLIENT_S_DN_CN in my httpd.conf, but it doesn't seem to make any kind of difference. To make sure it isn't just mod_ssl being lame for some reason, I've tried it with DOCUMENT_ROOT and other standard ENV variables. But to no avail. :( --Ryan On Mon, 2003-06-09 at 13:59, Geoffrey Young wrote: Ryan Muldoon wrote: I'm not able to get *any* variables out from the apache server environment. ok, first off, this is a two step process for Apache. the first step is that modules (like mod_ssl) populate the subprocess_env table with various values. then, modules like mod_cgi and mod_perl come along and populate %ENV with the values from subprocess_env as well as various other CGI specific variables (like DOCUMENT_ROOT or whatever else there is). the point is that you're really not after environment variables if you want to test for something like $r-subprocess_env('HTTPS') - that it ends up as $ENV{HTTPS} is a byproduct of modules like mod_cgi and mod_perl. just for your own edification :) As you might be able to imagine, this is extremely frustrating, and inhibits my ability to do anything of use with mod_perl. My basic technique has been: my $uri = $r-uri; return unless $r-is_main(); my $subr = $r-lookup_uri($uri); my $apachecertcomp = $subr-subprocess_env($certcomponent); I don't understand the need for a subrequest to the same URI - subprocess_env has nothing to do with an actual subprocess. each request (including subrequests) have their own subprocess_env table attached to $r. in many cases, modules are coded to behave differently for subrequests than for the main request, so something you may see in $r-subprocess_env() could not be in $r-lookup_uri($uri)-subprocess_env(). But this doesn't work. I also tried my $var = $r-subprocess_env(VARIABLE_NAME); And this does not work either. I really need to be able to use environment variables that mod_ssl sets in my authentication handler. a few things here too. for the reasons described above, subprocess_env() is not a substitute for %ENV, so if what you want is a true %ENV value (such as those from PerlPassEnv), you will not be able to get to it via $r-subprocess_env(). Any ideas? Thanks! HTH --Geoff
Re: getting *any* variables out of the server environment
From what I understand, what you outline *should* work. It just doesn't for me for some reason. I really appreciate everyone's help though. (And as an aside - I learned how to program in Perl from your books - many thanks) --Ryan On Mon, 2003-06-09 at 14:23, Randal L. Schwartz wrote: Ryan == Ryan Muldoon [EMAIL PROTECTED] writes: Ryan Geoffrey, Ryan Thanks for the explanation. Unfortunately, I think I am still a little Ryan unclear as to how to proceed. If I understand you correctly, my first Ryan method is completely wrongheaded. (I tried this because it is how the Ryan Writing Apache Modules with Perl and C does it. p.327) So it sounds Ryan like the second way is the appropriate usage for subprocess_env(). But Ryan it seems like you're saying that I shouldn't be using that at all. Ryan Specifically, here is what I'd like to get out of the environment: Ryan SSL_CLIENT_S_DN_CN Ryan SSL_CLIENT_S_DN_O Ryan and things of that nature. According to mod_ssl's documentation, these Ryan are put in ENV upon processing of a client certificate. Ideally, I'd Ryan like to make which fields to extract configurable, so I don't want to Ryan hard-code. Well, then, in any handler after the mod_ssl has run, you should be be able to use $r-subprocess_env(SSL_CLIENT_S_DN_CN) to get at that info. Ryan Currently, I have Ryan PerlPassEnv SSL_CLIENT_S_DN_O Ryan PerlPassEnv SSL_CLIENT_S_DN_CN Ryan in my httpd.conf, but it doesn't seem to make any kind of difference. Ryan To make sure it isn't just mod_ssl being lame for some reason, I've Ryan tried it with DOCUMENT_ROOT and other standard ENV variables. But to no Ryan avail. :( That takes the enviroment variables that apache was started with and passes those to mod_perl. Probably not what you want. (I'm doing this from memory, so please correct me if I'm wrong.)
Re: getting *any* variables out of the server environment
On Mon, 2003-06-09 at 14:35, Geoffrey Young wrote: Ryan Muldoon wrote: Geoffrey, Thanks for the explanation. Unfortunately, I think I am still a little unclear as to how to proceed. If I understand you correctly, my first method is completely wrongheaded. :) (I tried this because it is how the Writing Apache Modules with Perl and C does it. p.327) don't have my book handy to check that. So it sounds like the second way is the appropriate usage for subprocess_env(). But it seems like you're saying that I shouldn't be using that at all. no, I wasn't saying that :) subprocess_env() from the main request is the right way to go. I was just trying to let you know that it has nothing to do with %ENV really. Ok, cool. Thanks for the clarification ;-) Specifically, here is what I'd like to get out of the environment: SSL_CLIENT_S_DN_CN SSL_CLIENT_S_DN_O and things of that nature. ok, those are definitely setup in the subprocess_env table according to the code I just took a look at. however... According to mod_ssl's documentation, these are put in ENV upon processing of a client certificate. from what I can see, that's not entirely true. they are set in subprocess_env where they sit and wait, presumably for somebody else to call add_cgi_vars since mod_ssl does not (but mod_cgi and mod_perl both do). the problem you're seeing is that these variables are setup during the fixup phase, so in using a PerlAuthenHandler you're trying to see them too early. int ssl_hook_Fixup(request_rec *r) { SSLSrvConfigRec *sc = mySrvConfig(r-server); SSLDirConfigRec *dc = myDirConfig(r); table *e = r-subprocess_env; ... /* * Annotate the SSI/CGI environment with standard SSL information */ /* the always present HTTPS (=HTTP over SSL) flag! */ ap_table_set(e, HTTPS, on); /* standard SSL environment variables */ if (dc-nOptions SSL_OPT_STDENVVARS) { for (i = 0; ssl_hook_Fixup_vars[i] != NULL; i++) { var = (char *)ssl_hook_Fixup_vars[i]; val = ssl_var_lookup(r-pool, r-server, r-connection, r, var); if (!strIsEmpty(val)) ap_table_set(e, var, val); } } in other words, you're SOL from the current request. perhaps this is why the eagle book said to get them from a subrequest - presumably the subrequest would have them, since it runs through the fixup phase and SSL stuff is per-connection and not per-request. Yeah, I think that was the motivation. On the upside of my current difficulty, I'm getting to learn a lot more about how apache does things. Ideally, I'd like to make which fields to extract configurable, so I don't want to hard-code. Currently, I have PerlPassEnv SSL_CLIENT_S_DN_O PerlPassEnv SSL_CLIENT_S_DN_CN in my httpd.conf, but it doesn't seem to make any kind of difference. don't do that. PerlPassEnv is for passing variables such as those from /etc/profile to the %ENV of the Apache child processes. Ok, removed. Thank you very much for the in-depth replies. It is very useful. Unfortunately any variable-reading continues to elude me. But I really appreciate all the help! --Ryan
Re: getting *any* variables out of the server environment
On Mon, 2003-06-09 at 15:35, Geoffrey Young wrote: no, I wasn't saying that :) subprocess_env() from the main request is the right way to go. I was just trying to let you know that it has nothing to do with %ENV really. I wouldn't go that far. %ENV does get populated with that stuff, just not yet. perhaps this is why the eagle book said to get them from a subrequest - presumably the subrequest would have them, since it runs through the fixup phase and SSL stuff is per-connection and not per-request. Exactly, and as it happens, that chapter is on-line. The part Ryan was referring to is here: http://modperl.com:9000/book/chapters/ch6.html#Using_Digital_Certificates_for_A Ryan, can you post a more complete code example? - Perrin
Re: getting *any* variables out of the server environment
Ok, removed. Thank you very much for the in-depth replies. It is very useful. Unfortunately any variable-reading continues to elude me. But I really appreciate all the help! well, it sounds like you are having a larger problem that just mod_ssl-based variables. since you mention you're interested in learning... :) if you really want to track this down you could start from the beginning, meaning a bare bones server and a bare bones mod_perl content handler that merely iterates over %ENV and $r-subprocess_env() (see the do() method from Apache::Table) this kind of bare bones thing used to be a pain, but with Apache-Test, it has gotten _lots_ easier. you can find Apache-Test on CPAN http://search.cpan.org/CPAN/authors/id/S/ST/STAS/Apache-Test-1.01.tar.gz you can look at some of the SSL tests in the Perl-Framework http://cvs.apache.org/viewcvs.cgi/httpd-test/perl-framework/ to see how they use Apache-Test to test SSL based things. for instance env.t tests basic environment setting for SSL connections - you can use that as the starting point for writing tests for your own stuff. or you can even download the Perl framework from http://httpd.apache.org/test/ and run the ssl tests to make sure you're server is configured properly. just some advice, and you certainly don't need to go through all the effort of reading, setting up the test environment, etc. however, once you get Apache-Test set up it will make your module development much, much easier, and you'll be able to pinpoint exactly where things go wrong much easier. some basic explanations and pointers to other docs can be found here http://www.perl.com/pub/a/2003/05/22/testing.html HTH --Geoff
Re: getting *any* variables out of the server environment
Actually, upon flushing my browser cache and checking again, I can in fact read the MOD_PERL environment variable just fine. But still no luck on any mod_ssl related variables. --Ryan
Re: getting *any* variables out of the server environment
[ Please keep it on the list. ] On Mon, 2003-06-09 at 16:12, Ryan Muldoon wrote: Ryan, can you post a more complete code example? - Perrin Here it is: package Apache::AuthNx509; use strict; use Apache::Constants qw(:common); use Text::ParseWords qw(quotewords); use Apache::Log (); sub handler { my $r = shift; my $c = $r-connection; my $log = $r-log; return OK unless $r-is_main; my $certcomponent = $r-dir_config('CertComponent') || 'SSL_CLIENT_S_DN_O'; my $certcompvalue = $r-dir_config('CertComponentValue') || 'University of Wisconsin'; my $usercomponent = $r-dir_config('RemoteUserCertComponent') || 'SSL_CLIENT_S_DN_CN'; #my $cn = $r-subprocess_env('MOD_PERL'); # $log-notice(test: $ENV{'MOD_PERL'}); my $apachecertcomp = $r-subprocess_env{$certcomponent}; That should be $r-subprocess_env($certcomponent). It's a method, not a hash key. Also, put the lookup_uri stuff back in, since it seems that you need it when trying to get the stuff from mod_ssl. - Perrin
Re: getting *any* variables out of the server environment
On Mon, 2003-06-09 at 15:24, Perrin Harkins wrote: [ Please keep it on the list. ] Sorry about that! On Mon, 2003-06-09 at 16:12, Ryan Muldoon wrote: Ryan, can you post a more complete code example? - Perrin Here it is: package Apache::AuthNx509; use strict; use Apache::Constants qw(:common); use Text::ParseWords qw(quotewords); use Apache::Log (); sub handler { my $r = shift; my $c = $r-connection; my $log = $r-log; return OK unless $r-is_main; my $certcomponent = $r-dir_config('CertComponent') || 'SSL_CLIENT_S_DN_O'; my $certcompvalue = $r-dir_config('CertComponentValue') || 'University of Wisconsin'; my $usercomponent = $r-dir_config('RemoteUserCertComponent') || 'SSL_CLIENT_S_DN_CN'; #my $cn = $r-subprocess_env('MOD_PERL'); # $log-notice(test: $ENV{'MOD_PERL'}); my $apachecertcomp = $r-subprocess_env{$certcomponent}; That should be $r-subprocess_env($certcomponent). It's a method, not a hash key. Also, put the lookup_uri stuff back in, since it seems that you need it when trying to get the stuff from mod_ssl. - Perrin I must have been stupid. Making those two corrections, everything works (Almost)! Right now it is failing on my attempts to set the user variable (I want to be able to set REMOTE_USER to an arbitrary cert field). I'll have to dig a bit to figure out how to do that. Thank you everyone on the list for helping me out so much today - I really appreciate it. Many days of hair-pulling are at an end. ;-) --Ryan
problem with pulling variables from mod_ssl
I'm trying to write an apache authentication module that uses client certificates for authentication. Basically, all I'm trying to do is use what mod_ssl does for cert verification, and then set REMOTE_USER. I wrote to the list last week about a segfault, which was resolved thanks to the help you guys gave me. Now I am stuck with a problem that is likely a logic error on my part, but I have a feeling that my problem stems from a misunderstanding of how apache is supposed to work. Since my module is very short, I'll include it in this email, along with the relevant contents of my error_log, in the hopes that someone might be able to point me in the right direction. Thanks! ---my module, AuthNx509.pm package Apache::AuthNx509; use strict; use Apache::Constants qw(:common); use Text::ParseWords qw(quotewords); use Apache::Log (); sub handler { my $r = shift; my $c = $r-connection; my $log = $r-log; my $certcomponent = $r-dir_config('CertComponent') || 'SSL_CLIENT_S_DN_O'; my $certcompvalue = $r-dir_config('CertComponentValue') || 'University of Wisconsin'; my $usercomponent = $r-dir_config('RemoteUserCertComponent') || 'SSL_CLIENT_S_DN_CN'; my $uri = $r-uri; return unless $r-is_main(); my $subr = $r-lookup_uri($uri); my $apachecertcomp = $subr-subprocess_env($certcomponent); $log-notice(hello: $apachecertcomp); if ($apachecertcomp eq $certcompvalue) { $log-notice($certcompvalue good); $c-user = $r-subprocess_env-{$usercomponent}; $log-notice($c-user logged in successfully); return OK; } $log-notice(cert no good: $r-subprocess_env-{$certcomponent}); my $reason = Client Cert not in correct form; $r-note_basic_auth_failure; $r-log_reason($reason, $r-filename); return DECLINED; } 1; __END__ -- error log data: Thu Jun 5 14:57:11 2003] [notice] [client 128.104.16.134] hello: [Thu Jun 5 14:57:11 2003] [notice] [client 128.104.16.134] cert no good: Apache=SCALAR(0x8100308)-subprocess_env-{SSL_CLIENT_S_DN_C} [Thu Jun 5 14:57:11 2003] [error] access to /var/www/html/test failed for 128.104.16.134, reason: Client Cert not in correct form [Thu Jun 5 14:57:13 2003] [notice] [client 128.104.16.134] hello: [Thu Jun 5 14:57:13 2003] [notice] [client 128.104.16.134] cert no good: Apache=SCALAR(0x8100308)-subprocess_env-{SSL_CLIENT_S_DN_C} [Thu Jun 5 14:57:13 2003] [error] access to /var/www/html/test failed for 128.104.16.134, reason: Client Cert not in correct form [Thu Jun 5 14:57:13 2003] [crit] [client 128.104.16.134] configuration error: couldn't check user. No user file?: /test/ configuration data (in a Directory statement): SSLVerifyClient require SSLVerifyDepth 10 SSLOptions +StrictRequire SSLRequire %{SSL_CIPHER_USEKEYSIZE} = 128 # Force clients to use HTTPS RewriteEngineon RewriteCond %{HTTPS} !=on RewriteRule .* - [F] AuthName Test AuthType Basic PerlAuthenHandler Apache::AuthNx509 PerlSetVar CertComponent SSL_CLIENT_S_DN_C PerlSetVar CertComponentValue US PerlSetVar RemoteUserCertComponent SSL_CLIENT_S_DN_CN require valid-user Any ideas would be most appreciated. Thanks again! --Ryan
virtualhost based variables
Greetings again. I'm trying to figure out the best/fastest/most elegant way of setting virtualhost based variables. Basically I have three sites, and the only difference between them is the DocumentRoot ($htdocroot) and the database their data is being accessed from ($dbh). When it was a single site I had $documentroot and $dbh declared in my startup.pl, and my modules accessed it through $main::dbh, and it was all find and dandy. Is there a way to do this? Or do I have to use $r-dir_config in every module to get the document root and re-create $dbh? I know mod_perl 2.0 will solve this problem with the +Parent option, but heading to apache 2.0 might not be an option at this point. So how does everyone else do it? :) TIA alan -- Alan Arcterex [EMAIL PROTECTED] -=][=- http://arcterex.net I used to herd dairy cows. Now I herd lusers. Apart from the isolation, I think I preferred the cows. They were better conversation, easier to milk, and if they annoyed me enough, I could shoot them and eat them. -Rodger Donaldson
Re: virtualhost based variables
Alan [EMAIL PROTECTED] wrote: Greetings again. I'm trying to figure out the best/fastest/most elegant way of setting virtualhost based variables. Basically I have three sites, and the only difference between them is the DocumentRoot ($htdocroot) and the database their data is being accessed from ($dbh). Document root should be accessable from $r. I would use Apache::DBI for persistent connections. Then connect at the beginning of the request with the DBI connection parameters coming from $r-dir_config. -- James Smith [EMAIL PROTECTED], 979-862-3725 Texas AM CIS Operating Systems Group, Unix
Re: virtualhost based variables
On Wed, Oct 02, 2002 at 06:04:03PM -0500, James G Smith wrote: Alan [EMAIL PROTECTED] wrote: Greetings again. I'm trying to figure out the best/fastest/most elegant way of setting virtualhost based variables. Basically I have three sites, and the only difference between them is the DocumentRoot ($htdocroot) and the database their data is being accessed from ($dbh). Document root should be accessable from $r. I would use Apache::DBI for persistent connections. Then connect at the beginning of the request with the DBI connection parameters coming from $r-dir_config. Yup, and this is exactly how I have it working right now. Each module starts by re-instantiating $dbh and $htdocroot via dir_config and a function that uses dir_config to find the database it's supposed to grab stuff from. The problem is that it seems like I've incurred a pretty high speed penalty, and my requests/sec have dropped from about 165 to 83 :( I'm still pushing enough data to saturate a T1, so at the end it's not going to be a noticable difference. I wanted to know if there was a better/faster way to do this though, without having to call $r-dir_config and $r-document_root for /every/ request. Alan -- Alan Arcterex [EMAIL PROTECTED] -=][=- http://arcterex.net I used to herd dairy cows. Now I herd lusers. Apart from the isolation, I think I preferred the cows. They were better conversation, easier to milk, and if they annoyed me enough, I could shoot them and eat them. -Rodger Donaldson
Perl environment variables in mod_perl 1.26
Gday fellow mod_perl'ers, In order to get mod_perl to look in the right place for my perl modules, I have been using the SetEnv PERL5LIB /foo method in my apache config file. This is giving me bad results when I use more than one mod_perl module. To my knowledge, the way this works is that when the perl interpreter is loaded, it prepends the normal INC paths with the directory[s] in your PERL5LIB environment variable. What I'm finding is that when the first mod_perl module loads, it uses the PERL5LIB variable to build up an INC list. Then when the second mod_perl module is called, it's not rebuilding the INC path. Say I have an apache config like so: Directory /foo SetEnv PERL5LIB /tmp/foo /Directory Directory /bar SetEnv PERL5LIB /tmp/bar /Directory If I load a mod_perl module from the /foo directory, then the INC for perl contains /tmp/foo. If that mod_perl script then does an internal redirect to another mod_perl module in /bar, then the INC path is not rebuilt with the new environment. This is relevant for PerlAuthzHandler's and such, as they are loaded by apache first, as mod_perl modules. Then once authenticated, they do some sort of internal redirect to the original request. If this original request was for a mod_perl module, then it doesn't recieve it's appropriate INC. The environment variables are all set properly, ie: PERL5LIB is what is supposed to be, it's just that the INC hasn't be rebuilt. Does anyone know if this is a bug in mod_perl? I have found a way around it by just manually pushing the environment variable onto the INC before the second mod_perl module is called. But I believe this is an incorrect way of doing things. cheers Danial Pearce
RE: variables not changing with modperl??
I'm sure someone will correct me if I'm wrong... But, variables in the initial section (ie outside of a function) in the main package will stay in scope all the time. This means that it will retain the value from a previous request- which might be giving you these problems. As Perrin Harkins wrote, there are various solutions documented in the FAQ. You need to read these and follow one of the methods. Read this: http://perl.apache.org/docs/general/perl_reference/perl_reference.html#my___ Scoped_Variable_in_Nested_Subroutines - Perrin Personally I use the CGI::Application framework, which I find gives a really nice framework to develop applications in. Each application is a package, and each run mode is a sub which means you don't get any of these scope problems. Good luck, David. Maer neges e-bost hon ac unrhyw ffeiliau sydd ynghlwm wrthi yn gwbl gyfrinachol ac wediu bwriadu at sylw yr unigolyn neur endid y maent wedi eu cyfeirio ato yn unig. Gallant gynnwys gwybodaeth syn freintiedig yn gyfreithiol a/neun gyfrinachol ac os nad chi ywr sawl y cyfeiriwyd y neges ato, yna peidiwch â chopio, dosbarthu na chymryd unrhyw gamau o ganlyniad a gan ddibynnu arni. Os ydych wedi derbyn y neges e-bost hon ar gam, a wnewch chi ein hysbysu o hyn cyn gynted â phosib ai dileu os gwelwch yn dda. Barn neu safbwyntiaur awdur ywr rhai a fynegir yn y neges e-bost hon ac/neun unrhyw atodiadau ac nid ydynt yn adlewyrchu o anghenraid barn neu safbwyntiau S4C. This e-mail message and any files attached are strictly confidential and intended solely for the attention of the person or entity to whom they are addressed. They may contain legally privileged and/or confidential information and if you are not the addressee, you should not copy, distribute nor take any action in reliance on them. If you have received this e-mail message in error, please notify us as soon as possible and delete it. The views and opinions expressed in this e-mail message and any attachments are the authors own and they do not reflect necessarily the views and opinions of S4C.
Re: variables not changing with modperl??
* Michael Drons [EMAIL PROTECTED] [2002-08-13 01:55]: Thanks for the link. I actually don't use functions. Everything is mostly in MAIN. Here is a snip of code: #!/usr/bin/perl -wT use strict; print body; my $r = Apache-request; $r-content_type(text/html); $r-status(200); my $auth_type = $r-auth_type; $cookie=$auth_type-key; ($user,$hash)=split(/:/,$cookie); read(STDIN, my $buffer, $ENV{'CONTENT_LENGTH'}); my @pairs = split(//, $buffer); foreach my $pair (@pairs) { } What I am doing wrong? Everytime the script runs the values of the variables coming in change. Should I use the delete function and delete all of the variables at the end of the script? @pairs is what should change, but sometimes does not. I have tried to add a undef @pairs before the split, but no luck. Are you sure that this is the code that is running? It doesn't compile: $ perl #!/usr/bin/perl -wT use strict; print body; my $r = Apache-request; $r-content_type(text/html); $r-status(200); my $auth_type = $r-auth_type; $cookie=$auth_type-key; ($user,$hash)=split(/:/,$cookie); read(STDIN, my $buffer, $ENV{'CONTENT_LENGTH'}); my @pairs = split(//, $buffer); foreach my $pair (@pairs) { } Global symbol $cookie requires explicit package name at - line 7. Global symbol $user requires explicit package name at - line 8. Global symbol $hash requires explicit package name at - line 8. Global symbol $cookie requires explicit package name at - line 8. Execution of - aborted due to compilation errors Make those global symbols ($cookie, $user, and $hash) lexical (declare with my) and the code will both compile and do what you expect (i.e., not maintain values from call to call). You'll also want to print things *after* you set the content type and status, not before. (darren) -- The biggest difference between time and space is that you can't reuse time. -- Merrick Furst
Re: variables not changing with modperl??
Hi darren Did you try starting apache with "httpd -X". It spawns only one process and that helps keep things inorder, as far as variable values. You can try trouble shooting with that. darren chamberlain <[EMAIL PROTECTED]>wrote: * Michael Drons <[EMAIL PROTECTED]>[2002-08-13 01:55]: Thanks for the link. I actually don't use functions. Everything is mostly in MAIN. Here is a snip of code: #!/usr/bin/perl -wT use strict; print ""; my $r = Apache-request; $r-content_type("text/html"); $r-status(200); my $auth_type = $r-auth_type; $cookie=$auth_type-key; ($user,$hash)=split(/:/,$cookie); read(STDIN, my $buffer, $ENV{'CONTENT_LENGTH'}); my @pairs = split(//, $buffer); foreach my $pair (@pairs) { } What I am doing wrong? Everytime the script runs the values of the variables coming in change. Should I use the delete function and delete all of the variables at the end of the script? @pairs is what should change, but sometimes does not. I have tried to add a undef @pairs before the split, but no luck.Are you sure that this is the code that is running? It doesn't compile:$ perl#!/usr/bin/perl -wTuse strict;print "";my $r = Apache-request;$r-content_type("text/html");$r-status(200);my $auth_type = $r-auth_type;$cookie=$auth_type-key;($user,$hash)=split(/:/,$cookie);read(STDIN, my $buffer, $ENV{'CONTENT_LENGTH'});my @pairs = split(//, $buffer);foreach my $pair (@pairs) { }Global symbol "$cookie" requires explicit package name at - line 7.Global symbol "$user" requires explicit package name at - line 8.Global symbol "$hash" requires explicit package name at - line 8.Global symbol "$cookie" requires explicit package name at - line 8.Execution of - aborted due to compilation errorsMake those global symbols ($cookie, $user, and $hash) lexical (declarewith my) and the code will both compile and do what you expect (i.e.,not maintain values from call to call).You'll also want to print things *after* you set the content type andstatus, not before.(darren)--The biggest difference between time and space is that you can'treuse time.-- Merrick FurstDo You Yahoo!? HotJobs, a Yahoo! service - Search Thousands of New Jobs
Re: variables not changing with modperl??
darren chamberlain wrote: Make those global symbols ($cookie, $user, and $hash) lexical (declare with my) and the code will both compile and do what you expect (i.e., not maintain values from call to call). That's what I was thinking too. Also, it's really not a good idea to do your own parsing of the input and cookies. You should use one of the CGI modules or Apache::Request and Apache::Cookie for this. Writing your own routine for this is just asking for security problems and bugs. - Perrin
Re: variables not changing with modperl??
Sorry, There is a my in front of the ($cookie,$user) code. I am confused about your second statement about parsing the input. What should I be doing? Do you mean I should use $r-read($content, $r-header_in('Content-length'))? to read in the variables? I use the AuthCookie modules to set the cookies and to authenicate. Mike --- Perrin Harkins [EMAIL PROTECTED] wrote: darren chamberlain wrote: Make those global symbols ($cookie, $user, and $hash) lexical (declare with my) and the code will both compile and do what you expect (i.e., not maintain values from call to call). That's what I was thinking too. Also, it's really not a good idea to do your own parsing of the input and cookies. You should use one of the CGI modules or Apache::Request and Apache::Cookie for this. Writing your own routine for this is just asking for security problems and bugs. - Perrin __ Do You Yahoo!? HotJobs - Search Thousands of New Jobs http://www.hotjobs.com
Re: variables not changing with modperl??
On Tue, 13 Aug 2002, Michael Drons wrote: Date: Tue, 13 Aug 2002 07:46:16 -0700 (PDT) From: Michael Drons [EMAIL PROTECTED] Reply-To: [EMAIL PROTECTED] To: Perrin Harkins [EMAIL PROTECTED], darren chamberlain [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: variables not changing with modperl?? Sorry, There is a my in front of the ($cookie,$user) code. I am confused about your second statement about parsing the input. What should I be doing? Do you mean I should use $r-read($content, $r-header_in('Content-length'))? to read in the variables? Michael, In one of your posts, you included the following code: #!/usr/bin/perl -wT use strict; print body; my $r = Apache-request; $r-content_type(text/html); $r-status(200); my $auth_type = $r-auth_type; $cookie=$auth_type-key; ($user,$hash)=split(/:/,$cookie); read(STDIN, my $buffer, $ENV{'CONTENT_LENGTH'}); my @pairs = split(//, $buffer); foreach my $pair (@pairs) { } There is no my in front of $cookie or $user variables. If you are lexically scoping them somewhere else in your script, please include enough of an example for us to help you. I use the AuthCookie modules to set the cookies and to authenicate. As for this and Perrin's comment about parsing on your own, the point is that you've written a lot of code that has already been written and debugged by a lot of really smart people. There's no reason for you to be reading STDIN and spliting and all that. If you're using mod_perl, then you really should do yourself a favor and read up on Apache::Request and Apache::Cookie for doing all this stuff. It's much faster (it's written in c), safer (it's been debugged), easier (just install the module), and standard (i.e., more maintainable). Of course, some people say that the nice thing about standards is that there are so many to choose from. :) ky
Re: variables not changing with modperl??
Ken Y. Clark wrote: As for this and Perrin's comment about parsing on your own, the point is that you've written a lot of code that has already been written and debugged by a lot of really smart people. There's no reason for you to be reading STDIN and spliting and all that. If you're using mod_perl, then you really should do yourself a favor and read up on Apache::Request and Apache::Cookie for doing all this stuff. Even if you are just using CGI, you shouldn't write your own parsing code like this. Rather than try to explain why, I'll point you to this article on the subject: http://perlmonks.org/index.pl?node_id=51012 - Perrin
variables not changing with modperl??
I am using Apache::Registry (Apache 1.3.26) I am see weird things happen with my scripts. I have have use strict in all of the scripts and I use my() for all of my variables. But I still have variables that contain data from previous loads. I see it in hashes and arrays. Especially, if I have an array that contains 6 strings in load 1 and only 2 strings in load 2. In the second load of the script the array will contain the 2 new strings and the 4 old strings. Everything I can find in docs says read the FAQ at http://perl.apache.org/faq/, which does not exists. This link comes from the subscribe message. I have thought about using PerlRun, but a module I use (AuthCookie) requies mod_perl. How do I undefine or reinit the variable? I am currently using undef, but it does not work. Mike Drons __ Do You Yahoo!? HotJobs - Search Thousands of New Jobs http://www.hotjobs.com
Re: variables not changing with modperl??
Thanks for the link. I actually don't use functions. Everything is mostly in MAIN. Here is a snip of code: #!/usr/bin/perl -wT use strict; print body; my $r = Apache-request; $r-content_type(text/html); $r-status(200); my $auth_type = $r-auth_type; $cookie=$auth_type-key; ($user,$hash)=split(/:/,$cookie); read(STDIN, my $buffer, $ENV{'CONTENT_LENGTH'}); my @pairs = split(//, $buffer); foreach my $pair (@pairs) { } What I am doing wrong? Everytime the script runs the values of the variables coming in change. Should I use the delete function and delete all of the variables at the end of the script? @pairs is what should change, but sometimes does not. I have tried to add a undef @pairs before the split, but no luck. Mike --- Perrin Harkins [EMAIL PROTECTED] wrote: Michael Drons wrote: I am using Apache::Registry (Apache 1.3.26) I am see weird things happen with my scripts. I have have use strict in all of the scripts and I use my() for all of my variables. But I still have variables that contain data from previous loads. Sounds like the closure problem with subroutines in Apache::Registry. Does you code have subroutines that refer to variables declared outside of them? Everything I can find in docs says read the FAQ at http://perl.apache.org/faq/, which does not exists. Read this: http://perl.apache.org/docs/general/perl_reference/perl_reference.html#my___Scoped_Variable_in_Nested_Subroutines - Perrin __ Do You Yahoo!? HotJobs - Search Thousands of New Jobs http://www.hotjobs.com
Exporter variables get lost
Hello, I'm working on mod_perl project which has many different modules. One is so-called 'main' modules which loads other when needed. Until now everything worked just fine, but now one module just says that he doesn't know the variable I've exported. And interesting is, that when I comment out either $sub_first-do_something(); or other three lines about Sub::Second then it works just fine. Error it get looks like this: Can't call method notice on an undefined value at /usr/local/lib/perl/5.6.1/Sub/First.pm line 25. First.pm and Second.pm use Export.pm exactly same way. So, it this some mod_perl specific feature to just eat up some variables, or what? Here are cut-down versions of my modules: Site.pm: - package Site; use strict; use Apache::Log; sub handler { my $r = shift; use vars qw( $log ); $log = $r-log(); if ( $some_case eq 'true' ) { use Sub::First qw( $log ); my $sub_first = new Sub::First; $sub_first-do_something(); if ( $some_other_case eq 'yes' ) { use Sub::Second qw( $log ); my $sub_second = new Sub::Second; # if I comment out $sub_first-do_something then it works... $sub_first-do_something(); $sub_second-do_something_else(); } } } 1; --- package Sub::First; use strict; use Apache::Log; BEGIN { use Exporter(); Sub::First::ISA = qw( Exporter ); Sub::First::EXPORT= qw(); Sub::First::EXPORT_OK = qw( $log ); } use vars qw( $log ); sub new { my $class = $_[0]; my $objref = { }; bless ( $objref, $class ); return $objref; } sub do_somehing { $log-notice(Now this here doesn\'t work); } 1; -- Rgds, Viljo
Re: Exporter variables get lost
Viljo Marrandi actually wrote: my $r = shift; use vars qw( $log ); $log = $r-log(); if ( $some_case eq 'true' ) { use Sub::First qw( $log ); I haven't tested, but this doesn't look as a good idea. I don't think your code does what you think it does (or what you think it should do.) Moreover I don't know what this actually does (or should do) precisely. Exporter essentially does this: *Site::log = \$Sub::First::log; and vars essentially does this: *Site::log = \$Site::log; And this symbol table manipulation occurs at compile-time, before your code is run (without scoping effecs). In other words don't do that. -- Rafael Garcia-Suarez
Re: Exporter variables get lost
The answer to the trick question is that the subroutine name in package Sub::First is misspelled (missing a t). However, I think I would provide the Apache::Log object as a parameter to new() rather than twiddling with package vars to try to have it magically updated by Exporter. For example: package Sub::First; use strict; # simple constructor expects classname, log object sub new { my($class,$ap_log) = _; return bless {apache_log=$ap_log}, $class; } sub do_something { $self-{apache_log}-notice(this will work); } package Sub::Second; use strict; # another simple constructor expects classname, log object sub new { my($class,$ap_log) = _; return bless {apache_log=$ap_log}, $class; } sub do_something_else { $self-{apache_log}-notice(this will work, too); } package Site; use strict; use Sub::First; use Sub::Second; sub handler { my $r = shift; # test values for conditions my $some_case = 'true'; my $some_other_case = 'yes'; if ( $some_case eq 'true' ) { my $sub_first = Sub::First-new($r-log); $sub_first-do_something(); if ( $some_other_case eq 'yes' ) { my $sub_second = Sub::Second-new($r-log); $sub_first-do_something(); $sub_second-do_something_else(); } } } # End Example Regards, Tim Tompkins -- Programmer http://www.arttoday.com/ http://www.rebelartist.com/ --
Re: Scope of Perl Special Variables
Stas Bekman wrote: This explains why by default %ENV is set for each request afresh. http://perl.apache.org/guide/performance.html#PerlSetupEnv_Off Great. Thank you Stas. Now I know /how/ that happens, but I don't know /why/ the existing inctances' ENV is not clobbered. My guess is that a localized copy of the %ENV variable is created by the above referenced process, thus no clobbering of existing instances' %ENV occurs. Would that be correct? -Bill
Re: Scope of Perl Special Variables
I thought that using 'local' would successfully scope those globals to within a sub, so you could,k for example, slurp an entire file by doing: local $/ = undef; my $file = FH; Or am I wrong in that? I use it frequently, and don't seem to have any troubles. --Jon R. It is my understanding that that is correct. I am a novice at mod_perl, but your experience would seem to match up with my understanding of the Guide. Local would scope it to within the enclosing block; so you could scope a variable within a bare block so that it would be local to you package, but shareable between subs. # $/ equals default, global value { local $/ = undef; sub { ... # $/ equals undef } sub { ... # $/ equals undef } sub { local $/ = \n\n; # localized value for sub } # $/ back to undef } # $/ back to default, global value -Bill
Re: Can mod_perl help me use ENV variables in httpd.conf?
You'll also need to use a PerlPassEnv directive prior to your Perl block. For debug purposes, try adding the following inside your Perl block: print join(\n, map { $_ = $ENV{$_} } (keys %ENV)), \n; OR, my personal quick-debugging catch-all: use Data::Dumper; print Dumper \%ENV; You'll be able to see what is available in %ENV when running under mod_perl. See also Chapter 9, page 498 of the Eagle. jason Ken Williams wrote: On Wednesday, May 1, 2002, at 05:04 AM, Fran Fabrizio wrote: I spoke too soon. I need: Perl push Alias, [ qw(/cgi-bin/chimpkit/ $ENV{SERVER_ROOT}/cgi- bin/chimpkit/) ]; /Perl This does not appear to be possible because there's no way to pass in SERVER_ROOT to the apache startup. I think the problem is your Perl syntax, not the value of the variable. Scalars do not interpolate in qw() constructs. Try this instead: Perl push Alias, '/cgi-bin/chimpkit/', $ENV{SERVER_ROOT}/cgi- bin/chimpkit/; /Perl or even Perl push Alias, '/cgi-bin/chimpkit/', $r-server_root_relative . '/cgi-bin/chimpkit/'; /Perl -Ken
Re: Scope of Perl Special Variables
I thought that using 'local' would successfully scope those globals to within a sub, so you could,k for example, slurp an entire file by doing: local $/ = undef; my $file = FH; Or am I wrong in that? I use it frequently, and don't seem to have any troubles. --Jon R. PGP Key fingerprint = 12 DA FC 06 AB 4C D6 A4 DE 03 E0 77 D6 DE E0 73 PGP public key available by fingering [EMAIL PROTECTED] On Fri, 3 May 2002, Bill Catlan wrote: Hello, The online mod_perl guide (http://thingy.kcilink.com/modperlguide/perl/The_Scope_of_the_Special_Perl_Va.ht ml) states: Special Perl variables like $| (buffering), $^T (script's start time), $^W (warnings mode), $/ (input record separator), $\ (output record separator) and many more are all true global variables; they do not belong to any particular package (not even main::) and are universally available. This means that if you change them, you change them anywhere across the entire program; furthermore you cannot scope them with my(). My question pertains the CGI %ENV hash. First, I'm assumong that this is a global variable in the sense of a Perl Special Variable, and not just a main:: or other package global. My question is how is it the case that the %ENV variable script instance might be working with doesn't get clobbered or reset by the next incoming request. Are some variables, like %ENV treated differently by mod_perl? Also, how can special variables be reliably initialized? For example, if one request provides a certain attribute, such as HTTP_IDENT, but a subsequent request does not, how do I know that the value of $ENV{HTTP_IDENT} on the second request will indeed be undefined? Thanks. Bill
Re: Scope of Perl Special Variables
On Sun, 5 May 2002, Jon wrote: I thought that using 'local' would successfully scope those globals to within a sub, so you could,k for example, slurp an entire file by doing: local $/ = undef; my $file = FH; Or am I wrong in that? I use it frequently, and don't seem to have any troubles. Okay, local takes a temporary copy of the variable and then restores the original value at the end of the block. It's the same variable though. my creates a new variable that is only visible from within the block and can't be seen from other subroutines. With my there are two variables that just happen to be called the same things, and which one you get depends if you're in within the enclosing block. The difference is that when you use local any subroutines that you call from within that subroutine will *also* see the variable. With a my variable whatever you change can't be seen in other subroutines The practical difference is if you set $/ and you call any routine from within that same subroutine (that same block) they will also see the new version of $/. This means that anything that you call from within that routine will also slurp in the whole file when it tries to read a line - if it was expecting it or not. In terms of mod_perl this isn't so bad. The local is fine when used in a subroutine like you described, as this subroutine will be exited by the time the handler returns, meaning you won't get any interaction between calls. Of course there's still ways for you to screw yourself over with local, but used carefully it should be fine... Later. Mark. -- s'' Mark Fowler London.pm Bath.pm http://www.twoshortplanks.com/ [EMAIL PROTECTED] ';use Term'Cap;$t=Tgetent Term'Cap{};print$t-Tputs(cl);for$w(split/ +/ ){for(0..30){$|=print$t-Tgoto(cm,$_,$y). $w;select$k,$k,$k,.03}$y+=2}
Re: Scope of Perl Special Variables
Bill Catlan wrote: Stas Bekman wrote: This explains why by default %ENV is set for each request afresh. http://perl.apache.org/guide/performance.html#PerlSetupEnv_Off Great. Thank you Stas. Now I know /how/ that happens, but I don't know /why/ the existing inctances' ENV is not clobbered. My guess is that a localized copy of the %ENV variable is created by the above referenced process, thus no clobbering of existing instances' %ENV occurs. Would that be correct? Can you send a reproducable example of a problem? For example this code does the right thing: $r-send_http_header('text/plain'); print exists $ENV{FOO} ? $ENV{FOO}\n : NONE\n; local $ENV{FOO} = BAR; print exists $ENV{FOO} ? $ENV{FOO}\n : NONE\n; it'll always print: NONE BAR Make sure that you test under httpd -X mode so you won't get mislead. __ Stas BekmanJAm_pH -- Just Another mod_perl Hacker http://stason.org/ mod_perl Guide --- http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
Re: Scope of Perl Special Variables
Bill Catlan wrote: Hello, The online mod_perl guide (http://thingy.kcilink.com/modperlguide/perl/The_Scope_of_the_Special_Perl_Va.ht ml) states: Special Perl variables like $| (buffering), $^T (script's start time), $^W (warnings mode), $/ (input record separator), $\ (output record separator) and many more are all true global variables; they do not belong to any particular package (not even main::) and are universally available. This means that if you change them, you change them anywhere across the entire program; furthermore you cannot scope them with my(). My question pertains the CGI %ENV hash. First, I'm assumong that this is a global variable in the sense of a Perl Special Variable, and not just a main:: or other package global. My question is how is it the case that the %ENV variable script instance might be working with doesn't get clobbered or reset by the next incoming request. Are some variables, like %ENV treated differently by mod_perl? Also, how can special variables be reliably initialized? For example, if one request provides a certain attribute, such as HTTP_IDENT, but a subsequent request does not, how do I know that the value of $ENV{HTTP_IDENT} on the second request will indeed be undefined? This explains why by default %ENV is set for each request afresh. http://perl.apache.org/guide/performance.html#PerlSetupEnv_Off __ Stas BekmanJAm_pH -- Just Another mod_perl Hacker http://stason.org/ mod_perl Guide --- http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
Re: Can mod_perl help me use ENV variables in httpd.conf?
What I was really looking for was $r-server_root_relative. =) Thanks Geoff! That's to all for your help. -Fran You'll also need to use a PerlPassEnv directive prior to your Perl block. For debug purposes, try adding the following inside your Perl block: print join(\n, map { $_ = $ENV{$_} } (keys %ENV)), \n; OR, my personal quick-debugging catch-all: use Data::Dumper; print Dumper \%ENV; You'll be able to see what is available in %ENV when running under mod_perl. See also Chapter 9, page 498 of the Eagle. jason Ken Williams wrote: On Wednesday, May 1, 2002, at 05:04 AM, Fran Fabrizio wrote: I spoke too soon. I need: Perl push Alias, [ qw(/cgi-bin/chimpkit/ $ENV{SERVER_ROOT}/cgi- bin/chimpkit/) ]; /Perl This does not appear to be possible because there's no way to pass in SERVER_ROOT to the apache startup. I think the problem is your Perl syntax, not the value of the variable. Scalars do not interpolate in qw() constructs. Try this instead: Perl push Alias, '/cgi-bin/chimpkit/', $ENV{SERVER_ROOT}/cgi- bin/chimpkit/; /Perl or even Perl push Alias, '/cgi-bin/chimpkit/', $r-server_root_relative . '/cgi-bin/chimpkit/'; /Perl -Ken
Re: Can mod_perl help me use ENV variables in httpd.conf?
On Wednesday, May 1, 2002, at 05:04 AM, Fran Fabrizio wrote: I spoke too soon. I need: Perl push Alias, [ qw(/cgi-bin/chimpkit/ $ENV{SERVER_ROOT}/cgi- bin/chimpkit/) ]; /Perl This does not appear to be possible because there's no way to pass in SERVER_ROOT to the apache startup. I think the problem is your Perl syntax, not the value of the variable. Scalars do not interpolate in qw() constructs. Try this instead: Perl push Alias, '/cgi-bin/chimpkit/', $ENV{SERVER_ROOT}/cgi- bin/chimpkit/; /Perl or even Perl push Alias, '/cgi-bin/chimpkit/', $r-server_root_relative . '/cgi-bin/chimpkit/'; /Perl -Ken
Can mod_perl help me use ENV variables in httpd.conf?
I am trying to make a portable mod_perl.conf. I have things like: Alias /cgi-bin/chimpkit/ /usr/local/apache/cgi-bin/chimpkit/ Location /cgi-bin/chimpkit/ SetHandler perl-script PerlHandler Apache::Registry Options +ExecCGI PerlSendHeader On /Location which really needs to become something like: Alias /cgi-bin/chimpkit/ $SERVER_ROOT/cgi-bin/chimpkit/ etc... I don't think I can do this directly with Apache but I found a random newsgroup thread that suggested something like the following might work: Perl push PerlConfig, EOF Alias /cgi-bin/chimpkit/ $ENV{'SERVER_ROOT'}/cgi-bin/chimpkit/ Location /cgi-bin/chimpkit/ SetHandler perl-script PerlHandler Apache::Registry Options +ExecCGI PerlSendHeader On /Location EOF /Perl Is this a good way to solve this problem, is there an easier way, and does this even work? :-) Thanks, Fran
Re: Can mod_perl help me use ENV variables in httpd.conf?
Yup. See the perl directive. Good description of how it works in the Eagle Book. -- Fran Fabrizio [EMAIL PROTECTED] I am trying to make a portable mod_perl.conf. I have things like: Alias /cgi-bin/chimpkit/ /usr/local/apache/cgi-bin/chimpkit/ Location /cgi-bin/chimpkit/ SetHandler perl-script PerlHandler Apache::Registry Options +ExecCGI PerlSendHeader On /Location which really needs to become something like: Alias /cgi-bin/chimpkit/ $SERVER_ROOT/cgi-bin/chimpkit/ etc... I don't think I can do this directly with Apache but I found a random newsgroup thread that suggested something like the following might work: Perl push @PerlConfig, EOF Alias /cgi-bin/chimpkit/ $ENV{'SERVER_ROOT'}/cgi-bin/chimpkit/ Location /cgi-bin/chimpkit/ SetHandler perl-script PerlHandler Apache::Registry Options +ExecCGI PerlSendHeader On /Location EOF /Perl Is this a good way to solve this problem, is there an easier way, and does this even work? :-) Thanks, Fran -- Steven Lembark 2930 W. Palmer Workhorse Computing Chicago, IL 60647 +1 800 762 1582
Re: Can mod_perl help me use ENV variables in httpd.conf?
Yikes, I just found an example of the exact thing I needed in the cookbook (recipe 2.16). Sorry, and thanks! -Fran
Re: Can mod_perl help me use ENV variables in httpd.conf?
I spoke too soon. I need: Perl push Alias, [ qw(/cgi-bin/chimpkit/ $ENV{SERVER_ROOT}/cgi-bin/chimpkit/) ]; /Perl This does not appear to be possible because there's no way to pass in SERVER_ROOT to the apache startup. I have SERVER_ROOT getting set in root's .bashrc, but when I execute ./apachectl start it appears to not pass in any ENV at all, and the server seems to set only a fewGATEWAY_INTERFACE, MOD_PERL and PATH. I can't use PerlSetEnv of course because I'm trying to make a portable mod_perl.conf in the first place. I can't use SetEnv in the httpd.conf because that doesn't get set until the fixup phase. Is there any way? -Fran Fran Fabrizio wrote: Yikes, I just found an example of the exact thing I needed in the cookbook (recipe 2.16). Sorry, and thanks! -Fran
Re: Can mod_perl help me use ENV variables in httpd.conf?
Fran Fabrizio wrote: I spoke too soon. I need: Perl push Alias, [ qw(/cgi-bin/chimpkit/ $ENV{SERVER_ROOT}/cgi-bin/chimpkit/) ]; /Perl This does not appear to be possible because there's no way to pass in SERVER_ROOT to the apache startup. I have SERVER_ROOT getting set in root's .bashrc, but when I execute ./apachectl start it appears to not pass in any ENV at all, and the server seems to set only a fewGATEWAY_INTERFACE, MOD_PERL and PATH. I can't use PerlSetEnv of course because I'm trying to make a portable mod_perl.conf in the first place. I can't use SetEnv in the httpd.conf because that doesn't get set until the fixup phase. Is there any way? what about: Perl warn ServerRoot: , Apache-server_root_relative; /Perl ? you also might want to do something with -D flags to httpd. it would mean editing apachectl, but then you could either do IfDefine ClientA do stuff or Perl $ServerRoot = 'ClientA' if Apache-defined('ClientA'); or somesuch. HTH --Geoff
Global (to page) variables under Apache::ASP
In my httpd.conf I have set 'PerlSetVar UseStrict 1' because I always use sctict anyway and I see in the docs that this might become the default too. So I always declare my variables with my(). Suppose I have a master ASP file that includes other scripts and these other scripts need access to the variables declrared in the master - no problem. But reading through the docs it looks like turning on DynamicIncludes would save alot of memory and be generally more efficient. Indeed, it would also protect the variables declared in one file from another because the includes are compliled and called as seperate subs. And here lies the problem, how to declare a vaiable in the master ASP file that is also in the scope of the dynamic include? -- Simon Oliver
Re: Global (to page) variables under Apache::ASP
Simon Oliver wrote: The Apache::ASP mailing list is at [EMAIL PROTECTED] ... please subscribe to it to post questions on this topic by emailing [EMAIL PROTECTED] Apache::ASP dev issues are officially off-topic on the mod_perl list now. More below on this issue... In my httpd.conf I have set 'PerlSetVar UseStrict 1' because I always use sctict anyway and I see in the docs that this might become the default too. So I always declare my variables with my(). Suppose I have a master ASP file that includes other scripts and these other scripts need access to the variables declrared in the master - no problem. But reading through the docs it looks like turning on DynamicIncludes would save alot of memory and be generally more efficient. Indeed, it would also protect the variables declared in one file from another because the includes are compliled and called as seperate subs. And here lies the problem, how to declare a vaiable in the master ASP file that is also in the scope of the dynamic include? You can stick with inline includes as you are doing, but DynamicIncludes are good, and you can pass values into them as subroutines: $Response-Includes($file, @args); # in $file % my @args = @_; % Just like a normal perl subroutine. For more on this, please see: http://www.apache-asp.org/objects.html#%24Response-%3EI2a8df2f3 You can also use globals, which you can declare for your entire application in your global.asa # global.asa use vars qw($Var1 $Var2); sub Script_OnStart { $Var1 = ''; $Var2 = 0; } I would strongly suggest you use locally scoped my() variables when possibly passing as @args to an include, but sometimes having a global can be handy which is why I mention the latter. --Josh _ Joshua Chamas Chamas Enterprises Inc. NodeWorks Founder Huntington Beach, CA USA http://www.nodeworks.com1-714-625-4051
Re: Are global variables truly global?
I have some state data that I need to persist between requests. At the moment these are COM objects, but they'll be ported to Perl Classes. It is quite important that only one of these instances exist per web server. These instances are too large to write and read to file on every request. So I have defined the variable as a package level variable. Package level variables are shared upon fork(), in the sense that the memory segment(s) they use is made available to all child processes. BUT the memory itself isn't shared, and any subsequent write to the variable in one of the children will not reflect in the others. So unless your state data is a constant, this is not what you want. -- Tout n'y est pas parfait, mais on y honore certainement les jardiniers Dominique Quatravaux [EMAIL PROTECTED]
RE: Are global variables truly global?
-Original Message- From: Chui G. Tey [mailto:[EMAIL PROTECTED]] package Apache::MyPkg; my $COM_instance; sub handler { if (!$COM_instance) { $COM_instance = Win32::OLE-new(ProgID.Class); } } Will the different child processes created by Apache share the same variable? Or will each child create an additional instance? It looks like you're using Win32, so you only get one process anyway - no children, no forking. All the other suggestions apply if you intend to be cross platform once you switch from COM to Perl objects though. Matt. _ This message has been checked for all known viruses by Star Internet delivered through the MessageLabs Virus Scanning Service. For further information visit http://www.star.net.uk/stats.asp or alternatively call Star Internet for details on the Virus Scanning Service.
Are global variables truly global?
I have some state data that I need to persist between requests. At the moment these are COM objects, but they'll be ported to Perl Classes. It is quite important that only one of these instances exist per web server. These instances are too large to write and read to file on every request. So I have defined the variable as a package level variable. I have been instantiating the variable in my handler() routine if it has not already been instantiated. ie. package Apache::MyPkg; my $COM_instance; sub handler { if (!$COM_instance) { $COM_instance = Win32::OLE-new(ProgID.Class); } } Will the different child processes created by Apache share the same variable? Or will each child create an additional instance? I'm happy to lose the data if Apache falls over. Chui Tey Software Engineer Advanced Data Integration PO Box 660 Spring Hill QLD 4004 AUSTRALIA Ph:07 3250 5300 Fax: 07 3250 5399 [mailto: [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] ]
Re: Are global variables truly global?
-- Chui G. Tey [EMAIL PROTECTED] I have some state data that I need to persist between requests. At the moment these are COM objects, but they'll be ported to Perl Classes. It is quite important that only one of these instances exist per web server. These instances are too large to write and read to file on every request. So I have defined the variable as a package level variable. I have been instantiating the variable in my handler() routine if it has not already been instantiated. ie. Global variables are exactly that: global. If you use something like: our $foo ||= somefunc; or our $foo = Someclass-constructor( @blah ); then you'll get a value that goes into the symbol table and is unique w/in the executing process. Thing you'll need to read up on are global variables, packages/namespaces and how use strict effects things (all of which are in the Camel or Llama books). -- Steven Lembark 2930 W. Palmer Workhorse Computing Chicago, IL 60647 +1 800 762 1582
Re: Are global variables truly global?
Will the different child processes created by Apache share the same variable? Or will each child create an additional instance? Each child has a separate interpreter and thus a separate instance of your global. If you need to co-ordinate data between processes, you might want to look at Cache::Cache or MLDBM::Sync. If you just need an exclusive lock, file locking is the simplest way to go. - Perrin
Environment variables and mod_perl
I'm working on a project that is highly configurable via environment variables. I'd like a way to get those environment variables into my mod_perl processes so that the mod_perl portion of this project can be configured the same way as the non mod_perl portions. I know that I can use PerlSetEnv and PerlPassEnv. I've used these with my current configuration and they work. The problem is this: I'd like a method to do this flexibly so that when one of my team created a new configuration environment variable, they don't need to change two files, the environment setup shell script and the httpd.conf file! All the environment variables begin with the name of our company in upper case letters, followed by an underscore character. This code prints them all out just perfectly outside of mod_perl: [tmornini@millenium conf]$ perl for my $env ( grep /^EWINGZ_/,keys %ENV ) { print $env\n; } EWINGZ_DBI_USERNAME EWINGZ_ERROR_DB EWINGZ_CODE_BASE EWINGZ_ASSERT_ASSERTIONS EWINGZ_LOG_FILE EWINGZ_LOG_BASE EWINGZ_LOG_SPREAD_GROUP EWINGZ_HOST_NAME EWINGZ_OBJECT_WO EWINGZ_LOG_UPPER_LEVEL EWINGZ_SPREAD_NAME EWINGZ_LOG_OBJECT EWINGZ_DBI_PASSWORD EWINGZ_LOG_LOWER_LEVEL EWINGZ_DBI_DATASOURCE EWINGZ_OBJECT_PR EWINGZ_OBJECT_RO EWINGZ_OBJECT_RW However, this code doesn't work so well in a Perl section in httpd.conf: Perl open FH,'/tmp/env.txt'; for my $env ( grep /^EWINGZ_/,keys %ENV ) { push @PerlPassEnv,$env; print FH $env\n; } print FH All done\n; close FH; /Perl After startup, 1) The environment variables are NOT passed and 2) /tmp/env.txt contains a single line: All done which means that at startup, these environment variables aren't available to Perl sections, either. This does jive with page 423 of the Eagle book. Stas' excellent Guide is somewhat confusing on this subject: http://perl.apache.org/guide/config.html To pass all environment variables to the children with a single configuration directive, rather than listing each one via PassEnv or PerlPassEnv, a Perl section could read in a file and: But this won't work for the same reason as above, namely, the environment variables are visible at that time, and I don't want to write a Perl script to parse a sh script! :-) Also, I think that pushing an arrayref into @PerlPassEnv doesn't seem to make sense since PerlPassEnv only takes a single argument. Looks like this is an error that the line should read: push @PerlSetEnv, [ $key = $val ]; Or have I been smoking again? :-) How can I get around this? Thanks for everyone's time and attention! Configuration: Server Version: Apache/1.3.20 (Unix) mod_perl/1.26 Server Built: Aug 28 2001 22:53:29 mod_perl.c, mod_log_spread.c, mod_access.c, mod_rewrite.c, mod_info.c, mod_status.c, mod_mime.c, http_core.c Linux version 2.4.2-2 ([EMAIL PROTECTED]) (gcc version 2.96 2731 (Red Hat Linux 7.1 2.96-79)) #1 Sun Apr 8 20:41:30 EDT 2001 -- Tom Mornini -- eWingz Systems, Inc. -- ICQ 113526784
Re: Converting Perl section variables into plain text directives
On Fri, 24 Aug 2001, Eric Hammond wrote: Is there any way to take the Apache::ReadConfig name space (variables set in Perl sections) and generate plain text Apache directives? I don't know if there is a simple answer to this one, but the way I would handle it is to scrap the Perl sections, and generate the entire config file using a standalone perl script. Then just change your apache start script to first generate the config file, and then start Apache. This way you get the best of both worlds! Your config file is dynamically generated, and you can create a light apache without mod_perl. Since you already have a half perl, half text config file, It would probably be quite easy to use one of the many Template modules out there to simplify this process... I guess a module that does this automatically would be interesting, but it would really only be useful to recover from some bad planning :) (and I guess we've all been there at one point or another) Cees For example, assuming some_function() returns myhost, I would like to convert the variables generated by: Perl $ServerName = some_function(); $Port = 80; /Perl into: ServerName myhost Port 80 I have a hypothetical situation where a friend of a friend spent a lot of time setting up a nice Perl configuration for an extended family of web servers with various requirements. He then realized that one of the requirements was that some of the web servers run without mod_perl (to serve static files and proxy requests to separate mod_perl servers). My hypothetical friend of a friend is very embarrassed. After studying the instructions given in the Eagle book on how to convert plain directives into Perl variables, it seems that it should be possible to traverse the name space in Apache::ReadConfig and unwind the directives into something that standard mod_perl-less Apache could process. In fact, I have embarked on a project to build just such a tool. Before I go too far, though, I thought it would be helpful to seek wisdom here. Perhaps somebody else has already done this? Perhaps mod_perl already has the code embedded in it that could be used? Perhaps some wish to tell me it is near impossible in the general case and I should abandon my foolish quest? Of course, I realize that the output generated will not be able to duplicate any side-effects or dynamic nature of code in the Perl sections. One of the requirements for using this utility will be that you only need the end results stored in Apache::ReadConfig. I would be interested in suggestions for package naming if I do succeed to an extent that others might be interested in using it. Should I create a new method in the Apache::PerlSections name space or would this be stepping on Doug's toes? Please do let me know if anybody else has a use for such a tool. This will help me figure out how much time I should spend trying to handle the general cases instead of just writing it to meet my... er, my friend's... specific needs. Thanks -- Eric Hammond [EMAIL PROTECTED] -- Cees Hek SiteSuite Corporation [EMAIL PROTECTED]
Re: Global variables
On Wed, May 16, 2001 at 07:13:22AM +0200, Bjoern wrote: i want to define a global variable which is also present in subroutines coded in extra perl modules. I tried this our $test; but amod_perl tells me following Global symbol $test requires explicit package name I know, this is a question which may be not right here ! I don`t want to use the perlmodule CGI !! I hope some persons can help me, primarily, global variables are looked down upon. but like the error message says, you can explicitly name any global like this: $The::Meaning::Of::Life::The::Universe::And::Everything = 42; you might also try use vars($Something); $Something = whatever(); but you should probably use closures and references instead. (i'll be re-coding my website to avoid globals in the next few weeks, now that i understand what i just said, there. :) see also http://thingy.kcilink.com/modperlguide/porting/Dynamically_updating_configurati.html -- What do I need manners for? I already got me a wife. -- Adam Pontipee, Seven Brides for Seven Brothers [EMAIL PROTECTED] http://sourceforge.net/projects/newbiedoc -- we need your brain! http://www.dontUthink.com/ -- your brain needs us!
Global variables
Hi all, i want to define a global variable which is also present in subroutines coded in extra perl modules. I tried this our $test; but amod_perl tells me following Global symbol $test requires explicit package name I know, this is a question which may be not right here ! I don`t want to use the perlmodule CGI !! I hope some persons can help me, Björn P.S. i also used the module strict !!! -- *** Bjoern Teipel *** E-Mail : mailto:[EMAIL PROTECTED] HTTP: http://www.visit-bjoern.de Frankfurt am Main * Germany
Re: Environment variables in startup.pl
Scott Alexander ([EMAIL PROTECTED]) said something to this effect on 04/27/2001: Should this work in a startup.pl file my $hostname = $ENV{HOSTNAME} ; from the prompt I can write echo $HOSTNAME and get the correct hostname of the server. But from within startup.pl I don't get it. Scott use Sys::Hostname; $host = hostname; (darren) -- vi, vi, vi - the Editor of the Beast
[OT] How to write this perl sub w/o variables?
Is it possible to rewrite this perl subroutine without using variables? sub XMLEncode { my ($line) = @_; $line =~ s//amp;/g; $line =~ s//lt;/g; $line =~ s//gt;/g; return $line; } I was thinking something like sub XMLEncode { s//amp;/g; s//lt;/g; s//gt;/g; return $_; } but I can't get it to work like that. -Philip Mak ([EMAIL PROTECTED])
Re: [OT] How to write this perl sub w/o variables?
On Sun, Apr 29, 2001 at 04:34:40AM -0400, Philip Mak wrote: I was thinking something like sub XMLEncode { local $_ = shift; s//amp;/g; s//lt;/g; s//gt;/g; return $_; } -- Honza Pazdziora | [EMAIL PROTECTED] | http://www.fi.muni.cz/~adelton/ .project: Perl, DBI, Oracle, MySQL, auth. WWW servers, DBD::XBase.
Re: [OT] How to write this perl sub w/o variables?
On Sun, 29 Apr 2001, Philip Mak wrote: Is it possible to rewrite this perl subroutine without using variables? sub XMLEncode { my ($line) = @_; $line =~ s//amp;/g; $line =~ s//lt;/g; $line =~ s//gt;/g; return $line; } I was thinking something like sub XMLEncode { s//amp;/g; s//lt;/g; s//gt;/g; return $_; } but I can't get it to work like that. don't reinvent the wheel, use CPAN: # get the encoding sub right if ($ENV{MOD_PERL}) { require Apache::Util; # much faster! XS/C code! *encode = \Apache::Util::escape_html; } else { require HTML::Entities; *encode = \HTML::Entities::encode; } then call encode($mytext); not talking about the fact that your code is highly inefficient (you run s/// 3 times!!!), at least use a hash: %map = ( '' = 'amp', '' = 'lt', '' = 'gt', ); sub encode { $_[0] =~ s/(||)/$map{$1}/g; } note that this will fail: encode(hello), because you will try to modify a constant string (versus, $a = 'hello'; encode($a)). hope this helps... _ Stas Bekman JAm_pH -- Just Another mod_perl Hacker http://stason.org/ mod_perl Guide http://perl.apache.org/guide mailto:[EMAIL PROTECTED] http://apachetoday.com http://logilune.com/ http://singlesheaven.com http://perl.apache.org http://perlmonth.com/
Re: Environment variables in startup.pl
Hi there, On Fri, 27 Apr 2001, Philip Mak wrote: On Fri, 27 Apr 2001, Scott Alexander wrote: Should this work in a startup.pl file my $hostname = $ENV{HOSTNAME} ; from the prompt I can write echo $HOSTNAME and get the correct hostname of the server. But from within startup.pl I don't get it. Try this: my $hostname = `/bin/hostname`; Or better still: http://perl.apache.org/guide 73, Ged.
Environment variables in startup.pl
Should this work in a startup.pl file my $hostname = $ENV{HOSTNAME} ; from the prompt I can write echo $HOSTNAME and get the correct hostname of the server. But from within startup.pl I don't get it. Scott
Re: Environment variables in startup.pl
On Fri, 27 Apr 2001, Scott Alexander wrote: Should this work in a startup.pl file my $hostname = $ENV{HOSTNAME} ; from the prompt I can write echo $HOSTNAME and get the correct hostname of the server. But from within startup.pl I don't get it. The reason echo $HOSTNAME works from the prompt is because /etc/profile contains the command HOSTNAME=`/bin/hostname`. When you're in a non-interactive environment, that's not available. Try this: my $hostname = `/bin/hostname`; -Philip Mak ([EMAIL PROTECTED])
Global Variables Question
Hello All, I apologize if this is in a FAQ somewhere. I have a script, lets call it test.pl. Test.pl requires in config.pl. Test.pl uses variables (via use vars) from config.pl. These variables are defined and given values in config.pl. AFter the first usage of test.pl, the variables we are pulling in from config.pl no longer have values. So it's something like this: config.pl use vars ($G_ROOTPATH); $G_ROOTPATH = /home/warren; config.pl test.pl require config.pl; use vars ($G_ROOTPATH); # at this point, G_ROOTPATH is inherited from config.pl and has the value of /home/warren test.pl On the first run of the script G_ROOTPATH in test.pl has the value of home/warren... subsequent runs, it does not. I'm a little confused as to exact ways modperl handles global variables. Anyone have a simple tweak for this? Or do I have to make a config package? Thanks in advance!
Re: Global Variables Question
http://perl.apache.org/guide/porting.html#Configuration_Files_Writing_Dy Guide Good! Warren D. Johnson wrote: Hello All, I apologize if this is in a FAQ somewhere. I have a script, lets call it test.pl. Test.pl requires in config.pl. Test.pl uses variables (via use vars) from config.pl. These variables are defined and given values in config.pl. AFter the first usage of test.pl, the variables we are pulling in from config.pl no longer have values. So it's something like this: config.pl use vars ($G_ROOTPATH); $G_ROOTPATH = /home/warren; config.pl test.pl require config.pl; use vars ($G_ROOTPATH); # at this point, G_ROOTPATH is inherited from config.pl and has the value of /home/warren test.pl On the first run of the script G_ROOTPATH in test.pl has the value of home/warren... subsequent runs, it does not. I'm a little confused as to exact ways modperl handles global variables. Anyone have a simple tweak for this? Or do I have to make a config package? Thanks in advance!
Re: mod_perl forgets filled global variables
Hi Werner, On Fri, 30 Mar 2001, werner.schmidt-wilczek wrote: I am using mod_perl for our Intranet. The performance is great, but there are many sideeffects! http://perl.apache.org/guide :) sometimes it seems mod_perl has forgotten the array. There are many ways of sharing data between your processes, and this is a topic often discussed on this List. You might like to search the archives for things like DBM, tied hash, database, shared data, shared variables. There are links to search engines on the mod_perl home page. Also there are one or two things in the DIGEST which might interest you, it has many useful references. 73, Ged.
mod_perl forgets filled global variables
Hi, my name is Werner Schmidt-Wilczek, i am a programmer at the Policegovernment in Nuremberg, Bavaria, Germany. I am using mod_perl for our Intranet. The performance is great, but there are many sideeffects! An example: I have a database with 5 items. I load this items one time in a hour in a array named ARTIKEL. The array ARTIKEL ist declared in /usr/inclued/apache/modules/perl/startup.perl - i think its global an correct in this way - all users can search in this array. But sometimes it seams mod_perl has forgotten the array. I call my script 4,5... times, it runs correct but perhaps it has forgotten all the global filled variables - what happens. I called the Dumper \@ARTIKEL and he says the array is filled, but next time the array is empty - what is my failure??? Please help me I am looking forward to your answer with greetings Werner Schmidt-Wilczek
Re: perl5.6 (was: Shared variables, inner subs and our)
Unfortunately it is a requirement for this project. We need to parse utf8 XML and munge other XML using that data. I seem to have everything working now although I had to fix some stuff in XML::DOM. --Jauder On Sun, 18 Mar 2001, Bogomolnyi Constantin wrote: Hi , Unicode is a way of pain . don't go this way . specialy in 5.7.0 were it is broken . 5.6.0 is well you know what . There is many other systems to hold multilingual apps , that not require any unicode . I use 5.7.0 in production (i386 , BSD 4.2) and it runs perfectly . Except unicode support. 5.6.0 has a lot of bugs (witch were fixed in 5.7.0) Best Cb - Original Message - From: "Jauder Ho" [EMAIL PROTECTED] To: "Bogomolnyi Constantin" [EMAIL PROTECTED] Sent: Monday, March 19, 2001 8:44 AM Subject: Re: perl5.6 (was: Shared variables, inner subs and "our") Hello there, could you detail a little more about your Unicode experience with perl? I am currently evaluating what the best verion of perl to use for a multilingual application. Thanks. --Jauder On Fri, 16 Mar 2001, Bogomolnyi Constantin wrote: Hi , You should probably try 5.7.0 witch is much more stable than 5.6.0 (you should not try unicode stuff , whitch is quite buggy) I use 5.7.0 on all my production servers without any problems . Best - Original Message - From: "Wim Kerkhoff" [EMAIL PROTECTED] To: "modperl" [EMAIL PROTECTED] Sent: Saturday, March 17, 2001 6:20 AM Subject: Re: perl5.6 (was: Shared variables, inner subs and "our") Stas Bekman wrote: our() and other perl5.6 new APIs are too early to be endorsed, as 5.6 is not yet considered as a stable version for mod_perl production sites, therefore the guide barely touches on it. Would you recommend the use of perl5.6 with mod_perl? What you are saying is making me queasy. I'm asking because I've been having bad luck with Apache::Session and some other modules in some mod_perl aware applications. Things aren't comming out the data source properly, things are hanging, things aren't locking/unlocking properly, etc. It could well be that the applications I'm working with aren't using Sessions, Tie::Cache, etc properly. I may downgrade to perl5.005 and give that a whirl... -- Regards, Wim Kerkhoff
Re: perl5.6 (was: Shared variables, inner subs and our)
Hi , Unicode is a way of pain . don't go this way . specialy in 5.7.0 were it is broken . 5.6.0 is well you know what . There is many other systems to hold multilingual apps , that not require any unicode . I use 5.7.0 in production (i386 , BSD 4.2) and it runs perfectly . Except unicode support. 5.6.0 has a lot of bugs (witch were fixed in 5.7.0) Best Cb - Original Message - From: "Jauder Ho" [EMAIL PROTECTED] To: "Bogomolnyi Constantin" [EMAIL PROTECTED] Sent: Monday, March 19, 2001 8:44 AM Subject: Re: perl5.6 (was: Shared variables, inner subs and "our") Hello there, could you detail a little more about your Unicode experience with perl? I am currently evaluating what the best verion of perl to use for a multilingual application. Thanks. --Jauder On Fri, 16 Mar 2001, Bogomolnyi Constantin wrote: Hi , You should probably try 5.7.0 witch is much more stable than 5.6.0 (you should not try unicode stuff , whitch is quite buggy) I use 5.7.0 on all my production servers without any problems . Best - Original Message - From: "Wim Kerkhoff" [EMAIL PROTECTED] To: "modperl" [EMAIL PROTECTED] Sent: Saturday, March 17, 2001 6:20 AM Subject: Re: perl5.6 (was: Shared variables, inner subs and "our") Stas Bekman wrote: our() and other perl5.6 new APIs are too early to be endorsed, as 5.6 is not yet considered as a stable version for mod_perl production sites, therefore the guide barely touches on it. Would you recommend the use of perl5.6 with mod_perl? What you are saying is making me queasy. I'm asking because I've been having bad luck with Apache::Session and some other modules in some mod_perl aware applications. Things aren't comming out the data source properly, things are hanging, things aren't locking/unlocking properly, etc. It could well be that the applications I'm working with aren't using Sessions, Tie::Cache, etc properly. I may downgrade to perl5.005 and give that a whirl... -- Regards, Wim Kerkhoff
Re: perl5.6 (was: Shared variables, inner subs and our)
Hi , You should probably try 5.7.0 witch is much more stable than 5.6.0 (you should not try unicode stuff , whitch is quite buggy) I use 5.7.0 on all my production servers without any problems . Best - Original Message - From: "Wim Kerkhoff" [EMAIL PROTECTED] To: "modperl" [EMAIL PROTECTED] Sent: Saturday, March 17, 2001 6:20 AM Subject: Re: perl5.6 (was: Shared variables, inner subs and "our") Stas Bekman wrote: our() and other perl5.6 new APIs are too early to be endorsed, as 5.6 is not yet considered as a stable version for mod_perl production sites, therefore the guide barely touches on it. Would you recommend the use of perl5.6 with mod_perl? What you are saying is making me queasy. I'm asking because I've been having bad luck with Apache::Session and some other modules in some mod_perl aware applications. Things aren't comming out the data source properly, things are hanging, things aren't locking/unlocking properly, etc. It could well be that the applications I'm working with aren't using Sessions, Tie::Cache, etc properly. I may downgrade to perl5.005 and give that a whirl... -- Regards, Wim Kerkhoff
Re: perl5.6 (was: Shared variables, inner subs and our)
On Fri, 16 Mar 2001, Bogomolnyi Constantin wrote: You should probably try 5.7.0 witch is much more stable than 5.6.0 (you should not try unicode stuff , whitch is quite buggy) I use 5.7.0 on all my production servers without any problems . 5.7.0 may have fixed some of the bugs of 5.6.0 but it is a dev release (anything where the subversion is odd is a dev release). I don't think anyone working on the Perl core would recommend the use of a dev release in production unless you absolutely need a piece of functionality present in that particular dev release. I'd suggest using 5.00503 until 5.6.1 comes out, which should fix lots of bugs. -dave /*== www.urth.org We await the New Sun ==*/
Shared variables, inner subs and our
Hi, I was just tidying up an old mod_perl script which had some ugly "use vars qw(...);" lines in it which I thought I'd replace with "our ...;". I realise this isn't always a good idea since "our" is not intended as a replacement for "use vars", but its often OK and I thought it would be in my case. I was only half right: The script still works fine, but emits warnings which it previously didn't about "variable will not stay shared". The mod_perl Guide (1.28) refers to such problems in section 3.5: It gives as an example the following program: use strict; use warnings; sub print_power_of_2 { my $x = shift; sub power_of_2 { return $x ** 2; } my $result = power_of_2(); print "$x^2 = $result\n"; } print_power_of_2(5); print_power_of_2(6); This prints: Variable "$x" will not stay shared at ./nested.pl line 7. 5^2 = 25 6^2 = 25 The solution is to use a package-global $x which won't get deep-bound into power_of_2(): use strict; use warnings; sub print_power_of_2 { use vars qw($x); $x = shift; sub power_of_2 { return $x ** 2; } my $result = power_of_2(); print "$x^2 = $result\n"; } print_power_of_2(5); print_power_of_2(6); This prints: 5^2 = 25 6^2 = 36 However, if you change the ugly "use vars" to the sexier-although-not-quite-the-same "our": use strict; use warnings; sub print_power_of_2 { our $x = shift; sub power_of_2 { return $x ** 2; } my $result = power_of_2(); print "$x^2 = $result\n"; } print_power_of_2(5); print_power_of_2(6); then it prints: Variable "$x" will not stay shared at ./nested.pl line 7. 5^2 = 25 6^2 = 36 !!! In other words, we get a bizarre cross between the two: the warning about $x not staying shared is emitted, but of course its nonsense (?) because package-globals don't get deep-bound into subroutines anyway, and the program actually works fine! The eagle-eyed will have noticed that the above "use vars" solution is not *exactly* as presented in the mod_perl Guide: the solution there puts the "use vars" *outside" of the declaration of print_power_of_2(), not *inside* as above. This, of course, makes no difference to "use vars" which affects the package, not a lexical scope. But it *does* make a big difference to "our", which applies to a lexical scope, not a package: If we move the "our" *outside* of the declaration of print_power_of_2(): use strict; use warnings; our $x; sub print_power_of_2 { $x = shift; sub power_of_2 { return $x ** 2; } my $result = power_of_2(); print "$x^2 = $result\n"; } print_power_of_2(5); print_power_of_2(6); then the confusing warning goes away: 5^2 = 25 6^2 = 36 Why am I bringing this up? (a) because I think the mod_perl Guide needs to mention the use of "our" as well as "use vars" (they're only very briefly mentioned, regarding something else, in section 10.6.5); (b) because I can't actually do what I just did above in my mod_perl script! I run my mod_perl script under Apache::Registry, which (as we all know) makes the script into a subroutine, and therefore any subroutines into inner subroutines. In the example above, print_power_of_2() is like my script, power_of_2() is like a subroutine in my script, and the two calls to print_power_of_2() are like my script being run twice. Obviously I can't move the "our" declaration *outside* my script like I did above (unless Apache::Registry did this for me when it does its stuff with my script), so I'm stuck with the warning (or else "use vars"). Is there some reason why the warning gets emitted with "our" inside print_power_of_2()? Was I just lucky that this particular example worked and I should really heed the warning, or is the warning actually bogus? Is there any way I can use "our" rather than "use vars" and not get these warnings? - Steve Hay
Re: Shared variables, inner subs and our
not really answering your questions, but Ragarding moving the "our()" statement out of the function -- --- Steve Hay [EMAIL PROTECTED] wrote: (b) because I can't actually do what I just did above in my mod_perl script! Couldn't you, if you put the func's into a module and our()'d it there, then use()'d it from your script? I realize that sort of redesign might not be convenient, but wouldn't it work? __ Do You Yahoo!? Get email at your own domain with Yahoo! Mail. http://personal.mail.yahoo.com/
Re: Shared variables, inner subs and our
On Fri, 16 Mar 2001, Paul wrote: not really answering your questions, but Ragarding moving the "our()" statement out of the function -- --- Steve Hay [EMAIL PROTECTED] wrote: (b) because I can't actually do what I just did above in my mod_perl script! Couldn't you, if you put the func's into a module and our()'d it there, then use()'d it from your script? I realize that sort of redesign might not be convenient, but wouldn't it work? That's exactly what I was going to anwer. The example in the guide *demonstrates* the problem and possible workarounds for it. But it states that the best approach is to have your registry script with a single call to some method in another module, which solves all the problems. Of course you can go for workarounds, but those will haunt you until you will give up and redesign (move the code out of the script). If you need a quick solution with no redesign, you have it in the guide. our() and other perl5.6 new APIs are too early to be endorsed, as 5.6 is not yet considered as a stable version for mod_perl production sites, therefore the guide barely touches on it. _ Stas Bekman JAm_pH -- Just Another mod_perl Hacker http://stason.org/ mod_perl Guide http://perl.apache.org/guide mailto:[EMAIL PROTECTED] http://apachetoday.com http://logilune.com/ http://singlesheaven.com http://perl.apache.org http://perlmonth.com/
Re: perl5.6 (was: Shared variables, inner subs and our)
Stas Bekman wrote: our() and other perl5.6 new APIs are too early to be endorsed, as 5.6 is not yet considered as a stable version for mod_perl production sites, therefore the guide barely touches on it. Would you recommend the use of perl5.6 with mod_perl? What you are saying is making me queasy. I'm asking because I've been having bad luck with Apache::Session and some other modules in some mod_perl aware applications. Things aren't comming out the data source properly, things are hanging, things aren't locking/unlocking properly, etc. It could well be that the applications I'm working with aren't using Sessions, Tie::Cache, etc properly. I may downgrade to perl5.005 and give that a whirl... -- Regards, Wim Kerkhoff
Re: perl5.6 (was: Shared variables, inner subs and our)
On Fri, 16 Mar 2001, Wim Kerkhoff wrote: Stas Bekman wrote: our() and other perl5.6 new APIs are too early to be endorsed, as 5.6 is not yet considered as a stable version for mod_perl production sites, therefore the guide barely touches on it. Would you recommend the use of perl5.6 with mod_perl? What you are saying is making me queasy. I'm asking because I've been having bad luck with Apache::Session and some other modules in some mod_perl aware applications. Things aren't comming out the data source properly, things are hanging, things aren't locking/unlocking properly, etc. It could well be that the applications I'm working with aren't using Sessions, Tie::Cache, etc properly. I may downgrade to perl5.005 and give that a whirl... Please search the archives. There were reports of problems with perl5.6, Doug has submitted quite a few fixes for 5.6 to make it working with mod_perl. I'm not sure whether perl5.6-PATCH2 is bugless with regard to mod_perl. Not to mention possible problems that has nothing to do with mod_perl, but are general Perl issues. Therefore I still use 5.00503 on my production sites. But some people are using 5.6 without any problems on their production sites. _ Stas Bekman JAm_pH -- Just Another mod_perl Hacker http://stason.org/ mod_perl Guide http://perl.apache.org/guide mailto:[EMAIL PROTECTED] http://apachetoday.com http://logilune.com/ http://singlesheaven.com http://perl.apache.org http://perlmonth.com/
Re: PerlRun problem: undefined variables (Was: can't find method uri)
On Thu, 11 Jan 2001, Doug MacEachern wrote: On Thu, 4 Jan 2001, Jie Gao wrote: Another problem with PerlRun is that it seems to interfere with mod_perl handlers. I have an authentication/authorisation handler, which reads in from a file for someinformation. After a script under PerlRun is run, the handler fails to read anything from that file anymore. i can't see what's happening from this, too much missing. can you provide a small, but complete drop-in test case? Sorry for this late reply, Doug. Here are some details. This is from my authentication handler, which gets the location of a file from a PerlSetVar directive, and then opens the file and reads username and password into the variables to be used for database connection: --- my ($dsf, $db_f_name, $db_user_name, $db_user_pwd, $ds_name, $AuthenQueryValue); # Get the db data source file. $dsf = $r-dir_config( 'DSF' ); if (!defined $dsf || $dsf eq '') { $r-log_error("DSF not defined.") if ($debug 3); return SERVER_ERROR; } # Get the db server login info. if (defined $dsf) { open(DBCONF, "$dsf") || $r-log_error("Can't open DSF file $dsf:$!"); while(DBCONF){ next if /^#/; next unless /^$ds_name:/; chomp; ($ds_name, $db_f_name, $db_user_name, $db_user_pwd) = split(':', $_); $r-log_error("In loop: ds_name=\"$ds_name\", db_f_name=\"$db_f_name\", db_user_name=\"$db_user_name\ ", db_user_pwd=\"$db_user_pwd\"\n") if ($debug 3); last; } close DBCONF; } else { $r-log_reason("DB source file not defined.") if ($debug 3); return SERVER_ERROR; } unless (defined $db_f_name defined $db_user_name defined $db_user_pwd) { $r-log_reason("DB source file error: definition incomplete: db_f_name=\"$db_f_name\"; db_user_name=\"$db _user_name\"; db_user_pwd=\"$db_user_pwd\".") if ($debug 3); return SERVER_ERROR; } --- Now from time to time these variables become undefined, as shown in the error_log: [Sat Feb 10 12:30:13 2001] [error] access to / failed for 129.xx.xx.xx, reason: DB source file error: definition incomplete: db_f_name=""; db_user_name=""; db_user_pwd="". This happens with 1.25 as well. Hardcoding the variables prevents this from happening. Regards, Jie
RE: Help: Can't use string (Exchange::Account::My) as a HASH ref while strict refs in use trying to use instance variables in my handler
Anyway, what you should do is create a constructor: sub new { [snip] You mean like this code segment that I included in my original post just below the handler code :) sub init { [snip] Ah yes, but you called your's "init", which is quite misleading to those of us who tend not to pay attention. Wait a second. I have a startup.pl, and inside that I have the lines: use Exchange::Account::My; my $account_interface = Exchange::Account::My-init; Won't that do what I need it to do? When the root process forks off children, won't a complete copy of $account_interface go with it, with everything all set and ready to go? I wouldn't think that this would be the case, but I may be mistaken. Since you've declared $account_interface with 'my', that variable should only be available within the scope of the startup.pl script. Even if you went with use vars qw($account_interface); I still don't think that it would be available in the Exchange::Account::My namespace. Except for calling the contructor with every call of the handler, I think I've done everything right. Isn't the part of idea behind mod_perl handlers that one _doesn't_ have to call the contructor _every_ time the handler gets called? Otherwise invites massive overhead. Is a bless really massive overhead? I can't say as I've ever had a problem calling the constructor with every request (at least with simple objects). Obviously, what I'm doing doesn't work. But could someone show me how to call the constructor just once in in a childs lifetime? startup.pl is not the place to do this - it gets called at server start-up (or restart), not child initialization. What you could do is create a ChildInitHandler for this class, which sets a global variable within your package: use vars qw($SELF); sub configure { my ($class) = shift; Apache-push_handlers( PerlChildInitHandler = sub { # use that weird "init" constructor name $SELF = $class-init(@_); } ); } You can then change your handler to not use the $$ prototype, but get an object reference from $SELF: sub handler { my $q = shift; my $self = $SELF; # the rest of your code as is... } In your startup.pl, you'd have: use Exchange::Account::My; Exchange::Account::My-configure(); I haven't tested that. As I said, I've never had call to create the object only upon child initialization. I'll be the first to admit that I'm relatively new to the mod_perl thing, so there may be an easier or more elegant way to do this, but that ought to work. Hope that helps. Chris
RE: Help: Can't use string (Exchange::Account::My) as a HASH ref while strict refs in use trying to use instance variables in my handler
Subject: Help: Can't use string ("Exchange::Account::My") as a HASH ref while "strict refs" in use trying to use instance variables in my handler [snip] sub handler ($$) { my ($self, $q) = @_; my $r= Apache::Request-new($q); $self-child_init unless $self-{_child_started_up}; # dies here! [snip] I think that you really need to have a legitimate constructor, not one that is called conditionally. $self is not a blessed reference - just a string containing the class name. The call to $self-child_init works, even with strict refs, because there is a child_init subroutine defined in your package's namespace. With $self-{_child_started_up}, you're just calling "Exchange::Account::My"-{_child_started_up}, which will cause the error since the string "Exchange::Account::My" is not a reference to a hash, it's just a string. Anyway, what you should do is create a constructor: sub new { my $class = shift; my $self {@_}; bless $self, $class; return $self; } Then rewrite the above snippet of your code to: sub handler ($$) { my ($class, $q) = @_; my $r = Apache::Request-new($q); my $self = $class-new(request=$r); $self-child_init unless $self-{_child_started_up}; # The rest of the code... Then you should be good to go (instance variables and all!). Hope that helps, Chris
Re: Help: Can't use string (Exchange::Account::My) as a HASH ref while strict refs in use trying to use instance variables in my handler
Anyway, what you should do is create a constructor: sub new { my $class = shift; my $self {@_}; bless $self, $class; return $self; } You mean like this code segment that I included in my original post just below the handler code :) sub init { my $invocant = shift; my $class = ref ($invocant) || $invocant; my $self = {}; bless ($self, $class); $self-{config}= $self-init_config; $self-{dispatch} = $self-init_dispatch_table; $self-{templates} = $self-init_templates; $self-{_child_started_up} = 0; return $self; } ... straight out of "Programming Perl" ... Then rewrite the above snippet of your code to: sub handler ($$) { my ($class, $q) = @_; my $r = Apache::Request-new($q); my $self = $class-new(request=$r); Hunh?!? Wait a second. I have a startup.pl, and inside that I have the lines: use Exchange::Account::My; my $account_interface = Exchange::Account::My-init; Won't that do what I need it to do? When the root process forks off children, won't a complete copy of $account_interface go with it, with everything all set and ready to go? $self-child_init unless $self-{_child_started_up}; # The rest of the code... Then you should be good to go (instance variables and all!). Hope that helps, Chris Except for calling the contructor with every call of the handler, I think I've done everything right. Isn't the part of idea behind mod_perl handlers that one _doesn't_ have to call the contructor _every_ time the handler gets called? Otherwise invites massive overhead. Obviously, what I'm doing doesn't work. But could someone show me how to call the constructor just once in in a childs lifetime? Please? --Christopher
Re: Text::Template and passing in variables; going bug nuts!
Maybe I'm missing something here, but can't you just use use strict; use vars qw(%config %session); or better yet, fully qualify your variables %MyApp::Framework::config; %MyApp::Framework::session; The mod_perl guide has excellent sections on this: http://perl.apache.org/guide/perl.html#Using_Global_Variables_and_Shari http://perl.apache.org/guide/performance.html#Global_vs_Fully_Qualified_Varia Also, there are a couple of useful modules on CPAN for inheriting class data, not sure if they will apply in your case: http://cpan2.org/Asset/display?dist=Class-Data-Inheritable http://cpan2.org/Asset/display?dist=foundation Where I'm getting hosed is that %config and %session have data I need visible to the Text::Template objects themselves. I've RTFM'ed until my eyes are pink, and I see no options short of copying variables wholesale into another Package, but then I still can't get at them and "use strict" can I? _ T.J. Mather http://tjmather.com http://cpan2.org/ New CPAN Search Engine http://www.anidea.com/ Digital Asset Management http://www.theinnkeeper.com/Bed and Breakfast Directory