rp_abstract_url_serverWhat it does:
Searches through the file system for an appropriate file to serve, based on $ad_conn(urlv). The algorithm is as follows:Defined in: /web/philip/packages/acs-core/abstract-url-procs.tclThis routine should really be part of the request processor.
- If the URL specifies a directory but doesn't have a trailing slash, append a slash to the URL and redirect (just like AOLserver would).
- If the URL specifies a directory and does have a trailing slash, append "index" to the URL (so we'll search for an index.* file in the filesystem).
- If the file corresponding to the requested URL exists (probably because the user provided the extension), just deliver the file.
- Find a file in the file system with the provided URL as the root (i.e., some file exists which is the URL plus some extension). Give precedence to extensions specified in the ExtensionPrecedence parameter in the abstract-url configuration section (in the order provided). If such a file exists, deliver it.
- The requested resource doesn't exist - return a 404 Not Found.
Source code:
global ad_conn set ad_conn(canonical_url) $ad_conn(url) set ad_conn(full_url) $ad_conn(url) # Determine the path corresponding to the user's request (i.e., prepend the document root) set path [rp_url2file $ad_conn(urlv)] if { [file isdirectory $path] } { # The path specified was a directory; return its index file. rp_debug "Looking for index in directory $path" if { [string index $ad_conn(url) end] != "/" } { # Directory name with no trailing slash. Redirect to the same URL but with # a trailing slash. set url "[ns_conn url]/" if { [ns_conn query] != "" } { append url "?[ns_conn query]" } ad_returnredirect $url return } else { # Directory name with trailing slash. Search for an index.* file. # Remember the name of the directory in $dir_index, so we can later # generate a directory listing if necessary. set dir_index $path set path "[string trimright $path /]/index" append ad_conn(canonical_url) "index" } } else { # If there's a trailing slash on the path, the URL must refer to a directory # (which we know doesn't exist, since [file isdirectory $path] returned 0). if { [string equal [string index $path end] "/"] } { ns_returnnotfound return } } if { ![file isfile $path] } { # The path provided doesn't correspond directly to a file - we need to glob. if { ![file isdirectory [file dirname $path]] } { # ns_returnnotfound source "[ns_info pageroot]/global/file-not-found.tcl" return } rp_debug "Searching for $path.*" set ad_conn(file) [ad_get_true_file_path $path] # Nothing at all found! 404 time. if { ![string compare $ad_conn(file) ""] } { if { [info exists dir_index] } { set listings [ns_config "ns/server/[ns_info server]" "directorylisting" "none"] if { [lsearch -exact { fancy simple } $listings] != -1 } { # Oh, wait: actually we were looking for a nonexistent index file, and # directory indexing is enabled. Create a directory listing. ns_returnnotice 200 "Directory listing of $dir_index" [rp_html_directory_listing $dir_index] return } } else { # ns_returnnotfound source "[ns_info pageroot]/global/file-not-found.tcl" return } } # Replace the last element of the full URL with the actual file name. if {[regexp {(.+)/$} $ad_conn(full_url) match dirname]} { set ad_conn(full_url) "[file join $dirname [file tail $ad_conn(file)]]" } else { set ad_conn(full_url) "[string trimright [file dirname $ad_conn(full_url)] /]/[file tail $ad_conn(file)]" } } else { # It's actually a file. Ensure that there are no trailing slashes (which # might cause handlers to be subverted) and deliver it directly. set ad_conn(file) $path } set ad_conn(canonical_url) [file rootname $ad_conn(full_url)] set extension [file extension $ad_conn(file)] if { [nsv_exists rp_extension_handlers $extension] } { set handler [nsv_get rp_extension_handlers $extension] rp_debug "Serving $ad_conn(file) with $handler" eval $handler } else { # Some other random kind of find - guess the type and return it. set type [ns_guesstype $ad_conn(file)] rp_debug "Serving $ad_conn(file) as $type" ns_returnfile 200 $type $ad_conn(file) }