PUT request from RCurl - r

I'm looking to send a PUT command to a server from R. The following unix commandline snippet works fine:
curl -i -k -u "username:pass" -X PUT -d "description=test+test+test" https://somewebsite.com/application
I've tried various iterations on httpPUT(), and I'm now working with the inner function getURLContent:
curl_opts = curlOptions(username = "username", password = "pass", httpauth=AUTH_BASIC, ssl.verifypeer = FALSE, headerfunction=h$update)
url=paste("https://somewebsite.com/", "application", sep="")
info <- "description=test+test+test"
val <- charToRaw(info)
getURLContent(url, infilesize = length(val), readfunction = val, upload = TRUE, customrequest = "PUT", .opts=curl_opts)
The server is sending back a search like response, as if I did not actually post the data. Any thoughts on how to recreate the curl commandline PUT in RCurl?
Thanks!

Related

Writing Curl POST in R: uploading an image to a website

I am trying to upload an image to a website. Below is the successful curl function:
curl --location --request POST 'http://xxxxx?laboratoryResultVisibleId=LR-116807&assayAttribute=Trace&onBehalfOf=minnie' \
--header 'Authorization: Basic U1JWR0JMLUdEQklPTDpQZjgyNTE5Mw==' \
--form 'imageFile=#/C:/Users/minnie/Downloads/plot.png'
I am writing my R code as follows:
username <- "minnie"
url <- "http://xxxxx"
auth <- authenticate(user='abc', password='xyz', type="basic")
header <- list(username)
names(header) <- "X-On-Behalf-Of"
filepath <- "C:/Users/minnie/Downloads/plot.png"
post_zip <- httr::POST(
url = url,
auth,
body = list(
laboratoryResultVisibleId = 'LR-116807',
assayAttribute = 'Trace',
file = httr::upload_file(filepath),
userid = username
),
httr::add_headers("Content-Type"="multipart/form-data")
)
post_zip
content(post_zip, "text")
and I got the following feedback:
Response [http://xxxxx]
Date: 2020-11-18 22:30
Status: 200
Content-Type: application/json;charset=UTF-8
Size: 43 B
> content(post_zip, "text")
[1] "{\"success\":false,\"message\":\"No File found\"}"
It seems that no file has been found. Any clue? Thank you so much for your help :-)
I feel like this has something to do with http vs https, can you try changing to https?
The problem resides in the file path. We should use the file.path () function in R to let the server know it is a file path, rather than a character string.
filepath <- file.path(getwd(), "plot.png")
post_zip <- httr::POST(
url = url,
auth,
body = list(
laboratoryResultVisibleId = 'LR-116807',
assayAttribute = 'Trace',
imageFile = httr::upload_file(filepath),
userid = username
),
httr::add_headers("Content-Type"="multipart/form-data")
)
post_zip
content(post_zip, "text")

How to send a mail via SMTPS using the curl package in R?

I would like to send a mail using SMTPS in R. Currently, non of the available packages supports sending Mails via TLS (rmail & sendmaileR) or they have a hard to install Java dependency (mailr). I tried using curl and managed to send a mail using the following code snippet:
curl --url 'smtps://mail.server.com:465' --ssl-reqd --mail-from 'mail1#example.com' --mail-rcpt 'mail2#example.com' --upload-file mail.txt --user 'user:password'
Unfortunately, I could not translate that snippet into R using the brilliant curl package. While I managed to find all options, the curl statement crashes the R session every time. Furthermore, I was not able to add the mail.txt file to the request which I created in a temporary directory. Did someone manage sending mails using the curl package? Why does the program always crash? The goal should be to send mails on all platforms.
# input variables
to <- "mail1#example.com"
from <- Sys.getenv("MAIL_USER")
password <- Sys.getenv("MAIL_PASSWORD")
server <- Sys.getenv("MAIL_SERVER")
port <- 465
subject <- "Test Mail"
message <- c("Hi there!",
"This is a test message.",
"Cheers!")
# compose email body
header <- c(paste0('From: "', from, '" <', from, '>'),
paste0('To: "', to, '" <', to, '>'),
paste0('Subject: ', subject))
body <- c(header, "", message)
# create tmp file to save mail text
mail_file <- tempfile(pattern = "mail_", fileext = ".txt")
file_con <- file(mail_file)
writeLines(body, file_con)
close(file_con)
# define curl options
handle <- curl::new_handle()
curl::handle_setopt(handle = handle,
mail_from = from,
mail_rcpt = to,
use_ssl = TRUE,
port = port,
userpwd = paste(from, password, sep = ":"))
con <- curl::curl(url = server, handle = handle)
open(con, "r")
close(con)
# delete file
unlink(mail_file)

How to pass the curl -F parameter in the httr package?

