hrbrmstr / curlconverter

:curly_loop: :arrow_right: :heavy_minus_sign: Translate cURL command lines into parameters for use with httr or actual httr calls (R)
http://rud.is/b/2016/02/10/craft-httr-calls-cleverly-with-curlconverter/
Other
91 stars 12 forks source link

Straighte curl request for Oauth 2.0 in Oracle Apex with flags user and data #19

Open geneorama opened 6 years ago

geneorama commented 6 years ago

While trying to develop a way to get a token from our server I found an error in straighten.

Maybe it's really a problem in httr, but I'm not sure.

The steps to reproduce are below.

Say you want to run a curl command as follows:

curlcmd <- paste('curl -i --user portpolice..:deepsecret..',
                       '--data "grant_type=client_credentials"',
                       'http://httpbin.org/post')

The response from httpbin looks like this:

system(curlcmd)
# Connection: keep-alive
# Server: meinheld/0.6.1
# Date: Tue, 20 Feb 2018 21:19:13 GMT
# Content-Type: application/json
# Access-Control-Allow-Origin: *
# Access-Control-Allow-Credentials: true
# X-Powered-By: Flask
# X-Processed-Time: 0
# Content-Length: 476
# Via: 1.1 vegur
#
# {
#  "args": {}, 
#  "data": "", 
#  "files": {}, 
#  "form": {
#    "grant_type": "client_credentials"
#  }, 
#  "headers": {
#     "Accept": "*/*", 
#     "Authorization": "Basic cG9ydHBvbGljZS4uOmRlZXBzZWNyZXQuLg==", 
#     "Connection": "close", 
#     "Content-Length": "29", 
#     "Content-Type": "application/x-www-form-urlencoded", 
#     "Host": "httpbin.org", 
#     "User-Agent": "curl/7.49.0"
#   }, 
#   "json": null, 
#   "origin": "167.165.222.49", 
#   "url": "http://httpbin.org/post"
# }
#

If I use curlconverter to come up with an equivalent command I get this:

req <- curlconverter::straighten(curlcmd)
res <- curlconverter::make_req(req)
res
# [[1]]
# function () 
# httr::VERB(verb = "GET", url = "http://httpbin.org/post", httr::authenticate(user = "portpolice..", 
#     password = "deepsecret.."), body = list(grant_type = "client_credentials"))

Executing this against httpbin.org will demonstrate that the two commands are not equivalent. For one thing, this command doesn't work as a GET. I think it's a POST not a GET, but even changing that doesn't make them match up. The biggest difference is in the authenticate section (see below).

In earlier tests I thought that "grant_type:client_credentials" appeared in the body, maybe there's more than one way to send that part of the request. The tricky part was that curl seems to have translated the username and password into base64.

geneorama commented 6 years ago

I don't know the equivalent command in httr, but in curl I eventually found out that I could match the call to curl as follows:

h <- curl::new_handle()
curl::handle_setopt(h, copypostfields = "grant_type=client_credentials")
curl::handle_setheaders(h, 
                        "Authorization"= paste("Basic", caTools::base64encode("portpolice..:deepsecret..")),
                        "Content-Type" = "application/x-www-form-urlencoded",
                        "User-Agent" = "Using R curl library directly")
cat(rawToChar(curl::curl_fetch_memory(url = "http://httpbin.org/post", handle = h)$content))

Which will yield the following:

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "grant_type": "client_credentials"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Authorization": "Basic cG9ydHBvbGljZS4uOmRlZXBzZWNyZXQuLg==", 
    "Connection": "close", 
    "Content-Length": "29", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "Using R curl library directly"
  }, 
  "json": null, 
  "origin": "167.165.222.49", 
  "url": "http://httpbin.org/post"
}