Internal server error using Rcurl - r

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.

Related

httr POST request error: upstream connect error or disconnect/reset before headers. reset reason: connection termination

I am currently trying to upload a CSV file to a proprietary service via httr::POST(). Unfortunately the Admins are not experienced in R and can give only little support.
This is an example on how it should look like in the command line:
curl -X POST --header 'Content-Type: multipart/form-data' \
-F file=#"member-1-test.csv.gz" 'https://some/api/endpoint'
So, in the following code I just try to stick with the example (and additionally provide a token).
> library(tidyverse)
> library(httr)
# Provide some test data with characters specifically quoted
> test_file <- tibble::tribble(
~keytype, ~key, ~action, ~segment,
6,"\"https://www.google.com\"", 0, 37372818,
6,"\"https://www.sport1.de\"" , 0, 37372818
)
> data.table::fwrite(test_file, "test.csv", quote = FALSE)
> file <- upload_file(path = "C:/R/projects/DefaultWorkingDirectory/test.csv")
> res <- POST(
url = "https://some/api/endpoint",
body = list(file = file),
add_headers(.headers = c('Content-Type' = "multipart/form-data", "Authorization" = token))
)
This gives me the follwing error:
> res
Response [https://some/api/endpoint]
Date: 2020-11-18 09:35
Status: 503
Content-Type: text/plain
Size: 95 B
> content(res, encoding = "UTF8")
"upstream connect error or disconnect/reset before headers. reset reason: connection termination"
Any help or guidance on how to move forward with this issue is very much appreciated. Thanks!
Directly after posting the question it was already solved by one of the Admins :)
The issue was that the encoding needs to be set to "multipart" and that a specific content type needs to be provided which is similar to JSON but needs to be added to the "Accept"-header field.
Here the answer for any future references:
> res <- POST(
url = "https://some/api/endpoint",
body = list(
file = upload_file("test.csv")
),
add_headers(c(
"Authorization" = token,
"Accept" = "specific_format_for_the_application"
)),
encode = "multipart",
verbose()
)

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())

Translating a curl command to R using httr (specifically '--data-binary #')

I am trying to transcribe some sound files to text using bing speech-to-text.
The following command works in command line (using git bash on Windows 10):
curl -v -X POST "https://speech.platform.bing.com/speech/recognition/interactive/
cognitiveservices/v1?language=<LANG>&format=detailed" -H "Transfer-Encoding:
chunked" -H "Ocp-Apim-Subscription-Key: <MY KEY>" -H "Content-type:
audio/wav; codec=audio/pcm; samplerate=16000" --data-binary #<MY .WAV-FILE>
I've tried this, but it doesnt work:
httr::POST(url = myURL,
add_headers("Ocp-Apim-Subscription-Key" = key,
"Content-type" = "audio/wav; codec=audio/pcm; samplerate=16000",
"Transfer-Encoding" = "chunked"),
body = (list("file" = upload_file("PATH_TO_FILE.wav"))),
verbose())
It returns this output:
Response
[https://speech.platform.bing.com/speech/recognition/dictation/
cognitiveservices/v1?language=<LANG>&format=detailed]
Date: 2017-11-29 13:29
Status: 200
Content-Type: text/plain
Size: 75 B
I believe that the request is related to the interpretation of the .wav file, and that I need to somehow add the '--data-binary' tag to the httr-request. I can see that my "content-type" is plain text, although i've specified. Furthermore: the API documentation specifies that i need to prefix my wav-file with an at-sign.
Any help would be much appreciated.
cheers.
EDIT: Link to API documentation
https://learn.microsoft.com/da-dk/azure/cognitive-services/speech/getstarted/getstartedrest?tabs=curl#tabpanel_AFC9x30-dR_curl
I figured it out.
The key is to set the proper MIME type in the body. Not setting this MIME type can result in wrongful interpretation on the receiving end, even though we get a response 200 back.
body <- list(file = httr::upload_file(
paste0(path, "/", f),
type = "audio/wav; codec=audio/pcm; samplerate=16000"))
where paste0(path, "/", f) is a path to an audio file.
myURL <- sprintf('https://speech.platform.bing.com/speech/recognition/%s/cognitiveservices/v1?language=%s&format=%s',
"dictation",
"da-DK",
"detailed")
rs <- httr::POST(
url = myURL,
httr::add_headers(.headers = c("Ocp-Apim-Subscription-Key" = key)),
httr::add_headers(.headers = c("Transfer-Encoding" = "chunked")),
body = body)

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)

PUT request from RCurl

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!

Resources