cpr icon indicating copy to clipboard operation
cpr copied to clipboard

cpr::Download with POST method

Open 07C0 opened this issue 3 years ago • 15 comments

Hi, can I cpr::Download using a POST method and payload? Something like

session.SetUrl({"http://localhost/file"});
session.SetPayload({{"file_hash", "12345"}});
// Set post method ?
// session.download...

07C0 avatar Sep 23 '22 13:09 07C0

Currently no. But this is something that should be easy to fix. However I won't have time for it until the 15th of October.

Any chance you would like have a look at this and create a PR?

COM8 avatar Sep 23 '22 14:09 COM8

Sure, thanks for your reply.

07C0 avatar Sep 23 '22 14:09 07C0

I'm keeping this issue open until we solved it :)

COM8 avatar Sep 23 '22 14:09 COM8

Unfortunately, I don't have enough c++ programming experience to write this enhancement =(

07C0 avatar Oct 01 '22 16:10 07C0

I can have a look into this one

ATM-SALEH avatar Oct 12 '22 22:10 ATM-SALEH

@ATM-SALEH You are more thank welcome to look at this. Let me know in case you need any help.

COM8 avatar Oct 13 '22 07:10 COM8

@ATM-SALEH any updates from your side? The 1.10.0 release date is coming closer and I also can have a look at it.

COM8 avatar Dec 28 '22 11:12 COM8

@COM8 - Apologies, I couldn't manage time to look into this.

Feel free to have a look

ATM-SALEH avatar Jan 22 '23 16:01 ATM-SALEH

@COM8 @ATM-SALEH Can I look into this? but I will take some time as I am new to this repo.

harcool avatar Sep 23 '23 11:09 harcool

@harcool sure. You are more than welcome to. Let me know when you need some help/pointers. As soon as you actually start I can assign the issue to you.

COM8 avatar Sep 24 '23 07:09 COM8

Hi @COM8 I have started looking into this. Currently we can only download the file from get method (due to hardcoded option here - https://github.com/libcpr/cpr/blob/e3413506f73eeeafcecabb4ac652aa5560b8fde7/cpr/session.cpp#L860 ). We can download the file using this -

std::ofstream of("1.jpg", std::ios::binary);
cpr::Response r = cpr::Download(of, cpr::Url{"http://www.httpbin.org/1.jpg"});
std::cout << "http status code = " << r.status_code << std::endl << std::endl;

To download using post, We need to set - curl_easy_setopt(curl_->handle, CURLOPT_HTTPPOST, 1); in preparedownload function. I am thinking like creating a setPostDownload() function in session class. which would set CURLOPT_HTTPPOST to 1. and then call the download function with that session object. It would look like this -

session.SetUrl({"http://localhost/file"});
session.SetPayload({{"file_hash", "12345"}});
session.setpostdownload();
cpr::download(<ofstream object> , session);

Let me know your thoughts on this.

harcool avatar Sep 24 '23 09:09 harcool

First I was thinking about adding a new cpr::Download(...) call like cpr::DownloadPost(...) This would solve this quite easily. BUT it's not scalable in my eyes. I like your approach better. We should add a cpr::DownloadPost{true} option like we are doing it for cpr::Verbose{true}. This is the way to here in my eyes.

TLDR; Yes, I agree with your approach.

COM8 avatar Sep 24 '23 12:09 COM8

okay got it. I will take inspiration from cpr::Verbose and raise a PR . I wanted to understand the flow for verbose. Let's say I want to enable verbose for download api.

auto res= cpr::Download(<ostream obj> , cpr::Verbose{true}) 

my intuition says that cpr::Verbose{true} this would call session::setoption(const verbose& verbose) function but I am not able to understand how it would call. Can you give some pointers on it?

harcool avatar Sep 24 '23 15:09 harcool

Take a look inside api.h. There you find more information. But the TLDR is: cpr::Download(cpr::Verbose{true}) -> priv::set_option(session, std::forward<Ts>(ts)...) (recursive for all options) -> session.SetOption(cpr::Verbose{true}) -> session.SetVerbose(cpr::Verbose{true}).

COM8 avatar Sep 27 '23 15:09 COM8

Also a god way to checkout something like this is setting a breakpoint inside cpr::Session::SetVerbose and then inspect the callstack.

COM8 avatar Sep 27 '23 15:09 COM8