summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/filter-predicates.js
blob: 75ee422aad60885167f2f63c55f7ef124dff1d18 (plain)
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
"use strict";

/**
 * Predicates used when filtering items.
 *
 * @param object item
 *        The filtered item.
 * @return boolean
 *         True if the item should be visible, false otherwise.
 */
function all() {
  return true;
}

function isHtml({ mimeType }) {
  return mimeType && mimeType.includes("/html");
}

function isCss({ mimeType }) {
  return mimeType && mimeType.includes("/css");
}

function isJs({ mimeType }) {
  return mimeType && (
    mimeType.includes("/ecmascript") ||
    mimeType.includes("/javascript") ||
    mimeType.includes("/x-javascript"));
}

function isXHR(item) {
  // Show the request it is XHR, except if the request is a WS upgrade
  return item.isXHR && !isWS(item);
}

function isFont({ url, mimeType }) {
  // Fonts are a mess.
  return (mimeType && (
      mimeType.includes("font/") ||
      mimeType.includes("/font"))) ||
    url.includes(".eot") ||
    url.includes(".ttf") ||
    url.includes(".otf") ||
    url.includes(".woff");
}

function isImage({ mimeType }) {
  return mimeType && mimeType.includes("image/");
}

function isMedia({ mimeType }) {
  // Not including images.
  return mimeType && (
    mimeType.includes("audio/") ||
    mimeType.includes("video/") ||
    mimeType.includes("model/"));
}

function isFlash({ url, mimeType }) {
  // Flash is a mess.
  return (mimeType && (
      mimeType.includes("/x-flv") ||
      mimeType.includes("/x-shockwave-flash"))) ||
    url.includes(".swf") ||
    url.includes(".flv");
}

function isWS({ requestHeaders, responseHeaders }) {
  // Detect a websocket upgrade if request has an Upgrade header with value 'websocket'
  if (!requestHeaders || !Array.isArray(requestHeaders.headers)) {
    return false;
  }

  // Find the 'upgrade' header.
  let upgradeHeader = requestHeaders.headers.find(header => {
    return (header.name.toLowerCase() == "upgrade");
  });

  // If no header found on request, check response - mainly to get
  // something we can unit test, as it is impossible to set
  // the Upgrade header on outgoing XHR as per the spec.
  if (!upgradeHeader && responseHeaders &&
      Array.isArray(responseHeaders.headers)) {
    upgradeHeader = responseHeaders.headers.find(header => {
      return (header.name.toLowerCase() == "upgrade");
    });
  }

  // Return false if there is no such header or if its value isn't 'websocket'.
  if (!upgradeHeader || upgradeHeader.value != "websocket") {
    return false;
  }

  return true;
}

function isOther(item) {
  let tests = [isHtml, isCss, isJs, isXHR, isFont, isImage, isMedia, isFlash, isWS];
  return tests.every(is => !is(item));
}

function isFreetextMatch({ url }, text) {
  let lowerCaseUrl = url.toLowerCase();
  let lowerCaseText = text.toLowerCase();
  let textLength = text.length;
  // Support negative filtering
  if (text.startsWith("-") && textLength > 1) {
    lowerCaseText = lowerCaseText.substring(1, textLength);
    return !lowerCaseUrl.includes(lowerCaseText);
  }

  // no text is a positive match
  return !text || lowerCaseUrl.includes(lowerCaseText);
}

exports.Filters = {
  all: all,
  html: isHtml,
  css: isCss,
  js: isJs,
  xhr: isXHR,
  fonts: isFont,
  images: isImage,
  media: isMedia,
  flash: isFlash,
  ws: isWS,
  other: isOther,
};

exports.isFreetextMatch = isFreetextMatch;