Debnath
Debnath

Reputation: 13

How to avoid uri encoding of posted JSON data in R (using RCurl)

I am trying to post JSON data from R using RCurl. However I ran into a problem that the JSON arrives at the server in an encoded format. How can I turn off encoding?

I am using "postfields" in my curl.opts as follows:

curl.opts <- list(httpheader = "Content-Type: application/json",
                    httpheader = "Accept: application/json", 
                    timeout = 20, 
                    verbose = FALSE, 
                    useragent = "RCurl",   
                    postfields = bodyJSON
    )

where bodyJSON is a JSON object created using toJSON from the RJSONIO package

Finally the JSON is posted using:

result <- postForm(<<url>>, .opts = curl.opts)

The resultant JSON (from the bodyJSON field) arrives at the server using uri encoding, whereas I do not want encoding.

I tried out contentEncodeFun but the data was still arriving at the server in encoded form:

result <- postForm(<<url>>, .opts = curl.opts, .contentEncodeFun = curlPercentEncode)
Also tried:
result <- postForm(<<url>>, .opts = curl.opts, .contentEncodeFun = identity) 

Am I using the .contentEncodeFun correctly ?

A reproducible script is below:

h <- basicHeaderGatherer()
postData <- function(url) {
  library(RCurl)
  library(RJSONIO)

  print(url)

  body <- "{\"version\":\"1.0.1\"}"


  curl.opts <- list(
            httpheader = "Content-Type: application/json",
                    httpheader = "Accept: application/json",
            timeout = 20, 
                    verbose = FALSE, 
                    useragent = "RCurl",
            postfields = body,
            headerfunction=h$update         
            )



  result <- postForm(url, .opts = curl.opts)
  cat(result)

}

postData(<<url>>)
h$value()

Correctly working code:

h <- basicHeaderGatherer()
    postData <- function(url) {
      library(RCurl)
      library(RJSONIO)

      print(url)

      body <- "{\"version\":\"1.0.1\"}"


      curl.opts <- list(
                httpheader = c("Content-Type: application/json", "Accept:application/json"),
                timeout = 20, 
                verbose = FALSE, 
                useragent = "RCurl",
                postfields = body,
                headerfunction=h$update         
                )



      result <- postForm(url, .opts = curl.opts)
      cat(result)

    }

    postData(<<url>>)
    h$value()

Thanks in advance

Upvotes: 1

Views: 523

Answers (2)

MrFlick
MrFlick

Reputation: 206242

You are specifying the httpheader incorrectly. You can only set the parameter once. If you want to set multiple values, you need to use a named vector. For example

curl.opts <- list(
    httpheader = c(
        "Content-Type"="application/json",
        "Accept"="application/json"),
    timeout = 20, 
    verbose = FALSE, 
    useragent = "RCurl",
    postfields = body,
    headerfunction=h$update         
)

I tested this with http://requestb.in/ and it seemed to work. If you still have trouble, please be a bit more precise about exactly what's wrong with the request.

Upvotes: 0

hadley
hadley

Reputation: 103898

Use httr instead of RCurl:

library(httr)
POST(url, body = data, encode = "json")

Upvotes: 1

Related Questions