MCPcopy Create free account
hub / github.com/php/frankenphp / TestSessionNoLeakAfterExit_worker

Function TestSessionNoLeakAfterExit_worker

frankenphp_test.go:1260–1314  ·  view source on GitHub ↗
(t *testing.T)

Source from the content-addressed store, hash-verified

1258}
1259
1260func TestSessionNoLeakAfterExit_worker(t *testing.T) {
1261 runTest(t, func(_ func(http.ResponseWriter, *http.Request), ts *httptest.Server, i int) {
1262 // Client A: Set a secret value in session and call exit(1)
1263 clientA := &http.Client{}
1264 resp1, err := clientA.Get(ts.URL + "/session-leak.php?action=set_and_exit&value=exit_secret&client_id=exitClient")
1265 assert.NoError(t, err)
1266 body1, _ := io.ReadAll(resp1.Body)
1267 _ = resp1.Body.Close()
1268
1269 body1Str := string(body1)
1270 t.Logf("Client A set and exit: %s", body1Str)
1271 // The response may be incomplete due to exit(1)
1272 assert.Contains(t, body1Str, "BEFORE_EXIT")
1273
1274 // Client B: Check that session is empty (should not see Client A's data)
1275 // Retry until the worker has restarted after exit(1)
1276 clientB := &http.Client{}
1277 var body2Str string
1278 assert.Eventually(t, func() bool {
1279 resp2, err := clientB.Get(ts.URL + "/session-leak.php?action=check_empty")
1280 if err != nil {
1281 return false
1282 }
1283 body2, _ := io.ReadAll(resp2.Body)
1284 _ = resp2.Body.Close()
1285 body2Str = string(body2)
1286 return strings.Contains(body2Str, "SESSION_CHECK")
1287 }, 2*time.Second, 10*time.Millisecond, "Worker did not restart in time after exit(1)")
1288
1289 t.Logf("Client B check empty after exit: %s", body2Str)
1290 assert.Contains(t, body2Str, "SESSION_EMPTY=true",
1291 "Client B should have empty session after Client A's exit(1).\nResponse: %s", body2Str)
1292 assert.NotContains(t, body2Str, "exit_secret",
1293 "Client A's secret should not leak to Client B after exit(1).\nResponse: %s", body2Str)
1294
1295 // Client C: Try to read session (should also be empty)
1296 clientC := &http.Client{}
1297 resp3, err := clientC.Get(ts.URL + "/session-leak.php?action=get")
1298 assert.NoError(t, err)
1299 body3, _ := io.ReadAll(resp3.Body)
1300 _ = resp3.Body.Close()
1301
1302 body3Str := string(body3)
1303 t.Logf("Client C get session after exit: %s", body3Str)
1304 assert.Contains(t, body3Str, "SESSION_READ")
1305 assert.Contains(t, body3Str, "secret=NOT_FOUND",
1306 "Client C should not find any secret after exit(1).\nResponse: %s", body3Str)
1307
1308 }, &testOptions{
1309 workerScript: "session-leak.php",
1310 nbWorkers: 1,
1311 nbParallelRequests: 1,
1312 realServer: true,
1313 })
1314}
1315
1316func TestOpcachePreload_module(t *testing.T) {
1317 testOpcachePreload(t, &testOptions{env: map[string]string{"TEST": "123"}, realServer: true})

Callers

nothing calls this directly

Calls 3

runTestFunction · 0.85
GetMethod · 0.80
CloseMethod · 0.80

Tested by

no test coverage detected