UNPKG

@bmqube/xmlrpc

Version:

A pure TypeScript XML-RPC client and server. Forked from (https://github.com/baalexander/node-xmlrpc)

109 lines (108 loc) 3.57 kB
export default class Cookies { constructor() { this.cookies = {}; } /** * Obtains value of the cookie with specified name. * Checks expiration and returns null for expired/nonexistent cookies. */ get(name) { const cookie = this.cookies[name]; if (cookie && this.checkNotExpired(name)) { return this.cookies[name].value; } return null; } /** * Sets a cookie's value with optional attributes. */ set(name, value, options) { const cookie = typeof options === "object" ? { value, expires: options.expires, secure: options.secure ?? false, new: options.new ?? false, } : { value }; if (this.checkNotExpired(name, cookie)) { this.cookies[name] = cookie; } } /** For testing / inspection */ getExpirationDate(name) { return this.cookies[name] ? this.cookies[name].expires ?? null : null; } /** * Internal helper: true if cookie is not expired. Deletes expired entries. */ checkNotExpired(name, cookie) { const c = cookie ?? this.cookies[name]; if (!c) return false; const now = new Date(); if (c.expires && now > c.expires) { delete this.cookies[name]; return false; } return true; } /** * Parses response headers, collecting Set-Cookie values. * Only the Expires attribute is honored (parity with original). */ parseResponse(headers) { const setCookie = headers["set-cookie"]; if (!setCookie) return; const list = Array.isArray(setCookie) ? setCookie : [setCookie]; list.forEach((c) => { if (!c) return; const parts = c.split(";"); const nameValue = parts.shift(); if (!nameValue) return; const eqIdx = nameValue.indexOf("="); const name = eqIdx >= 0 ? nameValue.slice(0, eqIdx).trim() : nameValue.trim(); const value = eqIdx >= 0 ? nameValue.slice(eqIdx + 1).trim() : ""; const options = {}; parts.forEach((param) => { const p = param.trim(); if (p.toLowerCase().startsWith("expires")) { const eq = p.indexOf("="); if (eq >= 0) { const dateStr = p.slice(eq + 1).trim(); const d = new Date(dateStr); if (!Number.isNaN(d.getTime())) { options.expires = d; } } } }); this.set(name, value, options); }); } /** * Adds cookies to outgoing request headers (as a single "Cookie" header). * Skips if there are no (non-expired) cookies. */ composeRequest(headers) { const asString = this.toString(); if (!asString) return; headers["Cookie"] = asString; } /** * Returns cookies formatted as "name=value" pairs joined by semicolons. * Filters out expired cookies on the fly. */ toString() { const names = Object.keys(this.cookies).filter((n) => this.checkNotExpired(n)); if (names.length === 0) return ""; return names .map((name) => `${name}=${this.cookies[name].value}`) .join(";"); } }