HTTPS/JSON REST API

This API is encrypted through TLS/HTTPS and uses JSON syntax for POST/PATCH
commands and all responses.

JSON is a very common standard syntax for data structures, see examples below
and here: https://en.wikipedia.org/wiki/JSON

Cbftp uses a self-signed TLS certificate, so certificate verification must be
disabled (which is what the -k flag to curl does).

In a REST API, the HTTP methods used are:

GET - Read an existing resource.
POST - Create a new resource.
PATCH - Update an existing resource.
DELETE - Delete a resource.

The API password is provided through HTTP Basic auth, which is entered as
username:password and encoded with base64 as a HTTP message header.
The username is ignored.

Example usage: (Configuration: HTTPS/JSON API port 55477, password bestpass)

List sites:
  curl -k -u :bestpass https://localhost:55477/sites

Send a raw command (and get results):
  curl -k -u :bestpass -X POST https://localhost:55477/raw -d '{
    "command": "site deluser me", "sites": ["SITE1"]}'

Add a site (read json blob from file):
  curl -k -u :bestpass -X POST https://localhost:55477/sites -d @newsite.json


Available commands:

- List all sites. Section filter is optional
    GET /sites
    GET /sites?section=sectionname

- Get details of a specific site
    GET /sites/SITE1

- Add a new site
    POST /sites

- Update an existing site
    PATCH /sites/SITE1

An example body when POST/PATCH'ing a site:

{
  "name": "SITE1",
  "addresses": [
    "address1.com:46473",
    "address2.com"
  ],
  "affils": [
    "GROUP1",
    "GROUP2"
  ],
  "allow_download": "YES",           // (YES/NO/MATCH_ONLY)
  "allow_upload": "NO",              // (YES/NO)
  "avg_speed": {
    "SITE2": 20000,                  // speed SITE1 -> SITE2
    "SITE3": 30000
  },
  "base_path": "/",
  "broken_pasv": false,
  "cepr": true,
  "cpsv": true,
  "disabled": false,
  "except_source_sites": [
    "SITE2"
  ],
  "except_target_sites": [
    "SITE3"
  ],
  "force_binary_mode": false,
  "leave_free_slot": true,
  "list_command": "STAT_L",          // (STAT_L/LIST)
  "max_idle_time": 60,
  "max_logins": 3,
  "max_sim_down": 2,
  "max_sim_down_complete": 0,
  "max_sim_down_pre": 0,
  "max_sim_down_transferjob": 0,
  "max_sim_up": 3,
  "password": "SecretPassword",
  "pret": false,
  "priority": "HIGH",                // (VERY_LOW/LOW/NORMAL/HIGH/VERY_HIGH)
  "list_frequency": "AUTO",          // (VERY_LOW/FIXED_LOW/FIXED_AVERAGE/ 
                                     //  FIXED_HIGH/FIXED_VERY_HIGH/AUTO/
                                     //  DYNAMIC_LOW/DYNAMIC_AVERAGE/
                                     //  DYNAMIC_HIGH/DYNAMIC_VERY_HIGH)
  "proxy_name": "",
  "proxy_type": "GLOBAL",            // (GLOBAL/NONE/USE)
  "sections": [
    {
      "name": "SEC1",
      "path": "/some/path"
    },
    {
      "name": "SEC2",
      "path": "/some/other/path"
    }
  ],
  "skiplist": [
    {
      "action": "DENY",              // (ALLOW/DENY/UNIQUE/SIMILAR)
      "dir": false,
      "file": true,
      "pattern": ".*asdf.*",
      "regex": true,
      "scope": "IN_RACE"             // (IN_RACE/ALL)
    }
  ],
  "sscn": false,
  "stay_logged_in": false,
  "tls_mode": "AUTH_TLS",              // (NONE/AUTH_TLS/IMPLICIT)
  "tls_transfer_policy": "PREFER_OFF", // (ALWAYS_OFF/PREFER_OFF/...)
  "transfer_protocol": "IPV4_ONLY",    // (IPV4_ONLY/PREFER_IPV4/...)
  "transfer_source_policy": "ALLOW",   // (ALLOW/BLOCK)
  "transfer_target_policy": "BLOCK",   
  "user": "myusername",
  "xdupe": true
}

All values do not have to be included. When modifying a site, only the edited
values need to be included. When adding a site, unspecified values will get
their default values. Example:

{
  "affils": [
    "GROUP3"
  ]
}

- Get sections for a site (also visible when getting the entire site)
    GET /sites/SITE1/sections

- Get a single section for a site
    GET /sites/SITE1/sections/SECTIONNAME

