More information about filters can be found in the [filters](12-icinga2-api.md#icinga2-api-filters) chapter.
+Note that the permissions a API user has also specify the max body size of their requests.
+A API user with `*` permissions is allowed to send 512 MB.
+
+
Available permissions for specific URL endpoints:
- Permissions | URL Endpoint | Supports Filters
- ------------------------------|---------------|-----------------
- actions/<action> | /v1/actions | Yes
- config/query | /v1/config | No
- config/modify | /v1/config | No
- console | /v1/console | No
- events/<type> | /v1/events | No
- objects/query/<type> | /v1/objects | Yes
- objects/create/<type> | /v1/objects | No
- objects/modify/<type> | /v1/objects | Yes
- objects/delete/<type> | /v1/objects | Yes
- status/query | /v1/status | Yes
- templates/<type> | /v1/templates | Yes
- types | /v1/types | Yes
- variables | /v1/variables | Yes
+ Permissions | URL Endpoint | Supports Filters | Max Body Size in MB
+ ------------------------------|---------------|-------------------|---------------------
+ actions/<action> | /v1/actions | Yes | 1
+ config/query | /v1/config | No | 1
+ config/modify | /v1/config | No | 512
+ console | /v1/console | No | 512
+ events/<type> | /v1/events | No | 1
+ objects/query/<type> | /v1/objects | Yes | 1
+ objects/create/<type> | /v1/objects | No | 512
+ objects/modify/<type> | /v1/objects | Yes | 512
+ objects/delete/<type> | /v1/objects | Yes | 512
+ status/query | /v1/status | Yes | 1
+ templates/<type> | /v1/templates | Yes | 1
+ types | /v1/types | Yes | 1
+ variables | /v1/variables | Yes | 1
The required actions or types can be replaced by using a wildcard match ("\*").
return nullptr;
}
-ApiUser::Ptr ApiUser::GetByAuthHeader(const String& auth_header) {
+ApiUser::Ptr ApiUser::GetByAuthHeader(const String& auth_header)
+{
String::SizeType pos = auth_header.FindFirstOf(" ");
String username, password;
bool HttpServerConnection::ProcessMessage()
{
+
bool res;
HttpResponse response(m_Stream, m_CurrentRequest);
bool HttpServerConnection::ManageHeaders(HttpResponse& response)
{
+ static const size_t defaultContentLengthLimit = 1 * 1028 * 1028;
+ static const Dictionary::Ptr specialContentLengthLimits = new Dictionary({
+ {"*", 512 * 1028 * 1028},
+ {"config/modify", 512 * 1028 * 1028},
+ {"console", 512 * 1028 * 1028},
+ {"objects/create", 512 * 1028 * 1028},
+ {"objects/modify", 512 * 1028 * 1028},
+ {"objects/delete", 512 * 1028 * 1028}
+ });
+
if (m_CurrentRequest.Headers->Get("expect") == "100-continue") {
String continueResponse = "HTTP/1.1 100 Continue\r\n\r\n";
m_Stream->Write(continueResponse.CStr(), continueResponse.GetLength());
return false;
}
+ size_t maxSize = defaultContentLengthLimit;
+
+ Array::Ptr permissions = m_AuthenticatedUser->GetPermissions();
+ ObjectLock olock(permissions);
+
+ for (const Value& permission : permissions) {
+ std::vector<String> permissionParts = String(permission).Split("/");
+ String permissionPath = permissionParts[0] + (permissionParts.size() > 1 ? "/" + permissionParts[1] : "");
+ int size = specialContentLengthLimits->Get(permissionPath);
+ maxSize = size > maxSize ? size : maxSize;
+ }
+
+ size_t contentLength = m_CurrentRequest.Headers->Get("content-length");
+
+ if (contentLength > maxSize) {
+ response.SetStatus(400, "Bad Request");
+ String msg = String("<h1>Content length exceeded maximum</h1>");
+ response.WriteBody(msg.CStr(), msg.GetLength());
+ response.Finish();
+
+ return false;
+ }
+
return true;
}