<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://panoptic.com/mediawiki/aolserver/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Juanjose</id>
	<title>AOLserver Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://panoptic.com/mediawiki/aolserver/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Juanjose"/>
	<link rel="alternate" type="text/html" href="https://panoptic.com/wiki/aolserver/Special:Contributions/Juanjose"/>
	<updated>2026-04-22T04:25:59Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5115</id>
		<title>AOLserver Cookbook</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5115"/>
		<updated>2008-01-10T16:49:10Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A collection of questions, and code examples to answer them.&lt;br /&gt;
&lt;br /&gt;
Add your questions here.  Answers should be placed below the question.  Place a horizontal line (&amp;quot;----&amp;quot;) between questions.  Please keep this text before the first question.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Limiting bandwidth ==&lt;br /&gt;
&lt;br /&gt;
Is there a simple way to limit bandwidth per connection/ip???&lt;br /&gt;
&lt;br /&gt;
: There's no simple way of doing it, i.e., no configuration option you can set.  If I had to implement this, I'd use NSV's and [[ns_register_filter]] to keep track of bandwidth consumed by each client IP which can act as an all-or-nothing mechanism.  However, what might be interesting to implement in the socket driver is a setting to control the rate at which bytes are written back to the socket, perhaps configurable per request, so that large HTTP responses don't soak up your upstream bandwidth.  We should keep this in mind for a future version of AOLserver. ''-- [[User:Dossy|Dossy]] 20:06, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
One more question... How can I read output buffer inside function registered as postauth filter?&lt;br /&gt;
And how can I stream it? ns_adp_puts cannot be used inside filters... ns_return would return all data at once. I assume that per connection limit would look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc ..... {&lt;br /&gt;
ns_adp_stream&lt;br /&gt;
set data [get output content buffer]&lt;br /&gt;
set data_length [output buffer size]&lt;br /&gt;
set block_size 4096&lt;br /&gt;
for {set i 0} {$i &amp;lt; $data_length} {incr i $block_size} {&lt;br /&gt;
   send_to_client [string range $data [expr $block_size*$i] [expr $block_size*[expr$i+1]]]&lt;br /&gt;
   sleep 1&lt;br /&gt;
}&lt;br /&gt;
ns_returnok&lt;br /&gt;
return filter_return&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
I want to limit only one vhost so nssock limit would be too much;)&lt;br /&gt;
&lt;br /&gt;
: First, you don't want to turn [[ns_adp_stream]]'ing on.  Getting the size of the ADP output buffer can be done using [[ns_adp_tell]] and getting the contents with [[ns_adp_dump]].  I guess you could [[ns_adp_trunc]] the output buffer to clear it, then slowly write the contents back using [[ns_write]].  You'd also then need to look at [[ns_conn]] '''outputheaders''' to make sure that you wrote the proper HTTP response ... ah, but I don't know if you can get the HTTP response status code somehow.  I still think doing it in nssock is probably the best place, even with vhosts -- I'd make it a preauth or postauth filter that sets the configuration for the response and then have nssock be responsible for ensuring the response is written at that rate. ''-- [[User:Dossy|Dossy]] 07:24, 8 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
ns_adp_tell inside postauth filter:&lt;br /&gt;
   Error: This function cannot be used outside of an ADP&lt;br /&gt;
what's more, i use ns_returnfile inside some adp code and if i use ns_adp_tell after it, it returns 0 (this adp only returns file, no adp_puts or write).&lt;br /&gt;
Unfortunetly i think there is no other solution then implement it inside nssock or implement some tcl code to manipulate all output buffer.&lt;br /&gt;
&lt;br /&gt;
I use this code for big files... some time I'll add per ip limit, now it's for connection.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc returnfile { file } {                                                      &lt;br /&gt;
    set filefp [open $file r]                                                   &lt;br /&gt;
    fconfigure $filefp -translation binary                                      &lt;br /&gt;
    set data_length [file size $file]                                           &lt;br /&gt;
    set block_size 4096                                                         &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_write &amp;quot;HTTP/1.0 200 OK                                                   &lt;br /&gt;
MIME-Version: 1.0                                                               &lt;br /&gt;
Content-Type: [ns_guesstype $file]                                              &lt;br /&gt;
Content-Length: $data_length                                                    &lt;br /&gt;
                                                                                &lt;br /&gt;
&amp;quot;                                                                               &lt;br /&gt;
    while { ! [eof $filefp] } {                                                 &lt;br /&gt;
        ns_writefp $filefp $block_size                                          &lt;br /&gt;
        ns_sleep 1                                                              &lt;br /&gt;
    }                                                                           &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_conn close                                                               &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Paul Bukowski&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Virtual server configuration ==&lt;br /&gt;
&lt;br /&gt;
Is it possible to use wildcard '*' in domain name inside &amp;quot;ns/module/nssock/servers&amp;quot; section of aolserver4 config file? I would like to map all requests to *.somedomain.org to one virtual host...&lt;br /&gt;
Something like this doesn't work:&lt;br /&gt;
&lt;br /&gt;
 ns_section &amp;quot;ns/module/nssock/servers&amp;quot;&lt;br /&gt;
 ns_param   forum           somedomain.org                                           &lt;br /&gt;
 ns_param   forum           somedomain.org:80                                        &lt;br /&gt;
 ns_param   forum           *.somedomain.org                                       &lt;br /&gt;
 ns_param   forum           *.somedomain.org:80&lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org&amp;quot;                                       &lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org:80&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-Paul Bukowski&lt;br /&gt;
&lt;br /&gt;
: ''2005aug15 [[Dossy]]: Unfortunately, no -- you currently can't use wildcards the way you want.  Not yet, at least.''&lt;br /&gt;
&lt;br /&gt;
Why won't you get some code for mass virtual hosts from http://naviserver.sourceforge.net/ ??&lt;br /&gt;
-PB&lt;br /&gt;
&lt;br /&gt;
: Right now, to map a request to its (virtual) server, there's an O(n) search being done, but it's a &amp;quot;cheap&amp;quot; exact string comparison.  To implement glob-style wildcard support, it'll become a more expensive (but possibly still &amp;quot;cheap&amp;quot; by most people's standards) glob-match comparison.  When you're serving &amp;quot;n&amp;quot; requests per second (where &amp;quot;n&amp;quot; is small) the difference in cost is probably immeasurable, but when &amp;quot;n&amp;quot; is large, the cost is additive and possibly significant.  It might be good if someone could benchmark the two and see what the real cost is. ''-- [[User:Dossy|Dossy]] 20:12, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Server-side Includes ==&lt;br /&gt;
&lt;br /&gt;
Does anyone have some code to implement apache-compatible SSI (Server-side includes)?  I have some old pages that use SSI that I'd like to move to my aolserver install but I don't have the time to rewrite them as ADPs.&lt;br /&gt;
&lt;br /&gt;
: ''[[User:Dossy|Dossy]] 20:20, 4 November 2005 (EST)'': I make no representations or warranties about the safety (!) or correctness of the code I'm about to share, but it might get folks started on a proper implementation in the future.  In particular, I didn't implement any commands other than &amp;quot;include&amp;quot; and I even implemented it &amp;quot;wrong&amp;quot; (not according to [http://hoohoo.ncsa.uiuc.edu/docs/tutorials/includes.html the specification]).  If there's real interest in having a complete SSI implementation for AOLserver, I'd be willing to improve this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags&amp;quot;&lt;br /&gt;
&lt;br /&gt;
proc ssi_include_tag {params} {&lt;br /&gt;
        set param_count [ns_set size $params]&lt;br /&gt;
        for {set i 0} {$i &amp;lt; $param_count} {incr i} {&lt;br /&gt;
                set ssi_var_[ns_set key $params $i] [ns_set value $params $i]&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if [info exists ssi_var_file] {&lt;br /&gt;
                if {[ns_adp_argc] &amp;gt; 1} {&lt;br /&gt;
                        set basedir [lindex [ns_adp_argv] 1]&lt;br /&gt;
                } else {&lt;br /&gt;
                        set basedir [ns_adp_dir]&lt;br /&gt;
                }&lt;br /&gt;
                if [regexp {^/} $ssi_var_file] {&lt;br /&gt;
                        set filename $ssi_var_file&lt;br /&gt;
                } else {&lt;br /&gt;
                        set filename $basedir/$ssi_var_file&lt;br /&gt;
                }&lt;br /&gt;
                return [ns_adp_parse -file $filename $basedir]&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ns_register_adptag {!--#include} ssi_include_tag&lt;br /&gt;
&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags done&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
   &lt;br /&gt;
Is there a way to see only the errors (for example - 'variable' xxx not found? I seem to remember 2 logs - servername.log and servername-error.log?  The version I have now - aolserver 3.2/ad1.2 only seems to give us servername.log - and all the error messages are mixed with the normal msgs - its very hard to debug!&lt;br /&gt;
[[dannyl50]]&lt;br /&gt;
&lt;br /&gt;
The default/example config file did not have entries for both logs. The two sections you need look like (in old style notation): &lt;br /&gt;
&lt;br /&gt;
 [ns/parameters]&lt;br /&gt;
 User=nsadmin &lt;br /&gt;
 Group=nsadmin &lt;br /&gt;
 ServerLog=/var/log/aolserver/servername-error.log &lt;br /&gt;
 PidFile=/var/log/aolserver/nspid.servername&lt;br /&gt;
 Home=/usr/bin/aolserver-3.3ad13 &lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
 [ns/server/servername/module/nslog]&lt;br /&gt;
 File=/var/log/aolserver/emp.log &lt;br /&gt;
 LogCombined=On &lt;br /&gt;
 MaxBackup=3 &lt;br /&gt;
 RollFmt=%Y-%m-%d-%H:%M &lt;br /&gt;
 RollHour=0 &lt;br /&gt;
 RollOnSignal=On &lt;br /&gt;
 RollLog=On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Howdy!  Can someone tell me, in general terms, how they have implemented [[nsperm]]?  It looks cool, but I am using a plain old database with names and passwords, and it is very easy.  I would like the allow/deny functionality, can I have that without the username/password part? -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I've implemented [[nsperm]] to restrict access to specific URLs using HTTP authentication (the username/password dialog) and cookie-based (if they have the correct cookie, otherwise URL redirect them to a login page that may set the cookie).''&lt;br /&gt;
''The latter is done using a registered preauth filter.  I chose to use [[nsperm]] over a database since [[nsperm]] (presumably) manages the authentication information in memory better than repeatedly hitting the database with authentication requests, but there's no reason''&lt;br /&gt;
''I couldn't have used a database to store username/password information.  Does this answer your question?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pretty much, although I started writing my app before I understood AOLServer, so I have a rather strange design that is good in some ways, bad in others.  Keep in mind that this is a low activity app, no more than 20 concurrent users right now.  &lt;br /&gt;
&lt;br /&gt;
What I did was to create an [[ADP]] that has a big case statement.  It calls functions to generate pages based on the 'task' value it is passed through POST.  I have created a pretty complex app this way, not using [[ns_register_proc]] at all.  I know now I should have.  As I understand it, ns_register_proc lets you create a 'virtual' directory structure that actually just calls certain procedures based on the GET or POST requested URL.  This is far more graceful than hitting my main adp which opens up the form data, looks at the 'task' value, and decides which procedures to call.  &lt;br /&gt;
&lt;br /&gt;
Given this lame structure, each time someone requests the main adp, I just check for a valid cookie and generate a login page if it's not there.  After that, I have to set another cookie that is their 'access rights' which is then checked from within the procs that generate the pages.  If I was doing it right, I could have registered a proc that would fire for all URLs in my virtual tree, checking your rights to the particular URL you reqested, and redirecting you if you are not allowed, right?  &lt;br /&gt;
&lt;br /&gt;
Thanks!!! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I probably would've created an ADP per task, and then registered a preauth filter that checked for the cookie and redirected the user to the login page (outside the directory that the preauth filter covers''&lt;br /&gt;
''-- avoid funny redirection loops) if the cookie wasn't set properly.''&lt;br /&gt;
''If you don't want to create a separate ADP per task, you could have used ns_register_proc to create what you describe as &amp;quot;virtual pages&amp;quot; and still have the preauth filter kind of &amp;quot;sit in front&amp;quot; and handle the autehntication, keeping that logic seperate from your actual page generation code.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I started with a separate adp for each task, but I thought it would get out of hand quickly.  I do think I will re-work the thing to use ns_register_proc and even do away with the few adp I do have.  It seems far easier to maintain.  In the meantime, I have to re-write all my SQL Server procedures in PostgreSQL PL/Tcl.  That's why I want the [[nsfreetds]] module so badly, it buys me a little time!&lt;br /&gt;
&lt;br /&gt;
Thanks for all your work! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
''Speaking of [[nsfreetds]], did you try nsfreetds-0.1pre?  Any luck?  Any problems?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I just now tried it.  I installed freetds with no trouble, compiled nsfreetds, modified my nsd.tcl [[config file]], added the datasource to interfaces, and all seems fine, except for that I always get &amp;quot;no access to pool &amp;quot;mypool&amp;quot; while executing &amp;quot;ns_db gethandle mypool&amp;quot; ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
I must have missed something.  I saw something in the README about setting $env(SYBASE) before starting nsd.  Is this the same as the SYBASE=/usr/pkg/freetds I had to do even before the build of nsfreetds?&lt;br /&gt;
&lt;br /&gt;
Thanks again... I feel like I am close.. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Yes, the $env(SYBASE) means setting the SYBASE environment variable.  To be safe, you can try this:''&lt;br /&gt;
&lt;br /&gt;
   $ cd /path/to/aolserver/install&lt;br /&gt;
   $ SYBASE=/usr/pkg/freetds; export SYBASE&lt;br /&gt;
   $ bin/nsd ...args...&lt;br /&gt;
&lt;br /&gt;
''Check log/server.log to make sure that the nsfreetds driver is actually loading.  You should see a lines like this at start-up:''&lt;br /&gt;
&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: modload: loading '/home/aolserver-dev/bin/nsfreetds.so'&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: Ns_FreeTDS_DriverInit(freetds):  Loaded Panoptic FreeTDS Driver v0.1-pre, built on May 21 2001 at 22:23:01.&lt;br /&gt;
&lt;br /&gt;
''Are you getting an error in the [[server log]] instead?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I don't get an error, it seems to load nicely.  I can post or give you access to whatever files or output you would like to see, or an ssh login... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Another question:  Global variables ([[nsv]]*).  I am re-writing my app to use the [[ns_register_proc]] functionality versus my kludge where everything goes through an [[ADP]] that acts as a filter and traffic cop.  I have figured out register filter and register proc, but seem not to be able to use [[ns_puts]] from within the procs.  Is this right?  Anyway, I had been using [[ns_adp_include]] in my filter/traffic cop page to put consistent headers/footers on my pages.  I gather the more correct way (and only possible way with registered procs?) is to use global variables.  &lt;br /&gt;
&lt;br /&gt;
When do I initialize them?  How do I use them?  What are the caveats? W&lt;br /&gt;
&lt;br /&gt;
Thanks, -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Have you started by reading the NSV documentation?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
Of course not 8^0  That would be too easy!  I will... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
OK, I read it.  It's too easy.  I use it for header, footer, and client side script html, which I stuff into html variable before returning it.  I would like the filter option we talked about in the chat which would prepend or append html automatically, but this will do. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
How hard would it be to add an HTTPS equivalent of Ns_FetchURL?&lt;br /&gt;
&lt;br /&gt;
''If you can build shared libraries on your target platform with OpenSSL, it probably wouldn't be too hard.  The trick would be writing enough stub code that can be loaded via the Tcl &amp;quot;load&amp;quot; proc so that you could access the OpenSSL-based https client from your Tcl code.  Is there a lot of demand for this?  I could probably bang something out as an initial attempt.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
[[Scott Goodwin]]'s [[nsopenssl]] now contains client side https functionality.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Am I a brick, or does ns_register_proc just plain not work with more than one argument for the proc?  I have tried the following code on both aolserver 3.2 running on NT4 and aolserver 3.4 on NetBSD 1.5.  It fails to register the proc even once, if I try to register it with more than one argument anywhere else.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ns_register_proc GET /foo1 foo 1&lt;br /&gt;
 ns_register_proc GET /foo2 foo 1 2&lt;br /&gt;
 ns_register_proc GET /foo3 foo 1 2 3&lt;br /&gt;
&lt;br /&gt;
 proc foo { conn one {two 22} {three 333}} {&lt;br /&gt;
 ns_return 200 text/html &amp;quot;one is $one, two is $two, three is $three&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This must be something simple.  I have already posted to the aolserver list but the listserv seems to have gone mad.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''What are you trying to do?  It appears you want to pass constant parameters to your procedures.  If they are constants, why pass them?  Since ns_register_proc calls are generally in the global scope (and sourced when nsd starts) even a parameter that appears to be a variable probably can/will not vary.''&lt;br /&gt;
&lt;br /&gt;
''Presumably you need to get information from one page to another.  That means formvalues unless your page is stateful (usually a bad idea).  Check out the '''[[ns_conn]] form''' command to get yourself started.''  -- [[Jason Kane]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
OK, I'm using Windows 2000 SP2 and 3.4.1, and trying in vain to get Perl CGIs (legacy) to work.  The scripts work outside of Aolserver, and work on AOLserver on Linux, but when I try inside the script to GET from myself (eg, GET http://localhost:8000/foo?bar=bas), I'm told &amp;quot;unknown protocol TCP&amp;quot;, which is quite aggravating.&lt;br /&gt;
&lt;br /&gt;
Does anyone have any experience administering AOLServer on Windows?&lt;br /&gt;
&lt;br /&gt;
Thanks in advance!&lt;br /&gt;
&lt;br /&gt;
-Bill&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
This is interesting, wy do you let me change your page?&lt;br /&gt;
I'm trying to find an example of how to get my data using:&lt;br /&gt;
 set formdata [ns_conn form $conn]&lt;br /&gt;
&lt;br /&gt;
-Jason&lt;br /&gt;
&lt;br /&gt;
Because it's a wiki!  A proc that gets posted variables includes the line you wrote there... then when you want to actually get the values, you can use something like &lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_set get $formdata myvar]&lt;br /&gt;
&lt;br /&gt;
where myvar is the name of the variable.  There is also ns_queryget which looks like&lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_queryget myvar defaultval]&lt;br /&gt;
&lt;br /&gt;
This is handy because if there is no value, it will assign a default value.  &lt;br /&gt;
&lt;br /&gt;
Check out aolserver.com, they have extensive (although sometimes misleading) docs.  If something the docs says should work doesn't, ask.  It may be out of date.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I don't know where else to share my code fragments, so here seems like as good a place as any.  This one implements user public_html directories. It's based on someone else's stuff (I forget whose tho).  It should really do something with unknown mime types, and should do a better job with errors like unknown users.  It does honor directoryFile and adp maps in the config file.&lt;br /&gt;
&lt;br /&gt;
It works by registering a procedure to /users that interprets the username and finds their directory.  ns_register_proc doesn't allow wildcards other than in the last path element, so /~*  wouldn't work.  However that's not a problem for a filter, so there's a filter to take your /~user url and redirect it to /users/user&lt;br /&gt;
&lt;br /&gt;
-JR&lt;br /&gt;
&lt;br /&gt;
 proc homedir { conn ctx } {&lt;br /&gt;
   set url [ns_conn url $conn]&lt;br /&gt;
   set user {}&lt;br /&gt;
   set file {}&lt;br /&gt;
   regexp {^/users/([^/]*)(/.*)?$} $url dummy user file&lt;br /&gt;
   # ns_returnnotice 200 &amp;quot;url is $url user is $user, file is $file&amp;quot;&lt;br /&gt;
   set userfile [getUserFile $user $file]&lt;br /&gt;
   set type [ns_guesstype $userfile]&lt;br /&gt;
   if {[string match &amp;quot;*[ns_config ns/server/[ns_info server]]/adp map]&amp;quot; $userfile]} {&lt;br /&gt;
     # ns_log notice &amp;quot;adp parsing $userfile&amp;quot;&lt;br /&gt;
     set cwd [pwd]&lt;br /&gt;
     cd [file dirname $userfile]&lt;br /&gt;
     # ns_return 200 text/html [ns_adp_parse -file $userfile]&lt;br /&gt;
     set result [catch {ns_adp_parse -file $userfile} error]&lt;br /&gt;
     if {$result} {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     } else {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     }&lt;br /&gt;
     cd $cwd&lt;br /&gt;
   } else {&lt;br /&gt;
     switch $type {&lt;br /&gt;
       &amp;quot;*/*&amp;quot; {&lt;br /&gt;
       }&lt;br /&gt;
       default {&lt;br /&gt;
        ns_returnfile 200 $type $userfile&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
       &lt;br /&gt;
   if {[catch {set fp [open $userfile]}]} {&lt;br /&gt;
     ns_returnnotfound&lt;br /&gt;
     return&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 proc getUserFile {user path} {&lt;br /&gt;
   foreach tail [split ,[ns_config ns/server/[ns_info server] directoryfile] ,] {&lt;br /&gt;
     set userfile &amp;quot;[glob ~$user]/public_html$path$tail&amp;quot;&lt;br /&gt;
     if {[file exists $userfile] &amp;amp;&amp;amp; ![file isdirectory $userfile]} {&lt;br /&gt;
       return $userfile&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
   ns_returnnotfound&lt;br /&gt;
   # break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_proc GET /users/ homedir&lt;br /&gt;
 ns_register_proc POST /users/ homedir&lt;br /&gt;
 ns_register_proc HEAD /users/ homedir&lt;br /&gt;
 &lt;br /&gt;
 proc userRedir {conn arg why} {&lt;br /&gt;
   set url [ns_conn url]&lt;br /&gt;
   regsub {^/~(.*)} $url {/users/\1} redir&lt;br /&gt;
   ns_log notice &amp;quot;url is $url, redir is $redir&amp;quot;&lt;br /&gt;
   ns_returnredirect $redir&lt;br /&gt;
   return filter_break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_filter preauth GET /~* userRedir&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Hi!&lt;br /&gt;
&lt;br /&gt;
Does anybody know a graphing module for Aolserver/TCL, with e.g. bargraphs, linegraphs,... ?&lt;br /&gt;
&lt;br /&gt;
-[[wiwo]]&lt;br /&gt;
&lt;br /&gt;
''Yes: [[nsgds]], [[nschartdir]].''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Can I detect if the user pushes the Stop button in their browser in my TCL/ADP page?&lt;br /&gt;
&lt;br /&gt;
Yes, although it's a kludge. ns_write will return zero if it cannot write because the connection has been lost. However, ns_write is not stupid enough to try writing when you give it nothing to write, and so you must send something to the client. To prevent this being rendered use HTML comments, e.g.&lt;br /&gt;
&lt;br /&gt;
 if {[ns_write &amp;quot;&amp;lt;nowiki&amp;gt;&amp;lt;!-- STOP DETECTOR --&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;] == 0} {&lt;br /&gt;
     # user hit the stop button, browser page was closed, or connection to client was lost.&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Ximon Eighteen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Generating random passwords ==&lt;br /&gt;
&lt;br /&gt;
The following method can be useful to generate random passwords and/or password salts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # desired length of random string&lt;br /&gt;
  set iStringLength 8&lt;br /&gt;
&lt;br /&gt;
 # characters allowed to appear in the string&lt;br /&gt;
  set sAllowableCharacters &amp;quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # get length one time&lt;br /&gt;
  set iAllowableCharacters [string length $sAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
 # begin random string as empty&lt;br /&gt;
  set sRandomString &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # loop until desired length is achieved&lt;br /&gt;
  for {set ii 0} {$ii &amp;lt; $iStringLength} {incr ii} {&lt;br /&gt;
&lt;br /&gt;
   # get next random between 0 and length of allowed characters&lt;br /&gt;
    set iRandomInt [ns_rand $iAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
   # retrieve this random character&lt;br /&gt;
    set sRandomCharacter [string index $sAllowableCharacters $iRandomInt]&lt;br /&gt;
&lt;br /&gt;
   # append the character to our random string&lt;br /&gt;
    append sRandomString $sRandomCharacter&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  ns_adp_puts &amp;quot;sRandomString: $sRandomString&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Customizing error pages ==&lt;br /&gt;
&lt;br /&gt;
Edit your AOLServer's config file, and add the paths to the error pages as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Internal redirects&lt;br /&gt;
#&lt;br /&gt;
ns_section &amp;quot;ns/server/${servername}/redirects&amp;quot;&lt;br /&gt;
ns_param   404 &amp;quot;/notfound.html&amp;quot;      ;# Not Found error page&lt;br /&gt;
ns_param   500 &amp;quot;/servererror.html&amp;quot;   ;# Server Error page&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Fast caching of generated pages ==&lt;br /&gt;
&lt;br /&gt;
You can use an adp page to handle a 404 (not found) error that generated exactly the page it was looking for.  Conceptually this is similar to how tcl's autoloading using unknown works.  From Bas Sheffers, via John Buckman.&lt;br /&gt;
&lt;br /&gt;
from config.tcl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_section &amp;quot;ns/server/$server1/redirects&amp;quot;&lt;br /&gt;
ns_param   404           /404.adp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
404.adp:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% handle_404 %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Support procs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc handle_404 {} {&lt;br /&gt;
    set myurl [myurl]&lt;br /&gt;
    set parts [split $myurl /]&lt;br /&gt;
    set root [lindex $parts 1]&lt;br /&gt;
&lt;br /&gt;
    if {$root == &amp;quot;photo&amp;quot;} {&lt;br /&gt;
        return [404_photo $parts]&lt;br /&gt;
    } else {&lt;br /&gt;
        ns_returnredirect &amp;quot;[myhost]/&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc 404_photo {parts} {&lt;br /&gt;
    &lt;br /&gt;
    set userid [file rootname [lindex $parts 2]]&lt;br /&gt;
    set d [user_photo_data $userid]&lt;br /&gt;
    if {$d == &amp;quot;&amp;quot;} {&lt;br /&gt;
        set fn &amp;quot;/b/photo/unknown.jpg&amp;quot;&lt;br /&gt;
    } else {&lt;br /&gt;
        set fn &amp;quot;/b/photo/${userid}.jpg&amp;quot;&lt;br /&gt;
        write_binary_file $fn $d&lt;br /&gt;
    }&lt;br /&gt;
    ns_returnfile 200 &amp;quot;image/jpeg&amp;quot; $fn&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc myurl {} {&lt;br /&gt;
    return [lindex [split [ns_conn request]] 1]   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc photo_cache_dirty {userid} {&lt;br /&gt;
    set fn &amp;quot;/b/photo/${userid}.jpg&amp;quot;&lt;br /&gt;
    file delete $fn&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changing maximum upload file size ==&lt;br /&gt;
&lt;br /&gt;
For aolserver 4.5 and higher, to change the maximum upload file size from the default value to a custom one, add a line like this to the server configuration file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_limits set default -maxupload [expr 25 * 1024 * 1024]  ;# Maximum file size set to 25Mb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Return a file generated live ==&lt;br /&gt;
&lt;br /&gt;
Example using the db_foreach function from OpenACS, for the sake of code readability:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db_foreach get_mailing_addrs &amp;quot;&lt;br /&gt;
&lt;br /&gt;
   select company_name,&lt;br /&gt;
          address,&lt;br /&gt;
          city,&lt;br /&gt;
          province_abbrev,&lt;br /&gt;
          postal_code&lt;br /&gt;
     from ce_members&lt;br /&gt;
    order by company_name&amp;quot; {&lt;br /&gt;
&lt;br /&gt;
         append csv_text &amp;quot;\&amp;quot;$company_name\&amp;quot;,\&amp;quot;$address\&amp;quot;,\&amp;quot;$city\&amp;quot;,\&amp;quot;$province_abbrev\&amp;quot;,\&amp;quot;$postal_code\&amp;quot;\r\n&amp;quot;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
ns_set update [ns_conn outputheaders] content-disposition &amp;quot;attachment; filename=\&amp;quot;member-addresses.csv\&amp;quot;&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
ns_return 200 application/octet-stream $csv_text&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5114</id>
		<title>AOLserver Cookbook</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5114"/>
		<updated>2008-01-10T16:48:36Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A collection of questions, and code examples to answer them.&lt;br /&gt;
&lt;br /&gt;
Add your questions here.  Answers should be placed below the question.  Place a horizontal line (&amp;quot;----&amp;quot;) between questions.  Please keep this text before the first question.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Limiting bandwidth ==&lt;br /&gt;
&lt;br /&gt;
Is there a simple way to limit bandwidth per connection/ip???&lt;br /&gt;
&lt;br /&gt;
: There's no simple way of doing it, i.e., no configuration option you can set.  If I had to implement this, I'd use NSV's and [[ns_register_filter]] to keep track of bandwidth consumed by each client IP which can act as an all-or-nothing mechanism.  However, what might be interesting to implement in the socket driver is a setting to control the rate at which bytes are written back to the socket, perhaps configurable per request, so that large HTTP responses don't soak up your upstream bandwidth.  We should keep this in mind for a future version of AOLserver. ''-- [[User:Dossy|Dossy]] 20:06, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
One more question... How can I read output buffer inside function registered as postauth filter?&lt;br /&gt;
And how can I stream it? ns_adp_puts cannot be used inside filters... ns_return would return all data at once. I assume that per connection limit would look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc ..... {&lt;br /&gt;
ns_adp_stream&lt;br /&gt;
set data [get output content buffer]&lt;br /&gt;
set data_length [output buffer size]&lt;br /&gt;
set block_size 4096&lt;br /&gt;
for {set i 0} {$i &amp;lt; $data_length} {incr i $block_size} {&lt;br /&gt;
   send_to_client [string range $data [expr $block_size*$i] [expr $block_size*[expr$i+1]]]&lt;br /&gt;
   sleep 1&lt;br /&gt;
}&lt;br /&gt;
ns_returnok&lt;br /&gt;
return filter_return&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
I want to limit only one vhost so nssock limit would be too much;)&lt;br /&gt;
&lt;br /&gt;
: First, you don't want to turn [[ns_adp_stream]]'ing on.  Getting the size of the ADP output buffer can be done using [[ns_adp_tell]] and getting the contents with [[ns_adp_dump]].  I guess you could [[ns_adp_trunc]] the output buffer to clear it, then slowly write the contents back using [[ns_write]].  You'd also then need to look at [[ns_conn]] '''outputheaders''' to make sure that you wrote the proper HTTP response ... ah, but I don't know if you can get the HTTP response status code somehow.  I still think doing it in nssock is probably the best place, even with vhosts -- I'd make it a preauth or postauth filter that sets the configuration for the response and then have nssock be responsible for ensuring the response is written at that rate. ''-- [[User:Dossy|Dossy]] 07:24, 8 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
ns_adp_tell inside postauth filter:&lt;br /&gt;
   Error: This function cannot be used outside of an ADP&lt;br /&gt;
what's more, i use ns_returnfile inside some adp code and if i use ns_adp_tell after it, it returns 0 (this adp only returns file, no adp_puts or write).&lt;br /&gt;
Unfortunetly i think there is no other solution then implement it inside nssock or implement some tcl code to manipulate all output buffer.&lt;br /&gt;
&lt;br /&gt;
I use this code for big files... some time I'll add per ip limit, now it's for connection.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc returnfile { file } {                                                      &lt;br /&gt;
    set filefp [open $file r]                                                   &lt;br /&gt;
    fconfigure $filefp -translation binary                                      &lt;br /&gt;
    set data_length [file size $file]                                           &lt;br /&gt;
    set block_size 4096                                                         &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_write &amp;quot;HTTP/1.0 200 OK                                                   &lt;br /&gt;
MIME-Version: 1.0                                                               &lt;br /&gt;
Content-Type: [ns_guesstype $file]                                              &lt;br /&gt;
Content-Length: $data_length                                                    &lt;br /&gt;
                                                                                &lt;br /&gt;
&amp;quot;                                                                               &lt;br /&gt;
    while { ! [eof $filefp] } {                                                 &lt;br /&gt;
        ns_writefp $filefp $block_size                                          &lt;br /&gt;
        ns_sleep 1                                                              &lt;br /&gt;
    }                                                                           &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_conn close                                                               &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Paul Bukowski&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Virtual server configuration ==&lt;br /&gt;
&lt;br /&gt;
Is it possible to use wildcard '*' in domain name inside &amp;quot;ns/module/nssock/servers&amp;quot; section of aolserver4 config file? I would like to map all requests to *.somedomain.org to one virtual host...&lt;br /&gt;
Something like this doesn't work:&lt;br /&gt;
&lt;br /&gt;
 ns_section &amp;quot;ns/module/nssock/servers&amp;quot;&lt;br /&gt;
 ns_param   forum           somedomain.org                                           &lt;br /&gt;
 ns_param   forum           somedomain.org:80                                        &lt;br /&gt;
 ns_param   forum           *.somedomain.org                                       &lt;br /&gt;
 ns_param   forum           *.somedomain.org:80&lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org&amp;quot;                                       &lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org:80&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-Paul Bukowski&lt;br /&gt;
&lt;br /&gt;
: ''2005aug15 [[Dossy]]: Unfortunately, no -- you currently can't use wildcards the way you want.  Not yet, at least.''&lt;br /&gt;
&lt;br /&gt;
Why won't you get some code for mass virtual hosts from http://naviserver.sourceforge.net/ ??&lt;br /&gt;
-PB&lt;br /&gt;
&lt;br /&gt;
: Right now, to map a request to its (virtual) server, there's an O(n) search being done, but it's a &amp;quot;cheap&amp;quot; exact string comparison.  To implement glob-style wildcard support, it'll become a more expensive (but possibly still &amp;quot;cheap&amp;quot; by most people's standards) glob-match comparison.  When you're serving &amp;quot;n&amp;quot; requests per second (where &amp;quot;n&amp;quot; is small) the difference in cost is probably immeasurable, but when &amp;quot;n&amp;quot; is large, the cost is additive and possibly significant.  It might be good if someone could benchmark the two and see what the real cost is. ''-- [[User:Dossy|Dossy]] 20:12, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Server-side Includes ==&lt;br /&gt;
&lt;br /&gt;
Does anyone have some code to implement apache-compatible SSI (Server-side includes)?  I have some old pages that use SSI that I'd like to move to my aolserver install but I don't have the time to rewrite them as ADPs.&lt;br /&gt;
&lt;br /&gt;
: ''[[User:Dossy|Dossy]] 20:20, 4 November 2005 (EST)'': I make no representations or warranties about the safety (!) or correctness of the code I'm about to share, but it might get folks started on a proper implementation in the future.  In particular, I didn't implement any commands other than &amp;quot;include&amp;quot; and I even implemented it &amp;quot;wrong&amp;quot; (not according to [http://hoohoo.ncsa.uiuc.edu/docs/tutorials/includes.html the specification]).  If there's real interest in having a complete SSI implementation for AOLserver, I'd be willing to improve this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags&amp;quot;&lt;br /&gt;
&lt;br /&gt;
proc ssi_include_tag {params} {&lt;br /&gt;
        set param_count [ns_set size $params]&lt;br /&gt;
        for {set i 0} {$i &amp;lt; $param_count} {incr i} {&lt;br /&gt;
                set ssi_var_[ns_set key $params $i] [ns_set value $params $i]&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if [info exists ssi_var_file] {&lt;br /&gt;
                if {[ns_adp_argc] &amp;gt; 1} {&lt;br /&gt;
                        set basedir [lindex [ns_adp_argv] 1]&lt;br /&gt;
                } else {&lt;br /&gt;
                        set basedir [ns_adp_dir]&lt;br /&gt;
                }&lt;br /&gt;
                if [regexp {^/} $ssi_var_file] {&lt;br /&gt;
                        set filename $ssi_var_file&lt;br /&gt;
                } else {&lt;br /&gt;
                        set filename $basedir/$ssi_var_file&lt;br /&gt;
                }&lt;br /&gt;
                return [ns_adp_parse -file $filename $basedir]&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ns_register_adptag {!--#include} ssi_include_tag&lt;br /&gt;
&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags done&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
   &lt;br /&gt;
Is there a way to see only the errors (for example - 'variable' xxx not found? I seem to remember 2 logs - servername.log and servername-error.log?  The version I have now - aolserver 3.2/ad1.2 only seems to give us servername.log - and all the error messages are mixed with the normal msgs - its very hard to debug!&lt;br /&gt;
[[dannyl50]]&lt;br /&gt;
&lt;br /&gt;
The default/example config file did not have entries for both logs. The two sections you need look like (in old style notation): &lt;br /&gt;
&lt;br /&gt;
 [ns/parameters]&lt;br /&gt;
 User=nsadmin &lt;br /&gt;
 Group=nsadmin &lt;br /&gt;
 ServerLog=/var/log/aolserver/servername-error.log &lt;br /&gt;
 PidFile=/var/log/aolserver/nspid.servername&lt;br /&gt;
 Home=/usr/bin/aolserver-3.3ad13 &lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
 [ns/server/servername/module/nslog]&lt;br /&gt;
 File=/var/log/aolserver/emp.log &lt;br /&gt;
 LogCombined=On &lt;br /&gt;
 MaxBackup=3 &lt;br /&gt;
 RollFmt=%Y-%m-%d-%H:%M &lt;br /&gt;
 RollHour=0 &lt;br /&gt;
 RollOnSignal=On &lt;br /&gt;
 RollLog=On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Howdy!  Can someone tell me, in general terms, how they have implemented [[nsperm]]?  It looks cool, but I am using a plain old database with names and passwords, and it is very easy.  I would like the allow/deny functionality, can I have that without the username/password part? -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I've implemented [[nsperm]] to restrict access to specific URLs using HTTP authentication (the username/password dialog) and cookie-based (if they have the correct cookie, otherwise URL redirect them to a login page that may set the cookie).''&lt;br /&gt;
''The latter is done using a registered preauth filter.  I chose to use [[nsperm]] over a database since [[nsperm]] (presumably) manages the authentication information in memory better than repeatedly hitting the database with authentication requests, but there's no reason''&lt;br /&gt;
''I couldn't have used a database to store username/password information.  Does this answer your question?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pretty much, although I started writing my app before I understood AOLServer, so I have a rather strange design that is good in some ways, bad in others.  Keep in mind that this is a low activity app, no more than 20 concurrent users right now.  &lt;br /&gt;
&lt;br /&gt;
What I did was to create an [[ADP]] that has a big case statement.  It calls functions to generate pages based on the 'task' value it is passed through POST.  I have created a pretty complex app this way, not using [[ns_register_proc]] at all.  I know now I should have.  As I understand it, ns_register_proc lets you create a 'virtual' directory structure that actually just calls certain procedures based on the GET or POST requested URL.  This is far more graceful than hitting my main adp which opens up the form data, looks at the 'task' value, and decides which procedures to call.  &lt;br /&gt;
&lt;br /&gt;
Given this lame structure, each time someone requests the main adp, I just check for a valid cookie and generate a login page if it's not there.  After that, I have to set another cookie that is their 'access rights' which is then checked from within the procs that generate the pages.  If I was doing it right, I could have registered a proc that would fire for all URLs in my virtual tree, checking your rights to the particular URL you reqested, and redirecting you if you are not allowed, right?  &lt;br /&gt;
&lt;br /&gt;
Thanks!!! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I probably would've created an ADP per task, and then registered a preauth filter that checked for the cookie and redirected the user to the login page (outside the directory that the preauth filter covers''&lt;br /&gt;
''-- avoid funny redirection loops) if the cookie wasn't set properly.''&lt;br /&gt;
''If you don't want to create a separate ADP per task, you could have used ns_register_proc to create what you describe as &amp;quot;virtual pages&amp;quot; and still have the preauth filter kind of &amp;quot;sit in front&amp;quot; and handle the autehntication, keeping that logic seperate from your actual page generation code.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I started with a separate adp for each task, but I thought it would get out of hand quickly.  I do think I will re-work the thing to use ns_register_proc and even do away with the few adp I do have.  It seems far easier to maintain.  In the meantime, I have to re-write all my SQL Server procedures in PostgreSQL PL/Tcl.  That's why I want the [[nsfreetds]] module so badly, it buys me a little time!&lt;br /&gt;
&lt;br /&gt;
Thanks for all your work! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
''Speaking of [[nsfreetds]], did you try nsfreetds-0.1pre?  Any luck?  Any problems?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I just now tried it.  I installed freetds with no trouble, compiled nsfreetds, modified my nsd.tcl [[config file]], added the datasource to interfaces, and all seems fine, except for that I always get &amp;quot;no access to pool &amp;quot;mypool&amp;quot; while executing &amp;quot;ns_db gethandle mypool&amp;quot; ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
I must have missed something.  I saw something in the README about setting $env(SYBASE) before starting nsd.  Is this the same as the SYBASE=/usr/pkg/freetds I had to do even before the build of nsfreetds?&lt;br /&gt;
&lt;br /&gt;
Thanks again... I feel like I am close.. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Yes, the $env(SYBASE) means setting the SYBASE environment variable.  To be safe, you can try this:''&lt;br /&gt;
&lt;br /&gt;
   $ cd /path/to/aolserver/install&lt;br /&gt;
   $ SYBASE=/usr/pkg/freetds; export SYBASE&lt;br /&gt;
   $ bin/nsd ...args...&lt;br /&gt;
&lt;br /&gt;
''Check log/server.log to make sure that the nsfreetds driver is actually loading.  You should see a lines like this at start-up:''&lt;br /&gt;
&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: modload: loading '/home/aolserver-dev/bin/nsfreetds.so'&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: Ns_FreeTDS_DriverInit(freetds):  Loaded Panoptic FreeTDS Driver v0.1-pre, built on May 21 2001 at 22:23:01.&lt;br /&gt;
&lt;br /&gt;
''Are you getting an error in the [[server log]] instead?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I don't get an error, it seems to load nicely.  I can post or give you access to whatever files or output you would like to see, or an ssh login... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Another question:  Global variables ([[nsv]]*).  I am re-writing my app to use the [[ns_register_proc]] functionality versus my kludge where everything goes through an [[ADP]] that acts as a filter and traffic cop.  I have figured out register filter and register proc, but seem not to be able to use [[ns_puts]] from within the procs.  Is this right?  Anyway, I had been using [[ns_adp_include]] in my filter/traffic cop page to put consistent headers/footers on my pages.  I gather the more correct way (and only possible way with registered procs?) is to use global variables.  &lt;br /&gt;
&lt;br /&gt;
When do I initialize them?  How do I use them?  What are the caveats? W&lt;br /&gt;
&lt;br /&gt;
Thanks, -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Have you started by reading the NSV documentation?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
Of course not 8^0  That would be too easy!  I will... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
OK, I read it.  It's too easy.  I use it for header, footer, and client side script html, which I stuff into html variable before returning it.  I would like the filter option we talked about in the chat which would prepend or append html automatically, but this will do. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
How hard would it be to add an HTTPS equivalent of Ns_FetchURL?&lt;br /&gt;
&lt;br /&gt;
''If you can build shared libraries on your target platform with OpenSSL, it probably wouldn't be too hard.  The trick would be writing enough stub code that can be loaded via the Tcl &amp;quot;load&amp;quot; proc so that you could access the OpenSSL-based https client from your Tcl code.  Is there a lot of demand for this?  I could probably bang something out as an initial attempt.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
[[Scott Goodwin]]'s [[nsopenssl]] now contains client side https functionality.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Am I a brick, or does ns_register_proc just plain not work with more than one argument for the proc?  I have tried the following code on both aolserver 3.2 running on NT4 and aolserver 3.4 on NetBSD 1.5.  It fails to register the proc even once, if I try to register it with more than one argument anywhere else.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ns_register_proc GET /foo1 foo 1&lt;br /&gt;
 ns_register_proc GET /foo2 foo 1 2&lt;br /&gt;
 ns_register_proc GET /foo3 foo 1 2 3&lt;br /&gt;
&lt;br /&gt;
 proc foo { conn one {two 22} {three 333}} {&lt;br /&gt;
 ns_return 200 text/html &amp;quot;one is $one, two is $two, three is $three&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This must be something simple.  I have already posted to the aolserver list but the listserv seems to have gone mad.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''What are you trying to do?  It appears you want to pass constant parameters to your procedures.  If they are constants, why pass them?  Since ns_register_proc calls are generally in the global scope (and sourced when nsd starts) even a parameter that appears to be a variable probably can/will not vary.''&lt;br /&gt;
&lt;br /&gt;
''Presumably you need to get information from one page to another.  That means formvalues unless your page is stateful (usually a bad idea).  Check out the '''[[ns_conn]] form''' command to get yourself started.''  -- [[Jason Kane]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
OK, I'm using Windows 2000 SP2 and 3.4.1, and trying in vain to get Perl CGIs (legacy) to work.  The scripts work outside of Aolserver, and work on AOLserver on Linux, but when I try inside the script to GET from myself (eg, GET http://localhost:8000/foo?bar=bas), I'm told &amp;quot;unknown protocol TCP&amp;quot;, which is quite aggravating.&lt;br /&gt;
&lt;br /&gt;
Does anyone have any experience administering AOLServer on Windows?&lt;br /&gt;
&lt;br /&gt;
Thanks in advance!&lt;br /&gt;
&lt;br /&gt;
-Bill&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
This is interesting, wy do you let me change your page?&lt;br /&gt;
I'm trying to find an example of how to get my data using:&lt;br /&gt;
 set formdata [ns_conn form $conn]&lt;br /&gt;
&lt;br /&gt;
-Jason&lt;br /&gt;
&lt;br /&gt;
Because it's a wiki!  A proc that gets posted variables includes the line you wrote there... then when you want to actually get the values, you can use something like &lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_set get $formdata myvar]&lt;br /&gt;
&lt;br /&gt;
where myvar is the name of the variable.  There is also ns_queryget which looks like&lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_queryget myvar defaultval]&lt;br /&gt;
&lt;br /&gt;
This is handy because if there is no value, it will assign a default value.  &lt;br /&gt;
&lt;br /&gt;
Check out aolserver.com, they have extensive (although sometimes misleading) docs.  If something the docs says should work doesn't, ask.  It may be out of date.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I don't know where else to share my code fragments, so here seems like as good a place as any.  This one implements user public_html directories. It's based on someone else's stuff (I forget whose tho).  It should really do something with unknown mime types, and should do a better job with errors like unknown users.  It does honor directoryFile and adp maps in the config file.&lt;br /&gt;
&lt;br /&gt;
It works by registering a procedure to /users that interprets the username and finds their directory.  ns_register_proc doesn't allow wildcards other than in the last path element, so /~*  wouldn't work.  However that's not a problem for a filter, so there's a filter to take your /~user url and redirect it to /users/user&lt;br /&gt;
&lt;br /&gt;
-JR&lt;br /&gt;
&lt;br /&gt;
 proc homedir { conn ctx } {&lt;br /&gt;
   set url [ns_conn url $conn]&lt;br /&gt;
   set user {}&lt;br /&gt;
   set file {}&lt;br /&gt;
   regexp {^/users/([^/]*)(/.*)?$} $url dummy user file&lt;br /&gt;
   # ns_returnnotice 200 &amp;quot;url is $url user is $user, file is $file&amp;quot;&lt;br /&gt;
   set userfile [getUserFile $user $file]&lt;br /&gt;
   set type [ns_guesstype $userfile]&lt;br /&gt;
   if {[string match &amp;quot;*[ns_config ns/server/[ns_info server]]/adp map]&amp;quot; $userfile]} {&lt;br /&gt;
     # ns_log notice &amp;quot;adp parsing $userfile&amp;quot;&lt;br /&gt;
     set cwd [pwd]&lt;br /&gt;
     cd [file dirname $userfile]&lt;br /&gt;
     # ns_return 200 text/html [ns_adp_parse -file $userfile]&lt;br /&gt;
     set result [catch {ns_adp_parse -file $userfile} error]&lt;br /&gt;
     if {$result} {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     } else {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     }&lt;br /&gt;
     cd $cwd&lt;br /&gt;
   } else {&lt;br /&gt;
     switch $type {&lt;br /&gt;
       &amp;quot;*/*&amp;quot; {&lt;br /&gt;
       }&lt;br /&gt;
       default {&lt;br /&gt;
        ns_returnfile 200 $type $userfile&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
       &lt;br /&gt;
   if {[catch {set fp [open $userfile]}]} {&lt;br /&gt;
     ns_returnnotfound&lt;br /&gt;
     return&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 proc getUserFile {user path} {&lt;br /&gt;
   foreach tail [split ,[ns_config ns/server/[ns_info server] directoryfile] ,] {&lt;br /&gt;
     set userfile &amp;quot;[glob ~$user]/public_html$path$tail&amp;quot;&lt;br /&gt;
     if {[file exists $userfile] &amp;amp;&amp;amp; ![file isdirectory $userfile]} {&lt;br /&gt;
       return $userfile&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
   ns_returnnotfound&lt;br /&gt;
   # break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_proc GET /users/ homedir&lt;br /&gt;
 ns_register_proc POST /users/ homedir&lt;br /&gt;
 ns_register_proc HEAD /users/ homedir&lt;br /&gt;
 &lt;br /&gt;
 proc userRedir {conn arg why} {&lt;br /&gt;
   set url [ns_conn url]&lt;br /&gt;
   regsub {^/~(.*)} $url {/users/\1} redir&lt;br /&gt;
   ns_log notice &amp;quot;url is $url, redir is $redir&amp;quot;&lt;br /&gt;
   ns_returnredirect $redir&lt;br /&gt;
   return filter_break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_filter preauth GET /~* userRedir&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Hi!&lt;br /&gt;
&lt;br /&gt;
Does anybody know a graphing module for Aolserver/TCL, with e.g. bargraphs, linegraphs,... ?&lt;br /&gt;
&lt;br /&gt;
-[[wiwo]]&lt;br /&gt;
&lt;br /&gt;
''Yes: [[nsgds]], [[nschartdir]].''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Can I detect if the user pushes the Stop button in their browser in my TCL/ADP page?&lt;br /&gt;
&lt;br /&gt;
Yes, although it's a kludge. ns_write will return zero if it cannot write because the connection has been lost. However, ns_write is not stupid enough to try writing when you give it nothing to write, and so you must send something to the client. To prevent this being rendered use HTML comments, e.g.&lt;br /&gt;
&lt;br /&gt;
 if {[ns_write &amp;quot;&amp;lt;nowiki&amp;gt;&amp;lt;!-- STOP DETECTOR --&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;] == 0} {&lt;br /&gt;
     # user hit the stop button, browser page was closed, or connection to client was lost.&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Ximon Eighteen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Generating random passwords ==&lt;br /&gt;
&lt;br /&gt;
The following method can be useful to generate random passwords and/or password salts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # desired length of random string&lt;br /&gt;
  set iStringLength 8&lt;br /&gt;
&lt;br /&gt;
 # characters allowed to appear in the string&lt;br /&gt;
  set sAllowableCharacters &amp;quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # get length one time&lt;br /&gt;
  set iAllowableCharacters [string length $sAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
 # begin random string as empty&lt;br /&gt;
  set sRandomString &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # loop until desired length is achieved&lt;br /&gt;
  for {set ii 0} {$ii &amp;lt; $iStringLength} {incr ii} {&lt;br /&gt;
&lt;br /&gt;
   # get next random between 0 and length of allowed characters&lt;br /&gt;
    set iRandomInt [ns_rand $iAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
   # retrieve this random character&lt;br /&gt;
    set sRandomCharacter [string index $sAllowableCharacters $iRandomInt]&lt;br /&gt;
&lt;br /&gt;
   # append the character to our random string&lt;br /&gt;
    append sRandomString $sRandomCharacter&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  ns_adp_puts &amp;quot;sRandomString: $sRandomString&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Customizing error pages ==&lt;br /&gt;
&lt;br /&gt;
Edit your AOLServer's config file, and add the paths to the error pages as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Internal redirects&lt;br /&gt;
#&lt;br /&gt;
ns_section &amp;quot;ns/server/${servername}/redirects&amp;quot;&lt;br /&gt;
ns_param   404 &amp;quot;/notfound.html&amp;quot;      ;# Not Found error page&lt;br /&gt;
ns_param   500 &amp;quot;/servererror.html&amp;quot;   ;# Server Error page&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Fast caching of generated pages ==&lt;br /&gt;
&lt;br /&gt;
You can use an adp page to handle a 404 (not found) error that generated exactly the page it was looking for.  Conceptually this is similar to how tcl's autoloading using unknown works.  From Bas Sheffers, via John Buckman.&lt;br /&gt;
&lt;br /&gt;
from config.tcl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_section &amp;quot;ns/server/$server1/redirects&amp;quot;&lt;br /&gt;
ns_param   404           /404.adp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
404.adp:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% handle_404 %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Support procs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc handle_404 {} {&lt;br /&gt;
    set myurl [myurl]&lt;br /&gt;
    set parts [split $myurl /]&lt;br /&gt;
    set root [lindex $parts 1]&lt;br /&gt;
&lt;br /&gt;
    if {$root == &amp;quot;photo&amp;quot;} {&lt;br /&gt;
        return [404_photo $parts]&lt;br /&gt;
    } else {&lt;br /&gt;
        ns_returnredirect &amp;quot;[myhost]/&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc 404_photo {parts} {&lt;br /&gt;
    &lt;br /&gt;
    set userid [file rootname [lindex $parts 2]]&lt;br /&gt;
    set d [user_photo_data $userid]&lt;br /&gt;
    if {$d == &amp;quot;&amp;quot;} {&lt;br /&gt;
        set fn &amp;quot;/b/photo/unknown.jpg&amp;quot;&lt;br /&gt;
    } else {&lt;br /&gt;
        set fn &amp;quot;/b/photo/${userid}.jpg&amp;quot;&lt;br /&gt;
        write_binary_file $fn $d&lt;br /&gt;
    }&lt;br /&gt;
    ns_returnfile 200 &amp;quot;image/jpeg&amp;quot; $fn&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc myurl {} {&lt;br /&gt;
    return [lindex [split [ns_conn request]] 1]   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc photo_cache_dirty {userid} {&lt;br /&gt;
    set fn &amp;quot;/b/photo/${userid}.jpg&amp;quot;&lt;br /&gt;
    file delete $fn&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changing maximum upload file size ==&lt;br /&gt;
&lt;br /&gt;
For aolserver 4.5 and higher, to change the maximum upload file size from the default value to a custom one, add a line like this to the server configuration file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_limits set default -maxupload [expr 25 * 1024 * 1024]  ;# Maximum file size set to 25Mb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Return a file generated live ==&lt;br /&gt;
&lt;br /&gt;
Example using the db_foreach function from OpenACS, for the sake of code readibility:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
db_foreach get_mailing_addrs &amp;quot;&lt;br /&gt;
&lt;br /&gt;
   select company_name,&lt;br /&gt;
          address,&lt;br /&gt;
          city,&lt;br /&gt;
          province_abbrev,&lt;br /&gt;
          postal_code&lt;br /&gt;
     from ce_members&lt;br /&gt;
    order by company_name&amp;quot; {&lt;br /&gt;
&lt;br /&gt;
         append csv_text &amp;quot;\&amp;quot;$company_name\&amp;quot;,\&amp;quot;$address\&amp;quot;,\&amp;quot;$city\&amp;quot;,\&amp;quot;$province_abbrev\&amp;quot;,\&amp;quot;$postal_code\&amp;quot;\r\n&amp;quot;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
ns_set update [ns_conn outputheaders] content-disposition &amp;quot;attachment; filename=\&amp;quot;member-addresses.csv\&amp;quot;&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
ns_return 200 application/octet-stream $csv_text&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5113</id>
		<title>AOLserver Cookbook</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5113"/>
		<updated>2008-01-09T03:05:35Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: /* Changing maximum upload file size */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A collection of questions, and code examples to answer them.&lt;br /&gt;
&lt;br /&gt;
Add your questions here.  Answers should be placed below the question.  Place a horizontal line (&amp;quot;----&amp;quot;) between questions.  Please keep this text before the first question.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Limiting bandwidth ==&lt;br /&gt;
&lt;br /&gt;
Is there a simple way to limit bandwidth per connection/ip???&lt;br /&gt;
&lt;br /&gt;
: There's no simple way of doing it, i.e., no configuration option you can set.  If I had to implement this, I'd use NSV's and [[ns_register_filter]] to keep track of bandwidth consumed by each client IP which can act as an all-or-nothing mechanism.  However, what might be interesting to implement in the socket driver is a setting to control the rate at which bytes are written back to the socket, perhaps configurable per request, so that large HTTP responses don't soak up your upstream bandwidth.  We should keep this in mind for a future version of AOLserver. ''-- [[User:Dossy|Dossy]] 20:06, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
One more question... How can I read output buffer inside function registered as postauth filter?&lt;br /&gt;
And how can I stream it? ns_adp_puts cannot be used inside filters... ns_return would return all data at once. I assume that per connection limit would look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc ..... {&lt;br /&gt;
ns_adp_stream&lt;br /&gt;
set data [get output content buffer]&lt;br /&gt;
set data_length [output buffer size]&lt;br /&gt;
set block_size 4096&lt;br /&gt;
for {set i 0} {$i &amp;lt; $data_length} {incr i $block_size} {&lt;br /&gt;
   send_to_client [string range $data [expr $block_size*$i] [expr $block_size*[expr$i+1]]]&lt;br /&gt;
   sleep 1&lt;br /&gt;
}&lt;br /&gt;
ns_returnok&lt;br /&gt;
return filter_return&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
I want to limit only one vhost so nssock limit would be too much;)&lt;br /&gt;
&lt;br /&gt;
: First, you don't want to turn [[ns_adp_stream]]'ing on.  Getting the size of the ADP output buffer can be done using [[ns_adp_tell]] and getting the contents with [[ns_adp_dump]].  I guess you could [[ns_adp_trunc]] the output buffer to clear it, then slowly write the contents back using [[ns_write]].  You'd also then need to look at [[ns_conn]] '''outputheaders''' to make sure that you wrote the proper HTTP response ... ah, but I don't know if you can get the HTTP response status code somehow.  I still think doing it in nssock is probably the best place, even with vhosts -- I'd make it a preauth or postauth filter that sets the configuration for the response and then have nssock be responsible for ensuring the response is written at that rate. ''-- [[User:Dossy|Dossy]] 07:24, 8 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
ns_adp_tell inside postauth filter:&lt;br /&gt;
   Error: This function cannot be used outside of an ADP&lt;br /&gt;
what's more, i use ns_returnfile inside some adp code and if i use ns_adp_tell after it, it returns 0 (this adp only returns file, no adp_puts or write).&lt;br /&gt;
Unfortunetly i think there is no other solution then implement it inside nssock or implement some tcl code to manipulate all output buffer.&lt;br /&gt;
&lt;br /&gt;
I use this code for big files... some time I'll add per ip limit, now it's for connection.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc returnfile { file } {                                                      &lt;br /&gt;
    set filefp [open $file r]                                                   &lt;br /&gt;
    fconfigure $filefp -translation binary                                      &lt;br /&gt;
    set data_length [file size $file]                                           &lt;br /&gt;
    set block_size 4096                                                         &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_write &amp;quot;HTTP/1.0 200 OK                                                   &lt;br /&gt;
MIME-Version: 1.0                                                               &lt;br /&gt;
Content-Type: [ns_guesstype $file]                                              &lt;br /&gt;
Content-Length: $data_length                                                    &lt;br /&gt;
                                                                                &lt;br /&gt;
&amp;quot;                                                                               &lt;br /&gt;
    while { ! [eof $filefp] } {                                                 &lt;br /&gt;
        ns_writefp $filefp $block_size                                          &lt;br /&gt;
        ns_sleep 1                                                              &lt;br /&gt;
    }                                                                           &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_conn close                                                               &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Paul Bukowski&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Virtual server configuration ==&lt;br /&gt;
&lt;br /&gt;
Is it possible to use wildcard '*' in domain name inside &amp;quot;ns/module/nssock/servers&amp;quot; section of aolserver4 config file? I would like to map all requests to *.somedomain.org to one virtual host...&lt;br /&gt;
Something like this doesn't work:&lt;br /&gt;
&lt;br /&gt;
 ns_section &amp;quot;ns/module/nssock/servers&amp;quot;&lt;br /&gt;
 ns_param   forum           somedomain.org                                           &lt;br /&gt;
 ns_param   forum           somedomain.org:80                                        &lt;br /&gt;
 ns_param   forum           *.somedomain.org                                       &lt;br /&gt;
 ns_param   forum           *.somedomain.org:80&lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org&amp;quot;                                       &lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org:80&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-Paul Bukowski&lt;br /&gt;
&lt;br /&gt;
: ''2005aug15 [[Dossy]]: Unfortunately, no -- you currently can't use wildcards the way you want.  Not yet, at least.''&lt;br /&gt;
&lt;br /&gt;
Why won't you get some code for mass virtual hosts from http://naviserver.sourceforge.net/ ??&lt;br /&gt;
-PB&lt;br /&gt;
&lt;br /&gt;
: Right now, to map a request to its (virtual) server, there's an O(n) search being done, but it's a &amp;quot;cheap&amp;quot; exact string comparison.  To implement glob-style wildcard support, it'll become a more expensive (but possibly still &amp;quot;cheap&amp;quot; by most people's standards) glob-match comparison.  When you're serving &amp;quot;n&amp;quot; requests per second (where &amp;quot;n&amp;quot; is small) the difference in cost is probably immeasurable, but when &amp;quot;n&amp;quot; is large, the cost is additive and possibly significant.  It might be good if someone could benchmark the two and see what the real cost is. ''-- [[User:Dossy|Dossy]] 20:12, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Server-side Includes ==&lt;br /&gt;
&lt;br /&gt;
Does anyone have some code to implement apache-compatible SSI (Server-side includes)?  I have some old pages that use SSI that I'd like to move to my aolserver install but I don't have the time to rewrite them as ADPs.&lt;br /&gt;
&lt;br /&gt;
: ''[[User:Dossy|Dossy]] 20:20, 4 November 2005 (EST)'': I make no representations or warranties about the safety (!) or correctness of the code I'm about to share, but it might get folks started on a proper implementation in the future.  In particular, I didn't implement any commands other than &amp;quot;include&amp;quot; and I even implemented it &amp;quot;wrong&amp;quot; (not according to [http://hoohoo.ncsa.uiuc.edu/docs/tutorials/includes.html the specification]).  If there's real interest in having a complete SSI implementation for AOLserver, I'd be willing to improve this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags&amp;quot;&lt;br /&gt;
&lt;br /&gt;
proc ssi_include_tag {params} {&lt;br /&gt;
        set param_count [ns_set size $params]&lt;br /&gt;
        for {set i 0} {$i &amp;lt; $param_count} {incr i} {&lt;br /&gt;
                set ssi_var_[ns_set key $params $i] [ns_set value $params $i]&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if [info exists ssi_var_file] {&lt;br /&gt;
                if {[ns_adp_argc] &amp;gt; 1} {&lt;br /&gt;
                        set basedir [lindex [ns_adp_argv] 1]&lt;br /&gt;
                } else {&lt;br /&gt;
                        set basedir [ns_adp_dir]&lt;br /&gt;
                }&lt;br /&gt;
                if [regexp {^/} $ssi_var_file] {&lt;br /&gt;
                        set filename $ssi_var_file&lt;br /&gt;
                } else {&lt;br /&gt;
                        set filename $basedir/$ssi_var_file&lt;br /&gt;
                }&lt;br /&gt;
                return [ns_adp_parse -file $filename $basedir]&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ns_register_adptag {!--#include} ssi_include_tag&lt;br /&gt;
&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags done&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
   &lt;br /&gt;
Is there a way to see only the errors (for example - 'variable' xxx not found? I seem to remember 2 logs - servername.log and servername-error.log?  The version I have now - aolserver 3.2/ad1.2 only seems to give us servername.log - and all the error messages are mixed with the normal msgs - its very hard to debug!&lt;br /&gt;
[[dannyl50]]&lt;br /&gt;
&lt;br /&gt;
The default/example config file did not have entries for both logs. The two sections you need look like (in old style notation): &lt;br /&gt;
&lt;br /&gt;
 [ns/parameters]&lt;br /&gt;
 User=nsadmin &lt;br /&gt;
 Group=nsadmin &lt;br /&gt;
 ServerLog=/var/log/aolserver/servername-error.log &lt;br /&gt;
 PidFile=/var/log/aolserver/nspid.servername&lt;br /&gt;
 Home=/usr/bin/aolserver-3.3ad13 &lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
 [ns/server/servername/module/nslog]&lt;br /&gt;
 File=/var/log/aolserver/emp.log &lt;br /&gt;
 LogCombined=On &lt;br /&gt;
 MaxBackup=3 &lt;br /&gt;
 RollFmt=%Y-%m-%d-%H:%M &lt;br /&gt;
 RollHour=0 &lt;br /&gt;
 RollOnSignal=On &lt;br /&gt;
 RollLog=On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Howdy!  Can someone tell me, in general terms, how they have implemented [[nsperm]]?  It looks cool, but I am using a plain old database with names and passwords, and it is very easy.  I would like the allow/deny functionality, can I have that without the username/password part? -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I've implemented [[nsperm]] to restrict access to specific URLs using HTTP authentication (the username/password dialog) and cookie-based (if they have the correct cookie, otherwise URL redirect them to a login page that may set the cookie).''&lt;br /&gt;
''The latter is done using a registered preauth filter.  I chose to use [[nsperm]] over a database since [[nsperm]] (presumably) manages the authentication information in memory better than repeatedly hitting the database with authentication requests, but there's no reason''&lt;br /&gt;
''I couldn't have used a database to store username/password information.  Does this answer your question?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pretty much, although I started writing my app before I understood AOLServer, so I have a rather strange design that is good in some ways, bad in others.  Keep in mind that this is a low activity app, no more than 20 concurrent users right now.  &lt;br /&gt;
&lt;br /&gt;
What I did was to create an [[ADP]] that has a big case statement.  It calls functions to generate pages based on the 'task' value it is passed through POST.  I have created a pretty complex app this way, not using [[ns_register_proc]] at all.  I know now I should have.  As I understand it, ns_register_proc lets you create a 'virtual' directory structure that actually just calls certain procedures based on the GET or POST requested URL.  This is far more graceful than hitting my main adp which opens up the form data, looks at the 'task' value, and decides which procedures to call.  &lt;br /&gt;
&lt;br /&gt;
Given this lame structure, each time someone requests the main adp, I just check for a valid cookie and generate a login page if it's not there.  After that, I have to set another cookie that is their 'access rights' which is then checked from within the procs that generate the pages.  If I was doing it right, I could have registered a proc that would fire for all URLs in my virtual tree, checking your rights to the particular URL you reqested, and redirecting you if you are not allowed, right?  &lt;br /&gt;
&lt;br /&gt;
Thanks!!! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I probably would've created an ADP per task, and then registered a preauth filter that checked for the cookie and redirected the user to the login page (outside the directory that the preauth filter covers''&lt;br /&gt;
''-- avoid funny redirection loops) if the cookie wasn't set properly.''&lt;br /&gt;
''If you don't want to create a separate ADP per task, you could have used ns_register_proc to create what you describe as &amp;quot;virtual pages&amp;quot; and still have the preauth filter kind of &amp;quot;sit in front&amp;quot; and handle the autehntication, keeping that logic seperate from your actual page generation code.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I started with a separate adp for each task, but I thought it would get out of hand quickly.  I do think I will re-work the thing to use ns_register_proc and even do away with the few adp I do have.  It seems far easier to maintain.  In the meantime, I have to re-write all my SQL Server procedures in PostgreSQL PL/Tcl.  That's why I want the [[nsfreetds]] module so badly, it buys me a little time!&lt;br /&gt;
&lt;br /&gt;
Thanks for all your work! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
''Speaking of [[nsfreetds]], did you try nsfreetds-0.1pre?  Any luck?  Any problems?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I just now tried it.  I installed freetds with no trouble, compiled nsfreetds, modified my nsd.tcl [[config file]], added the datasource to interfaces, and all seems fine, except for that I always get &amp;quot;no access to pool &amp;quot;mypool&amp;quot; while executing &amp;quot;ns_db gethandle mypool&amp;quot; ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
I must have missed something.  I saw something in the README about setting $env(SYBASE) before starting nsd.  Is this the same as the SYBASE=/usr/pkg/freetds I had to do even before the build of nsfreetds?&lt;br /&gt;
&lt;br /&gt;
Thanks again... I feel like I am close.. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Yes, the $env(SYBASE) means setting the SYBASE environment variable.  To be safe, you can try this:''&lt;br /&gt;
&lt;br /&gt;
   $ cd /path/to/aolserver/install&lt;br /&gt;
   $ SYBASE=/usr/pkg/freetds; export SYBASE&lt;br /&gt;
   $ bin/nsd ...args...&lt;br /&gt;
&lt;br /&gt;
''Check log/server.log to make sure that the nsfreetds driver is actually loading.  You should see a lines like this at start-up:''&lt;br /&gt;
&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: modload: loading '/home/aolserver-dev/bin/nsfreetds.so'&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: Ns_FreeTDS_DriverInit(freetds):  Loaded Panoptic FreeTDS Driver v0.1-pre, built on May 21 2001 at 22:23:01.&lt;br /&gt;
&lt;br /&gt;
''Are you getting an error in the [[server log]] instead?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I don't get an error, it seems to load nicely.  I can post or give you access to whatever files or output you would like to see, or an ssh login... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Another question:  Global variables ([[nsv]]*).  I am re-writing my app to use the [[ns_register_proc]] functionality versus my kludge where everything goes through an [[ADP]] that acts as a filter and traffic cop.  I have figured out register filter and register proc, but seem not to be able to use [[ns_puts]] from within the procs.  Is this right?  Anyway, I had been using [[ns_adp_include]] in my filter/traffic cop page to put consistent headers/footers on my pages.  I gather the more correct way (and only possible way with registered procs?) is to use global variables.  &lt;br /&gt;
&lt;br /&gt;
When do I initialize them?  How do I use them?  What are the caveats? W&lt;br /&gt;
&lt;br /&gt;
Thanks, -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Have you started by reading the NSV documentation?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
Of course not 8^0  That would be too easy!  I will... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
OK, I read it.  It's too easy.  I use it for header, footer, and client side script html, which I stuff into html variable before returning it.  I would like the filter option we talked about in the chat which would prepend or append html automatically, but this will do. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
How hard would it be to add an HTTPS equivalent of Ns_FetchURL?&lt;br /&gt;
&lt;br /&gt;
''If you can build shared libraries on your target platform with OpenSSL, it probably wouldn't be too hard.  The trick would be writing enough stub code that can be loaded via the Tcl &amp;quot;load&amp;quot; proc so that you could access the OpenSSL-based https client from your Tcl code.  Is there a lot of demand for this?  I could probably bang something out as an initial attempt.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
[[Scott Goodwin]]'s [[nsopenssl]] now contains client side https functionality.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Am I a brick, or does ns_register_proc just plain not work with more than one argument for the proc?  I have tried the following code on both aolserver 3.2 running on NT4 and aolserver 3.4 on NetBSD 1.5.  It fails to register the proc even once, if I try to register it with more than one argument anywhere else.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ns_register_proc GET /foo1 foo 1&lt;br /&gt;
 ns_register_proc GET /foo2 foo 1 2&lt;br /&gt;
 ns_register_proc GET /foo3 foo 1 2 3&lt;br /&gt;
&lt;br /&gt;
 proc foo { conn one {two 22} {three 333}} {&lt;br /&gt;
 ns_return 200 text/html &amp;quot;one is $one, two is $two, three is $three&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This must be something simple.  I have already posted to the aolserver list but the listserv seems to have gone mad.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''What are you trying to do?  It appears you want to pass constant parameters to your procedures.  If they are constants, why pass them?  Since ns_register_proc calls are generally in the global scope (and sourced when nsd starts) even a parameter that appears to be a variable probably can/will not vary.''&lt;br /&gt;
&lt;br /&gt;
''Presumably you need to get information from one page to another.  That means formvalues unless your page is stateful (usually a bad idea).  Check out the '''[[ns_conn]] form''' command to get yourself started.''  -- [[Jason Kane]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
OK, I'm using Windows 2000 SP2 and 3.4.1, and trying in vain to get Perl CGIs (legacy) to work.  The scripts work outside of Aolserver, and work on AOLserver on Linux, but when I try inside the script to GET from myself (eg, GET http://localhost:8000/foo?bar=bas), I'm told &amp;quot;unknown protocol TCP&amp;quot;, which is quite aggravating.&lt;br /&gt;
&lt;br /&gt;
Does anyone have any experience administering AOLServer on Windows?&lt;br /&gt;
&lt;br /&gt;
Thanks in advance!&lt;br /&gt;
&lt;br /&gt;
-Bill&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
This is interesting, wy do you let me change your page?&lt;br /&gt;
I'm trying to find an example of how to get my data using:&lt;br /&gt;
 set formdata [ns_conn form $conn]&lt;br /&gt;
&lt;br /&gt;
-Jason&lt;br /&gt;
&lt;br /&gt;
Because it's a wiki!  A proc that gets posted variables includes the line you wrote there... then when you want to actually get the values, you can use something like &lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_set get $formdata myvar]&lt;br /&gt;
&lt;br /&gt;
where myvar is the name of the variable.  There is also ns_queryget which looks like&lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_queryget myvar defaultval]&lt;br /&gt;
&lt;br /&gt;
This is handy because if there is no value, it will assign a default value.  &lt;br /&gt;
&lt;br /&gt;
Check out aolserver.com, they have extensive (although sometimes misleading) docs.  If something the docs says should work doesn't, ask.  It may be out of date.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I don't know where else to share my code fragments, so here seems like as good a place as any.  This one implements user public_html directories. It's based on someone else's stuff (I forget whose tho).  It should really do something with unknown mime types, and should do a better job with errors like unknown users.  It does honor directoryFile and adp maps in the config file.&lt;br /&gt;
&lt;br /&gt;
It works by registering a procedure to /users that interprets the username and finds their directory.  ns_register_proc doesn't allow wildcards other than in the last path element, so /~*  wouldn't work.  However that's not a problem for a filter, so there's a filter to take your /~user url and redirect it to /users/user&lt;br /&gt;
&lt;br /&gt;
-JR&lt;br /&gt;
&lt;br /&gt;
 proc homedir { conn ctx } {&lt;br /&gt;
   set url [ns_conn url $conn]&lt;br /&gt;
   set user {}&lt;br /&gt;
   set file {}&lt;br /&gt;
   regexp {^/users/([^/]*)(/.*)?$} $url dummy user file&lt;br /&gt;
   # ns_returnnotice 200 &amp;quot;url is $url user is $user, file is $file&amp;quot;&lt;br /&gt;
   set userfile [getUserFile $user $file]&lt;br /&gt;
   set type [ns_guesstype $userfile]&lt;br /&gt;
   if {[string match &amp;quot;*[ns_config ns/server/[ns_info server]]/adp map]&amp;quot; $userfile]} {&lt;br /&gt;
     # ns_log notice &amp;quot;adp parsing $userfile&amp;quot;&lt;br /&gt;
     set cwd [pwd]&lt;br /&gt;
     cd [file dirname $userfile]&lt;br /&gt;
     # ns_return 200 text/html [ns_adp_parse -file $userfile]&lt;br /&gt;
     set result [catch {ns_adp_parse -file $userfile} error]&lt;br /&gt;
     if {$result} {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     } else {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     }&lt;br /&gt;
     cd $cwd&lt;br /&gt;
   } else {&lt;br /&gt;
     switch $type {&lt;br /&gt;
       &amp;quot;*/*&amp;quot; {&lt;br /&gt;
       }&lt;br /&gt;
       default {&lt;br /&gt;
        ns_returnfile 200 $type $userfile&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
       &lt;br /&gt;
   if {[catch {set fp [open $userfile]}]} {&lt;br /&gt;
     ns_returnnotfound&lt;br /&gt;
     return&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 proc getUserFile {user path} {&lt;br /&gt;
   foreach tail [split ,[ns_config ns/server/[ns_info server] directoryfile] ,] {&lt;br /&gt;
     set userfile &amp;quot;[glob ~$user]/public_html$path$tail&amp;quot;&lt;br /&gt;
     if {[file exists $userfile] &amp;amp;&amp;amp; ![file isdirectory $userfile]} {&lt;br /&gt;
       return $userfile&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
   ns_returnnotfound&lt;br /&gt;
   # break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_proc GET /users/ homedir&lt;br /&gt;
 ns_register_proc POST /users/ homedir&lt;br /&gt;
 ns_register_proc HEAD /users/ homedir&lt;br /&gt;
 &lt;br /&gt;
 proc userRedir {conn arg why} {&lt;br /&gt;
   set url [ns_conn url]&lt;br /&gt;
   regsub {^/~(.*)} $url {/users/\1} redir&lt;br /&gt;
   ns_log notice &amp;quot;url is $url, redir is $redir&amp;quot;&lt;br /&gt;
   ns_returnredirect $redir&lt;br /&gt;
   return filter_break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_filter preauth GET /~* userRedir&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Hi!&lt;br /&gt;
&lt;br /&gt;
Does anybody know a graphing module for Aolserver/TCL, with e.g. bargraphs, linegraphs,... ?&lt;br /&gt;
&lt;br /&gt;
-[[wiwo]]&lt;br /&gt;
&lt;br /&gt;
''Yes: [[nsgds]], [[nschartdir]].''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Can I detect if the user pushes the Stop button in their browser in my TCL/ADP page?&lt;br /&gt;
&lt;br /&gt;
Yes, although it's a kludge. ns_write will return zero if it cannot write because the connection has been lost. However, ns_write is not stupid enough to try writing when you give it nothing to write, and so you must send something to the client. To prevent this being rendered use HTML comments, e.g.&lt;br /&gt;
&lt;br /&gt;
 if {[ns_write &amp;quot;&amp;lt;nowiki&amp;gt;&amp;lt;!-- STOP DETECTOR --&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;] == 0} {&lt;br /&gt;
     # user hit the stop button, browser page was closed, or connection to client was lost.&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Ximon Eighteen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Generating random passwords ==&lt;br /&gt;
&lt;br /&gt;
The following method can be useful to generate random passwords and/or password salts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # desired length of random string&lt;br /&gt;
  set iStringLength 8&lt;br /&gt;
&lt;br /&gt;
 # characters allowed to appear in the string&lt;br /&gt;
  set sAllowableCharacters &amp;quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # get length one time&lt;br /&gt;
  set iAllowableCharacters [string length $sAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
 # begin random string as empty&lt;br /&gt;
  set sRandomString &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # loop until desired length is achieved&lt;br /&gt;
  for {set ii 0} {$ii &amp;lt; $iStringLength} {incr ii} {&lt;br /&gt;
&lt;br /&gt;
   # get next random between 0 and length of allowed characters&lt;br /&gt;
    set iRandomInt [ns_rand $iAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
   # retrieve this random character&lt;br /&gt;
    set sRandomCharacter [string index $sAllowableCharacters $iRandomInt]&lt;br /&gt;
&lt;br /&gt;
   # append the character to our random string&lt;br /&gt;
    append sRandomString $sRandomCharacter&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  ns_adp_puts &amp;quot;sRandomString: $sRandomString&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Customizing error pages ==&lt;br /&gt;
&lt;br /&gt;
Edit your AOLServer's config file, and add the paths to the error pages as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Internal redirects&lt;br /&gt;
#&lt;br /&gt;
ns_section &amp;quot;ns/server/${servername}/redirects&amp;quot;&lt;br /&gt;
ns_param   404 &amp;quot;/notfound.html&amp;quot;      ;# Not Found error page&lt;br /&gt;
ns_param   500 &amp;quot;/servererror.html&amp;quot;   ;# Server Error page&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Fast caching of generated pages ==&lt;br /&gt;
&lt;br /&gt;
You can use an adp page to handle a 404 (not found) error that generated exactly the page it was looking for.  Conceptually this is similar to how tcl's autoloading using unknown works.  From Bas Sheffers, via John Buckman.&lt;br /&gt;
&lt;br /&gt;
from config.tcl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_section &amp;quot;ns/server/$server1/redirects&amp;quot;&lt;br /&gt;
ns_param   404           /404.adp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
404.adp:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% handle_404 %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Support procs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc handle_404 {} {&lt;br /&gt;
    set myurl [myurl]&lt;br /&gt;
    set parts [split $myurl /]&lt;br /&gt;
    set root [lindex $parts 1]&lt;br /&gt;
&lt;br /&gt;
    if {$root == &amp;quot;photo&amp;quot;} {&lt;br /&gt;
        return [404_photo $parts]&lt;br /&gt;
    } else {&lt;br /&gt;
        ns_returnredirect &amp;quot;[myhost]/&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc 404_photo {parts} {&lt;br /&gt;
    &lt;br /&gt;
    set userid [file rootname [lindex $parts 2]]&lt;br /&gt;
    set d [user_photo_data $userid]&lt;br /&gt;
    if {$d == &amp;quot;&amp;quot;} {&lt;br /&gt;
        set fn &amp;quot;/b/photo/unknown.jpg&amp;quot;&lt;br /&gt;
    } else {&lt;br /&gt;
        set fn &amp;quot;/b/photo/${userid}.jpg&amp;quot;&lt;br /&gt;
        write_binary_file $fn $d&lt;br /&gt;
    }&lt;br /&gt;
    ns_returnfile 200 &amp;quot;image/jpeg&amp;quot; $fn&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc myurl {} {&lt;br /&gt;
    return [lindex [split [ns_conn request]] 1]   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc photo_cache_dirty {userid} {&lt;br /&gt;
    set fn &amp;quot;/b/photo/${userid}.jpg&amp;quot;&lt;br /&gt;
    file delete $fn&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changing maximum upload file size ==&lt;br /&gt;
&lt;br /&gt;
For aolserver 4.5 and higher, to change the maximum upload file size from the default value to a custom one, add a line like this to the server configuration file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_limits set default -maxupload [expr 25 * 1024 * 1024]  ;# Maximum file size set to 25Mb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5112</id>
		<title>AOLserver Cookbook</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5112"/>
		<updated>2008-01-09T03:04:59Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A collection of questions, and code examples to answer them.&lt;br /&gt;
&lt;br /&gt;
Add your questions here.  Answers should be placed below the question.  Place a horizontal line (&amp;quot;----&amp;quot;) between questions.  Please keep this text before the first question.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Limiting bandwidth ==&lt;br /&gt;
&lt;br /&gt;
Is there a simple way to limit bandwidth per connection/ip???&lt;br /&gt;
&lt;br /&gt;
: There's no simple way of doing it, i.e., no configuration option you can set.  If I had to implement this, I'd use NSV's and [[ns_register_filter]] to keep track of bandwidth consumed by each client IP which can act as an all-or-nothing mechanism.  However, what might be interesting to implement in the socket driver is a setting to control the rate at which bytes are written back to the socket, perhaps configurable per request, so that large HTTP responses don't soak up your upstream bandwidth.  We should keep this in mind for a future version of AOLserver. ''-- [[User:Dossy|Dossy]] 20:06, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
One more question... How can I read output buffer inside function registered as postauth filter?&lt;br /&gt;
And how can I stream it? ns_adp_puts cannot be used inside filters... ns_return would return all data at once. I assume that per connection limit would look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc ..... {&lt;br /&gt;
ns_adp_stream&lt;br /&gt;
set data [get output content buffer]&lt;br /&gt;
set data_length [output buffer size]&lt;br /&gt;
set block_size 4096&lt;br /&gt;
for {set i 0} {$i &amp;lt; $data_length} {incr i $block_size} {&lt;br /&gt;
   send_to_client [string range $data [expr $block_size*$i] [expr $block_size*[expr$i+1]]]&lt;br /&gt;
   sleep 1&lt;br /&gt;
}&lt;br /&gt;
ns_returnok&lt;br /&gt;
return filter_return&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
I want to limit only one vhost so nssock limit would be too much;)&lt;br /&gt;
&lt;br /&gt;
: First, you don't want to turn [[ns_adp_stream]]'ing on.  Getting the size of the ADP output buffer can be done using [[ns_adp_tell]] and getting the contents with [[ns_adp_dump]].  I guess you could [[ns_adp_trunc]] the output buffer to clear it, then slowly write the contents back using [[ns_write]].  You'd also then need to look at [[ns_conn]] '''outputheaders''' to make sure that you wrote the proper HTTP response ... ah, but I don't know if you can get the HTTP response status code somehow.  I still think doing it in nssock is probably the best place, even with vhosts -- I'd make it a preauth or postauth filter that sets the configuration for the response and then have nssock be responsible for ensuring the response is written at that rate. ''-- [[User:Dossy|Dossy]] 07:24, 8 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
ns_adp_tell inside postauth filter:&lt;br /&gt;
   Error: This function cannot be used outside of an ADP&lt;br /&gt;
what's more, i use ns_returnfile inside some adp code and if i use ns_adp_tell after it, it returns 0 (this adp only returns file, no adp_puts or write).&lt;br /&gt;
Unfortunetly i think there is no other solution then implement it inside nssock or implement some tcl code to manipulate all output buffer.&lt;br /&gt;
&lt;br /&gt;
I use this code for big files... some time I'll add per ip limit, now it's for connection.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc returnfile { file } {                                                      &lt;br /&gt;
    set filefp [open $file r]                                                   &lt;br /&gt;
    fconfigure $filefp -translation binary                                      &lt;br /&gt;
    set data_length [file size $file]                                           &lt;br /&gt;
    set block_size 4096                                                         &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_write &amp;quot;HTTP/1.0 200 OK                                                   &lt;br /&gt;
MIME-Version: 1.0                                                               &lt;br /&gt;
Content-Type: [ns_guesstype $file]                                              &lt;br /&gt;
Content-Length: $data_length                                                    &lt;br /&gt;
                                                                                &lt;br /&gt;
&amp;quot;                                                                               &lt;br /&gt;
    while { ! [eof $filefp] } {                                                 &lt;br /&gt;
        ns_writefp $filefp $block_size                                          &lt;br /&gt;
        ns_sleep 1                                                              &lt;br /&gt;
    }                                                                           &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_conn close                                                               &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Paul Bukowski&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Virtual server configuration ==&lt;br /&gt;
&lt;br /&gt;
Is it possible to use wildcard '*' in domain name inside &amp;quot;ns/module/nssock/servers&amp;quot; section of aolserver4 config file? I would like to map all requests to *.somedomain.org to one virtual host...&lt;br /&gt;
Something like this doesn't work:&lt;br /&gt;
&lt;br /&gt;
 ns_section &amp;quot;ns/module/nssock/servers&amp;quot;&lt;br /&gt;
 ns_param   forum           somedomain.org                                           &lt;br /&gt;
 ns_param   forum           somedomain.org:80                                        &lt;br /&gt;
 ns_param   forum           *.somedomain.org                                       &lt;br /&gt;
 ns_param   forum           *.somedomain.org:80&lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org&amp;quot;                                       &lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org:80&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-Paul Bukowski&lt;br /&gt;
&lt;br /&gt;
: ''2005aug15 [[Dossy]]: Unfortunately, no -- you currently can't use wildcards the way you want.  Not yet, at least.''&lt;br /&gt;
&lt;br /&gt;
Why won't you get some code for mass virtual hosts from http://naviserver.sourceforge.net/ ??&lt;br /&gt;
-PB&lt;br /&gt;
&lt;br /&gt;
: Right now, to map a request to its (virtual) server, there's an O(n) search being done, but it's a &amp;quot;cheap&amp;quot; exact string comparison.  To implement glob-style wildcard support, it'll become a more expensive (but possibly still &amp;quot;cheap&amp;quot; by most people's standards) glob-match comparison.  When you're serving &amp;quot;n&amp;quot; requests per second (where &amp;quot;n&amp;quot; is small) the difference in cost is probably immeasurable, but when &amp;quot;n&amp;quot; is large, the cost is additive and possibly significant.  It might be good if someone could benchmark the two and see what the real cost is. ''-- [[User:Dossy|Dossy]] 20:12, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Server-side Includes ==&lt;br /&gt;
&lt;br /&gt;
Does anyone have some code to implement apache-compatible SSI (Server-side includes)?  I have some old pages that use SSI that I'd like to move to my aolserver install but I don't have the time to rewrite them as ADPs.&lt;br /&gt;
&lt;br /&gt;
: ''[[User:Dossy|Dossy]] 20:20, 4 November 2005 (EST)'': I make no representations or warranties about the safety (!) or correctness of the code I'm about to share, but it might get folks started on a proper implementation in the future.  In particular, I didn't implement any commands other than &amp;quot;include&amp;quot; and I even implemented it &amp;quot;wrong&amp;quot; (not according to [http://hoohoo.ncsa.uiuc.edu/docs/tutorials/includes.html the specification]).  If there's real interest in having a complete SSI implementation for AOLserver, I'd be willing to improve this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags&amp;quot;&lt;br /&gt;
&lt;br /&gt;
proc ssi_include_tag {params} {&lt;br /&gt;
        set param_count [ns_set size $params]&lt;br /&gt;
        for {set i 0} {$i &amp;lt; $param_count} {incr i} {&lt;br /&gt;
                set ssi_var_[ns_set key $params $i] [ns_set value $params $i]&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if [info exists ssi_var_file] {&lt;br /&gt;
                if {[ns_adp_argc] &amp;gt; 1} {&lt;br /&gt;
                        set basedir [lindex [ns_adp_argv] 1]&lt;br /&gt;
                } else {&lt;br /&gt;
                        set basedir [ns_adp_dir]&lt;br /&gt;
                }&lt;br /&gt;
                if [regexp {^/} $ssi_var_file] {&lt;br /&gt;
                        set filename $ssi_var_file&lt;br /&gt;
                } else {&lt;br /&gt;
                        set filename $basedir/$ssi_var_file&lt;br /&gt;
                }&lt;br /&gt;
                return [ns_adp_parse -file $filename $basedir]&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ns_register_adptag {!--#include} ssi_include_tag&lt;br /&gt;
&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags done&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
   &lt;br /&gt;
Is there a way to see only the errors (for example - 'variable' xxx not found? I seem to remember 2 logs - servername.log and servername-error.log?  The version I have now - aolserver 3.2/ad1.2 only seems to give us servername.log - and all the error messages are mixed with the normal msgs - its very hard to debug!&lt;br /&gt;
[[dannyl50]]&lt;br /&gt;
&lt;br /&gt;
The default/example config file did not have entries for both logs. The two sections you need look like (in old style notation): &lt;br /&gt;
&lt;br /&gt;
 [ns/parameters]&lt;br /&gt;
 User=nsadmin &lt;br /&gt;
 Group=nsadmin &lt;br /&gt;
 ServerLog=/var/log/aolserver/servername-error.log &lt;br /&gt;
 PidFile=/var/log/aolserver/nspid.servername&lt;br /&gt;
 Home=/usr/bin/aolserver-3.3ad13 &lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
 [ns/server/servername/module/nslog]&lt;br /&gt;
 File=/var/log/aolserver/emp.log &lt;br /&gt;
 LogCombined=On &lt;br /&gt;
 MaxBackup=3 &lt;br /&gt;
 RollFmt=%Y-%m-%d-%H:%M &lt;br /&gt;
 RollHour=0 &lt;br /&gt;
 RollOnSignal=On &lt;br /&gt;
 RollLog=On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Howdy!  Can someone tell me, in general terms, how they have implemented [[nsperm]]?  It looks cool, but I am using a plain old database with names and passwords, and it is very easy.  I would like the allow/deny functionality, can I have that without the username/password part? -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I've implemented [[nsperm]] to restrict access to specific URLs using HTTP authentication (the username/password dialog) and cookie-based (if they have the correct cookie, otherwise URL redirect them to a login page that may set the cookie).''&lt;br /&gt;
''The latter is done using a registered preauth filter.  I chose to use [[nsperm]] over a database since [[nsperm]] (presumably) manages the authentication information in memory better than repeatedly hitting the database with authentication requests, but there's no reason''&lt;br /&gt;
''I couldn't have used a database to store username/password information.  Does this answer your question?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pretty much, although I started writing my app before I understood AOLServer, so I have a rather strange design that is good in some ways, bad in others.  Keep in mind that this is a low activity app, no more than 20 concurrent users right now.  &lt;br /&gt;
&lt;br /&gt;
What I did was to create an [[ADP]] that has a big case statement.  It calls functions to generate pages based on the 'task' value it is passed through POST.  I have created a pretty complex app this way, not using [[ns_register_proc]] at all.  I know now I should have.  As I understand it, ns_register_proc lets you create a 'virtual' directory structure that actually just calls certain procedures based on the GET or POST requested URL.  This is far more graceful than hitting my main adp which opens up the form data, looks at the 'task' value, and decides which procedures to call.  &lt;br /&gt;
&lt;br /&gt;
Given this lame structure, each time someone requests the main adp, I just check for a valid cookie and generate a login page if it's not there.  After that, I have to set another cookie that is their 'access rights' which is then checked from within the procs that generate the pages.  If I was doing it right, I could have registered a proc that would fire for all URLs in my virtual tree, checking your rights to the particular URL you reqested, and redirecting you if you are not allowed, right?  &lt;br /&gt;
&lt;br /&gt;
Thanks!!! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I probably would've created an ADP per task, and then registered a preauth filter that checked for the cookie and redirected the user to the login page (outside the directory that the preauth filter covers''&lt;br /&gt;
''-- avoid funny redirection loops) if the cookie wasn't set properly.''&lt;br /&gt;
''If you don't want to create a separate ADP per task, you could have used ns_register_proc to create what you describe as &amp;quot;virtual pages&amp;quot; and still have the preauth filter kind of &amp;quot;sit in front&amp;quot; and handle the autehntication, keeping that logic seperate from your actual page generation code.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I started with a separate adp for each task, but I thought it would get out of hand quickly.  I do think I will re-work the thing to use ns_register_proc and even do away with the few adp I do have.  It seems far easier to maintain.  In the meantime, I have to re-write all my SQL Server procedures in PostgreSQL PL/Tcl.  That's why I want the [[nsfreetds]] module so badly, it buys me a little time!&lt;br /&gt;
&lt;br /&gt;
Thanks for all your work! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
''Speaking of [[nsfreetds]], did you try nsfreetds-0.1pre?  Any luck?  Any problems?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I just now tried it.  I installed freetds with no trouble, compiled nsfreetds, modified my nsd.tcl [[config file]], added the datasource to interfaces, and all seems fine, except for that I always get &amp;quot;no access to pool &amp;quot;mypool&amp;quot; while executing &amp;quot;ns_db gethandle mypool&amp;quot; ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
I must have missed something.  I saw something in the README about setting $env(SYBASE) before starting nsd.  Is this the same as the SYBASE=/usr/pkg/freetds I had to do even before the build of nsfreetds?&lt;br /&gt;
&lt;br /&gt;
Thanks again... I feel like I am close.. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Yes, the $env(SYBASE) means setting the SYBASE environment variable.  To be safe, you can try this:''&lt;br /&gt;
&lt;br /&gt;
   $ cd /path/to/aolserver/install&lt;br /&gt;
   $ SYBASE=/usr/pkg/freetds; export SYBASE&lt;br /&gt;
   $ bin/nsd ...args...&lt;br /&gt;
&lt;br /&gt;
''Check log/server.log to make sure that the nsfreetds driver is actually loading.  You should see a lines like this at start-up:''&lt;br /&gt;
&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: modload: loading '/home/aolserver-dev/bin/nsfreetds.so'&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: Ns_FreeTDS_DriverInit(freetds):  Loaded Panoptic FreeTDS Driver v0.1-pre, built on May 21 2001 at 22:23:01.&lt;br /&gt;
&lt;br /&gt;
''Are you getting an error in the [[server log]] instead?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I don't get an error, it seems to load nicely.  I can post or give you access to whatever files or output you would like to see, or an ssh login... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Another question:  Global variables ([[nsv]]*).  I am re-writing my app to use the [[ns_register_proc]] functionality versus my kludge where everything goes through an [[ADP]] that acts as a filter and traffic cop.  I have figured out register filter and register proc, but seem not to be able to use [[ns_puts]] from within the procs.  Is this right?  Anyway, I had been using [[ns_adp_include]] in my filter/traffic cop page to put consistent headers/footers on my pages.  I gather the more correct way (and only possible way with registered procs?) is to use global variables.  &lt;br /&gt;
&lt;br /&gt;
When do I initialize them?  How do I use them?  What are the caveats? W&lt;br /&gt;
&lt;br /&gt;
Thanks, -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Have you started by reading the NSV documentation?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
Of course not 8^0  That would be too easy!  I will... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
OK, I read it.  It's too easy.  I use it for header, footer, and client side script html, which I stuff into html variable before returning it.  I would like the filter option we talked about in the chat which would prepend or append html automatically, but this will do. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
How hard would it be to add an HTTPS equivalent of Ns_FetchURL?&lt;br /&gt;
&lt;br /&gt;
''If you can build shared libraries on your target platform with OpenSSL, it probably wouldn't be too hard.  The trick would be writing enough stub code that can be loaded via the Tcl &amp;quot;load&amp;quot; proc so that you could access the OpenSSL-based https client from your Tcl code.  Is there a lot of demand for this?  I could probably bang something out as an initial attempt.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
[[Scott Goodwin]]'s [[nsopenssl]] now contains client side https functionality.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Am I a brick, or does ns_register_proc just plain not work with more than one argument for the proc?  I have tried the following code on both aolserver 3.2 running on NT4 and aolserver 3.4 on NetBSD 1.5.  It fails to register the proc even once, if I try to register it with more than one argument anywhere else.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ns_register_proc GET /foo1 foo 1&lt;br /&gt;
 ns_register_proc GET /foo2 foo 1 2&lt;br /&gt;
 ns_register_proc GET /foo3 foo 1 2 3&lt;br /&gt;
&lt;br /&gt;
 proc foo { conn one {two 22} {three 333}} {&lt;br /&gt;
 ns_return 200 text/html &amp;quot;one is $one, two is $two, three is $three&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This must be something simple.  I have already posted to the aolserver list but the listserv seems to have gone mad.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''What are you trying to do?  It appears you want to pass constant parameters to your procedures.  If they are constants, why pass them?  Since ns_register_proc calls are generally in the global scope (and sourced when nsd starts) even a parameter that appears to be a variable probably can/will not vary.''&lt;br /&gt;
&lt;br /&gt;
''Presumably you need to get information from one page to another.  That means formvalues unless your page is stateful (usually a bad idea).  Check out the '''[[ns_conn]] form''' command to get yourself started.''  -- [[Jason Kane]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
OK, I'm using Windows 2000 SP2 and 3.4.1, and trying in vain to get Perl CGIs (legacy) to work.  The scripts work outside of Aolserver, and work on AOLserver on Linux, but when I try inside the script to GET from myself (eg, GET http://localhost:8000/foo?bar=bas), I'm told &amp;quot;unknown protocol TCP&amp;quot;, which is quite aggravating.&lt;br /&gt;
&lt;br /&gt;
Does anyone have any experience administering AOLServer on Windows?&lt;br /&gt;
&lt;br /&gt;
Thanks in advance!&lt;br /&gt;
&lt;br /&gt;
-Bill&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
This is interesting, wy do you let me change your page?&lt;br /&gt;
I'm trying to find an example of how to get my data using:&lt;br /&gt;
 set formdata [ns_conn form $conn]&lt;br /&gt;
&lt;br /&gt;
-Jason&lt;br /&gt;
&lt;br /&gt;
Because it's a wiki!  A proc that gets posted variables includes the line you wrote there... then when you want to actually get the values, you can use something like &lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_set get $formdata myvar]&lt;br /&gt;
&lt;br /&gt;
where myvar is the name of the variable.  There is also ns_queryget which looks like&lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_queryget myvar defaultval]&lt;br /&gt;
&lt;br /&gt;
This is handy because if there is no value, it will assign a default value.  &lt;br /&gt;
&lt;br /&gt;
Check out aolserver.com, they have extensive (although sometimes misleading) docs.  If something the docs says should work doesn't, ask.  It may be out of date.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I don't know where else to share my code fragments, so here seems like as good a place as any.  This one implements user public_html directories. It's based on someone else's stuff (I forget whose tho).  It should really do something with unknown mime types, and should do a better job with errors like unknown users.  It does honor directoryFile and adp maps in the config file.&lt;br /&gt;
&lt;br /&gt;
It works by registering a procedure to /users that interprets the username and finds their directory.  ns_register_proc doesn't allow wildcards other than in the last path element, so /~*  wouldn't work.  However that's not a problem for a filter, so there's a filter to take your /~user url and redirect it to /users/user&lt;br /&gt;
&lt;br /&gt;
-JR&lt;br /&gt;
&lt;br /&gt;
 proc homedir { conn ctx } {&lt;br /&gt;
   set url [ns_conn url $conn]&lt;br /&gt;
   set user {}&lt;br /&gt;
   set file {}&lt;br /&gt;
   regexp {^/users/([^/]*)(/.*)?$} $url dummy user file&lt;br /&gt;
   # ns_returnnotice 200 &amp;quot;url is $url user is $user, file is $file&amp;quot;&lt;br /&gt;
   set userfile [getUserFile $user $file]&lt;br /&gt;
   set type [ns_guesstype $userfile]&lt;br /&gt;
   if {[string match &amp;quot;*[ns_config ns/server/[ns_info server]]/adp map]&amp;quot; $userfile]} {&lt;br /&gt;
     # ns_log notice &amp;quot;adp parsing $userfile&amp;quot;&lt;br /&gt;
     set cwd [pwd]&lt;br /&gt;
     cd [file dirname $userfile]&lt;br /&gt;
     # ns_return 200 text/html [ns_adp_parse -file $userfile]&lt;br /&gt;
     set result [catch {ns_adp_parse -file $userfile} error]&lt;br /&gt;
     if {$result} {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     } else {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     }&lt;br /&gt;
     cd $cwd&lt;br /&gt;
   } else {&lt;br /&gt;
     switch $type {&lt;br /&gt;
       &amp;quot;*/*&amp;quot; {&lt;br /&gt;
       }&lt;br /&gt;
       default {&lt;br /&gt;
        ns_returnfile 200 $type $userfile&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
       &lt;br /&gt;
   if {[catch {set fp [open $userfile]}]} {&lt;br /&gt;
     ns_returnnotfound&lt;br /&gt;
     return&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 proc getUserFile {user path} {&lt;br /&gt;
   foreach tail [split ,[ns_config ns/server/[ns_info server] directoryfile] ,] {&lt;br /&gt;
     set userfile &amp;quot;[glob ~$user]/public_html$path$tail&amp;quot;&lt;br /&gt;
     if {[file exists $userfile] &amp;amp;&amp;amp; ![file isdirectory $userfile]} {&lt;br /&gt;
       return $userfile&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
   ns_returnnotfound&lt;br /&gt;
   # break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_proc GET /users/ homedir&lt;br /&gt;
 ns_register_proc POST /users/ homedir&lt;br /&gt;
 ns_register_proc HEAD /users/ homedir&lt;br /&gt;
 &lt;br /&gt;
 proc userRedir {conn arg why} {&lt;br /&gt;
   set url [ns_conn url]&lt;br /&gt;
   regsub {^/~(.*)} $url {/users/\1} redir&lt;br /&gt;
   ns_log notice &amp;quot;url is $url, redir is $redir&amp;quot;&lt;br /&gt;
   ns_returnredirect $redir&lt;br /&gt;
   return filter_break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_filter preauth GET /~* userRedir&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Hi!&lt;br /&gt;
&lt;br /&gt;
Does anybody know a graphing module for Aolserver/TCL, with e.g. bargraphs, linegraphs,... ?&lt;br /&gt;
&lt;br /&gt;
-[[wiwo]]&lt;br /&gt;
&lt;br /&gt;
''Yes: [[nsgds]], [[nschartdir]].''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Can I detect if the user pushes the Stop button in their browser in my TCL/ADP page?&lt;br /&gt;
&lt;br /&gt;
Yes, although it's a kludge. ns_write will return zero if it cannot write because the connection has been lost. However, ns_write is not stupid enough to try writing when you give it nothing to write, and so you must send something to the client. To prevent this being rendered use HTML comments, e.g.&lt;br /&gt;
&lt;br /&gt;
 if {[ns_write &amp;quot;&amp;lt;nowiki&amp;gt;&amp;lt;!-- STOP DETECTOR --&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;] == 0} {&lt;br /&gt;
     # user hit the stop button, browser page was closed, or connection to client was lost.&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Ximon Eighteen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Generating random passwords ==&lt;br /&gt;
&lt;br /&gt;
The following method can be useful to generate random passwords and/or password salts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # desired length of random string&lt;br /&gt;
  set iStringLength 8&lt;br /&gt;
&lt;br /&gt;
 # characters allowed to appear in the string&lt;br /&gt;
  set sAllowableCharacters &amp;quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # get length one time&lt;br /&gt;
  set iAllowableCharacters [string length $sAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
 # begin random string as empty&lt;br /&gt;
  set sRandomString &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # loop until desired length is achieved&lt;br /&gt;
  for {set ii 0} {$ii &amp;lt; $iStringLength} {incr ii} {&lt;br /&gt;
&lt;br /&gt;
   # get next random between 0 and length of allowed characters&lt;br /&gt;
    set iRandomInt [ns_rand $iAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
   # retrieve this random character&lt;br /&gt;
    set sRandomCharacter [string index $sAllowableCharacters $iRandomInt]&lt;br /&gt;
&lt;br /&gt;
   # append the character to our random string&lt;br /&gt;
    append sRandomString $sRandomCharacter&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  ns_adp_puts &amp;quot;sRandomString: $sRandomString&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Customizing error pages ==&lt;br /&gt;
&lt;br /&gt;
Edit your AOLServer's config file, and add the paths to the error pages as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Internal redirects&lt;br /&gt;
#&lt;br /&gt;
ns_section &amp;quot;ns/server/${servername}/redirects&amp;quot;&lt;br /&gt;
ns_param   404 &amp;quot;/notfound.html&amp;quot;      ;# Not Found error page&lt;br /&gt;
ns_param   500 &amp;quot;/servererror.html&amp;quot;   ;# Server Error page&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Fast caching of generated pages ==&lt;br /&gt;
&lt;br /&gt;
You can use an adp page to handle a 404 (not found) error that generated exactly the page it was looking for.  Conceptually this is similar to how tcl's autoloading using unknown works.  From Bas Sheffers, via John Buckman.&lt;br /&gt;
&lt;br /&gt;
from config.tcl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_section &amp;quot;ns/server/$server1/redirects&amp;quot;&lt;br /&gt;
ns_param   404           /404.adp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
404.adp:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;% handle_404 %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Support procs:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc handle_404 {} {&lt;br /&gt;
    set myurl [myurl]&lt;br /&gt;
    set parts [split $myurl /]&lt;br /&gt;
    set root [lindex $parts 1]&lt;br /&gt;
&lt;br /&gt;
    if {$root == &amp;quot;photo&amp;quot;} {&lt;br /&gt;
        return [404_photo $parts]&lt;br /&gt;
    } else {&lt;br /&gt;
        ns_returnredirect &amp;quot;[myhost]/&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc 404_photo {parts} {&lt;br /&gt;
    &lt;br /&gt;
    set userid [file rootname [lindex $parts 2]]&lt;br /&gt;
    set d [user_photo_data $userid]&lt;br /&gt;
    if {$d == &amp;quot;&amp;quot;} {&lt;br /&gt;
        set fn &amp;quot;/b/photo/unknown.jpg&amp;quot;&lt;br /&gt;
    } else {&lt;br /&gt;
        set fn &amp;quot;/b/photo/${userid}.jpg&amp;quot;&lt;br /&gt;
        write_binary_file $fn $d&lt;br /&gt;
    }&lt;br /&gt;
    ns_returnfile 200 &amp;quot;image/jpeg&amp;quot; $fn&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc myurl {} {&lt;br /&gt;
    return [lindex [split [ns_conn request]] 1]   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
proc photo_cache_dirty {userid} {&lt;br /&gt;
    set fn &amp;quot;/b/photo/${userid}.jpg&amp;quot;&lt;br /&gt;
    file delete $fn&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changing maximum upload file size ==&lt;br /&gt;
&lt;br /&gt;
For aolserver 4.5 and higher, to change the maximum upload file size from the default value to a custom one, add a line like this to the server configuration file:&lt;br /&gt;
&lt;br /&gt;
ns_limits set default -maxupload [expr 25 * 1024 * 1024]  ;# Maximum file size set to 25Mb&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Frequently_Asked_Questions&amp;diff=5093</id>
		<title>Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Frequently_Asked_Questions&amp;diff=5093"/>
		<updated>2007-09-06T23:58:33Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: /* What platforms does AOLserver support? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
(Please add new questions at the very bottom  of the list.  Thanks.)&lt;br /&gt;
&lt;br /&gt;
== What is AOLserver? ==&lt;br /&gt;
&lt;br /&gt;
AOLserver is America Online's Open Source web server.  AOLserver is the backbone of the largest and busiest production environments in the world.&lt;br /&gt;
&lt;br /&gt;
AOLserver is a multithreaded, Tcl-enabled, massively-scalable and extensible web server tuned for large scale, dynamic web sites. AOLserver also includes complete database integration and a dynamic page scripting language.&lt;br /&gt;
&lt;br /&gt;
== What is the latest version of AOLserver? ==&lt;br /&gt;
&lt;br /&gt;
* The latest stable 3.4.x version is 3.4.2 released 18 September 2001.&lt;br /&gt;
* The latest stable 3.5.x version is 3.5.11 released 17 October 2003.&lt;br /&gt;
* The latest stable 4.0.x version is 4.0.10 released 18 January 2005.&lt;br /&gt;
* The latest stable 4.5.x version is 4.5.0 released 27 June 2006.&lt;br /&gt;
* Current development (CVS HEAD) is 4.5.0.&lt;br /&gt;
&lt;br /&gt;
== Where can I get AOLserver? ==&lt;br /&gt;
&lt;br /&gt;
The AOLserver project is hosted at [http://sourceforge.net/ SourceForge], and file releases are available for [[download]] in the [http://sourceforge.net/project/showfiles.php?group_id=3152 AOLserver Project Filelist].&lt;br /&gt;
&lt;br /&gt;
== What platforms does AOLserver support? ==&lt;br /&gt;
&lt;br /&gt;
'''AOLserver''' is known to compile and run on the following platforms:&lt;br /&gt;
* Linux 2.2 (i386), 2.4 and 2.6&lt;br /&gt;
* Windows 95/98/NT/2K/XP (i386) (partially supported, see #6)&lt;br /&gt;
* FreeBSD 3.4, 5, 6 (i386)&lt;br /&gt;
* OpenBSD 2.5 (i386)&lt;br /&gt;
* UnixWare 7.x (i386)&lt;br /&gt;
* DEC Tru64 &amp;amp; OSF/1 4.0 (alpha)&lt;br /&gt;
* Solaris 2.x (sparc), Solaris 2.10 (x86)&lt;br /&gt;
* HP/UX 10 &amp;amp; 11 (hppa)&lt;br /&gt;
* Irix 6.x (mips)&lt;br /&gt;
* Apple MacOS X 10.3 (ppc), 10.4 (ppc)&lt;br /&gt;
&lt;br /&gt;
== How is AOLserver licensed and distributed? ==&lt;br /&gt;
&lt;br /&gt;
Via the [[AOLserver Public License]], viewable at http://aolserver.com/license/.&lt;br /&gt;
&lt;br /&gt;
== How does AOLserver performance compare to other major servers? ==&lt;br /&gt;
&lt;br /&gt;
[[Brady Wetherington]] says:  On Unix, AOLserver can generate many, many dynamic pages very quickly and reliably. It also has some special code paths designed to speed up processing of static pages (fastpath), though I don't use that very much, personally.  Along with the database connection pools, it's definitely one of the highest-performance web-based database systems I've used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How is it different from Apache HTTP Server? ==&lt;br /&gt;
&lt;br /&gt;
The current Apache HTTP Server&lt;br /&gt;
* is part of / a project of the Apache Software Foundation. The process of development and decision making is working for years and accepted by all participants&lt;br /&gt;
* allows to run applications in a process-pre-forking or multi-threaded environment by design&lt;br /&gt;
* is the leading webserver, so it is widely known, accepted and supported&lt;br /&gt;
* is itself a subproject accompanied by lots of well known other projects and frameworks (like Ant, Jakarta, Struts...)&lt;br /&gt;
&lt;br /&gt;
In contrast AOLserver&lt;br /&gt;
* can do lots of use cases that are done with Apache modules with a few lines of TCL code (via registered filters and procs)&lt;br /&gt;
* is bound to its multi-threaded architecture that has its own disadvantages, depending on what you want to do&lt;br /&gt;
&lt;br /&gt;
== How is it different from &amp;lt;insert other webserver&amp;gt;? ==&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
== Where is AOLserver appropriate?  Where is it not? ==&lt;br /&gt;
&lt;br /&gt;
It is not appropriate...&lt;br /&gt;
* when you want to do virtual hosting for multiple customers.  For static content, AOLserver is fine - you're just serving static content.  For dynamic, server-side functionality, to get the level of privilege separation necessary, you'd have to run a separate nsd per customer to ensure that one customer can't access the content/data of another's.  There are apparently some folks out there who have set up AOLserver just this way and are doing just this.&lt;br /&gt;
* when the code you want to use is not thread-safe (and you are not able to change that)&lt;br /&gt;
* when your main application makes heavy use of cgi-tools or other scripting languages like PHP or Phython (in general: where currently no active dedicated maintainer for corresponding modules is known)&lt;br /&gt;
* when you need backup of a large world wide community that uses tools, modules and code you can find and read in every single computer magazine. AOLserver and TCL are niche products, which only means they are not sexy to the broad audience, but are used intensively by a sophisticated, intelligent minority&lt;br /&gt;
* when you know you would need more than one day to convince your customer to use it (in other words: if you use technology the first time don't let your most important customer be the beta tester)&lt;br /&gt;
&lt;br /&gt;
It is appropriate...&lt;br /&gt;
* when you want to make maximum use of your machines hardware ressources: AOLserver is a highly configurable beast that allows you to run big websites&lt;br /&gt;
* when you plan to run a website that makes heavy use of one or more databases (using pooled connections)&lt;br /&gt;
* when you want to cache lots or all of your static files (.html,.gif,.css.,.js ...) in your servers memory (via modules fastpath and nscache)&lt;br /&gt;
* when you like the good feeling of running and coding your apps on a well-tested multi-threaded server architecture. The server never has been a process-forking one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The idea here is if you know your requirements and your scope is fairly stable and you feel comfortable you can predict the future, and if all signs point to the app. remaining small-to-medium in usage/traffic, then pick whatever platform or technology you like the best -- it really won't make a difference.  But, if you think that it's a very real possibility you'll need&lt;br /&gt;
to scale up capacity to meet growing demand/traffic, possibly indefinitely, then yes, the hidden cost of re-architecting or migrating to a different technology can be a killer when you have to use the words &amp;quot;sunk cost&amp;quot; to describe the originally developed system.  In that case, you may be better off starting with implementing with AOLserver, as its performance &amp;quot;ceiling&amp;quot; so to speak is higher than other technologies.  (TODO: Benchmarks demonstrating this empirically?)&lt;br /&gt;
&lt;br /&gt;
== How do I get started with AOLserver? ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;need to link to a newbie guide HOWTO&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How can I learn more about AOLserver? ==&lt;br /&gt;
&lt;br /&gt;
Start by reading the [[Documentation]], which is still a work-in-progress.&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;package require&amp;quot; doesn't work!  What's wrong? ==&lt;br /&gt;
&lt;br /&gt;
Here's the relevant portion of a message [[Dossy Shiobara]] sent to the AOLserver mailing list back on 16 June 2000:&lt;br /&gt;
&lt;br /&gt;
  set tcl_library [file join $tcl_pkgPath tcl${tcl_version}]&lt;br /&gt;
  source [file join $tcl_library init.tcl]&lt;br /&gt;
&lt;br /&gt;
  package require works like a charm after that :-)&lt;br /&gt;
&lt;br /&gt;
There you have it.  Perhaps, some day, this won't be a necessary step.  But, in the meantime ...&lt;br /&gt;
&lt;br /&gt;
''As of AOLserver 4.0 and perhaps even a late version of 3.5.x, this step is no longer necessary.''&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;ns_set update [ns_conn outputheaders] Content-Type&amp;quot; results in the server sending two copies of the Content-Type header.  Why? ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ns_set update [ns_conn outputheaders $conn] Content-Type {application/x-tcl}&amp;quot; does not work in .adp files as I wish.  The server always returns two copies of the Content-Type header, one as application/x-tcl, another as text/html and clients(galeon, tcl http package) always use the second.  How do I remove the second Content-Type?'''&lt;br /&gt;
&lt;br /&gt;
Good question -- this is really a bug that needs to be fixed in the server code itself.&lt;br /&gt;
&lt;br /&gt;
== How can I get Tclet scripts served from AOLserver to run inside the Tcl Plugin? ==&lt;br /&gt;
&lt;br /&gt;
Someone asks: ''I have an aolserver for OpenACS.  I installed Tcl Plugin which works well with classic Tclets on Tcl Plugin Home Pages.  But with Aolserver, it doesn't work.... Do you know the answer of this?''&lt;br /&gt;
&lt;br /&gt;
== How can I compile AOLserver on HP-UX, both 10.20 and 11.x? ==&lt;br /&gt;
&lt;br /&gt;
[[Dossy]]: Good question.  If I had easy access to HP-UX machines, I'd try it myself.  AOLserver 4.x should hopefully build on HP-UX without any changes, but I'm only guessing.&lt;br /&gt;
&lt;br /&gt;
HPUX doesn't implement a lot of BSD/POSIX IPC functions, or so I hear.&lt;br /&gt;
&lt;br /&gt;
== I'm getting an error compiling AOLserver about POLLIN, POLLOUT and POLLPRI being redefined.  What's wrong? ==&lt;br /&gt;
&lt;br /&gt;
AOLserver requires that the &amp;quot;configure&amp;quot; script be run using the GNU C (gcc) compiler.  Try running the configure script like this:&lt;br /&gt;
&lt;br /&gt;
    $ CC=gcc ./configure --args...&lt;br /&gt;
