Skip to content

Commit

Permalink
AG-35395 revert to old redirects
Browse files Browse the repository at this point in the history
Merge in ADGUARD-FILTERS/tsurlfilter from fix/AG-35395 to master

Squashed commit of the following:

commit d44f518
Author: Maxim Topciu <[email protected]>
Date:   Mon Aug 26 16:04:30 2024 +0300

    AG-35395 update changelog

commit 71ea9a7
Author: Maxim Topciu <[email protected]>
Date:   Mon Aug 26 16:01:43 2024 +0300

    AG-35395 fix eslint error

commit 9ef3308
Author: Maxim Topciu <[email protected]>
Date:   Mon Aug 26 15:49:27 2024 +0300

    AG-35395 revert to old redirects
  • Loading branch information
maximtop committed Aug 26, 2024
1 parent b97a6a6 commit 2d04d17
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 131 deletions.
8 changes: 8 additions & 0 deletions packages/tswebextension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<!-- TODO: manually add compare links for version changes -->
<!-- e.g. [0.1.2]: https://github.com/AdguardTeam/tsurlfilter/compare/tswebextension-v0.1.1...tswebextension-v0.1.2 -->

## [Unreleased]

### Fixed

- Redirect rule blocks request in the Spotify player instead of redirecting [AdguardBrowserExtension#2913]

[AdguardBrowserExtension#2913]: https://github.com/AdguardTeam/AdguardBrowserExtension/issues/2913

## [2.0.0] - 2024-08-15

### Added
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
import { redirects } from '@adguard/scriptlets';
import type { Redirect, Redirects } from '@adguard/scriptlets';
import type { Redirects } from '@adguard/scriptlets';
import type { ResourcesService } from '../resources-service';

import { redirectsCache } from './redirects-cache';
import { redirectsTokensCache } from './redirects-tokens-cache';
import { logger } from '../../../../common';
import { isFirefox } from '../../utils';

const BASE_64 = 'base64';
const CONTENT_TYPE_SEPARATOR = ';';

/**
* Service for working with redirects.
*/
export class RedirectsService {
redirects: Redirects | null = null;

/**
* Cache for encoded redirects.
*/
dataUrlCache: Map<string, string> = new Map();

/**
* Creates {@link RedirectsService} instance.
* @param resourcesService Prevent web pages to identify extension through its web accessible resources.
Expand All @@ -42,43 +33,6 @@ export class RedirectsService {
}
}

/**
* Checks whether content type is base64 encoded.
*
* @param contentType Content type.
* @returns True if content type is base64 encoded.
*/
private static isBase64EncodedContentType = (contentType: string): boolean => {
return contentType.endsWith(BASE_64);
};

/**
* Creates data url for the specified redirect. It caches created urls.
*
* @param redirect Redirect.
* @returns Data URL.
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs
*/
private createRedirectDataUrl(redirect: Redirect): string {
let url = this.dataUrlCache.get(redirect.title);

if (url) {
return url;
}

let { contentType, content } = redirect;

if (!RedirectsService.isBase64EncodedContentType(contentType)) {
contentType += CONTENT_TYPE_SEPARATOR + BASE_64;
content = btoa(content);
}

url = `data:${contentType},${content}`;
this.dataUrlCache.set(redirect.title, url);

return url;
}

/**
* Returns redirect url for the specified title.
*
Expand Down Expand Up @@ -107,21 +61,9 @@ export class RedirectsService {
return null;
}

if (redirectSource.isBlocking) {
// For blocking redirects we generate additional search params.
const params = this.blockingUrlParams(title, requestUrl);
return this.resourcesService.createResourceUrl(`redirects/${redirectSource.file}`, params);
}

if (isFirefox) {
// Firefox throws same origin policy error when trying to load redirect resource from data url,
// so we use the old way to load redirect resources.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1016491
// https://www.rfc-editor.org/rfc/rfc6454#section-5
return this.resourcesService.createResourceUrl(`redirects/${redirectSource.file}`);
}

return this.createRedirectDataUrl(redirectSource);
// For blocking redirects we generate additional search params.
const params = this.blockingUrlParams(title, requestUrl);
return this.resourcesService.createResourceUrl(`redirects/${redirectSource.file}`, params);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ jest.mock('@lib/mv2/background/services/resources-service', () => ({
...jest.requireActual('../mocks/resources-service-mock'),
}));

const browserDetectorMock = jest.requireMock('@lib/mv2/background/utils/browser-detector');
jest.mock('@lib/mv2/background/utils/browser-detector', () => ({
isFirefox: false,
}));

describe('RedirectsService', () => {
const resourcesService = new ResourcesService(() => {
return Math.floor(Math.random() * 982451653 + 982451653).toString(36);
Expand All @@ -24,76 +19,15 @@ describe('RedirectsService', () => {
await redirectsService.start();
});

it('checks for content type', () => {
// @ts-ignore: accessing private method
expect(RedirectsService.isBase64EncodedContentType('text/javascript; base64')).toBeTruthy();
// @ts-ignore: accessing private method
expect(RedirectsService.isBase64EncodedContentType('text/javascript')).toBeFalsy();
});

it('creates data urls by redirect source', () => {
// Creates data url for an already encoded content
let redirectSource = redirectsService.redirects!.getRedirect('1x1-transparent.gif');
let expectedDataUrl = `data:${redirectSource?.contentType},${redirectSource!.content}`;

// @ts-ignore: accessing private method
let dataUrl = redirectsService.createRedirectDataUrl(redirectSource);
expect(dataUrl).toBe(expectedDataUrl);

// Create data url for a non-encoded content
redirectSource = redirectsService.redirects!.getRedirect('matomo');
expectedDataUrl = `data:${redirectSource?.contentType};base64,${btoa(redirectSource!.content)}`;

// @ts-ignore: accessing private method
dataUrl = redirectsService.createRedirectDataUrl(redirectSource);
expect(dataUrl).toBe(expectedDataUrl);
});

it('uses cache for managing data urls', () => {
const redirectSource = redirectsService.redirects!.getRedirect('google-ima3');
const expectedDataUrl = `data:${redirectSource?.contentType};base64,${btoa(redirectSource!.content)}`;

const spy = jest.spyOn(global, 'btoa');

// @ts-ignore: accessing private method
let dataUrl = redirectsService.createRedirectDataUrl(redirectSource);
expect(dataUrl).toBe(expectedDataUrl);

// @ts-ignore: accessing private method
dataUrl = redirectsService.createRedirectDataUrl(redirectSource);
expect(dataUrl).toBe(expectedDataUrl);

// createRedirectDataUrl was called twice, but btoa was called only once
expect(btoa).toHaveBeenCalledTimes(1);
spy.mockRestore();
});

it('creates redirect urls by redirect title', () => {
const url = 'https://example.com';
let redirectTitle = 'fingerprintjs3';

let dataUrl = redirectsService.createRedirectUrl(redirectTitle, url);
let redirectSource = redirectsService.redirects!.getRedirect(redirectTitle);
let expectedDataUrl = `data:${redirectSource?.contentType};base64,${btoa(redirectSource!.content)}`;
expect(dataUrl).toBe(expectedDataUrl);

redirectTitle = '1x1-transparent.gif';
dataUrl = redirectsService.createRedirectUrl(redirectTitle, url);
redirectSource = redirectsService.redirects!.getRedirect(redirectTitle);
expectedDataUrl = `data:${redirectSource?.contentType},${redirectSource!.content}`;
expect(dataUrl).toBe(expectedDataUrl);
});

it('Firefox still using the legacy URL', async () => {
it('createResourceUrl is called', async () => {
const url = 'https://example.com';
const redirectTitle = '1x1-transparent.gif';

browserDetectorMock.isFirefox = true;

redirectsService = new RedirectsService(resourcesService);
await redirectsService.start();

redirectsService.createRedirectUrl(redirectTitle, url);
expect(resourcesService.createResourceUrl).toHaveBeenCalledWith(`redirects/${redirectTitle}`);
expect(resourcesService.createResourceUrl)
.toHaveBeenCalledWith(`redirects/${redirectTitle}`, new URLSearchParams());
});
});

0 comments on commit 2d04d17

Please sign in to comment.