Skip to content
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

eof(::Session) and read(::Session) don't get along #26

Open
jkroso opened this issue Jan 7, 2015 · 9 comments
Open

eof(::Session) and read(::Session) don't get along #26

jkroso opened this issue Jan 7, 2015 · 9 comments

Comments

@jkroso
Copy link

jkroso commented Jan 7, 2015

The following prints the complete response then throws a "read: end of file" error. Where as I would expect it to block on eof until the connection is closed by the github server.

using GnuTLS

sess = GnuTLS.Session()
set_priority_string!(sess)
set_credentials!(sess, GnuTLS.CertificateStore())
associate_stream(sess, connect("github.com", 443))
handshake!(sess)
write(sess, "GET / HTTP/1.1\r\n\r\n")

while !eof(sess)
  print(read(sess, Char))
end
@sbromberger
Copy link
Contributor

the issue is in read()- if the ccall returns 0, it throws an EOFError. Better to use readavailable() / readall(), which should handle this gracefully:

while !eof(sess)
         print(bytestring(readavailable(sess)))
end

Please confirm that this works for you and I'll close it out.

@jkroso
Copy link
Author

jkroso commented Feb 20, 2015

Now it throws "stream is closed or unusable" from the readavailable call so it looks like eof still isn't doing its job properly

@sbromberger
Copy link
Contributor

Can you make sure you've done a Pkg.update() first? We've explicitly fixed this issue in the latest versions of Requests and GnuTLS.

@jkroso
Copy link
Author

jkroso commented Feb 20, 2015

Oh yup sweet readavailable works with the latest version. I still feel like eof should be fixed though

@sbromberger
Copy link
Contributor

How would you propose doing that with read()?

That is, eof() isn't broken; EOFError is thrown when the ccall that is performed by read() returns 0. Since read() is designed to be (more or less) atomic, what should be done?

@jkroso
Copy link
Author

jkroso commented Feb 21, 2015

I guess you would probably have to block inside eof until at least the next byte is available so you can see if its the null byte.

However, then you would have to hold that data in a buffer until read or one of its variants are called. So it will probably add a lot of internal complexity to manage the buffer but at least at the end Session will have a peek method :)

@sbromberger
Copy link
Contributor

well, we could do a wait_readnb(s,1) in read() but that's really just mimicking what we do in eof() on the read stream.

My current preference is that eof() shouldn't be used with read() in any case, since any eof check in read() will likely block on nb_available < 1, and it's probably better just to throw the exception right away.

Of course, my present understanding of 1) how this should work and 2) how it actually works is suspect.

@jkroso
Copy link
Author

jkroso commented Feb 21, 2015

That is, eof() isn't broken; EOFError is thrown when the ccall that is performed by read() returns 0. Since read() is designed to be (more or less) atomic, what should be done?

Huh..? if a call to read would result in an EOFError shouldn't eof return true?

@sbromberger
Copy link
Contributor

So - one other thing that doesn't make a difference in this particular case, but read() needs a UInt8 (1 byte), not a Char (4 bytes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants