Finally, I found the solution. It turns out that the authentication scheme accepted by the server (a builtin server I can not configure) was not Basic but rather Digest! Added the --anyauth solved the problem. Posting it here in case it is helpful to others:
curl --user username:password --anyauth -H Content-Type:application/json -H accept:application/json --trace-ascii curlTest.log “your URL, in my case http://192.168.39.21/api/v1/production/inverters/”
The resulting output is:
== Info: Trying 192.168.39.21…
== Info: TCP_NODELAY set
== Info: Connected to 192.168.39.21 (192.168.39.21) port 80 (#0)
=> Send header, 149 bytes (0x95)
0000: GET /api/v1/production/inverters/ HTTP/1.1
002c: Host: 192.168.39.21
0042: User-Agent: curl/7.52.1
005b: Content-Type:application/json
007a: accept:application/json
0093:
<= Recv header, 27 bytes (0x1b)
0000: HTTP/1.1 401 Unauthorized
<= Recv header, 37 bytes (0x25)
0000: Date: Sat, 27 Jul 2019 00:09:47 GMT
<= Recv header, 84 bytes (0x54)
0000: WWW-Authenticate: Digest qop=“auth”, realm=“enphaseenergy.com”,
0040: nonce=“1564186186”
<= Recv header, 32 bytes (0x20)
0000: Content-Type: application/json
<= Recv header, 20 bytes (0x14)
0000: Content-Length: 90
<= Recv header, 2 bytes (0x2)
0000:
== Info: Ignoring the response-body
<= Recv data, 90 bytes (0x5a)
0000: {. “status”: 401,. “error”: “”,. “info”: “Authentication requ
0040: ired”,. “moreInfo”: “”.}.
== Info: Curl_http_done: called premature == 0
== Info: Connection #0 to host 192.168.39.21 left intact
== Info: Issue another request to this URL: ‘http://192.168.39.21/api/v1/production/inverters/’
== Info: Found bundle for host 192.168.39.21: 0xc69568 [can pipeline]
== Info: Connection 0 seems to be dead!
== Info: Closing connection 0
== Info: Hostname 192.168.39.21 was found in DNS cache
== Info: Trying 192.168.39.21…
== Info: TCP_NODELAY set
== Info: Connected to 192.168.39.21 (192.168.39.21) port 80 (#1)
== Info: Server auth using Digest with user ‘username’
=> Send header, 400 bytes (0x190)
0000: GET /api/v1/production/inverters/ HTTP/1.1
002c: Host: 192.168.39.21
0042: Authorization: Digest username=“username”, realm=“enphaseenergy
0082: .com”, nonce=“1564186186”, uri="/api/v1/production/inverters/",
00c2: cnonce=“N2VjYTE3NGM5NTE3NJ78c504f27e238ff9287bcc374db9609ecd”
013d: User-Agent: curl/7.52.1
0156: Content-Type:application/json
0175: accept:application/json
018e:
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 37 bytes (0x25)
0000: Date: Sat, 27 Jul 2019 00:09:47 GMT
<= Recv header, 32 bytes (0x20)
0000: Content-Type: application/json
<= Recv header, 22 bytes (0x16)
0000: Content-Length: 2757
<= Recv header, 2 bytes (0x2)
0000:
<= Recv data, 2757 bytes (0xac5)
0000: [. {. “serialNumber”: “121412031054”,. “lastReportDate”:
0040: 1564169396,. “lastReportWatts”: 1,. “maxReportWatts”: 193.
0080: },. {. “serialNumber”: “121412031017”,. "lastReportDate
00c0: ": 1564170304,. “lastReportWatts”: 0,. “maxReportWatts”: 1
0100: 91. },. {. “serialNumber”: “121412030724”,. “lastReportD
0140: ate”: 1564169393,. “lastReportWatts”: 0,. “maxReportWatts”
0180: : 195. },. {. “serialNumber”: “121412031058”,. “lastRepo
01c0: rtDate”: 1564169397,. “lastReportWatts”: 1,. "maxReportWat
…and a bunch of JSON data…
0a40: . {. “serialNumber”: “121412035391”,. “lastReportDate”: 1
0a80: 564164879,. “lastReportWatts”: 5,. “maxReportWatts”: 177.
0ac0: }.].
== Info: Curl_http_done: called premature == 0
== Info: Connection #1 to host 192.168.39.21 left intact
Note that the --trace-ascii curlTest.log
option is not needed. Interestingly, the --anyauth option was mentioned by CASio in the original question but was lost in the discussion that followed.
Just to add the context in case someone is searching for a solution for this specific problem, this is for polling my solar array with an Enphase/Envoy central unit for production data. The end goal is to create an alternative to the existing Envoy binding ([New Binding] Enphase Envoy Solar System gateway) that unfortunately has a username and password combination hardcoded.
Best /Brus-Per