icinga2 icon indicating copy to clipboard operation
icinga2 copied to clipboard

Clarify Request Method Override Documentation

Open oxzi opened this issue 1 year ago • 3 comments

The documentation stated that HTTP GET requests are not allowed to carry content (formerly known as payload) within a request body. While this was mostly correct during RFC 2616 (1999) times, this changed with RFC 7231 (2014) and the latest RFC 9110 (2022) ^0.

As I am currently using Request Method Overriding and had an offline discussion about this, I did some research and, following this, rephrased the documentation. The new spin now indicates that sending content within a direct GET request to the Icinga 2 API is possible, but with regard to middle boxes, Request Method Overriding should be performed anyway.

oxzi avatar Jan 05 '24 14:01 oxzi

Actually, a GET request with a payload may not be used like any other usual GET request without a request body. Meaning, if you want to send a payload with a GET request, you must also explicitly set the request method and accept header, otherwise Icinga 2 will simply reject that request.

  1. curl -ksu root:icinga 'https://localhost:5665/v1/objects/hosts/dummy-5' is a valid GET request, but ...
  2. curl -ksu root:icinga 'https://localhost:5665/v1/objects/hosts' -d '{"filter": "host.name==\"dummy-5\"", "pretty": true}' is not. <h1>Accept header is missing or not set to 'application/json'.</h1>%
  3. curl -ksu root:icinga -H 'Accept: application/json' 'https://localhost:5665/v1/objects/hosts' -d '{"filter": "host.name==\"dummy-5\"", "pretty": true}' is still not a valid request.
     {
          "error": 400,
          "status": "Missing both 'attrs' and 'restore_attrs'. Or is this a POST query and you missed adding a 'X-HTTP-Method-Override: GET' header?"
     }
    

The only working GET request with a payload is this one, which is way to complex compared to the first request.

 curl -ksu root:icinga -H 'Accept: application/json' 'https://localhost:5665/v1/objects/hosts' -X GET -d '{"filter": "host.name==\"dummy-5\"", "pretty": true}'

yhabteab avatar May 06 '24 15:05 yhabteab

I think there might be some confusion due to two behaviors:

  • Passing -d/--data implicitly sets the request method to POST
  • Icinga 2 does not require Accept: application/json for GET requests like it does for other requests, even though it responds with JSON in both cases.

The following curl call also works:

curl -ksu root:icinga 'https://localhost:5665/v1/objects/hosts' \
    -X GET \
    -d '{"filter": "host.name==\"dummy-5\"", "pretty": true}'

julianbrost avatar May 07 '24 08:05 julianbrost

The following curl call also works:

curl -ksu root:icinga 'https://localhost:5665/v1/objects/hosts' \
    -X GET \
    -d '{"filter": "host.name==\"dummy-5\"", "pretty": true}'

Yes, it works on the Icinga 2 API, but is not really RFC-compliant as I wrote in this PR's change.

Honestly, I don't even know why I created this change back then. I guess, I wrote this because I was unsure why the X-HTTP-Method-Override: GET header was set and I found no satisfying explanation in the manual.

oxzi avatar May 08 '24 09:05 oxzi