mirror of https://gitlab.com/hrbrmstr/playdoh.git
boB Rudis
5 years ago
13 changed files with 215 additions and 174 deletions
@ -1,6 +1,6 @@ |
|||||
# Generated by roxygen2: do not edit by hand |
# Generated by roxygen2: do not edit by hand |
||||
|
|
||||
export(doh_post) |
export(doh_get) |
||||
|
export(doh_servers) |
||||
import(httr) |
import(httr) |
||||
import(reticulate) |
|
||||
importFrom(jsonlite,fromJSON) |
importFrom(jsonlite,fromJSON) |
||||
|
@ -0,0 +1,7 @@ |
|||||
|
httr::user_agent( |
||||
|
sprintf( |
||||
|
"playdoh package v%s: (<%s>)", |
||||
|
utils::packageVersion("playdoh"), |
||||
|
utils::packageDescription("playdoh")$URL |
||||
|
) |
||||
|
) -> .PLAYDOH_UA |
@ -0,0 +1,51 @@ |
|||||
|
#' Make a DoH Request (GET/REST) |
||||
|
#' |
||||
|
#' Issue a `GET` REST API query of type `type` for `name` to the |
||||
|
#' DoH endpoint specified at `server_path`. |
||||
|
#' |
||||
|
#' @param name name to query for |
||||
|
#' @param type DNS query type (defaults to "`A`") |
||||
|
#' @param server_path full URL path to the DoH server quer endpoint (defaults to Quad9). |
||||
|
#' @param extra_params any special `GET` query parameter needed for a given server API endpoint. |
||||
|
#' this should be a named `list`. |
||||
|
#' @return `NULL` (if the query failed) or a `data.frame` (tibble) |
||||
|
#' @references <https://tools.ietf.org/id/draft-ietf-doh-dns-over-https-05.html> |
||||
|
#' @export |
||||
|
#' @examples |
||||
|
#' doh_get("rud.is", "A") |
||||
|
doh_get <- function(name, type = "a", extra_params = list(), service_path = "https://9.9.9.9/dns-query") { |
||||
|
|
||||
|
stopifnot(is.list(extra_params)) |
||||
|
|
||||
|
extra_params[["name"]] <- tolower(name) |
||||
|
extra_params[["type"]] <- tolower(type[1]) |
||||
|
|
||||
|
httr::GET( |
||||
|
url = service_path, |
||||
|
query = extra_params, |
||||
|
.PLAYDOH_UA |
||||
|
) -> res |
||||
|
|
||||
|
httr::stop_for_status(res) |
||||
|
|
||||
|
out <- httr::content(res, as = "text", encoding = "UTF-8") |
||||
|
out <- jsonlite::fromJSON(out) |
||||
|
|
||||
|
# will be NULL or a data frame |
||||
|
ret <- out[["Answer"]] |
||||
|
|
||||
|
# cleanup column names and add query metadata if query was OK |
||||
|
if (length(ret)) { |
||||
|
|
||||
|
colnames(ret) <- tolower(colnames(ret)) |
||||
|
|
||||
|
attr(ret, "question") <- out[["Question"]] |
||||
|
attr(ret, "flags") <- out[c("Status", "TC", "RD", "RA", "AD", "CD")] |
||||
|
attr(ret, "edns_client_subnet") <- out[["edns_client_subnet"]] |
||||
|
attr(ret, "comment") <- out[["comment"]] |
||||
|
|
||||
|
} |
||||
|
|
||||
|
ret |
||||
|
|
||||
|
} |
@ -1,70 +0,0 @@ |
|||||
#' Make a POST DoH Request (wireformat) |
|
||||
#' |
|
||||
#' Issue the query of type `type` for `name` to the DoH endpoint specified at `server_path`. |
|
||||
#' |
|
||||
#' @param name name to query for |
|
||||
#' @param type DNS query type (defaults to "`A`") |
|
||||
#' @param server_path full URL path to the DoH server quer endpoint (defaults to Quad9). |
|
||||
#' @return `NULL` (if the query failed) or a `data.frame` (tibble) |
|
||||
#' @references <https://tools.ietf.org/id/draft-ietf-doh-dns-over-https-05.html> |
|
||||
#' @export |
|
||||
doh_post <- function(name, type = "A", server_path = "https://dns.quad9.net/dns-query") { |
|
||||
|
|
||||
# for now, use python's {dnslib} as a crutch to |
|
||||
# encode/decode wireformat DNS questions and answers |
|
||||
|
|
||||
.dns$DNSRecord$question( |
|
||||
qname = tolower(name[1]), |
|
||||
qtype = toupper(type[1]), |
|
||||
qclass = "IN" |
|
||||
) -> q |
|
||||
|
|
||||
qpak <- q$pack() |
|
||||
|
|
||||
# now, send it off to the server |
|
||||
|
|
||||
httr::POST( |
|
||||
url = server_path[1], |
|
||||
httr::add_headers( |
|
||||
`Content-Type` = "application/dns-message", |
|
||||
`Accept` = "application/dns-message" |
|
||||
), |
|
||||
encode = "raw", |
|
||||
body = qpak |
|
||||
) -> res |
|
||||
|
|
||||
httr::warn_for_status(res) |
|
||||
|
|
||||
# if the response is OK, make it a data frame |
|
||||
|
|
||||
if (httr::status_code(res) == 200) { |
|
||||
|
|
||||
r <- .dns$DNSRecord$parse(httr::content(res)) |
|
||||
|
|
||||
q <- r$get_q() |
|
||||
|
|
||||
do.call( |
|
||||
rbind.data.frame, |
|
||||
lapply(r$rr, function(.x) { |
|
||||
data.frame( |
|
||||
query = py_str(q$qname), |
|
||||
qtype = q$qtype, |
|
||||
rname = py_str(.x$rname), |
|
||||
rtype = .x$rtype, |
|
||||
rdata = py_str(.x$rdata), |
|
||||
ttl = .x$ttl, |
|
||||
stringsAsFactors = FALSE |
|
||||
) |
|
||||
}) |
|
||||
|
|
||||
) -> xdf |
|
||||
|
|
||||
class(xdf) <- c("tbl_df", "tbl", "data.frame") |
|
||||
|
|
||||
xdf |
|
||||
|
|
||||
} else { |
|
||||
NULL |
|
||||
} |
|
||||
|
|
||||
} |
|
@ -1,29 +0,0 @@ |
|||||
py_c <- reticulate::py_config() |
|
||||
|
|
||||
.dns <- NULL |
|
||||
|
|
||||
.onLoad <- function(libname, pkgname) { |
|
||||
|
|
||||
if (utils::compareVersion(py_c$version, "3.5") < 0) { |
|
||||
stop( |
|
||||
paste0( |
|
||||
c( |
|
||||
"Python 3.5+ is required. If this is installed please set RETICULATE_PYTHON ", |
|
||||
"to the path to the Python 3 binary on your system and try re-installing/", |
|
||||
"re-loading the package." |
|
||||
), |
|
||||
collapse = "" |
|
||||
) |
|
||||
) |
|
||||
return() |
|
||||
} |
|
||||
|
|
||||
if (!reticulate::py_module_available("dnslib")) { |
|
||||
packageStartupMessage( |
|
||||
"The 'dnslib' Python module must be installed." |
|
||||
) |
|
||||
} else { |
|
||||
.dns <<- reticulate::import("dnslib", delay_load = TRUE) |
|
||||
} |
|
||||
|
|
||||
} |
|
@ -0,0 +1,32 @@ |
|||||
|
% Generated by roxygen2: do not edit by hand |
||||
|
% Please edit documentation in R/doh-get.R |
||||
|
\name{doh_get} |
||||
|
\alias{doh_get} |
||||
|
\title{Make a DoH Request (GET/REST)} |
||||
|
\usage{ |
||||
|
doh_get(name, type = "a", extra_params = list(), |
||||
|
service_path = "https://9.9.9.9/dns-query") |
||||
|
} |
||||
|
\arguments{ |
||||
|
\item{name}{name to query for} |
||||
|
|
||||
|
\item{type}{DNS query type (defaults to "\code{A}")} |
||||
|
|
||||
|
\item{extra_params}{any special \code{GET} query parameter needed for a given server API endpoint. |
||||
|
this should be a named \code{list}.} |
||||
|
|
||||
|
\item{server_path}{full URL path to the DoH server quer endpoint (defaults to Quad9).} |
||||
|
} |
||||
|
\value{ |
||||
|
\code{NULL} (if the query failed) or a \code{data.frame} (tibble) |
||||
|
} |
||||
|
\description{ |
||||
|
Issue a \code{GET} REST API query of type \code{type} for \code{name} to the |
||||
|
DoH endpoint specified at \code{server_path}. |
||||
|
} |
||||
|
\examples{ |
||||
|
doh_get("rud.is", "A") |
||||
|
} |
||||
|
\references{ |
||||
|
\url{https://tools.ietf.org/id/draft-ietf-doh-dns-over-https-05.html} |
||||
|
} |
@ -1,25 +0,0 @@ |
|||||
% Generated by roxygen2: do not edit by hand |
|
||||
% Please edit documentation in R/doh-post.R |
|
||||
\name{doh_post} |
|
||||
\alias{doh_post} |
|
||||
\title{Make a POST DoH Request (wireformat)} |
|
||||
\usage{ |
|
||||
doh_post(name, type = "A", |
|
||||
server_path = "https://dns.quad9.net/dns-query") |
|
||||
} |
|
||||
\arguments{ |
|
||||
\item{name}{name to query for} |
|
||||
|
|
||||
\item{type}{DNS query type (defaults to "\code{A}")} |
|
||||
|
|
||||
\item{server_path}{full URL path to the DoH server quer endpoint (defaults to Quad9).} |
|
||||
} |
|
||||
\value{ |
|
||||
\code{NULL} (if the query failed) or a \code{data.frame} (tibble) |
|
||||
} |
|
||||
\description{ |
|
||||
Issue the query of type \code{type} for \code{name} to the DoH endpoint specified at \code{server_path}. |
|
||||
} |
|
||||
\references{ |
|
||||
\url{https://tools.ietf.org/id/draft-ietf-doh-dns-over-https-05.html} |
|
||||
} |
|
@ -0,0 +1,27 @@ |
|||||
|
% Generated by roxygen2: do not edit by hand |
||||
|
% Please edit documentation in R/globals.R |
||||
|
\docType{data} |
||||
|
\name{doh_servers} |
||||
|
\alias{doh_servers} |
||||
|
\title{Built-in list of DoH Servers} |
||||
|
\format{An object of class \code{list} of length 6.} |
||||
|
\usage{ |
||||
|
doh_servers |
||||
|
} |
||||
|
\description{ |
||||
|
The \code{url} element has the URL for the \code{GET} requests and |
||||
|
the \code{extra_params} element has any needed query parameters |
||||
|
for the \code{GET} requests. |
||||
|
} |
||||
|
\details{ |
||||
|
The list so far. |
||||
|
\itemize{ |
||||
|
\item \code{google}: \url{https://dns.google.com/experimental} |
||||
|
\item \code{cloudflare}: \url{https://cloudflare-dns.com/dns-query} |
||||
|
\item \code{quad9}: \url{https://dns.quad9.net/dns-query} |
||||
|
\item \code{securedns_eu}: \url{https://doh.securedns.eu/dns-query} |
||||
|
\item \code{dnswarden_adblock}: \url{https://doh.dnswarden.com/adblock} |
||||
|
\item \code{dnswarden_uncensored}: \url{https://doh.dnswarden.com/uncensored} |
||||
|
} |
||||
|
} |
||||
|
\keyword{datasets} |
Loading…
Reference in new issue