This Appendix describes the changes to an NFS implementation that are needed to support the WebNFS extensions. It also describes NFS URLs, which can be used by WebNFS clients, including web browsers, to specify files on WebNFS servers.
Version 3 of the NFS protocol is particularly well matched to the use of TCP as a transport protocol. Version 3 removes the arbitrary 8k transfer size limit of version 2, allowing the READ or WRITE of very large streams of data over a TCP connection. Note that version 2 is also supported on TCP connections, though the benefits of TCP data streaming will not be as great.
A WebNFS client must first attempt to connect to its server with a TCP connection. If the server refuses the connection, the client should attempt to use UDP.
NFS servers are constrained by a requirement to re-register at the same port after a server crash and recovery so that clients can recover simply by retransmitting an RPC request until a response is received. This is simpler than the alternative of having the client repeatedly check with the portmap service for a new port assignment. NFS servers typically achieve this port invariance by registering a constant port assignment, 2049, for both UDP and TCP.
To avoid the overhead of contacting the server's portmap service, and to facilitate transit through packet filtering firewalls, WebNFS clients optimistically assume that NFS servers register on port 2049. Most NFS servers use this port assignment already, so this client optimism is well justified.
WebNFS clients are not required to use reserved ports. This means that a WebNFS server must not check the originating port for requests to filesystems which are made available to WebNFS clients.
The public filehandle is an an exception. It is an NFS filehandle with a reserved value and special semantics. A WebNFS client uses the public filehandle as an initial filehandle rather than using the MOUNT protocol. Since versions 2 and 3 of the NFS protocol have different filehandle formats, the public filehandle is defined differently for each.
A LOOKUP request that uses the public filehandle can provide a pathname containing multiple components. The server is expected to evaluate the entire pathname and return a filehandle for the final component.
For example, rather than evaluate the path "a/b/c" as:
Relative to the public filehandle, these 3 LOOKUP
requests can be replaced by a single multi-component lookup:
Multi-component lookup is supported only for LOOKUP requests relative to the public filehandle.
of the NFS URL (see
If the url-path is empty, the client must send a multi-component lookup for the pathname "." (dot).
If the first character of the path is a slash, then the canonical path is evaluated relative to the server's root directory. If the first character is not a slash, then the path is evaluated relative to the directory with which the public filehandle is associated.
Not all WebNFS servers can support arbitrary use of absolute paths. Clearly, the server cannot return a filehandle if the path identifies a file or directory that is not exported by the server. In addition, servers need not return a filehandle if the path names a file or directory in an exported filesystem different from the one that is associated with the public filehandle.
If the first character of the path is 0x80 (non-ASCII), then
the following character is the first in a native path.
A native path conforms to the normal pathname syntax of the
server. For example:
LOOKUP FH=0x0 "/a/b/c"
Lookup for Native Path:
LOOKUP FH=0x0 0x80 "a:b:c"
LOOKUP FH=0x0 "/a/b/c"
Lookup for Native Path:
LOOKUP FH=0x0 0x80 "a:b:c"
The :<port> part is optional. If omitted then port 2049 is assumed. The <url-path> is also optional. If it is omitted, then the "/" between <host>:<port> and <url-path> may also be omitted.
The <url-path> is a hierarchical directory path of the form
The <url-path> must consist only of characters within the US-ASCII character set. Within a <directory> or <name> component, the character "/" is reserved and must be encoded as described in Section 2.2 of RFC 1738. If <url-path> is omitted, it must default to the path "." (dot).
When presented with an NFS URL, a client must use the WebNFS technique described in this document to bind to the server, and evaluate the pathname using the public filehandle and multi-component lookup.
Note that the "/" in an NFS URL that delimits the <host>:<port>
from the <url-path> is not considered part of the pathname. For
example, if the public filehandle is associated with the server's
directory "/a/b/c" then the URL:
will be evaluated with a relative multi-component lookup of the
path "d/e/f" relative to the server's directory "/a/b/c", while
will locate the same file with an absolute multi-component lookup of the path "/a/b/c/d/e/f" relative to the server's filesystem root. Notice that a double slash is required at the beginning of the path; the first slash is the URL delimiter between the <host>:<port> and the <url-path>, and the second slash is the first character of <url-path>.
Not all WebNFS servers can support arbitrary use of absolute paths. Clearly, the server must not return a filehandle if the path identifies a file or directory that is not exported by the server. In addition, servers need not return a filehandle if the path names a file or directory in an exported filesystem different from the one that is associated with the public filehandle.
This path should then be combined with the URL which referenced the symbolic link according to the rules described in RFC 1808. If the relative URL in the symbolic link text is to be resolved successfully then it must contain only ASCII characters and conform to the syntax described in RFC 1808. Note that this allows a symbolic link to contain an entire URL and it may specify a scheme that is not necessarily an NFS URL (for example, HTTP).
An exception to RFC 1808 rules applies in the case of an absolute symbolic link, where the path begins with a "/". RFC 1808 describes a method for resolving relative URLs with respect to the base URL. Given a base URL of "nfs://s/a/b/c" which references a symbolic link with contents "/a/b/c/d", the method would yield a URL "nfs://s/a/b/c/" which would be correct only if the public filehandle were co-located with the server's filesystem root.
If the symbolic link begins with a slash, then after resolving a relative URL derived from the symbolic link contents according to the method in RFC 1808, the client must insert an additional slash in front of the path so that the server will evaluate the path relative to the server's root, rather than the public filehandle directory. This variation from the normal method of resolving a relative URL applies only to handling of symbolic links. The additional slash must not be inserted if the relative URL was embedded in a document or other encapsulating entity.
For example, if the symbolic link is named by the URL:
then the the following examples show how a new URL can be
formed from the symbolic link text:
Clearly, if the destination of the path is not in an exported filesystem, then the server must return an error to the client.
Many NFS server implementations rely on the MOUNT protocol for checking access to exported filesystems, and their NFS server does no access checking. The NFS server assumes that the filehandle does double duty: identifying a file as well as being a security token. Since WebNFS clients do not normally use the MOUNT protocol, a server that relies on MOUNT checking cannot automatically grant access to another exported filesystem at the destination of a spanning path. These servers must return an error.
For example: suppose the server exports two filesystems. One is
associated with the public filehandle:
The server receives a LOOKUP request with the public
filehandle that identifies a file or directory in the
other exported filesystem:
Even though the pathname destination is in an exported filesystem, the server cannot return a filehandle without an assurance that the client's use of this filehandle will be authorized.
Servers that check client access to an export on every NFS request have more flexibility. These servers can return filehandles for paths that span exports since the client's use of the filehandle for the destination filesystem will be checked by the NFS server.
On servers that support spanning paths, the public filehandle need not necessarily be attached to an exported directory, though a successful LOOKUP relative to the public filehandle must identify a file or directory that is exported.
For instance, if an NFS server exports a directory "/export/foo" and the public filehandle is attached to the server's root directory, then a LOOKUP of "export/foo" relative to the public filehandle will return a valid file handle but a LOOKUP of "export" will return an access error since the server's "/export" directory is not exported.
The client should start with the assumption that the server supports:
If these assumptions are not met, the client should fall back gracefully with a minimum number of messages. The following steps are recommended:
If the connection fails then assume that a request sent over UDP will work. Use UDP port 2049.
Do not use the PORTMAP protocol to determine the server's port unless the server does not respond to port 2049 for both TCP and UDP.
If the server returns an RPC PROG_MISMATCH error then assume that version 3 is not supported. Retry the LOOKUP with a version 2 public filehandle.
If the server returns an NFS3ERR_STALE, NFS3ERR_INVAL, or NFS3ERR_BADHANDLE error, then assume that the server does not support the WebNFS extensions because it does not recognize the public filehandle. The client must use the server's portmap service to locate and use the MOUNT protocol to obtain an initial filehandle for the requested path.
WebNFS clients can benefit by caching information about the server:
If the server does not support public filehandles, the client may choose to cache the port assignment of the MOUNT service as well as previously used pathnames and their filehandles.
If the server returns an NFS3ERR_STALE, NFS3ERR_INVAL, or NFS3ERR_BADHANDLE error in response to the client's use of a public filehandle, then the client should attempt to resolve the <url-path> to a filehandle using the MOUNT protocol.
Note that the pathname sent to the server in the MOUNTPROC_MNT request is assumed to be a server native path, rather than a slash-separated path described by RFC 1738. Hence, the MOUNT protocol can reasonably be expected to map a <url-path> to a filehandle only on servers that support slash-separated ASCII native paths. In general, servers that do not support WebNFS access or slash-separated ASCII native paths should not advertise NFS URLs.
At this point the client must already have some indication as to which version of the NFS protocol is supported on the server. Since the filehandle format differs between NFS versions 2 and 3, the client must select the appropriate version of the MOUNT protocol. MOUNT versions 1 and 2 return only NFS version 2 filehandles, whereas MOUNT version 3 returns NFS version 3 filehandles.
Unlike the NFS service, the MOUNT service is not registered on a well-known port. The client must use the PORTMAP service to locate the server's MOUNT port before it can transmit a MOUNTPROC_MNT request to retrieve the filehandle corresponding to the requested path. This is described in the following diagram:
NFS servers commonly use a client's successful MOUNTPROC_MNT request as an indication that the client has mounted the filesystem and may maintain this information in a file that lists the filesystems that clients currently have mounted. This information is removed from the file when the client transmits a MOUNTPROC_UMNT request. Upon receiving a successful reply to a MOUNTPROC_MNT request, a WebNFS client should send a MOUNTPROC_UMNT request to prevent an accumulation of mounted records on the server.