Pathnames and URIs
The Common Lisp standard provides logical-pathnames as a portable representation and these are supported and recommended for use in portable Common Lisp code. The Scieneer Common Lisp also supports the Uniform Resource Identifier (URI) standard, see RFC2396, as the default pathname namestring representation.
For the support of URIs, the Scieneer Common Lisp extends the pathname object to include the: scheme; scheme-specific-part for opaque URIs; port; username; password; parameters; query; and fragment. The pathname host is either a logical host name or a URI authority host name. The Common Lisp pathname device is not implemented. Accessors for the new information have been added, and function arguments expanded. The new function ext:resolve-pathname has been added to resolve a pathname against a base pathname. Logical-pathnames map to URIs with a file scheme and host equal to the logical pathname host.
When parsing a namestring the logical host name or scheme prefix is used to determine the class of the resulting pathname and to dispatch to the appropriate parsing methods. Separate namespaces are used for logical host names and scheme names. When a name clash occurs there is potential ambiguity when parsing a namestring so it is recommended that logical hosts not use a common scheme name. However it is typically possible to differentiate a scheme name from a logical host name by examining the remainder of the namestring and the implementation makes a best guess to support applications that use logical host names such as http.
The URI path is parsed into a directory, name, type, and version. Directory segments equal to "**" are parsed as :wild-inferiors and "*" is parse as :wild. The file name, type, and version may be wild but the syntax of [*.*.~*~] contrasts with the logical pathname syntax of [*.*.*] so take care to use the appropriate syntax.
When generating a URI namestring the URI port is typically not shown if it equals the default port for the scheme. Some scheme default ports are defined, and others may be defined using ext:scheme-default-port.
- The conventional case for the pathname, the default.
- For the Common Lisp common case.
- For URI lower, mixed, conventional case - extention.
For the extended functions ext:pathname-scheme, ext:pathname-port, ext:pathname-username, ext:pathname-password, ext:pathname-parameters, ext:pathname-query, and ext:pathname-fragment, the result is always in URI case conventions.
Pathname translation and search lists.
The Common Lisp logical pathname translation mechanism is generalized and extended. Translations may be defined for URIs, and each matching translation may have a list of potential paths to search. For example, this mechanism is used to define a search list for the UNIX environment PATH which may be accessed via #p"http://path/".
User defined pathnames
User defined pathname formats are supported by the definition of specialized pathname classes and methods. For parsing, a specialized method for ext:parse-namestring-initialize will need to be defined. For generating namestrings, specialize methods may be defined for the following generic functions: namestring, host-namestring, ext:authority-namestring, directory-namestring, file-namestring enough-namestring. Some of the CL functions need to map pathname case, and specialized methods may need to be defined for ext:pathname-customary-case, ext:pathname-mixed-case-p.
URIs with a scheme or authority component and a relative directory are inconsistent with the URI namestring syntax and so do not have a printable representation. This is in contrast to a logical pathname.
The Scieneer Common Lisp currently only supports operations on URIs with a file scheme and a "localhost" host name. The HTTP library adds support for http and https schemes pathnames. Support for other schemes may be added in future, such as the ftp, and nfs schemes.
Class precedence list:
pathname, standard-object, ext:instance, t.
Base class for pathnames. The pathname object is able to represent the components of a Uniform Resource Identifier.
Class precedence list:
Returns true if pathname is of class pathname, otherwise false.
|make-pathname &key scheme scheme-specific-part host device port username password directory name type version parameters query fragment defaults case class||[Function]|
Make a new pathname from the component arguments, and then merge in any unsupplied components from the defaults using the merging rules of merge-pathnames.
The class of the new pathname is either: the specified class, or logical-pathname if a defined logical pathname host is supplied or defaulted, or the result ext:scheme-pathname-class if a scheme is supplied or defaulted, otherwise the class is pathname.
The case argument specifies the case of the host, directory, name and type arguments. The other arguments are interpreted using URI case conventions of lower mixed case. The scheme and host arguments are always canonicalized to lower case. The case argument may be either:
- The arguments are interpreted using the local case conventions for the resulting pathname class. This is the default. The pathname class conventions may be specialized using the ext:pathname-customary-case and ext:pathname-mixed-case-p.
- The arguments are interpreted using the Common Lisp Common pathname case conventions. See the ANSI-CL manual for more information. The use of the :common case convention is recommended if portability with other Common Lisp implementations is important.
- The arguments are interpreted using URI case conventions of lower mixed case. The components are stored internally using URI conventions.
The arguments and their allowed values:
- The URI scheme. Either a string which is canonicalized to lower case, or the symbol nil, :unspecific or :wild.
- The URI scheme specific part for an opaque URI. Either an appropriately escaped string or the symbol nil, :unspecific or :wild.
- The URI authority host. Either an unescaped string which is canonicalized to lower case, or the symbol nil, :unspecific or :wild.
- The pathname device. The device component is not implemented. Only the values nil or :unspecific are accepted, and pathname-device will always return :unspecific.
- The URI authority port. Either an integer or the symbol nil, :unspecific or :wild.
- The URI authority username. Either an unescaped string, or the symbol nil, :unspecific or :wild.
- The URI authority password. Either an unescaped string, or the symbol nil, :unspecific or :wild. Note that the use of the password in a URI is not recommended in RFC2396 for security reasons.
- The URI path directory. A list of directories, a string, or the symbol nil, :unspecific, or :wild. A symbol :wild is canonicalized to the list '(:absolute :wild-inferiors), and a symbol :unspecific is canonicalized to the list '(:relative). A string is interpreted as a absolute directory and canonicalized to the list '(:absolute string).
- The URI path name. Either an unescaped string, or the symbol nil, :unspecific or :wild.
- The URI path type. Either an unescaped string, or the symbol nil, :unspecific or :wild.
- The URI path version. Either an unescaped string, or the symbol nil, :unspecific, :wild or :newest.
- The URI path parameters for the path segment associated with the name. Either an alist of unescaped parameter names and associated unescaped value(s), or the symbol nil, :unspecific or :wild.
- The URI query component. Either an alist of unescaped query names and an associated unescaped value(s), or the symbol nil, :unspecific or :wild.
- The URI fragment component. Either an unescaped string, or the symbol nil, :unspecific or :wild.
The first element of the directory list should be either :absolute or :relative, and the remaining elements are the directory segments. If a segment does not contain parameters then the associated element is an unescaped string. Otherwise, if a segment contains parameters then the segment element is a list of the unescaped segment name without the parameters and an alist of unescaped parameter names and associated unescaped values.
The URI path parameters are separated by #\; and each parameter name is separated from its values by #\=. If the name is not supplied then it is interpreted as an empty string. If there are no values then the associated value is nil. If there is a single value then the associated value is the unescaped string - even if empty. Multiple values are parsed and are placed in a list. For example, the pathname parameters alist for the URI "/file;;x;=1;y=;z=1;p=1==2" is:
(("") ("x" . nil) ("" . "1") ("y" . "") ("z" . "1") ("p" . ("1" "" "2"))
The URI query arguments are separated by #\& and each argument name is separated from its values by #\=. If the name is not supplied then it is interpreted as an empty string. If there are no values then the associated value is nil. If there is a single value then the associated value is the unescaped string - even if empty. Multiple values are parsed and are placed in a list. A query component with the value "" is represented by the query alist '(("")). For example, the pathname query alist for the URI query "?&x&=1&y=&z=1&p=1==2" is:
(("") ("x" . nil) ("" . "1") ("y" . "") ("z" . "1") ("p" . ("1" "" "2"))
Return the pathname class defined for the given pathname scheme, otherwise return nil. A pathname namestring may include a scheme or logical host prefix ending with a colon, and this prefix is used by parse-namestring to determine the pathname class before parsing the namestring. The common URI schemes are defined and return the class pathname: file, http, https, ftp, and telnet. The pathname class for other schemes may be defined using (setf scheme-pathname-class). Logical pathnames have a separate namespace.
Convert thing (a pathname, string or stream) into a pathname.
|ext:pathname-customary-case pathname||[Generic Function]|
Returns the customary case for the pathname object which will be either :upper or :lower case.
|ext:pathname-mixed-case-p pathname||[Generic Function]|
Returns true when the pathname object components use a mixed character mixed case convention.
|merge-pathnames pathname &optional defaults default-version||[Function]|
Construct a new pathname from pathname filled in unspecified components from the defaults and default-version. The created pathname will have the same class as the given pathname - irrespective of the pathname host. For the pathname directory, name and type components the customary case of the defaults is mapped to the customary case for the pathname.
|ext:resolve-pathname pathname &optional base||[Function]|
Resolve the relative pathname against the base pathname using the algorithm given in RFC2396. For the pathname directory, name and type components the customary case of the base is mapped to the customary case for the pathname. If the relative pathname has a relative directory then it is resolved against the base only if the scheme and authority component match. When a new relative pathname is created using the base then the class of the result is the same as the base pathname.
The default base pathname used by resolve-pathname. The value is initialize upon startup to file://localhost/<current-working-directory>/.
Accessor for the pathname's scheme.
Accessor for the pathname's scheme-specific-part.
|pathname-host pathname &key case||[Function]|
Accessor for the pathname's host.
|pathname-device pathname &key case||[Function]|
Accessor for pathname's device. Note that the pathname device component is not implemented and this function always returns :unspecific.
Accessor for the pathname's port.
Accessor for the pathname's username.
Accessor for the pathname's password.
|pathname-directory pathname &key case||[Function]|
Accessor for the pathname's directory list.
|pathname-name pathname &key case||[Function]|
Accessor for the pathname's name.
|pathname-type pathname &key case||[Function]|
Accessor for the pathname's name.
Accessor for the pathname's version.
Accessor for the pathname parameters of the file name segment.
Accessor for the pathname's query.
|ext:pathname-query-value pathname name||[Function]|
Find the value associated with the first pathname query to match the given name. Return the value and true upon success, otherwise nil and nil.
|ext:pathname-query-values pathname name||[Function]|
Return a list of the values associated with the pathname query matching the given name.
Accessor for the pathname's fragment.
|parse-namestring thing &optional host defaults &key start end junk-allowed class||[Function]|
Converts pathname thing, a pathname designator, into a pathname object, for a physical pathname, returns the printed representation.
The class of the pathname is either: the specified class, or logical-pathname if a defined logical pathname host is supplied or if a namestring has a logical host prefix, or the result of calling ext:scheme-pathname-class if a namestring has a defined scheme prefix, otherwise the class is pathname.
The default pathname namestring format is a Uniform Resource Identifier, see RFC2396. Logical pathnames are also recognised and their use is recommended for portable code.
The generic function ext:parse-namestring-initialize is called with the the new pathname object to parse the namestring and initialize the object. Parsers for user defined namestrings formats may be defined by specialized pathname classes and a specialised ext:parse-namestring-initialize method.
|ext:parse-namestring-initialize pathname namestring &optional start end||[Generic Function]|
Parse the namestring using the namestring format of the given pathname and filling in the pathname object slots. Implements parse-namestring. Specialized methods may be defined to parse user defined pathname class namestring formats.
When true wildcards are ignored when parsing URIs and pathnames.
|namestring pathname||[Generic Function]|
Construct the full namestring form of the pathname. The default format constructs a Universal Resource Identifier (URI).
|host-namestring pathname||[Generic Function]|
Returns a string representation of the name of the host in the pathname. The default method returns the host canonicalized to lower case as for use in a URI.
|ext:authority-namestring pathname||[Generic Function]|
Returns a string representation of the URI authority components in the pathname.
|directory-namestring pathname||[Generic Function]|
Returns a string representation of the directories used in the pathname. The default method returns the directory in escaped URI format.
|file-namestring pathname||[Generic Function]|
Returns a string representation of the name, type, and version components of the pathname. The default method returns the name in escaped URI format.
|enough-namestring pathname &optional defaults||[Generic Function]|
Returns an abbreviated pathname string sufficient to identify the pathname relative to the defaults. The default method returns a relative URI.
Return the default port for the given URI scheme, otherwise nil. When generating a URI string, the port number is not shown if it equals a defined default for the scheme.
|wild-pathname-p pathname &optional field-key||[Function]|
Predicate for determining whether pathname contains any wildcards.
|pathname-match-p in-pathname in-wildname||[Function]|
Pathname matches the wildname template?
|translate-pathname source from-wildname to-wildname &key||[Function]|
Use the source pathname to translate the from-wildname's wild and unspecified elements into a completed to-pathname based on the to-wildname.
|ext:enumerate-pathname-translations (var pathname &optional result) &body body||[Macro]|
Execute body with var bound to each successive possible translation for pathname and then return result. Note: if pathname does not have any translations, then body is executed exactly once. Everything is wrapped in a block named nil, so return can be used to terminate early. Note: var is not bound inside of result. The pathname is firstly resolved against the *default-pathname-base*.
Return the translation that matches the given pathname. A list of pathnames is returned representing pathnames to search for the given translation.
|(setf (ext:pathname-translation pathname) translation)||[Function]|
Set the translation list for the given pathname.
Converts the pathspec argument to a logical-pathname and returns it.
Return the pathname translations for all pathnames with a host matching host. If there are no translations then return nil.
|(setf (logical-pathname-translations host) translations)||[Function]|
Set the translations list for the logical host argument, returning the translations.
Search for a logical pathname named host, if not already defined. If already defined then no attempt to find or load a definition is attempted and nil is returned. If host is not already defined, but a definition is found and loaded successfully, t is returned, else error. The translations should be placed in a file with the name of the host and type "translations", and in the file://library/ path, and should contain the list of translations.
|translate-logical-pathname pathname &key||[Function]|
Translates pathname to a physical pathname or URI, which is returned. If the result is still a logical-pathname then signal an error.