1
0
mirror of https://git.sr.ht/~cadence/bibliogram synced 2025-12-18 03:58:49 +00:00

Allow got as request backend

This commit is contained in:
Cadence Fish
2020-03-15 19:50:29 +13:00
parent a861df2662
commit 3efc4928a5
10 changed files with 439 additions and 51 deletions

View File

@@ -1,16 +1,39 @@
const fetch = require("node-fetch").default
const NodeFetch = require("./requestbackends/node-fetch")
const Got = require("./requestbackends/got")
const constants = require("../constants")
const userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
const backendStatusLineMap = new Map([
["node-fetch", "NF "],
["got", "GOT"]
])
/**
* @returns {import("./requestbackends/reference")}
*/
function request(url, options = {}, settings = {}) {
if (settings.statusLine === undefined) settings.statusLine = "OUT"
if (settings.log === undefined) settings.log = true
if (settings.log) console.log(` -> [${settings.statusLine}] ${url}`) // todo: make more like pinski?
// @ts-ignore
return fetch(url, Object.assign({
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
},
redirect: "manual"
}, options))
if (settings.log) console.log(` -> [${settings.statusLine}-${backendStatusLineMap.get(constants.request_backend)}] ${url}`) // todo: make more like pinski?
if (constants.request_backend === "node-fetch") {
return new NodeFetch(url, Object.assign({
headers: {
"User-Agent": userAgent
},
redirect: "manual"
}, options))
} else if (constants.request_backend === "got") {
return new Got(url, Object.assign({
headers: {
"User-Agent": userAgent
},
followRedirect: false
}, options))
} else {
throw new Error("Invalid value for setting `request_backend`.")
}
}
module.exports.request = request

View File

@@ -0,0 +1,46 @@
try {
var got = require("got").default
} catch (e) {}
class Got {
constructor(url, options, stream) {
if (!got) throw new Error("`got` is not installed, either install it or set a different request backend.")
this.url = url
this.options = options
}
stream() {
return Promise.resolve(got.stream(this.url, this.options))
}
send() {
if (!this.instance) {
this.instance = got(this.url, this.options)
}
return this
}
/**
* @returns {Promise<import("./reference").GrabResponse>}
*/
response() {
return this.send().instance.then(res => ({
status: res.statusCode
}))
}
async check(test) {
await this.send().response().then(res => test(res))
return this
}
json() {
return this.send().instance.json()
}
text() {
return this.send().instance.text()
}
}
module.exports = Got

View File

@@ -0,0 +1,30 @@
const fetch = require("node-fetch").default
class NodeFetch {
constructor(url, options) {
this.instance = fetch(url, options)
}
stream() {
return this.instance.then(res => res.body)
}
response() {
return this.instance
}
json() {
return this.instance.then(res => res.json())
}
text() {
return this.instance.then(res => res.text())
}
async check(test) {
await this.response().then(res => test(res))
return this
}
}
module.exports = NodeFetch

View File

@@ -0,0 +1,45 @@
/**
* @typedef GrabResponse
* @property {number} status
*/
// @ts-nocheck
class GrabReference {
/**
* @param {string} url
* @param {any} options
*/
constructor(url, options) {
throw new Error("This is the reference class, do not instantiate it.")
}
// Please help me type this
/**
* @returns {Promise<any>}
*/
stream() {}
/**
* @returns {Promise<GrabResponse>}
*/
response() {}
/**
* @returns {Promise<any>}
*/
json() {}
/**
* @returns {Promise<string>}
*/
text() {}
/**
* @param {(res: GrabResponse) => any}
* @returns {Promise<Reference>}
*/
check(test) {}
}
module.exports = GrabReference

View File

@@ -21,15 +21,14 @@ class TorSwitcher {
* If the test function fails, its error will be rejected here.
* Only include rate limit logic in the test function!
* @param {string} url
* @param {(res: import("node-fetch").Response) => Promise<T>} test
* @returns {Promise<T>}
* @template T the return value of the test function
* @param {(res: import("./requestbackends/reference").GrabResponse) => any} test
* @returns {Promise<import("./requestbackends/reference")>}
*/
request(type, url, test) {
if (this.torManager && constants.tor.for[type]) {
return this.torManager.request(url, test)
} else {
return request(url).then(res => test(res))
return request(url).check(test)
}
}
}