Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/firebase_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export 'src/remote_config/remote_config.dart';
// Experimental: Scheduler triggers (not yet supported in production or emulator)
export 'src/scheduler/scheduler.dart';
// Core runtime
export 'src/server.dart' show fireUp, runFunctions;
export 'src/server.dart' show RunFunctionsOptions, fireUp, runFunctions;
// Experimental: Storage triggers (emulator only)
export 'src/storage/storage.dart';
// Experimental: Task queue triggers (not yet supported in production or emulator)
Expand Down
24 changes: 22 additions & 2 deletions lib/src/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ import 'logger/logger.dart';
/// Callback type for the user's function registration code.
typedef FunctionsRunner = FutureOr<void> Function(Firebase firebase);

/// Runtime configuration options for [runFunctions].
class RunFunctionsOptions {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we handle this for other SDKs and are we being consistent?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other SDKs don't provide support for overriding the default X-Powered-By header, so this is purely an addition to the dart SDK.

Do we want to add support for this?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine. We added default support for x-powered-by to shelf, but folks want to be able to remove it.

const RunFunctionsOptions({this.poweredByHeader});

/// Value for the `x-powered-by` response header.
///
/// Defaults to `null`, which omits the header entirely. Pass a string to set
/// a custom value. This applies to all responses, including
/// internally-generated shelf error responses.
final String? poweredByHeader;
}

/// Starts the Firebase Functions runtime.
///
/// This is the main entry point for a Firebase Functions application.
Expand Down Expand Up @@ -64,7 +76,10 @@ Future<void> fireUp(List<String> args, FunctionsRunner runner) =>
/// });
/// }
/// ```
Future<void> runFunctions(FunctionsRunner runner) async {
Future<void> runFunctions(
FunctionsRunner runner, {
RunFunctionsOptions options = const RunFunctionsOptions(),
}) async {
final firebase = createFirebaseInternal();
final env = firebase.$env;
final projectId = env.projectId;
Expand Down Expand Up @@ -95,7 +110,12 @@ Future<void> runFunctions(FunctionsRunner runner) async {
});

// Start HTTP server
await shelf_io.serve(handler, InternetAddress.anyIPv4, env.port);
await shelf_io.serve(
handler,
InternetAddress.anyIPv4,
env.port,
poweredByHeader: options.poweredByHeader,
);
});
}

Expand Down
12 changes: 12 additions & 0 deletions test/unit/server_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ void main() {
});
});

group('RunFunctionsOptions', () {
test('defaults to null (no header)', () {
const opts = RunFunctionsOptions();
expect(opts.poweredByHeader, isNull);
});

test('accepts a custom header value', () {
const opts = RunFunctionsOptions(poweredByHeader: 'MyApp/1.0');
expect(opts.poweredByHeader, 'MyApp/1.0');
});
});

group('corsHeadersFor', () {
test('returns asterisk when allowedOrigins contains asterisk', () {
final request = Request('GET', Uri.parse('http://localhost/test'));
Expand Down
Loading