This can probably use the multipart crate, unsure the most ergonomic API to actually expose.
My current thinking is to add a form<T: Serialize>(val: T) method, which will form urlencode. To allow multipart, I'm thinking that a file()method could also exist, which would set the same internally that the form and files are multipart.
A form<T: Serialize>(val: T) method now exists. To add multipart support, a possibility is as described before, adding a file(name: &str, f: File) method, and if form() and file() are both called, then internally the RequestBuilder makes the request multipart.
What the status of this issue? I'd like to use multipart with reqwest.
The status is all here in the issue. The question is on how should the API look for adding it.
I see. So, could I suggest a new API? I'd like to have a explicit multipart() call and then accept form<T: Serialize>(val: T) and file<P: AsRef<Path>>(name: &str, p: P) . multipart() may return a new builder, say MultpartRequestBuilder or phantom typed RequestBuilder<Multipart>.
I think your option works well but I prefer explicit control over the format like json() and form.
@seanmonstar Any blockers from multipart on this? We're blocked on upgrading Hyper because of Nickel but I'm thinking of just dropping support or moving it to an external crate because they move so slowly.
@abonander if there is a blocker, I'm not aware of it. I admit I haven't had much time to look into the this issue yet.
As for the suggested API comment, having multipart() -> MultipartRequestBuilder sounds like an excellent idea.
There are already a few multipart related crates around: https://crates.io/search?q=multipart Maybe that could help, or be an inspiration.
How can I send multipart requests with this library now? I can't get it to work, sadly.
@voider1 this issue is still open, no one has been motivated enough to implement it.
How can I send multipart requests with this library now? I can't get it to work, sadly.
What you could do as a workaround is to use one of the crates here https://crates.io/search?q=multipart and simply encode the request body yourself. Once you have the encoded bytes, you can send them using reqwest.
@seanmonstar I'll give it a try, if you have any suggestions I'd like to hear them. I will be taking the suggested approach from this issue to implement it.
I think I basically finished the multipart method (didn't have a lot of time on my hands), but how should I go about implementing the send method for both RequestBuilder and MultipartRequestBuilder?
For now I have made a macro called impl_send which implements the send method for the struct which gets passed to it.
@voider1 it'd be better if there was only 1 function that was ultimately called. There's some other work to introduce a Request type, and probably some sort of client.execute(Request), so there's several different entry points to actually sending a request over the wire, and they should all converge on a single function. It may be clearer with the proposed RequestBuilder::send() internally just doing client.execute(builder.build()).
If you're using multipart::client::lazy::Multipart, there is a bug with the internal buffering that I need to sort out before this gets merged (https://github.com/abonander/multipart/issues/82). If you're using a different crate entirely then obviously it's a non-issue.
@seanmonstar Should I just implement the MultipartRequestBuilder as I normally would do? I could adopt the Request type if you could expand on how it should be implemented. As of now, the MultipartRequestBuilder is a wrapper around RequestBuilder, I can make the RequestBuilder public so people could call multipartrequestbuilder.requestbuilder.send() or I could make a method on the MultipartRequestBuilder called send() which would call self.requestbuilder.send(). That's what I'm thinking about now, but I could adopt the Request type and the other mentioned methods and changes in my fork.
@abonander Thanks for mentioning it, but I am not using a crate for this. Implementing multipart/form-data requests myself seems easier and is trivial. I didn't take much time to look at multipart crates and when I did I couldn't get it working with Reqwest.
@voider1 I've merged the Request and RequestBuilder changes into master, so maybe it's easier to understand what I was referring to. I suspect having send() and build() methods on a multipart builder makes sense.
I wonder though, if having made all the builder methods return &mut Self will have made the chaining into a multipart builder impossible...
Thought some more, I retract what I said, even though the builder uses &mut Self, it should still be perfectly fine to chain it together. You can see this is already possible since you can chain using the ClientBuilder and RequestBuilder together in a single statement.
@seanmonstar Yes, I've implemented them in such a way that params() and files can be chained. Thanks for your input! I will make a PR soon.
On the off chance it's useful for anyone, I threw together a quick-and-dirty example of manually using the multipart crate with reqwest 0.6.2, based on dbrgn's suggestion:
https://gist.github.com/simmons/6c2e6eb3ade5bfcb962250603dd667cf
Most helpful comment
On the off chance it's useful for anyone, I threw together a quick-and-dirty example of manually using the
multipartcrate withreqwest0.6.2, based on dbrgn's suggestion:https://gist.github.com/simmons/6c2e6eb3ade5bfcb962250603dd667cf