require_once("docutil.php"); page_head("Data server protocol"); echo " Core client communicate with data servers using HTTP. A data server is typically implemented using a web server together with a BOINC-supplied CGI program, file_upload_handler.
File download is done by a GET request to a URL from the FILE_INFO element. The file offset, if any, is given in Range: attribute of the HTTP header.
File upload is done using POST operations to a CGI program. A security mechanism prevents unauthorized upload of large amounts of data to the server. Two RPC operations are used.
1) Get file size
The request message has the form:
", htmlspecialchars(""), " 1 1 filename
The reply message has the form:
", htmlspecialchars("Status is"; list_start(); list_item("0", "Success. Nbytes is 0 if the file doesn't exist."); list_item("1", "Transient error. The client should try another data server, or try this one later. "); list_item("-1", "Permanent error. The client should give up on the result."); list_end(); echo " In the error cases, the <file_size> element is omitted and the <message> element gives an explanation."), " x [text& | nbytes ]
2) Upload file
Request message format:
", htmlspecialchars("1 1 ... ... x x ... (nbytes bytes of data; may include non-ASCII data) "), "
The <file_info> element is the exact text sent from the scheduling server to the client. It includes a signature based on the project's file upload authentication key pair. <nbytes> is the size of the file. <offset> is the offset within the file.
Reply message format:
", htmlspecialchars("Status is "; list_start(); list_item("0", "success"); list_item("1", "transient error; The client should try another data server, or try this one later. "); list_item("-1", "Permanent error. The client should give up on the result. "); list_end(); echo " In the error cases, the <message> element gives an explanation."), " x text
TODO: if there's an error in the header (bad signature, or file is too large) the client should learn this without actually uploading the file. "; page_tail(); ?>