&lt;br /&gt;
== Does AOLserver support HTTP Keep-Alive?  I'm sending a HTTP/1.1 request via httperf and AOLserver isn't doing Keep-Alive like Apache does!  What's wrong? ==&lt;br /&gt;
&lt;br /&gt;
Actually, nothing is wrong. You just need to tell httperf to include the headers that tell AOLserver to expect multiple requests per connection. Add '--add_header &amp;quot;Connection: Keep-Alive\n&amp;quot;' to your httperf request. &lt;br /&gt;
&lt;br /&gt;
The issue is that Apache and AOLserver chose opposite default behaviors when interpretting [http://www.ietf.org/rfc/rfc2068.txt RFC 2068 section 8.1.2.1]:&lt;br /&gt;
&lt;br /&gt;
   An HTTP/1.1 server MAY assume that a HTTP/1.1 client intends to&lt;br /&gt;
   maintain a persistent connection unless a Connection header including&lt;br /&gt;
   the connection-token &amp;quot;close&amp;quot; was sent in the request. If the server&lt;br /&gt;
   chooses to close the connection immediately after sending the&lt;br /&gt;
   response, it SHOULD send a Connection header including the&lt;br /&gt;
   connection-token close.&lt;br /&gt;
&lt;br /&gt;
   An HTTP/1.1 client MAY expect a connection to remain open, but would&lt;br /&gt;
   decide to keep it open based on whether the response from a server&lt;br /&gt;
   contains a Connection header with the connection-token close. In case&lt;br /&gt;
   the client does not want to maintain a connection for more than that&lt;br /&gt;
   request, it SHOULD send a Connection header including the&lt;br /&gt;
   connection-token close.&lt;br /&gt;
&lt;br /&gt;
The key here is &amp;quot;MAY&amp;quot; -- AOLserver (currently, as of 4.0.10) chooses not to assume a Keep-Alive connection unless the client explicitly requests it by sending &amp;quot;Connection: Keep-Alive&amp;quot; in the HTTP request header.  This may change in the future (HTTP/1.1 requests default to Keep-Alive unless the client explicitly sends &amp;quot;Connection: close&amp;quot; -- apparently this is how Apache works).&lt;br /&gt;
&lt;br /&gt;
== AOLserver 4.0.10 is consuming all my memory ==&lt;br /&gt;
&lt;br /&gt;
[http://www.mail-archive.com/aolserver%40listserv.aol.com/msg09104.html Bas Scheffers says]: What version of Tcl did you use? Use 8.4.11 or 8.4.6, but nothing in between as they have a big memory leak.&lt;br /&gt;
&lt;br /&gt;
Note that debian sarge includes tcl 8.4.9 (as of 2006-01-03).&lt;br /&gt;
&lt;br /&gt;
== How do I customize standard HTTP responses? ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Internal redirects&lt;br /&gt;
#&lt;br /&gt;
ns_section &amp;quot;ns/server/${servername}/redirects&amp;quot;&lt;br /&gt;
ns_param   404 &amp;quot;/notfound.html&amp;quot;      ;# Not Found error page&lt;br /&gt;
ns_param   500 &amp;quot;/servererror.html&amp;quot;   ;# Server Error page&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]]&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5092</id>
		<title>User:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5092"/>
		<updated>2007-09-05T16:57:10Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: /* Experience with AOLServer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Quick Contact info ==&lt;br /&gt;
&lt;br /&gt;
Name: Juan José del Río&amp;lt;br/&amp;gt;&lt;br /&gt;
Company: [http://www.simpleoption.com/empresa/ Simple Option]&amp;lt;br/&amp;gt;&lt;br /&gt;
Telephone: +34 616 512 340&amp;lt;br/&amp;gt;&lt;br /&gt;
E-mail: [mailto:juanjose@simpleoption.com]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://juanjose.simpleoption.com/ Business blog]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.sandii.org/juan/ More information about me]&lt;br /&gt;
&lt;br /&gt;
== Experience with AOLServer ==&lt;br /&gt;
&lt;br /&gt;
I have used AOLServer on top of FreeBSD to design an online shop ( [http://www.simpleoption.com Simple Option] ). Basically it's a site that interacts with a database, using the great AOLServer database access API. Also, I use many other modules like nssession to track users. And all of this is acomplished in around 2K lines of code.&lt;br /&gt;
&lt;br /&gt;
Also, the raw-text visit logs are processed, and logged into a database, and later are processed via AOLServer + GdTclFt to create graphs, and give many other statistics of the usage.&lt;br /&gt;
&lt;br /&gt;
The advantages of AOLServer for this kind of project is the easyness of programming, since TCL is an excellent language if you want to work with strings (that is, HTML), and AOLServer lets me have a really easy and efficient access to several databases in the application. This combination lets me focus in the real problem, and not in the pure technical side of it.&lt;br /&gt;
&lt;br /&gt;
As a side note, the expertise that you get by using TCL can be reused later when programming TK applications for desktop.&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5091</id>
		<title>User:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5091"/>
		<updated>2007-09-05T14:05:26Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: /* Quick Contact info */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Quick Contact info ==&lt;br /&gt;
&lt;br /&gt;
Name: Juan José del Río&amp;lt;br/&amp;gt;&lt;br /&gt;
Company: [http://www.simpleoption.com/empresa/ Simple Option]&amp;lt;br/&amp;gt;&lt;br /&gt;
Telephone: +34 616 512 340&amp;lt;br/&amp;gt;&lt;br /&gt;
E-mail: [mailto:juanjose@simpleoption.com]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://juanjose.simpleoption.com/ Business blog]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.sandii.org/juan/ More information about me]&lt;br /&gt;
&lt;br /&gt;
== Experience with AOLServer ==&lt;br /&gt;
&lt;br /&gt;
I have used AOLServer on top of FreeBSD to design an online shop ( [http://www.simpleoption.com Simple Option] ). Basically it's a site that interacts with a database, using the great AOLServer database access API. Also, I use many other modules as nssession to track users. And all of this is acomplished in around 2K lines of code.&lt;br /&gt;
&lt;br /&gt;
Also, the raw-text visit logs are processed, and logged into a database, where later are processed via AOLServer + GdTclFt to create graphs, and give many other statistics of the usage.&lt;br /&gt;
&lt;br /&gt;
The advantages of AOLServer for this kind of project is the easyness of programming, since TCL is an excellent language if you want to work with strings (that is, HTML), and AOLServer lets me have a really easy and efficient access to several databases in the application. This combination lets me focus in the real problem, and not in the pure technical side of it.&lt;br /&gt;
&lt;br /&gt;
As a side note, the expertise that you get by using TCL can be reused later when programming TK applications for desktop.&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5090</id>
		<title>User:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5090"/>
		<updated>2007-09-05T13:56:18Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: /* Experience with AOLServer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Quick Contact info ==&lt;br /&gt;
&lt;br /&gt;
Name: Juan José del Río&amp;lt;br/&amp;gt;&lt;br /&gt;
Company: Simple Option&amp;lt;br/&amp;gt;&lt;br /&gt;
Telephone: +34 616 512 340&amp;lt;br/&amp;gt;&lt;br /&gt;
E-mail: [mailto:juanjose@simpleoption.com]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://juanjose.simpleoption.com/ Business blog]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.sandii.org/juan/ More information about me]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Experience with AOLServer ==&lt;br /&gt;
&lt;br /&gt;
I have used AOLServer on top of FreeBSD to design an online shop ( [http://www.simpleoption.com Simple Option] ). Basically it's a site that interacts with a database, using the great AOLServer database access API. Also, I use many other modules as nssession to track users. And all of this is acomplished in around 2K lines of code.&lt;br /&gt;
&lt;br /&gt;
Also, the raw-text visit logs are processed, and logged into a database, where later are processed via AOLServer + GdTclFt to create graphs, and give many other statistics of the usage.&lt;br /&gt;
&lt;br /&gt;
The advantages of AOLServer for this kind of project is the easyness of programming, since TCL is an excellent language if you want to work with strings (that is, HTML), and AOLServer lets me have a really easy and efficient access to several databases in the application. This combination lets me focus in the real problem, and not in the pure technical side of it.&lt;br /&gt;
&lt;br /&gt;
As a side note, the expertise that you get by using TCL can be reused later when programming TK applications for desktop.&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5089</id>
		<title>User:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5089"/>
		<updated>2007-09-05T13:55:49Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: /* Experience with AOLServer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Quick Contact info ==&lt;br /&gt;
&lt;br /&gt;
Name: Juan José del Río&amp;lt;br/&amp;gt;&lt;br /&gt;
Company: Simple Option&amp;lt;br/&amp;gt;&lt;br /&gt;
Telephone: +34 616 512 340&amp;lt;br/&amp;gt;&lt;br /&gt;
E-mail: [mailto:juanjose@simpleoption.com]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://juanjose.simpleoption.com/ Business blog]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.sandii.org/juan/ More information about me]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Experience with AOLServer ==&lt;br /&gt;
&lt;br /&gt;
I have used AOLServer on top of FreeBSD to design an online shop ( [http://www.simpleoption.com Simple Option] ). Basically it's a site that interacts with a database, using the great AOLServer database access API. Also, I use many other modules as nssession to track users. And all of this is acomplished in around 3K lines of code.&lt;br /&gt;
&lt;br /&gt;
Also, the raw-text visit logs are processed, and logged into a database, where later are processed via AOLServer + GdTclFt to create graphs, and give many other statistics of the usage.&lt;br /&gt;
&lt;br /&gt;
The advantages of AOLServer for this kind of project is the easyness of programming, since TCL is an excellent language if you want to work with strings (that is, HTML), and AOLServer lets me have a really easy and efficient access to several databases in the application. This combination lets me focus in the real problem, and not in the pure technical side of it.&lt;br /&gt;
&lt;br /&gt;
As a side note, the expertise that you get by using TCL can be reused later when programming TK applications for desktop.&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5088</id>
		<title>User:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5088"/>
		<updated>2007-09-05T13:53:50Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: /* Quick Contact info */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Quick Contact info ==&lt;br /&gt;
&lt;br /&gt;
Name: Juan José del Río&amp;lt;br/&amp;gt;&lt;br /&gt;
Company: Simple Option&amp;lt;br/&amp;gt;&lt;br /&gt;
Telephone: +34 616 512 340&amp;lt;br/&amp;gt;&lt;br /&gt;
E-mail: [mailto:juanjose@simpleoption.com]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://juanjose.simpleoption.com/ Business blog]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.sandii.org/juan/ More information about me]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Experience with AOLServer ==&lt;br /&gt;
&lt;br /&gt;
I have used AOLServer on top of FreeBSD to design an online shop ( [http://www.simpleoption.com Simple Option] ). Basically it's a site that interacts with a database, using the great AOLServer database access API. Also, I use many other modules as nssession to track users.&lt;br /&gt;
&lt;br /&gt;
Also, the text visit logs are processed, and logged into a database, where later are processed via AOLServer + GdTclFt to create graphs, and give many other statistics of the usage.&lt;br /&gt;
&lt;br /&gt;
The advantages of AOLServer for this kind of project is the easyness of programming, since TCL is an excellent language if you want to work with strings (that is, HTML), and AOLServer lets you have easy and efficient access to databases. This combination lets you focusing in the real problem, and not in the pure technical side of it.&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Nssession&amp;diff=5087</id>
		<title>Nssession</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Nssession&amp;diff=5087"/>
		<updated>2007-09-05T13:44:47Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;nssession is a module for [[AOLserver]] whose goal is to implement server-side session management.&lt;br /&gt;
&lt;br /&gt;
The [[nssession specification]] describes the functionality of the module.  If you're interested in it, check it out.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''2001-12-22''':  New!  A reference implementation is available via anonymous CVS:&lt;br /&gt;
&lt;br /&gt;
 cvs -d :pserver:anonymous@cvs.panoptic.com:/home/cvs co -d nssession aolserver/nssession&lt;br /&gt;
&lt;br /&gt;
It's still (at best) alpha quality, but it might be fun to play with.&lt;br /&gt;
&lt;br /&gt;
Quickstart guide:&lt;br /&gt;
* Slap the nssession.tcl file into your tcl library.&lt;br /&gt;
* Add the following to your nsd.tcl:&lt;br /&gt;
&lt;br /&gt;
 ns_section &amp;quot;ns/server/${server_name}/sessions&amp;quot;&lt;br /&gt;
 ns_param dir          /path/to/where/you/want/to/store/your/sessions&lt;br /&gt;
&lt;br /&gt;
(The default location is [ns_info home]/servers/[ns_info server]/modules/nssession/sessions.)&lt;br /&gt;
* Restart your nsd.&lt;br /&gt;
&lt;br /&gt;
Read the [[nssession specification]] to see what's in the ns_session API,&lt;br /&gt;
and start playing.&lt;br /&gt;
&lt;br /&gt;
-- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
'''2007-08-26''':  I got nssession working on AOLServer 4.5 on top of FreeBSD 6.2&lt;br /&gt;
&lt;br /&gt;
http://juanjose.simpleoption.com/2007/08/26/how-to-get-nssession-working-on-aolserver-45/&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Juanjose&amp;diff=5023</id>
		<title>User talk:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Juanjose&amp;diff=5023"/>
		<updated>2006-12-18T20:24:43Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am feeling so alone... ;) Please, tell me something! :D&lt;br /&gt;
&lt;br /&gt;
: ''Looks like you're able to get on the wiki now.  :-)'' -- [[User:Dossy|Dossy]] 14:00, 18 December 2006 (EST)&lt;br /&gt;
&lt;br /&gt;
:: ''Yep. This rocks :-)'' --[[User:Juanjose|juanjose]] 15:23, 18 December 2006 (EST)&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Juanjose&amp;diff=5022</id>
		<title>User talk:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Juanjose&amp;diff=5022"/>
		<updated>2006-12-18T20:23:49Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am feeling so alone... ;) Please, tell me something! :D&lt;br /&gt;
&lt;br /&gt;
: ''Looks like you're able to get on the wiki now.  :-)'' -- [[User:Dossy|Dossy]] 14:00, 18 December 2006 (EST)&lt;br /&gt;
&lt;br /&gt;
Yep. This rocks :) --[[User:Juanjose|juanjose]] 15:23, 18 December 2006 (EST)&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5020</id>
		<title>User:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5020"/>
		<updated>2006-12-15T17:45:12Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Quick Contact info ==&lt;br /&gt;
&lt;br /&gt;
Name: Juan José del Río&amp;lt;br/&amp;gt;&lt;br /&gt;
Company: Simple Option&amp;lt;br/&amp;gt;&lt;br /&gt;
Telephone: +34 616 512 340&amp;lt;br/&amp;gt;&lt;br /&gt;
E-mail: [mailto:juanjose@simpleoption.com]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: [http://www.sandii.org/juan]&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:See_if_it_happens_again&amp;diff=5019</id>
		<title>Talk:See if it happens again</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:See_if_it_happens_again&amp;diff=5019"/>
		<updated>2006-12-15T17:32:03Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;lol --[[User:Juanjose|juanjose]] 12:32, 15 December 2006 (EST)&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Juanjose&amp;diff=5018</id>
		<title>User talk:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Juanjose&amp;diff=5018"/>
		<updated>2006-12-15T17:28:30Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am feeling so alone... ;) Please, tell me something! :D&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5017</id>
		<title>User:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5017"/>
		<updated>2006-12-15T17:27:08Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Quick Contact info ==&lt;br /&gt;
&lt;br /&gt;
Name: Juan José del Río&amp;lt;br/&amp;gt;&lt;br /&gt;
Company: Simple Option&amp;lt;br/&amp;gt;&lt;br /&gt;
Telephone: +34 616 512 340&amp;lt;br/&amp;gt;&lt;br /&gt;
E-mail: juanjose@simpleoption.com&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: [http://www.sandii.org/juan]&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5016</id>
		<title>User:Juanjose</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Juanjose&amp;diff=5016"/>
		<updated>2006-12-15T17:25:35Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Name: Juan José del Río&lt;br /&gt;
Company: Simple Option&lt;br /&gt;
Telephone: +34 616 512 340&lt;br /&gt;
E-mail: juanjose@simpleoption.com&lt;br /&gt;
Country: Spain&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5015</id>
		<title>AOLserver Cookbook</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Cookbook&amp;diff=5015"/>
		<updated>2006-12-15T17:23:57Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A collection of questions, and code examples to answer them.&lt;br /&gt;
&lt;br /&gt;
Add your questions here.  Answers should be placed below the question.  Place a horizontal line (&amp;quot;----&amp;quot;) between questions.  Please keep this text before the first question.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Limiting bandwidth ==&lt;br /&gt;
&lt;br /&gt;
Is there a simple way to limit bandwidth per connection/ip???&lt;br /&gt;
&lt;br /&gt;
: There's no simple way of doing it, i.e., no configuration option you can set.  If I had to implement this, I'd use NSV's and [[ns_register_filter]] to keep track of bandwidth consumed by each client IP which can act as an all-or-nothing mechanism.  However, what might be interesting to implement in the socket driver is a setting to control the rate at which bytes are written back to the socket, perhaps configurable per request, so that large HTTP responses don't soak up your upstream bandwidth.  We should keep this in mind for a future version of AOLserver. ''-- [[User:Dossy|Dossy]] 20:06, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
One more question... How can I read output buffer inside function registered as postauth filter?&lt;br /&gt;
And how can I stream it? ns_adp_puts cannot be used inside filters... ns_return would return all data at once. I assume that per connection limit would look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc ..... {&lt;br /&gt;
ns_adp_stream&lt;br /&gt;
set data [get output content buffer]&lt;br /&gt;
set data_length [output buffer size]&lt;br /&gt;
set block_size 4096&lt;br /&gt;
for {set i 0} {$i &amp;lt; $data_length} {incr i $block_size} {&lt;br /&gt;
   send_to_client [string range $data [expr $block_size*$i] [expr $block_size*[expr$i+1]]]&lt;br /&gt;
   sleep 1&lt;br /&gt;
}&lt;br /&gt;
ns_returnok&lt;br /&gt;
return filter_return&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
I want to limit only one vhost so nssock limit would be too much;)&lt;br /&gt;
&lt;br /&gt;
: First, you don't want to turn [[ns_adp_stream]]'ing on.  Getting the size of the ADP output buffer can be done using [[ns_adp_tell]] and getting the contents with [[ns_adp_dump]].  I guess you could [[ns_adp_trunc]] the output buffer to clear it, then slowly write the contents back using [[ns_write]].  You'd also then need to look at [[ns_conn]] '''outputheaders''' to make sure that you wrote the proper HTTP response ... ah, but I don't know if you can get the HTTP response status code somehow.  I still think doing it in nssock is probably the best place, even with vhosts -- I'd make it a preauth or postauth filter that sets the configuration for the response and then have nssock be responsible for ensuring the response is written at that rate. ''-- [[User:Dossy|Dossy]] 07:24, 8 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
ns_adp_tell inside postauth filter:&lt;br /&gt;
   Error: This function cannot be used outside of an ADP&lt;br /&gt;
what's more, i use ns_returnfile inside some adp code and if i use ns_adp_tell after it, it returns 0 (this adp only returns file, no adp_puts or write).&lt;br /&gt;
Unfortunetly i think there is no other solution then implement it inside nssock or implement some tcl code to manipulate all output buffer.&lt;br /&gt;
&lt;br /&gt;
I use this code for big files... some time I'll add per ip limit, now it's for connection.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
proc returnfile { file } {                                                      &lt;br /&gt;
    set filefp [open $file r]                                                   &lt;br /&gt;
    fconfigure $filefp -translation binary                                      &lt;br /&gt;
    set data_length [file size $file]                                           &lt;br /&gt;
    set block_size 4096                                                         &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_write &amp;quot;HTTP/1.0 200 OK                                                   &lt;br /&gt;
MIME-Version: 1.0                                                               &lt;br /&gt;
Content-Type: [ns_guesstype $file]                                              &lt;br /&gt;
Content-Length: $data_length                                                    &lt;br /&gt;
                                                                                &lt;br /&gt;
&amp;quot;                                                                               &lt;br /&gt;
    while { ! [eof $filefp] } {                                                 &lt;br /&gt;
        ns_writefp $filefp $block_size                                          &lt;br /&gt;
        ns_sleep 1                                                              &lt;br /&gt;
    }                                                                           &lt;br /&gt;
                                                                                &lt;br /&gt;
    ns_conn close                                                               &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Paul Bukowski&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Virtual server configuration ==&lt;br /&gt;
&lt;br /&gt;
Is it possible to use wildcard '*' in domain name inside &amp;quot;ns/module/nssock/servers&amp;quot; section of aolserver4 config file? I would like to map all requests to *.somedomain.org to one virtual host...&lt;br /&gt;
Something like this doesn't work:&lt;br /&gt;
&lt;br /&gt;
 ns_section &amp;quot;ns/module/nssock/servers&amp;quot;&lt;br /&gt;
 ns_param   forum           somedomain.org                                           &lt;br /&gt;
 ns_param   forum           somedomain.org:80                                        &lt;br /&gt;
 ns_param   forum           *.somedomain.org                                       &lt;br /&gt;
 ns_param   forum           *.somedomain.org:80&lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org&amp;quot;                                       &lt;br /&gt;
 ns_param   forum           &amp;quot;*.somedomain.org:80&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-Paul Bukowski&lt;br /&gt;
&lt;br /&gt;
: ''2005aug15 [[Dossy]]: Unfortunately, no -- you currently can't use wildcards the way you want.  Not yet, at least.''&lt;br /&gt;
&lt;br /&gt;
Why won't you get some code for mass virtual hosts from http://naviserver.sourceforge.net/ ??&lt;br /&gt;
-PB&lt;br /&gt;
&lt;br /&gt;
: Right now, to map a request to its (virtual) server, there's an O(n) search being done, but it's a &amp;quot;cheap&amp;quot; exact string comparison.  To implement glob-style wildcard support, it'll become a more expensive (but possibly still &amp;quot;cheap&amp;quot; by most people's standards) glob-match comparison.  When you're serving &amp;quot;n&amp;quot; requests per second (where &amp;quot;n&amp;quot; is small) the difference in cost is probably immeasurable, but when &amp;quot;n&amp;quot; is large, the cost is additive and possibly significant.  It might be good if someone could benchmark the two and see what the real cost is. ''-- [[User:Dossy|Dossy]] 20:12, 4 November 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Server-side Includes ==&lt;br /&gt;
&lt;br /&gt;
Does anyone have some code to implement apache-compatible SSI (Server-side includes)?  I have some old pages that use SSI that I'd like to move to my aolserver install but I don't have the time to rewrite them as ADPs.&lt;br /&gt;
&lt;br /&gt;
: ''[[User:Dossy|Dossy]] 20:20, 4 November 2005 (EST)'': I make no representations or warranties about the safety (!) or correctness of the code I'm about to share, but it might get folks started on a proper implementation in the future.  In particular, I didn't implement any commands other than &amp;quot;include&amp;quot; and I even implemented it &amp;quot;wrong&amp;quot; (not according to [http://hoohoo.ncsa.uiuc.edu/docs/tutorials/includes.html the specification]).  If there's real interest in having a complete SSI implementation for AOLserver, I'd be willing to improve this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags&amp;quot;&lt;br /&gt;
&lt;br /&gt;
proc ssi_include_tag {params} {&lt;br /&gt;
        set param_count [ns_set size $params]&lt;br /&gt;
        for {set i 0} {$i &amp;lt; $param_count} {incr i} {&lt;br /&gt;
                set ssi_var_[ns_set key $params $i] [ns_set value $params $i]&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if [info exists ssi_var_file] {&lt;br /&gt;
                if {[ns_adp_argc] &amp;gt; 1} {&lt;br /&gt;
                        set basedir [lindex [ns_adp_argv] 1]&lt;br /&gt;
                } else {&lt;br /&gt;
                        set basedir [ns_adp_dir]&lt;br /&gt;
                }&lt;br /&gt;
                if [regexp {^/} $ssi_var_file] {&lt;br /&gt;
                        set filename $ssi_var_file&lt;br /&gt;
                } else {&lt;br /&gt;
                        set filename $basedir/$ssi_var_file&lt;br /&gt;
                }&lt;br /&gt;
                return [ns_adp_parse -file $filename $basedir]&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ns_register_adptag {!--#include} ssi_include_tag&lt;br /&gt;
&lt;br /&gt;
ns_log Notice &amp;quot;ssi: registering SSI ADP tags done&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
   &lt;br /&gt;
Is there a way to see only the errors (for example - 'variable' xxx not found? I seem to remember 2 logs - servername.log and servername-error.log?  The version I have now - aolserver 3.2/ad1.2 only seems to give us servername.log - and all the error messages are mixed with the normal msgs - its very hard to debug!&lt;br /&gt;
[[dannyl50]]&lt;br /&gt;
&lt;br /&gt;
The default/example config file did not have entries for both logs. The two sections you need look like (in old style notation): &lt;br /&gt;
&lt;br /&gt;
 [ns/parameters]&lt;br /&gt;
 User=nsadmin &lt;br /&gt;
 Group=nsadmin &lt;br /&gt;
 ServerLog=/var/log/aolserver/servername-error.log &lt;br /&gt;
 PidFile=/var/log/aolserver/nspid.servername&lt;br /&gt;
 Home=/usr/bin/aolserver-3.3ad13 &lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
 [ns/server/servername/module/nslog]&lt;br /&gt;
 File=/var/log/aolserver/emp.log &lt;br /&gt;
 LogCombined=On &lt;br /&gt;
 MaxBackup=3 &lt;br /&gt;
 RollFmt=%Y-%m-%d-%H:%M &lt;br /&gt;
 RollHour=0 &lt;br /&gt;
 RollOnSignal=On &lt;br /&gt;
 RollLog=On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Howdy!  Can someone tell me, in general terms, how they have implemented [[nsperm]]?  It looks cool, but I am using a plain old database with names and passwords, and it is very easy.  I would like the allow/deny functionality, can I have that without the username/password part? -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I've implemented [[nsperm]] to restrict access to specific URLs using HTTP authentication (the username/password dialog) and cookie-based (if they have the correct cookie, otherwise URL redirect them to a login page that may set the cookie).''&lt;br /&gt;
''The latter is done using a registered preauth filter.  I chose to use [[nsperm]] over a database since [[nsperm]] (presumably) manages the authentication information in memory better than repeatedly hitting the database with authentication requests, but there's no reason''&lt;br /&gt;
''I couldn't have used a database to store username/password information.  Does this answer your question?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pretty much, although I started writing my app before I understood AOLServer, so I have a rather strange design that is good in some ways, bad in others.  Keep in mind that this is a low activity app, no more than 20 concurrent users right now.  &lt;br /&gt;
&lt;br /&gt;
What I did was to create an [[ADP]] that has a big case statement.  It calls functions to generate pages based on the 'task' value it is passed through POST.  I have created a pretty complex app this way, not using [[ns_register_proc]] at all.  I know now I should have.  As I understand it, ns_register_proc lets you create a 'virtual' directory structure that actually just calls certain procedures based on the GET or POST requested URL.  This is far more graceful than hitting my main adp which opens up the form data, looks at the 'task' value, and decides which procedures to call.  &lt;br /&gt;
&lt;br /&gt;
Given this lame structure, each time someone requests the main adp, I just check for a valid cookie and generate a login page if it's not there.  After that, I have to set another cookie that is their 'access rights' which is then checked from within the procs that generate the pages.  If I was doing it right, I could have registered a proc that would fire for all URLs in my virtual tree, checking your rights to the particular URL you reqested, and redirecting you if you are not allowed, right?  &lt;br /&gt;
&lt;br /&gt;
Thanks!!! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''I probably would've created an ADP per task, and then registered a preauth filter that checked for the cookie and redirected the user to the login page (outside the directory that the preauth filter covers''&lt;br /&gt;
''-- avoid funny redirection loops) if the cookie wasn't set properly.''&lt;br /&gt;
''If you don't want to create a separate ADP per task, you could have used ns_register_proc to create what you describe as &amp;quot;virtual pages&amp;quot; and still have the preauth filter kind of &amp;quot;sit in front&amp;quot; and handle the autehntication, keeping that logic seperate from your actual page generation code.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I started with a separate adp for each task, but I thought it would get out of hand quickly.  I do think I will re-work the thing to use ns_register_proc and even do away with the few adp I do have.  It seems far easier to maintain.  In the meantime, I have to re-write all my SQL Server procedures in PostgreSQL PL/Tcl.  That's why I want the [[nsfreetds]] module so badly, it buys me a little time!&lt;br /&gt;
&lt;br /&gt;
Thanks for all your work! -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
''Speaking of [[nsfreetds]], did you try nsfreetds-0.1pre?  Any luck?  Any problems?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I just now tried it.  I installed freetds with no trouble, compiled nsfreetds, modified my nsd.tcl [[config file]], added the datasource to interfaces, and all seems fine, except for that I always get &amp;quot;no access to pool &amp;quot;mypool&amp;quot; while executing &amp;quot;ns_db gethandle mypool&amp;quot; ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
I must have missed something.  I saw something in the README about setting $env(SYBASE) before starting nsd.  Is this the same as the SYBASE=/usr/pkg/freetds I had to do even before the build of nsfreetds?&lt;br /&gt;
&lt;br /&gt;
Thanks again... I feel like I am close.. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Yes, the $env(SYBASE) means setting the SYBASE environment variable.  To be safe, you can try this:''&lt;br /&gt;
&lt;br /&gt;
   $ cd /path/to/aolserver/install&lt;br /&gt;
   $ SYBASE=/usr/pkg/freetds; export SYBASE&lt;br /&gt;
   $ bin/nsd ...args...&lt;br /&gt;
&lt;br /&gt;
''Check log/server.log to make sure that the nsfreetds driver is actually loading.  You should see a lines like this at start-up:''&lt;br /&gt;
&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: modload: loading '/home/aolserver-dev/bin/nsfreetds.so'&lt;br /&gt;
   [30/May/2001:13:42:37][11838.1024][-main-] Notice: Ns_FreeTDS_DriverInit(freetds):  Loaded Panoptic FreeTDS Driver v0.1-pre, built on May 21 2001 at 22:23:01.&lt;br /&gt;
&lt;br /&gt;
''Are you getting an error in the [[server log]] instead?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
I don't get an error, it seems to load nicely.  I can post or give you access to whatever files or output you would like to see, or an ssh login... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Another question:  Global variables ([[nsv]]*).  I am re-writing my app to use the [[ns_register_proc]] functionality versus my kludge where everything goes through an [[ADP]] that acts as a filter and traffic cop.  I have figured out register filter and register proc, but seem not to be able to use [[ns_puts]] from within the procs.  Is this right?  Anyway, I had been using [[ns_adp_include]] in my filter/traffic cop page to put consistent headers/footers on my pages.  I gather the more correct way (and only possible way with registered procs?) is to use global variables.  &lt;br /&gt;
&lt;br /&gt;
When do I initialize them?  How do I use them?  What are the caveats? W&lt;br /&gt;
&lt;br /&gt;
Thanks, -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''Have you started by reading the NSV documentation?'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
Of course not 8^0  That would be too easy!  I will... -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
OK, I read it.  It's too easy.  I use it for header, footer, and client side script html, which I stuff into html variable before returning it.  I would like the filter option we talked about in the chat which would prepend or append html automatically, but this will do. -- [[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
How hard would it be to add an HTTPS equivalent of Ns_FetchURL?&lt;br /&gt;
&lt;br /&gt;
''If you can build shared libraries on your target platform with OpenSSL, it probably wouldn't be too hard.  The trick would be writing enough stub code that can be loaded via the Tcl &amp;quot;load&amp;quot; proc so that you could access the OpenSSL-based https client from your Tcl code.  Is there a lot of demand for this?  I could probably bang something out as an initial attempt.'' -- [[Dossy]]&lt;br /&gt;
&lt;br /&gt;
[[Scott Goodwin]]'s [[nsopenssl]] now contains client side https functionality.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Am I a brick, or does ns_register_proc just plain not work with more than one argument for the proc?  I have tried the following code on both aolserver 3.2 running on NT4 and aolserver 3.4 on NetBSD 1.5.  It fails to register the proc even once, if I try to register it with more than one argument anywhere else.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 ns_register_proc GET /foo1 foo 1&lt;br /&gt;
 ns_register_proc GET /foo2 foo 1 2&lt;br /&gt;
 ns_register_proc GET /foo3 foo 1 2 3&lt;br /&gt;
&lt;br /&gt;
 proc foo { conn one {two 22} {three 333}} {&lt;br /&gt;
 ns_return 200 text/html &amp;quot;one is $one, two is $two, three is $three&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This must be something simple.  I have already posted to the aolserver list but the listserv seems to have gone mad.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
''What are you trying to do?  It appears you want to pass constant parameters to your procedures.  If they are constants, why pass them?  Since ns_register_proc calls are generally in the global scope (and sourced when nsd starts) even a parameter that appears to be a variable probably can/will not vary.''&lt;br /&gt;
&lt;br /&gt;
''Presumably you need to get information from one page to another.  That means formvalues unless your page is stateful (usually a bad idea).  Check out the '''[[ns_conn]] form''' command to get yourself started.''  -- [[Jason Kane]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
OK, I'm using Windows 2000 SP2 and 3.4.1, and trying in vain to get Perl CGIs (legacy) to work.  The scripts work outside of Aolserver, and work on AOLserver on Linux, but when I try inside the script to GET from myself (eg, GET http://localhost:8000/foo?bar=bas), I'm told &amp;quot;unknown protocol TCP&amp;quot;, which is quite aggravating.&lt;br /&gt;
&lt;br /&gt;
Does anyone have any experience administering AOLServer on Windows?&lt;br /&gt;
&lt;br /&gt;
Thanks in advance!&lt;br /&gt;
&lt;br /&gt;
-Bill&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
This is interesting, wy do you let me change your page?&lt;br /&gt;
I'm trying to find an example of how to get my data using:&lt;br /&gt;
 set formdata [ns_conn form $conn]&lt;br /&gt;
&lt;br /&gt;
-Jason&lt;br /&gt;
&lt;br /&gt;
Because it's a wiki!  A proc that gets posted variables includes the line you wrote there... then when you want to actually get the values, you can use something like &lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_set get $formdata myvar]&lt;br /&gt;
&lt;br /&gt;
where myvar is the name of the variable.  There is also ns_queryget which looks like&lt;br /&gt;
&lt;br /&gt;
 set myvar [ns_queryget myvar defaultval]&lt;br /&gt;
&lt;br /&gt;
This is handy because if there is no value, it will assign a default value.  &lt;br /&gt;
&lt;br /&gt;
Check out aolserver.com, they have extensive (although sometimes misleading) docs.  If something the docs says should work doesn't, ask.  It may be out of date.&lt;br /&gt;
&lt;br /&gt;
[[Ian Harding]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I don't know where else to share my code fragments, so here seems like as good a place as any.  This one implements user public_html directories. It's based on someone else's stuff (I forget whose tho).  It should really do something with unknown mime types, and should do a better job with errors like unknown users.  It does honor directoryFile and adp maps in the config file.&lt;br /&gt;
&lt;br /&gt;
It works by registering a procedure to /users that interprets the username and finds their directory.  ns_register_proc doesn't allow wildcards other than in the last path element, so /~*  wouldn't work.  However that's not a problem for a filter, so there's a filter to take your /~user url and redirect it to /users/user&lt;br /&gt;
&lt;br /&gt;
-JR&lt;br /&gt;
&lt;br /&gt;
 proc homedir { conn ctx } {&lt;br /&gt;
   set url [ns_conn url $conn]&lt;br /&gt;
   set user {}&lt;br /&gt;
   set file {}&lt;br /&gt;
   regexp {^/users/([^/]*)(/.*)?$} $url dummy user file&lt;br /&gt;
   # ns_returnnotice 200 &amp;quot;url is $url user is $user, file is $file&amp;quot;&lt;br /&gt;
   set userfile [getUserFile $user $file]&lt;br /&gt;
   set type [ns_guesstype $userfile]&lt;br /&gt;
   if {[string match &amp;quot;*[ns_config ns/server/[ns_info server]]/adp map]&amp;quot; $userfile]} {&lt;br /&gt;
     # ns_log notice &amp;quot;adp parsing $userfile&amp;quot;&lt;br /&gt;
     set cwd [pwd]&lt;br /&gt;
     cd [file dirname $userfile]&lt;br /&gt;
     # ns_return 200 text/html [ns_adp_parse -file $userfile]&lt;br /&gt;
     set result [catch {ns_adp_parse -file $userfile} error]&lt;br /&gt;
     if {$result} {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     } else {&lt;br /&gt;
       ns_return 200 text/html $error&lt;br /&gt;
     }&lt;br /&gt;
     cd $cwd&lt;br /&gt;
   } else {&lt;br /&gt;
     switch $type {&lt;br /&gt;
       &amp;quot;*/*&amp;quot; {&lt;br /&gt;
       }&lt;br /&gt;
       default {&lt;br /&gt;
        ns_returnfile 200 $type $userfile&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
       &lt;br /&gt;
   if {[catch {set fp [open $userfile]}]} {&lt;br /&gt;
     ns_returnnotfound&lt;br /&gt;
     return&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 proc getUserFile {user path} {&lt;br /&gt;
   foreach tail [split ,[ns_config ns/server/[ns_info server] directoryfile] ,] {&lt;br /&gt;
     set userfile &amp;quot;[glob ~$user]/public_html$path$tail&amp;quot;&lt;br /&gt;
     if {[file exists $userfile] &amp;amp;&amp;amp; ![file isdirectory $userfile]} {&lt;br /&gt;
       return $userfile&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
   ns_returnnotfound&lt;br /&gt;
   # break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_proc GET /users/ homedir&lt;br /&gt;
 ns_register_proc POST /users/ homedir&lt;br /&gt;
 ns_register_proc HEAD /users/ homedir&lt;br /&gt;
 &lt;br /&gt;
 proc userRedir {conn arg why} {&lt;br /&gt;
   set url [ns_conn url]&lt;br /&gt;
   regsub {^/~(.*)} $url {/users/\1} redir&lt;br /&gt;
   ns_log notice &amp;quot;url is $url, redir is $redir&amp;quot;&lt;br /&gt;
   ns_returnredirect $redir&lt;br /&gt;
   return filter_break&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ns_register_filter preauth GET /~* userRedir&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Hi!&lt;br /&gt;
&lt;br /&gt;
Does anybody know a graphing module for Aolserver/TCL, with e.g. bargraphs, linegraphs,... ?&lt;br /&gt;
&lt;br /&gt;
-[[wiwo]]&lt;br /&gt;
&lt;br /&gt;
''Yes: [[nsgds]], [[nschartdir]].''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Can I detect if the user pushes the Stop button in their browser in my TCL/ADP page?&lt;br /&gt;
&lt;br /&gt;
Yes, although it's a kludge. ns_write will return zero if it cannot write because the connection has been lost. However, ns_write is not stupid enough to try writing when you give it nothing to write, and so you must send something to the client. To prevent this being rendered use HTML comments, e.g.&lt;br /&gt;
&lt;br /&gt;
 if {[ns_write &amp;quot;&amp;lt;nowiki&amp;gt;&amp;lt;!-- STOP DETECTOR --&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;quot;] == 0} {&lt;br /&gt;
     # user hit the stop button, browser page was closed, or connection to client was lost.&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Ximon Eighteen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Generating random passwords ==&lt;br /&gt;
&lt;br /&gt;
The following method can be useful to generate random passwords and/or password salts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # desired length of random string&lt;br /&gt;
  set iStringLength 8&lt;br /&gt;
&lt;br /&gt;
 # characters allowed to appear in the string&lt;br /&gt;
  set sAllowableCharacters &amp;quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # get length one time&lt;br /&gt;
  set iAllowableCharacters [string length $sAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
 # begin random string as empty&lt;br /&gt;
  set sRandomString &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 # loop until desired length is achieved&lt;br /&gt;
  for {set ii 0} {$ii &amp;lt; $iStringLength} {incr ii} {&lt;br /&gt;
&lt;br /&gt;
   # get next random between 0 and length of allowed characters&lt;br /&gt;
    set iRandomInt [ns_rand $iAllowableCharacters]&lt;br /&gt;
&lt;br /&gt;
   # retrieve this random character&lt;br /&gt;
    set sRandomCharacter [string index $sAllowableCharacters $iRandomInt]&lt;br /&gt;
&lt;br /&gt;
   # append the character to our random string&lt;br /&gt;
    append sRandomString $sRandomCharacter&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  ns_adp_puts &amp;quot;sRandomString: $sRandomString&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Customizing error pages ==&lt;br /&gt;
&lt;br /&gt;
Edit your AOLServer's config file, and add the paths to the error pages as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Internal redirects&lt;br /&gt;
#&lt;br /&gt;
ns_section &amp;quot;ns/server/${servername}/redirects&amp;quot;&lt;br /&gt;
ns_param   404 &amp;quot;/notfound.html&amp;quot;      ;# Not Found error page&lt;br /&gt;
ns_param   500 &amp;quot;/servererror.html&amp;quot;   ;# Server Error page&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ns_dbquotevalue&amp;diff=5010</id>
		<title>Talk:Ns dbquotevalue</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ns_dbquotevalue&amp;diff=5010"/>
		<updated>2006-12-14T14:29:10Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== double single quotes in examples ==&lt;br /&gt;
&lt;br /&gt;
there are errors in the examples: the double single quote is being hijacked by the wiki and turning the text into italic instead of showing the double single quote.&lt;br /&gt;
&lt;br /&gt;
Fixed --[[User:Juanjose|juanjose]] 09:29, 14 December 2006 (EST)&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ns_dbquotevalue&amp;diff=5009</id>
		<title>Talk:Ns dbquotevalue</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ns_dbquotevalue&amp;diff=5009"/>
		<updated>2006-12-14T14:22:24Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== double single quotes in examples ==&lt;br /&gt;
&lt;br /&gt;
there are errors in the examples: the double single quote is being hijacked by the wiki and turning the text into italic instead of showing the double single quote.&lt;br /&gt;
&lt;br /&gt;
Fixed --[[User:Juanjose|juanjose]] 09:22, 14 December 2006 (EST)&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_dbquotevalue&amp;diff=5008</id>
		<title>Ns dbquotevalue</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_dbquotevalue&amp;diff=5008"/>
		<updated>2006-12-14T14:01:25Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Man page: http://aolserver.com/docs/tcl/ns_dbquotevalue.html&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''NAME'''&lt;br /&gt;
&lt;br /&gt;
: ns_dbquotevalue - Prepare a value string for inclusion in an SQL statement.&lt;br /&gt;
&lt;br /&gt;
'''SYNOPSIS'''&lt;br /&gt;
&lt;br /&gt;
: '''ns_dbquotevalue''' ''value ?type?''&lt;br /&gt;
&lt;br /&gt;
'''DESCRIPTION'''&lt;br /&gt;
&lt;br /&gt;
: This command prepares the string ''value'' for inclusion in an SQL statement.  If ''value'' is &amp;quot;&amp;quot;, ns_dbquotevalue will return the string &amp;quot;NULL&amp;quot;.  If ''value'' is not &amp;quot;&amp;quot;, the returned value depends on ''type''.  If ''type'' is one of: bigint, bit, decimal, double, float, int, integer, numeric, real, smallint, or tinyint, then ''value'' will be returned without modification.  When ''type'' is any other string, or if ''type'' is omitted, ''value'' will be surrounded by single quotes, and any single quotes that it contains will be escaped by translation into two single quotes.&lt;br /&gt;
&lt;br /&gt;
'''EXAMPLES'''&lt;br /&gt;
&lt;br /&gt;
    % ns_dbquotevalue &amp;quot;&amp;quot;&lt;br /&gt;
    NULL&lt;br /&gt;
&lt;br /&gt;
    % ns_dbquotevalue 45.3 float&lt;br /&gt;
    45.3&lt;br /&gt;
&lt;br /&gt;
    % ns_dbquotevalue &amp;quot;John's Car&amp;quot;&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;'John''s Car'&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    % set company &amp;quot;John's Cheese Factory&amp;quot;&lt;br /&gt;
    % ns_db dml $db &amp;quot;INSERT INTO companies (name) VALUES ([ns_dbquotevalue $company])&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''SEE ALSO'''&lt;br /&gt;
&lt;br /&gt;
: [[ns_dbquotename]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category Documentation]] - [[Category Core Tcl API]]&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Nspasswd&amp;diff=5007</id>
		<title>Nspasswd</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Nspasswd&amp;diff=5007"/>
		<updated>2006-12-14T13:04:53Z</updated>

		<summary type="html">&lt;p&gt;Juanjose: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''nspasswd does not exist nowadays.'''&lt;br /&gt;
&lt;br /&gt;
nsperm doesn't speak md5 hashed passwords, only unix crypt.  If you need to crypt a password, try this Perl script one-liner:&lt;br /&gt;
&lt;br /&gt;
$ perl -le 'print crypt(&amp;quot;password&amp;quot;, &amp;quot;..&amp;quot;);'&amp;lt;br/&amp;gt;&lt;br /&gt;
..UZoIyj/Hy/c&lt;br /&gt;
&lt;br /&gt;
Replace &amp;quot;password&amp;quot; with the password you want to encrypt (up to 8 characters -- anything more gets truncated silently anyway).  The output from the script (&amp;quot;..UZoIyj/Hy/c&amp;quot;) is the crypted password that you can cut and paste into your passwd file.&lt;/div&gt;</summary>
		<author><name>Juanjose</name></author>
		
	</entry>
</feed>