-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
159 lines (141 loc) · 5.21 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// This file implements LLaMA, a client-side defense against WF,
// as an add-on for the Tor browser. It can be easily installed
// by following the same procedure as with any other FF add-ons.
const { Cc, Ci } = require('chrome')
const observerService = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const URL = "https://tablog-webfpext.rhcloud.com/getsize.php";
const Request = require("sdk/request").Request;
// whether to delay requests
const DELAY = true;
// whether to send extra requests
const EXTRA = true;
// Median time to load a site in our dataset.
const MEDIAN_TOTAL = 3600;
// it will last until the end of the session
// we could flush it from time to time. we can
// keep it as it is for now.
var DOMAINS = {};
// send an HTTP request
var sendRequest = function(target) {
var req = Request({
url: target,
overrideMimeType: "text/plain;",
onComplete: function(response) {
// log extra response
var sz = response.text.length;
console.log("X-RES: " + target + " (" + sz + "B)");
}
});
var d = new Date();
var ts = d.getTime();
// log extra request
console.log("X-REQ: " + target);
req.get();
}
// send a custom-sized request
var sendSizeRequest = function(size) {
sendRequest(URL + '?size=' + size);
}
// send a request depending on the outcome of tossing a coin
var probSendRequest = function(sendRequestCallback, arg, delay) {
if (typeof delay === "undefined") {
delay = Math.floor(Math.random() * 1001);
}
if (Math.random() > 0.5) {
// Delay request
delayedFunction(delay, function() {
sendRequestCallback(arg);
});
}
}
// trigger another request with some prob
var customNewRequest = function() {
var size = Math.floor(Math.random() * 1000001);
probSendRequest(sendSizeRequest, size);
}
// repeat a previous request with some prob
var repeatRandomRequest = function(domain) {
var requests = DOMAINS[domain];
// select a previous request uniformly at random
if (!(typeof requests === "undefined") && (requests.length > 0)) {
var url = requests[Math.floor(Math.random() * requests.length)];
probSendRequest(sendRequest, url, 0);
}
}
// delay the execution of a function
var delayedFunction = function(delay, fun) {
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback({
notify: function(timer) {
fun();
}
}, delay, Ci.nsITimer.TYPE_ONE_SHOT);
}
var httpObs = {
observe: function(aSubject, aTopic, aData) {
aSubject.QueryInterface(Ci.nsIHttpChannel);
var visitor = new HeaderInfoVisitor(aSubject);
if (aTopic == "http-on-modify-request") {
// suspend request and schecule resume after a number
// between 0 and 1 seconds.
if (aSubject instanceof Ci.nsIRequest) { // Is this needed?
// add url for this domain
if (aSubject.URI instanceof Ci.nsIURI) {
var requestHeaders = visitor.visitRequest();
var domain = aSubject.URI.host;
var url = aSubject.URI.spec;
var sheaders = get_str(requestHeaders);
console.log("REQ: " + url + ", headers=" + sheaders);
// add domain to known domains
if (!(domain in DOMAINS)) {
DOMAINS[domain] = [];
}
if (DOMAINS[domain].indexOf(url) == -1) {
DOMAINS[domain].push(url);
}
// delay request
if (DELAY) {
aSubject.suspend();
// sample a delay
d = Math.floor(Math.random() * MEDIAN_TOTAL);
delayedFunction(d, function() {
aSubject.resume();
console.log("RESUMED: " + url);
});
console.log("DELAY: " + url + "("+ d +" ms)");
}
if (EXTRA) {
// fire another request after this one?
repeatRandomRequest(domain);
}
}
}
} else if (aTopic == "http-on-examine-response") {
var url = aSubject.URI.asciiSpec;
var responseHeaders = visitor.visitResponse();
var sheaders = get_str(responseHeaders);
console.log("RESP: " + url + ", headers=" + sheaders);
}
},
};
function HeaderInfoVisitor(oHttp) {
this.oHttp = oHttp;
this.headers = new Array();
}
HeaderInfoVisitor.prototype = {
visitHeader: function(name, value) {
this.headers[name] = value;
},
visitRequest: function() {
this.oHttp.visitRequestHeaders(this);
return this.headers;
},
visitResponse: function() {
this.oHttp.visitResponseHeaders(this);
return this.headers;
}
};
// register HTTP observers
observerService.addObserver(httpObs, "http-on-modify-request", false);
observerService.addObserver(httpObs, "http-on-examine-response", false);