@samitouri / QOSami-HFS / commits / 3449415b

http requests will by default include user-agent

Massimo Melina committed Apr 27, 2026 at 19:39 UTC 3449415b03965b67b69c630da8620e751a61780b
2 files changed +8 -2
src/index.ts
+2 -1
@@ -19,7 +19,7 @@ import { adminApis } from './adminApis'
19 import { defineConfig, Version } from './config'
20 import { ok } from 'assert'
21 import _ from 'lodash'
22 -import { randomId } from './misc'
22 +import { httpStream, randomId } from './misc'
23 import { selfCheckMiddleware } from './selfCheck'
24 import { acmeMiddleware } from './acme'
25 import './geo'
@@ -37,6 +37,7 @@ if (new Version(process.versions.node).olderThan('18.15.0')) {
37 }
38
39 process.title = 'HFS ' + VERSION
40 +httpStream.defaultUA = 'HFS'
41 const keys = process.env.COOKIE_SIGN_KEYS?.split(',')
42 || [randomId(30)] // randomness at start gives some extra security, btu also invalidates existing sessions
43 export const app = new Koa({ keys })
src/util-http.ts
+6 -1
@@ -32,13 +32,18 @@ export interface XRequestOptions extends https.RequestOptions {
32 httpThrow?: boolean
33 }
34
35 -export declare namespace httpStream { let defaultProxy: string | undefined }
35 +export declare namespace httpStream {
36 + let defaultProxy: string | undefined
37 + let defaultUA: string | undefined
38 +}
39 export function httpStream(url: string, { body, proxy, jar, noRedirect, httpThrow=true, ...options }: XRequestOptions ={}, redirected: string[]=[]) {
40 const controller = new AbortController()
41 options.signal ??= controller.signal
42 return Object.assign(new Promise<IncomingMessage>(async (resolve, reject) => {
43 proxy ??= httpStream.defaultProxy
44 options.headers ??= {}
45 + if (httpStream.defaultUA && !Object.keys(options.headers).find(k => k.toLowerCase() === 'user-agent'))
46 + options.headers['user-agent'] = httpStream.defaultUA
47 if (body) {
48 options.method ||= 'POST'
49 if (_.isPlainObject(body)) {