- Add a section to a site
    POST /sites/SITE1/sections

- Edit a section on a site
    PATCH /sites/SITE1/sections/SECTIONNAME

- Delete a section on a site
    DELETE /sites/SITE1/sections/SECTIONNAME

- Delete a site
    DELETE /sites/SITE1

- Send a raw command
    POST /raw

An example body when sending a raw command:

{
  "command": "site deluser me",
  "sites": [               // run on these sites
    "SITE1"
  ],
  "sites_with_sections": [ // run on sites with these sections defined
    "SEC1"
  ],
  "sites_all": true,       // run on all sites
  "path": "/some/path",    // the path to cwd to before running command
  "path_section": "SEC1",  // section to cwd to before running command
  "timeout": 10,           // max wait before failing
  "async": false           // if false, wait for command to finish before
                           // responding. If true, respond with a request
                           // id and let command run in the background
}

Section paths in the command can be inserted with:
$path(sectionname)
  
- Get raw command results for an async raw command with id 1
   GET /raw/1

- List a directory. The path can also be a section name. Timeout is optional,
  defaults to 60 seconds
   GET /path?site=SITE1&path=/&timeout=2

- Delete a directory. The path can also be a section name. Type is optional,
  defaults to ALL
   DELETE /path?site=SITE1&path=/unwanted/dir&type=OWN

- Show a file. Timeout is optional, defaults to 60 seconds. The maximum allowed
  file size is hardcoded to 500k by default.
   GET /file?site=SITENAME&path=/path/to/some/file.nfo&timeout=10

- List all spread jobs. Filters are optional
   GET /spreadjobs
   GET /spreadjobs?status=RUNNING&section=SOMESECTION
   GET /spreadjobs?profile=RACE&site=SOMESITE&name=*debian*
   
- Get details of a specific spread job
   GET /spreadjobs/JOBNAME
   
- Start a new spread job
   POST /spreadjobs

An example body when starting a spread job:

{
  "section": "LINUX_ISOS",
  "name": "LATEST_DISTRO_1.0-NEW,
  "sites": [
    "SITE1",
    "SITE2",
    "SITE3"
  ],
  "sites_dlonly": [         // (optional)
    "SITE1"
  ],
  "sites_all": false,       // (optional) whether to add all sites with the
                            // section defined
  "reset": false,           // (optional) whether to reset the job if it
                            // already exists
  "profile": "DISTRIBUTE"   // (RACE/DISTRIBUTE/PREPARE)
}

- Reset a spread job
   POST /spreadjobs/JOBNAME/reset

Example body (optional) when reseting a spread job:

{
  "hard": false  // optional
}

- Abort a spread job
   POST /spreadjobs/JOBNAME/abort

Example body (optional) when aborting a spread job:

{
  "delete": "NONE", // (optional, NONE/INCOMPLETE/OWN/ALL)
  "sites": [        // (optional) if specified, remove these sites from job
                    // instead of aborting
    "SITE1"
  ]
}

- List all transfer jobs. Filters are optional.
   GET /transferjobs?id=false
   GET /transferjobs?status=RUNNING&src_site=SOMESITE&type=FXP
   GET /transferjobs?dst_site=SOMESITE&type=UPLOAD
   GET /transferjobs?site=SOMESITE&name=*debian*
   
- Get details of a specific transfer job. Use the id query param to get job via
  id instead of name
   GET /transferjobs/JOBNAME_OR_ID?id=false
   
- Start a new transfer job
   POST /transferjobs
   
An example body when starting an FXP job:

{
  "src_site": "SITE1",
  "src_section": "SECTION1",        // src_section or src_path
  "dst_site": "SITE2",
  "dst_path": "/MISC",              // dst_section or dst_path
  "name": "LATEST_DISTRO_1.0-NEW"
}

An example body when starting a download job:

{
  "src_site": "SITE1",
  "src_section": "SECTION1",        // src_section or src_path
  "name": "LATEST_DISTRO_1.0-NEW",
  "dst_path": "/linux-isos"         // optional
}

An example body when starting an upload job:

{
  "dst_site": "SITE1",
  "dst_path": "/linux-isos",        // dst_section or dst_path
  "name": "LATEST_DISTRO_1.0-NEW",
  "src_path": "/linux-isos"         // optional
}

- Reset a transfer job
   POST /transferjobs/JOBNAME_OR_ID/reset?id=false (no body)
   
- Abort a transfer job
   POST /transferjobs/JOBNAME_OR_ID/abort?id=false (no body)

- List all sections
   GET /sections

- Show details for a specific section
   GET /sections/SECTIONNAME

- Add a section
   POST /sections

- Modify a section
   PATCH /sections/SECTIONNAME

An example body when adding or modifying a section:

{
  "name": "TESTSEC1",
  "hotkey": 7,           // optional, 0-9
  "num_jobs": 0,         // optional, why would anyone edit this?
  "skiplist": [
    {
      "action": "DENY",     // (ALLOW/DENY/UNIQUE/SIMILAR)
      "dir": false,
      "file": true,
      "pattern": "*asdf*",
      "regex": false,
      "scope": "ALL"   // (IN_RACE/ALL)
    }
  ]
}

- Delete a section
   DELETE /sections/SECTIONNAME

- Show various build information, stats etc
   GET /info

UDP API

The UDP API is one-way, i.e. does not provide responses.
When encryption is enabled, the encryption key is the same as the password.

Example usage: (Configuration: UDP API port 55477, password bestpass)

Plaintext example:
echo -n "bestpass raw SITE1 site deluser me" > /dev/udp/127.0.0.1/55477

Encrypted example:
echo -n "bestpass raw SITE1 site deluser me" | openssl enc -aes-256-cbc \
  -md sha256 > /dev/udp/127.0.0.1/55477
(and then enter bestpass again when prompted)

Available commands:

<password> download <srcsite> <srcpath> [srcfile]
This command will result in cbftp starting a transfer job for downloading
the specified item to your default download directory. The srcfile field is
optional, if omitted cbftp will use the base name of the srcpath as file name.
The srcpath field can also be a section name, in which case srcfile must also
be specified.

<password> upload <srcpath> [srcfile] <dstsite> <dstpath>
This command will result in cbftp starting a transfer job for uploading
the specified item to the specified site and path. The srcfile field is
optional, if omitted cbftp will use the base name of the srcpath as file name.
The dstpath field can also be a section name.

<password> fxp <srcsite> <srcpath> <srcfile> <dstsite> <dstpath> [dstfile]
This command will result in cbftp starting a transfer job for sending
the specified item from one site to another via FXP. The dstfile field
is optional and will be the same as srcfile if omitted.
The srcpath/dstpath fields can also be section names, and if dstpath is a
section name then dstfile must also be specified.

<password> downloadtopath <srcsite> <srcpath> [srcfile] <dstpath>
This command will result in cbftp starting a transfer job for downloading
the specified item to the specified download path. The srcfile field is
optional, if omitted cbftp will use the base name of the srcpath as file name.
The srcpath field can also be a section name, in which case srcfile must also
be specified.

<password> race <section> <file> <sitelist> [dlonlysitelist]
This command starts a spread job with the 'race' profile for the specified
item on the specified sites. The site list is a list of site names,
comma-separated without spaces. (Example: site1,site2,site3). Wildcard (*)
also works, which means all sites added in cbftp will be selected.
An optional site list with download-only sites can be appended.

<password> distribute <section> <file> <sitelist> [dlonlysitelist]
This command starts a spread job with the 'distribute' profile for the
specified item on the specified sites.

<password> prepare <section> <file> <sitelist> [dlonlysitelist]
This command prepares a spread job with the 'race' profile, which means
cbftp will log onto the specified sites and await user input. Prepared
spread jobs are started from a list on the main screen and can be started
by selecting the prepared job and pressing enter, or pressing p from anywhere
in the cbftp UI to start the latest prepared job.

<password> raw <sitelist> <command>
This command makes cbftp issue the given raw command on the listed sites.
The sitelist can also be a section name.
Section paths in the command can be inserted with: $path(sectionname)

<password> rawwithpath <sitelist> <path> <command>
This command makes cbftp change directory to the given path and then issue
the given raw command on the listed sites. The sitelist and path field can also
be section names.

<password> idle <sitelist> [time]
This command makes cbftp login and idle on the specified sites. Specifying
how long the sites should stay logged in is optional, and defaults to the
"max idle time" specified per site.
The sitelist can also be a section name.

<password> abort <job>
This command makes cbftp abort the specified spread job.

<password> delete <job> [sites]
This command makes cbftp abort the specified spread job, and then delete
all your own related files on all involved sites.
If a sitelist is specified, those sites will be removed from the job instead
of aborting it.

<password> abortdeleteincomplete <job>
This command makes cbftp abort the specified spread job, and then delete
all your own related files on all incomplete sites.

<password> reset <job>
This command makes cbftp soft reset (no re-mkdir) the specified spread job.

<password> hardreset <job>
This command makes cbftp hard reset the specified spread job.
