Repository: encode/starlette

Issue:
Session cookie should use root path
The session cookie currently uses '/'.
It should really use the ASGI root path instead, in case the application is submounted.

Discussion:
JayH5: Thanks, this seems like a reasonable improvement. It does need a test, I think, though.
mahmoudhossam: I'm going to add a test and then we can merge this, thanks for the quick response!
mahmoudhossam: I couldn't find a way to set the root path directly on the app so I had to mount another app on the main one and tested that, seems to work as expected.
tomchristie: Ah fantastic, yup.

Patch:
diff --git a/starlette/middleware/sessions.py b/starlette/middleware/sessions.py
index d1b1d5a..a13ec5c 100644
--- a/starlette/middleware/sessions.py
+++ b/starlette/middleware/sessions.py
@@ -49,14 +49,16 @@ class SessionMiddleware:
 
         async def send_wrapper(message: Message) -> None:
             if message["type"] == "http.response.start":
+                path = scope.get("root_path", "") or "/"
                 if scope["session"]:
                     # We have session data to persist.
                     data = b64encode(json.dumps(scope["session"]).encode("utf-8"))
                     data = self.signer.sign(data)
                     headers = MutableHeaders(scope=message)
-                    header_value = "%s=%s; path=/; Max-Age=%d; %s" % (
+                    header_value = "%s=%s; path=%s; Max-Age=%d; %s" % (
                         self.session_cookie,
                         data.decode("utf-8"),
+                        path,
                         self.max_age,
                         self.security_flags,
                     )
@@ -66,7 +68,7 @@ class SessionMiddleware:
                     headers = MutableHeaders(scope=message)
                     header_value = "{}={}; {}".format(
                         self.session_cookie,
-                        "null; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT;",
+                        f"null; path={path}; expires=Thu, 01 Jan 1970 00:00:00 GMT;",
                         self.security_flags,
                     )
                     headers.append("Set-Cookie", header_value)


Test patch:
diff --git a/tests/middleware/test_session.py b/tests/middleware/test_session.py
index 3f71232..68cf36d 100644
--- a/tests/middleware/test_session.py
+++ b/tests/middleware/test_session.py
@@ -101,3 +101,15 @@ def test_secure_session():
 
     response = secure_client.get("/view_session")
     assert response.json() == {"session": {}}
+
+
+def test_session_cookie_subpath():
+    app = create_app()
+    second_app = create_app()
+    second_app.add_middleware(SessionMiddleware, secret_key="example")
+    app.mount("/second_app", second_app)
+    client = TestClient(app, base_url="http://testserver/second_app")
+    response = client.post("second_app/update_session", json={"some": "data"})
+    cookie = response.headers["set-cookie"]
+    cookie_path = re.search(r"; path=(\S+);", cookie).groups()[0]
+    assert cookie_path == "/second_app"