surf: curl client does not receive the full body
It seems like the curl based client does not wait until all the data is received, which can make it fail deserializing when the response is too large.
The code is roughly this, but this is not the actual URL as its a private gitlab instance:
let response: Vec<Project> = surf::get("http://gitlab.com/api/v4/projects")
.recv_json()
.await
.unwrap();
The response suddenly ends like this:
..."star_count":100,"forks_count":2,"last_activity_at":"2019-07-02T08:41:28.976Z","namespace":{"id":999,"name":"r
Querying the same URL with the curl command line tool shows the whole body.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 3
- Comments: 18 (7 by maintainers)
The upstream Isahc bug has been fixed, so updating the version Surf uses should fix the problem.
Published
v1.0.2
which should fix this! Let us know if it works out alright!Going to go ahead an close this issue assuming it’s fixed; happy to reopen if more work is needed!
Also haunted by this issue, when will the next version be published? This looks like a critical fix to me.
I am hitting the same issue. Here is a one-liner to reproduce it 😃.
Looks fixed for me. First time I retrieve a 300kbs file 😃. Thanks!
@yoshuawuyts I think this assessment is most accurate:
Your
chttp::Client
is being dropped after you receive the response headers, but during the middle of tranferring the response stream. This happens because awaiting aRequest
consumes self and returns aResponse
after the response headers are received. Since theRequest
is dropped, theHttpClient
is also dropped.https://github.com/rustasync/surf/blob/d7d9d054aad0a9bc46a7d177e133770c25451c6a/src/request.rs#L575-L582
Since all we have left on the stack is a
http::Response<Body>
after executing the request, theHttpClient
is no longer alive to finish the transfer of the response body.There’s some interesting questions here on how the lifetime of an
HttpClient
should interact with aBody
, but either way, Isahc clients should probably keep themselves alive in the background until all active transfers either finish or are cancelled (dropping achttp::Body
is enough to signal cancellation). I opened a bug on Isahc here: https://github.com/sagebind/isahc/issues/64Okay, re-ran it with
hyper
again (used #34), and this time around it does work! This is with the defaultruntime
(though I suspect that may not be the problem right now).Repro code
main.rs
index.js
Screenshot
Repro
https://github.com/yoshuawuyts/repro-surf-36
cc/ @sagebind, do you have any idea what might be going wrong here?