Skip to content
Open
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
38 changes: 37 additions & 1 deletion packages/nextjs/src/proxy/proxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('ProxyBase', () => {
Object.defineProperties(res.headers, {
set: {
value: (key, value) => {
res.headers[key] = value;
res.headers[key] = value;
},
enumerable: false,
},
Expand Down Expand Up @@ -677,6 +677,42 @@ describe('defineProxy', () => {
});
});

it('should stop executing proxies when a previous proxy sets location header', async () => {
const firstProxySpy = sinon.spy();
const skippedProxySpy = sinon.spy();

const proxy1: ProxyHandler = {
handle: (_req, res) => {
firstProxySpy();
return Promise.resolve(res);
},
};

const redirectingProxy: ProxyHandler = {
handle: (_req, res) => {
res.headers.set('location', '/redirect-target');
return Promise.resolve(res);
},
};

const proxyAfterRedirect: ProxyHandler = {
handle: (_req, res) => {
skippedProxySpy();
res.headers.set('after-redirect', 'true');
return Promise.resolve(res);
},
};

const req = {} as NextRequest;

const result = await defineProxy(proxy1, redirectingProxy, proxyAfterRedirect).exec(req);

expect(firstProxySpy).to.have.been.calledOnce;
expect(skippedProxySpy).to.not.have.been.called;
expect(result.headers.get('location')).to.equal('/redirect-target');
expect(result.headers.get('after-redirect')).to.equal(null);
});

it('should execute proxies with empty response', async () => {
class SampleProxy extends ProxyBase {
handle(_req: NextRequest, res: NextResponse) {
Expand Down
3 changes: 1 addition & 2 deletions packages/nextjs/src/proxy/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,7 @@ export const defineProxy = (...proxies: ProxyHandler[]) => {
p.then((res) => {
// Short-circuit the remaining proxies once a previous one
// denied the request (e.g. PreviewProxy returning 403).
if (res.status === 403) return res;

if (res.headers?.get('location') || res.status === 403) return res;
return proxy.handle(req, res);
}),
Promise.resolve(response)
Expand Down