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

Handle edge cases of failure for RETR command #51

Closed
robinrodricks opened this issue Feb 22, 2017 · 1 comment
Closed

Handle edge cases of failure for RETR command #51

robinrodricks opened this issue Feb 22, 2017 · 1 comment

Comments

@robinrodricks
Copy link
Owner

From crypto, by D. J. Bernstein

Normally the server responds with a mark using code 150. It then stops accepting new connections, attempts to send the contents of the file over the data connection, and closes the data connection. Finally it

  • accepts the RETR request with code 226 if the entire file was successfully written to the server's TCP buffers;
  • rejects the RETR request with code 425 if no TCP connection was established;
  • rejects the RETR request with code 426 if the TCP connection was established but then broken by the client or by network failure; or
  • rejects the RETR request with code 451 or 551 if the server had trouble reading the file from disk.

The server is obliged to close the data connection in each of these cases. The client is not expected to look for a response from the server until the client sees that the data connection is closed.

The server may reject the RETR request without first responding with a mark. In this case the server does not touch the data connection. RFC 959 allows code 550 for file-does-not-exist, permission-denied, etc., and code 450 for out-of-memory, disk-failure, etc.

The client needs to be prepared for many different ways that RETR can fail:

  • After sending the RETR request, the client reads one response from the server. If this response is anything but a mark (for example, the server can't find the file, or doesn't have permission to open it, or is temporarily out of memory, or the server crashes and the connection is closed without a response, or the server is overloaded and the client times out before receiving a response), the client stops and reports temporary failure.
  • After sending the RETR request and reading a mark, the client reads data from the data connection until FIN (end of file), or a TCP error (for example, TCP reset or network unreachable), or timeout. The client saves the data, remembers whether there was a FIN, and closes the data connection.
  • After sending the RETR request, reading a mark, reading data from the data connection, and closing the data connection, the client reads another response from the server. If this response is acceptance and the data connection ended with FIN, the client knows that it has received the entire file from the server. Otherwise the client reports temporary failure; the file has (probably) been truncated.

Note that code 226 from the server does not guarantee that the client has received, or will receive, the entire file. The client must check for TCP errors on the data connection.

Some clients do not close the data connection until they receive the 226 response from the server. This behavior is permitted by RFC 959. However, I recommend that clients close the data connection immediately after seeing the end of data.

@robinrodricks
Copy link
Owner Author

Added to the bucket list. We will pick this up as and when we have free time. Comment on this issue if you want us to prioritize it. Thanks!

@robinrodricks robinrodricks closed this as not planned Won't fix, can't repro, duplicate, stale Sep 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant