So I'm still having issues with my DoH implementation—this time it's Firefox complaining about not finding a server. I modified the script to log the request and response and as far as I could tell, the addresses were being resolved. It's just that Firefox was refusing to use the given answers. And trying to find an answer to “firefox server not found” is a futile exercise these days, giving me years old answers to issues that weren't quite what I was experiencing.
It's all very annoying.
But in looking over the script, again, I had a small epiphany.
local function output(status,data) if not data then io.stdout:write(string.format([[ Status: %d Content-Length: 0 ]],status)) else io.stdout:write(string.format([[ Status: %d Content-Type: application/dns-message Content-Length: %d %s]],status,#data,data)) end end
The code is running on Unix. By default, the “end-of-line” marker is just a line feed character. But the HTTP specification requires both a line feed and a carriage return character to mark the “end-of-line.” Given that the script works most of the time, I thought Self, perhaps there's a different codepath that is a bit more pedantic about the HTTP specification these particular sites hit for whatever reason. I changed the code:
local function output(status,data) if not data then io.stdout:write( string.format("Status: %d\r\n",status), "Content-Length: 0\r\n", "\r\n" ) else io.stdout:write( string.format("Status: %d\r\n",status), "Content-Type: application/dns-message\r\n", string.format("Content-Length: %d\r\n",#data), "\r\n", data ) end end
And immediately, the sites I was having problems with started loading reliably in Firefox. Hopefully, this is the last bug with this service …