Community discussions

MikroTik App
 
istooi
just joined
Topic Author
Posts: 24
Joined: Thu Feb 27, 2014 1:18 pm

REST API problems

Tue Feb 22, 2022 4:35 pm

Hi,

i hope someone can help me with a problem regarding the REST API

The REST API does work with curl, but for some reason a device has problems and i don't know why.
I'm not even sure who's fault it is, but i suspect the device, not the router.

Since i have not found a useful log for this (not even debug outputs anything), i did setup a docker container (mendhak/http-https-echo) to compare both requests.

The first request is with curl from a ubuntu VM and the second request is from the mentioned device.
First request disables the firewall rule. Second request does nothing.

----------------------------------
Works:

{
"path": "/rest/ip/firewall/filter/disable",
"headers": {
"host": "xxx.xxx.xxx.xxx:8443",
"authorization": "Basic xxx",
"user-agent": "curl/7.68.0",
"accept": "*/*",
"content-type": "application/json",
"content-length": "16"
},
"method": "POST",
"body": "{\"numbers\": \"1\"}",
"fresh": false,
"hostname": "xxx.xxx.xxx.xxx",
"ip": "::ffff:xxx.xxx.xxx.xxx",
"ips": [],
"protocol": "https",
"query": {},
"subdomains": [],
"xhr": false,
"os": {
"hostname": "http-req-debugger"
},
"connection": {
"servername": false
},
"json": {
"numbers": "1"
}
}
::ffff:xxx.xxx.xxx.xxx - xxx [22/Feb/2022:14:12:52 +0000] "POST /rest/ip/firewall/filter/disable HTTP/1.1" 200 623 "-" "curl/7.68.0"

-------------------------------------------------------
Does not work:

{
"path": "/rest/ip/firewall/filter/enable",
"headers": {
"host": "xxx.xxx.xxx.xxx:8443",
"user-agent": "[en]",
"content-length": "15",
"content-type": "application/json; charset=utf-8",
"connection": "close",
"authorization": "Basic xxx"
},
"method": "POST",
"body": "{\"numbers\":\"1\"}",
"fresh": false,
"hostname": "xxx.xxx.xxx.xxx",
"ip": "::ffff:xxx.xxx.xxx.xxx",
"ips": [],
"protocol": "https",
"query": {},
"subdomains": [],
"xhr": false,
"os": {
"hostname": "http-req-debugger"
},
"connection": {
"servername": false
},
"json": {
"numbers": "1"
}
}
::ffff:xxx.xxx.xxx.xxx - xxx [22/Feb/2022:14:15:24 +0000] "POST /rest/ip/firewall/filter/enable HTTP/1.1" 200 635 "-" "[en]"


-------------------------------------------------
I used the same SSL certificate for the debugging container and the router.
Later i generated a new one with 2048 key length instead of 4096 (in case that's the problem) but that didn't help either.
 
istooi
just joined
Topic Author
Posts: 24
Joined: Thu Feb 27, 2014 1:18 pm

Re: REST API problems

Thu Feb 24, 2022 4:16 pm

Hello,

i think i found the Problem

The device has default values for the content-type ("content-type": "text/plain; charset=utf-8",) which can only be overwritten but not removed.
So by defining "content-type": "application/json", it will result in "content-type": "application/json; charset=utf-8", which leads to the Error:
{"error":415,"message":"Unsupported Media Type"}

This can be reproduced with cURL:
curl -s -k -u xxx:xxx -X POST https://xxx.xxx.xxx.xxx/rest/ip/firewall/filter/disable --data "{\"numbers\": \"1\"}" -H "content-type: application/json; charset=urf-8"

Other charsets like ISO-8859-1 didn't work either. Can i overwrite it with a value that works or will any charset definition break the API?
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3169
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: REST API problems

Thu Feb 24, 2022 5:00 pm

This can be reproduced with cURL:
curl -s -k -u xxx:xxx -X POST https://xxx.xxx.xxx.xxx/rest/ip/firewall/filter/disable --data "{\"numbers\": \"1\"}" -H "content-type: application/json; charset=urf-8"

Other charsets like ISO-8859-1 didn't work either. Can i overwrite it with a value that works or will any charset definition break the API?
You can just leave off a charset. In your example "urf-8" would be in fact "unsupported", maybe "utf-8" might. But Mikrotik's curl examples just use a -H "content-type: application/json", I suspect it's always UTF-8 without doing anything.

You can also try a tool like https://www.postman.com to test various HTTP/JSON options instead of `curl`, might be more user friendly for you. From Postman, it has an option for the right `curl` command line for the operation.
 
istooi
just joined
Topic Author
Posts: 24
Joined: Thu Feb 27, 2014 1:18 pm

Re: REST API problems

Fri Feb 25, 2022 9:59 am

This can be reproduced with cURL:
curl -s -k -u xxx:xxx -X POST https://xxx.xxx.xxx.xxx/rest/ip/firewall/filter/disable --data "{\"numbers\": \"1\"}" -H "content-type: application/json; charset=urf-8"

Other charsets like ISO-8859-1 didn't work either. Can i overwrite it with a value that works or will any charset definition break the API?
You can just leave off a charset. In your example "urf-8" would be in fact "unsupported", maybe "utf-8" might. But Mikrotik's curl examples just use a -H "content-type: application/json", I suspect it's always UTF-8 without doing anything.

You can also try a tool like https://www.postman.com to test various HTTP/JSON options instead of `curl`, might be more user friendly for you. From Postman, it has an option for the right `curl` command line for the operation.
Hi,
You can just leave off a charset.
Unfortunately i can't prevent the device from just adding a charset. I can only change it and add new headers.
You can also try a tool like https://www.postman.com to test various HTTP/JSON options instead of `curl`, might be more user friendly for you. From Postman, it has an option for the right `curl` command line for the operation.
To "bruteforce" a working value for charset?
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3169
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: REST API problems

Fri Feb 25, 2022 6:32 pm


Unfortunately i can't prevent the device from just adding a charset. I can only change it and add new headers.

Yeah it seems the Mikrotik is looking for exactly "application/json" as the "Content-Type:", just confirm that myself.

I'd recommend filing a bug report at help.mikrotik.com. It really should at least ignore the charset, since I'd imagine a lot of library automatically include "application/json; charset=utf-8" like yours. From stuff like curl, NodeJS or Python, can deal with it. Mikrotik is ignoring the HTTP/1.1 spec here – it needs to accept at least one charset.

This can be reproduced on a Mikrotik with HTTPS enabled using /tool/fetch to localhost even. I call a function to do a /tool/fetch with different Content-Types, which test the problem locally on a Mikrotik.

# you need a Mikrotik user/password to call REST
:global user CHANGE_ME
:global password CHANGE_ME

# "$fetchrest function, it takes a type= in $type to control the Content-Type: used in this test
:global fetchrest do={/tool/fetch url=https://localhost/rest/ip/firewall/layer7-protocol http-header-field="Content-Type: $type" http-method=put http-data="{\"name\": \"rest-put-charset-$[:timestamp]\", \"regexp\": \"test\"}" user=$user password="$password"}

# above rest call adds a layer7-protocol – which are ignored if not used, so safe to add something to them
Which shows the "Content-Type: application/json; charset=XXXX" bug:
# setting no charset works...

$fetchrest type="application/json"

#       status: finished
#   downloaded: 0KiBC-z pause]
#        total: 0KiB
#     duration: 1s

$fetchrest type="application/json;charset=utf-8"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

$fetchrest type="application/json; charset=utf-8"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

$fetchrest type="application/json; charset=utf-16"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

$fetchrest type="application/json; charset=iso-8859-1"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

$fetchrest type="application/json; charset=iso-8859-2"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

$fetchrest type="application/json; charset=ISO-8859-1"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

$fetchrest type="application/json; charset=ISO-8859-2"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

$fetchrest type="application/json; charset=us-ascii"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

$fetchrest type="application/json;charset=us-ascii"
#   status: failed
# failure: closing connection: <415 Unsupported Media Type> 127.0.0.1:443 (5)

Thus, why I think it's doing an EXACT match on "application/json" since anything else in content-type will get the HTTP 415 error code. Good luck.
 
istooi
just joined
Topic Author
Posts: 24
Joined: Thu Feb 27, 2014 1:18 pm

Re: REST API problems

Mon Feb 28, 2022 6:11 pm


Unfortunately i can't prevent the device from just adding a charset. I can only change it and add new headers.

Yeah it seems the Mikrotik is looking for exactly "application/json" as the "Content-Type:", just confirm that myself. ...
Thx for your work. I will file a bugreport.
 
istooi
just joined
Topic Author
Posts: 24
Joined: Thu Feb 27, 2014 1:18 pm

Re: REST API problems

Thu Mar 03, 2022 10:31 am

FYI

according to the Support, Mikrotik will fix this issue.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3169
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: REST API problems

Wed Mar 23, 2022 5:38 pm

according to the Support, Mikrotik will fix this issue.
See here: viewtopic.php?t=184351
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3169
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: REST API problems

Tue Aug 29, 2023 6:21 pm

Agree the backend logging could be improved. Logging isn't great in general, beyond just REST, is bigger issue. On the client side, the REST API does return an HTTP error code and short message, and that part seem reasonable. .

My guess converting CLI-syntax into REST is where most troubles lie... since that isn't always straightforward – but better log may not help much there (e.g. RouterOS doesn't know why the syntax isn't working as you expect) ;)

For some issues like certs/content-type/etc or connection issues.... Recent V7 release, allow REST over plain HTTP (e.g. not just HTTPS). While not ideal for production, it does allow sniffer to see the traffic & helpful for debugging.

Who is online

Users browsing this forum: GoogleOther [Bot] and 15 guests