aboutsummaryrefslogtreecommitdiff
path: root/bg/ResponseMetaData.js
diff options
context:
space:
mode:
authorhackademix <giorgio@maone.net>2018-07-15 23:15:34 +0200
committerhackademix <giorgio@maone.net>2018-07-17 17:45:27 +0200
commitdbe1ddbc1ddd9b40c6e0e5c896768f91cb6994e0 (patch)
treec3eb5a2b9bdbf59901d9da2602a0635ea3cc00c7 /bg/ResponseMetaData.js
parenteb929a0aff3a23a53f750ab3c866fbec57107fbb (diff)
Refactor and fix HTTP response filtering to touch only scripts, either external or embedded inside HTML documents and sub-documents.
Diffstat (limited to 'bg/ResponseMetaData.js')
-rw-r--r--bg/ResponseMetaData.js82
1 files changed, 82 insertions, 0 deletions
diff --git a/bg/ResponseMetaData.js b/bg/ResponseMetaData.js
new file mode 100644
index 0000000..40ca3f3
--- /dev/null
+++ b/bg/ResponseMetaData.js
@@ -0,0 +1,82 @@
+/**
+* GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
+*
+* Copyright (C) 2018 Giorgio Maone <giorgio@maone.net>
+*
+* This file is part of GNU LibreJS.
+*
+* GNU LibreJS is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* GNU LibreJS is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with GNU LibreJS. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ This class parses HTTP response headers to extract both the
+ MIME Content-type and the character set to be used, if specified,
+ to parse textual data through a decoder.
+*/
+
+class ResponseMetaData {
+ constructor(request) {
+ let {responseHeaders} = request;
+ this.headers = {};
+ for (let h of responseHeaders) {
+ if (/^\s*Content-(Type|Disposition)\s*$/i.test(h.name)) {
+ let propertyName = h.name.split("-")[1].trim();
+ propertyName = `content${propertyName.charAt(0).toUpperCase()}${propertyName.substring(1).toLowerCase()}`;
+ this[propertyName] = h.value;
+ this.headers[propertyName] = h;
+ }
+ }
+ this.forcedUTF8 = false;
+ }
+
+ get charset() {
+ let charset = "";
+ if (this.contentType) {
+ let m = this.contentType.match(/;\s*charset\s*=\s*(\S+)/);
+ if (m) {
+ charset = m[1];
+ }
+ }
+ Object.defineProperty(this, "charset", { value: charset, writable: false, configurable: true });
+ return charset;
+ }
+
+ get isUTF8() {
+ return /^utf-8$/i.test(this.charset);
+ }
+
+ forceUTF8() {
+ if (!(this.forcedUTF8 || this.isUTF8)) {
+ let h = this.headers.contentType;
+ if (h) {
+ h.value = h.value.replace(/;\s*charset\s*=.*|$/, "; charset=utf8");
+ this.forcedUTF8 = true;
+ } // if the header doesn't exist the browser should default to UTF-8 anyway
+ }
+ return this.forcedUTF8;
+ }
+
+ createDecoder() {
+ if (this.charset) {
+ try {
+ return new TextDecoder(this.charset);
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ return new TextDecoder("utf-8");
+ }
+};
+
+module.exports = { ResponseMetaData };