7.17. Work with storage content via API
Notes:
- The instruction describes the API for working with content of the storage. To work with the storage itself, use general API.
- Limits on the number of requests: in the old version of the API were identical to the limits of the general API, in the new version of the API there are no such limits (you can send more requests).
- All methods support only full paths, without
...
How to work with API
To send requests, use your storage address.
Getting a token:
- Create a web interface user (if not created).
- Authorize with the login and password of the created user and get the token.
Then use the obtained token when working with the rest of the methods (the token is specified in the Authorization: Bearer header).
Code example
Authorization and uploading a file to the storage:
<?php
// Storage host address, displayed at the top of the section in the control panel
$host = 'example.cdn.express';
// File to be uploaded to the storage
$file = '/path/to/local/file.ext';
// Path for uploading to storage and original file name
$path = '/upload/dir/' . basename($file);
// Web access user login to the storage (data can be obtained in the control panel on the "Users and API" tab)
$login = 'storage_login';
// Web user password for accessing the storage
$password = 'storage_password';
$curl = curl_init();
// Authorization
curl_setopt($curl, CURLOPT_URL, 'https://' . $host . '/~/api/auth');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($curl, CURLOPT_POSTFIELDS, ['login' => $login, 'password' => $password]);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: multipart/form-data']);
$json = curl_exec($curl);
$token = json_decode($json, true)['data']['token'];
if (!empty($token)) {
echo 'Authenticated successfully' . PHP_EOL;
} else {
// Check that the host, login and password are correct
echo 'Authentication failed. Check host, login and password.' . PHP_EOL;
exit;
}
// File upload (if the file already exists in the storage, there will be an error)
echo 'Uploading ' . $file . ' ... ';
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_URL, 'https://' . $host . '/~/api/file?path=' . urlencode($path));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_PUT, true);
curl_setopt($curl, CURLOPT_INFILE, fopen($file, 'rb'));
curl_setopt($curl, CURLOPT_INFILESIZE, filesize($file));
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $token]);
var_dump(curl_exec($curl));
$success = curl_getinfo($curl)['http_code'] === 200;
if ($success) {
echo 'success.' . PHP_EOL;
} else {
echo 'failed.' . PHP_EOL;
}
curl_close($curl);
Authorization
Methods for working with tokens.
Get a token
Important points:
- To use all methods at the moment of authorization the user must have write permission set. Without this permission, only getting file list and downloading will be available.
- Whenever you change user rights, you need to log in again and get a new token.
PUT /~/api/auth
Parameters in the request body:
multipart/form-data
login— web access user login.password— web access user password.remember— token validity period:0— 6 hours (default value).1— 7 days.
Authorizes under the specified user and returns a token with an expiration date.
Response:
token— token to use in theAuthorization: Bearerheader when using the rest of the methods.till— token expiration timestamp.
Token deactivation
DELETE /~/api/auth
The token is transferred in the header (as in the other methods).
Deactivates the previously obtained token.
Directories
Methods for working with directories and retrieving their contents.
File list
GET /~/api/directory
Request parameters:
path— path to the directory whose contents are to be retrieved (it is possible to specify severalpathparameters in one request — the data will be returned by unique values, sorted by path length in ascending order).recursive(optional) — recursive data retrieval:0— get the contents of only the specified directory (default value).1— get the contents of the specified directory and all its subdirectories.
iterator(optional) — getting data in a special format, when instead of one large JSON the response contains strings with separate JSON for each directory element. This allows you to significantly save RAM when processing the contents of directories with a large number of items — you can view the response line by line, find JSON of only the required item and unpack it without having to unpack a large JSON with all items.0— get the response as a single large JSON (default value).1— get the response as lines with separate JSON.
The response contains a list of objects with information on each of them:
name— file or directory name.path— path to the object from the storage root.isDirectory— object type: directory or not.size— file size in bytes (for directories it is always4096).mtime— timestamp of the last time the content of the object was changed.ctime— timestamp of the last change to the object's metadata.birthtime— timestamp of object creation or uploading.media— media type (for media files).ext— extension (for files with an extension).share— information about the presence of public link: public link ID ornull(with multiplepathparameters or when retrieving data recursively it is alwaysnull).uri— URI of the file depending on the public access status:- Public access enabled — direct link.
- Public access disabled — secure link (starts with
/~/secure/).
Create
PUT /~/api/directory
Parameters in the request body:
multipart/form-data
path— path to the new directory.
Creates a new directory at the specified path.
Rename/move
POST /~/api/directory
Parameters in the request body:
multipart/form-data
path— path to the directory to be renamed or moved.dest— new path or directory name (path must exist).overwrite— overwrite mode if the target directory already exists:0— do not overwrite and return an error (default value).1— replace the contents of an existing directory.
Renames or moves the specified directory.
Delete
DELETE /~/api/directory
Request parameters:
path— path to the directory to be deleted.
Deletes the specified directory with all its contents. Parent directories are not affected.
Files
Methods for working with files.
Upload
Notes:
- Maximum size of the uploaded file — 50 GB. If you try to upload a larger file, the server will return "413 Request Entity Too Large".
- Statistics are available on the number and amount of uploaded data.
PUT /~/api/file
Request parameters:
path— path to upload with the file name.overwrite— overwrite mode if the target file already exists:0— do not overwrite and return an error (default value).1— replace an existing file.
Uploads the file to the specified path (from the root of the storage).
For an example of PHP code, see. at the beginning of the article.
Command to upload a file from console:
curl -X PUT 'https://example.cdn.express/~/api/file' --header 'Authorization: Bearer <token>' --data-binary '@/path/to/local/file.ext' --url-query 'path=/upload/dir/file.ext'
Download
To maximize speed, files are not downloaded using a method, but rather a GET request via a direct or secure link to the file.
- Get the file list of the directory where the file you want to download is located.
- From the list, get the URI of the desired file.
- Send a GET request to the storage address with the received URI.
Download as archive
PUT /~/api/archive
Parameters in the request body:
application/json
items— paths to files and directories that need to be downloaded.
Downloads the listed objects as a .zip archive (all objects must exist).
Existence check
HEAD /~/api/file
Request parameters:
path— path to the file or directory whose existence is to be checked.
Checks if a file or directory exists at the specified path: response 200 — exists, response 404 — does not exist.
Rename/move
POST /~/api/file
Parameters in the request body:
multipart/form-data
path— path to the file to be renamed or moved.dest— new path or file name (path must exist).overwrite— overwrite mode if the target file already exists:0— do not overwrite and return an error (default value).1— replace an existing file.
Renames or moves the specified file.
Delete
DELETE /~/api/file
Request parameters:
path— path to the file to be deleted.
Deletes the specified file. Parent directories are not affected.
Public links
Methods for working with public links.
Create
PUT /~/api/share
Request parameters:
path— path to the file or directory for which you want to create a public link.write— access status for changing the directory contents:1(access allowed) or0(access denied).deathtime(optional) — timestamp for automatic link deletion (must be later than the current date,0— do not delete).
Creates a public link for the specified object.
Response:
id— public link ID.path— path to the public link object.birthtime— timestamp of the public link creation.isDirectory— object type: directory or not.exists— existence of a public link object (alwaystruewhen created).deathtime— timestamp for automatic link deletion (if passed in the request) or0.writeAccess— status of access to changing directory contents (alwaysfalseby default, configurable by a separate method),uri— URI of the public link (starts with/~/share/).
Link list
GET /~/api/share
Request parameters:
id(optional) — ID of the public link you want to retrieve data from.
Returns the list of public links and their data. If public link ID is specified — returns data of this link only.
The response contains a link list with information about each link (or information about a specific link if the request was for an ID):
id— public link ID.path— path to the public link object.isDirectory— object type: directory or not.writeAccess— status of access to changing directory contents (alwaysfalseby default, configurable by a separate method),birthtime— timestamp of the public link creation.deathtime— timestamp for automatic link deletion (if passed in the request) or0.exists— existence of the public link object (if the file or directory has been renamed, moved or deleted, it will befalse).uri— URI of the public link (starts with/~/share/).
Permissions
POST /~/api/share
Request parameters:
id— ID of the public link for which you want to change permissions (only for directory links).
Parameters in the request body:
multipart/form-data
write— access status for changing the directory contents:1(access allowed) or0(access denied).
Sets the public link's permissions to modify the contents of the directory.
The response is similar to getting a link list.
Delete
DELETE /~/api/share
Request parameters:
id— ID of the public link to be deleted.
Deletes the public link with the specified ID. The object pointed to by the link is not affected.
Secure Link
Generate
GET /~/api/link
Request parameters:
path— path to the file from the storage root.time(optional) — timestamp of the link's expiration (must be later than the current date).ip(optional) — IP address that will be allowed to access the file via the link.
Generates and returns a Secure Link for the specified file with the given parameters.
Response:
token— encoded hash of the set of data consisting of the secret key, path, and parameters.uri— URI of the link (starts with/secure/).url— full link.params:ip— IP address for which access to the file via the link is allowed (if passed in the request).time— timestamp of the link's expiration (if passed in the request).path— path to the file from the storage root.
stat:size— size of the file to which the link points (in bytes).atimeMs— timestamp of the last access to the file (in milliseconds).mtimeMs— timestamp of the last modification of the file content (in milliseconds).ctimeMs— timestamp of the last modification of the file metadata (in milliseconds).birthtimeMs— timestamp of file creation (in milliseconds).
Response codes
200— request successfully completed.400— error while performing request.- The response body will contain a description of the error, for example, "File exists" if the file being uploaded already exists, or "Item not found" if the public link ID cannot be found.
401— authorization not completed.- The response body will contain either "Invalid credential 'login' or 'password'" if the error occurred during authorization, or "Unauthorized" in all other cases.
403— access denied.404— the file or path specified in the request does not exist..429— too many requests.502/503— you need to wait before sending the next request.- For example, the request was received at the moment the API was restarted, or the server was overloaded and did not have time to process the request.
Response headers
Depending on the authorization status and request type, API responses contain additional headers.
For all requests:
x-storage-name— storage name or alias (if set).x-storage-logo— logo from storage settings: if set — URL of the logo file (cdn.adm.tools domain).x-storage-mode— status of the view when opened in storage settings:list(list) ortable(gallery).
For requests with authorization:
x-user-login— web access user login.x-user-till— token expiration timestamp.
For existence check and download requests:
x-stat-directory— object type: directory or not.x-stat-mtime— timestamp of the last time the content of the object was changed.x-stat-ctime— timestamp of the last change to the object's metadata.x-stat-birthtime— timestamp of object creation or uploading.x-stat-size— file size in bytes (for directories it is always4096).
Postman
Preparing to work with Postman:
- Importing collection and environment files:
- Download files:
- In the main menu, select "File → Import" (or press Ctrl+O), select the downloaded files and import them.
- Set up the environment:
- In the left pane, select "Environments".
- From the list of environments, select "storage".
- In the "Current value" column, enter your data and click "Save":
domain— address of your storage.username— storage user name.password— storage user password.
- In the upper right corner, select "storage".
Authorization:
- In the left pane, select "Collections".
- In the collection list, expand "storage" and select the "authorization" method.
- Click "Send" — method will return the token and Postman will automatically substitute the token into the environment.
Then you can select any methods, substitute your data on the "Body" tab and check their work.
In the right panel with the button "</>" you can generate ready-made code samples of method calls in PHP, Python and other languages, cURL, wget, etc. commands.
Comments
для таких файлов и\или автоматическое удаление таких файлов через N-количество обращений к ним (например автоматическое удаление файла после получения файла по API)
По поводу удаления — в настройках хранилища есть опция автоматического удаления файлов старше указанного количества дней. Если подразумевается удаление только определённых файлов, то сейчас это можно организовать самостоятельно через API (собственным скриптом, который будет находить в хранилище файлы с нужными вам критериями и удалять с заданной периодичностью). Может у вас есть пример сервиса, где такая функция доступна из коробки.
По поводу времени жизни сессии — в теории такое можно было бы реализовать для публичных ссылок, чтобы они срабатывали только заданное количество раз. Можете добавить такое предложение — https://www.ukraine.com.ua/#suggestion/ — и если оно наберёт достаточное количество голосов, то будет рассмотрено разработчиками.
UPD: В статью добавлены описания кодов ответов.
В аналогичных сервисах (например, Amazon S3) есть возможность быстро собрать и скачать несколько файлов в одном архиве — это удобно для автоматизации и экономит время при работе с большим количеством данных.
Робочий приклад авторизації і отримання вмісту кореневої папки сховища.
const CDN_URL = 'https://a1b2c3d4e5f6g7h8.cdn.express';
const CDN_USER = 'your-login';
const CDN_PASS = 'your-password';
function send_curl(string $method, array $fields, string $token = '') : array {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, CDN_URL . $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Storage-Token: ' . $token]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
function get_token() : string {
$curl = send_curl('/~/action/storage/auth/login/', ['username' => CDN_USER, 'password' => CDN_PASS]);
return $curl['callback']['token'];
}
$token = get_token();
$curl = send_curl('/~/action/storage/manage/ls/', ['path' => '/'], $token);
$list = $curl['callback'];
echo '<pre>';
print_r($list);
echo '</pre>';
Наостанок, кілька важливих моментів:
1. Тильду (~) в рядку команди - прибирати не можна (я подумав, що її треба замінити на адресу сховища).
$url_1 = 'https://a1b2c3d4e5f6g7h8.cdn.express/~/action/storage/auth/login/';; // правильно
$url_2 = 'https://a1b2c3d4e5f6g7h8.cdn.express/action/storage/auth/login/';; // неправильно
2. Сховище очікує вхідні дані в JSON форматі.
3. Доки ви ще не авториовані, $token - пустий рядок. Але при відправці пустого заголовка 'Storage-Token: ' - помилки немає.
Відповідно ми маємо один варіант CURLOPT_HTTPHEADER, незважаючи чи є токен, чи немає.