HTTP binding - openHAB 3 version

I think It‘s mostly ready. Some documentation is missing.

Hi Jan,
I now installed the binding and added a thing and a channel.
But I allways get an authentication error.
Old HTTP binding:

name.url=http://<username>:<password>@<IP>/sc2_val.xml
name.updateInterval=30000

No matter how I tried to enter the URL into the the thing, I get an authentication error:
- Full URL: http://<username>:<password>@<IP>/sc2_val.xml
or
- URL: http://<IP>/sc2_val.xml and username/password in the separate fields
or
- The same but just http://<IP>/ and the XML extension entered in the channel definitiont

Regards Joerg

BTW: I added 3 other HTTP things/channels without authentication without any issues

Strange thing ist, that the HTTP1 binding run in parallel with success.
So, authentication should not be necessary by HTTP2 binding when on the same server.
(tested with a simple request via browser)
Before I get the authentication error, I get the following warning (hope, that helps to nail it down)
2020-09-03 18:08:56.015 [WARN ] [p.internal.http.HttpResponseListener] - Requesting 'http://192.168.2.13/sc2_val.xml' (method='GET', content='null') failed: HttpConnectionOverHTTP@69f969::SocketChannelEndPoint@5f53ef{/192.168.2.13:80<->/192.168.2.2:64141,ISHUT,fill=-,flush=-,to=0/0}{io=0/0,kio=0,kro=1}->HttpConnectionOverHTTP@69f969(l:/192.168.2.2:64141 <-> r:/192.168.2.13:80,closed=false)=>HttpChannelOverHTTP@176d172(exchange=HttpExchange@676aac req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP@1d5faa2(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator@1e7015c{s=START}],recv=HttpReceiverOverHTTP@cbb313(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]

What kind of device is that?

A Solvis heating system

See: https://community.openhab.org/t/solved-solvis-heating/38966

Is it possible that you run into a timeout?

I don’t think so. HTTP1 runs in parallel without a timout and setting up the request via browser also works (fom the same client). Solvis answers within milliseconds via browser.
HTTP2 logs:
2020-09-04 12:53:33.016 [WARN ] [p.internal.http.HttpResponseListener] - Requesting 'http://192.168.2.13/sc2_val.xml' (method='GET', content='null') failed: Authorization error

If multiple channels use the same “state URL extension” are all these channels updated with a single request/response, or are they all checked separately?
Backgound of this question is, if it was better to add a channel for each value I request from a single JSON response and just have different transformation set between those channels, or to add a single channel for all these values and do the transformation on item-level.

From my understanding of the OH concept so far, a single channel per value would make more sense, but I don’t know if this would be the best option here performance-wise.

For example: for my OPNsense firewall different firmware stats are available under the same url ( https://<IP>/api/core/firmware/status), e.g. “product_version”, “last_update”, etc. Additionally, the reponse takes some time, so I’m not sure what would provide the best performance.

If they are in the same thing, the result is cached and re-used.

Ok. The problem seems to be that you require digest authentication while the binding currently only support basic authentication. I’ll try to provide a fix for that, but unfortunately I have no device where I could test that, So it might take some iterations and I need your support.

Jan,
thanks.
Sure, I’ll try to support.

Joerg

wouldn’t a VM with an apache installation and mod_auth_digest a way to test it ?

I have updated the link above. Please install that version. There is a new configuration option available, you might need to remove and re-add the thing. If you switch from “Basic Authentication” (which is the default) to “Digest Authentication” it should work,

Hi Jan,
I deleted channel, thing and jar and added all again.
Used new digest authetication and get a warning in log:

2020-09-06 10:28:03.806 [WARN ] [p.internal.http.HttpResponseListener] - Requesting 'http://192.168.2.13/sc2_val.xml' (method='GET', content='null') failed: HttpConnectionOverHTTP@7278f8::SocketChannelEndPoint@1fc343a{/192.168.2.13:80<->/192.168.2.2:64420,ISHUT,fill=-,flush=-,to=1/0}{io=0/0,kio=0,kro=1}->HttpConnectionOverHTTP@7278f8(l:/192.168.2.2:64420 <-> r:/192.168.2.13:80,closed=false)=>HttpChannelOverHTTP@1e338a3(exchange=HttpExchange@6d73f3 req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP@178efca(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator@1a3443b{s=START}],recv=HttpReceiverOverHTTP@197404c(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]

No data is written ito item :frowning:
Joerg

BTW: In the documentation of the Solvis Remote is mentioned, that the device uses basic authentication.
See: Solvis Remote Documnetation
Page 14

That’s very interesting since the curl-command in the linked thread requests digest authentication. Please set the binding to trace logging and show the actual response.

Hi Jan,
tracing shows just 2 lines:

2020-09-07 11:19:47.791 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Requesting refresh from 'http://192.168.2.13/sc2_val.xml' with timeout 3000ms
2020-09-07 11:19:47.792 [TRACE] [ttp.internal.http.RefreshingUrlCache] - Sending to 'http://192.168.2.13/sc2_val.xml': Method = {GET}, Headers = {Accept-Encoding: gzip, User-Agent: Jetty/9.4.20.v20190813}, Content = {null}

If there is nothing else, no response at all is received.

05:24:23.329 [TRACE] [http.internal.http.RefreshingUrlCache] - Requesting refresh (retry=false) from 'http://localhost:8088/digest-test/test.json' with timeout 3000ms
05:24:23.346 [TRACE] [http.internal.http.RefreshingUrlCache] - Sending to 'http://localhost:8088/digest-test/test.json': Method = {GET}, Headers = {Accept-Encoding: gzip, User-Agent: Jetty/9.4.20.v20190813}, Content = {null}
05:24:26.367 [TRACE] [tp.internal.http.HttpResponseListener] - Received from 'http://localhost:8088/digest-test/test.json': Code = {0}, Headers = {}, Content = {null}
05:24:26.367 [WARN ] [tp.internal.http.HttpResponseListener] - Requesting 'http://localhost:8088/digest-test/test.json' (method='GET', content='null') failed: Total timeout 3000 ms elapsed

This is my log when I run into a timeout (apache not running).

05:27:12.024 [TRACE] [http.internal.http.RefreshingUrlCache] - Requesting refresh (retry=false) from 'http://localhost:8088/digest-test/test.json' with timeout 3000ms
05:27:12.029 [TRACE] [http.internal.http.RefreshingUrlCache] - Sending to 'http://localhost:8088/digest-test/test.json': Method = {GET}, Headers = {Accept-Encoding: gzip, User-Agent: Jetty/9.4.20.v20190813}, Content = {null}
05:27:12.039 [TRACE] [tp.internal.http.HttpResponseListener] - Received from 'http://localhost:8088/digest-test/test.json': Code = {200}, Headers = {Date: Tue, 08 Sep 2020 03:27:10 GMT, Server: Apache/2.4.38 (Debian), Authentication-Info: rspauth="243705855adf72047d220683b61e24ec", cnonce="1b471f8c1ed54c25", nc=00000002, qop=auth, Last-Modified: Sat, 05 Sep 2020 16:14:06 GMT, ETag: "15-5ae934649cc01", Accept-Ranges: bytes, Content-Length: 21, Content-Type: application/json}, Content = {{
        "key" : "value"
}
}

This is how a successfull request looks like and

05:29:31.214 [TRACE] [http.internal.http.RefreshingUrlCache] - Requesting refresh (retry=false) from 'http://localhost:8088/digest-test/test.json' with timeout 3000ms
05:29:31.218 [TRACE] [http.internal.http.RefreshingUrlCache] - Sending to 'http://localhost:8088/digest-test/test.json': Method = {GET}, Headers = {Accept-Encoding: gzip, User-Agent: Jetty/9.4.20.v20190813}, Content = {null}
05:29:31.231 [TRACE] [tp.internal.http.HttpResponseListener] - Received from 'http://localhost:8088/digest-test/test.json': Code = {401}, Headers = {Date: Tue, 08 Sep 2020 03:29:31 GMT, Server: Apache/2.4.38 (Debian), WWW-Authenticate: Digest realm="private", nonce="Oil+8cSuBQA=1cded2677653cf767edf8ce1902d857adecd0ef2", algorithm=MD5, qop="auth", Content-Length: 458, Content-Type: text/html; charset=ISO-8859-1}, Content = {<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Unauthorized</title>
</head><body>
<h1>Unauthorized</h1>
<p>This server could not verify that you
are authorized to access the document
requested.  Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
<hr>
<address>Apache/2.4.38 (Debian) Server at localhost Port 8088</address>
</body></html>
}
05:29:31.245 [DEBUG] [tp.internal.http.HttpResponseListener] - Requesting 'http://localhost:8088/digest-test/test.json' (method='GET', content='null') failed: Authorization error

This how an authorization error (basic instead of digest authentication) looks like. I have no idea why you don’t receive anything.

And I still get this warning every 3 min:

2020-09-08 15:31:52.104 [WARN ] [p.internal.http.HttpResponseListener] - Requesting 'http://192.168.2.13/sc2_val.xml' (method='GET', content='null') failed: HttpConnectionOverHTTP@1fa0d50::SocketChannelEndPoint@10fafb4{/192.168.2.13:80<->/192.168.2.2:58695,ISHUT,fill=-,flush=-,to=0/0}{io=0/0,kio=0,kro=1}->HttpConnectionOverHTTP@1fa0d50(l:/192.168.2.2:58695 <-> r:/192.168.2.13:80,closed=false)=>HttpChannelOverHTTP@1923755(exchange=HttpExchange@11596a2 req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP@b4a215(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator@a8cd38{s=START}],recv=HttpReceiverOverHTTP@a065a7(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]