소스 검색

block page elements

tags/v0.5.0
Jonathan Cobb 4 년 전
부모
커밋
78a3fb96b9
3개의 변경된 파일115개의 추가작업 그리고 7개의 파일을 삭제
  1. +8
    -6
      bubble-server/src/main/java/bubble/rule/bblock/BubbleBlock.java
  2. +106
    -0
      bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlock.js.hbs
  3. +1
    -1
      utils/abp-parser

+ 8
- 6
bubble-server/src/main/java/bubble/rule/bblock/BubbleBlock.java 파일 보기

@@ -132,7 +132,6 @@ public class BubbleBlock extends TrafficAnalytics {

// Now that we know the content type, re-check the BlockList
final BlockDecision decision = blockList.getDecision(request.getFqdn(), request.getUri(), contentType);
final List<BlockSpec> filters;
switch (decision.getDecisionType()) {
case block:
log.warn("doFilterRequest: preprocessed request was filtered, but ultimate decision was block, returning EMPTY_STREAM");
@@ -146,7 +145,6 @@ public class BubbleBlock extends TrafficAnalytics {
log.warn("doFilterRequest: preprocessed request was filtered, but ultimate decision was filtered, but no filters provided, returning as-is");
return in;
}
filters = decision.getSpecs();
break;
default:
// should never happen
@@ -159,8 +157,7 @@ public class BubbleBlock extends TrafficAnalytics {
return in;
}

final String selectorsJson = json(decision.getSelectors(), COMPACT_MAPPER);
final String replacement = "<head><script>" + getBubbleJs(requestId, selectorsJson) + "</script>";
final String replacement = "<head><script>" + getBubbleJs(requestId, decision) + "</script>";
final RegexReplacementFilter filter = new RegexReplacementFilter("<head>", replacement);
final RegexFilterReader reader = new RegexFilterReader(new InputStreamReader(in), filter).setMaxMatches(1);
return new ReaderInputStream(reader, UTF8cs);
@@ -169,14 +166,19 @@ public class BubbleBlock extends TrafficAnalytics {
public static final Class<BubbleBlock> BB = BubbleBlock.class;
public static final String BUBBLE_JS_TEMPLATE = stream2string(getPackagePath(BB)+"/"+ BB.getSimpleName()+".js.hbs");
private static final String CTX_BUBBLE_SELECTORS = "BUBBLE_SELECTORS_JSON";
private static final String CTX_BUBBLE_BLACKLIST = "BUBBLE_BLACKLIST_JSON";
private static final String CTX_BUBBLE_WHITELIST = "BUBBLE_WHITELIST_JSON";

private String getBubbleJs(String requestId, BlockDecision decision) {

private String getBubbleJs(String requestId, String blockSpecJson) {
final Map<String, Object> ctx = new HashMap<>();
ctx.put(CTX_JS_PREFIX, "__bubble_block_"+sha256_hex(requestId)+"_");
ctx.put(CTX_BUBBLE_REQUEST_ID, requestId);
ctx.put(CTX_BUBBLE_HOME, configuration.getPublicUriBase());
ctx.put(CTX_BUBBLE_DATA_ID, getDataId(requestId));
ctx.put(CTX_BUBBLE_SELECTORS, blockSpecJson);
ctx.put(CTX_BUBBLE_SELECTORS, json(decision.getSelectors(), COMPACT_MAPPER));
ctx.put(CTX_BUBBLE_WHITELIST, json(blockList.getWhitelistDomains(), COMPACT_MAPPER));
ctx.put(CTX_BUBBLE_BLACKLIST, json(blockList.getBlacklistDomains(), COMPACT_MAPPER));
return HandlebarsUtil.apply(getHandlebars(), BUBBLE_JS_TEMPLATE, ctx);
}



+ 106
- 0
bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlock.js.hbs 파일 보기

@@ -3,8 +3,96 @@ const {{JS_PREFIX}}_request_id = '{{BUBBLE_REQUEST_ID}}';
const {{JS_PREFIX}}_interval = 50;
const {{JS_PREFIX}}_idle_interval = 1000;

const {{JS_PREFIX}}_blacklist = {{{BUBBLE_BLACKLIST_JSON}}};
const {{JS_PREFIX}}_whitelist = {{{BUBBLE_WHITELIST_JSON}}};

const {{JS_PREFIX}}_filters = {{{BUBBLE_SELECTORS_JSON}}};

function {{JS_PREFIX}}_check_entry_exclusions_and_types(entry, url, type) {
if (typeof entry.domainExclusions !== 'undefined' && entry.domainExclusions !== null) {
for (let i=0; i<entry.domainExclusions.length; i++) {
if (entry.domainExclusions[i] === url.hostname) return false;
}
}
if (typeof type !== 'undefined' && type !== null) {
if (typeof entry.typeExclusions !== 'undefined' && entry.typeExclusions !== null) {
for (let i=0; i<entry.typeExclusions.length; i++) {
if (entry.typeExclusions[i] === type) return false;
}
}
if (typeof entry.typeMatches !== 'undefined' && entry.typeMatches !== null) {
for (let i=0; i<entry.typeExclusions.length; i++) {
if (entry.typeMatches[i] === type) return true;
}
return false;
}
}
return true;
}

function {{JS_PREFIX}}_entry_matches(entry, url, type) {
const target = entry.target;
if (typeof target.domainRegex !== 'undefined' && target.domainRegex !== null && url.hostname.matches(target.domainRegex) !== null) {
return {{JS_PREFIX}}_check_entry_exclusions_and_types(entry, url, type);
}
if (typeof target.regex !== 'undefined' && target.regex !== null && (url.hostname.matches(target.regex) !== null || url.pathname.matches(target.regex) !== null)) {
return {{JS_PREFIX}}_check_entry_exclusions_and_types(entry, url, type);
}
}

function {{JS_PREFIX}}_block_target(url, type) {
if (typeof url === 'undefined' || url == null) return false;
let u;
try {
u = new URL(url);
} catch (e) {
return false;
}
if (typeof type === 'undefined' || type === null) {
if (url.pathname.endsWith('.png')
|| url.pathname.endsWith('.gif')
|| url.pathname.endsWith('.jpeg')
|| url.pathname.endsWith('.jpg')) {
type = 'image';
} else if (url.pathname.endsWith('.css')) {
type = 'stylesheet';
} else if (url.pathname.endsWith('.js')) {
type = 'script';
} else {
type = null;
}
for (let i=0; i<{{JS_PREFIX}}_whitelist.length; i++) {
const entry = {{JS_PREFIX}}_whitelist[i];
if ({{JS_PREFIX}}_entry_matches(entry, u, type)) return false;
}
for (let i=0; i<{{JS_PREFIX}}_blacklist.length; i++) {
const entry = {{JS_PREFIX}}_blacklist[i];
if ({{JS_PREFIX}}_entry_matches(entry, u, type)) return true;
}
return false;
}

window.f = Element.prototype.appendChild;
Element.prototype.appendChild = function() {
let type = null;
if (arguments[0] instance HTMLImageElement) {
type = 'image';
}
if (typeof arguments[0].src !== 'undefined') {
if ({{JS_PREFIX}}_block_target(arguments[0].src, type)) {
console.log('BLOCKING appendChild for '+arguments[0]+', src='+arguments[0].src);
return;
}
}
if (typeof arguments[0].href !== 'undefined') {
if ({{JS_PREFIX}}_block_target(arguments[0].href, type)) {
console.log('BLOCKING appendChild for '+arguments[0]+', src='+arguments[0].href);
return;
}
}
return window.f.apply(this, arguments);
};

function {{JS_PREFIX}}_onReady(callback) {
const intervalId = window.setInterval(function() {
if (document.getElementsByTagName('body')[0] !== undefined) {
@@ -212,6 +300,24 @@ function {{JS_PREFIX}}_process_filters() {
}
}
console.log('{{JS_PREFIX}}_process_filters: finished processing '+{{JS_PREFIX}}_filters.length+' filters');

const images = document.getElementsByTagName('img');
for (let i=0; i<images.length; i++) {
const image = images[i];
if ({{JS_PREFIX}}_block_target(image.src, 'image')) {
console.log('removing image: '+image.outerHTML);
image.parentNode.removeChild(image);
}
}
const anchors = document.getElementsByTagName('a');
for (let i=0; i<anchors.length; i++) {
const anchor = anchors[i];
if ({{JS_PREFIX}}_block_target(anchor.href)) {
console.log('removing anchor: '+anchor.outerHTML);
anchor.parentNode.removeChild(anchor);
}
}

}

{{JS_PREFIX}}_onReady(function() {


+ 1
- 1
utils/abp-parser

@@ -1 +1 @@
Subproject commit efef4043d70e2f63243a712fec7d28b7a64a1490
Subproject commit ab3185282fb6258c662fda4fd6d09a038a6560ea

불러오는 중...
취소
저장