mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	fix(interception): make set-cookie work in chromium (#9299)
This commit is contained in:
		
							parent
							
								
									4171dfb57f
								
							
						
					
					
						commit
						c516729544
					
				@ -514,13 +514,14 @@ class RouteImpl implements network.RouteDelegate {
 | 
				
			|||||||
    this._wasFulfilled = true;
 | 
					    this._wasFulfilled = true;
 | 
				
			||||||
    const body = response.isBase64 ? response.body : Buffer.from(response.body).toString('base64');
 | 
					    const body = response.isBase64 ? response.body : Buffer.from(response.body).toString('base64');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const responseHeaders = splitSetCookieHeader(response.headers);
 | 
				
			||||||
    // In certain cases, protocol will return error if the request was already canceled
 | 
					    // In certain cases, protocol will return error if the request was already canceled
 | 
				
			||||||
    // or the page was closed. We should tolerate these errors.
 | 
					    // or the page was closed. We should tolerate these errors.
 | 
				
			||||||
    await this._client._sendMayFail('Fetch.fulfillRequest', {
 | 
					    await this._client._sendMayFail('Fetch.fulfillRequest', {
 | 
				
			||||||
      requestId: this._interceptionId!,
 | 
					      requestId: this._interceptionId!,
 | 
				
			||||||
      responseCode: response.status,
 | 
					      responseCode: response.status,
 | 
				
			||||||
      responsePhrase: network.STATUS_TEXTS[String(response.status)],
 | 
					      responsePhrase: network.STATUS_TEXTS[String(response.status)],
 | 
				
			||||||
      responseHeaders: response.headers,
 | 
					      responseHeaders,
 | 
				
			||||||
      body,
 | 
					      body,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -537,6 +538,20 @@ class RouteImpl implements network.RouteDelegate {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function splitSetCookieHeader(headers: types.HeadersArray): types.HeadersArray {
 | 
				
			||||||
 | 
					  const index = headers.findIndex(({ name }) => name.toLowerCase() === 'set-cookie');
 | 
				
			||||||
 | 
					  if (index === -1)
 | 
				
			||||||
 | 
					    return headers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const header = headers[index];
 | 
				
			||||||
 | 
					  const values = header.value.split('\n');
 | 
				
			||||||
 | 
					  if (values.length === 1)
 | 
				
			||||||
 | 
					    return headers;
 | 
				
			||||||
 | 
					  const result = headers.slice();
 | 
				
			||||||
 | 
					  result.splice(index, 1, ...values.map(value => ({ name: header.name, value })));
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const errorReasons: { [reason: string]: Protocol.Network.ErrorReason } = {
 | 
					const errorReasons: { [reason: string]: Protocol.Network.ErrorReason } = {
 | 
				
			||||||
  'aborted': 'Aborted',
 | 
					  'aborted': 'Aborted',
 | 
				
			||||||
  'accessdenied': 'AccessDenied',
 | 
					  'accessdenied': 'AccessDenied',
 | 
				
			||||||
 | 
				
			|||||||
@ -248,3 +248,54 @@ it('should fetch original request and fulfill', async ({ page, server, isElectro
 | 
				
			|||||||
  expect(response.status()).toBe(200);
 | 
					  expect(response.status()).toBe(200);
 | 
				
			||||||
  expect(await page.title()).toEqual('Woof-Woof');
 | 
					  expect(await page.title()).toEqual('Woof-Woof');
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					it('should fulfill with multiple set-cookie', async ({ page, server, browserName }) => {
 | 
				
			||||||
 | 
					  it.fail(browserName === 'webkit', 'Response contained invalid HTTP headers');
 | 
				
			||||||
 | 
					  const cookies = ['a=b', 'c=d'];
 | 
				
			||||||
 | 
					  await page.route('**/empty.html', async route => {
 | 
				
			||||||
 | 
					    route.fulfill({
 | 
				
			||||||
 | 
					      status: 200,
 | 
				
			||||||
 | 
					      headers: {
 | 
				
			||||||
 | 
					        'X-Header-1': 'v1',
 | 
				
			||||||
 | 
					        'Set-Cookie': cookies.join('\n'),
 | 
				
			||||||
 | 
					        'X-Header-2': 'v2',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      body: ''
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  const response = await page.goto(server.EMPTY_PAGE);
 | 
				
			||||||
 | 
					  expect((await page.evaluate(() => document.cookie)).split(';').map(s => s.trim()).sort()).toEqual(cookies);
 | 
				
			||||||
 | 
					  expect(await response.headerValue('X-Header-1')).toBe('v1');
 | 
				
			||||||
 | 
					  expect(await response.headerValue('X-Header-2')).toBe('v2');
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					it('should fulfill with fetch response that has multiple set-cookie', async ({ playwright, page, server, browserName }) => {
 | 
				
			||||||
 | 
					  it.fail(browserName === 'webkit', 'Response contained invalid HTTP headers');
 | 
				
			||||||
 | 
					  server.setRoute('/empty.html', (req, res) => {
 | 
				
			||||||
 | 
					    res.setHeader('Set-Cookie', ['a=b', 'c=d']);
 | 
				
			||||||
 | 
					    res.end();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  await page.route('**/empty.html', async route => {
 | 
				
			||||||
 | 
					    const request = await playwright._newRequest();
 | 
				
			||||||
 | 
					    const response = await request.fetch(route.request());
 | 
				
			||||||
 | 
					    route.fulfill({ response });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  await page.goto(server.EMPTY_PAGE);
 | 
				
			||||||
 | 
					  const cookie = await page.evaluate(() => document.cookie);
 | 
				
			||||||
 | 
					  expect(cookie.split(';').map(s => s.trim()).sort()).toEqual(['a=b', 'c=d']);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					it('headerValue should return set-cookie from intercepted response', async ({ page, server, browserName }) => {
 | 
				
			||||||
 | 
					  it.fail(browserName === 'chromium', 'Set-Cookie is missing in response after interception');
 | 
				
			||||||
 | 
					  await page.route('**/empty.html', async route => {
 | 
				
			||||||
 | 
					    route.fulfill({
 | 
				
			||||||
 | 
					      status: 200,
 | 
				
			||||||
 | 
					      headers: {
 | 
				
			||||||
 | 
					        'Set-Cookie': 'a=b',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      body: ''
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  const response = await page.goto(server.EMPTY_PAGE);
 | 
				
			||||||
 | 
					  expect(await response.headerValue('Set-Cookie')).toBe('a=b');
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user