dsh-read-url 1.1.0 → 1.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-read-url",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "DeepSeek Harness URL reader: fetch any webpage (HTML/JSON/RSS/Atom), auto-detect encoding (UTF-16 BOM/GBK/Big5/Shift-JIS), extract clean main content with auto-pagination, output compact text/Markdown to save tokens. Zero runtime dependencies, no API key, drop-in.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/proxy-fallback.js CHANGED
@@ -97,7 +97,12 @@ export async function fetchViaCurlProxy(url, cfg, externalSignal, proxyOverride)
97
97
  '--max-filesize', String(cfg.maxBytes), // unit is BYTES, not KB
98
98
  '-x', proxy,
99
99
  '-A', cfg.userAgent,
100
- '-w', '\n%{http_code} %{content_type}',
100
+ // trailing metadata line: "<http_code> <content_type> <url_effective>"
101
+ // (url_effective last: content_type may be empty, URLs never contain
102
+ // unencoded spaces — parse from both ends). Without it a redirected
103
+ // fetch kept the ORIGINAL url as finalUrl and same-host pagination /
104
+ // link resolution ran against the wrong host.
105
+ '-w', '\n%{http_code} %{content_type} %{url_effective}',
101
106
  url,
102
107
  ]
103
108
  try {
@@ -107,14 +112,16 @@ export async function fetchViaCurlProxy(url, cfg, externalSignal, proxyOverride)
107
112
  resolve(stdout)
108
113
  })
109
114
  })
110
- // tail line carries the metadata: "<http_code> <content_type>"
115
+ // tail line carries the metadata: "<code> <content_type> <url_effective>"
111
116
  const nl = buf.lastIndexOf(0x0a)
112
117
  if (nl < 0) return null // no trailing metadata — abnormal response, treat as failure
113
118
  const meta = buf.subarray(nl + 1).toString('latin1').trim()
114
119
  const body = buf.subarray(0, nl)
115
- const [codeStr, ...ctParts] = meta.split(' ')
120
+ const parts = meta.split(' ')
121
+ const codeStr = parts.shift()
122
+ const finalUrlEff = parts.length > 1 ? parts.pop() : url
116
123
  const code = Number(codeStr)
117
- const contentType = ctParts.join(' ')
124
+ const contentType = parts.join(' ')
118
125
  if (code >= 200 && code < 300) {
119
126
  // Headerless responses: gate binary bodies out (same rule as the direct
120
127
  // path — curl writes an empty %{content_type} then).
@@ -126,7 +133,7 @@ export async function fetchViaCurlProxy(url, cfg, externalSignal, proxyOverride)
126
133
  if (contentType && !/text\/html|application\/xhtml|text\/plain|\/json|[+/]xml/i.test(contentType)) {
127
134
  return { error: `Unsupported content-type: ${contentType.split(';')[0]}` }
128
135
  }
129
- return { buffer: body, contentType, finalUrl: url, viaProxy: proxy }
136
+ return { buffer: body, contentType, finalUrl: finalUrlEff, viaProxy: proxy }
130
137
  } catch (err) {
131
138
  // curl error 63 = exceeded --max-filesize (page too large, not a proxy
132
139
  // problem — report it as such instead of "proxy unreachable")