Reputation: 9851
I have a Cloudflare (CF) worker that I want to have make a few DNS requests using the CF DNS (https://developers.cloudflare.com/1.1.1.1/dns-over-https/json-format/).
So a pretty basic worker:
/**
* readRequestBody reads in the incoming request body
* Use await readRequestBody(..) in an async function to get the string
* @param {Request} request the incoming request to read from
*/
async function readRequestBody(request) {
const { headers } = request
const contentType = headers.get('content-type')
if (contentType.includes('application/json')) {
const body = await request.json()
return JSON.stringify(body)
}
return ''
}
/**
* Respond to the request
* @param {Request} request
*/
async function handleRequest(request) {
let reqBody = await readRequestBody(request)
var jsonTlds = JSON.parse(reqBody);
const fetchInit = {
method: 'GET',
}
let promises = []
for (const tld of jsonTlds.tlds) {
//Dummy request until I can work out why I am not getting the response of the DNS query
var requestStr = 'https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=example.com&type=A'
let promise = fetch(requestStr, fetchInit)
promises.push(promise)
}
try {
let results = await Promise.all(promises)
return new Response(JSON.stringify(results), {status: 200})
} catch(err) {
return new Response(JSON.stringify(err), {status: 500})
}
}
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
I have just hardcoded the DNS query at the moment to:
https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=example.com&type=A
and I would expect that the JSON result I would get is:
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [
{
"name": "example.com.",
"type": 1
}
],
"Answer": [
{
"name": "example.com.",
"type": 1,
"TTL": 9540,
"data": "93.184.216.34"
}
]
}
however instead in results I get what appears to be the outcome of the websocket established as part of the fetch() (assuming I go around the loop once)
[
{
"webSocket": null,
"url": "https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=example.com&type=A",
"redirected": false,
"ok": true,
"headers": {},
"statusText": "OK",
"status": 200,
"bodyUsed": false,
"body": {
"locked": false
}
}
]
So my question is, what am I doing wrong here such that I am not getting the DNS JSON response from the 1.1.1.1 API?
Upvotes: 0
Views: 1064
Reputation: 45151
fetch()
returns a promise for a Response
object, which contains the response status, headers, and the body stream. This object is what you're seeing in your "results". In order to read the response body, you must make further calls.
Try defining a function like this:
async function fetchJsonBody(req, init) {
let response = await fetch(req, init);
if (!response.ok()) {
// Did not return status 200; throw an error.
throw new Error(response.status + " " + response.statusText);
}
// OK, now we can read the body and parse it as JSON.
return await response.json();
}
Now you can change:
let promise = fetch(requestStr, fetchInit)
to:
let promise = fetchJsonBody(requestStr, fetchInit)
Upvotes: 2