From d3f7d77316e13ad4d7a714559b505dca1963f722 Mon Sep 17 00:00:00 2001
From: szymonrybczak <szymon.rybczak@gmail.com>
Date: Fri, 30 Aug 2024 13:46:47 +0200
Subject: [PATCH] fix: invalid character in header

---
 .../__tests__/statusPageMiddleware.test.ts    | 30 ++++++++++++++++---
 .../src/statusPageMiddleware.ts               |  5 +++-
 packages/cli-tools/src/getNextPort.ts         |  5 +++-
 3 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/packages/cli-server-api/src/__tests__/statusPageMiddleware.test.ts b/packages/cli-server-api/src/__tests__/statusPageMiddleware.test.ts
index 3c783a948..8d92ff55e 100644
--- a/packages/cli-server-api/src/__tests__/statusPageMiddleware.test.ts
+++ b/packages/cli-server-api/src/__tests__/statusPageMiddleware.test.ts
@@ -2,15 +2,25 @@ import http from 'http';
 import statusPageMiddleware from './../statusPageMiddleware';
 
 describe('statusPageMiddleware', () => {
-  it('should set headers and end the response', () => {
-    process.cwd = () => '/mocked/path';
+  let res: jest.Mocked<http.ServerResponse>;
+  let mockReq: http.IncomingMessage;
 
-    const res: http.ServerResponse = {
+  beforeEach(() => {
+    res = {
       setHeader: jest.fn(),
       end: jest.fn(),
     } as any;
 
-    const mockReq: http.IncomingMessage = {} as any;
+    mockReq = {} as any;
+  });
+
+  afterEach(() => {
+    jest.restoreAllMocks();
+  });
+
+  it('should set headers and end the response', () => {
+    jest.spyOn(process, 'cwd').mockReturnValue('/mocked/path');
+
     statusPageMiddleware(mockReq, res);
 
     // We're strictly checking response here, because React Native is strongly depending on this response. Changing the response might be a breaking change.
@@ -20,4 +30,16 @@ describe('statusPageMiddleware', () => {
     );
     expect(res.end).toHaveBeenCalledWith('packager-status:running');
   });
+
+  it('should set headers and end the response with decoded value', () => {
+    jest.spyOn(process, 'cwd').mockReturnValue('/привіт/path');
+
+    statusPageMiddleware(mockReq, res);
+
+    expect(res.setHeader).toHaveBeenCalledWith(
+      'X-React-Native-Project-Root',
+      '/%D0%BF%D1%80%D0%B8%D0%B2%D1%96%D1%82/path',
+    );
+    expect(res.end).toHaveBeenCalledWith('packager-status:running');
+  });
 });
diff --git a/packages/cli-server-api/src/statusPageMiddleware.ts b/packages/cli-server-api/src/statusPageMiddleware.ts
index 3e98f2b2b..b7d690752 100644
--- a/packages/cli-server-api/src/statusPageMiddleware.ts
+++ b/packages/cli-server-api/src/statusPageMiddleware.ts
@@ -14,6 +14,9 @@ export default function statusPageMiddleware(
   _req: http.IncomingMessage,
   res: http.ServerResponse,
 ) {
-  res.setHeader('X-React-Native-Project-Root', process.cwd());
+  res.setHeader(
+    'X-React-Native-Project-Root',
+    new URL(`file:///${process.cwd()}`).pathname.slice(1),
+  );
   res.end('packager-status:running');
 }
diff --git a/packages/cli-tools/src/getNextPort.ts b/packages/cli-tools/src/getNextPort.ts
index 374fe13c7..be4a5a4d0 100644
--- a/packages/cli-tools/src/getNextPort.ts
+++ b/packages/cli-tools/src/getNextPort.ts
@@ -19,7 +19,10 @@ const getNextPort = async (port: number, root: string): Promise<Result> => {
 
   const isRunning = typeof result === 'object' && result.status === 'running';
 
-  if (isRunning && result.root === root) {
+  if (
+    isRunning &&
+    result.root === new URL(`file:///${root}`).pathname.slice(1)
+  ) {
     // Found running bundler for this project, so we do not need to start packager!
     start = false;
   } else if (isRunning || result === 'unrecognized') {