Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rumtime): disable server-timing header via options.timing #823

Merged
merged 11 commits into from
Jan 13, 2023
14 changes: 4 additions & 10 deletions docs/content/3.config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ Server runtime configuration.

**Note:**: `nitro` namespace is reserved.


<!-- Features -->

## `experimental`
Expand All @@ -59,7 +58,10 @@ Storage configuration.

- Default: `false`

Enable timing information.
Enable timing information:

- Nitro startup time log
- `Server-Timing` header on HTTP responses

## `renderer`

Expand Down Expand Up @@ -171,8 +173,6 @@ An array of paths to nitro plugins. They will be executed by order on the first

A map from dynamic virtual import names to their contents or an (async) function that returns it.



<!-- Routing -->

## `baseURL`
Expand Down Expand Up @@ -242,7 +242,6 @@ Route options. It is a map from route pattern (following [unjs/radix3](https://g

When `cache` option is set, handlers matching pattern will be automatically wrapped with `defineCachedEventHandler`. See [Cache API](/guide/introduction/cache) for all available cache options. (`swr: true|number` is shortcut for `cache: { swr: true, maxAge: number }`.)


**Example:**

```js
Expand All @@ -267,8 +266,6 @@ Prerendered options. Any route specified will be fetched during the build and co

If `crawlLinks` option is set to `true`, nitro starts with `/` by default (or all routes in `routes` array) and for HTML pages extracts `<a href="">` tags and prerender them as well.



<!-- Directories -->

## `rootDir`
Expand Down Expand Up @@ -297,8 +294,6 @@ nitro's temporary working directory for generating build-related files.

Output directories for production bundle.



<!-- Advanced -->

## `dev`
Expand Down Expand Up @@ -335,7 +330,6 @@ Preview and deploy command hints are usually filled by deployment presets.

A custom error handler function for development errors.


<!-- Rollup -->

## `rollupConfig`
Expand Down
4 changes: 4 additions & 0 deletions src/nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export async function createNitro(config: NitroConfig = {}): Promise<Nitro> {
nitro.options.plugins.push("#internal/nitro/debug");
}

if (nitro.options.timing) {
nitro.options.plugins.push("#internal/nitro/timing");
}

// Logger config
if (nitro.options.logLevel !== undefined) {
nitro.logger.level = nitro.options.logLevel;
Expand Down
3 changes: 0 additions & 3 deletions src/runtime/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
} from "unenv/runtime/fetch/index";
import { createHooks, Hookable } from "hookable";
import { useRuntimeConfig } from "./config";
import { timingMiddleware } from "./timing";
import { cachedEventHandler } from "./cache";
import { createRouteRulesHandler, getRouteRulesForPath } from "./route-rules";
import { plugins } from "#internal/nitro/virtual/plugins";
Expand All @@ -40,8 +39,6 @@ function createNitroApp(): NitroApp {
onError: errorHandler,
});

h3App.use(config.app.baseURL, timingMiddleware);

const router = createRouter();

h3App.use(createRouteRulesHandler());
Expand Down
14 changes: 12 additions & 2 deletions src/runtime/timing.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { eventHandler } from "h3";

export const globalTiming = globalThis.__timing__ || {
import { defineNitroPlugin } from "./plugin";

const globalTiming = globalThis.__timing__ || {
start: () => 0,
end: () => 0,
metrics: [],
};

// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
export const timingMiddleware = eventHandler((event) => {
const timingMiddleware = eventHandler((event) => {
const start = globalTiming.start();

const _end = event.node.res.end;
Expand All @@ -30,3 +32,11 @@ export const timingMiddleware = eventHandler((event) => {
return this;
}.bind(event.node.res);
});

export default defineNitroPlugin((nitro) => {
// Always add timing middleware to the beginning of handler stack
nitro.h3App.stack.unshift({
route: "/",
handler: timingMiddleware,
});
});
11 changes: 11 additions & 0 deletions test/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export async function setupTest(preset: string) {
"/rules/nested/**": { redirect: "/base", headers: { "x-test": "test" } },
"/rules/nested/override": { redirect: { to: "/other" } },
},
timing: preset !== "cloudflare" && preset !== "vercel-edge",
}));

if (ctx.isDev) {
Expand Down Expand Up @@ -240,4 +241,14 @@ export function testNitro(
additionalTests(ctx, callHandler);
}
}

if (ctx.nitro!.options.timing) {
it("set server timing header", async () => {
const { data, status, headers } = await callHandler({
url: "/api/hello",
});
expect(status).toBe(200);
expect(headers["server-timing"]).toMatch(/-;dur=\d+;desc="Generate"/);
});
}
}