$Header: /cvsroot/aolserver/aolserver.com/docs/devel/tcl/api/conn.html,v 1.1 2002/03/07 19:15:35 kriston Exp $
1. If the authuser is "nsadmin", the password is correct, and the IP address of the client is allowed nsadmin access, then access is authorized. 2. Find the relevant permission record. If an exact match for the method and URL combination is not found, the end of the URL is pared down until a match is found. For example, if there is no match for `/products/cereals/raisin_bran.html,' then the server looks for a permission record for the URL `/products/cereals.' If that permission record is specified as "Exact URL match is NOT required", then that permission record is used.By default, the server comes with a row that says GET on `/' is open to the world.
If no relevant permission record is found, access is denied (forbidden).
1. If the authuser is in the "Allow Users" list, access is permitted. If the authuser is a member of a group in the "Allow Groups" list and not in the "Deny Users' list, access is permitted. 2. If the host is in the "Hosts to allow" list, access is permitted. If the host is in the "Hosts to deny" list, access is denied. 3. If the request does not come in with authorization data, access is denied. 4. The user and password are verified. If there is no password specified in the database, any password is accepted. 5. Otherwise, access is denied.
OK
The user has permission to execute this URL and method.
DENIED
The user does not have permission to execute this URL and method.
FORBIDDEN
There is no possible user/password/IP Address combination that would
give authorization.
ERROR
There was an error.
If the permissions module is not loaded, an error is returned.
ns_conn authpassword ns_conn authuser ns_conn close ns_conn contentlength ns_conn driver ns_conn form ns_conn headers ns_conn host ns_conn isconnected ns_conn location ns_conn method |
ns_conn outputheaders ns_conn peeraddr ns_conn port ns_conn protocol ns_conn query ns_conn request ns_conn url ns_conn urlc ns_conn urlv ns_conn version |
ns_conn authuser returns the decoded user name from the authorization data.
ns_conn close closes the connection so the script (or ADP) can do any time-consuming processing without making the client wait. If you use ns_conn close in an ADP, streaming should be turned on before closing the connection (i.e. <SCRIPT RUNAT=SERVER STREAM=ON>) or nothing will get sent out at all.
ns_conn contentlength returns the number of bytes in the content passed in.
ns_conn driver returns the name of the module (nssock or nsssl) that is acting as the communications driver for this connection.
ns_conn form returns any submitted form data as an ns_set. This form data may have been submitted with a POST or appended to the URL in a GET request. Note: ns_conn form is not suitable for multipart formdata file upload widgets.
ns_conn headers returns all the header data as an ns_set. The keys of the ns_set represent the field names. The case of the returned field names depends on the HeaderCase configuration parameter. By default, HeaderCase is "Preserve", which means case is preserved.
ns_conn host returns the host part of the URL in the HTTP request.
ns_conn isconnected returns 1 if you're in a connection thread, and you are therefore allowed to make calls to ns_conn. It returns 0 if you're not in a connection thread (such as when you're in a schedule procedure) and you are not allowed to make calls to ns_conn.
ns_conn location returns the location string for this virtual server in the form: protocol://hostname[:port].
ns_conn method returns the HTTP method, e.g. GET.
ns_conn outputheaders returns an ns_set containing the headers that will be sent out when a result is returned to the client. This ns_set can be manipulated like any other ns_set. You can also use this command to write to the set of output headers. For example: ns_set put [ns_conn outputheaders] key value.
ns_conn peeraddr returns the IP address of the client, i.e. the "other side" of the HTTP connection. The IP address is returned in the form of a string separated with periods (e.g., 155.164.59.75).
ns_conn port returns the port specified explicitly in the URL of the HTTP request. If the browser does not explicity send the ":port" part of the URL, the port number returned will be 0.
ns_conn protocol returns the protocol of the URL in the HTTP request (usually unspecified).
ns_conn query returns any query data that was part of the HTTP request.
ns_conn request returns the HTTP request line as presented by the client, e.g. GET / HTTP/1.1.
ns_conn url returns the URL of the HTTP request. This is the portion of the request after the hostname, for example [ns_conn url] on http://aolserver.com/ returns /index.adp.
ns_conn urlc returns the number of elements (delimited by `/') in the URL of the HTTP request.
ns_conn urlv returns a list containing the pieces of the URL delimited by `/'.
ns_conn version returns the version of the HTTP request. This is usually 1.0 or 1.1.
The key argument is the key for the file widget.
The fileId argument must be the file ID of a file that is open for write operations. ns_get_multipart_formdata will write the submitted file (from the file widget) to the file specified by fileId.
If you pass a formdataSet into the function, the rest of the form data is dropped into that formdata set.
<form enctype=multipart/form-data method=post action=/foo> <input name=file type=file> </form>The POST action is handled by the /foo script defined below:
ns_register_proc POST /foo foo proc foo {conn ignore} { set fp [open "/tmp/uploaded_file" w+] ns_get_multipart_formdata "file" $fp close $fp ## Process file ## return something }
ns_register_proc GET /wais getwais proc getwais { conn context } { ns_return 200 text/html [ns_geturl http://www.wais.com/] }
Also, ns_geturl does not follow redirects or handle relative URLs. URLs that are server-relative (begin with "/") are translated into filenames, and the content of the file is returned.
set time [ns_httptime [ns_time]]
ns_httpopen returns a list with these three elements: a file descriptor for reading, a file descriptor for writing, and a set ID for a set describing the connection. The three elements of the set are date, server, and content type.
ns_register_proc POST /queryexiststest queryexiststest proc queryexiststest { } { if [ns_queryexists name] { # ...process the form... } else { ns_returnerror 400 "you need to supply your name in the form" } } ;# queryexiststest
If the optional value argument is specified, and the key does not exist in the query data, the specified value is simply returned. This capability allows for providing a default value if the key doesn't exist.
This function works for simple forms as well as for multipart formdata.
For files uploaded with the Netscape file upload widget, the file that was uploaded is an entry in the query data. See Example 3, below.
set x [ns_queryget name]If "name" is a key in the query data, the variable x will be set to the value associated with the "name" key. If "name" is not a key in the query data, "" will be returned.
Example 2:
set x [ns_queryget name Hoover]If "name" is a key in the query data, the variable x will be set to the value associated with the "name" key. If "name" is not a key in the query data, "Hoover" will be returned.
Example 3: Given this HTML form:
<form enctype=multipart/form-data method=POST action=/formtest> Local file: <input name=clientfile type=file> To remote file: <INPUT TYPE=text NAME=path VALUE="" SIZE=80> <input name=submit type=submit value=Upload> </form>and this POST handler:
proc formtest { } { set remotefile [ns_queryget path] set localfile [ns_queryget clientfile] set where_the_data_is [ns_queryget clientfile.tmpfile] } ;# formtest
Suppose the user specified "spoon.txt" as the Local File and
"/oop/ack/tick.txt" as the Remote File, and then submitted the form.
The variable values in the formtest procedure will be:
remotefile = "/oop/ack/tick.txt"
localfile = "spoon.txt"
_the_data = something like: "/var/tmp/baaa29444"
If you want to use the contents of the uploaded file, you can open it by executing:
open [ns_queryget clientfile.tmpfile]You can then read it and manipulate it as you want. Note, however, that this tmp file will be deleted once the connection closes.
1. If the authuser is "nsadmin", the password is correct, and the IP address of the client is allowed nsadmin access, then access is authorized. 2. Find the relevant permission record. If an exact match for the method and URL combination is not found, the end of the URL is pared down until a match is found. For example, if there is no match for `/products/cereals/raisin_bran.html,' then the server looks for a permission record for the URL `/products/cereals.' If that permission record is specified as "Exact URL match is NOT required", then that permission record is used.By default, the server comes with a row that says GET on `/' is open to the world.
If no relevant permission record is found, access is denied (forbidden).
1. If the authuser is in the "Allow Users" list, access is permitted. If the authuser is a member of a group in the "Allow Groups" list and not in the "Deny Users' list, access is permitted. 2. If the host is in the "Hosts to allow" list, access is permitted. If the host is in the "Hosts to deny" list, access is denied. 3. If the request does not come in with authorization data, access is denied. 4. The user and password are verified. If there is no password specified in the database, any password is accepted. 5. Otherwise, access is denied.
OK
The user has permission to execute this URL and method.
DENIED
The user does not have permission to execute this URL and method.
FORBIDDEN
There is no possible user/password/IP Address combination that would
give authorization.
ERROR
There was an error.
set headers [ns_set new myheaders] ns_set put $headers location http://www.aolserver.com ns_respond -status 302 -type text/plain \ -string "redirection" -headers $headers
type should be a MIME type (see ns_guesstype manual page for a list).
status is a three-digit number fitting the pattern below:
1xx Informational - Not used, but reserved for future use.Some common status values and their meanings are:
2xx Success - The action was successfully received, understood, and accepted.
3xx Redirection - Further action must be taken in order to complete the request.
4xx Client Error - The request contains bad syntax or cannot be fulfilled.
5xx Server Error - The server failed to fulfill an apparently valid request.
201 Created
202 Accepted
203 Provisional Information
204 No Content
300 Multiple Choices
301 Moved Permanently
302 Moved Temporarily
303 Method
304 Not Modified
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 None Acceptable
407 Proxy Authentication Required
408 Request Time-out
409 Conflict
410 Gone
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Time-out
ns_return sends back both the headers and the string.
ns_returnadminnotice performs the same function as ns_returnnotice, except that it appends a line with a link to "mailto:serveradministrator" based on the virtual server parameter "WebMaster".
ns_returnbadrequest returns a 400 status code and a formatted HTML message containing the reason text.
ns_returnerror wraps the text msg in some html and returns that to the client.
ns_returnfile sends back the headers and the contents of the file.
ns_returnforbidden returns a 403 status code.
ns_returnfp first sends the appropriate headers. Next, it writes out the contents of file from the current file position until the end of the file.
ns_returnnotfound returns a 404 status code.
ns_returnnotice wraps the text msg and longmsg in some html and returns that to the client.
ns_returnredirect returns a redirect to the passed in location.
ns_returnunauthorized returns a 401 status code.
ns_returnnotice 200 "Thank you" "Thank you for your input!" # Do more stuff... # Maybe get a cup of coffee... # It doesn't matter since the client has already left. return TCL_OK ;# not really needed but shown here for clarity.
#listen for connections on port 9000 set sock [ns_socklisten * 9000] #wait for new connection set fds [ns_sockaccept $sock] set rfd [lindex $fds 0] set wfd [lindex $fds 1] puts $wfd "Hello!" close $rfd close $wfd close $sock
r = the socket is readable
w = the socket is writeable
e = the socket has an exceptional condition
x = the server is shutting down
set sock [ns_socklisten * 9000] ns_sockcallback $sock newconn r # Keep $sock from closing after connection ends detach $sock # When a connection arrives, newconn will be called as: # newconn $sock r proc newconn {sock when} { set fds [ns_sockaccept $sock] set rfd [lindex $fds 0] set wfd [lindex $fds 1] puts $wfd "Hello!" close $rfd close $wfd }
The -nonblock option specifies that ns_sockopen will return immediately, while the connect is still in progress by the operating system. If you use -nonblock, you then can call ns_sockcheck with the write file id to see if the connect was actually completed.
The -timeout option specifies how long to wait for the connect to be made in seconds before timing out.
set fds [ns_sockopen www.aolserver.com 80] set rid [lindex $fds 0] set wid [lindex $fds 1] puts $wid "GET /index.htm HTTP/1.0\r\n\r" flush $wid while {[set line [string trim [gets $rid]]] != ""} { lappend headers $line } set page [read $rid] close $rid close $widA more advanced example containing ns_sockopen is provided under ns_sockselect.
The -timeout option specifies the length of time to wait in seconds for ns_sockselect to return before timing out.
The rfds, wfds, and efds arguments are lists of readable file id's, writeable file id's, and file id's with exceptions, respectively.
# Start nonblocking connect()'s to www01 through # www09.foo.com and remember the read fileid which # corresponds to each write fileid. for {set n 1} {$n < 10} {incr n} { set host [format "www%2d.foo.com" $n] set fds [ns_sockopen -nonblock $host 80] set r [lindex $fds 0] set w [lindex $fds 1] set w2r($w) $r lappend wfds $w } # All connect()'s are in progress, use select to wait for one or # more to become writable in the next two seconds which means # # they may have connected. We're not interested in readable or # exception sockets so the corresponding lists are empty # (i.e., {}). set sel [ns_sockselect -timeout 2 {} $wfds {}] # Select returned - get the sockets ready to write to. set wfds [lindex $sel 1] # Use ns_sockcheck to see if the sockets actually connected and # didn't become writable because the connect() failed (e.g., no # Web server was running on port 80 on the corresponding machine). # Note that the wfds list may be empty, meaning all sockets timed # out on connect. set ok "" foreach w $wfds { if [ns_sockcheck $w] { # Socket is connected - send a GET HTTP request. lappend ok $w puts $w "GET /index.htm HTTP/1.0\r\n\r" # The flush is important, otherwise the remote # server may never see the data. flush $w } } # Get the read ids for each socket which we sent the GET request to. foreach w $ok { lappend rfds $w2r($w) } # Use select again to wait for the read sockets to have data # available in response to the GET request. set sel [ns_sockselect -timeout 2 $rfds {} {}] set rfds [lindex $sel 0] # Read the pages which came back. foreach r $rfds { if [ns_sockcheck $r] { set page($r) [read $r] } } # Close all the sockets foreach w [array names w2r] { close $w close $w2r($w) }
<% ns_adp_include [ns_url2file /include/myfile.inc] %>