Search code examples
rcurlrcurlhttr

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 [email protected] -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


Solution

  • 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 [email protected] -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())