Skip to content

Commit

Permalink
fix: only update content-length header if one was present in spy (#25920
Browse files Browse the repository at this point in the history
)

Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
Co-authored-by: Bill Glesias <bglesias@gmail.com>
  • Loading branch information
3 people committed Mar 27, 2023
1 parent 5f48d3c commit 2452dee
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 1 deletion.
1 change: 1 addition & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:**

Expand Down
16 changes: 16 additions & 0 deletions packages/driver/cypress/e2e/commands/net_stubbing.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
})
})
})

Expand Down
4 changes: 4 additions & 0 deletions packages/driver/cypress/plugins/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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>`)
})
Expand Down
2 changes: 1 addition & 1 deletion packages/net-stubbing/lib/server/middleware/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
80 changes: 80 additions & 0 deletions packages/net-stubbing/test/unit/middleware-request-spec.ts
Original file line number Diff line number Diff line change
@@ -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
})
})
})

5 comments on commit 2452dee

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 2452dee Mar 27, 2023

Choose a reason for hiding this comment

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

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.8.2/linux-arm64/develop-2452dee969342302cdf34601010591b835c93a7f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 2452dee Mar 27, 2023

Choose a reason for hiding this comment

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

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.8.2/linux-x64/develop-2452dee969342302cdf34601010591b835c93a7f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 2452dee Mar 27, 2023

Choose a reason for hiding this comment

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

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.8.2/darwin-arm64/develop-2452dee969342302cdf34601010591b835c93a7f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 2452dee Mar 27, 2023

Choose a reason for hiding this comment

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

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.8.2/darwin-x64/develop-2452dee969342302cdf34601010591b835c93a7f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 2452dee Mar 27, 2023

Choose a reason for hiding this comment

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

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.8.2/win32-x64/develop-2452dee969342302cdf34601010591b835c93a7f/cypress.tgz

Please sign in to comment.