Repository navigation
Conversation
NewsCache sends one command at a time and reads each reply to its end, so the stream buffer is empty when the next command goes out. A news server that sends more than its reply, e.g. a block after a status line that announces none (215 and a list in reply to GROUP, 430 and text), left those lines there: the next command read them as its reply, and every later reply on the connection was shifted. The client got 430 for an article the server has, or 403. issue() now checks the buffer before it sends a command (in_avail: bytes already read from the socket, TLS or inflated, so a compressed connection's trailing flush bytes don't count) and, when anything is left, closes the connection and connects again; connect() selects the current group again. Inside connect() the set-up fails instead, and the caller tries again as for a lost connection. TestUpstreamReplyCorpus runs the 82 cases of nntp-testkit's reply corpus whose command NewsCache sends upstream (greeting, MODE READER, AUTHINFO, COMPRESS, GROUP, LISTGROUP, OVER, ARTICLE, LIST, STAT, POST, QUIT). Each case replaces the first reply on a connection; then a command that has to go to the server must get the right reply, DATE must still answer 111, and QUIT must end the session cleanly. Without the fix 10 cases fail (group-215-block, group-100-block, listgroup-215-block, list-231-block, list-282-block, over-225-block, article-222-block, article-430-block, stat-220-block, authinfo-user-215-block). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dist-hook refuses a tests/e2e Go file that isn't in EXTRA_DIST (found by the PR review). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A news server that sends more than its reply put NewsCache's connection to it out of step. Examples are a block after a status that announces none (215 and a list in reply to GROUP, 430 and text) or the rest of an overlong line. The next command read those lines as its reply, and every later reply was shifted, so the client got 430 for an article the server has, or 403.
Fix (
NServer-0.9.1/NServer.cc,RServer::issue, newRServer::stale_reply): NewsCache sends one command at a time and reads each reply to its end, so the stream buffer is empty before the next command.issue()now checksrdbuf()->in_avail()first. That counts bytes already read from the socket, from TLS or after inflating, so a compressed connection's trailing flush bytes don't count, and the check doesn't depend on timing. When anything is left, NewsCache closes the connection and connects again, andconnect()selects the current group again. Insideconnect()the set-up fails instead, and the caller retries as for a lost connection.Test (
tests/e2e/replycorpus_test.go,TestUpstreamReplyCorpus): runs the 82 cases of nntp-testkit v0.14.0's reply corpus whose command NewsCache sends upstream: the greeting, MODE READER, AUTHINFO, COMPRESS, GROUP, LISTGROUP, OVER, ARTICLE, LIST, STAT, POST and QUIT. Each case replaces the first reply on a connection. After the client steps, a command that has to go to the server must get the right reply (an article, or the overview for the ARTICLE cases). DATE must still answer 111, and QUIT must end the session with exit 0. For a reply to a set-up command, which comes again on every connection, a clean 403 is allowed, but wrong data isn't.NEWS:
changes/fix-upstream-stale-reply.md.🤖 Generated with Claude Code