-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Unable to safely close HTTP chunked encoding stream with SSL #4991
Comments
I might be misunderstanding term "Streaming". Maybe I don't need a block? 🤔 Closing for now, will check later today, I'm going to bar! 🍺 |
Nope, I see this the only way of implementing long polling and it doesn't work. Need some help here! Still going to bar... |
This issue is essential to me, because my client wants Twitter streaming with a list of donors changeable in runtime. I told him Crystal is awesome but I can't figure this out. Anyone? |
It works for me if I do: begin
client.get "/" do |response|
loop do
puts response.body_io.gets
end
end
rescue ex
# here the client should be closed, probably
end |
Can you provide minimal POC - I have not seen Anyway we need shortest full example that reproduces erroneous behavior. |
Yes, please, I forgot to mention this. Your example doesn't compile. To help you faster we need a full working example (and better if we have a server that sends data for a long polling client). Otherwise the work to fix the example has to be done by everyone who wants to help you. |
I thought it would be obvious for you from the example - like, who doesn't know that IO should be closed by |
I can't reproduce the issue yet due to I don't know how to do streaming in crystal (#5004) |
Not actual for now |
It's extremely hard to reproduce, because the code is private for my client. But I'll describe the context. A program streams content from a server with chunked encoding. It needs to restart the stream from time to time. That's a SIMPLIFIED piece of code: class Stream
def stream(&block : String -> Nil)
begin
@client = HTTP::Client.new(Host, tls: true)
@client.get("/stream") do |response|
yield response.body_io.gets
end
# I have to rescue it, it's a workaround
rescue ex : Errno | IO::Error
logger.info("Rescued #{ex}, means the stream is closed externally! Exiting stream.")
rescue ex
logger.error("Rescued #{ex}")
end
end
def close
begin
@client.close
rescue ex
logger.error(ex)
end
end
end
spawn do
sleep 5
@stream.close
end
loop do
@stream = Stream.new
stream.stream do |response|
puts response
end
end
That what's most important I think:
The issue occurs on production machine only, which is docker with Ngnix. The app runs in docker containers, obviously. DisclaimerI UNDERSTAND, that this code is not reproducible, but MAYBE someone could point me where to dig. |
Closed as duplicate of #5020 (the later provides reproducible code) |
I'd like to implement long polling with some query params changeable in the runtime. So the request must be stopped and run again:
Calling
@client.close
always causesClosed stream (IO::Error)
in the first loop. If rescuing this particular error, another one will definitely appear after some successfull closes:And even if rescuing this line
@client.close rescue nil
, the program crashes after some time:The text was updated successfully, but these errors were encountered: