sendHttpPostRequest fails with HTTP protocol violation

  • Platform information:
    • Hardware: Raspberry Pi 4, 4 GB RAM
    • OS: Openhabian
    • Java Runtime Environment: 11
    • openHAB version:3.0.1
  • Issue of the topic:

I’m trying to POST from a rule to the locally installed grafana to add annotations like described here:

val grafanaUrl = "http://192.168.x.y:3000/api/annotations"
val grafanaHeaders = newHashMap("Authorization" -> "Bearer <mybearertoken>")

    val String json = '{
        "tags":["shower_ff"],
        "text":"Duschbereich betreten"
    }'
    sendHttpPostRequest(grafanaUrl, "application/json", json, grafanaHeaders, 2000)

For me it’s failing on POST with

2021-06-20 13:20:21.369 [ERROR] [enhab.core.model.script.actions.HTTP] - Fatal transport error: java.util.concurrent.ExecutionException: org.eclipse.jetty.client.HttpResponseException: HTTP protocol violation: Authentication challenge without WWW-Authenticate header

I already tried with basic auth credentials as well like in the tutorial, but with the same effect.
I also could successfully POST the same thing manually via curl without any issue.
It seems I’m missing something here…

1 Like

Just a ping for a similar problem:
I faced some similar problems while trying to use the openHAB Rest api via a rule with a put request.
(Task: Deactivating a thing via rule)

But it was nearly before holidays and i was not able to break it down to something yet.
Therefore i may find an answer here too aside. :slight_smile:

Your error message says

Authentication challenge without WWW-Authenticate header

Maybe you need to add your user and password in the URL?!

I have not updated to openHAB 3, yet.
So it might be possible the http-Binding has changed and my commands do not work anymore.

I had a similar issue.

I had to change mine:

FROM
val headers = newHashMap("Authorization" -> "oh.TOKEN.myToken")

TO
val headers = newHashMap("WWW-Authenticate" -> "oh.TOKEN.myToken")

Now it works again

For calls to OH REST API could understand it - since I read somewhere that you have to activate basic auth in the settings for OH3. But for me it’s not OH I’m connecting to, so I’m somehow lost here what might causing this. Maybe I will create a github issue. But where is sendHttpPostRequest coming from? Is it using the HTTP Binding or something from core?

You wrote that you use the code

That should be the place where it is coming from.

The error message that you get says that the flow as described here HTTP authentication - HTTP | MDN is violated.

sendHttpPostRequest is available without installing the http binding. I think it belongs to core jetty.
How is your grafana configured could it be that it does not require user authentication but anonymous access ?

hehe, yeah I meant who is actually providing that method under the hood. An addon or something in core :).
But you answered that already, thanks!

How is your grafana configured could it be that it does not require user authentication but anonymous access ?

As I mentioned, it works properly with curl. If I leave out the auth (either basic auth or bearer token), grafana returns

{"message":"Access denied to this dashboard"}

If I provide credentials, it properly returns

{"id":2,"message":"Annotation added"}

So it has something todo with the specifics of sendHttpPostRequest I guess.

Ok, found the issue - it’s in front of the computer :man_facepalming:. Dumb copy/paste error of the API token. It seems this is the way it tells it got a 401. Case closed, thanks guys!

1 Like

This is http traffic so the easiest to find it out would be to use a network sniffer like wireshark.
Do a network trace of your curl request.
Do a network trace of the sendHttpPostRequest.
In wireshark you then can follow the complete communication between your client and grafanas reply.
You will see the HTTP headers and can check if a header is missing or if completely different headers are used.
In the company I am working for I used this approach to reverse engineer a windows exe that is being used to query a SOAP web service but I wanted to have a command line tool in the linux environment.
With wireshark I analyzed the network traffic of the windows tool and then rebuild the queries using perl.
This works for HTTP traffice but is more complicated for HTTPS traffic.