Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How upload file, just like curl -T <file> #560

Open
zhang-huaimin opened this issue May 8, 2024 · 3 comments
Open

How upload file, just like curl -T <file> #560

zhang-huaimin opened this issue May 8, 2024 · 3 comments

Comments

@zhang-huaimin
Copy link

Hello,
I often use curl -T file in bash to upload file, how should this be done in rust-curl?
Hope your reply, thanks!

@sagebind
Copy link
Collaborator

curl-rust is a thin wrapper over libcurl so generally examples out in the wild using the libcurl API in most any language should translate to some degree to curl-rust. (Note that the curl command is a application that uses libcurl but adds its own code on top. curl-rust has no interaction with the curl command.)

The curl command actually has a neat trick to show you how one might achieve similar results / options as any given curl command using libcurl by appending --libcurl to the command. For example, curl -T file.txt http://example.com --libcurl - will show you the following C code:

/********* Sample code generated by the curl command line tool **********
 * All curl_easy_setopt() options are documented at:
 * https://curl.se/libcurl/c/curl_easy_setopt.html
 ************************************************************************/
#include <curl/curl.h>

int main(int argc, char *argv[])
{
  CURLcode ret;
  CURL *hnd;

  hnd = curl_easy_init();
  curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
  curl_easy_setopt(hnd, CURLOPT_URL, "http://example.com/file.txt");
  curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
  curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L);
  curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/8.2.1");
  curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
  curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS);
  curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
  curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);

  /* Here is a list of options the curl code used that cannot get generated
     as source easily. You may choose to either not use them or implement
     them yourself.

  CURLOPT_WRITEDATA was set to an object pointer
  CURLOPT_WRITEFUNCTION was set to a function pointer
  CURLOPT_READDATA was set to an object pointer
  CURLOPT_READFUNCTION was set to a function pointer
  CURLOPT_SEEKDATA was set to an object pointer
  CURLOPT_SEEKFUNCTION was set to a function pointer
  CURLOPT_ERRORBUFFER was set to an object pointer
  CURLOPT_STDERR was set to an object pointer
  CURLOPT_HEADERFUNCTION was set to a function pointer
  CURLOPT_HEADERDATA was set to an object pointer

  */

  ret = curl_easy_perform(hnd);

  curl_easy_cleanup(hnd);
  hnd = NULL;

  return (int)ret;
}
/**** End of sample code ****/

Usually to upload a file you'd open the file and then set CURLOPT_READFUNCTION to a function that would read a chunk of the file and copy it into libcurl's upload buffer. One curl-rust wrapper for this option is read_function.

@nyovaya
Copy link

nyovaya commented Jul 13, 2024

For me the read_function call doesn't seem to work so far, as it seems to be never ending, but it also doesn't really seem to be called. https://gitlab.com/nyovaya/xmpp-http-upload/-/blob/tests/tests/v1.rs?ref_type=heads#L27

@sagebind
Copy link
Collaborator

@nyovaya Enabling verbose logging will usually help you troubleshoot libcurl behavior. I do see one problem in your code, that you're using CURLOPT_POSTFIELDSIZE / post_field_size (which only has to do with libcurl's built-in form handling) instead of CURLOPT_INFILESIZE / in_filesize which is properly related to read_function.

Note that libcurl behavior itself isn't really in the purview of curl-rust. We just provide safe bindings to libcurl and assume libcurl works correctly and you know how to use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants