Skip to content

Commit 70f68e9

Browse files
introduce a new option for configuring ignored routes (#679)
1 parent 1c039ab commit 70f68e9

File tree

6 files changed

+35
-4
lines changed

6 files changed

+35
-4
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ ignored.
182182
| `--signature-type` | `FUNCTION_SIGNATURE_TYPE` | The signature used when writing your function. Controls unmarshalling rules and determines which arguments are used to invoke your function. Default: `http`; accepted values: `http` or `event` or `cloudevent` |
183183
| `--source` | `FUNCTION_SOURCE` | The path to the directory of your function. Default: `cwd` (the current working directory) |
184184
| `--log-execution-id`| `LOG_EXECUTION_ID` | Enables execution IDs in logs, either `true` or `false`. When not specified, default to disable. Requires Node.js 13.0.0 or later. |
185+
| `--ignored-routes`| `IGNORED_ROUTES` | A route expression for requests that should not be routed the function. An empty 404 response will be returned. This is set to `/favicon.ico|/robots.txt` by default for `http` functions. |
185186
186187
You can set command-line flags in your `package.json` via the `start` script.
187188
For example:

src/options.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ export interface FrameworkOptions {
5656
* The request timeout.
5757
*/
5858
timeoutMilliseconds: number;
59+
/**
60+
* Routes that should return a 404 without invoking the function.
61+
*/
62+
ignoredRoutes: string | null;
5963
}
6064

6165
/**
@@ -86,7 +90,7 @@ class ConfigurableOption<T> {
8690

8791
parse(cliArgs: minimist.ParsedArgs, envVars: NodeJS.ProcessEnv): T {
8892
return this.validator(
89-
cliArgs[this.cliOption] || envVars[this.envVar] || this.defaultValue
93+
cliArgs[this.cliOption] ?? envVars[this.envVar] ?? this.defaultValue
9094
);
9195
}
9296
}
@@ -130,6 +134,11 @@ const TimeoutOption = new ConfigurableOption(
130134
return x * 1000;
131135
}
132136
);
137+
const IgnoredRoutesOption = new ConfigurableOption<string | null>(
138+
'ignored-routes',
139+
'IGNORED_ROUTES',
140+
null // null by default so we can detect if it is explicitly set to ""
141+
);
133142

134143
export const requiredNodeJsVersionForLogExecutionID = '13.0.0';
135144
const ExecutionIdOption = new ConfigurableOption(
@@ -181,6 +190,7 @@ export const parseOptions = (
181190
SignatureOption.cliOption,
182191
SourceLocationOption.cliOption,
183192
TimeoutOption.cliOption,
193+
IgnoredRoutesOption.cliOption,
184194
],
185195
});
186196
return {
@@ -191,5 +201,6 @@ export const parseOptions = (
191201
timeoutMilliseconds: TimeoutOption.parse(argv, envVars),
192202
printHelp: cliArgs[2] === '-h' || cliArgs[2] === '--help',
193203
enableExecutionId: ExecutionIdOption.parse(argv, envVars),
204+
ignoredRoutes: IgnoredRoutesOption.parse(argv, envVars),
194205
};
195206
};

src/server.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,23 @@ export function getServer(
134134
if (options.signatureType === 'cloudevent') {
135135
app.use(backgroundEventToCloudEventMiddleware);
136136
}
137-
138-
if (options.signatureType === 'http') {
137+
if (options.ignoredRoutes !== null) {
138+
// Ignored routes is a configuration option that allows requests to specific paths to be prevented
139+
// from invoking the user's function.
140+
app.use(options.ignoredRoutes, (req, res) => {
141+
res.status(404).send(null);
142+
});
143+
} else if (options.signatureType === 'http') {
144+
// We configure some default ignored routes, only for HTTP functions.
139145
app.use('/favicon.ico|/robots.txt', (req, res) => {
140146
// Neither crawlers nor browsers attempting to pull the icon find the body
141-
// contents particularly useful, so we send nothing in the response body.
147+
// contents particularly useful, so we filter these requests out from invoking
148+
// the user's function by default.
142149
res.status(404).send(null);
143150
});
151+
}
144152

153+
if (options.signatureType === 'http') {
145154
app.use('/*', (req, res, next) => {
146155
onFinished(res, (err, res) => {
147156
res.locals.functionExecutionFinished = true;

src/testing.ts

+1
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,6 @@ export const getTestServer = (functionName: string): Server => {
5656
target: '',
5757
sourceLocation: '',
5858
printHelp: false,
59+
ignoredRoutes: null,
5960
});
6061
};

test/integration/legacy_event.ts

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const testOptions = {
4040
target: '',
4141
sourceLocation: '',
4242
printHelp: false,
43+
ignoredRoutes: null,
4344
};
4445

4546
describe('Event Function', () => {

test/options.ts

+8
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ describe('parseOptions', () => {
6060
printHelp: false,
6161
enableExecutionId: false,
6262
timeoutMilliseconds: 0,
63+
ignoredRoutes: null,
6364
},
6465
},
6566
{
@@ -75,6 +76,7 @@ describe('parseOptions', () => {
7576
'--source=/source',
7677
'--timeout',
7778
'6',
79+
'--ignored-routes=banana',
7880
],
7981
envVars: {},
8082
expectedOptions: {
@@ -85,6 +87,7 @@ describe('parseOptions', () => {
8587
printHelp: false,
8688
enableExecutionId: false,
8789
timeoutMilliseconds: 6000,
90+
ignoredRoutes: 'banana',
8891
},
8992
},
9093
{
@@ -96,6 +99,7 @@ describe('parseOptions', () => {
9699
FUNCTION_SIGNATURE_TYPE: 'cloudevent',
97100
FUNCTION_SOURCE: '/source',
98101
CLOUD_RUN_TIMEOUT_SECONDS: '2',
102+
IGNORED_ROUTES: '',
99103
},
100104
expectedOptions: {
101105
port: '1234',
@@ -105,6 +109,7 @@ describe('parseOptions', () => {
105109
printHelp: false,
106110
enableExecutionId: false,
107111
timeoutMilliseconds: 2000,
112+
ignoredRoutes: '',
108113
},
109114
},
110115
{
@@ -119,13 +124,15 @@ describe('parseOptions', () => {
119124
'cloudevent',
120125
'--source=/source',
121126
'--timeout=3',
127+
'--ignored-routes=avocado',
122128
],
123129
envVars: {
124130
PORT: '4567',
125131
FUNCTION_TARGET: 'fooBar',
126132
FUNCTION_SIGNATURE_TYPE: 'event',
127133
FUNCTION_SOURCE: '/somewhere/else',
128134
CLOUD_RUN_TIMEOUT_SECONDS: '5',
135+
IGNORED_ROUTES: 'banana',
129136
},
130137
expectedOptions: {
131138
port: '1234',
@@ -135,6 +142,7 @@ describe('parseOptions', () => {
135142
printHelp: false,
136143
enableExecutionId: false,
137144
timeoutMilliseconds: 3000,
145+
ignoredRoutes: 'avocado',
138146
},
139147
},
140148
];

0 commit comments

Comments
 (0)