Hi I try to translate this curl instruction using httr
curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -F file=#test.txt -F filename=test.txt -F parent_dir=/ http://cloud.seafile.com:8082/upload-api/73c5d117-3bcf-48a0-aa2a-3f48d5274ae3
Without the -F parameter the instruction is :
httr::POST(
url = "http://cloud.seafile.com:8082/upload-api/73c5d117-3bcf-48a0-aa2a-3f48d5274ae3",
add_headers(Authorization = "Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd")
)
)
I think I have to use the httr::upload_file function but I didn't manage to use this without error.
Do you have any idea how I can do that ?
Regards
Here is how to construct this curl request with httr package. I used httpbin.org to test the request sent.
You'll use POST filling the body with a list. encode argument controls how this list will be handle and by default it is the correct multipart you need.
res <- httr::POST(
url = "http://httpbin.org/post",
httr::add_headers(Authorization = "Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd"),
# Add the file and metadata as body using a list. Default encode is ok
body = list(
file = httr::upload_file("test.txt"),
filename = "test.txt",
parent_dir = "/"
)
)
httr_ouput <- httr::content(res)
One way to check this is ok is to compare output with the curl command you know is working
out <- sys::exec_internal(
'curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -F file=#test.txt -F filename=test.txt -F parent_dir=/ http://httpbin.org/post'
)
curl_output <- jsonlite::fromJSON(rawToChar(out$stdout))
#compare body
identical(curl_output$files, httr_ouput$files)
#> TRUE
identical(curl_output$form, httr_ouput$form)
#> TRUE
You can also do it with the crul package, another wrapper above curl; The logic is identical
con <- crul::HttpClient$new(
url = "http://httpbin.org/post"
)
crul_req <- con$post(
body = list(
file = crul::upload("test.txt"),
filename = "test.ext",
parent_dir = "/"
)
)
crul_output <- jsonlite::fromJSON(crul_req$parse())

RCurl getting through proxy (curl works)

I'm having no joy getting through the corporate web proxy with RCurl.
I'm using R 3.1.2 and RCurl 1.95.4.5 on Windows 7. I've researched the existing stackoverflow workarounds but none of them work.
Here is my code which I expect to work :
curl <- getCurlHandle()
curlSetOpt(.opts = list(proxy = 'proxyIP:proxyPort',
proxyuserpwd = "domain\\username:password",
proxyauth="ntlm"
), curl = curl)
Res <- getURL('http://yahoo.com', curl=curl)
After hitting this wall I tried with Curl to diagnose more. I actually got the request working with Curl using this:
curl -x proxyIP:port --proxy-ntlm -U domain\username:password http://yahoo.com
I verified with curl (using -v) that NTLM was being used to authenticate.
I don't understand why the RCurl options aren't working as I'm sure I've used the correct setting names.
The error message I see in R is a 407 Proxy Authenticate page.
Is this an RCurl bug?
I sorted it. With the last throw of the dice :
From :
curlSetOpt(.opts = list(proxy = 'proxyIP:proxyPort',
proxyuserpwd = "domain\\username:password",
proxyauth="ntlm"
), curl = curl)
To
curlSetOpt(.opts = list(proxy = 'proxyIP:proxyPort',
proxyusername = "domain\\username",
proxypassword = "password",
proxyauth="ntlm"
), curl = curl)

Internal server error using Rcurl

I want to use the following curl command using RCurl
curl -X POST http://test.reco4j.org:7474/db/data/ext/Reco4jRecommender/node/248/get_recommendations -H "Content-Type: application/json" -d '{"type":"0"}'
so i am using the following R code
library(RCurl)
library(RJSONIO)
postForm("http://test.reco4j.org:7474/db/data/ext/Reco4jRecommender/node/248/get_recommendations",
.opts = list(postfields = toJSON(list(id = "0")),
httpheader = c('Content-Type' = 'application/json', ssl.verifypeer = FALSE)
))
But I get an "Internal server errror", so i am not sure my R code is wrong or it is a windows problem.
The reason I am mentioning this, is that the original curl command fails in windows but works on mac and Linux, so I am not sure the R failure is a windows issue or an R issue.
You have an error in your code. The pair you need to send is "type":"0" you are sending "id":"0".
library(RCurl)
library(RJSONIO)
res <- postForm("http://test.reco4j.org:7474/db/data/ext/Reco4jRecommender/node/248/get_recommendations",
.opts = list(postfields = toJSON(list(type = "0")),
httpheader = c('Content-Type' = 'application/json', ssl.verifypeer = FALSE)
))
out <- fromJSON(rawToChar(res))
> head(out[[1]])
$outgoing_relationships
[1] "http://test.reco4j.org:7474/db/data/node/2285/relationships/out"
$data
$data$movieId
[1] 1342
$data$title
[1] "Convent, The (Convento, O) (1995)"
$data$releaseDate
[1] "14-Jun-1996"
It looks like a bad URL. I get an HTTP ERROR 500: INTERNAL_SERVER_ERROR trying to access that URL in firefox.
EDIT: Disregard, you're right: the curl command worked in a shell prompt. Sorry for doubting you.

Resources