2020-05-02 13:56:49 +02:00
/ * *
* Remove integrity checks from embedded CSS and JavaScript files
* Belongs to LocalCDN .
*
* @ author nobody42
* @ since 2020 - 02 - 27
*
* @ license MPL 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this file ,
* You can obtain one at http : //mozilla.org/MPL/2.0/.
* /
'use strict' ;
/ * *
* Manipulate DOM
* /
var manipulateDOM = { } ;
/ * *
* Private Methods
* /
manipulateDOM . _removeCrossOriginAndIntegrityAttr = function ( details ) {
// by Jaap (https://gitlab.com/Jaaap)
let header = details . responseHeaders . find ( h => h . name . toLowerCase ( ) === 'content-type' ) ;
if ( header && BrowserType . FIREFOX ) {
2020-05-19 17:26:16 +02:00
let mimeType , initiatorDomain , isWhitelisted ;
2020-05-02 13:56:49 +02:00
mimeType = header . value . replace ( /;.*/ , '' ) . toLowerCase ( ) ;
initiatorDomain = helpers . extractDomainFromUrl ( details . url , true ) || Address . EXAMPLE ;
isWhitelisted = stateManager . _domainIsWhitelisted ( initiatorDomain ) ;
if ( ! isWhitelisted && mimeType === 'text/html' ) {
2020-05-19 17:38:07 +02:00
let asciiDecoder , decoder , encoder , charset , isFirstData , filter ;
2020-05-19 17:26:16 +02:00
asciiDecoder = new TextDecoder ( 'ASCII' ) ;
encoder = new TextEncoder ( ) ;
2020-05-21 19:44:33 +02:00
charset = /charset\s*=/ . test ( header . value ) && header . value . replace ( /^.*?charset\s*=\s*/ , '' ) . replace ( /["']?/g , '' ) ;
2020-05-22 07:19:01 +02:00
// Check if charset is supported by TextDecoder()
if ( EncodingTypes [ charset . toString ( ) . toLowerCase ( ) ] == undefined ) {
charset = false ;
}
2020-05-19 17:26:16 +02:00
isFirstData = true ;
filter = browser . webRequest . filterResponseData ( details . requestId ) ;
2020-05-02 13:56:49 +02:00
header . value = 'text/html; charset=UTF-8' ;
//Note that this will not work if the '<script crossorigin="anonymous" src="dfgsfgd.com">' string is divided into two chunks, but we want to flush this data asap.
filter . ondata = evt => {
2020-05-19 17:26:16 +02:00
if ( isFirstData ) {
if ( ! charset ) {
//content-type has no charset declared
let htmlHead = asciiDecoder . decode ( evt . data , { stream : false } ) ;
let charsetMatch = htmlHead . match ( /<meta\s+charset=["']?([^>"'\/]+)["'>\/]/i ) ;
if ( ! charsetMatch ) {
2020-05-21 20:26:41 +02:00
charsetMatch = htmlHead . match ( /<meta\s+http-equiv=["']?content-type["']?\s+content=["']?text\/html;\s*charset=([^>"'\/]+)["'>\/]/i ) ;
2020-05-19 17:26:16 +02:00
}
charset = charsetMatch ? charsetMatch [ 1 ] : "UTF-8" ;
}
decoder = new TextDecoder ( charset ) ;
}
2020-05-02 13:56:49 +02:00
//remove crossorigin and integrity attributes
let str = decoder . decode ( evt . data , { stream : true } ) . replace ( /<(link|script)[^>]+>/ig , m => {
2020-05-19 17:26:16 +02:00
if ( cdnDomainsRE . test ( m ) ) {
return m . replace ( /\s+(integrity|crossorigin)(="[^"]*"|='[^']*'|=[^"'`=\s]+|)/ig , '' ) ;
}
return m ;
} ) ;
2020-05-02 13:56:49 +02:00
filter . write ( encoder . encode ( str ) ) ;
2020-05-19 17:26:16 +02:00
isFirstData = false ;
2020-05-02 13:56:49 +02:00
}
filter . onstop = evt => {
let str = decoder . decode ( ) ; //end-of-stream
filter . write ( encoder . encode ( str ) ) ;
filter . close ( ) ;
}
}
2020-05-03 07:32:08 +02:00
return { responseHeaders : details . responseHeaders } ;
2020-05-02 13:56:49 +02:00
} else if ( BrowserType . CHROMIUM ) {
// Chromium browsers do not support webRequest.filterResponseData
// https://bugs.chromium.org/p/chromium/issues/detail?id=487422
console . warn ( '[ LocalCDN ] browser.webRequest.filterResponseData not supported by your browser.' ) ;
}
} ;
/ * *
* Initializations
* /
let whitelistedDomains = { } ;
let cdnDomainsRE = new RegExp ( '//(' + Object . keys ( mappings ) . map ( m => m . replace ( /\W/g , '\\$&' ) ) . join ( '|' ) + ')/' ) ;
/ * *
* Event Handlers
* /
chrome . webRequest . onHeadersReceived . addListener (
manipulateDOM . _removeCrossOriginAndIntegrityAttr ,
{ 'types' : [ WebRequestType . MAIN _FRAME ] , 'urls' : [ Address . ANY ] } ,
2020-05-19 17:26:16 +02:00
[ WebRequest . BLOCKING , WebRequest . RESPONSE _HEADERS ]
2020-05-02 13:56:49 +02:00
) ;