Skip to content

Commit fc1e089

Browse files
milanmajchrakclaude
andcommitted
TUL/Exclude /browse, /search and admin paths from SSR (port of upstream DSpace#4332)
Crawlers were feeding on SSR-rendered /browse pages: DSpace reflects unknown query params into generated links, and non-decoding crawlers turn the escaped separator into ever-growing amp;value params - an infinite URL space. On 7.5 every such URL is a full SSR render (~21 backend calls), which took the site down on Aug 6-9. Ports upstream dspace-7_x PR DSpace#4332 (excludePathPatterns) natively: excluded paths are served as CSR shell with no links to follow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 4035134 commit fc1e089

5 files changed

Lines changed: 87 additions & 4 deletions

File tree

server.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import { APP_CONFIG, AppConfig } from './src/config/app-config.interface';
5555
import { extendEnvironmentWithAppConfig } from './src/config/config.util';
5656
import { logStartupMessage } from './startup-message';
5757
import { TOKENITEM } from 'src/app/core/auth/models/auth-token-info.model';
58+
import { SsrExcludePatterns } from './src/config/universal-config.interface';
5859

5960

6061
/*
@@ -228,7 +229,7 @@ export function app() {
228229
* The callback function to serve server side angular
229230
*/
230231
function ngApp(req, res) {
231-
if (environment.universal.preboot) {
232+
if (environment.universal.preboot && req.method === 'GET' && (req.path === '/' || !isExcludedFromSsr(req.path, environment.universal.excludePathPatterns))) {
232233
// Render the page to user via SSR (server side rendering)
233234
serverSideRender(req, res);
234235
} else {
@@ -545,6 +546,21 @@ function start() {
545546
}
546547
}
547548

549+
/**
550+
* Check if SSR should be skipped for path
551+
*
552+
* @param path
553+
* @param excludePathPattern
554+
*/
555+
function isExcludedFromSsr(path: string, excludePathPattern: SsrExcludePatterns[]): boolean {
556+
const patterns = excludePathPattern.map(p =>
557+
new RegExp(p.pattern, p.flag || '')
558+
);
559+
return patterns.some((regex) => {
560+
return regex.test(path)
561+
});
562+
}
563+
548564
/*
549565
* The callback function to serve health check requests
550566
*/
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
import { Config } from './config.interface';
22

3+
export interface SsrExcludePatterns {
4+
pattern: string | RegExp;
5+
flag?: string;
6+
}
7+
38
export interface UniversalConfig extends Config {
49
preboot: boolean;
510
async: boolean;
611
time: boolean;
12+
13+
/**
14+
* Patterns to be used as regexes to match url's path and check if SSR is disabled for it.
15+
*/
16+
excludePathPatterns: SsrExcludePatterns[];
717
}

src/environments/environment.production.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,25 @@ export const environment: Partial<BuildConfig> = {
77
universal: {
88
preboot: true,
99
async: true,
10-
time: false
10+
time: false,
11+
excludePathPatterns: [
12+
{
13+
pattern: '^/communities/[a-f0-9-]{36}/browse(/.*)?$',
14+
flag: 'i',
15+
},
16+
{
17+
pattern: '^/collections/[a-f0-9-]{36}/browse(/.*)?$',
18+
flag: 'i',
19+
},
20+
{ pattern: '^/browse/' },
21+
{ pattern: '^/search' },
22+
{ pattern: '^/community-list$' },
23+
{ pattern: '^/statistics/?' },
24+
{ pattern: '^/admin/' },
25+
{ pattern: '^/processes/?' },
26+
{ pattern: '^/notifications/' },
27+
{ pattern: '^/access-control/' },
28+
{ pattern: '^/health$' },
29+
],
1130
}
1231
};

src/environments/environment.test.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,26 @@ export const environment: BuildConfig = {
1010
universal: {
1111
preboot: true,
1212
async: true,
13-
time: false
13+
time: false,
14+
excludePathPatterns: [
15+
{
16+
pattern: '^/communities/[a-f0-9-]{36}/browse(/.*)?$',
17+
flag: 'i',
18+
},
19+
{
20+
pattern: '^/collections/[a-f0-9-]{36}/browse(/.*)?$',
21+
flag: 'i',
22+
},
23+
{ pattern: '^/browse/' },
24+
{ pattern: '^/search' },
25+
{ pattern: '^/community-list$' },
26+
{ pattern: '^/statistics/?' },
27+
{ pattern: '^/admin/' },
28+
{ pattern: '^/processes/?' },
29+
{ pattern: '^/notifications/' },
30+
{ pattern: '^/access-control/' },
31+
{ pattern: '^/health$' },
32+
],
1433
},
1534

1635
// Angular Universal server settings.

src/environments/environment.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,26 @@ export const environment: Partial<BuildConfig> = {
1212
universal: {
1313
preboot: false,
1414
async: true,
15-
time: false
15+
time: false,
16+
excludePathPatterns: [
17+
{
18+
pattern: '^/communities/[a-f0-9-]{36}/browse(/.*)?$',
19+
flag: 'i',
20+
},
21+
{
22+
pattern: '^/collections/[a-f0-9-]{36}/browse(/.*)?$',
23+
flag: 'i',
24+
},
25+
{ pattern: '^/browse/' },
26+
{ pattern: '^/search' },
27+
{ pattern: '^/community-list$' },
28+
{ pattern: '^/statistics/?' },
29+
{ pattern: '^/admin/' },
30+
{ pattern: '^/processes/?' },
31+
{ pattern: '^/notifications/' },
32+
{ pattern: '^/access-control/' },
33+
{ pattern: '^/health$' },
34+
],
1635
},
1736

1837
// The REST API server settings.

0 commit comments

Comments
 (0)