Streamable HTTP client: update the stored endpoint URI after a 308
Mantenedores costumam responder em até 3 dias
@connor4312 já está trabalhando nisso.
Desde 16/10/2026.
Avaliação
Esta issue ainda não foi avaliada.
Descrição
Follow-up from #1203 and #1367.
Problem
After #1367, the default Streamable HTTP client follows same-origin 307 and 308 redirects. But it never saves the new location. Every request still goes to the configured URI first and gets redirected again.
A 308 means the move is permanent, so the client could send later requests straight to the new URI.
Current behavior
At a156be8, the URI lives in StreamableHttpClientTransportConfig::uri. The worker clones the config once and never changes it. Each request copies the URI from there:
- POST:
post_request, and the initialize POSTs at startup and in the fallback path. - Standalone GET stream: resumption with
Last-Event-IDuses its own copy inStreamableHttpClientReconnect. - SSE on a POST response: resumption gets a copy too.
- Re-initialization after a 404:
perform_reinitialization. - DELETE on close:
SessionCleanupInfoholds its own copy, used at exit.
All of these requests use the same reqwest::Client, so the redirect policy applies to GET and DELETE too, not only POST.
reqwest gives us the final URL through Response::url(), but not the status of each hop. The Policy::custom closure sees each hop's status. However, one policy is shared by every request on the client, and it can't tell which request a hop belongs to.
Proposal
- Only save the new URI when every hop in the chain is a 308. If any hop is a 307, keep the configured URI.
- Have the
runloop keep the current URI, since it already owns the session state. Use that URI for new POSTs, new GET streams, re-initialization and the DELETE. - Return the final URL from the client to the worker.
StreamableHttpPostResponsedoesn't carry a URL today.
To find out whether every hop was a 308, we could:
- Stop on 308 in the policy and follow it by hand in the reqwest
StreamableHttpClientimpl, with the same origin and hop-limit checks. - Record hops from the policy closure into shared state. This is unreliable when concurrent requests start from the same URI.
Open questions
- Same-origin is already enforced, so only the path and query can change. Do we need any other check?
- Should the session ID carry over to the new URI, or should the client re-initialize?
- OAuth:
AuthorizationManagerkeeps its ownbase_url. It's the fallbackresource, and the protected resource metadataresourceis checked against it. If the transport URI moves andbase_urldoesn't, they no longer match, and there's no way to updatebase_urltoday. Should we skip the update whenAuthClientwraps the transport, or move both? - Requests and streams already in flight keep the old URI. Is that fine, or should resumption pick up the new one?
- Default client only, or also clients passed to
with_client?
Related
- #1203: the original redirect report
- #1367: follows same-origin 307/308 in the default client
- The TypeScript and Python SDKs don't update the stored URL either. Both follow same-origin redirects and keep the configured URL (TypeScript, Python).
- Linguagem predominante
- Rust
- Estrelas
- 4.1k
- Forks
- 694
- Merge médio
- 4d 16h
- PRs com merge (30d)
- 43
Preparar o ambiente
Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.
- Sem Dockerfile nem arquivo Docker Compose
- Sem modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de modelcontextprotocol/rust-sdk
-
Return MergedList<T> from list_all_* and drop the _with_cache_hint variantsTalvez já em andamento @DaleSeo assumiu há 1 dia. Abertaenhancement P3 ready for work T-service v4
modelcontextprotocol/rust-sdk#1430 · 1 responsável ·
Mantenedores costumam responder em até 3 dias
-
Server logs a fabricated 'initialize' (with synthesized rmcp/3.8.0 peer identity) for no-initialize SEP-2567 requests, ignoring clientInfo from _metaTalvez já em andamento @jamadeo assumiu há 1 dia. Abertabug P2 ready for work T-service T-transport
modelcontextprotocol/rust-sdk#1425 · 2 comentários · 1 responsável ·
Mantenedores costumam responder em até 3 dias
-
OAuth discovery drops explicit default ports from advertised issuer identifiersTalvez já em andamento @gocamille assumiu há 3 dias. Abertabug P1 ready for work T-security T-transport
modelcontextprotocol/rust-sdk#1420 · 2 comentários · 1 responsável ·
Mantenedores costumam responder em até 3 dias
-
`register_client` drops `client_secret_expires_at` from the registration responseTalvez já em andamento @gocamille assumiu há 5 dias. Abertabug P2 ready for work T-security
modelcontextprotocol/rust-sdk#1416 · 1 comentário · 1 responsável ·
Mantenedores costumam responder em até 3 dias
-
Typed client calls drop the parse error when a reply misses a required fieldTalvez já em andamento @gocamille assumiu há 5 dias. Abertaenhancement P2 ready for work T-core T-service
modelcontextprotocol/rust-sdk#1415 · 1 comentário · 1 responsável ·
Mantenedores costumam responder em até 3 dias
Todas as issues de modelcontextprotocol/rust-sdk
Issues semelhantes
-
bug file-compat priority: high
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
storytold/photocraft#11330 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
redis-compat
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
Mantenedores costumam responder em até 1 dia
-
say: name hint should only fire on @tags, not bare words or text inside linksTalvez já em andamento @morganparadis assumiu hoje. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
CakeRepository/agentshangout#501 ·
-
area:ui could docs good first issue
Dificuldade 1/5 1-3 horas Facilidade para iniciantes 79/100
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100