Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@expressen/tallahassee

Package Overview
Dependencies
Maintainers
12
Versions
207
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@expressen/tallahassee - npm Package Compare versions

Comparing version 11.17.0 to 11.18.0

lib/WebPage.js

4

CHANGELOG.md
Changelog
=========
## 11.18.0
- Expose `lib/WebPage` to facilitate request override
## 11.17.0

@@ -5,0 +9,0 @@

174

index.js
"use strict";
const assert = require("assert");
const NodeFetch = require("node-fetch");
const url = require("url");
const BrowserTab = require("./lib/BrowserTab");
const Origin = require("./lib/Origin");
const {version} = require("./package.json");
const {CookieAccessInfo, CookieJar, Cookie} = require("cookiejar");
const {normalizeHeaders, getLocationHost} = require("./lib/getHeaders");
const {CookieJar, Cookie} = require("cookiejar");
const {normalizeHeaders} = require("./lib/getHeaders");
const WebPage = require("./lib/WebPage");
module.exports = Tallahassee;
const kOrigin = Symbol.for("origin");
const kRequestHeaders = Symbol.for("request headers");
class WebPage {
constructor(origin, jar, originRequestHeaders) {
this[kOrigin] = origin;
this.jar = jar;
this.originRequestHeaders = originRequestHeaders;
this.originHost = getLocationHost(originRequestHeaders);
this.userAgent = `Tallahassee/${version}`;
this.protocol = `${originRequestHeaders["x-forwarded-proto"] || "http"}:`;
this.referrer = originRequestHeaders.referer;
}
async navigateTo(uri, headers, statusCode = 200) {
const requestHeaders = normalizeHeaders(headers);
if (requestHeaders["user-agent"]) this.userAgent = requestHeaders["user-agent"];
module.exports = Tallahassee;
if (requestHeaders.cookie) {
const publicHost = getLocationHost(requestHeaders);
const parsedUri = url.parse(uri);
const cookieDomain = parsedUri.hostname || publicHost || this.originHost || "127.0.0.1";
const isSecure = (parsedUri.protocol || this.protocol) === "https:";
this.jar.setCookies(requestHeaders.cookie.split(";").map((c) => c.trim()).filter(Boolean), cookieDomain, "/", isSecure);
}
const resp = await this.fetch(uri, {
method: "GET",
headers: requestHeaders,
});
assert.equal(resp.status, statusCode, `Unexepected status code. Expected: ${statusCode}. Actual: ${resp.statusCode}`);
assert(resp.headers.get("content-type").match(/text\/html/i), `Unexepected content type. Expected: text/html. Actual: ${resp.headers["content-type"]}`);
const browser = new BrowserTab(this, resp);
return browser.load();
}
load(resp) {
const requestHeaders = this.originRequestHeaders;
if (requestHeaders["user-agent"]) this.userAgent = requestHeaders["user-agent"];
const publicHost = getLocationHost(requestHeaders);
const cookieDomain = publicHost || this.originHost || "127.0.0.1";
if (requestHeaders.cookie) {
const isSecure = this.protocol === "https:";
this.jar.setCookies(requestHeaders.cookie.split(";").map((c) => c.trim()).filter(Boolean), cookieDomain, "/", isSecure);
}
const browser = new BrowserTab(this, resp);
return browser.load();
}
async submit(uri, options) {
const res = await this.fetch(uri, options);
const response = await this.handleResponse(res, options);
const browser = new BrowserTab(this, response);
return browser.load();
}
async fetch(uri, requestOptions = {}) {
this.numRedirects = 0;
const res = await this.makeRequest(uri, requestOptions);
return this.handleResponse(res, requestOptions);
}
async handleResponse(res, requestOptions) {
const resUrl = this._getResponseURL(res);
const setCookieHeader = res.headers.raw()["set-cookie"];
const flOrigin = res.headers.get("fl-origin");
if (setCookieHeader) {
for (const cookieStr of setCookieHeader) {
const cookie = new Cookie(cookieStr);
if (!cookie.explicit_path) cookie.path = resUrl.pathname;
if (!cookie.domain) cookie.domain = resUrl.hostname;
this.jar.setCookie(cookie.toString());
}
}
if (res.status > 300 && res.status < 309 && requestOptions.redirect !== "manual") {
this.numRedirects++;
if (this.numRedirects > 20) {
throw new Error("Too many redirects");
}
let location = res.headers.get("location");
if (flOrigin) {
location = location.replace(flOrigin, "");
}
const redirectOptions = {...requestOptions};
if (res.status === 307 || res.status === 308) {
// NO-OP
} else {
redirectOptions.method = "GET";
delete redirectOptions.body;
}
const redirectedRes = await this.makeRequest(location, redirectOptions);
return this.handleResponse(redirectedRes, requestOptions);
}
if (!flOrigin) return res;
res.headers.delete("fl-origin");
const originHost = this.originHost;
if (!originHost) return res;
const originUrl = resUrl.toString();
return new Proxy(res, {
get(target, prop) {
if (prop === "url") return originUrl;
return target[prop];
}
});
}
async makeRequest(uri, requestOptions = {method: "GET", headers: {}}) {
let origin, flOrigin;
const parsedUri = url.parse(uri);
let headers = requestOptions.headers = normalizeHeaders(requestOptions.headers);
const isLocal = uri.startsWith("/") || parsedUri.hostname === this.originHost;
if (isLocal) {
origin = new Origin(this[kOrigin]);
flOrigin = await origin.init();
uri = new URL(parsedUri.path, flOrigin).toString();
headers = requestOptions.headers = {
...this.originRequestHeaders,
...headers,
};
} else {
headers.host = parsedUri.host;
}
const publicHost = getLocationHost(headers);
const cookieDomain = parsedUri.hostname || publicHost || this.originHost || "127.0.0.1";
const isSecure = (parsedUri.protocol || this.protocol) === "https:";
const accessInfo = CookieAccessInfo(cookieDomain, parsedUri.pathname, isSecure);
const cookieValue = this.jar.getCookies(accessInfo).toValueString();
if (cookieValue) headers.cookie = cookieValue;
try {
const response = await NodeFetch(uri, {...requestOptions, redirect: "manual"});
if (isLocal) {
response.headers.set("fl-origin", flOrigin);
}
response[kRequestHeaders] = headers;
response[kOrigin] = this[kOrigin];
return response;
} finally {
if (origin) origin.close();
}
}
_getResponseURL(res) {
const resUrl = new URL(res.url);
const flOrigin = res.headers.get("fl-origin");
if (!this.originHost || !flOrigin) return resUrl;
resUrl.port = "";
resUrl.host = this.originHost;
resUrl.protocol = this.protocol;
return resUrl;
}
}
function Tallahassee(...args) {

@@ -178,0 +12,0 @@ let origin, options;

{
"name": "@expressen/tallahassee",
"version": "11.17.0",
"version": "11.18.0",
"description": "Lightweight client testing framework",

@@ -39,7 +39,7 @@ "main": "index.js",

"chai": "^4.3.6",
"eslint": "^8.14.0",
"eslint": "^8.23.0",
"express": "^4.18.1",
"markdown-toc": "^1.2.0",
"mocha": "^10.0.0",
"nock": "^13.2.4"
"nock": "^13.2.9"
},

@@ -46,0 +46,0 @@ "files": [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc