You are viewing a plain text version of this content. The canonical link for it is here.
Posted to site-cvs@tcl.apache.org by da...@apache.org on 2003/06/11 16:01:00 UTC
cvs commit: tcl-site/presentations/rivet index.rvt intro.rvt apache-introduction.rvt about-apache.rvt apache-platform.rvt tcl-intro.rvt tcl-scripting.rvt tcl-features.rvt tcl-c-features.rvt tcl-example-1.rvt tcl-example-2.rvt apache-1.3.rvt writing-modules.rvt apache-architecture.rvt module-struct.rvt init-handler.rvt child-init.rvt configuration.rvt configcode.rvt serverconfig.rvt dirconfig.rvt userconfig.rvt handlers.rvt simple-handler.rvt handler-problems.rvt namespace-pages.rvt tcl-namespaces.rvt global-data.rvt embed-tcl.rvt embed-tcl-solution.rvt normal-tcl-scripts.rvt channelstruct.rvt outputproc.rvt conclusion.rvt further-information.rvt
davidw 2003/06/11 07:01:00
Added: presentations/rivet index.rvt intro.rvt
apache-introduction.rvt about-apache.rvt
apache-platform.rvt tcl-intro.rvt tcl-scripting.rvt
tcl-features.rvt tcl-c-features.rvt
tcl-example-1.rvt tcl-example-2.rvt apache-1.3.rvt
writing-modules.rvt apache-architecture.rvt
module-struct.rvt init-handler.rvt child-init.rvt
configuration.rvt configcode.rvt serverconfig.rvt
dirconfig.rvt userconfig.rvt handlers.rvt
simple-handler.rvt handler-problems.rvt
namespace-pages.rvt tcl-namespaces.rvt
global-data.rvt embed-tcl.rvt
embed-tcl-solution.rvt normal-tcl-scripts.rvt
channelstruct.rvt outputproc.rvt conclusion.rvt
further-information.rvt
Log:
Committed Rivet presentation.
Revision Changes Path
1.1 tcl-site/presentations/rivet/index.rvt
Index: index.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Apache Tcl</title>
<link rel="stylesheet" href="style.css">
</head>
<body class="splash">
<? prevnext {<img src="logo.gif" alt="Apache Tcl"></img>} ?>
<h2 align="center" class="splash">David N. Welton</h2>
<p align="center">
<a href="mailto:davidw@apache.org">davidw@apache.org</a>
</p>
</body>
</html>
1.1 tcl-site/presentations/rivet/intro.rvt
Index: intro.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Introduction</h1>" ?>
Apache's web server and Tcl are both very flexible systems that
give the programmer tools to extend and modify them in
interesting, unique and powerful ways. We will talk about the
many possibilities offered by Apache and Tcl's C API's, briefly
introduce the Tcl programming language and its concept of acting
as a command language for lower-level components, and also discuss
some interesting aspects of integrating Apache and Tcl.
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/apache-introduction.rvt
Index: apache-introduction.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>The Apache Web Server</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>The Apache Web Server</h1>" ?>
<ul>
<li>The world's most popular web server!</li>
<li>According to <a href="http://www.netcraft.com">netcraft</a>,
Apache accounts for around 60% of the web server market, putting
it ahead of all other contenders combined.</li>
<li>
Apache is:
<ul>
<li>flexible - can be configured to perform a variety of
tasks in disparate environments.</li>
<li>fast - quite competetive with other systems.</li>
<li>correct - standards compliant, part of standards committees.</li>
<li>secure - well tested, well known code.</li>
</ul>
</li>
</ul>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/about-apache.rvt
Index: about-apache.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>About Apache</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>About Apache</h1>" ?>
<p>
The Apache web server was first created by a group of sysadmins
who were using the NCSA server and had created patches to enhance
and improve it. Thus, "A Patchy" web server.
</p>
<p>
The Apache Software Foundation now encompasses a large variety
of diverse projects in addition to Tcl: the web server, XML,
Java, Perl, PHP, APR, Python, and is a non-profit corporation
registered in the U.S., with members throughout the world.
</p>
<p>
The ASF consists of 60-some members, and hundreds of
"committers" - those who have the rights to make changes to
different projects' code.
</p>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/apache-platform.rvt
Index: apache-platform.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Apache as a Platform</h1>" ?>
<p>
One of the biggest reasons for the Apache web server's
popularity is that it is a "platform".
</p>
<p>
This means that it provides a comprehensive API that lets you,
as a programmer, create new applications on top of the basic
system.
</p>
<p>
Even though we won't be talking about it much, this is
especially true of Apache 2, which can even serve other internet
protocols.
</p>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/tcl-intro.rvt
Index: tcl-intro.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Tcl</h1>" ?>
<p>
Tcl stands for "Tool Command Language". It was created in the
late 80'ies, by John Ousterhout, then a professor at the
University of California at Berkeley, as a replacement for the
many small extension languages he was writing for his
applications. From the very beginning, Tcl was engineered to be
combined with other systems.
</p>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/tcl-scripting.rvt
Index: tcl-scripting.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Scripting with Tcl</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Scripting with Tcl</h1>" ?>
<p>Tcl was created as a language to embed, extend and interact
with other systems, either through its C API, or through other
means (sockets, files, pipes, etc...).
</p>
<p>
The idea is that you can take pieces of C code, and glue them
together with Tcl:
</p>
<p align="center">
<img src="tcl-connector.png" alt="Tcl connects C code segments">
</p>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/tcl-features.rvt
Index: tcl-features.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl Features Overview</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Tcl Features Overview</h1>" ?>
<ul>
<li>Easy, Flexible
<ul>
<li>Tcl is easy to learn, it has a very simple syntax. It's
also very flexible, allowing you to mold it to your needs.
</li>
</ul>
</li>
<li>Extensible, Embeddable
<ul>
<li>
You can extend Tcl in many ways, both in Tcl and in C, or
embed it directly in your applications.
</li>
</ul>
</li>
<li>Powerful, Lightweight
<ul>
<li>Tcl does many things, easily, and has a small core.</li>
</ul>
</li>
<li>Multiplatform, Free
<ul>
<li>Tcl runs on UNIX, Windows and Mac OS. Tcl is distributed under a BSD license.</li>
</ul>
</li>
<li>Tk toolkit
<ul>
<li>Seperate from Tcl, althought it was also developed by
Ousterhout, and very well integrated with Tcl.</li>
</ul>
</li>
</ul>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/tcl-c-features.rvt
Index: tcl-c-features.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl's C API Features</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Tcl's C API Features</h1>" ?>
Tcl is easy to extend in C, and extremely powerful - you get
access to lots of things:
<table style="font-size: 38%;">
<tbody>
<tr valign="top">
<td>
<ul>
<li>Variables
<ul>
<li>From C</li>
<li>To C</li>
<li>Tie Tcl variable to C variable</li>
<li>Trace variables</li>
</ul>
</li>
</ul>
<ul><li>Interpreters
<ul>
<li>Seperate interpreters</li>
<li>Slave interpreters/shared resources</li></ul>
</li></ul>
<ul><li>Threads
<ul>
<li>Create/Destroy</li>
<li>Associate data</li></ul>
</li></ul>
</td>
<td>
<ul><li>IO/Channels
<ul>
<li>Create new channel types</li>
<li>Stacked channels</li>
<li>Buffering</li>
<li>Asynchronous</li></ul>
</li>
</ul>
<ul><li>Event Loop
<ul>
<li>Associate events with actions</li>
<li>Idle events</li></ul>
</li></ul>
<ul><li>Operating System Interaction
<ul>
<li>Filesystem</li>
<li>Processes</li></ul>
</li></ul>
</td>
<td>
<ul><li>Timers
<ul>
<li>Schedule events</li></ul>
</li></ul>
<ul><li>Commands
<ul>
<li>Create commands</li></ul>
</li></ul>
<ul><li>Hash Tables
<ul>
<li>Create and use hash tables at the C level</li></ul>
</li></ul>
<ul>
<li>Internationalization
<ul>
<li>Translate to/from different character sets</li>
</ul>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</body>
</html>
1.1 tcl-site/presentations/rivet/tcl-example-1.rvt
Index: tcl-example-1.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl Example</title>
<link rel="stylesheet" href="style.css">
<style>
<!--
pre {
color: #ffffff;
background-color: #000000;
margin: 1em;
padding: 1em;
} /* default */
span.string {
color: #696969;
} /* font-lock-string-face */
span.function-name {
color: #87cefa;
} /* font-lock-function-name-face */
span.keyword {
color: #00ffff;
} /* font-lock-keyword-face */
-->
</style>
</head>
<body>
<? prevnext "<h1>Tcl Example</h1>" ?>
</head>
<body>
Here is a tiny (and incorrect) web server in Tcl:
<pre>
<span class="keyword">proc</span> <span class="function-name">Serve</span> {chan addr port} {
fconfigure $chan -translation {auto binary}
set line [gets $chan]
<span class="keyword">if</span> { [catch { set fl [open <span class="string">".[lindex $line 1]"</span> r] } err] } {
puts $chan <span class="string">"HTTP/1.0 404 Not Found\r\n"</span>
} <span class="keyword">else</span> {
puts $chan <span class="string">"HTTP/1.0 200 OK"</span>
puts $chan <span class="string">"Content-Type: text/html\r\n\r\n[read $fl]"</span>
}
close $chan
}
set sk [socket -server Serve 5151]
fconfigure $sk -buffering line
vwait forever
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/tcl-example-2.rvt
Index: tcl-example-2.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl Example #2</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Tcl Example #2</h1>" ?>
Something you can't do in Perl, Python or PHP is create new
command structures:
<pre>
<span class="keyword">proc</span> <span class="function-name">do</span> {body <span class="keyword">while</span> expression} {
<span class="keyword">uplevel</span> $body
<span class="keyword">while</span> { [uplevel expr $expression] } {
<span class="keyword">uplevel</span> $body
}
}
set i 0
do {
puts $i
incr i
} <span class="keyword">while</span> {$i < 0}</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/apache-1.3.rvt
Index: apache-1.3.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Apache 1.3</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Apache 1.3</h1>" ?>
Today, we'll be talking about Apache 1.3 for the following
reasons:
<ul>
<li>I know it best:-)</li>
<li>On Unix, it works just fine.</li>
<li>Threads are <b>complicated</b> and introduce many
hard-to-find problems.</li>
<li>Apache 1.3 is not going away any time soon.</li>
</ul>
There are some differences with 2.0, but most programmers will be
able to pick up on them without too much trouble.
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/writing-modules.rvt
Index: writing-modules.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Writing Apache Modules</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Writing Apache Modules</h1>" ?>
Ok, so you want to write an Apache module. Here are a few initial
considerations:
<ul>
<li>Don't do it - spend some time thinking about what you
<b>really</b> need, and then look for it!</li>
<li>Create it first as a shared object module, in order to
facilitate testing.</li>
<li>Examine some other modules to see how they do it - go ahead
and copy them. The Apache license is very permissive.</li>
</ul>
Now, let's begin...
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/apache-architecture.rvt
Index: apache-architecture.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Apache Architecture</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Apache Architecture</h1>" ?>
<p>Parent server launches children as load requires. Note that
Apache does <b>not</b> fork one child per request! Multiple
children run select loops to accept and deal with requests.
Apache 2.0 supports multiple architectures, including several that
use threads.
</p>
<p align="center"><img src="arch.png" alt="Apache Architecture"></p>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/module-struct.rvt
Index: module-struct.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>The 'module' struct</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>The 'module' struct</h1>" ?>
<pre>
<span class="type">module</span> MODULE_VAR_EXPORT <span class="variable-name">rivet_module</span> =
{
STANDARD_MODULE_STUFF,
Rivet_InitHandler, <span class="comment">/* initializer */</span>
Rivet_CreateDirConfig, <span class="comment">/* dir config creater */</span>
Rivet_MergeDirConfig, <span class="comment">/* dir merger default is override */</span>
Rivet_CreateConfig, <span class="comment">/* server config */</span>
Rivet_MergeConfig, <span class="comment">/* merge server config */</span>
rivet_cmds, <span class="comment">/* command table */</span>
rivet_handlers, <span class="comment">/* handlers */</span>
NULL, <span class="comment">/* filename translation */</span>
NULL, <span class="comment">/* check_user_id */</span>
NULL, <span class="comment">/* check auth */</span>
NULL, <span class="comment">/* check access */</span>
NULL, <span class="comment">/* type_checker */</span>
NULL, <span class="comment">/* fixups */</span>
NULL, <span class="comment">/* logger */</span>
NULL, <span class="comment">/* header parser */</span>
Rivet_ChildInit, <span class="comment">/* child_init */</span>
Rivet_ChildExit, <span class="comment">/* child_exit */</span>
NULL <span class="comment">/* post read-request */</span>
};
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/init-handler.rvt
Index: init-handler.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Global Init Handler</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Global Init Handler</h1>" ?>
This is executed in the 'parent' process, so its effects are truly
global. In Rivet, we only add a string to the Apache version:
<pre>
<span class="type">MODULE_VAR_EXPORT</span> <span class="type">void</span>
<span class="function-name">Rivet_InitHandler</span>(server_rec *s, pool *p)
{
#<span class="builtin">ifndef</span> <span class="variable-name">HIDE_RIVET_VERSION</span>
ap_add_version_component(<span class="string">"Rivet / "</span>RIVET_VERSION);
#<span class="builtin">else</span>
ap_add_version_component(<span class="string">"Rivet"</span>);
#<span class="builtin">endif</span> <span class="comment">/* !HIDE_RIVET_VERSION */</span>
}
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/child-init.rvt
Index: child-init.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Child Init</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Child Init</h1>" ?>
<p> This code is called for every child process forked off from the
parent. This is a good place to do things that are
process-specific.
</p>
<p>In Rivet, we:</p>
<ul>
<li>Initialize Tcl.
<ul>
<li>Create global Tcl interpreter.</li>
<li>Set up environment.</li>
<li>Create channels (more about this later).</li>
<li>Create Rivet-specific commands.</li>
<li>Run Tcl scripts specific to ChildInit stage.</li>
</ul>
</li>
</li>
<li>Create Tcl interpreters for each Virtual Host (10.0.0.1 ->
foo.com, bar.com, baz.com)</li>
</ul>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/configuration.rvt
Index: configuration.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Rivet Configuration Directives</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Rivet Configuration Directives</h1>" ?>
Rivet provides several Apache configuration directives, and, where
possible, allows the administrator and or user to configure
options both in Apache's configuration file (httpd.conf) or via
.htaccess files.
<table align="center">
<tbody>
<tr>
<td>
<img src="confs.png" alt="Apache Configuration Hierarchy">
</td>
<td>
<pre>
/mysite
/.htaccess
/subdir1
/subdir2
/.htaccess
</pre>
</td>
</tr>
</tbody>
</table>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/configcode.rvt
Index: configcode.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Directive access code</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Directive access code</h1>" ?>
The command_rec structure links Directive names with the C
functions that handle them:
<pre>
<span class="keyword">const</span> command_rec <span class="variable-name">rivet_cmds</span>[] =
{
{<span class="string">"RivetServerConf"</span>, Rivet_ServerConf, NULL, RSRC_CONF, TAKE2,
NULL},
{<span class="string">"RivetDirConf"</span>, Rivet_DirConf, NULL, ACCESS_CONF, TAKE2, NULL},
{<span class="string">"RivetUserConf"</span>, Rivet_UserConf, NULL,
ACCESS_CONF|OR_FILEINFO, TAKE2,
<span class="string">"RivetUserConf key value: sets RivetUserConf(key) = value"</span>},
{NULL}
};
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/serverconfig.rvt
Index: serverconfig.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ServerConfig</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>ServerConfig</h1>" ?>
These configuration options are serverwide, because they don't
really work on a per-directory basis. Examples of this in Rivet
include the option that tells Rivet how many scripts to cache in
memory. This affects the whole server, and so it can only be
configured via a ServerConfig directive.
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/dirconfig.rvt
Index: dirconfig.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Directory Configuration</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Directory Configuration</h1>" ?>
Directory configurations are options which can change from
directory to directory. For instance, one might want to put a
different header and footer on pages in different directories.
Rivet would allow you to load up different headers and footers
depending on which directory the script is in.
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/userconfig.rvt
Index: userconfig.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>User Configuration</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>User Configuration</h1>" ?>
If you have ever had an account on an ISP that allows you access to
your own web pages, you may have also been able to use .htaccess
files. This allows non-administrator users to configure Apache on
a per-directory basis.
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/handlers.rvt
Index: handlers.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Request Handlers</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Request Handlers</h1>" ?>
<p> Now that we have our server initialized, running, and configured,
we get to the interesting part: handling incoming requests for web
pages.
</p>
<p>
Rivet actually defines two handlers, one for plain old .tcl
files, and the other for "PHP style" .rvt files, which contain a
mixture of Tcl and HTML. These link an application type to a C
function to process that type of request:
</p>
<pre>
<span class="keyword">const</span> handler_rec <span class="variable-name">rivet_handlers</span>[] =
{
{<span class="string">"application/x-httpd-rivet"</span>, Rivet_SendContent},
{<span class="string">"application/x-rivet-tcl"</span>, Rivet_SendContent},
{NULL}
};
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/simple-handler.rvt
Index: simple-handler.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Simple Handler</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Simple Handler</h1>" ?>
To give you an idea of what a handler really does, let's make a really
simple one:
<pre>
<span class="keyword">static</span> <span class="type">int</span> <span class="function-name">Send_Page</span>(request_rec *r)
{
<span class="keyword">if</span> (r->method_number != M_GET && r->method_number != M_POST) {
<span class="keyword">return</span> DECLINED;
}
ap_rputs(<span class="string">"Hello, Braga!"</span>, r);
<span class="keyword">return</span> OK;
}
</pre>
And associate it with a type:
<pre>
<span class="keyword">const</span> handler_rec <span class="variable-name">hello_handlers</span>[] =
{
{<span class="string">"application/x-hello-world"</span>, Send_Page},
{NULL}
};
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/handler-problems.rvt
Index: handler-problems.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Handler Problems to Overcome</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Handler Problems to Overcome</h1>" ?>
In order to create a system that is fast and easy to use that
doesn't surprise the user, we had a few problems to solve:
<ol>
<li>Keep each page 'seperate' - if you set a variable in
foo.rvt, you don't want to see it again in bar.rvt.</li>
<li>Provide a way to share global data for those who need to
access it. Persistent database connections, or sockets, for
example.</li>
<li>
Provide clean integration of Tcl and HTML, in order to make
quick and dirty templating possible, and easy.
</li>
<li>
Let users use 'normal' Tcl scripts. One of the big advantages
Tcl has (over, say, PHP) is that it is a multi-purpose
language. It's not restricted to just the web. Rivet
attempts to make it possible to take ordinary Tcl code and run
it in Rivet without changes, which means there is more code
available to use.
</li>
<li>Keep the whole system fast!</li>
</ol>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/namespace-pages.rvt
Index: namespace-pages.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>namespaces for seperate pages</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>namespaces for seperate pages</h1>" ?>
<p>To keep pages seperate, we run them in different namespaces, in
order to make sure local variables are really local:</p>
<p>
</p>
This is ok, because 'greeting' disappears when the 'request' namespace
is cleaned up after each page:
<pre>
namespace <span class="keyword">eval</span> request {
set greeting <span class="string">"Hello, World"</span>
puts -nonewline $greeting
}
namespace delete request
</pre>
The following code will fail, even if called after the first page
above, because 'greeting' has gone away.
<pre>
namespace <span class="keyword">eval</span> request {
puts -nonewline $greeting
}
namespace delete request
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/tcl-namespaces.rvt
Index: tcl-namespaces.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl Namespaces</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Tcl Namespaces</h1>" ?>
Tcl namespaces follow a hierarchy, and in terms of syntax, use
'::' to seperate namespaces. Each namespace can have variables
that are local to it.
<pre>
namespace <span class="keyword">eval</span> foo {
set foovar 1
namespace <span class="keyword">eval</span> bar {
set barvar 1
}
}
puts $::foo::bar::barvar
puts $::foo::foovar
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/global-data.rvt
Index: global-data.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Global Data</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Global Data</h1>" ?>
In order to access global data, we again utilize Tcl's namespace
hierarchy:
<pre>
namespace <span class="keyword">eval</span> request {
set ::global_data [clock seconds]
}
namespace delete request
namespace <span class="keyword">eval</span> request {
puts <span class="string">"The last person to access this child process came at:"</span>
puts [clock format $::global_data]
}
namespace delete request</pre>
As we can see, the first request sets a variable in the global
namespace, where it won't be destroyed when the 'request'
namespace is deleted. This makes it accessible to other scripts.
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/embed-tcl.rvt
Index: embed-tcl.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Embedding Tcl in HTML</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Embedding Tcl in HTML</h1>" ?>
Rivet scripts look something like this:
<pre>
<span class="variable-name"><html></span>
<span class="variable-name"><body></span>
<span class="type"><h1></span><span class="function-name">Rivet Example</span><span class="type"></h1></span>
<span class="type"><?
puts "The time is now:"
puts [clock format [clock seconds]]
?></span>
<span class="variable-name"></body></span>
<span class="variable-name"></html></span>
</pre>
The challenge is to turn that into something that can be executed as
Tcl code. The solution is pretty obvious...
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/embed-tcl-solution.rvt
Index: embed-tcl-solution.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>HTML/Tcl to Tcl</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>HTML/Tcl to Tcl</h1>" ?>
... the blocks of HTML are transformed into "puts" statements.
<pre>
puts -nonewline <span class="string">"
<html>
<body>
<h1>Rivet Example</h1>"</span>
puts <span class="string">"The time is now:"</span>
puts [clock format [clock seconds]]
puts -nonewline <span class="string">"
</body>
</html>"</span>
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/normal-tcl-scripts.rvt
Index: normal-tcl-scripts.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Off-the-shelf Tcl</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Off-the-shelf Tcl</h1>" ?>
<p>
One of the first things we faced when trying to make normal Tcl
scripts work under Apache was the output problem: Tcl scripts
usually send output via the "puts" command, and we didn't want
to make programmers use a special command that only works in
Rivet.
</p>
<p>
The answer: we create a special "channel" driver that integrates
Apache's I/O system with Tcl's.
</p>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/channelstruct.rvt
Index: channelstruct.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl Channel Struct</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Tcl Channel Struct</h1>" ?>
<pre>
<span class="type">Tcl_ChannelType</span> <span class="variable-name">RivetChan</span> = {
<span class="string">"apache_channel"</span>,
NULL,
closeproc,
inputproc,
outputproc,
NULL,
setoptionproc,
NULL,
watchproc,
gethandleproc,
NULL,
NULL
};
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/outputproc.rvt
Index: outputproc.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Tcl Channel Output</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Tcl Channel Output</h1>" ?>
<pre>
<span class="keyword">static</span> <span class="type">int</span>
<span class="function-name">outputproc</span>(ClientData instancedata, CONST84 <span class="type">char</span> *<span class="variable-name">buf</span>, <span class="type">int</span>
<span class="variable-name">toWrite</span>, <span class="type">int</span> *<span class="variable-name">errorCodePtr</span>)
{
rivet_server_conf *rsc = (rivet_server_conf *)instancedata;
rivet_interp_globals *globals =
Tcl_GetAssocData(rsc->server_interp, <span class="string">"rivet"</span>, NULL);
TclWeb_PrintHeaders(globals->req);
<span class="keyword">if</span> (globals->req->content_sent == 0)
{
ap_rwrite(buf, toWrite, globals->r);
ap_rflush(globals->r);
}
<span class="keyword">return</span> toWrite;
}
</pre>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/conclusion.rvt
Index: conclusion.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Conclusion</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>Conclusion</h1>" ?>
<p>Unfortunately, within a limited time, it's impossible to cover
all the intricacies and possibilities that Apache and Tcl offer,
but I hope to have shown that using these two systems lets you do
some very powerful things. </p>
<p>It may not seem like it in just an hour, but Rivet is
simple. It is less than 5000 lines of code, and yet it provides
most of what PHP does, with easily 1/10th the code. It does this
by carefully reutilizing everything it can from Apache and
Tcl.</p>
<p>
I hope that by showing you some of what is possible, you will be
able to further explore, and hopefully create something new and
interesting!
</p>
<?footer?>
</body>
</html>
1.1 tcl-site/presentations/rivet/further-information.rvt
Index: further-information.rvt
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>For More Information</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<? prevnext "<h1>For More Information</h1>" ?>
For more information:
<table align="center" width="%90">
<tr><td>Apache Tcl project</td><td><a
href="http://tcl.apache.org/">http://tcl.apache.org/</a>
</td></tr>
<tr><td>This Presentation</td><td><a
href="http://tcl.apache.org/presentations/rivet/">http://tcl.apache.org/presentations/rivet/</a>
</td></tr>
<tr><td>Apache web server</td><td><a
href="http://httpd.apache.org/">http://httpd.apache.org/</a>
</td></tr>
<tr><td>Tcl</td><td><a href="http://www.tcl.tk/">http://www.tcl.tk/</a>
</td></tr>
<tr><td>David N. Welton</td><td>davidw@apache.org</td></tr>
</table>
<?footer?>
</body>
</html>
---------------------------------------------------------------------
To unsubscribe, e-mail: site-cvs-unsubscribe@tcl.apache.org
For additional commands, e-mail: site-cvs-help@tcl.apache.org