Skip to content

Commit 1b8e45f

Browse files
authored
Merge pull request #261 from koic/return_404_for_invalid_session_id_in_handle_delete
Return 404 for invalid session ID in `handle_delete`
2 parents 910d3ca + abc7d6c commit 1b8e45f

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

lib/mcp/server/transports/streamable_http_transport.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,10 @@ def handle_delete(request)
155155
end
156156

157157
return missing_session_id_response unless (session_id = request.env["HTTP_MCP_SESSION_ID"])
158+
return session_not_found_response unless session_exists?(session_id)
158159

159160
cleanup_session(session_id)
161+
160162
success_response
161163
end
162164

test/mcp/server/transports/streamable_http_transport_test.rb

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,84 @@ class StreamableHTTPTransportTest < ActiveSupport::TestCase
332332
assert body["success"]
333333
end
334334

335+
test "handles DELETE request with invalid session ID" do
336+
request = create_rack_request(
337+
"DELETE",
338+
"/",
339+
{ "HTTP_MCP_SESSION_ID" => "invalid_id" },
340+
)
341+
342+
response = @transport.handle_request(request)
343+
assert_equal 404, response[0]
344+
assert_equal({ "Content-Type" => "application/json" }, response[1])
345+
346+
body = JSON.parse(response[2][0])
347+
assert_equal "Session not found", body["error"]
348+
end
349+
350+
test "POST returns 404 after session is deleted" do
351+
init_request = create_rack_request(
352+
"POST",
353+
"/",
354+
{ "CONTENT_TYPE" => "application/json" },
355+
{ jsonrpc: "2.0", method: "initialize", id: "init" }.to_json,
356+
)
357+
init_response = @transport.handle_request(init_request)
358+
session_id = init_response[1]["Mcp-Session-Id"]
359+
360+
delete_request = create_rack_request(
361+
"DELETE",
362+
"/",
363+
{ "HTTP_MCP_SESSION_ID" => session_id },
364+
)
365+
@transport.handle_request(delete_request)
366+
367+
post_request = create_rack_request(
368+
"POST",
369+
"/",
370+
{
371+
"CONTENT_TYPE" => "application/json",
372+
"HTTP_MCP_SESSION_ID" => session_id,
373+
},
374+
{ jsonrpc: "2.0", method: "ping", id: "456" }.to_json,
375+
)
376+
response = @transport.handle_request(post_request)
377+
assert_equal 404, response[0]
378+
379+
body = JSON.parse(response[2][0])
380+
assert_equal "Session not found", body["error"]
381+
end
382+
383+
test "DELETE returns 404 after session is already deleted" do
384+
init_request = create_rack_request(
385+
"POST",
386+
"/",
387+
{ "CONTENT_TYPE" => "application/json" },
388+
{ jsonrpc: "2.0", method: "initialize", id: "init" }.to_json,
389+
)
390+
init_response = @transport.handle_request(init_request)
391+
session_id = init_response[1]["Mcp-Session-Id"]
392+
393+
first_delete = create_rack_request(
394+
"DELETE",
395+
"/",
396+
{ "HTTP_MCP_SESSION_ID" => session_id },
397+
)
398+
response = @transport.handle_request(first_delete)
399+
assert_equal 200, response[0]
400+
401+
second_delete = create_rack_request(
402+
"DELETE",
403+
"/",
404+
{ "HTTP_MCP_SESSION_ID" => session_id },
405+
)
406+
response = @transport.handle_request(second_delete)
407+
assert_equal 404, response[0]
408+
409+
body = JSON.parse(response[2][0])
410+
assert_equal "Session not found", body["error"]
411+
end
412+
335413
test "handles DELETE request with missing session ID" do
336414
request = create_rack_request(
337415
"DELETE",

0 commit comments

Comments
 (0)