Pārlūkot izejas kodu

re-check block decision when filtering, now we know content type

tags/v0.5.0
Jonathan Cobb pirms 5 gadiem
vecāks
revīzija
3a785ebb34
4 mainītis faili ar 58 papildinājumiem un 10 dzēšanām
  1. +3
    -0
      bubble-server/src/main/java/bubble/resources/stream/FilterMatchersRequest.java
  2. +3
    -0
      bubble-server/src/main/java/bubble/rule/AppRuleDriver.java
  3. +51
    -9
      bubble-server/src/main/java/bubble/rule/bblock/BubbleBlock.java
  4. +1
    -1
      utils/abp-parser

+ 3
- 0
bubble-server/src/main/java/bubble/resources/stream/FilterMatchersRequest.java Parādīt failu

@@ -1,5 +1,6 @@
package bubble.resources.stream;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@@ -21,4 +22,6 @@ public class FilterMatchersRequest {
// FilterHttpResource.matchersCache cache would be useless, since every cache entry would be unique
public String cacheKey() { return hashOf(fqdn, uri, userAgent, referer, remoteAddr); }

@JsonIgnore public String getUrl() { return fqdn + "/" + uri; }

}

+ 3
- 0
bubble-server/src/main/java/bubble/rule/AppRuleDriver.java Parādīt failu

@@ -14,6 +14,7 @@ import org.cobbzilla.util.handlebars.HandlebarsUtil;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.jersey.server.ContainerRequest;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Map;

@@ -23,6 +24,8 @@ import static org.cobbzilla.util.string.StringUtil.getPackagePath;

public interface AppRuleDriver {

InputStream EMPTY_STREAM = new ByteArrayInputStream(new byte[0]);

AppRuleDriver getNext();
void setNext(AppRuleDriver next);
default boolean hasNext() { return getNext() != null; }


+ 51
- 9
bubble-server/src/main/java/bubble/rule/bblock/BubbleBlock.java Parādīt failu

@@ -1,9 +1,6 @@
package bubble.rule.bblock;

import bubble.abp.BlockDecision;
import bubble.abp.BlockList;
import bubble.abp.BlockListSource;
import bubble.abp.BlockSpec;
import bubble.abp.*;
import bubble.model.account.Account;
import bubble.model.app.AppMatcher;
import bubble.model.app.AppRule;
@@ -42,6 +39,7 @@ import static org.cobbzilla.util.string.StringUtil.getPackagePath;
@Slf4j
public class BubbleBlock extends TrafficAnalytics {

private static final String META_REQUEST = "__bubble_request";
private static final String META_BLOCK_FILTERS = "__bubble_block_filters";

private BubbleBlockConfig bubbleBlockConfig;
@@ -90,11 +88,11 @@ public class BubbleBlock extends TrafficAnalytics {
case allow: default:
return FilterMatchResponse.NO_MATCH;
case filter:
return getFilterMatchResponse(decision);
return getFilterMatchResponse(filter, decision);
}
}

public FilterMatchResponse getFilterMatchResponse(BlockDecision decision) {
public FilterMatchResponse getFilterMatchResponse(FilterMatchersRequest filter, BlockDecision decision) {
switch (decision.getDecisionType()) {
case block: return FilterMatchResponse.ABORT_NOT_FOUND;
case allow: return FilterMatchResponse.NO_MATCH;
@@ -106,7 +104,9 @@ public class BubbleBlock extends TrafficAnalytics {
} else {
return new FilterMatchResponse()
.setDecision(FilterMatchDecision.match)
.setMeta(new NameAndValue[]{new NameAndValue(META_BLOCK_FILTERS, json(specs, COMPACT_MAPPER))});
.setMeta(new NameAndValue[]{
new NameAndValue(META_REQUEST, json(filter, COMPACT_MAPPER))
});
}
}
return die("getFilterMatchResponse: invalid decisionType: "+decision.getDecisionType());
@@ -114,9 +114,51 @@ public class BubbleBlock extends TrafficAnalytics {

@Override public InputStream doFilterResponse(String requestId, String contentType, NameAndValue[] meta, InputStream in) {

final String blockSpecJson = NameAndValue.find(meta, META_BLOCK_FILTERS);
if (empty(blockSpecJson) || !isHtml(contentType)) return in;
final String requestJson = NameAndValue.find(meta, META_REQUEST);
if (requestJson == null) {
log.error("doFilterResponse: no request found, returning EMPTY_STREAM");
return EMPTY_STREAM;
}

final FilterMatchersRequest request;
try {
request = json(requestJson, FilterMatchersRequest.class);
} catch (Exception e) {
log.error("doFilterResponse: error parsing request, returning EMPTY_STREAM: "+shortError(e));
return EMPTY_STREAM;
}

// 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");
return EMPTY_STREAM;
case allow:
log.warn("doFilterRequest: preprocessed request was filtered, but ultimate decision was allow, returning as-is");
return in;
case filter:
if (!decision.hasSpecs()) {
// should never happen
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
log.warn("doFilterRequest: preprocessed request was filtered, but ultimate decision was invalid, returning EMPTY_STREAM");
return EMPTY_STREAM;
}


if (!isHtml(contentType)) {
log.warn("doFilterRequest: cannot filter non-html response ("+request.getUrl()+"), returning as-is: "+contentType);
return in;
}

final String blockSpecJson = json(filters, COMPACT_MAPPER);
final String replacement = "<head><script>" + getBubbleJs(requestId, blockSpecJson) + "</script>";
final RegexReplacementFilter filter = new RegexReplacementFilter("<head>", replacement);
final RegexFilterReader reader = new RegexFilterReader(new InputStreamReader(in), filter).setMaxMatches(1);


+ 1
- 1
utils/abp-parser

@@ -1 +1 @@
Subproject commit 2528e6ba5c69420515c08662899e123ea9334166
Subproject commit f82c8215876ba8e26a51541111c5befd009ad1d3

Notiek ielāde…
Atcelt
Saglabāt