@ai-sdk/provider-utils 4.0.59 → 4.0.61
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/CHANGELOG.md +15 -0
- package/dist/index.d.mts +53 -11
- package/dist/index.d.ts +53 -11
- package/dist/index.js +77 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +77 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/fetch-with-validated-redirects.ts +65 -28
- package/src/get-from-api.ts +65 -10
- package/src/sanitize-request-headers.ts +53 -0
package/dist/index.mjs
CHANGED
|
@@ -499,8 +499,45 @@ function getCurrentModulePath() {
|
|
|
499
499
|
}
|
|
500
500
|
}
|
|
501
501
|
|
|
502
|
+
// src/sanitize-request-headers.ts
|
|
503
|
+
var BLOCKED_REQUEST_HEADERS = [
|
|
504
|
+
// Hop-by-hop / transport (RFC 7230 §6.1)
|
|
505
|
+
"connection",
|
|
506
|
+
"keep-alive",
|
|
507
|
+
"te",
|
|
508
|
+
"trailer",
|
|
509
|
+
"transfer-encoding",
|
|
510
|
+
"upgrade",
|
|
511
|
+
// Host / virtual-host routing
|
|
512
|
+
"host",
|
|
513
|
+
// Proxy / origin spoofing
|
|
514
|
+
"forwarded",
|
|
515
|
+
"proxy-authorization",
|
|
516
|
+
"via",
|
|
517
|
+
"x-forwarded-for",
|
|
518
|
+
"x-forwarded-host",
|
|
519
|
+
"x-forwarded-proto",
|
|
520
|
+
"x-real-ip",
|
|
521
|
+
// Cloud metadata (GCP, AWS IMDSv1/v2, Azure, Alibaba, DigitalOcean)
|
|
522
|
+
"metadata",
|
|
523
|
+
"metadata-flavor",
|
|
524
|
+
"x-aws-ec2-metadata-token",
|
|
525
|
+
"x-metadata-token",
|
|
526
|
+
// Session / cookie
|
|
527
|
+
"cookie",
|
|
528
|
+
"set-cookie"
|
|
529
|
+
];
|
|
530
|
+
function sanitizeRequestHeaders(input) {
|
|
531
|
+
const headers = new Headers(input);
|
|
532
|
+
for (const name2 of BLOCKED_REQUEST_HEADERS) {
|
|
533
|
+
headers.delete(name2);
|
|
534
|
+
}
|
|
535
|
+
return headers;
|
|
536
|
+
}
|
|
537
|
+
|
|
502
538
|
// src/fetch-with-validated-redirects.ts
|
|
503
539
|
var MAX_DOWNLOAD_REDIRECTS = 10;
|
|
540
|
+
var REDIRECT_STATUS_CODES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
504
541
|
async function getValidatedFetch(customFetch) {
|
|
505
542
|
return customFetch == null || customFetch === globalThis.fetch ? await getDefaultDownloadFetch() : customFetch;
|
|
506
543
|
}
|
|
@@ -531,10 +568,14 @@ async function fetchWithValidatedRedirects({
|
|
|
531
568
|
trustedOrigin
|
|
532
569
|
}) {
|
|
533
570
|
var _a2;
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
571
|
+
let currentHeaders = headers === void 0 ? void 0 : sanitizeRequestHeaders(headers);
|
|
572
|
+
const perHopInit = (redirect) => {
|
|
573
|
+
const init = { signal: abortSignal, redirect };
|
|
574
|
+
if (currentHeaders !== void 0) {
|
|
575
|
+
init.headers = new Headers(currentHeaders);
|
|
576
|
+
}
|
|
577
|
+
return init;
|
|
578
|
+
};
|
|
538
579
|
let currentUrl = url;
|
|
539
580
|
for (let redirectCount = 0; redirectCount <= maxRedirects; redirectCount++) {
|
|
540
581
|
const isTrustedHop = trustedOrigin !== void 0 && isSameOrigin(currentUrl, trustedOrigin);
|
|
@@ -542,10 +583,7 @@ async function fetchWithValidatedRedirects({
|
|
|
542
583
|
validateDownloadUrl(currentUrl);
|
|
543
584
|
}
|
|
544
585
|
const fetch = isTrustedHop && customFetch != null ? customFetch : isTrustedHop ? globalThis.fetch : await getValidatedFetch(customFetch);
|
|
545
|
-
const response = await fetch(currentUrl,
|
|
546
|
-
...baseInit,
|
|
547
|
-
redirect: "manual"
|
|
548
|
-
});
|
|
586
|
+
const response = await fetch(currentUrl, perHopInit("manual"));
|
|
549
587
|
if (response.type === "opaqueredirect") {
|
|
550
588
|
if (!isBrowserRuntime()) {
|
|
551
589
|
throw new DownloadError({
|
|
@@ -553,12 +591,19 @@ async function fetchWithValidatedRedirects({
|
|
|
553
591
|
message: `Redirect from ${currentUrl} could not be validated and was blocked`
|
|
554
592
|
});
|
|
555
593
|
}
|
|
556
|
-
return await fetch(currentUrl,
|
|
594
|
+
return await fetch(currentUrl, perHopInit("follow"));
|
|
557
595
|
}
|
|
558
596
|
const location = (_a2 = response.headers) == null ? void 0 : _a2.get("location");
|
|
559
|
-
if (
|
|
560
|
-
|
|
561
|
-
|
|
597
|
+
if (REDIRECT_STATUS_CODES.has(response.status) && location) {
|
|
598
|
+
void cancelResponseBody(response);
|
|
599
|
+
const nextUrl = new URL(location, currentUrl).toString();
|
|
600
|
+
if (currentHeaders !== void 0 && !isSameOrigin(nextUrl, currentUrl)) {
|
|
601
|
+
const userAgent = currentHeaders.get("user-agent");
|
|
602
|
+
currentHeaders = new Headers(
|
|
603
|
+
userAgent == null ? void 0 : { "user-agent": userAgent }
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
currentUrl = nextUrl;
|
|
562
607
|
continue;
|
|
563
608
|
}
|
|
564
609
|
return response;
|
|
@@ -848,7 +893,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
|
|
|
848
893
|
}
|
|
849
894
|
|
|
850
895
|
// src/version.ts
|
|
851
|
-
var VERSION = true ? "4.0.
|
|
896
|
+
var VERSION = true ? "4.0.61" : "0.0.0-test";
|
|
852
897
|
|
|
853
898
|
// src/get-from-api.ts
|
|
854
899
|
var getOriginalFetch = () => globalThis.fetch;
|
|
@@ -858,16 +903,28 @@ var getFromApi = async ({
|
|
|
858
903
|
successfulResponseHandler,
|
|
859
904
|
failedResponseHandler,
|
|
860
905
|
abortSignal,
|
|
861
|
-
fetch
|
|
906
|
+
fetch,
|
|
907
|
+
validateUrl,
|
|
908
|
+
credentialedOrigin,
|
|
909
|
+
trustedOrigin
|
|
862
910
|
}) => {
|
|
863
911
|
try {
|
|
864
|
-
const
|
|
912
|
+
const requestFetch = fetch != null ? fetch : getOriginalFetch();
|
|
913
|
+
const outgoingHeaders = credentialedOrigin !== void 0 && !isSameOrigin(url, credentialedOrigin) ? {} : headers;
|
|
914
|
+
const requestHeaders = withUserAgentSuffix(
|
|
915
|
+
outgoingHeaders,
|
|
916
|
+
`ai-sdk/provider-utils/${VERSION}`,
|
|
917
|
+
getRuntimeEnvironmentUserAgent()
|
|
918
|
+
);
|
|
919
|
+
const response = validateUrl ? await fetchWithValidatedRedirects({
|
|
920
|
+
url,
|
|
921
|
+
headers: requestHeaders,
|
|
922
|
+
abortSignal,
|
|
923
|
+
fetch,
|
|
924
|
+
trustedOrigin
|
|
925
|
+
}) : await requestFetch(url, {
|
|
865
926
|
method: "GET",
|
|
866
|
-
headers:
|
|
867
|
-
headers,
|
|
868
|
-
`ai-sdk/provider-utils/${VERSION}`,
|
|
869
|
-
getRuntimeEnvironmentUserAgent()
|
|
870
|
-
),
|
|
927
|
+
headers: requestHeaders,
|
|
871
928
|
signal: abortSignal
|
|
872
929
|
});
|
|
873
930
|
const responseHeaders = extractResponseHeaders(response);
|