-
Notifications
You must be signed in to change notification settings - Fork 181
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
HTTP.open
hanging
#339
Comments
Did you try a
( The hang is not related to
Yes. Lines 291 to 296 in a1e92ca
You could do It would be possible to add
That is pretty much exactly what it is intended to provide. But currently the "stop reading" part is not handled nicely. In #338 I'm trying to make this work more smoothly with With #388 calling I will try adding a |
I filed this more or less concurrently with that issue, so hadn't tried it yet. I didn't think that So as I understand it there are 2 issues at play:
It seems weird that you'd need to call Thanks for the work on #338! I think that's orthogonal to this issue, so I'll try it out and let you know in that thread. |
Kind of, but no. You have to call startread to tell HTTP that you're ready to read the Response Headers and that you'd like to start reading the Response Body. But, HTTP is bi-directional, so being ready to read the Response is not necessarily related to being done with writing the request. The transfer of request and response data is asynchronous and both may well go on forever (see chat client/server example below).
Your mental model is what I intended. Not doing
Yes. I guess the problem here is that there are two different types of resource cleanup. There is "done with the transaction" and then there is "done with the connection". The do block cleans up Options I can see for an API to handle your use case are:
I think it makes sense to support both. Chat example: Lines 170 to 177 in df13276
Lines 161 to 169 in df13276
|
Ah, OK. thanks for taking the time to explain all this. I'm definitely used to thinking of HTTP in more of a request/response scenario, I didn't know exchanging interleaved data like the chat example was valid HTTP. What if |
I just noticed looking at A server that knows that it does not want the client to reuse the connection is supposed to send a "Connection: close" header. It seems that in the Icecast server in your case is not setting this header, but it probably should. If the response body is intended to be infinite, then it makes no sense to tell the client to reuse the connection for the next request. (In HTTP/1.0 the default was one-request-per-connection and a keep-alive header was used to signal an intent to reuse the connection. In HTTP/1.1 it is assumed that reuse is always wanted unless "Connection: close" is sent.
I'd like to try to find a solution within the intent of the protocol before resorting to timeout heuristics. I just tried this with $ curl -v -H "Connection: close" http://doppler.media.mit.edu/impoundment.opus
* Trying 18.85.59.166...
* TCP_NODELAY set
* Connected to doppler.media.mit.edu (18.85.59.166) port 80 (#0)
> GET /impoundment.opus HTTP/1.1
> Host: doppler.media.mit.edu
> User-Agent: curl/7.54.0
> Accept: */*
> Connection: close
>
< HTTP/1.1 200 OK
< Date: Sat, 27 Oct 2018 00:18:00 GMT
< Server: Icecast 2.4.0
< Content-Type: application/ogg
< Cache-Control: no-cache
< Expires: Sat, 26 Jul 1997 05:00:00 GMT
< Pragma: no-cache
< icy-name: no name
< icy-pub: 0
< Connection: close
< Transfer-Encoding: chunked
<
OggS���Bs��3OpusHead�����
... i.e. setting "Connection: close" on the request causes the server to respond with "Connection: close". |
Yeah, I agree this is definitely the right way to go about it if possible. I guess one issue here is that I'm not sure if Icecast makes the distinction between a stream that's "infinite", vs. one that's just really long or of indeterminate length (likely longer than the receiver wants so they're probably disconnect before it's over), and whether they couple that to the I just sent an email to the icecast-dev list to get their perspective. Another idea - what if HTTP.jl just didn't re-use connections if the client disconnected before reading the full response? I assume most of the time people read all the way to the end of a response, so the efficiencies of connection pooling would be retained. If they stopped early, you don't know how long you're going to spend reading out the rest of the data, just to discard it. For example, they could have started downloading some large (but finite) file and decided to cancel the transfer. It might be surprising if HTTP's default behavior is to download the rest of the file before it lets you continue. Is reading out the remainder of the response a common thing for client-side HTTP libraries (or HTTP proxies) to do? OK, I promise I'm done making armchair design suggestions. 🙂 Thanks for the help in figuring out the right way to use HTTP.jl for this use-case. |
No I don't.
👍
That is definitely worth considering.
I agree.
I haven't looked into that. There are a couple of (I think) common use-case where you might want to reuse the connection but not read complete Response Bodies:
However, in both of these cases, the size of the Response Body to be ignored should be quite small. |
I checked a little more into this, and it turns out that icecast is actually using HTTP/1.0 (non-persistent connection by default), but it's sitting behind a reverse proxy that is "upgrading" to HTTP/1.1 but not adding the So I do think that a big part of the issue here is a misbehaving server. Up to you whether you still want to make some of the proposed changes to be more tolerant to this sort of situation (I suppose and also handle the big cancelled download case), or call it a day and close the issue. Thanks again for looking into it and helping me learn more about HTTP |
Let's leave this open for now.
|
Close issue? |
Hey guys, I'm trying to read from an infinite stream line-by-line, and this is super confusing. So to recap:
Otherwise the connection never terminates and pollutes the connection pool, blocking all future requests forever. Since the use-case of reading from an infinite stream is not that weird, I feel like this should at least be documented in the |
@yohan-pg, would you mind making a PR to the |
Closing due to staleness |
Julia 1.0.1
HTTP.jl 0.7.1
MbedTLS.jl 0.6.4
I'm trying to explore
HTTP.open
, and I tried the following just to make sure I was able to connect:But it seems to hang on exiting the
do
block.The backtrace when I interrupt it is:
I tried adding a
readavailable(http)
and got the errorArgumentError: function requires headerscomplete(http.message)
. Looking at the docs more closely it looks like maybe I need to callstartread(http)
, but that also hangs.I'm not super clear on what level of abstraction to expect from
HTTP.open
. What I'm looking for is a way to open the given URL (which gives chunked binary data), read some data from it for a while, and then stop reading from it. Maybe the fact that I'm never hitting the end of the stream (because it doesn't end) is confusing HTTP.jl?The text was updated successfully, but these errors were encountered: