diff --git a/packages/angular/ssr/node/src/request.ts b/packages/angular/ssr/node/src/request.ts index 51331a18cc35..f99e40491b07 100644 --- a/packages/angular/ssr/node/src/request.ts +++ b/packages/angular/ssr/node/src/request.ts @@ -33,12 +33,14 @@ export function createWebRequestFromNodeRequest( ): Request { const { headers, method = 'GET' } = nodeRequest; const withBody = method !== 'GET' && method !== 'HEAD'; + const referrer = headers.referer && URL.canParse(headers.referer) ? headers.referer : undefined; return new Request(createRequestUrl(nodeRequest), { method, headers: createRequestHeaders(headers), body: withBody ? nodeRequest : undefined, duplex: withBody ? 'half' : undefined, + referrer, }); } diff --git a/packages/angular/ssr/node/test/request_http1_spec.ts b/packages/angular/ssr/node/test/request_http1_spec.ts index 6559af458954..87f25f918ef7 100644 --- a/packages/angular/ssr/node/test/request_http1_spec.ts +++ b/packages/angular/ssr/node/test/request_http1_spec.ts @@ -45,7 +45,7 @@ describe('createWebRequestFromNodeRequest (HTTP/1.1)', () => { server.close(done); }); - describe('GET Handling', () => { + describe('GET handling', () => { it('should correctly handle a basic GET request', async () => { const nodeRequest = await extractNodeRequest(() => { request({ @@ -96,9 +96,51 @@ describe('createWebRequestFromNodeRequest (HTTP/1.1)', () => { expect(webRequest.headers.get('x-custom-header1')).toBe('value1'); expect(webRequest.headers.get('x-custom-header2')).toBe('value2'); }); + + it('should correctly handle the referer header', async () => { + const referer = 'http://test-referer-site.com/page'; + const nodeRequest = await extractNodeRequest(() => { + request({ + hostname: 'localhost', + port, + path: '/with-referer', + method: 'GET', + headers: { + referer, + }, + }).end(); + }); + + expect(nodeRequest.headers['referer']).toBe(referer); + + const webRequest = createWebRequestFromNodeRequest(nodeRequest); + expect(webRequest.headers.get('referer')).toBe(referer); + expect(webRequest.referrer).toBe(referer); + }); + + it('should handle an invalid referer header gracefully', async () => { + const invalidReferer = '/invalid-referer'; + const nodeRequest = await extractNodeRequest(() => { + request({ + hostname: 'localhost', + port, + path: '/with-invalid-referer', + method: 'GET', + headers: { + referer: invalidReferer, + }, + }).end(); + }); + + expect(nodeRequest.headers['referer']).toBe(invalidReferer); + + const webRequest = createWebRequestFromNodeRequest(nodeRequest); + expect(webRequest.headers.get('referer')).toBe(invalidReferer); + expect(webRequest.referrer).toBe('about:client'); + }); }); - describe('POST Handling', () => { + describe('POST handling', () => { it('should handle POST request with JSON body and correct response', async () => { const postData = JSON.stringify({ message: 'Hello from POST' }); const nodeRequest = await extractNodeRequest(() => { diff --git a/packages/angular/ssr/node/test/request_http2_spec.ts b/packages/angular/ssr/node/test/request_http2_spec.ts index 4d9754d20cfc..7079a385daaf 100644 --- a/packages/angular/ssr/node/test/request_http2_spec.ts +++ b/packages/angular/ssr/node/test/request_http2_spec.ts @@ -56,7 +56,7 @@ describe('createWebRequestFromNodeRequest (HTTP/2)', () => { server.close(done); }); - describe('GET Handling', () => { + describe('GET handling', () => { it('should correctly handle a basic GET request', async () => { const nodeRequest = await extractNodeRequest(() => { client @@ -106,9 +106,48 @@ describe('createWebRequestFromNodeRequest (HTTP/2)', () => { expect(webRequest.headers.get('x-custom-header1')).toBe('value1'); expect(webRequest.headers.get('x-custom-header2')).toBe('value2'); }); + + it('should correctly handle the referer header', async () => { + const referer = 'http://test-referer-site.com/page'; + const nodeRequest = await extractNodeRequest(() => { + client + .request({ + ':path': '/with-referer', + ':method': 'GET', + referer, + }) + .end(); + }); + + expect(nodeRequest.headers['referer']).toBe(referer); + + const webRequest = createWebRequestFromNodeRequest(nodeRequest); + expect(webRequest.headers.get('referer')).toBe(referer); + expect(webRequest.referrer).toBe(referer); + expect(webRequest.url).toBe(`http://localhost:${port}/with-referer`); + }); + + it('should handle an invalid referer header gracefully', async () => { + const invalidReferer = '/invalid-referer'; + const nodeRequest = await extractNodeRequest(() => { + client + .request({ + ':path': '/with-referer', + ':method': 'GET', + referer: invalidReferer, + }) + .end(); + }); + + expect(nodeRequest.headers['referer']).toBe(invalidReferer); + + const webRequest = createWebRequestFromNodeRequest(nodeRequest); + expect(webRequest.headers.get('referer')).toBe(invalidReferer); + expect(webRequest.referrer).toBe('about:client'); + }); }); - describe('POST Handling', () => { + describe('POST handling', () => { it('should handle POST request with JSON body and correct response', async () => { const postData = JSON.stringify({ message: 'Hello from POST' }); const nodeRequest = await extractNodeRequest(() => {