mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-10 04:22:12 +00:00
[now dev] Add etag response header for Lambda invocations (#2502)
This matches the behavior in production.
This commit is contained in:
committed by
Leo Lamprecht
parent
2414767026
commit
f80f1f79a6
@@ -1,7 +1,6 @@
|
|||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import execa from 'execa';
|
import execa from 'execa';
|
||||||
import npa from 'npm-package-arg';
|
import npa from 'npm-package-arg';
|
||||||
import { createHash } from 'crypto';
|
|
||||||
import { join, resolve } from 'path';
|
import { join, resolve } from 'path';
|
||||||
import { funCacheDir } from '@zeit/fun';
|
import { funCacheDir } from '@zeit/fun';
|
||||||
import cacheDirectory from 'cache-or-tmp-directory';
|
import cacheDirectory from 'cache-or-tmp-directory';
|
||||||
@@ -12,6 +11,7 @@ import {
|
|||||||
BuilderCacheCleanError
|
BuilderCacheCleanError
|
||||||
} from '../errors-ts';
|
} from '../errors-ts';
|
||||||
import wait from '../output/wait';
|
import wait from '../output/wait';
|
||||||
|
import { getSha } from '../sha';
|
||||||
import { Output } from '../output';
|
import { Output } from '../output';
|
||||||
|
|
||||||
import * as staticBuilder from './static-builder';
|
import * as staticBuilder from './static-builder';
|
||||||
@@ -215,9 +215,3 @@ function getPackageName(
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSha(buffer: Buffer): string {
|
|
||||||
const hash = createHash('sha256');
|
|
||||||
hash.update(buffer);
|
|
||||||
return hash.digest('hex');
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import chalk from 'chalk';
|
|||||||
import which from 'which';
|
import which from 'which';
|
||||||
import ora, { Ora } from 'ora';
|
import ora, { Ora } from 'ora';
|
||||||
|
|
||||||
|
import { getSha } from '../sha';
|
||||||
import { Output } from '../output';
|
import { Output } from '../output';
|
||||||
import { relative } from '../path-helpers';
|
import { relative } from '../path-helpers';
|
||||||
import { LambdaSizeExceededError } from '../errors-ts';
|
import { LambdaSizeExceededError } from '../errors-ts';
|
||||||
@@ -354,6 +355,7 @@ export async function executeBuild(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
asset.sha = getSha(asset.zipBuffer, 'sha1');
|
||||||
}
|
}
|
||||||
|
|
||||||
match.buildTimestamp = Date.now();
|
match.buildTimestamp = Date.now();
|
||||||
|
|||||||
@@ -839,7 +839,7 @@ export default class DevServer {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case 'Lambda':
|
case 'Lambda':
|
||||||
if (!asset.fn) {
|
if (!asset.fn || !asset.sha) {
|
||||||
// This is mostly to appease TypeScript since `fn` is an optional prop,
|
// This is mostly to appease TypeScript since `fn` is an optional prop,
|
||||||
// but this shouldn't really ever happen since we run the builds before
|
// but this shouldn't really ever happen since we run the builds before
|
||||||
// responding to HTTP requests.
|
// responding to HTTP requests.
|
||||||
@@ -894,6 +894,7 @@ export default class DevServer {
|
|||||||
|
|
||||||
res.statusCode = result.statusCode;
|
res.statusCode = result.statusCode;
|
||||||
this.setResponseHeaders(res, nowRequestId, result.headers);
|
this.setResponseHeaders(res, nowRequestId, result.headers);
|
||||||
|
res.setHeader('etag', `W/"${asset.sha}"`);
|
||||||
|
|
||||||
let resBody: Buffer | string | undefined;
|
let resBody: Buffer | string | undefined;
|
||||||
if (result.encoding === 'base64' && typeof result.body === 'string') {
|
if (result.encoding === 'base64' && typeof result.body === 'string') {
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export interface BuilderInputs {
|
|||||||
|
|
||||||
export type BuiltLambda = Lambda & {
|
export type BuiltLambda = Lambda & {
|
||||||
fn?: FunLambda;
|
fn?: FunLambda;
|
||||||
|
sha?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BuilderOutput = BuiltLambda | FileFsRef | FileBlob;
|
export type BuilderOutput = BuiltLambda | FileFsRef | FileBlob;
|
||||||
|
|||||||
7
src/util/sha.ts
Normal file
7
src/util/sha.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { createHash } from 'crypto';
|
||||||
|
|
||||||
|
export function getSha(buffer: Buffer, cypher: string = 'sha256'): string {
|
||||||
|
const hash = createHash(cypher);
|
||||||
|
hash.update(buffer);
|
||||||
|
return hash.digest('hex');
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@ function testFixture(name, fn) {
|
|||||||
function validateResponseHeaders(t, res) {
|
function validateResponseHeaders(t, res) {
|
||||||
t.is(res.headers.get('cache-control'), 'public, max-age=0, must-revalidate');
|
t.is(res.headers.get('cache-control'), 'public, max-age=0, must-revalidate');
|
||||||
t.is(res.headers.get('x-now-trace'), 'dev1');
|
t.is(res.headers.get('x-now-trace'), 'dev1');
|
||||||
|
t.truthy(/^W\/"[0-9a-f]{40}"$/.test(res.headers.get('etag')));
|
||||||
t.truthy(
|
t.truthy(
|
||||||
/^dev1:[0-9a-z]{5}-[1-9][0-9]+-[a-f0-9]{12}$/.test(
|
/^dev1:[0-9a-z]{5}-[1-9][0-9]+-[a-f0-9]{12}$/.test(
|
||||||
res.headers.get('x-now-id')
|
res.headers.get('x-now-id')
|
||||||
|
|||||||
Reference in New Issue
Block a user