httr icon indicating copy to clipboard operation
httr copied to clipboard

[feature-request] Upload data directly from R session

Open pjbulls opened this issue 5 years ago • 3 comments

I am currently using httr::upload_file to fill a specific part of a multipart form and upload data to a server (actually via rvest:::request_POST since I need a stateful session), but this only works on files that are actually stored on the file system.

We would like to upload directly from memory within the R session, which seems to be a feature of RCurl::fileUpload. Would it be possible for this to be implemented here as well, or is there another way of doing this within httr/rvest?

pjbulls avatar May 27 '20 10:05 pjbulls

Did you try curl::form_data() ? It is supported by httr See https://github.com/r-lib/httr/blob/master/NEWS.md#minor-bug-fixes-and-improvements

It is the companion function in curl to form_file() (used by upload_file()) to send data through multipart form body.

Maybe it could help you.

cderv avatar May 28 '20 06:05 cderv

Thanks, that seems to be exactly what I need.

My problem is now that I can't get it to work, and I'm not sure this can be fixed on the client side. This does work:

rvest:::request_POST(
  html_session,
  url,
  body = list(
     param1 = "foo",
     param2 = "bar",
     param3 = httr::upload_file("file.txt")
  ),
  ...
)

POSTing the same dummy text file as a raw vector via the following does not work:

rvest:::request_POST(
  html_session,
  url,
  body = list(
     param1 = "foo",
     param2 = "bar",
     param3 = curl::form_data(readBin("file.txt", "raw", file.info("file.txt")$size),
                              type="text/plain")
  ),
  ...
)

Looking at curl's verbose output I see the second call results in * schannel: failed to decrypt data, need more data. From this issue I infer that something is going wrong server-side (over which I have no control)?

pjbulls avatar May 28 '20 09:05 pjbulls

Yes it probably comes from server because this works for me:

r <- httr::POST("https://localhost/", body=list("file"=curl::form_data(csv, type="application/csv")), encode = "multipart", httr::verbose())

charlax avatar Nov 08 '21 17:11 charlax