@angular/ssr 21.2.7 → 21.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/fesm2022/ssr.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { validateRequest, cloneRequestAndPatchHeaders } from './_validation-chunk.mjs';
1
+ import { normalizeTrustProxyHeaders, sanitizeRequestHeaders, validateRequest } from './_validation-chunk.mjs';
2
2
  import { APP_BASE_HREF, PlatformLocation } from '@angular/common';
3
3
  import { ɵConsole as _Console, ApplicationRef, REQUEST, makeEnvironmentProviders, provideEnvironmentInitializer, inject, InjectionToken, ɵENABLE_ROOT_COMPONENT_BOOTSTRAP as _ENABLE_ROOT_COMPONENT_BOOTSTRAP, Compiler, createEnvironmentInjector, EnvironmentInjector, runInInjectionContext, ɵresetCompiledComponents as _resetCompiledComponents, REQUEST_CONTEXT, RESPONSE_INIT, LOCALE_ID } from '@angular/core';
4
4
  import { platformServer, INITIAL_CONFIG, ɵSERVER_CONTEXT as _SERVER_CONTEXT, ɵrenderInternal as _renderInternal, provideServerRendering as provideServerRendering$1 } from '@angular/platform-server';
@@ -166,12 +166,12 @@ async function renderAngular(html, bootstrap, url, platformProviders, serverCont
166
166
  search,
167
167
  hash
168
168
  } = envInjector.get(PlatformLocation);
169
- const finalUrl = constructDecodedUrl({
169
+ const finalUrl = constructSerializedUrl(router, {
170
170
  pathname,
171
171
  search,
172
172
  hash
173
173
  }, requestPrefix);
174
- const urlToRenderString = constructDecodedUrl(urlToRender, requestPrefix);
174
+ const urlToRenderString = constructSerializedUrl(router, urlToRender, requestPrefix);
175
175
  if (urlToRenderString !== finalUrl) {
176
176
  redirectTo = [pathname, search, hash].join('');
177
177
  }
@@ -207,7 +207,7 @@ function asyncDestroyPlatform(platformRef) {
207
207
  }, 0);
208
208
  });
209
209
  }
210
- function constructDecodedUrl(url, prefix) {
210
+ function constructSerializedUrl(router, url, prefix) {
211
211
  const {
212
212
  pathname,
213
213
  hash,
@@ -220,7 +220,8 @@ function constructDecodedUrl(url, prefix) {
220
220
  urlParts.push(stripTrailingSlash(pathname));
221
221
  }
222
222
  urlParts.push(search, hash);
223
- return decodeURIComponent(urlParts.join(''));
223
+ const urlTree = router.parseUrl(urlParts.join(''));
224
+ return router.serializeUrl(urlTree);
224
225
  }
225
226
 
226
227
  function promiseWithAbort(promise, signal, errorMessagePrefix) {
@@ -386,7 +387,7 @@ class RouteTree {
386
387
  }
387
388
  }
388
389
  getPathSegments(route) {
389
- return route.split('/').filter(Boolean);
390
+ return route.split('/').filter(Boolean).map(decodeURIComponent);
390
391
  }
391
392
  traverseBySegments(segments, node = this.root, currentIndex = 0) {
392
393
  if (currentIndex >= segments.length) {
@@ -939,7 +940,6 @@ class ServerRouter {
939
940
  pathname
940
941
  } = stripIndexHtmlFromURL(url);
941
942
  pathname = stripMatrixParams(pathname);
942
- pathname = decodeURIComponent(pathname);
943
943
  return this.routeTree.match(pathname);
944
944
  }
945
945
  }
@@ -1176,8 +1176,7 @@ class AngularServerApp {
1176
1176
  redirectTo,
1177
1177
  status,
1178
1178
  renderMode,
1179
- headers
1180
- } = matchedRoute;
1179
+ headers} = matchedRoute;
1181
1180
  if (redirectTo !== undefined) {
1182
1181
  return createRedirectResponse(joinUrlParts(request.headers.get('X-Forwarded-Prefix') ?? '', buildPathWithParams(redirectTo, url.pathname)), status, headers);
1183
1182
  }
@@ -1492,9 +1491,11 @@ class AngularAppEngine {
1492
1491
  manifest = getAngularAppEngineManifest();
1493
1492
  allowedHosts;
1494
1493
  supportedLocales = Object.keys(this.manifest.supportedLocales);
1494
+ trustProxyHeaders;
1495
1495
  entryPointsCache = new Map();
1496
1496
  constructor(options) {
1497
1497
  this.allowedHosts = this.getAllowedHosts(options);
1498
+ this.trustProxyHeaders = normalizeTrustProxyHeaders(options?.trustProxyHeaders);
1498
1499
  }
1499
1500
  getAllowedHosts(options) {
1500
1501
  const allowedHosts = new Set([...(options?.allowedHosts ?? []), ...this.manifest.allowedHosts]);
@@ -1505,27 +1506,21 @@ class AngularAppEngine {
1505
1506
  }
1506
1507
  async handle(request, requestContext) {
1507
1508
  const allowedHost = this.allowedHosts;
1508
- const disableAllowedHostsCheck = AngularAppEngine.ɵdisableAllowedHostsCheck;
1509
+ const {
1510
+ request: securedRequest,
1511
+ deoptToCSR
1512
+ } = sanitizeRequestHeaders(request, this.trustProxyHeaders);
1509
1513
  try {
1510
- validateRequest(request, allowedHost, disableAllowedHostsCheck);
1514
+ validateRequest(securedRequest, allowedHost, AngularAppEngine.ɵdisableAllowedHostsCheck);
1511
1515
  } catch (error) {
1512
- return this.handleValidationError(error, request);
1516
+ return this.handleValidationError(error, securedRequest);
1513
1517
  }
1514
- const {
1515
- request: securedRequest,
1516
- onError: onHeaderValidationError
1517
- } = disableAllowedHostsCheck ? {
1518
- request,
1519
- onError: null
1520
- } : cloneRequestAndPatchHeaders(request, allowedHost);
1521
1518
  const serverApp = await this.getAngularServerAppForRequest(securedRequest);
1522
1519
  if (serverApp) {
1523
- const promises = [];
1524
- if (onHeaderValidationError) {
1525
- promises.push(onHeaderValidationError.then(error => this.handleValidationError(error, securedRequest)));
1520
+ if (deoptToCSR) {
1521
+ return serverApp.serveClientSidePage();
1526
1522
  }
1527
- promises.push(serverApp.handle(securedRequest, requestContext));
1528
- return Promise.race(promises);
1523
+ return serverApp.handle(securedRequest, requestContext);
1529
1524
  }
1530
1525
  if (this.supportedLocales.length > 1) {
1531
1526
  return this.redirectBasedOnAcceptLanguage(securedRequest);