Commit 2c152076 authored by Laurent Wouters's avatar Laurent Wouters
Browse files

Preempts the page's content when looking at raw data

parent 9c8fa240e7a9
......@@ -27,7 +27,8 @@ import {
DataSourcePage,
Link,
DataSource,
tryNegotiateData
tryNegotiateData,
MimeInfo
} from "../common/api";
/// <reference path="./fallback.d.ts"/>
let F = require("./register");
......@@ -169,6 +170,25 @@ function getHeader(
return null;
}
/**
* Set the value of a header
* @param headers The headers
* @param name The name of a header
* @param value The value for the header
*/
function setHeader(
headers: chrome.webRequest.HttpHeader[],
name: string,
value: string
): void {
for (var i = 0; i != headers.length; i++) {
if (headers[i].name == name) {
headers[i].value = value;
}
}
headers.push({ name: name, value: value });
}
/**
* Detects linked data in HTTP headers
* @param headers he headers
......@@ -205,13 +225,52 @@ function detectDataOnContent(
: NO_DATA;
}
/**
* Gets whether based on the specified details a request's content should be pre-empted
* @param details The details of an incoming request
*/
function shouldPreempt(
details: chrome.webRequest.WebResponseHeadersDetails
): MimeInfo {
let contentType = getHeader(details.responseHeaders, "Content-Type");
contentType = contentType != null ? contentType.split(";")[0] : null;
let mimes = Object.keys(MIME).map((key: string) => MIME[key]);
for (var i = 0; i != mimes.length; i++) {
if (
mimes[i].mime == contentType ||
details.url.endsWith(mimes[i].fileExtension)
) {
return mimes[i];
}
}
return null;
}
/**
* Preempts the content of a request
* @param details The details of an incoming request
* @param mime The catpured MIME type
*/
function doPreempt(
details: chrome.webRequest.WebResponseHeadersDetails,
mime: MimeInfo
): chrome.webRequest.BlockingResponse {
let headers = details.responseHeaders;
setHeader(headers, "Content-Type", "text/plain");
let data = getTabData(details.tabId);
data.sources.push(new DataSourcePage(details.url, mime.mime));
data.isActive = true; // activate by default
data.selectMain();
return { responseHeaders: headers };
}
/**
* When headers are received for a tab
* @param details The details
*/
function onHeadersReceived(
details: chrome.webRequest.WebResponseHeadersDetails
): void {
): chrome.webRequest.BlockingResponse {
if (
details.tabId == -1 || // invalid tab
details.frameId != 0 || // not the main top-level frame
......@@ -219,13 +278,17 @@ function onHeadersReceived(
(details.hasOwnProperty("originUrl") &&
(details as any).originUrl != details.url) // not the original URL
)
return;
console.log("inspecting request to " + details.url);
return {};
let data = getTabData(details.tabId);
if (data.mainSource != NO_DATA)
// already detected something
return;
return {};
let mime = shouldPreempt(details);
if (mime != null) {
// preempts this request
return doPreempt(details, mime);
}
data.sources.push(detectDataOnContent(details, details.responseHeaders));
data.sources = data.sources.concat(
detectDataOnLinks(details.responseHeaders)
......@@ -244,6 +307,7 @@ function onHeadersReceived(
});
}
updateIcon(details.tabId);
return {};
}
/**
......@@ -273,7 +337,7 @@ function onCompleted(
chrome.webRequest.onHeadersReceived.addListener(
onHeadersReceived,
{ urls: ["<all_urls>"] },
["responseHeaders"]
["blocking", "responseHeaders"]
);
// listen to navigation
F.registerNavigations(onBeforeNavigate, onCompleted);
......@@ -283,12 +347,8 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.reqType == "links") {
data.sources = data.sources.concat(
request.links
.filter((link: Link) => {
return link.refersToData();
})
.map((link: Link) => {
return new DataSourceLinked(link);
})
.filter((link: Link) => link.refersToData())
.map((link: Link) => new DataSourceLinked(link))
);
data.selectMain();
updateIcon(sender.tab.id);
......
......@@ -22,6 +22,18 @@
* Metadata about a MIME type
*/
export class MimeInfo {
constructor(
mime: string,
name: string,
priority: number,
fileExtension: string
) {
this.mime = mime;
this.name = name;
this.priority = priority;
this.fileExtension = fileExtension;
}
/**
* The MIME type
*/
......@@ -34,6 +46,10 @@ export class MimeInfo {
* The relative priority of using this MIME type (lower is better)
*/
priority: number;
/**
* The associated file extension
*/
fileExtension: string;
}
/**
......@@ -82,29 +98,18 @@ export class Link {
* Map of known MIME types to badge names
*/
export const MIME: { [mime: string]: MimeInfo } = {
"text/n3": { mime: "text/n3", name: "N3", priority: 5 },
"application/n-triples": {
mime: "application/n-triples",
name: "NT",
priority: 6
},
"application/n-quads": {
mime: "application/n-quads",
name: "NQ",
priority: 7
},
"text/turtle": { mime: "text/turtle", name: "TTL", priority: 8 },
"application/trig": { mime: "application/trig", name: "TRIG", priority: 9 },
"application/rdf+xml": {
mime: "application/rdf+xml",
name: "RDF",
priority: 10
},
"application/ld+json": {
mime: "application/ld+json",
name: "LD",
priority: 11
}
"text/n3": new MimeInfo("text/n3", "N3", 5, ".n3"),
"application/n-triples": new MimeInfo(
"application/n-triples",
"NT",
6,
".nt"
),
"application/n-quads": new MimeInfo("application/n-quads", "NQ", 7, ".nq"),
"text/turtle": new MimeInfo("text/turtle", "TTL", 8, ".ttl"),
"application/trig": new MimeInfo("application/trig", "TRIG", 9, ".trig"),
"application/rdf+xml": new MimeInfo("application/rdf+xml", "RDF", 10, ".xml"),
"application/ld+json": new MimeInfo("application/ld+json", "LD", 11, ".json")
};
/**
......
......@@ -9,6 +9,7 @@
"permissions": [
"tabs",
"webRequest",
"webRequestBlocking",
"webNavigation",
"*://*/*"
],
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment