mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-24 15:16:41 +00:00
351 lines
14 KiB
Plaintext
351 lines
14 KiB
Plaintext
|
|
Writing "8011" into CLIENTDIR/webport causes the client to run a webserver on
|
|
port 8011. Writing "tcp:8011:interface=127.0.0.1" into CLIENTDIR/webport does
|
|
the same but binds to the loopback interface, ensuring that only the programs
|
|
on the local host can connect. Using
|
|
"ssl:8011:privateKey=mykey.pem:certKey=cert.pem" would run an SSL server. See
|
|
twisted.application.strports for more details.
|
|
|
|
If CLIENTDIR/webpassword exists, it will be used (somehow) to require HTTP
|
|
Digest Authentication for all webserver connections.
|
|
|
|
|
|
The client provides some small number of "virtual drives". In the 0.4.0
|
|
release, this number is two: the first is the global shared vdrive, the
|
|
second is the private non-shared vdrive. We will call these "global" and
|
|
"private" for now.
|
|
|
|
For the purpose of this document, let us assume that the vdrives currently
|
|
contain the following directories and files:
|
|
|
|
global/
|
|
global/Documents/
|
|
global/Documents/notes.txt
|
|
|
|
private/
|
|
private/Pictures/
|
|
private/Pictures/tractors.jpg
|
|
|
|
|
|
== vdrive ==
|
|
|
|
Within the webserver, there is a tree of resources. The top-level "vdrive"
|
|
resource gives access to files and directories in all of the user's virtual
|
|
drives. For example, the URL that corresponds to notes.txt would be:
|
|
|
|
FILEURL = http://localhost:8011/vdrive/global/Documents/notes.txt
|
|
|
|
and the URL for tractors.jpg would be:
|
|
|
|
http://localhost:8011/vdrive/private/Pictures/tractors.jpg
|
|
|
|
In addition, each directory has a corresponding URL. The Pictures URL is:
|
|
|
|
DIRURL = http://localhost:8011/vdrive/private/Pictures
|
|
|
|
Now, what can we do with these URLs? By varying the HTTP "method"
|
|
(GET/PUT/POST/DELETE) and by appending a type-indicating query argument, we
|
|
control how what we want to do with the data and how it should be presented.
|
|
|
|
In the following examples, FILEURL and DIRURL are abbreviations for the
|
|
previously listed examples. In addition. NEWFILEURL and NEWDIRURL are URLs
|
|
for files and directories which do not yet exist.
|
|
|
|
=== Files ===
|
|
|
|
GET FILEURL
|
|
|
|
This simply retrives the contents of the file at the given place in the
|
|
vdrive. The Content-Type is set according to the vdrive's metadata (if
|
|
available) or by using the usual filename-extension-magic built into most
|
|
webservers. The file's contents are provided in the body of the HTTP
|
|
response.
|
|
|
|
(thought: we could conceivably provide some measure of gathering-peers
|
|
progress and pre-plaintext status information by emitting some extra
|
|
X-Tahoe-Status headers. Of course, once the headers are done and we start
|
|
sending plaintext, we have to stop sending such headers)
|
|
|
|
PUT NEWFILEURL
|
|
|
|
This uploads a file to the given place in the vdrive. It will create
|
|
intermediate directory nodes as necessary. The file's contents are taken
|
|
from the body of the HTTP request. For convenience, the HTTP response
|
|
contains the URI that results from uploading the file, although the client
|
|
is not obligated to do anything with the URI. According to the HTTP/1.1
|
|
specification (rfc2068), this should return a 200 (OK) code when modifying
|
|
and existing file, and a 201 (Created) code when creating a new file.
|
|
|
|
To use this, run 'curl -T localfile http://localhost:8011/vdrive/global/newfile'
|
|
|
|
DELETE FILEURL
|
|
|
|
This deletes the given file from the vdrive. Note that this *does not*
|
|
delete any parent directories, so a sequence of 'PUT NEWFILEURL' and
|
|
'DELETE NEWFILEURL' does not necessarily return the vdrive to its original
|
|
state (it may leave some intermediate directory nodes).
|
|
|
|
GET FILEURL?t=json
|
|
|
|
This returns machine-parseable information about the file in the HTTP
|
|
response body, including file size, metadata (like Content-Type), and URIs.
|
|
This information is also required to contain a flag that distinguishes
|
|
between files and directories. Programatic clients are expected to use this
|
|
query before actually downloading the file's contents.
|
|
|
|
The JSON data is as follows:
|
|
|
|
[ 'filenode', { 'mutable': bool, 'uri': file_uri, 'size': bytes } ]
|
|
|
|
|
|
GET FILEURL?t=download&localfile=$FILENAME
|
|
|
|
This instructs the client to download the given file and write its contents
|
|
into the local filesystem at $FILENAME. This request will only be accepted
|
|
from an HTTP client connection originating at 127.0.0.1 . This request is
|
|
most useful when the client node and the HTTP client are operated by the
|
|
same user. $FILENAME should be an absolute pathname.
|
|
|
|
(thoughts: we could use either the response headers or the response body
|
|
to indicate download progress)
|
|
|
|
PUT NEWFILEURL?t=upload&localfile=$FILENAME
|
|
|
|
This uploads file to the vdrive and gets the contents from a file in the
|
|
client's local filesystem. As with GET, this request will only be accepted
|
|
from an HTTP connection originating from 127.0.0.1.
|
|
|
|
(we could indicate upload progress too. The response body could contain
|
|
the URI of the uploaded file)
|
|
|
|
|
|
GET FILEURL?t=uri
|
|
|
|
This returns the URI of the given file in the HTTP response body.
|
|
|
|
GET FILEURL?t=readonly-uri
|
|
|
|
This also returns the URI of the given file. For now, all files are
|
|
immutable, so t=uri and t=readonly-uri return the same value. In the
|
|
future, when we have mutable files, they will return different values.
|
|
|
|
=== Directories ===
|
|
|
|
GET DIRURL
|
|
|
|
This returns an HTML page, intended to be used by humans, which contains
|
|
HREF links to all files and directories reachable from this dirnode. These
|
|
HREF links do not have a t= argument, meaning that a human who follows them
|
|
will get pages also meant for a human. It also contains forms to upload new
|
|
files, and to delete files and directories. These forms use POST methods to
|
|
do their job.
|
|
|
|
GET DIRURL?t=json
|
|
|
|
This returns machine-parseable information about this directory in the HTTP
|
|
response body. This information first contains a flag to indicate that
|
|
DIRURL referenced a directory (as opposed to a file). Then it contains a
|
|
flag to indicate whether this is a read-write dirnode or a read-only
|
|
dirnode. Finally it also contains information about the children of this
|
|
directory, probably as a mapping from child name to a set of metadata about
|
|
the child (basically the same data that would appear in a corresponding
|
|
GET?t=json of the child itself). A programmatic client should be able to use
|
|
the information from this query to display filesystem navigation choices to
|
|
a human user.
|
|
|
|
The JSON data is as follows:
|
|
|
|
[ 'dirnode', { 'mutable': bool, 'uri': uri, 'children': children } ]
|
|
|
|
where 'children' is a dictionary in which the keys are child names
|
|
and the values depend upon whether the child is a file or a directory:
|
|
|
|
'foo.txt': [ 'filenode', { 'mutable': bool, 'uri': uri, 'size': bytes } ]
|
|
'subdir': [ 'dirnode', { 'mutable': bool, 'uri': uri } ]
|
|
|
|
note that the value is the same as the JSON representation of the
|
|
corresponding FILEURL or DIRURL (except that dirnodes do not recurse).
|
|
|
|
|
|
GET DIRURL?t=uri
|
|
GET DIRURL?t=readonly-uri
|
|
|
|
Return a URI for this dirnode in the HTTP response body. If the dirnode is
|
|
read-only, the t=uri and t=readonly-uri responses will be the same.
|
|
|
|
GET DIRURL?t=manifest
|
|
|
|
Return an HTML-formatted manifest of the given directory, for debugging.
|
|
|
|
PUT NEWDIRURL?t=mkdir
|
|
|
|
Create a new empty directory at the given path. The HTTP response contains
|
|
the URI of the given directory, although the client is not obligated to do
|
|
anything with it.
|
|
|
|
DELETE DIRURL
|
|
|
|
This deletes the given directory (and all of its children). Note that this
|
|
*does not* delete any parent directories, so a sequence of 'PUT
|
|
NEWDIRURL?t=mkdir' and 'DELETE NEWDIRURL does not necessarily return the
|
|
vdrive to its original state (it may leave some intermediate directory
|
|
nodes).
|
|
|
|
GET DIRURL?t=download&localdir=$DIRNAME
|
|
|
|
This instructs the client to perform a recursive download of the given
|
|
directory and all its descendant files and directories, writing the results
|
|
to the local filesystem starting at DIRNAME.
|
|
|
|
(thoughts: we could use the response headers or the response body to
|
|
indicate download progress)
|
|
|
|
PUT NEWDIRURL?t=upload&localdir=$DIRNAME
|
|
|
|
This instructs the client to perform a recursive upload of a directory on
|
|
the local filesystem into the vdrive at the given location. NEWDIRURL will
|
|
be created if necessary. When the operation is complete, the directory
|
|
referenced by NEWDIRURL will contain all of the files and directories that
|
|
were present in DIRNAME, so this is equivalent to the unix commands:
|
|
|
|
mkdir -p NEWDIRURL; cp -r DIRNAME/* NEWDIRURL/
|
|
|
|
Note that the "curl" utility can be used to provoke this sort of recursive
|
|
upload, since the -T option will make it use an HTTP 'PUT':
|
|
|
|
curl -T /dev/null 'http://localhost:8011/vdrive/global/newdir?t=upload&localdir=/home/user/directory-to-upload'
|
|
|
|
GET DIRURL?t=rename-form&name=$CHILDNAME
|
|
|
|
This provides a useful facility to browser-based user interfaces.
|
|
It returns a page containing a form targetting the POST DIRURL t=rename
|
|
functionality listed below, with the provided $CHILDNAME present in the
|
|
'from_name' field of that form. i.e. this presents a form offering to
|
|
rename $CHILDNAME, requesting the new name, and submitting POST rename
|
|
|
|
== POST Forms ==
|
|
|
|
POST DIRURL
|
|
t=upload
|
|
name=childname (optional)
|
|
file=newfile
|
|
|
|
This instructs the client to upload a file into the given dirnode. We need
|
|
this because forms are the only way for a web browser to upload a file
|
|
(browsers do not know how to do PUT or DELETE). The file's contents and the
|
|
new child name will be included in the form's arguments. This can only be
|
|
used to upload a single file at a time. To avoid confusion, name= is not
|
|
allowed to contain a slash (a 400 Bad Request error will result).
|
|
|
|
POST DIRURL
|
|
t=mkdir
|
|
name=childname
|
|
|
|
This instructs the client to create a new empty directory. The name of the
|
|
new child directory will be included in the form's arguments.
|
|
|
|
POST DIRURL
|
|
t=uri
|
|
name=childname
|
|
uri=newuri
|
|
|
|
This instructs the client to attach a child that is referenced by URI (just
|
|
like the PUT NEWFILEURL?t=uri method). The name and URI of the new child
|
|
will be included in the form's arguments.
|
|
|
|
POST DIRURL
|
|
t=delete
|
|
name=childname
|
|
|
|
This instructs the client to delete a file from the given dirnode. The name
|
|
of the child to be deleted will be included in the form's arguments.
|
|
|
|
POST DIRURL
|
|
t=rename
|
|
from_name=oldchildname
|
|
to_name=newchildname
|
|
|
|
This instructs the client to rename a child within the given dirnode. The
|
|
child specified by 'from_name' is removed, and reattached as a child named
|
|
for 'to_name'. This is unconditional and will replace any child already
|
|
present under 'to_name', akin to 'mv -f' in unix parlance.
|
|
|
|
== URI ==
|
|
|
|
http://localhost:8011/uri/$URI
|
|
|
|
A separate top-level resource namespace ("uri" instead of "vdrive") is used
|
|
to get access to files and dirnodes that are indexed directly by URI,
|
|
rather than by going through the vdrive. The resource thus referenced is
|
|
used the same way as if it were accessed through the vdrive, including
|
|
child-resource-traversal behavior. For example, if the URI corresponds to a
|
|
file, then
|
|
|
|
GET http://localhost:8011/uri/$URI
|
|
|
|
would retrieve the contents of the file. Since files accessed this way do
|
|
not have a naturally-occurring filename (from which a MIME-type can be
|
|
derived), one can be specified using a 'filename=' query argument. This
|
|
filename is also the one used if the 'save=true' argument is set, which
|
|
adds a 'Content-Disposition: attachment' header to prompt most web browsers
|
|
to save the file to disk rather than attempting to display it:
|
|
|
|
GET http://localhost:8011/uri/$URI?filename=foo.jpg
|
|
GET http://localhost:8011/uri/$URI?filename=foo.jpg&save=true
|
|
|
|
If the URI corresponds to a directory, then:
|
|
|
|
PUT http://localhost:8011/uri/$URI/subdir/newfile?localfile=$FILENAME
|
|
|
|
would upload a file (with contents taken from the local filesystem) to a
|
|
new file in a subdirectory of the referenced dirnode.
|
|
|
|
Note that since tahoe URIs may contain slashes (in particular, dirnode URIs
|
|
contain a FURL, which resembles a regular HTTP URL and starts with pb://),
|
|
when URIs are used in this form, they must be specially quoted. All slashes
|
|
in the URI must be replaced by '!' characters.
|
|
|
|
|
|
PUT NEWFILEURL?t=uri
|
|
|
|
This attaches a child (either a file or a directory) to the vdrive at the
|
|
given location. The URI is provided in the body of the HTTP request. This
|
|
can be used to attach a shared directory to the vdrive. Intermediate
|
|
directories are created on-demand just like with the regular PUT command.
|
|
|
|
GET http://localhost:8011/uri?uri=$URI
|
|
|
|
This causes a redirect to /uri/$URI, and retains any additional query
|
|
arguments (like filename= or save=). This is for the convenience of web
|
|
forms which allow the user to paste in a URI (obtained through some
|
|
out-of-band channel, like IM or email).
|
|
|
|
Note that this form only redirects to the specific node indicated by the
|
|
URI: unlike the GET /uri/$URI form, you cannot traverse to child nodes by
|
|
appending additional path segments to the URL.
|
|
|
|
The $URI provided as a query argument is allowed to contain slashes. The
|
|
redirection provided will escape the slashes with exclamation points, as
|
|
described above.
|
|
|
|
== XMLRPC ==
|
|
|
|
http://localhost:8011/xmlrpc
|
|
|
|
This resource provides an XMLRPC server on which all of the previous
|
|
operations can be expressed as function calls taking a "pathname" argument.
|
|
This is provided for applications that want to think of everything in terms
|
|
of XMLRPC.
|
|
|
|
listdir(vdrivename, path) -> dict of (childname -> (stuff))
|
|
put(vdrivename, path, contents) -> URI
|
|
get(vdrivename, path) -> contents
|
|
mkdir(vdrivename, path) -> URI
|
|
put_localfile(vdrivename, path, localfilename) -> URI
|
|
get_localfile(vdrivename, path, localfilename)
|
|
put_localdir(vdrivename, path, localdirname) # recursive
|
|
get_localdir(vdrivename, path, localdirname) # recursive
|
|
put_uri(vdrivename, path, URI)
|
|
|
|
etc..
|