R/http-internal.R

Defines functions httpInternal

# Internal sockets HTTP transport. Not recommended since it does not support HTTPS, but useful as a
# last resort if other methods don't work since it can piggyback on IE proxy settings via R's own
# internet configuration.

httpInternal <- function(
  protocol,
  host,
  port,
  method,
  path,
  headers,
  contentType = NULL,
  contentFile = NULL,
  certificate = NULL,
  timeout = NULL
) {
  if (!is.null(contentFile) && is.null(contentType)) {
    stop("You must specify a contentType for the specified file")
  }

  # default port to 80 if necessary
  if (!nzchar(port)) {
    port <- "80"
  }

  # read file in binary mode
  if (!is.null(contentFile)) {
    fileLength <- file.info(contentFile)$size
    fileContents <- readBin(contentFile, what = "raw", n = fileLength)
  }

  # build http request
  request <- NULL
  request <- c(request, paste(method, " ", path, " HTTP/1.1\r\n", sep = ""))
  request <- c(request, "User-Agent: ", userAgent(), "\r\n")
  request <- c(request, "Host: ", host, "\r\n", sep = "")
  request <- c(request, "Accept: */*\r\n")
  if (!is.null(contentFile)) {
    request <- c(
      request,
      paste("Content-Type: ", contentType, "\r\n", sep = "")
    )
    request <- c(
      request,
      paste("Content-Length: ", fileLength, "\r\n", sep = "")
    )
  }
  headers <- appendCookieHeaders(
    list(protocol = protocol, host = host, port = port, path = path),
    headers
  )
  for (name in names(headers)) {
    request <- c(request, paste(name, ": ", headers[[name]], "\r\n", sep = ""))
  }
  request <- c(request, "\r\n")

  # output request if in verbose mode
  if (httpVerbose()) {
    cat(request)
  }

  # use timeout if supplied, default timeout if not (matches parameter behavior
  # for socketConnection)
  timeout <- if (is.null(timeout)) getOption("timeout") else timeout

  # open socket connection
  time <- system.time(gcFirst = FALSE, {
    conn <- socketConnection(
      host = host,
      port = as.integer(port),
      open = "w+b",
      blocking = TRUE,
      timeout = timeout
    )
    defer(close(conn))

    # write the request header and file payload
    writeBin(charToRaw(paste(request, collapse = "")), conn, size = 1)
    if (!is.null(contentFile)) {
      writeBin(fileContents, conn, size = 1)
    }

    # read the response
    response <- readHttpResponse(
      list(
        protocol = protocol,
        host = host,
        port = port,
        method = method,
        path = path
      ),
      conn
    )
  })
  httpTrace(method, path, time)

  # print if in verbose mode
  if (httpVerbose()) {
    print(response)
  }

  # output JSON if requested
  if (httpTraceJson() && identical(contentType, "application/json")) {
    cat(paste0("<< ", rawToChar(fileContents), "\n"))
  }

  # return it
  response
}

Try the rsconnect package in your browser

Any scripts or data that you put into this service are public.

rsconnect documentation built on June 26, 2025, 5:07 p.m.