From 857036b7cd7c7458773fd3e0cbff376844356287 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Wed, 22 Jul 2026 13:06:21 -0700 Subject: [PATCH] media: serialize the mist pull request with net/http, not by hand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tryMistGET still dials its own conn — that part is load-bearing (the raw fd gets passed to the detached worker, which http.Client can't provide) — but the request itself is now a real *http.Request written with req.Write instead of a concatenated header string, and http.ReadResponse gets the request for context. Same wire bytes, stdlib framing. The %2B-escaped wildcard path survives req.Write via URL.RawPath (covered by TestMistPullConnect's EscapedPath assertion). Co-Authored-By: Claude Fable 5 --- pkg/media/mist_pull.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/pkg/media/mist_pull.go b/pkg/media/mist_pull.go index 528dcad44..66d473be9 100644 --- a/pkg/media/mist_pull.go +++ b/pkg/media/mist_pull.go @@ -103,23 +103,28 @@ func tryMistGET(ctx context.Context, hostport, path string) (*net.TCPConn, []byt raw.Close() return nil, nil, false, fmt.Errorf("expected TCP connection, got %T", raw) } - // Connection: close — one stream per connection, body runs to EOF (or + // A real *http.Request serialized by the stdlib — we only own the conn by + // hand (it gets fd-passed to the worker), not the HTTP framing. req.Close + // sends Connection: close: one stream per connection, body runs to EOF (or // chunked-EOS) when the Mist stream ends. No keepalive reuse to reason about. - req := "GET " + path + " HTTP/1.1\r\n" + - "Host: " + hostport + "\r\n" + - "User-Agent: streamplace-ingest\r\n" + - "Accept: video/mp4\r\n" + - "Connection: close\r\n\r\n" + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://"+hostport+path, nil) + if err != nil { + conn.Close() + return nil, nil, false, err + } + req.Close = true + req.Header.Set("User-Agent", "streamplace-ingest") + req.Header.Set("Accept", "video/mp4") if err := conn.SetDeadline(time.Now().Add(10 * time.Second)); err != nil { conn.Close() return nil, nil, false, err } - if _, err := io.WriteString(conn, req); err != nil { + if err := req.Write(conn); err != nil { conn.Close() return nil, nil, false, err } br := bufio.NewReader(conn) - resp, err := http.ReadResponse(br, nil) + resp, err := http.ReadResponse(br, req) if err != nil { conn.Close() return nil, nil, false, err -- 2.51.2