The Octopus Daemon Network Protocol (Version 1.1) =========================================================================== Erik Scharwaechter 2006-07-10 1. Commands 1.1. ADD 1.2. DEL 1.3. PAUSE 1.4. RESUME 1.5. RESTART 1.6. UPDATE 1.7. INFO 1.8. STATUS 1.9. LIST 1.10. VERSION 2. Download ID Format 3. Arguments 4. Notes I. Appendix 1. Commands =========================================================================== The default port of the network protocol is 7700/tcp. When an error occures on execution of a command or an invalid command is sent to the server, it answers ERROR message with message being the error message in human-readable plain text. All the lines are finished with , a.k.a "line feed" or \n, the ASCII character 10. 1.1. ADD Add a new download job to the queue and start downloading it as soon as possible. See Section 3 (Arguments) for valid arguments and the possible values. ADD url=value[,arg=value[...]] As you can see, only the url is mandatory, the remaining arguments are set to their default values. The answer the server sends is the following: OK download_id download_id is the Download ID (see Section 2) of the download added to the queue. 1.2. DEL Delete the download with the Download ID download_id from the queue. The downloaded file on your local hard disk is NOT removed. DEL download_id The answer the server sends is the following: OK 1.3. PAUSE Pause a (running) download. PAUSE download_id Answer: OK 1.4. RESUME Resume a (paused) download. RESUME download_id Answer: OK 1.5. RESTART Restart the download with the given Download ID. The local data (if any) is erased and the download starts from the beginning on. RESTART download_id Answer: OK 1.6. UPDATE Update the information about a download. You can specify any of the arguments from Section 3. NOTE: If the URL is changed and no filename is specified, the filename from the url will be taken over. The Download ID will be recalculated. You probably need to RESTART the download after updating it, so the changes can take effect. UPDATE download_id arg=value[,arg=value[...]] Answer: OK download_id 1.7. INFO Fetch STATIC information about the download. Static information means all the information the client can pass with the ADD or UPDATE command. INFO download_id The answer is one line containing CSV (comma separated values) with all the information. When url or filename contain a comma, the WHOLE arg=value part is enclosed with quotation marks, e.g. "filename=foo,bar". No other character has to be escaped. url=value[,arg=value[...]] 1.8. STATUS Fetch DYNAMIC information about the download. Dynamic information contains all the information that is changed regularly, e.g. the download speed or the bytes already downloaded. Have a look at the answer for details. STATUS download_id The answer consists of the following CSV (comma separated values): state=value,[error=msg,]size_total=value,size_fetched=value, \ speed=value,duration=value,url=value state is one of RUNNING, PAUSED, FAILED, FINISHED or WAITING. error is only sent, if state is FAILED. size_total and size_fetched return the bytes as a double, speed is the download speed in bytes per second (also double) and duration is the download time in seconds. The url is a string. NOTE: The line break after "size_fetched=value," is only for formatting reasons and not a part of the protocol, as indicated by the back slash. 1.9. LIST Get a list with all Download IDs in the queue. LIST The answer is one Download ID per line, followed by a line containing OK: download_id1 download_id2 [...] OK 1.10. VERSION Query the protocol version the server understands. This is needed to check the compatibility between client and server. VERSION Answer: version With version being the version number of the protocol. 2. Download ID Format =========================================================================== The download id is calculated using the URL of a download and the timestamp (and microseconds) of the time it was generated. It is represented as a 128 bit hexadecimal number, e.g. "814fab1a109da1003434de20c8d8fe50" (32 characters). Have a look at for implementation details. 3. Arguments =========================================================================== GENERIC ARGUMENTS ARGMUENT TYPE DESCRIPTION | DEFAULT ------------------------------------------------------------+-------------- filename str name of the local file | remote file | name | timeout int connection timeout time, | in seconds | 300 | move str UP or DOWN, increase or decrease | priority (only useful in UPDATE | command) | - HTTP DOWNLOAD ARGUMENTS ARGMUENT TYPE DESCRIPTION | DEFAULT ------------------------------------------------------------+-------------- follow bool follow "Location:" redirects | true | max_redirs int maximum number of redirects, | 0=infinite | 5 | unrestricted bool send auth information to servers | after redirect | false FTP DOWNLOAD ARGUMENTS ARGMUENT TYPE DESCRIPTION | DEFAULT ------------------------------------------------------------+-------------- ascii bool use ascii mode | false | pasv bool use passive ftp mode | true | eprt bool use EPRT/LPRT instead of | PORT (in active mode) | false | epsv bool use EPSV (in passive mode) | false 4. NOTES =========================================================================== If you have any ideas or recommendations concerning this protocol, please let me know by writing an e-mail to diozaka@gmx.de. I. APPENDIX =========================================================================== If you are developing a client, you will once face the problem to parse the CSV data received by the INFO and STATUS commands. As I don't want you to reinvent the wheel, this is the method the daemon itself uses to do so: #include #include #include #include typedef std::map MapStrStr; MapStrStr csv2map(const std::string& csv) { MapStrStr map; boost::tokenizer > tok(csv); // for each comma seperated argument... for (boost::tokenizer >::iterator beg=tok.begin(); beg!=tok.end();++beg) { std::vector vec; // ...split the argument into key and value... boost::algorithm::split(vec, *beg, boost::algorithm::is_any_of("=")); if (vec.size()==2) { boost::trim(vec[0]); boost::trim(vec[1]); // ...and write it to the map map[vec[0]] = vec[1]; } } return map; } A call to csv2map("arg1=value1,arg2=value2") will return a map with two elements: map["arg1"]=="value1" and map["arg2"]=="value2".