Skip to content

Fix blocking mux reads and RAW download parsing#221

Open
durck wants to merge 3 commits into
NHAS:unstablefrom
durck:fix/raw-download-request-read-v2
Open

Fix blocking mux reads and RAW download parsing#221
durck wants to merge 3 commits into
NHAS:unstablefrom
durck:fix/raw-download-request-read-v2

Conversation

@durck

@durck durck commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep bufferedConn as a prefix replay wrapper and avoid reading from the underlying connection while buffered prefix data is still available.
  • Add a regression test that uses a 4096-byte caller buffer with a blocking underlying connection.
  • Read RAW download requests with bounded protocol parsing instead of relying on a single TCP read.
  • Cover .sh, .ps1, raw/binary filenames, split TCP chunks, empty names, and over-length names.

Validation

  • go test -count=1 ./pkg/mux ./internal/server/tcp

This replaces #220 after the source branch was accidentally deleted while cleaning stale branches in my fork.

Comment thread pkg/mux/bufferedConn.go
}

return n, err
return n, nil

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good as in hindsight this definitely was a mistake

io.Copy(conn, file)
}

func readRawDownloadName(conn net.Conn) (string, error) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This chain of random functions makes it much much harder to reason about what this code is doing

@NHAS NHAS left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you just explain the rationale around why you've changed the function parsing the raw download request

Comment thread internal/server/tcp/downloader.go Outdated
limit := len(rawDownloadPrefix) + rawDownloadMaxNameLength + 1

for {
fragment, err := reader.ReadSlice('\n')

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we reading until \n here?

Comment thread internal/server/tcp/downloader.go Outdated
}

func readRawDownloadRequest(reader *bufio.Reader) (string, error) {
var request []byte

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using both a bufio reader and then also a buffer that we're appending to here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that makes sense. The rationale for changing this was to avoid relying on a single conn.Read() returning the full RAW<name> request. Since this is TCP, the request can be split across reads, and the old code could parse a partial filename.

The \n handling came from the generated raw download command using echo RAW<name>&3, so the normal request is line-delimited. I kept EOF as a valid terminator as well for callers that send RAW<name> without a newline.

That said, I agree the current helper split makes this look more complicated than the protocol needs. I can simplify it so the raw request parsing is easier to follow while keeping the important behavior:

  • bounded read
  • support split TCP chunks
  • accept newline or EOF as the request terminator
  • preserve the existing 64-byte filename limit

@durck durck requested a review from NHAS July 9, 2026 08:56
@durck

durck commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Updated this to simplify the RAW request parsing.

The parser now keeps the bounded read and split-TCP-chunk handling, but removes the bufio.Reader + helper chain. It reads the small RAW<name> request directly until newline or EOF, preserves the 64-byte filename limit, and keeps the existing regression coverage.

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 this pull request may close these issues.

2 participants