Usage
The File Inspection Engine starts in approximately 4 seconds, assuming that the static analysis engine initializes successfully and the license is valid. You can confirm that the application is ready by checking if the readiness endpoint returns 200 OK
.
When starting for the first time, the application needs to download threat data. This process may take some time, and the application will only become fully usable once the threat data download is complete, regardless of the messages displayed.
If the static analysis engine fails to initialize, the application will exit. For all other errors, logs will be generated, and the application will continue to run.
File Submissions
POST /scan
To scan a file, make a POST request to http://<host>:<port>/scan
, with the file contents as the raw request body.
- You don’t need to set the
Content-Type
header. If set, it will be included alongside every log message related to that submission. - It is recommended to set the
Content-Length
header to prevent files larger than the maximum upload size from partially uploading before getting rejected. - Optionally, you can provide an
external_id
query string parameter that will also be included alongside log messages related to the submission. This parameter can contain any value meaningful to the client application, such as a file name, database ID, or other identifying information.
Examples using curl
Example request:
curl -X POST --upload-file example.docx http://<host>:<port>/scan
Example response:
{
"classification": "OK",
"message": "",
"errors": []
}
Classification: The classification
string will be either "OK"
or "malicious"
.
If paranoid mode is turned on, the classification could also be "suspicious"
.
If with-threat-details
and add-file-type
options are enabled, the response may look like:
{
"classification": "malicious",
"message": "",
"errors": [],
"threat_details": {
"platform": "Script",
"type": "Trojan",
"threat_name": "Script-JS.Trojan.Redirector"
},
"file_type": "Text"
}
Logging:
The following example provides Content-Type
and a custom external ID in the request, both of which can be visible in application logs:
curl -v -X POST -H 'Content-Type: application/x-tar' --upload-file archive.tar 'http://localhost:8000/scan?external_id=my%20external%20id'
Log example:
This request would create the following log entry, including the external ID:
{
"level": "info",
"request_id": "21e7262b-28a0-43a0-be4e-a6f0a5d897a3",
"external_id": "my external id",
"content_type": "application/x-tar",
"component": "http.api",
"request_path": "/scan",
"content_length": 244244480,
"active_concurrency": 1,
"time": "2024-11-27T13:41:52.593520919+01:00",
"message": "Upload started"
}
Error handling
If there are any errors, they will be returned in the message
field (deprecated), as well as the errors
field. The message
field will contain the same errors as the errors
array, only it will be a semicolon-concatenated string. For example:
{
"message": "error one; error two; error three",
"errors": ["error one", "error two", "error three"]
}
In some cases, certain errors are expected, and are converted to additional properties inside analysis_information
. For example, if a file hits the decompression factor limit, this error will be logged in errors
and message
, but also present in analysis_information.partial_unpacking
.
{
"errors": ["Exceeds decompression ratio."],
"message": "Exceeds decompression ratio.",
"analysis_information": {
"partial_unpacking": true
}
}
Response Status Codes
The errors
and message
fields may contain soft errors (e.g., failing to get detailed threat information from the cloud), but are often empty. Hard errors will be returned as HTTP status 500 Internal Server Error
.
Code | Description | Message |
---|---|---|
200 | The request has succeeded. | N/A |
400 | File size error. | {"error": "Maximum upload file size in bytes is {configured_value}" } |
429 | Concurrency limit reached. | {"error": "The concurrent analysis limit has been reached"} |
524 | A timeout occurred. | {"error": "The analysis could not be completed within the configured maximum analysis time"} |
Timeouts
If timeouts are configured for uploads, they apply to all processing after the upload is complete.
Analyses may fail due to one of two reasons:
-
Complex file: The file is too complex and it will never be analyzed within the configured time limit, even when the server is idle. Waiting and trying again will not help.
-
Server load: The file is a bit more complex relative to the current load on the server. If the server were less busy, it might be possible to process it within the configured time limit. Waiting and trying again might help.
Check Application Liveness
curl http://<host>:<port>/livez
To verify that the File Inspection Engine is running, use the /livez
endpoint. It responds with an HTTP 200 OK
status if the application is operational. This endpoint is intended for integration with Kubernetes liveness probes to ensure the service remains healthy.
Check Application Readiness
curl http://<host>:<port>/readyz
The /readyz
endpoint checks the application's readiness to serve traffic. If all checks pass, it returns an HTTP 200 OK
status with no errors. If any check fails, it returns a 4xx
or 5xx
status code with an error message.
Check Application Version / License / Configuration
GET /status
To check the File Inspection Engine version, license expiration date, threat data timestamp, and configuration, use the /status
endpoint.
The config
section contains all the configurable options and their current values. Values containing sensitive information are redacted.
curl http://<host>:<port>/status
{
"config": {
"add_file_type": "disabled",
"cloud_update_interval": "5m0s",
"cloud_updates": true,
"concurrency_limit": 20,
"http_address": ":8000",
"log_json": true,
"max_decompression_factor": 1,
"max_upload_file_size": 100,
"paranoid_mode": false,
"proxy_address": "http://user:xxxxx@proxy.company.lan",
"timeout": "0s",
"unpacking_depth": 17,
"with_threat_details": false
},
"license": {
"valid_until": "2025-06-01"
},
"version": {
"application": "1.2.0",
"threat_data": "2025-02-26T17:44:50Z"
}
}