% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/fetch.R
\name{curl_fetch_memory}
\alias{curl_fetch_memory}
\alias{curl_fetch_disk}
\alias{curl_fetch_stream}
\alias{curl_fetch_multi}
\alias{curl_fetch_echo}
\alias{handle_data}
\title{Fetch the contents of a URL}
\usage{
curl_fetch_memory(url, handle = new_handle())

curl_fetch_disk(url, path, handle = new_handle())

curl_fetch_stream(url, fun, handle = new_handle())

curl_fetch_multi(
  url,
  done = NULL,
  fail = NULL,
  pool = NULL,
  data = NULL,
  handle = new_handle()
)

curl_fetch_echo(url, handle = new_handle())

handle_data(handle)
}
\arguments{
\item{url}{A character string naming the URL of a resource to be downloaded.}

\item{handle}{A curl handle object.}

\item{path}{Path to save results}

\item{fun}{Callback function. Should have one argument, which will be
a raw vector.}

\item{done}{callback function for completed request. Single argument with
response data in same structure as \link{curl_fetch_memory}.}

\item{fail}{callback function called on failed request. Argument contains
error message.}

\item{pool}{a multi handle created by \link{new_pool}. Default uses a global pool.}

\item{data}{(advanced) callback function, file path, or connection object for writing
incoming data. This callback should only be used for \emph{streaming} applications,
where small pieces of incoming data get written before the request has completed. The
signature for the callback function is \code{write(data, final = FALSE)}. If set
to \code{NULL} the entire response gets buffered internally and returned by in
the \code{done} callback (which is usually what you want).}
}
\description{
Low-level bindings to write data from a URL into memory, disk or a callback
function.
}
\details{
The \verb{curl_fetch_*()} functions automatically raise an error upon protocol problems
(network, disk, TLS, etc.) but do not implement application logic. For example,
you need to check the status code of HTTP requests in the response by yourself,
and deal with it accordingly.

Both \code{curl_fetch_memory()} and \code{curl_fetch_disk} have a blocking and a
non-blocking C implementation. The latter is slightly slower but allows for
interrupting the download prematurely (using e.g. CTRL+C or ESC). Interrupting
is enabled when R runs in interactive mode or when
\code{getOption("curl_interrupt") == TRUE}.

The \code{curl_fetch_multi()} function is the asynchronous equivalent of
\code{curl_fetch_memory()}. It wraps \code{\link[=multi_add]{multi_add()}} to
schedule requests which are executed concurrently when calling
\code{\link[=multi_run]{multi_run()}}\code{}. For each successful request, the
\code{done} callback is triggered with response data. For failed requests
(when \code{curl_fetch_memory()} would raise an error), the \code{fail} function
is triggered with the error message.

After a request has been performed, metadata from the request can be read
from the handle object using \code{handle_data()} (this same information also gets
returned by \code{curl_fetch_memory()} directly). It includes things like:
\itemize{
\item Final URL (after redirects)
\item HTTP status code
\item Content-type
\item Response headers
\item Timings
\item Http-version
This data remains available in the handle until it is either re-used for a
new request, or \code{handle_reset()} is called.
}
}
\examples{
\donttest{
# Load in memory
res <- curl_fetch_memory("https://hb.cran.dev/cookies/set?foo=123&bar=ftw")
res$content

# Save to disk
res <- curl_fetch_disk("https://hb.cran.dev/stream/10", tempfile())
res$content
readLines(res$content)

# Stream with callback
drip_url <- "https://hb.cran.dev/drip?duration=3&numbytes=15&code=200"
res <- curl_fetch_stream(drip_url, function(x){
  cat(rawToChar(x))
})

# Async API
data <- list()
success <- function(res){
  cat("Request done! Status:", res$status, "\n")
  data <<- c(data, list(res))
}
failure <- function(msg){
  cat("Oh noes! Request failed!", msg, "\n")
}
curl_fetch_multi("https://hb.cran.dev/get", success, failure)
curl_fetch_multi("https://hb.cran.dev/status/418", success, failure)
curl_fetch_multi("https://urldoesnotexist.xyz", success, failure)
multi_run()
str(data)
}
}
