<commit_before>import {Entry} from "../typing/har";
import {WaterfallData, WaterfallEntry} from "../typing/waterfall";
import {getHeader, hasHeader} from "./har";
import * as misc from "./misc";

/**
 *
 * Checks if `entry.response.status` code is `>= lowerBound` and `<= upperBound`
 * @param  {Entry} entry
 * @param  {number} lowerBound - inclusive lower bound
 * @param  {number} upperBound - inclusive upper bound
 */
export function isInStatusCodeRange(entry: Entry, lowerBound: number, upperBound: number) {
  return entry.response.status >= lowerBound && entry.response.status <= upperBound;
}

function isCompressible(entry: WaterfallEntry): boolean {
  const harEntry = entry.rawResource;
  const minCompressionSize = 1000;
  // small responses
  if (harEntry.response.bodySize < minCompressionSize) {
    return false;
  }

  if (misc.contains(["html", "css", "javascript", "svg", "plain"], entry.requestType)) {
    return true;
  }
  const mime = harEntry.response.content.mimeType;
  const compressableMimes = ["application/vnd.ms-fontobject",
    "application/x-font-opentype",
    "application/x-font-truetype",
    "application/x-font-ttf",
    "application/xml",
    "font/eot",
    "font/opentype",
    "font/otf",
    "image/vnd.microsoft.icon"];
  if (misc.contains(["text"], mime.split("/")[0]) || misc.contains(compressableMimes, mime.split(";")[0])) {
    return true;
  }
  return false;
}

function isCachable(entry: WaterfallEntry): boolean {
  const harEntry = entry.rawResource;
  const headers = harEntry.response.headers;

  // do not cache non-gets,204 and non 2xx status codes
  if (harEntry.request.method.toLocaleLowerCase() !== "get" ||
    harEntry.response.status === 204 ||
    !isInStatusCodeRange(harEntry, 200, 299)) {
    return false;
  }

  if (!(hasHeader(headers, "Cache-Control") || hasHeader(headers, "Expires"))) {
    return true;
  }
  return getHeader(headers, "Cache-Control").indexOf("no-cache") > -1
    || getHeader(headers, "Pragma") === "no-cache";
}

export function hasCacheIssue(entry: WaterfallEntry) {
  const harEntry = entry.rawResource;
  const headers = harEntry.response.headers;
  return (!hasHeader(headers, "Content-Encoding") && isCachable(entry));
}

export function hasCompressionIssue(entry: WaterfallEntry) {
  const harEntry = entry.rawResource;
  const headers = harEntry.response.headers;
  return (!hasHeader(headers, "Content-Encoding") && isCompressible(entry));
}

export function isSecure(entry: WaterfallEntry) {
  return entry.name.indexOf("https://") === 0;
}

/**
 * Check if the document (disregarding any initial http->https redirects) is loaded over a secure connection.
 * @param data the waterfall data.
 * @returns {boolean}
 */
export function documentIsSecure(data: WaterfallData) {
  const rootDocument = data.entries.filter((e) => !e.rawResource.response.redirectURL)[0];
  return isSecure(rootDocument);
}<commit_msg>Fix JSDoc comment.<commit_after>import {Entry} from "../typing/har";
import {WaterfallData, WaterfallEntry} from "../typing/waterfall";
import {getHeader, hasHeader} from "./har";
import * as misc from "./misc";

/**
 *
 * Checks if `entry.response.status` code is `>= lowerBound` and `<= upperBound`
 * @param  {Entry} entry
 * @param  {number} lowerBound - inclusive lower bound
 * @param  {number} upperBound - inclusive upper bound
 */
export function isInStatusCodeRange(entry: Entry, lowerBound: number, upperBound: number) {
  return entry.response.status >= lowerBound && entry.response.status <= upperBound;
}

function isCompressible(entry: WaterfallEntry): boolean {
  const harEntry = entry.rawResource;
  const minCompressionSize = 1000;
  // small responses
  if (harEntry.response.bodySize < minCompressionSize) {
    return false;
  }

  if (misc.contains(["html", "css", "javascript", "svg", "plain"], entry.requestType)) {
    return true;
  }
  const mime = harEntry.response.content.mimeType;
  const compressableMimes = ["application/vnd.ms-fontobject",
    "application/x-font-opentype",
    "application/x-font-truetype",
    "application/x-font-ttf",
    "application/xml",
    "font/eot",
    "font/opentype",
    "font/otf",
    "image/vnd.microsoft.icon"];
  if (misc.contains(["text"], mime.split("/")[0]) || misc.contains(compressableMimes, mime.split(";")[0])) {
    return true;
  }
  return false;
}

function isCachable(entry: WaterfallEntry): boolean {
  const harEntry = entry.rawResource;
  const headers = harEntry.response.headers;

  // do not cache non-gets,204 and non 2xx status codes
  if (harEntry.request.method.toLocaleLowerCase() !== "get" ||
    harEntry.response.status === 204 ||
    !isInStatusCodeRange(harEntry, 200, 299)) {
    return false;
  }

  if (!(hasHeader(headers, "Cache-Control") || hasHeader(headers, "Expires"))) {
    return true;
  }
  return getHeader(headers, "Cache-Control").indexOf("no-cache") > -1
    || getHeader(headers, "Pragma") === "no-cache";
}

export function hasCacheIssue(entry: WaterfallEntry) {
  const harEntry = entry.rawResource;
  const headers = harEntry.response.headers;
  return (!hasHeader(headers, "Content-Encoding") && isCachable(entry));
}

export function hasCompressionIssue(entry: WaterfallEntry) {
  const harEntry = entry.rawResource;
  const headers = harEntry.response.headers;
  return (!hasHeader(headers, "Content-Encoding") && isCompressible(entry));
}

export function isSecure(entry: WaterfallEntry) {
  return entry.name.indexOf("https://") === 0;
}

/**
 * Check if the document (disregarding any initial http->https redirects) is loaded over a secure connection.
 * @param {WaterfallData} data -  the waterfall data.
 * @returns {boolean}
 */
export function documentIsSecure(data: WaterfallData) {
  const rootDocument = data.entries.filter((e) => !e.rawResource.response.redirectURL)[0];
  return isSecure(rootDocument);
}
{'fraction_non_alphanumeric': 0.1485148514851485, 'fraction_numerical': 0.0075110959371799246, 'mean_word_length': 4.527358490566038, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2986067', 'n_tokens_mistral': 1874, 'n_tokens_neox': 1810, 'n_words': 431}