You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
1.6KB

  1. #' Make a POST DoH Request (wireformat)
  2. #'
  3. #' Issue the query of type `type` for `name` to the DoH endpoint specified at `server_path`.
  4. #'
  5. #' @param name name to query for
  6. #' @param type DNS query type (defaults to "`A`")
  7. #' @param server_path full URL path to the DoH server quer endpoint (defaults to Quad9).
  8. #' @return `NULL` (if the query failed) or a `data.frame` (tibble)
  9. #' @export
  10. doh_post <- function(name, type = "A", server_path = "https://dns.quad9.net/dns-query") {
  11. # for now, use python's {dnslib} as a crutch to
  12. # encode/decode wireformat DNS questions and answers
  13. .dns$DNSRecord$question(
  14. qname = tolower(name[1]),
  15. qtype = toupper(type[1]),
  16. qclass = "IN"
  17. ) -> q
  18. qpak <- q$pack()
  19. # now, send it off to the server
  20. httr::POST(
  21. url = server_path[1],
  22. httr::add_headers(
  23. `Content-Type` = "application/dns-message",
  24. `Accept` = "application/dns-message"
  25. ),
  26. encode = "raw",
  27. body = qpak
  28. ) -> res
  29. httr::warn_for_status(res)
  30. # if the response is OK, make it a data frame
  31. if (httr::status_code(res) == 200) {
  32. r <- .dns$DNSRecord$parse(httr::content(res))
  33. q <- r$get_q()
  34. do.call(
  35. rbind.data.frame,
  36. lapply(r$rr, function(.x) {
  37. data.frame(
  38. query = py_str(q$qname),
  39. qtype = q$qtype,
  40. rname = py_str(.x$rname),
  41. rtype = .x$rtype,
  42. rdata = py_str(.x$rdata),
  43. ttl = .x$ttl,
  44. stringsAsFactors = FALSE
  45. )
  46. })
  47. ) -> xdf
  48. class(xdf) <- c("tbl_df", "tbl", "data.frame")
  49. xdf
  50. } else {
  51. NULL
  52. }
  53. }