donsetch 5.0.0-beta.3 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/install.js +27 -4
- package/package.json +1 -1
- package/pi-extension.ts +8 -10
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**The web, for AI agents.** Fetch, search, crawl and screenshot from one local binary. Zero API keys, zero accounts.
|
|
4
4
|
|
|
5
|
-
**v5
|
|
5
|
+
**v5:** a new fetch engine. No browser in the fetch path: a wall is answered by the right client identity, the site's own challenge program run in-process, or the site's own public interface.
|
|
6
6
|
|
|
7
7
|
[](https://github.com/dondai44423/donsetch/releases)
|
|
8
8
|
[](https://github.com/dondai44423/donsetch/actions/workflows/ci.yml)
|
package/install.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const http = require('http');
|
|
8
8
|
const https = require('https');
|
|
9
|
+
const net = require('net');
|
|
9
10
|
const tls = require('tls');
|
|
10
11
|
const crypto = require('crypto');
|
|
11
12
|
const fs = require('fs');
|
|
@@ -159,15 +160,30 @@ function requestDirect(target) {
|
|
|
159
160
|
});
|
|
160
161
|
}
|
|
161
162
|
|
|
163
|
+
// Basic credentials from the proxy URL's user:pass@ part, or null when
|
|
164
|
+
// it has none. The URL parser keeps them percent-encoded.
|
|
165
|
+
function proxyAuthorization(proxy) {
|
|
166
|
+
if (!proxy.username && !proxy.password) return null;
|
|
167
|
+
const decode = (part) => {
|
|
168
|
+
try { return decodeURIComponent(part); } catch (_) { return part; }
|
|
169
|
+
};
|
|
170
|
+
const pair = `${decode(proxy.username)}:${decode(proxy.password)}`;
|
|
171
|
+
return `Basic ${Buffer.from(pair).toString('base64')}`;
|
|
172
|
+
}
|
|
173
|
+
|
|
162
174
|
function requestThroughProxy(target, proxy) {
|
|
163
175
|
return new Promise((resolve, reject) => {
|
|
176
|
+
const authority = `${target.hostname}:${target.port || 443}`;
|
|
177
|
+
const connectHeaders = { Host: authority };
|
|
178
|
+
const authorization = proxyAuthorization(proxy);
|
|
179
|
+
if (authorization) connectHeaders['Proxy-Authorization'] = authorization;
|
|
164
180
|
const connectTransport = proxy.protocol === 'https:' ? https : http;
|
|
165
181
|
const proxyReq = connectTransport.request({
|
|
166
182
|
hostname: proxy.hostname,
|
|
167
183
|
port: proxy.port || (proxy.protocol === 'https:' ? 443 : 80),
|
|
168
184
|
method: 'CONNECT',
|
|
169
|
-
path:
|
|
170
|
-
headers:
|
|
185
|
+
path: authority,
|
|
186
|
+
headers: connectHeaders,
|
|
171
187
|
});
|
|
172
188
|
proxyReq.once('connect', (response, socket) => {
|
|
173
189
|
if (response.statusCode !== 200) {
|
|
@@ -184,10 +200,17 @@ function requestThroughProxy(target, proxy) {
|
|
|
184
200
|
Accept: 'application/octet-stream',
|
|
185
201
|
'User-Agent': 'donsetch-npm-installer',
|
|
186
202
|
},
|
|
187
|
-
agent:
|
|
203
|
+
// No `agent` key: Node uses createConnection only when no agent
|
|
204
|
+
// is in use, and `agent: false` means a fresh default Agent,
|
|
205
|
+
// which dials the host directly and leaves the tunnel unused.
|
|
206
|
+
// Without an agent the request also closes its connection, and
|
|
207
|
+
// with it the tunnel, once the response ends.
|
|
208
|
+
// The certificate is verified (tls.connect's default) against
|
|
209
|
+
// the release host; SNI takes host names only (RFC 6066 3).
|
|
188
210
|
createConnection: () => tls.connect({
|
|
189
211
|
socket,
|
|
190
|
-
|
|
212
|
+
host: target.hostname,
|
|
213
|
+
servername: net.isIP(target.hostname) ? undefined : target.hostname,
|
|
191
214
|
}),
|
|
192
215
|
}, resolve);
|
|
193
216
|
req.setTimeout(REQUEST_TIMEOUT_MS, () => req.destroy(new Error('request timeout')));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "donsetch",
|
|
3
|
-
"version": "5.0.0
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "MCP server that gives AI agents the web: fetch, search, crawl and screenshot from one local Rust binary. Zero API keys, zero accounts, Chrome-true TLS.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"author": "Bishesh Bhandari",
|
package/pi-extension.ts
CHANGED
|
@@ -199,8 +199,8 @@ function startServer(): Promise<void> {
|
|
|
199
199
|
}
|
|
200
200
|
});
|
|
201
201
|
|
|
202
|
-
// The daemon writes diagnostics to stderr (
|
|
203
|
-
//
|
|
202
|
+
// The daemon writes diagnostics to stderr (config warnings,
|
|
203
|
+
// rerank and OCR notices). Pi's TUI surfaces stderr
|
|
204
204
|
// as user-facing output: raw forwarding used to pop non-fatal
|
|
205
205
|
// warnings up (issue #95). Gate it:
|
|
206
206
|
// - DONSETCH_DEBUG / DEBUG set: forward everything (dev mode)
|
|
@@ -449,14 +449,12 @@ function getSearchProvider(sc: any, dbg: any): string {
|
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
/**
|
|
452
|
-
* Extract the fetch source label from
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
* fresh fetch), "ghost" when tier starts with "2" (browser
|
|
459
|
-
* escalation), or "" for a normal tier-1 fetch.
|
|
452
|
+
* Extract the fetch source label from the `tier` field that servers
|
|
453
|
+
* before 5.0 report, in _meta["com.donsetch/fetch-debug"] or on
|
|
454
|
+
* structuredContent. Returns "cache" when tier is "1(warm)" (warm
|
|
455
|
+
* cookies, not a fresh fetch), "ghost" when tier starts with "2"
|
|
456
|
+
* (their browser tier), or "" otherwise. A 5.x server sends no
|
|
457
|
+
* tier and has no browser tier, so the result is always "".
|
|
460
458
|
*/
|
|
461
459
|
function getFetchSource(sc: any, dbg: any): string {
|
|
462
460
|
const tier = String(
|