| [ Team LiB ] |
|
Application Direct URLsThe Application Direct domain implementation provides the simplest way to extend the Web server. It hides the details associated with query data, decoding URL paths, and returning results. All you do is define Tcl procedures that correspond to URLs. Their arguments are automatically matched up to the query data, as shown in Example 13-3 on page 189. The Tcl procedures compute a string that is the result data, which is usually HTML. That's all there is to it. The name of the Tcl procedure that implements an Application Direct URL is related to the name of the URL. This way, TclHttpd can automatically look up the Tcl procedure that should implement a given URL. The Tcl procedure name and the URL have distinct prefixes, but the suffix is the same. For example, if the Tcl procedure prefix is Demo and the URL prefix is /demo, then the Demo/time Tcl procedure implements the /demo/time URL. The Direct_Url procedure sets up the correspondence between the procedures and URLs. This is shown in Example 18-3: Example 18-3 Application Direct URLs
Direct_Url /demo Demo
proc Demo {} {
return "<html><head><title>Demo page</title></head>\n\
<body><h1>Demo page</h1>\n\
<a href=/demo/time>What time is it?</a>\n\
<form action=/demo/echo>\n\
Data: <input type=text name=data>\n\
<br>\n\
<input type=submit name=echo value='Echo Data'>\n\
</form>\n\
</body></html>"
}
proc Demo/time {{format "%H:%M:%S"}} {
return [clock format [clock seconds] -format $format]
}
proc Demo/echo {args} {
# Compute a page that echoes the query data
set html "<head><title>Echo</title></head>\n"
append html "<body>"
append html [html::tableFromList $args "border=1"]
return $html
}
Example 18-3 defines /demo as an Application Direct URL domain that is implemented by procedures that begin with Demo. There are just three URLs defined: /demo /demo/time /demo/echo The /demo page displays a hypertext link to the /demo/time page and a simple form that will be handled by the /demo/echo page. This page is static, so there is just one return command in the procedure body. Each line of the string ends with: \n\ This is just a formatting trick to let me indent each line in the procedure, without having the line indented in the resulting string. Actually, the \-newline will be replaced by one space, so each line will be indented one space. You can leave those off and the page will display the same in the browser, but when you view the page source, you'll see the indenting. Or you could not indent the lines in the string, but then your code looks somewhat odd. The /demo/time procedure just returns the result of clock format. It doesn't even bother adding <html>, <head>, or <body> tags, which you can get away with in today's browsers. A simple result like this is also useful if you are using programs to fetch information via HTTP requests to your application. Using Query DataApplication Direct URL handlers have their parameters automatically assigned to values from the query data. Like any Tcl procedure, your Application Direct URL procedure can have named parameters, named parameters with default values, and the args parameter. The server matches the names of form values with names of your procedure parameters in order to assign their values. There are three cases:
You can see that missing arguments or extra arguments do not cause errors. If you want to do strict parameter checking, then just use args and check the name-value query list yourself. Here is another example to illustrate the different ways that form data is assigned to procedure parameters. Suppose you have an Application Direct procedure declared like this:
proc Demo/param { a b {c cdef} args} { body }
You could create an HTML form that had elements named a, b, and c, and specified /demo/param for the ACTION parameter of the FORM tag. Or you could type the following into your browser to embed the query data right into the URL: /demo/param?a=5&b=7&c=red&d=%7ewelch&e=two+words The ? separates the query data from the URL, and each query item is separated by &. In this case, when your procedure is called, a is 5, b is 7, c is red, and the args parameter becomes a list of:
d ~welch e {two words}
The %7e and the + are special codes for nonalphanumeric characters in the query data. The + becomes a space, and the %xx sequence is replaced by the character with character code xx (e.g., %7e becomes ~). Normally, this encoding is taken care of automatically by the Web browser when it gets data from a form and passes it to the Web server. However, if you type query data directly or format URLs with complex query data in them, then you need to encode special values as we did here. Use the Url_Encode procedure to encode URLs that you put into Web pages. The Web server automatically decodes the values as it makes the assignments to the Application Direct URL procedure parameters. If a parameter does not match the query data, it gets its default value from the procedure definition, or it gets the empty string. Consider this example: /demo/param?b=5 In this case, a is "", b is 5, c is cdef, and args is an empty list. Returning Other Content TypesThe default content type for Application Direct URLs is text/html. You can specify other content types by using a global variable with the same name as your procedure. (Yes, this is a crude way to craft an interface.) Example 18-4 shows part of the faces.tcl file that implements an interface to a database of picons — personal icons — that is organized by user and domain names. The idea is that the database contains images corresponding to your email correspondents. The Faces_ByEmail procedure, which is not shown, looks up an appropriate image file. The Application Direct procedure is Faces/byemail, and it sets the global variable Faces/byemail to the correct Content-Type value based on the filename extension. The mapping from extension to content type is implemented by the Mtype procedure (mtype.tcl). MIME is the multimedia content standard for email, and it originated the various content types now also used in HTTP, hence the term "MIME type." Example 18-4 Alternate types for Application Direct URLs
Direct_Url /faces Faces
proc Faces/byemail {email} {
global Faces/byemail
set filename [Faces_ByEmail $email]
set Faces/byemail [Mtype $filename]
set in [open $filename]
fconfigure $in -translation binary
set X [read $in]
close $in
return $X
}
|
| [ Team LiB ] |
|