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

FETCH BODY[HEADER] hangs #22

Closed
netvl opened this issue Dec 27, 2019 · 4 comments · Fixed by #23
Closed

FETCH BODY[HEADER] hangs #22

netvl opened this issue Dec 27, 2019 · 4 comments · Fixed by #23

Comments

@netvl
Copy link
Contributor

netvl commented Dec 27, 2019

I can consistently observe that requests like

        let messages = session.fetch("7", "BODY[HEADER]").await.unwrap();

always hang when processing the messages stream, i.e. something like

        futures::pin_mut!(messages);
        let message = messages.next().await.unwrap();

never finishes.

The issue goes away if BODY[HEADER] is not requested, e.g. with BODY[TEXT] or UID or ENVELOPE or BODYSTRUCTURE. BODY[] does not work as well, so it seems that there is some issue with headers processing?

I see this consistently with different mailboxes and different messages on a Fastmail account (imap.fastmail.com).

All of these requests can be done just fine with a raw telnet connection to the server.

@netvl
Copy link
Contributor Author

netvl commented Dec 27, 2019

BTW, it does not seem that the debug flag

pub debug: bool,
is used anywhere, enabling it does not result in any kind of debug logs.

Edit: it seems that RUST_LOG=async_imap=trace does work though.

@netvl
Copy link
Contributor Author

netvl commented Dec 27, 2019

Ok, I've upgraded to the latest possible git version and now it looks like the fetch method returns an empty stream... Need to test more.

Edit: yup, using e.g. UID instead of BODY[HEADER] results in a non-empty stream.

@netvl
Copy link
Contributor Author

netvl commented Dec 27, 2019

This seems to happen with large enough data chunks. For example, for my test case I have the server return a literal of length 8088, and it seems to be split into several parts inside async_imap, however, only two parts are visible in the TRACE logs, and there are clearly more because these two parts don't contain the entirety of headers which I can see in the raw message.

Edit: interesting, results does not seem to be consistent - on the second run, I see more trace entries which are correct, but still no proper parsed output.

@netvl
Copy link
Contributor Author

netvl commented Dec 27, 2019

I think I found the reason - the problem is that the ImapStream::poll_next method does not persist the current (usize, usize) position in case the futures::ready! returns early because of Pending from the underlying stream. This results in the buffer being overwritten from the beginning upon the next non-pending poll, and therefore in partial data being passed to decode.

I might be able to send a PR to fix this later :)

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

Successfully merging a pull request may close this issue.

1 participant