@j0hanz/superfetch 1.1.0 → 1.1.1

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 CHANGED
@@ -148,6 +148,34 @@ See [Configuration](#configuration) section below for all available options and
148
148
 
149
149
  > **Tip:** On Windows, if you encounter issues, try: `cmd /c "npx -y @j0hanz/superfetch@latest --stdio"`
150
150
 
151
+ <details>
152
+ <summary><strong>Codex IDE</strong></summary>
153
+
154
+ Add to your `~/.codex/config.toml` file:
155
+
156
+ **Basic Configuration:**
157
+
158
+ ```toml
159
+ [mcp_servers.superfetch]
160
+ command = "npx"
161
+ args = ["-y", "@j0hanz/superfetch@latest", "--stdio"]
162
+ ```
163
+
164
+ **With Environment Variables:**
165
+
166
+ ```toml
167
+ [mcp_servers.superfetch]
168
+ command = "npx"
169
+ args = ["-y", "@j0hanz/superfetch@latest", "--stdio"]
170
+ env = { CACHE_TTL = "7200", LOG_LEVEL = "debug", FETCH_TIMEOUT = "60000" }
171
+ ```
172
+
173
+ > **Access config file:** Click the gear icon → "Codex Settings &gt; Open config.toml"
174
+ >
175
+ > **Documentation:** [Codex MCP Guide](https://codex.com/docs/mcp)
176
+
177
+ </details>
178
+
151
179
  <details>
152
180
  <summary><strong>Cline (VS Code Extension)</strong></summary>
153
181
 
@@ -31,5 +31,10 @@ export declare const config: {
31
31
  readonly maxContentSize: number;
32
32
  readonly maxUrlLength: 2048;
33
33
  };
34
+ readonly security: {
35
+ readonly blockedHosts: Set<string>;
36
+ readonly blockedIpPatterns: readonly RegExp[];
37
+ readonly blockedHeaders: Set<string>;
38
+ };
34
39
  };
35
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCT,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCA0DV,SAAS,MAAM,EAAE;;;CAUhB,CAAC"}
@@ -58,5 +58,40 @@ export const config = {
58
58
  maxContentSize: 5 * 1024 * 1024,
59
59
  maxUrlLength: 2048,
60
60
  },
61
+ security: {
62
+ blockedHosts: new Set([
63
+ 'localhost',
64
+ '127.0.0.1',
65
+ '0.0.0.0',
66
+ '::1',
67
+ '169.254.169.254',
68
+ 'metadata.google.internal',
69
+ 'metadata.azure.com',
70
+ '100.100.100.200',
71
+ 'instance-data',
72
+ ]),
73
+ blockedIpPatterns: [
74
+ /^10\./,
75
+ /^172\.(1[6-9]|2\d|3[01])\./,
76
+ /^192\.168\./,
77
+ /^127\./,
78
+ /^0\./,
79
+ /^169\.254\./,
80
+ /^fc00:/i,
81
+ /^fe80:/i,
82
+ /^::ffff:127\./,
83
+ /^::ffff:10\./,
84
+ /^::ffff:172\.(1[6-9]|2\d|3[01])\./,
85
+ /^::ffff:192\.168\./,
86
+ ],
87
+ blockedHeaders: new Set([
88
+ 'host',
89
+ 'authorization',
90
+ 'cookie',
91
+ 'x-forwarded-for',
92
+ 'x-real-ip',
93
+ 'proxy-authorization',
94
+ ]),
95
+ },
61
96
  };
62
97
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,SAAS,YAAY,CACnB,QAA4B,EAC5B,YAAoB,EACpB,GAAY,EACZ,GAAY;IAEZ,IAAI,CAAC,QAAQ;QAAE,OAAO,YAAY,CAAC;IACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IACvC,IAAI,GAAG,KAAK,SAAS,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,YAAY,CAAC;IAC3D,IAAI,GAAG,KAAK,SAAS,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,YAAY,CAAC;IAC3D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CACnB,QAA4B,EAC5B,YAAqB;IAErB,IAAI,CAAC,QAAQ;QAAE,OAAO,YAAY,CAAC;IACnC,OAAO,QAAQ,KAAK,OAAO,CAAC;AAC9B,CAAC;AAED,SAAS,aAAa,CACpB,QAA4B;IAE5B,MAAM,KAAK,GAAG,QAAQ,EAAE,WAAW,EAAE,CAAC;IACtC,IACE,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,OAAO,EACjB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;QACvD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,WAAW;KACtC;IACD,OAAO,EAAE;QACP,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC;QACrE,YAAY,EAAE,CAAC;QACf,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,oBAAoB;QACzD,gBAAgB,EAAE,QAAQ;KAC3B;IACD,KAAK,EAAE;QACL,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC;QACtD,GAAG,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC;QACzD,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC;KACjE;IACD,UAAU,EAAE;QACV,kBAAkB,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC;QACxE,eAAe,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC;QACjE,cAAc,EAAE,IAAI;QACpB,kBAAkB,EAAE,EAAE;KACvB;IACD,OAAO,EAAE;QACP,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QAC3C,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC;KACxD;IACD,SAAS,EAAE;QACT,WAAW,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;QAC7B,cAAc,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;QAC/B,YAAY,EAAE,IAAI;KACnB;CACO,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/services/fetcher.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAgEvD,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAwND,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,YAAY,EACtB,UAAU,SAAI,GACb,OAAO,CAAC,MAAM,CAAC,CA4CjB"}
1
+ {"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/services/fetcher.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA2UvD,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,YAAY,EACtB,UAAU,SAAI,GACb,OAAO,CAAC,MAAM,CAAC,CAsCjB"}
@@ -1,99 +1,85 @@
1
1
  import axios, { isCancel, } from 'axios';
2
2
  import crypto from 'crypto';
3
+ import dns from 'dns';
3
4
  import http from 'http';
4
5
  import https from 'https';
5
6
  import os from 'os';
6
7
  import { config } from '../config/index.js';
7
8
  import { FetchError } from '../errors/app-error.js';
8
- import { validateResolvedIps } from '../utils/url-validator.js';
9
+ import { isBlockedIp } from '../utils/url-validator.js';
9
10
  import { logDebug, logError, logWarn } from './logger.js';
11
+ // --- Constants & Types ---
10
12
  const REQUEST_START_TIME = Symbol('requestStartTime');
11
13
  const REQUEST_ID = Symbol('requestId');
12
- const BLOCKED_HEADERS = new Set([
13
- 'host',
14
- 'authorization',
15
- 'cookie',
16
- 'x-forwarded-for',
17
- 'x-real-ip',
18
- 'proxy-authorization',
19
- ]);
14
+ // --- Helper Functions ---
20
15
  function sanitizeHeaders(headers) {
21
- if (!headers || Object.keys(headers).length === 0)
16
+ if (!headers || Object.keys(headers).length === 0) {
22
17
  return undefined;
18
+ }
19
+ const { blockedHeaders } = config.security;
20
+ const crlfRegex = /[\r\n]/;
23
21
  const sanitized = {};
24
22
  for (const [key, value] of Object.entries(headers)) {
25
- if (!BLOCKED_HEADERS.has(key.toLowerCase())) {
26
- // Prevent HTTP header injection via CRLF
27
- if (/[\r\n]/.test(key) || /[\r\n]/.test(value)) {
28
- continue;
29
- }
23
+ if (!blockedHeaders.has(key.toLowerCase()) &&
24
+ !crlfRegex.test(key) &&
25
+ !crlfRegex.test(value)) {
30
26
  sanitized[key] = value;
31
27
  }
32
28
  }
33
29
  return Object.keys(sanitized).length > 0 ? sanitized : undefined;
34
30
  }
35
- const CPU_COUNT = os.cpus().length;
36
- const MAX_SOCKETS = Math.max(CPU_COUNT * 2, 25);
37
- const MAX_FREE_SOCKETS = Math.max(Math.floor(CPU_COUNT * 0.5), 10);
38
- const httpAgent = new http.Agent({
39
- keepAlive: true,
40
- maxSockets: MAX_SOCKETS,
41
- maxFreeSockets: MAX_FREE_SOCKETS,
42
- timeout: 60000,
43
- scheduling: 'fifo',
44
- });
45
- const httpsAgent = new https.Agent({
46
- keepAlive: true,
47
- maxSockets: MAX_SOCKETS,
48
- maxFreeSockets: MAX_FREE_SOCKETS,
49
- timeout: 60000,
50
- scheduling: 'fifo',
51
- });
52
- export function destroyAgents() {
53
- httpAgent.destroy();
54
- httpsAgent.destroy();
31
+ function resolveDns(hostname, options, callback) {
32
+ dns.lookup(hostname, options, (err, address, family) => {
33
+ if (err) {
34
+ callback(err, address, family);
35
+ return;
36
+ }
37
+ const addresses = Array.isArray(address) ? address : [{ address, family }];
38
+ for (const addr of addresses) {
39
+ const ip = typeof addr === 'string' ? addr : addr.address;
40
+ if (isBlockedIp(ip)) {
41
+ const error = new Error(`Blocked IP detected for ${hostname}`);
42
+ error.code = 'EBLOCKED';
43
+ callback(error, address, family);
44
+ return;
45
+ }
46
+ }
47
+ callback(null, address, family);
48
+ });
55
49
  }
56
- const client = axios.create({
57
- timeout: config.fetcher.timeout,
58
- maxRedirects: config.fetcher.maxRedirects,
59
- maxContentLength: config.fetcher.maxContentLength,
60
- httpAgent,
61
- httpsAgent,
62
- headers: {
63
- 'User-Agent': config.fetcher.userAgent,
64
- Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
65
- 'Accept-Language': 'en-US,en;q=0.5',
66
- 'Accept-Encoding': 'gzip, deflate, br',
67
- Connection: 'keep-alive',
68
- },
69
- validateStatus: (status) => status >= 200 && status < 300,
70
- });
71
- client.interceptors.request.use((requestConfig) => {
72
- const timedConfig = requestConfig;
50
+ function getAgentOptions() {
51
+ const cpuCount = os.cpus().length;
52
+ return {
53
+ keepAlive: true,
54
+ maxSockets: Math.max(cpuCount * 2, 25),
55
+ maxFreeSockets: Math.max(Math.floor(cpuCount * 0.5), 10),
56
+ timeout: 60000,
57
+ scheduling: 'fifo',
58
+ lookup: resolveDns,
59
+ };
60
+ }
61
+ function handleRequest(config) {
62
+ const timedConfig = config;
73
63
  timedConfig[REQUEST_START_TIME] = Date.now();
74
64
  timedConfig[REQUEST_ID] = crypto.randomUUID().substring(0, 8);
75
65
  logDebug('HTTP Request', {
76
66
  requestId: timedConfig[REQUEST_ID],
77
- method: requestConfig.method?.toUpperCase(),
78
- url: requestConfig.url,
67
+ method: config.method?.toUpperCase(),
68
+ url: config.url,
79
69
  });
80
- return requestConfig;
81
- }, (error) => {
70
+ return config;
71
+ }
72
+ function handleRequestError(error) {
82
73
  logError('HTTP Request Error', error);
83
74
  throw error;
84
- });
85
- client.interceptors.response.use((response) => {
86
- const timedConfig = response.config;
87
- const startTime = timedConfig[REQUEST_START_TIME];
88
- const requestId = timedConfig[REQUEST_ID];
89
- const duration = startTime ? Date.now() - startTime : 0;
90
- if (timedConfig[REQUEST_START_TIME] !== undefined) {
91
- timedConfig[REQUEST_START_TIME] = undefined;
92
- }
93
- if (timedConfig[REQUEST_ID] !== undefined) {
94
- timedConfig[REQUEST_ID] = undefined;
95
- }
96
- const contentType = response.headers['content-type'];
75
+ }
76
+ function calculateDuration(config) {
77
+ const startTime = config[REQUEST_START_TIME];
78
+ return startTime ? Date.now() - startTime : 0;
79
+ }
80
+ function logResponse(response, requestId, duration) {
81
+ const headers = response.headers;
82
+ const contentType = headers['content-type'];
97
83
  const contentTypeStr = typeof contentType === 'string' ? contentType : undefined;
98
84
  logDebug('HTTP Response', {
99
85
  requestId,
@@ -101,7 +87,7 @@ client.interceptors.response.use((response) => {
101
87
  url: response.config.url ?? 'unknown',
102
88
  contentType: contentTypeStr,
103
89
  duration: `${duration}ms`,
104
- size: response.headers['content-length'],
90
+ size: headers['content-length'],
105
91
  });
106
92
  if (duration > 5000) {
107
93
  logWarn('Slow HTTP request detected', {
@@ -110,8 +96,14 @@ client.interceptors.response.use((response) => {
110
96
  duration: `${duration}ms`,
111
97
  });
112
98
  }
113
- return response;
114
- }, (error) => {
99
+ }
100
+ function parseRetryAfter(header) {
101
+ if (!header)
102
+ return 60;
103
+ const parsed = typeof header === 'string' ? parseInt(header, 10) : Number(header);
104
+ return isNaN(parsed) ? 60 : parsed;
105
+ }
106
+ function handleResponseError(error) {
115
107
  const url = error.config?.url ?? 'unknown';
116
108
  if (isCancel(error) ||
117
109
  error.name === 'AbortError' ||
@@ -127,22 +119,11 @@ client.interceptors.response.use((response) => {
127
119
  }
128
120
  if (error.response) {
129
121
  const { status, statusText, headers } = error.response;
122
+ const responseHeaders = headers;
130
123
  if (status === 429) {
131
- const retryAfterHeader = headers['retry-after'];
132
- let retryAfterSeconds = 60;
133
- if (retryAfterHeader) {
134
- const parsed = parseInt(retryAfterHeader, 10);
135
- if (!isNaN(parsed)) {
136
- retryAfterSeconds = parsed;
137
- }
138
- }
139
- logWarn('Rate limited by server', {
140
- url,
141
- retryAfter: `${retryAfterSeconds}s`,
142
- });
143
- throw new FetchError('Too many requests', url, 429, {
144
- retryAfter: retryAfterSeconds,
145
- });
124
+ const retryAfter = parseRetryAfter(responseHeaders['retry-after']);
125
+ logWarn('Rate limited by server', { url, retryAfter: `${retryAfter}s` });
126
+ throw new FetchError('Too many requests', url, 429, { retryAfter });
146
127
  }
147
128
  logError('HTTP Error Response', { url, status, statusText });
148
129
  throw new FetchError(`HTTP ${status}: ${statusText}`, url, status);
@@ -153,106 +134,140 @@ client.interceptors.response.use((response) => {
153
134
  }
154
135
  logError('HTTP Unknown Error', { url, message: error.message });
155
136
  throw new FetchError(error.message, url);
156
- });
157
- async function fetchUrl(url, options) {
158
- try {
159
- const urlObj = new URL(url);
160
- await validateResolvedIps(urlObj.hostname);
137
+ }
138
+ function handleResponse(response) {
139
+ const timedConfig = response.config;
140
+ const duration = calculateDuration(timedConfig);
141
+ const requestId = timedConfig[REQUEST_ID];
142
+ // Cleanup symbols safely
143
+ timedConfig[REQUEST_START_TIME] = undefined;
144
+ timedConfig[REQUEST_ID] = undefined;
145
+ logResponse(response, requestId, duration);
146
+ return response;
147
+ }
148
+ class RetryPolicy {
149
+ maxRetries;
150
+ url;
151
+ static BASE_DELAY_MS = 1000;
152
+ static MAX_DELAY_MS = 10000;
153
+ static JITTER_FACTOR = 0.25;
154
+ constructor(maxRetries, url) {
155
+ this.maxRetries = maxRetries;
156
+ this.url = url;
161
157
  }
162
- catch (error) {
163
- if (error instanceof Error) {
164
- throw new FetchError(error.message, url);
158
+ async execute(operation, signal) {
159
+ let lastError = new Error(`Failed to fetch ${this.url}`);
160
+ const retries = Math.min(Math.max(1, this.maxRetries), 10);
161
+ for (let attempt = 1; attempt <= retries; attempt++) {
162
+ if (signal?.aborted) {
163
+ throw new FetchError('Request was aborted before execution', this.url);
164
+ }
165
+ try {
166
+ return await operation();
167
+ }
168
+ catch (error) {
169
+ lastError = error instanceof Error ? error : new Error(String(error));
170
+ if (!this.shouldRetry(attempt, retries, lastError)) {
171
+ throw lastError;
172
+ }
173
+ await this.wait(attempt, lastError);
174
+ }
165
175
  }
166
- throw error;
176
+ throw new FetchError(`Failed after ${retries} attempts: ${lastError.message}`, this.url);
167
177
  }
168
- const requestConfig = {
169
- method: 'GET',
170
- url,
171
- responseType: 'text',
172
- };
173
- if (options?.signal) {
174
- requestConfig.signal = options.signal;
175
- }
176
- else if (options?.timeout) {
177
- requestConfig.signal = AbortSignal.timeout(options.timeout);
178
- }
179
- const sanitized = sanitizeHeaders(options?.customHeaders);
180
- if (sanitized) {
181
- const existingHeaders = requestConfig.headers && typeof requestConfig.headers === 'object'
182
- ? requestConfig.headers
183
- : {};
184
- requestConfig.headers = { ...existingHeaders, ...sanitized };
185
- }
186
- try {
187
- const response = await client.request(requestConfig);
188
- return response.data;
189
- }
190
- catch (error) {
178
+ shouldRetry(attempt, maxRetries, error) {
179
+ if (attempt >= maxRetries)
180
+ return false;
191
181
  if (error instanceof FetchError) {
192
- throw error;
182
+ if (error.details.reason === 'aborted')
183
+ return false;
184
+ if (error.details.httpStatus === 429)
185
+ return true;
186
+ const status = error.details.httpStatus;
187
+ if (status && status >= 400 && status < 500)
188
+ return false;
193
189
  }
194
- throw new FetchError(`Unexpected error: ${error instanceof Error ? error.message : 'Unknown'}`, url);
190
+ return true;
195
191
  }
196
- }
197
- function calculateRetryDelay(attempt) {
198
- const baseDelayMs = 1000;
199
- const maxDelayMs = 10000;
200
- const jitterFactor = 0.25;
201
- const exponentialDelay = Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
202
- const jitter = exponentialDelay * jitterFactor * (Math.random() * 2 - 1);
203
- return Math.round(exponentialDelay + jitter);
204
- }
205
- function shouldRetryError(attempt, maxRetries, error) {
206
- if (attempt >= maxRetries)
207
- return false;
208
- // Don't retry aborted requests
209
- if (error instanceof FetchError && error.details.reason === 'aborted')
210
- return false;
211
- // Don't retry on client errors (4xx except 429)
212
- if (error instanceof FetchError) {
213
- const status = error.details.httpStatus;
214
- if (status && status >= 400 && status < 500 && status !== 429)
215
- return false;
192
+ async wait(attempt, error) {
193
+ let delay;
194
+ if (error instanceof FetchError && error.details.httpStatus === 429) {
195
+ const retryAfter = error.details.retryAfter || 60;
196
+ delay = Math.min(retryAfter * 1000, 30000);
197
+ logWarn('Rate limited, waiting before retry', {
198
+ url: this.url,
199
+ attempt,
200
+ waitTime: `${delay}ms`,
201
+ });
202
+ }
203
+ else {
204
+ delay = this.calculateBackoff(attempt);
205
+ logDebug('Retrying request', {
206
+ url: this.url,
207
+ attempt,
208
+ delay: `${delay}ms`,
209
+ });
210
+ }
211
+ await new Promise((resolve) => setTimeout(resolve, delay));
212
+ }
213
+ calculateBackoff(attempt) {
214
+ const exponentialDelay = Math.min(RetryPolicy.BASE_DELAY_MS * Math.pow(2, attempt - 1), RetryPolicy.MAX_DELAY_MS);
215
+ const jitter = exponentialDelay * RetryPolicy.JITTER_FACTOR * (Math.random() * 2 - 1);
216
+ return Math.round(exponentialDelay + jitter);
216
217
  }
217
- return true;
218
+ }
219
+ const httpAgent = new http.Agent(getAgentOptions());
220
+ const httpsAgent = new https.Agent(getAgentOptions());
221
+ const client = axios.create({
222
+ timeout: config.fetcher.timeout,
223
+ maxRedirects: config.fetcher.maxRedirects,
224
+ maxContentLength: config.fetcher.maxContentLength,
225
+ httpAgent,
226
+ httpsAgent,
227
+ headers: {
228
+ 'User-Agent': config.fetcher.userAgent,
229
+ Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
230
+ 'Accept-Language': 'en-US,en;q=0.5',
231
+ 'Accept-Encoding': 'gzip, deflate, br',
232
+ Connection: 'keep-alive',
233
+ },
234
+ validateStatus: (status) => status >= 200 && status < 300,
235
+ });
236
+ client.interceptors.request.use(handleRequest, handleRequestError);
237
+ client.interceptors.response.use(handleResponse, handleResponseError);
238
+ export function destroyAgents() {
239
+ httpAgent.destroy();
240
+ httpsAgent.destroy();
218
241
  }
219
242
  export async function fetchUrlWithRetry(url, options, maxRetries = 3) {
220
- const retries = Math.min(Math.max(1, maxRetries), 10);
221
- let lastError = new Error(`Failed to fetch ${url}`);
222
- for (let attempt = 1; attempt <= retries; attempt++) {
223
- if (options?.signal?.aborted) {
224
- throw new FetchError('Request was aborted before execution', url);
243
+ const policy = new RetryPolicy(maxRetries, url);
244
+ return policy.execute(async () => {
245
+ const requestConfig = {
246
+ method: 'GET',
247
+ url,
248
+ responseType: 'text',
249
+ };
250
+ if (options?.signal) {
251
+ requestConfig.signal = options.signal;
252
+ }
253
+ else if (options?.timeout) {
254
+ requestConfig.signal = AbortSignal.timeout(options.timeout);
255
+ }
256
+ const sanitizedHeaders = sanitizeHeaders(options?.customHeaders);
257
+ if (sanitizedHeaders) {
258
+ const existingHeaders = (requestConfig.headers ?? {});
259
+ requestConfig.headers = { ...existingHeaders, ...sanitizedHeaders };
225
260
  }
226
261
  try {
227
- return await fetchUrl(url, options);
262
+ const response = await client.request(requestConfig);
263
+ return response.data;
228
264
  }
229
265
  catch (error) {
230
- lastError = error instanceof Error ? error : new Error(String(error));
231
- // Handle rate limiting with smart retry (429 with Retry-After)
232
- if (error instanceof FetchError && error.details.httpStatus === 429) {
233
- const retryAfter = error.details.retryAfter;
234
- if (attempt < retries && retryAfter) {
235
- const waitTime = Math.min(retryAfter * 1000, 30000);
236
- logWarn('Rate limited, waiting before retry', {
237
- url,
238
- attempt,
239
- waitTime: `${waitTime}ms`,
240
- });
241
- await new Promise((resolve) => setTimeout(resolve, waitTime));
242
- continue;
243
- }
244
- throw error;
245
- }
246
- if (shouldRetryError(attempt, retries, lastError)) {
247
- const delay = calculateRetryDelay(attempt);
248
- logDebug('Retrying request', { url, attempt, delay: `${delay}ms` });
249
- await new Promise((resolve) => setTimeout(resolve, delay));
250
- }
251
- else {
266
+ if (error instanceof FetchError) {
252
267
  throw error;
253
268
  }
269
+ throw new FetchError(`Unexpected error: ${error instanceof Error ? error.message : 'Unknown'}`, url);
254
270
  }
255
- }
256
- throw new FetchError(`Failed after ${retries} attempts: ${lastError.message}`, url);
271
+ }, options?.signal);
257
272
  }
258
273
  //# sourceMappingURL=fetcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.js","sourceRoot":"","sources":["../../src/services/fetcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetcher.js","sourceRoot":"","sources":["../../src/services/fetcher.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,7 @@
1
- export declare function validateResolvedIps(hostname: string): Promise<void>;
1
+ /**
2
+ * Check if an IP address is in a blocked private range
3
+ */
4
+ export declare function isBlockedIp(ip: string): boolean;
2
5
  export declare function validateAndNormalizeUrl(urlString: string): string;
3
6
  export declare function isInternalUrl(url: string, baseUrl: string): boolean;
4
7
  //# sourceMappingURL=url-validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-validator.d.ts","sourceRoot":"","sources":["../../src/utils/url-validator.ts"],"names":[],"mappings":"AAsCA,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BzE;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2DjE;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAQnE"}
1
+ {"version":3,"file":"url-validator.d.ts","sourceRoot":"","sources":["../../src/utils/url-validator.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2DjE;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAQnE"}
@@ -1,59 +1,9 @@
1
- import dns from 'dns/promises';
2
1
  import { config } from '../config/index.js';
3
- const BLOCKED_HOSTS = new Set([
4
- 'localhost',
5
- '127.0.0.1',
6
- '0.0.0.0',
7
- '::1',
8
- '169.254.169.254',
9
- 'metadata.google.internal',
10
- 'metadata.azure.com',
11
- '100.100.100.200',
12
- 'instance-data',
13
- ]);
14
- const BLOCKED_IP_PATTERNS = [
15
- /^10\./,
16
- /^172\.(1[6-9]|2\d|3[01])\./,
17
- /^192\.168\./,
18
- /^127\./,
19
- /^0\./,
20
- /^169\.254\./,
21
- /^fc00:/i,
22
- /^fe80:/i,
23
- /^::ffff:127\./,
24
- /^::ffff:10\./,
25
- /^::ffff:172\.(1[6-9]|2\d|3[01])\./,
26
- /^::ffff:192\.168\./,
27
- ];
28
2
  /**
29
3
  * Check if an IP address is in a blocked private range
30
4
  */
31
- function isBlockedIp(ip) {
32
- return BLOCKED_IP_PATTERNS.some((pattern) => pattern.test(ip));
33
- }
34
- export async function validateResolvedIps(hostname) {
35
- if (/^[\d.]+$/.test(hostname) || hostname.includes(':')) {
36
- return;
37
- }
38
- try {
39
- const ipv4Addresses = await dns.resolve4(hostname).catch(() => []);
40
- for (const ip of ipv4Addresses) {
41
- if (isBlockedIp(ip) || BLOCKED_HOSTS.has(ip)) {
42
- throw new Error(`DNS rebinding detected: ${hostname} resolves to blocked IP ${ip}`);
43
- }
44
- }
45
- const ipv6Addresses = await dns.resolve6(hostname).catch(() => []);
46
- for (const ip of ipv6Addresses) {
47
- if (isBlockedIp(ip) || BLOCKED_HOSTS.has(ip)) {
48
- throw new Error(`DNS rebinding detected: ${hostname} resolves to blocked IP ${ip}`);
49
- }
50
- }
51
- }
52
- catch (error) {
53
- if (error instanceof Error && error.message.includes('DNS rebinding')) {
54
- throw error;
55
- }
56
- }
5
+ export function isBlockedIp(ip) {
6
+ return config.security.blockedIpPatterns.some((pattern) => pattern.test(ip));
57
7
  }
58
8
  export function validateAndNormalizeUrl(urlString) {
59
9
  if (!urlString || typeof urlString !== 'string') {
@@ -83,7 +33,7 @@ export function validateAndNormalizeUrl(urlString) {
83
33
  if (!hostname) {
84
34
  throw new Error('URL must have a valid hostname');
85
35
  }
86
- if (BLOCKED_HOSTS.has(hostname)) {
36
+ if (config.security.blockedHosts.has(hostname)) {
87
37
  throw new Error(`Blocked host: ${hostname}. Internal hosts are not allowed`);
88
38
  }
89
39
  if (isBlockedIp(hostname)) {
@@ -1 +1 @@
1
- {"version":3,"file":"url-validator.js","sourceRoot":"","sources":["../../src/utils/url-validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"url-validator.js","sourceRoot":"","sources":["../../src/utils/url-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CACb,iCAAiC,MAAM,CAAC,SAAS,CAAC,YAAY,aAAa,CAC5E,CAAC;IACJ,CAAC;IAED,IAAI,GAAQ,CAAC;IAEb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,qBAAqB,GAAG,CAAC,QAAQ,qCAAqC,CACvE,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE5C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CACb,iBAAiB,QAAQ,kCAAkC,CAC5D,CAAC;IACJ,CAAC;IAED,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,qBAAqB,QAAQ,+BAA+B,CAC7D,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CACb,6BAA6B,QAAQ,4CAA4C,CAClF,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,OAAe;IACxD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,MAAM,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@j0hanz/superfetch",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "mcpName": "io.github.j0hanz/superfetch",
5
5
  "description": "Intelligent web content fetcher MCP server that converts HTML to clean, AI-readable JSONL format",
6
6
  "type": "module",
@@ -50,14 +50,14 @@
50
50
  "dependencies": {
51
51
  "@modelcontextprotocol/sdk": "^1.25.1",
52
52
  "@mozilla/readability": "^0.6.0",
53
- "axios": "^1.13.2",
53
+ "axios": "^1.7.9",
54
54
  "cheerio": "^1.1.2",
55
55
  "domhandler": "^5.0.3",
56
56
  "express": "^5.2.1",
57
57
  "jsdom": "^27.3.0",
58
58
  "node-cache": "^5.1.2",
59
59
  "turndown": "^7.2.2",
60
- "zod": "^3.25.76"
60
+ "zod": "^3.24.1"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@eslint/js": "^9.39.2",