mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	fix(fetch): allow UTF-8 in Location header (#30904)
This commit is contained in:
		
							parent
							
								
									042896472b
								
							
						
					
					
						commit
						a93ad3dade
					
				@ -336,12 +336,15 @@ export abstract class APIRequestContext extends SdkObject {
 | 
			
		||||
            redirectOptions.rejectUnauthorized = false;
 | 
			
		||||
 | 
			
		||||
          // HTTP-redirect fetch step 4: If locationURL is null, then return response.
 | 
			
		||||
          if (response.headers.location) {
 | 
			
		||||
          // Best-effort UTF-8 decoding, per spec it's US-ASCII only, but browsers are more lenient.
 | 
			
		||||
          // Node.js parses it as Latin1 via std::v8::String, so we convert it to UTF-8.
 | 
			
		||||
          const locationHeaderValue = Buffer.from(response.headers.location ?? '', 'latin1').toString('utf8');
 | 
			
		||||
          if (locationHeaderValue) {
 | 
			
		||||
            let locationURL;
 | 
			
		||||
            try {
 | 
			
		||||
              locationURL = new URL(response.headers.location, url);
 | 
			
		||||
              locationURL = new URL(locationHeaderValue, url);
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
              reject(new Error(`uri requested responds with an invalid redirect URL: ${response.headers.location}`));
 | 
			
		||||
              reject(new Error(`uri requested responds with an invalid redirect URL: ${locationHeaderValue}`));
 | 
			
		||||
              request.destroy();
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -198,6 +198,20 @@ it('should follow redirects', async ({ context, server }) => {
 | 
			
		||||
  expect(await response.json()).toEqual({ foo: 'bar' });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
it('should follow redirects correctly when Location header contains UTF-8 characters', async ({ context, server }) => {
 | 
			
		||||
  it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30903' });
 | 
			
		||||
  server.setRoute('/redirect', (req, res) => {
 | 
			
		||||
    // Node.js only allows US-ASCII, so we can't send invalid headers directly. Sending it as a raw response instead.
 | 
			
		||||
    res.socket.write('HTTP/1.1 301 Moved Permanently\r\n');
 | 
			
		||||
    res.socket.write(`Location: ${server.PREFIX}/empty.html?message=マスクПривет\r\n`);
 | 
			
		||||
    res.socket.write('\r\n');
 | 
			
		||||
    res.socket.uncork();
 | 
			
		||||
    res.socket.end();
 | 
			
		||||
  });
 | 
			
		||||
  const response = await context.request.get(server.PREFIX + '/redirect');
 | 
			
		||||
  expect(response.url()).toBe(server.PREFIX + '/empty.html?' + new URLSearchParams({ message: 'マスクПривет' }));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
it('should add cookies from Set-Cookie header', async ({ context, page, server }) => {
 | 
			
		||||
  server.setRoute('/setcookie.html', (req, res) => {
 | 
			
		||||
    res.setHeader('Set-Cookie', ['session=value', 'foo=bar; max-age=3600']);
 | 
			
		||||
@ -794,21 +808,6 @@ it('should respect timeout after redirects', async function({ context, server })
 | 
			
		||||
  expect(error.message).toContain(`Request timed out after 100ms`);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
it('should throw on a redirect with an invalid URL', async ({ context, server }) => {
 | 
			
		||||
  server.setRedirect('/redirect', '/test');
 | 
			
		||||
  server.setRoute('/test', (req, res) => {
 | 
			
		||||
    // Node.js prevents us from responding with an invalid header, therefore we manually write the response.
 | 
			
		||||
    const conn = res.connection!;
 | 
			
		||||
    conn.write('HTTP/1.1 302\r\n');
 | 
			
		||||
    conn.write('Location: https://здравствуйте/\r\n');
 | 
			
		||||
    conn.write('\r\n');
 | 
			
		||||
    conn.uncork();
 | 
			
		||||
    conn.end();
 | 
			
		||||
  });
 | 
			
		||||
  const error = await context.request.get(server.PREFIX + '/redirect').catch(e => e);
 | 
			
		||||
  expect(error.message).toContain('apiRequestContext.get: uri requested responds with an invalid redirect URL');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
it('should not hang on a brotli encoded Range request', async ({ context, server }) => {
 | 
			
		||||
  it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/18190' });
 | 
			
		||||
  it.skip(+process.versions.node.split('.')[0] < 18);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user