diff -rN -u old-tahoe/contrib/fuse/impl_c/blackmatch.py new-tahoe/contrib/fuse/impl_c/blackmatch.py --- old-tahoe/contrib/fuse/impl_c/blackmatch.py 2010-01-24 05:51:58.956000000 +0000 +++ new-tahoe/contrib/fuse/impl_c/blackmatch.py 2010-01-24 05:52:03.173000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python #----------------------------------------------------------------------------------------------- -from allmydata.uri import CHKFileURI, DirectoryURI, LiteralFileURI +from allmydata.uri import CHKFileURI, DirectoryURI, LiteralFileURI, is_literal_file_uri from allmydata.scripts.common_http import do_http as do_http_req from allmydata.util.hashutil import tagged_hash from allmydata.util.assertutil import precondition @@ -335,7 +335,7 @@ self.fname = self.tfs.cache.tmp_file(os.urandom(20)) if self.fnode is None: log('TFF: [%s] open() for write: no file node, creating new File %s' % (self.name, self.fname, )) - self.fnode = File(0, 'URI:LIT:') + self.fnode = File(0, LiteralFileURI.BASE_STRING) self.fnode.tmp_fname = self.fname # XXX kill this self.parent.add_child(self.name, self.fnode, {}) elif hasattr(self.fnode, 'tmp_fname'): @@ -362,7 +362,7 @@ self.fname = self.fnode.tmp_fname log('TFF: reopening(%s) for reading' % self.fname) else: - if uri.startswith("URI:LIT") or not self.tfs.async: + if is_literal_file_uri(uri) or not self.tfs.async: log('TFF: synchronously fetching file from cache for reading') self.fname = self.tfs.cache.get_file(uri) else: @@ -906,7 +906,7 @@ class TStat(fuse.Stat): # in fuse 0.2, these are set by fuse.Stat.__init__ - # in fuse 0.2-pre3 (hardy) they are not. badness unsues if they're missing + # in fuse 0.2-pre3 (hardy) they are not. badness ensues if they're missing st_mode = None st_ino = 0 st_dev = 0 @@ -1237,7 +1237,7 @@ def get_file(self, uri): self.log('get_file(%s)' % (uri,)) - if uri.startswith("URI:LIT"): + if is_literal_file_uri(uri): return self.get_literal(uri) else: return self.get_chk(uri, async=False) diff -rN -u old-tahoe/docs/frontends/webapi.txt new-tahoe/docs/frontends/webapi.txt --- old-tahoe/docs/frontends/webapi.txt 2010-01-24 05:51:59.214000000 +0000 +++ new-tahoe/docs/frontends/webapi.txt 2010-01-24 05:52:03.375000000 +0000 @@ -70,20 +70,20 @@ these tasks. In general, everything that can be done with a PUT or DELETE can also be done with a POST. -Tahoe's web API is designed for two different consumers. The first is a -program that needs to manipulate the virtual file system. Such programs are +Tahoe's web API is designed for two different kinds of consumer. The first is +a program that needs to manipulate the virtual file system. Such programs are expected to use the RESTful interface described above. The second is a human using a standard web browser to work with the filesystem. This user is given a series of HTML pages with links to download files, and forms that use POST actions to upload, rename, and delete files. When an error occurs, the HTTP response code will be set to an appropriate -400-series code (like 404 for an unknown childname, or 400 Gone when a file -is unrecoverable due to insufficient shares), and the HTTP response body will -usually contain a few lines of explanation as to the cause of the error and -possible responses. Unusual exceptions may result in a 500 Internal Server -Error as a catch-all, with a default response body will contain a -Nevow-generated HTML-ized representation of the Python exception stack trace +400-series code (like 404 Not Found for an unknown childname, or 400 Bad Request +when the parameters to a webapi operation are invalid), and the HTTP response +body will usually contain a few lines of explanation as to the cause of the +error and possible responses. Unusual exceptions may result in a +500 Internal Server Error as a catch-all, with a default response body containing +a Nevow-generated HTML-ized representation of the Python exception stack trace that caused the problem. CLI programs which want to copy the response body to stderr should provide an "Accept: text/plain" header to their requests to get a plain text stack trace instead. If the Accept header contains */*, or @@ -108,9 +108,9 @@ read- and write- caps, which start with "URI:SSK", and give access to mutable files. -(later versions of Tahoe will make these strings shorter, and will remove the +(Later versions of Tahoe will make these strings shorter, and will remove the unfortunate colons, which must be escaped when these caps are embedded in -URLs). +URLs.) To refer to any Tahoe object through the web API, you simply need to combine a prefix (which indicates the HTTP server to use) with the cap (which @@ -150,8 +150,12 @@ === Child Lookup === -Tahoe directories contain named children, just like directories in a regular -local filesystem. These children can be either files or subdirectories. +Tahoe directories contain named child entries, just like directories in a regular +local filesystem. These child entries, called "dirnodes", consist of a name, +metadata, a write slot, and a read slot. The write and read slots normally contain +a writecap and readcap referring to the same object, which can be either a file +or a subdirectory. The write slot may be empty (actually, both may be empty, +but that is unusual). If you have a Tahoe URL that refers to a directory, and want to reference a named child inside it, just append the child name to the URL. For example, if @@ -195,9 +199,9 @@ representable as such. All Tahoe operations that refer to existing files or directories must include -a suitable read- or write- cap in the URL: the wapi server won't add one +a suitable read- or write- cap in the URL: the webapi server won't add one for you. If you don't know the cap, you can't access the file. This allows -the security properties of Tahoe caps to be extended across the wapi +the security properties of Tahoe caps to be extended across the webapi interface. == Slow Operations, Progress, and Cancelling == @@ -271,7 +275,7 @@ since the operation completed) will remain valid for ten minutes. Many "slow" operations can begin to use unacceptable amounts of memory when -operation on large directory structures. The memory usage increases when the +operating on large directory structures. The memory usage increases when the ophandle is polled, as the results must be copied into a JSON string, sent over the wire, then parsed by a client. So, as an alternative, many "slow" operations have streaming equivalents. These equivalents do not use operation @@ -314,7 +318,7 @@ To use the /uri/$FILECAP form, $FILECAP be a write-cap for a mutable file. In the /uri/$DIRCAP/[SUBDIRS../]FILENAME form, if the target file is a - writable mutable file, that files contents will be overwritten in-place. If + writable mutable file, that file's contents will be overwritten in-place. If it is a read-cap for a mutable file, an error will occur. If it is an immutable file, the old file will be discarded, and a new one will be put in its place. @@ -333,7 +337,7 @@ PUT /uri This uploads a file, and produces a file-cap for the contents, but does not - attach the file into the virtual drive. No directories will be modified by + attach the file into the filesystem. No directories will be modified by this operation. The file-cap is returned as the body of the HTTP response. If "mutable=true" is in the query arguments, the operation will create a @@ -347,7 +351,7 @@ Create a new empty directory and return its write-cap as the HTTP response body. This does not make the newly created directory visible from the - virtual drive. The "PUT" operation is provided for backwards compatibility: + filesystem. The "PUT" operation is provided for backwards compatibility: new code should use POST. POST /uri?t=mkdir-with-children @@ -388,8 +392,29 @@ "linkcrtime": 1202777696.7564139, "linkmotime": 1202777696.7564139, } } } ] - } + } + For forward-compatibility, a mutable directory can also contain caps in + a format that is unknown to the webapi server. When such caps are retrieved + from a mutable directory in a "ro_uri" field, they will be prefixed with + the string "ro.", indicating that they must not be decoded without + checking that they are read-only. The "ro." prefix must not be stripped + off without performing this check. (Future versions of the webapi server + will perform it where necessary.) + + If both the "rw_uri" and "ro_uri" fields are present in a given PROPDICT, + and the webapi server recognizes the rw_uri as a write cap, then it will + reset the ro_uri to the corresponding read cap and discard the original + contents of ro_uri (in order to ensure that the two caps correspond to the + same object and that the ro_uri is in fact read-only). However this may not + happen for caps in a format unknown to the webapi server. Therefore, when + writing a directory the webapi client should ensure that the contents + of "rw_uri" and "ro_uri" for a given PROPDICT are a consistent + (write cap, read cap) pair if possible. If the webapi client only has + one cap and does not know whether it is a write cap or read cap, then + it is acceptable to set "rw_uri" to that cap and omit "ro_uri". The + client must not put a write cap into a "ro_uri" field. + Note that the webapi-using client application must not provide the "Content-Type: multipart/form-data" header that usually accompanies HTML form submissions, since the body is not formatted this way. Doing so will @@ -404,59 +429,95 @@ Like t=mkdir-with-children above, but the new directory will be deep-immutable. This means that the directory itself is immutable, and that - it can only contain deep-immutable objects, like immutable files, literal - files, and deep-immutable directories. A non-empty request body is - mandatory, since after the directory is created, it will not be possible to - add more children to it. + it can only contain objects that are treated as being deep-immutable, like + immutable files, literal files, and deep-immutable directories. + + For forward-compatibility, a deep-immutable directory can also contain caps + in a format that is unknown to the webapi server. When such caps are retrieved + from a deep-immutable directory in a "ro_uri" field, they will be prefixed + with the string "imm.", indicating that they must not be decoded without + checking that they are immutable. The "imm." prefix must not be stripped + off without performing this check. (Future versions of the webapi server + will perform it where necessary.) + + The cap for each child may be given either in the "rw_uri" or "ro_uri" + field of the PROPDICT (not both). If a cap is given in the "rw_uri" field, + then the webapi server will check that it is an immutable readcap of a + *known* format, and give an error if it is not. If a cap is given in the + "ro_uri" field, then the webapi server will still check whether known + caps are immutable, but for unknown caps it will simply assume that the + cap can be stored, as described above. Note that an attacker would be + able to store any cap in an immutable directory, so this check when + creating the directory is only to help non-malicious clients to avoid + accidentally giving away more authority than intended. + + A non-empty request body is mandatory, since after the directory is created, + it will not be possible to add more children to it. POST /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir PUT /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir Create new directories as necessary to make sure that the named target ($DIRCAP/SUBDIRS../SUBDIR) is a directory. This will create additional - intermediate directories as necessary. If the named target directory already - exists, this will make no changes to it. + intermediate mutable directories as necessary. If the named target directory + already exists, this will make no changes to it. If the final directory is created, it will be empty. - This will return an error if a blocking file is present at any of the parent - names, preventing the server from creating the necessary parent directory. + This operation will return an error if a blocking file is present at any of + the parent names, preventing the server from creating the necessary parent + directory, or if it would require changing an immutable directory. The write-cap of the new directory will be returned as the HTTP response body. POST /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir-with-children - Like above, but if the final directory is created, it will be populated with - initial children from the POST request body, as described above in the - /uri?t=mkdir-with-children operation. + Like /uri?t=mkdir-with-children, but the final directory is created as a + child of an existing mutable directory. This will create additional + intermediate mutable directories as necessary. If the final directory is + created, it will be populated with initial children from the POST request + body, as described above. POST /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir-immutable - Like above, but the final directory will be deep-immutable, with the - children specified as a JSON dictionary in the POST request body. + Like /uri?t=mkdir-immutable, but the final directory is created as a child + of an existing mutable directory. The final directory will be deep-immutable, + and will be populated with the children specified as a JSON dictionary in + the POST request body. + + In Tahoe 1.6 this operation creates intermediate mutable directories if + necessary, but that behaviour should not be relied on; see ticket #920. POST /uri/$DIRCAP/[SUBDIRS../]?t=mkdir&name=NAME - Create a new empty directory and attach it to the given existing directory. - This will create additional intermediate directories as necessary. + Create a new empty mutable directory and attach it to the given existing + directory. This will create additional intermediate directories as necessary. - The URL of this form points to the parent of the bottom-most new directory, - whereas the previous form has a URL that points directly to the bottom-most - new directory. + This operation will return an error if a blocking file is present at any of + the parent names, preventing the server from creating the necessary parent + directory, or if it would require changing any immutable directory. + + The URL of this operation points to the parent of the bottommost new directory, + whereas the /uri/$DIRCAP/[SUBDIRS../]SUBDIR?t=mkdir operation above has a URL + that points directly to the bottommost new directory. POST /uri/$DIRCAP/[SUBDIRS../]?t=mkdir-with-children&name=NAME - As above, but the new directory will be populated with initial children via - the POST request body, as described in /uri?t=mkdir-with-children above. + Like /uri/$DIRCAP/[SUBDIRS../]?t=mkdir&name=NAME, but the new directory will + be populated with initial children via the POST request body. Note that the name= argument must be passed as a queryarg, because the POST request body is used for the initial children JSON. POST /uri/$DIRCAP/[SUBDIRS../]?t=mkdir-immutable&name=NAME - As above, but the new directory will be deep-immutable, with the children - specified as a JSON dictionary in the POST request body. Again, the name= - argument must be passed as a queryarg. + Like /uri/$DIRCAP/[SUBDIRS../]?t=mkdir-with-children&name=NAME, but the + final directory will be deep-immutable. The children are specified as a + JSON dictionary in the POST request body. Again, the name= argument must be + passed as a queryarg. + + In Tahoe 1.6 this operation creates intermediate mutable directories if + necessary, but that behaviour should not be relied on; see ticket #920. === Get Information About A File Or Directory (as JSON) === @@ -546,7 +607,7 @@ Then the rw_uri field will be present in the information about a directory if and only if you have read-write access to that directory. The verify_uri - field will be presend if and only if the object has a verify-cap + field will be present if and only if the object has a verify-cap (non-distributed LIT files do not have verify-caps). ==== About the metadata ==== @@ -622,11 +683,11 @@ link points. 4. Also, quite apart from Tahoe, you might be confused about the meaning of - the 'ctime' in unix local filesystems, which people sometimes think means - file creation time, but which actually means, in unix local filesystems, the + the 'ctime' in UNIX local filesystems, which people sometimes think means + file creation time, but which actually means, in UNIX local filesystems, the most recent time that the file contents or the file metadata (such as owner, permission bits, extended attributes, etc.) has changed. Note that although - 'ctime' does not mean file creation time in Unix, it does mean link creation + 'ctime' does not mean file creation time in UNIX, it does mean link creation time in Tahoe, unless the "tahoe backup" command has been used on that link, in which case it means something about the local filesystem file which corresponds to the Tahoe file which is pointed at by the link. It means @@ -634,7 +695,6 @@ Windows) or file-contents-or-metadata-update-time of the local file (if "tahoe backup" was run on a different operating system). - === Attaching an existing File or Directory by its read- or write- cap === PUT /uri/$DIRCAP/[SUBDIRS../]CHILDNAME?t=uri @@ -658,10 +718,15 @@ if there is already an object at the given location, rather than overwriting the existing object. To allow the operation to overwrite a file, but return an error when trying to overwrite a directory, use - "replace=only-files" (this behavior is closer to the traditional unix "mv" + "replace=only-files" (this behavior is closer to the traditional UNIX "mv" command). Note that "true", "t", and "1" are all synonyms for "True", and "false", "f", and "0" are synonyms for "False", and the parameter is case-insensitive. + + Note that this operation does not take its child cap in the form of + separate "rw_uri" and "ro_uri" fields. Therefore, it cannot accept a + child cap in a format unknown to the webapi server, because the server + is not able to attenuate an unknown write cap to a read cap. === Adding multiple files or directories to a parent directory at once === @@ -679,7 +744,9 @@ "childinfo" is a dictionary that contains "rw_uri", "ro_uri", and "metadata" keys. You can take the output of "GET /uri/$DIRCAP1?t=json" and use it as the input to "POST /uri/$DIRCAP2?t=set_children" to make DIR2 - look very much like DIR1. + look very much like DIR1 (except for any existing children of DIR2 that + were not overwritten, and any existing "tahoe" metadata keys as described + below). When the set_children request contains a child name that already exists in the target directory, this command defaults to overwriting that child with @@ -721,7 +788,7 @@ The object will only become completely unreachable once 1: there are no reachable directories that reference it, and 2: nobody is holding a read- or write- cap to the object. (This behavior is very similar to the way - hardlinks and anonymous files work in traditional unix filesystems). + hardlinks and anonymous files work in traditional UNIX filesystems). This operation will not modify more than a single directory. Intermediate directories which were implicitly created by PUT or POST methods will *not* @@ -850,7 +917,7 @@ POST /uri?t=upload This uploads a file, and produces a file-cap for the contents, but does not - attach the file into the virtual drive. No directories will be modified by + attach the file into the filesystem. No directories will be modified by this operation. The file must be provided as the "file" field of an HTML encoded form body, @@ -880,9 +947,9 @@ POST /uri/$DIRCAP/[SUBDIRS../]?t=upload - This uploads a file, and attaches it as a new child of the given directory. - The file must be provided as the "file" field of an HTML encoded form body, - produced in response to an HTML form like this: + This uploads a file, and attaches it as a new child of the given directory, + which must be mutable. The file must be provided as the "file" field of an + HTML-encoded form body, produced in response to an HTML form like this: