diff --git a/R/http.r b/R/http.r index deb1860..4208719 100644 --- a/R/http.r +++ b/R/http.r @@ -3,10 +3,12 @@ #' @details This function constructs and signs an SQS API request and returns the results thereof, or relevant debugging information in the case of error. #' @param url A character string containing an SQS API endpoint URL. #' @param query An optional named list containing query string parameters and their character values. -#' @param region A character string containing an AWS region. If missing, the default \dQuote{us-east-1} is used. -#' @param key A character string containing an AWS Access Key ID. See \code{\link[aws.signature]{locate_credentials}}. -#' @param secret A character string containing an AWS Secret Access Key. See \code{\link[aws.signature]{locate_credentials}}. -#' @param session_token Optionally, a character string containing an AWS temporary Session Token. See \code{\link[aws.signature]{locate_credentials}}. +#' @param headers A list of headers to pass to the HTTP request. +#' @param verbose A logical indicating whether to be verbose. Default is given by \code{options("verbose")}. +#' @param region A character string specifying an AWS region. See \code{\link[aws.signature]{locate_credentials}}. +#' @param key A character string specifying an AWS Access Key. See \code{\link[aws.signature]{locate_credentials}}. +#' @param secret A character string specifying an AWS Secret Key. See \code{\link[aws.signature]{locate_credentials}}. +#' @param session_token Optionally, a character string specifying an AWS temporary Session Token to use in signing a request. See \code{\link[aws.signature]{locate_credentials}}. #' @param ... Additional arguments passed to \code{\link[httr]{GET}}. #' @return If successful, a named list. Otherwise, a data structure of class #' \dQuote{aws_error} containing any error message(s) from AWS and information @@ -17,20 +19,33 @@ #' @importFrom xml2 read_xml as_list #' @import httr #' @export -sqsHTTP <- function(url = NULL, - query = list(), - region = Sys.getenv("AWS_DEFAULT_REGION", "us-east-1"), - key = NULL, - secret = NULL, - session_token = NULL, - ...) { +sqsHTTP <- +function( + url = NULL, + headers = list(), + query = list(), + verbose = getOption("verbose", FALSE), + region = Sys.getenv("AWS_DEFAULT_REGION", "us-east-1"), + key = NULL, + secret = NULL, + session_token = NULL, + ... +) { + # locate and validate credentials + credentials <- locate_credentials(key = key, secret = secret, session_token = session_token, region = region, verbose = verbose) + key <- credentials[["key"]] + secret <- credentials[["secret"]] + session_token <- credentials[["session_token"]] + region <- credentials[["region"]] + + # generate request signature if (is.null(url)) { url <- paste0("https://sqs.",region,".amazonaws.com") } p <- parse_url(url) action <- if(p$path == "") "/" else paste0("/", p$path) d_timestamp <- format(Sys.time(), "%Y%m%dT%H%M%SZ", tz = "UTC") - S <- signature_v4_auth( + Sig <- signature_v4_auth( datetime = d_timestamp, region = region, service = "sqs", @@ -42,15 +57,18 @@ sqsHTTP <- function(url = NULL, request_body = "", key = key, secret = secret, - session_token = session_token) - headers <- list(`x-amz-date` = d_timestamp, - `x-amz-content-sha256` = S$BodyHash, - Authorization = S$SignatureHeader) + session_token = session_token, + verbose = verbose) + # setup request headers + headers[["x-amz-date"]] <- d_timestamp + headers[["x-amz-content-sha256"]] <- Sig$BodyHash + headers[["Authorization"]] <- Sig[["SignatureHeader"]] if (!is.null(session_token) && session_token != "") { headers[["x-amz-security-token"]] <- session_token } H <- do.call(add_headers, headers) + # execute request if (length(query)) { r <- GET(url, H, query = query, ...) } else { @@ -61,16 +79,16 @@ sqsHTTP <- function(url = NULL, if (http_error(r)) { x <- try(as_list(read_xml(cont)), silent = TRUE) if (inherits(x, "try-error")) { - x <- try(fromJSON(cont)$Error, silent = TRUE) + x <- try(jsonlite::fromJSON(cont)$Error, silent = TRUE) } warning(paste0(http_status(r)$message, ": ", x$Code, " (", x$Message, ")")) h <- headers(r) out <- structure(x, headers = h, class = "aws_error") - attr(out, "request_canonical") <- S$CanonicalRequest - attr(out, "request_string_to_sign") <- S$StringToSign - attr(out, "request_signature") <- S$SignatureHeader + attr(out, "request_canonical") <- Sig$CanonicalRequest + attr(out, "request_string_to_sign") <- Sig$StringToSign + attr(out, "request_signature") <- Sig$SignatureHeader } else { - out <- try(fromJSON(cont), silent = TRUE) + out <- try(jsonlite::fromJSON(cont), silent = TRUE) if (inherits(out, "try-error")) { out2 <- try(as_list(read_xml(cont)), silent = TRUE) if (inherits(out2, "try-error")) { diff --git a/man/sqsHTTP.Rd b/man/sqsHTTP.Rd index 75b7d04..9f4ff62 100644 --- a/man/sqsHTTP.Rd +++ b/man/sqsHTTP.Rd @@ -4,22 +4,27 @@ \alias{sqsHTTP} \title{Execute SQS API Request} \usage{ -sqsHTTP(url = NULL, query = list(), +sqsHTTP(url = NULL, headers = list(), query = list(), + verbose = getOption("verbose", FALSE), region = Sys.getenv("AWS_DEFAULT_REGION", "us-east-1"), key = NULL, secret = NULL, session_token = NULL, ...) } \arguments{ \item{url}{A character string containing an SQS API endpoint URL.} +\item{headers}{A list of headers to pass to the HTTP request.} + \item{query}{An optional named list containing query string parameters and their character values.} -\item{region}{A character string containing an AWS region. If missing, the default \dQuote{us-east-1} is used.} +\item{verbose}{A logical indicating whether to be verbose. Default is given by \code{options("verbose")}.} + +\item{region}{A character string specifying an AWS region. See \code{\link[aws.signature]{locate_credentials}}.} -\item{key}{A character string containing an AWS Access Key ID. See \code{\link[aws.signature]{locate_credentials}}.} +\item{key}{A character string specifying an AWS Access Key. See \code{\link[aws.signature]{locate_credentials}}.} -\item{secret}{A character string containing an AWS Secret Access Key. See \code{\link[aws.signature]{locate_credentials}}.} +\item{secret}{A character string specifying an AWS Secret Key. See \code{\link[aws.signature]{locate_credentials}}.} -\item{session_token}{Optionally, a character string containing an AWS temporary Session Token. See \code{\link[aws.signature]{locate_credentials}}.} +\item{session_token}{Optionally, a character string specifying an AWS temporary Session Token to use in signing a request. See \code{\link[aws.signature]{locate_credentials}}.} \item{...}{Additional arguments passed to \code{\link[httr]{GET}}.} }