mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-12 02:00:06 -06:00
fix: only update content-length header if one was present in spy (#25920)
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com> Co-authored-by: Bill Glesias <bglesias@gmail.com>
This commit is contained in:
@@ -7,6 +7,7 @@ _Released 03/28/2023 (PENDING)_
|
||||
|
||||
- Fixed a compatibility issue so that component test projects can use [Vite](https://vitejs.dev/) version 4.2.0 and greater. Fixes [#26138](https://github.com/cypress-io/cypress/issues/26138).
|
||||
- Changed the way that Git hashes are loaded so that non-relevant runs are excluded from the Debug page. Fixes [#26058](https://github.com/cypress-io/cypress/issues/26058).
|
||||
- Fixed an issue where [`cy.intercept()`](https://docs.cypress.io/api/commands/intercept) added an additional `content-length` header to spied requests that did not set a `content-length` header on the original request. Fixes [#24407](https://github.com/cypress-io/cypress/issues/24407).
|
||||
|
||||
**Misc:**
|
||||
|
||||
|
||||
@@ -2627,6 +2627,22 @@ describe('network stubbing', { retries: 15 }, function () {
|
||||
$.post('/post-only', 'baz')
|
||||
})
|
||||
})
|
||||
|
||||
// @see https://github.com/cypress-io/cypress/issues/24407
|
||||
it('does not calculate content-length on spied request if one does not exist on the initial request (if merging)', { retries: 0 }, function (done) {
|
||||
cy.intercept('/verify-content-length-is-absent*', function (req) {
|
||||
// modify the intercepted request to trigger a request merge in net_stubbing
|
||||
req.headers['foo'] = 'bar'
|
||||
// send the modified request and skip any other
|
||||
// matching request handlers
|
||||
req.continue()
|
||||
}).then(async () => {
|
||||
const isContentLengthHeaderAbsent = await $.get('/verify-content-length-is-absent')
|
||||
|
||||
expect(isContentLengthHeaderAbsent).to.be.true
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -172,6 +172,10 @@ const createApp = (port) => {
|
||||
return res.send(`<html><body>it worked!<br>request body:<br>${JSON.stringify(req.body)}</body></html>`)
|
||||
})
|
||||
|
||||
app.get('/verify-content-length-is-absent', (req, res) => {
|
||||
return res.send(req.headers['content-length'] === undefined)
|
||||
})
|
||||
|
||||
app.get('/dump-headers', (req, res) => {
|
||||
return res.send(`<html><body>request headers:<br>${JSON.stringify(req.headers)}</body></html>`)
|
||||
})
|
||||
|
||||
@@ -140,7 +140,7 @@ export const InterceptRequest: RequestMiddleware = async function () {
|
||||
request.req.body = req.body
|
||||
|
||||
const mergeChanges = (before: CyHttpMessages.IncomingRequest, after: CyHttpMessages.IncomingRequest) => {
|
||||
if (before.headers['content-length'] === after.headers['content-length']) {
|
||||
if ('content-length' in before.headers && before.headers['content-length'] === after.headers['content-length']) {
|
||||
// user did not purposely override content-length, let's set it
|
||||
after.headers['content-length'] = String(Buffer.from(after.body).byteLength)
|
||||
}
|
||||
|
||||
80
packages/net-stubbing/test/unit/middleware-request-spec.ts
Normal file
80
packages/net-stubbing/test/unit/middleware-request-spec.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { expect } from 'chai'
|
||||
import sinon from 'sinon'
|
||||
import { InterceptRequest } from '../../lib/server/middleware/request'
|
||||
import { state as NetStubbingState } from '../../lib/server/state'
|
||||
|
||||
describe('request', () => {
|
||||
context('InterceptedRequest', () => {
|
||||
// @see https://github.com/cypress-io/cypress/issues/24407
|
||||
it('does not set the content-length header if the header was not there to begin with on the original request', async () => {
|
||||
const socket = {
|
||||
toDriver: sinon.stub(),
|
||||
}
|
||||
const state = NetStubbingState()
|
||||
|
||||
const beforeRequestData = {
|
||||
body: 'stubbed_body',
|
||||
proxiedUrl: 'https://foobar.com',
|
||||
url: 'https://foobar.com',
|
||||
}
|
||||
|
||||
const afterRequestData = {
|
||||
...beforeRequestData,
|
||||
body: '',
|
||||
headers: {},
|
||||
}
|
||||
|
||||
// using a ES6 proxy to intercept the promise assignment on pendingEventHandlers.
|
||||
// this way, we can resolve the event immediately
|
||||
const pendingEventProxy = new Proxy(state.pendingEventHandlers, {
|
||||
get (target, prop, receiver) {
|
||||
// @ts-expect-error
|
||||
return Reflect.get(...arguments)
|
||||
},
|
||||
set (obj, prop, value) {
|
||||
// @ts-expect-error
|
||||
const setProp = Reflect.set(...arguments)
|
||||
|
||||
// invoke the promise function immediately
|
||||
if (typeof value === 'function') {
|
||||
value({
|
||||
changedData: afterRequestData,
|
||||
stopPropagation: false,
|
||||
})
|
||||
}
|
||||
|
||||
return setProp
|
||||
},
|
||||
})
|
||||
|
||||
state.pendingEventHandlers = pendingEventProxy
|
||||
|
||||
const request = {
|
||||
req: {
|
||||
...beforeRequestData,
|
||||
headers: {},
|
||||
matchingRoutes: [
|
||||
{
|
||||
id: '1',
|
||||
hasInterceptor: true,
|
||||
routeMatcher: {},
|
||||
},
|
||||
],
|
||||
pipe: sinon.stub(),
|
||||
},
|
||||
res: {
|
||||
once: sinon.stub(),
|
||||
},
|
||||
socket,
|
||||
debug: sinon.stub(),
|
||||
netStubbingState: state,
|
||||
next: sinon.stub(),
|
||||
onError: sinon.stub(),
|
||||
onResponse: sinon.stub(),
|
||||
}
|
||||
|
||||
await InterceptRequest.call(request)
|
||||
expect(request.req.headers['content-length']).to.be.undefined
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user