Project

General

Profile

Download (2.87 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / background / main.js @ 3303d7d7

1
/**
2
 * Hachette main background script
3
 *
4
 * Copyright (C) 2021 Wojtek Kosior
5
 * Redistribution terms are gathered in the `copyright' file.
6
 */
7

    
8
/*
9
 * IMPORTS_START
10
 * IMPORT TYPE_PREFIX
11
 * IMPORT get_storage
12
 * IMPORT start_storage_server
13
 * IMPORT start_page_actions_server
14
 * IMPORT browser
15
 * IMPORT is_privileged_url
16
 * IMPORT query_best
17
 * IMPORT gen_nonce
18
 * IMPORT inject_csp_headers
19
 * IMPORT apply_stream_filter
20
 * IMPORT filter_cookie_headers
21
 * IMPORT is_chrome
22
 * IMPORTS_END
23
 */
24

    
25
start_storage_server();
26
start_page_actions_server();
27

    
28
async function init_ext(install_details)
29
{
30
    if (install_details.reason != "install")
31
	return;
32

    
33
    let storage = await get_storage();
34

    
35
    await storage.clear();
36

    
37
    /*
38
     * Below we add sample settings to the extension.
39
     */
40

    
41
    for (let setting of // The next line is replaced with the contents of /default_settings.json by the build script
42
        `DEFAULT SETTINGS`
43
    ) {
44
	let [key, value] = Object.entries(setting)[0];
45
	storage.set(key[0], key.substring(1), value);
46
    }
47
}
48

    
49
browser.runtime.onInstalled.addListener(init_ext);
50

    
51

    
52
let storage;
53

    
54
function on_headers_received(details)
55
{
56
    const url = details.url;
57
    if (is_privileged_url(details.url))
58
	return;
59

    
60
    const [pattern, settings] = query_best(storage, details.url);
61
    const allow = !!(settings && settings.allow);
62
    const nonce = gen_nonce();
63
    const policy = {allow, url, nonce};
64

    
65
    let headers = details.responseHeaders;
66
    let skip = false;
67
    for (const header of headers) {
68
	if ((header.name.toLowerCase().trim() === "content-disposition" &&
69
	     /^\s*attachment\s*(;.*)$/i.test(header.value)))
70
	    skip = true;
71
    }
72

    
73
    headers = inject_csp_headers(headers, policy);
74

    
75
    skip = skip || (details.statusCode >= 300 && details.statusCode < 400);
76
    if (!skip) {
77
	/* Check for API availability. */
78
	if (browser.webRequest.filterResponseData)
79
	    headers = apply_stream_filter(details, headers, policy);
80
    }
81

    
82
    return {responseHeaders: headers};
83
}
84

    
85
function on_before_send_headers(details)
86
{
87
    let headers = details.requestHeaders;
88
    headers = filter_cookie_headers(headers);
89
    return {requestHeaders: headers};
90
}
91

    
92
const all_types = [
93
    "main_frame", "sub_frame", "stylesheet", "script", "image", "font",
94
    "object", "xmlhttprequest", "ping", "csp_report", "media", "websocket",
95
    "other", "main_frame", "sub_frame"
96
];
97

    
98
async function start_webRequest_operations()
99
{
100
    storage = await get_storage();
101

    
102
    const extra_opts = ["blocking"];
103
    if (is_chrome)
104
	extra_opts.push("extraHeaders");
105

    
106
    browser.webRequest.onHeadersReceived.addListener(
107
	on_headers_received,
108
	{urls: ["<all_urls>"], types: ["main_frame", "sub_frame"]},
109
	extra_opts.concat("responseHeaders")
110
    );
111

    
112
    browser.webRequest.onBeforeSendHeaders.addListener(
113
	on_before_send_headers,
114
	{urls: ["<all_urls>"], types: all_types},
115
	extra_opts.concat("requestHeaders")
116
    );
117
}
118

    
119
start_webRequest_operations();
(2-2/7)