Skip to content

Commit 4ab93ca

Browse files
committed
Match filters against both up & downstream content
1 parent d4d8cc8 commit 4ab93ca

File tree

3 files changed

+46
-36
lines changed

3 files changed

+46
-36
lines changed

src/components/view/view-page.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,13 @@ class ViewPage extends React.Component<ViewPageProps> {
194194

195195
const filteredEvents = (this.currentSearchFilters.length === 0)
196196
? events
197-
: events.filter((event) =>
198-
this.currentSearchFilters.every((f) => f.matches(event))
199-
);
197+
: events.filter((event) => {
198+
if (event.isHttp() && event.wasTransformed) {
199+
return this.currentSearchFilters.every((f) => f.matches(event.downstream) || f.matches(event.upstream!))
200+
} else {
201+
return this.currentSearchFilters.every((f) => f.matches(event))
202+
}
203+
});
200204

201205
return {
202206
filteredEvents,

src/model/filters/search-filters.ts

+33-33
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as _ from 'lodash';
22

3-
import { CollectedEvent, ViewableEvent } from '../../types';
3+
import { ViewableEvent } from '../../types';
44
import { joinAnd } from '../../util/text';
55
import { stringToBuffer } from '../../util/buffer';
66

@@ -106,7 +106,7 @@ export class StringFilter extends Filter {
106106
super(filter);
107107
}
108108

109-
matches(event: CollectedEvent): boolean {
109+
matches(event: ViewableEvent): boolean {
110110
if (this.filter === '') return true;
111111
const filter = this.filter.toLocaleLowerCase();
112112
return event.searchIndex.includes(filter);
@@ -246,7 +246,7 @@ class StatusFilter extends Filter {
246246
"<"
247247
]),
248248
new FixedLengthNumberSyntax(3, {
249-
suggestionGenerator: (_v, _i, events: CollectedEvent[]) =>
249+
suggestionGenerator: (_v, _i, events: ViewableEvent[]) =>
250250
_(events)
251251
.map(e =>
252252
'response' in e &&
@@ -298,7 +298,7 @@ class StatusFilter extends Filter {
298298
this.predicate = numberOperations[this.op];
299299
}
300300

301-
matches(event: CollectedEvent): boolean {
301+
matches(event: ViewableEvent): boolean {
302302
return event.isHttp() &&
303303
event.isSuccessfulExchange() &&
304304
this.predicate(event.response.statusCode, this.status);
@@ -319,7 +319,7 @@ class CompletedFilter extends Filter {
319319
return "requests that have received a response";
320320
}
321321

322-
matches(event: CollectedEvent): boolean {
322+
matches(event: ViewableEvent): boolean {
323323
return event.isHttp() &&
324324
event.isSuccessfulExchange();
325325
}
@@ -339,7 +339,7 @@ class PendingFilter extends Filter {
339339
return "requests that are still waiting for a response";
340340
}
341341

342-
matches(event: CollectedEvent): boolean {
342+
matches(event: ViewableEvent): boolean {
343343
return event.isHttp() &&
344344
!event.isCompletedExchange();
345345
}
@@ -359,7 +359,7 @@ class AbortedFilter extends Filter {
359359
return "requests whose connection failed before receiving a response";
360360
}
361361

362-
matches(event: CollectedEvent): boolean {
362+
matches(event: ViewableEvent): boolean {
363363
return event.isHttp() &&
364364
event.response === 'aborted'
365365
}
@@ -379,7 +379,7 @@ class ErrorFilter extends Filter {
379379
return "requests that weren't transmitted successfully";
380380
}
381381

382-
matches(event: CollectedEvent): boolean {
382+
matches(event: ViewableEvent): boolean {
383383
return !(event.isHttp()) || // TLS Error
384384
event.tags.some(tag =>
385385
tag.startsWith('client-error') ||
@@ -402,7 +402,7 @@ class PinnedFilter extends Filter {
402402
return "exchanges that are pinned";
403403
}
404404

405-
matches(event: CollectedEvent): boolean {
405+
matches(event: ViewableEvent): boolean {
406406
return event.pinned;
407407
}
408408

@@ -439,7 +439,7 @@ class CategoryFilter extends Filter {
439439
this.expectedCategory = categoryString;
440440
}
441441

442-
matches(event: CollectedEvent): boolean {
442+
matches(event: ViewableEvent): boolean {
443443
return event.isHttp() &&
444444
event.category === this.expectedCategory
445445
}
@@ -459,7 +459,7 @@ class MethodFilter extends Filter {
459459
]),
460460
new StringSyntax("method", {
461461
allowedChars: ALPHABETICAL,
462-
suggestionGenerator: (_v, _i, events: CollectedEvent[]) =>
462+
suggestionGenerator: (_v, _i, events: ViewableEvent[]) =>
463463
_(events)
464464
.map(e => e.isHttp() && e.request.method)
465465
.uniq()
@@ -502,7 +502,7 @@ class MethodFilter extends Filter {
502502
this.expectedMethod = method.toUpperCase();
503503
}
504504

505-
matches(event: CollectedEvent): boolean {
505+
matches(event: ViewableEvent): boolean {
506506
return event.isHttp() &&
507507
this.predicate(event.request.method.toUpperCase(), this.expectedMethod);
508508
}
@@ -541,7 +541,7 @@ class HttpVersionFilter extends Filter {
541541
this.expectedVersion = parseInt(versionString, 10);
542542
}
543543

544-
matches(event: CollectedEvent): boolean {
544+
matches(event: ViewableEvent): boolean {
545545
return event.isHttp() &&
546546
Math.round(event.httpVersion) === this.expectedVersion;
547547
}
@@ -567,7 +567,7 @@ class WebSocketFilter extends Filter {
567567
super(filter);
568568
}
569569

570-
matches(event: CollectedEvent): boolean {
570+
matches(event: ViewableEvent): boolean {
571571
return event instanceof WebSocketStream;
572572
}
573573

@@ -609,7 +609,7 @@ class ProtocolFilter extends Filter {
609609
this.expectedProtocol = protocol.toLowerCase();
610610
}
611611

612-
matches(event: CollectedEvent): boolean {
612+
matches(event: ViewableEvent): boolean {
613613
if (!(event.isHttp())) return false;
614614

615615
// Parsed protocol is like 'http:', so we strip the colon
@@ -639,7 +639,7 @@ class HostnameFilter extends Filter {
639639
charRange("-"),
640640
charRange(".")
641641
],
642-
suggestionGenerator: (_v, _i, events: CollectedEvent[]) =>
642+
suggestionGenerator: (_v, _i, events: ViewableEvent[]) =>
643643
_(events)
644644
.map(e => e.isHttp() && e.request.parsedUrl.hostname.toLowerCase())
645645
.uniq()
@@ -674,7 +674,7 @@ class HostnameFilter extends Filter {
674674
this.expectedHostname = hostname.toLowerCase();
675675
}
676676

677-
matches(event: CollectedEvent): boolean {
677+
matches(event: ViewableEvent): boolean {
678678
return event.isHttp() &&
679679
this.predicate(
680680
event.request.parsedUrl.hostname.toLowerCase(),
@@ -731,7 +731,7 @@ class PortFilter extends Filter {
731731
this.predicate = numberOperations[this.op];
732732
}
733733

734-
matches(event: CollectedEvent): boolean {
734+
matches(event: ViewableEvent): boolean {
735735
if (!(event.isHttp())) return false;
736736

737737
const { protocol, port: explicitPort } = event.request.parsedUrl;
@@ -762,7 +762,7 @@ class PathFilter extends Filter {
762762
"$="
763763
]),
764764
new StringSyntax("path", {
765-
suggestionGenerator: (_v, _i, events: CollectedEvent[]) =>
765+
suggestionGenerator: (_v, _i, events: ViewableEvent[]) =>
766766
_(events)
767767
.map(e => e.isHttp() && e.request.parsedUrl.pathname)
768768
.uniq()
@@ -795,7 +795,7 @@ class PathFilter extends Filter {
795795
this.predicate = stringOperations[this.op];
796796
}
797797

798-
matches(event: CollectedEvent): boolean {
798+
matches(event: ViewableEvent): boolean {
799799
return event.isHttp() &&
800800
this.predicate(event.request.parsedUrl.pathname, this.expectedPath);
801801
}
@@ -827,7 +827,7 @@ class QueryFilter extends Filter {
827827
// You can pass an empty query only to = or !=
828828
return op === "=" || op === "!=";
829829
},
830-
suggestionGenerator: (_v, _i, events: CollectedEvent[]) =>
830+
suggestionGenerator: (_v, _i, events: ViewableEvent[]) =>
831831
_(events)
832832
.map(e => e.isHttp() && e.request.parsedUrl.search)
833833
.uniq()
@@ -877,7 +877,7 @@ class QueryFilter extends Filter {
877877
this.predicate = stringOperations[this.op];
878878
}
879879

880-
matches(event: CollectedEvent): boolean {
880+
matches(event: ViewableEvent): boolean {
881881
return event.isHttp() &&
882882
this.predicate(event.request.parsedUrl.search, this.expectedQuery);
883883
}
@@ -887,7 +887,7 @@ class QueryFilter extends Filter {
887887
}
888888
}
889889

890-
const getAllHeaders = (e: CollectedEvent): [string, string | string[]][] => {
890+
const getAllHeaders = (e: ViewableEvent): [string, string | string[]][] => {
891891
if (!(e.isHttp())) return [];
892892
return [
893893
...Object.entries(e.request.headers),
@@ -913,7 +913,7 @@ class HeadersFilter extends Filter {
913913
['[', ']'],
914914
new StringSyntax("header value", {
915915
allowedChars: [[0, 255]], // Any ASCII! Wrapper guards against spaces for us.
916-
suggestionGenerator: (value, index, events: CollectedEvent[]) => {
916+
suggestionGenerator: (value, index, events: ViewableEvent[]) => {
917917
return _(events)
918918
.map(e =>
919919
_(getAllHeaders(e))
@@ -961,7 +961,7 @@ class HeadersFilter extends Filter {
961961
this.expectedHeaderValue = headerValue.toLowerCase();
962962
}
963963

964-
matches(event: CollectedEvent): boolean {
964+
matches(event: ViewableEvent): boolean {
965965
if (!(event.isHttp())) return false;
966966

967967
const headers = getAllHeaders(event);
@@ -993,7 +993,7 @@ class HeaderFilter extends Filter {
993993
['[', ']'],
994994
new StringSyntax("header value", {
995995
allowedChars: [[0, 255]], // Any ASCII! Wrapper guards against spaces for us.
996-
suggestionGenerator: (value, index, events: CollectedEvent[]) => {
996+
suggestionGenerator: (value, index, events: ViewableEvent[]) => {
997997
// Find the start of the wrapped header name text that precedes this
998998
const headerNameIndex = value.slice(0, index - 1).lastIndexOf('[');
999999

@@ -1030,7 +1030,7 @@ class HeaderFilter extends Filter {
10301030
new SyntaxWrapperSyntax(
10311031
['[', ']'],
10321032
new StringSyntax("header name", {
1033-
suggestionGenerator: (_v, _i, events: CollectedEvent[]) =>
1033+
suggestionGenerator: (_v, _i, events: ViewableEvent[]) =>
10341034
_(events)
10351035
.map(e =>
10361036
getAllHeaders(e).map(([headerName]) =>
@@ -1088,7 +1088,7 @@ class HeaderFilter extends Filter {
10881088
}
10891089
}
10901090

1091-
matches(event: CollectedEvent): boolean {
1091+
matches(event: ViewableEvent): boolean {
10921092
if (!(event.isHttp())) return false;
10931093

10941094
const headers = getAllHeaders(event);
@@ -1153,7 +1153,7 @@ class BodySizeFilter extends Filter {
11531153
this.predicate = numberOperations[this.op];
11541154
}
11551155

1156-
matches(event: CollectedEvent): boolean {
1156+
matches(event: ViewableEvent): boolean {
11571157
if (!(event.isHttp())) return false;
11581158

11591159
const requestBody = event.request.body;
@@ -1219,7 +1219,7 @@ class BodyFilter extends Filter {
12191219
this.predicate = bufferOperations[this.op];
12201220
}
12211221

1222-
matches(event: CollectedEvent): boolean {
1222+
matches(event: ViewableEvent): boolean {
12231223
if (!event.isHttp()) return false;
12241224
if (!event.hasRequestBody() && !event.hasResponseBody()) return false; // No body, no match
12251225

@@ -1276,7 +1276,7 @@ class ContainsFilter extends Filter {
12761276
this.expectedContent = expectedContent.toLowerCase();
12771277
}
12781278

1279-
matches(event: CollectedEvent): boolean {
1279+
matches(event: ViewableEvent): boolean {
12801280
let content: Array<string | Buffer | number | undefined>;
12811281

12821282
if (event.isHttp()) {
@@ -1428,7 +1428,7 @@ class NotFilter extends Filter {
14281428
this.innerFilter = new matchingFilterClass(innerValue) as Filter; // Never Filters - we don't support filter aliases here
14291429
}
14301430

1431-
matches(event: CollectedEvent): boolean {
1431+
matches(event: ViewableEvent): boolean {
14321432
return !this.innerFilter.matches(event);
14331433
}
14341434

@@ -1505,7 +1505,7 @@ class OrFilter extends Filter {
15051505
});
15061506
}
15071507

1508-
matches(event: CollectedEvent): boolean {
1508+
matches(event: ViewableEvent): boolean {
15091509
return this.innerFilters.some(f => f.matches(event));
15101510
}
15111511

src/model/http/http-exchange.ts

+6
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ export class HttpExchange extends HTKEventBase implements HttpExchangeView {
181181
}
182182
}
183183

184+
@computed
185+
get wasTransformed() {
186+
if (!this.upstream) return false;
187+
return this.upstream.wasTransformed;
188+
}
189+
184190
// An autorun, which ensures the transformed & original views are kept observed & updated, for as long
185191
// as this upstream exchange exists (until cleanup);
186192
private computedKeepAlive = {

0 commit comments

Comments
 (0)