Add issues for CORS disabled scheme problems
This CL adds issues for the CORS error codes
CorsDisabledScheme
Screenshot: https://imgur.com/a/3nVmUn6
Bug: chromium:1141824
Change-Id: I29f085e660ba6985b028cbc52e9460857525da52
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2897284
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Wolfgang Beyer <wolfi@chromium.org>
diff --git a/config/gni/all_devtools_files.gni b/config/gni/all_devtools_files.gni
index b16b95c..bac60f1 100644
--- a/config/gni/all_devtools_files.gni
+++ b/config/gni/all_devtools_files.gni
@@ -213,6 +213,7 @@
"front_end/models/issues_manager/descriptions/heavyAd.md",
"front_end/models/issues_manager/descriptions/corsAllowCredentialsRequired.md",
"front_end/models/issues_manager/descriptions/corsDisallowedByMode.md",
+ "front_end/models/issues_manager/descriptions/corsDisabledScheme.md",
"front_end/models/issues_manager/descriptions/corsHeaderDisallowedByPreflightResponse.md",
"front_end/models/issues_manager/descriptions/corsInvalidHeaderValues.md",
"front_end/models/issues_manager/descriptions/corsMethodDisallowedByPreflightResponse.md",
diff --git a/config/gni/devtools_grd_files.gni b/config/gni/devtools_grd_files.gni
index c3508ab..5b8f46d 100644
--- a/config/gni/devtools_grd_files.gni
+++ b/config/gni/devtools_grd_files.gni
@@ -246,6 +246,7 @@
"front_end/models/issues_manager/descriptions/TwaHttpError.md",
"front_end/models/issues_manager/descriptions/TwaPageUnavailableOffline.md",
"front_end/models/issues_manager/descriptions/corsAllowCredentialsRequired.md",
+ "front_end/models/issues_manager/descriptions/corsDisabledScheme.md",
"front_end/models/issues_manager/descriptions/corsDisallowedByMode.md",
"front_end/models/issues_manager/descriptions/corsHeaderDisallowedByPreflightResponse.md",
"front_end/models/issues_manager/descriptions/corsInsecurePrivateNetwork.md",
diff --git a/front_end/core/i18n/locales/en-US.json b/front_end/core/i18n/locales/en-US.json
index 530c552..7c2df4c 100644
--- a/front_end/core/i18n/locales/en-US.json
+++ b/front_end/core/i18n/locales/en-US.json
@@ -4982,6 +4982,9 @@
"panels/issues/CorsIssueDetailsView.ts | status": {
"message": "Status"
},
+ "panels/issues/CorsIssueDetailsView.ts | unsupportedScheme": {
+ "message": "Unsupported Scheme"
+ },
"panels/issues/CorsIssueDetailsView.ts | warning": {
"message": "warning"
},
diff --git a/front_end/core/i18n/locales/en-XL.json b/front_end/core/i18n/locales/en-XL.json
index 418efdf..a86bfb1 100644
--- a/front_end/core/i18n/locales/en-XL.json
+++ b/front_end/core/i18n/locales/en-XL.json
@@ -4982,6 +4982,9 @@
"panels/issues/CorsIssueDetailsView.ts | status": {
"message": "Ŝt́ât́ûś"
},
+ "panels/issues/CorsIssueDetailsView.ts | unsupportedScheme": {
+ "message": "Ûńŝúp̂ṕôŕt̂éd̂ Śĉh́êḿê"
+ },
"panels/issues/CorsIssueDetailsView.ts | warning": {
"message": "ŵár̂ńîńĝ"
},
diff --git a/front_end/models/issues_manager/BUILD.gn b/front_end/models/issues_manager/BUILD.gn
index 837c62b..ae3a193 100644
--- a/front_end/models/issues_manager/BUILD.gn
+++ b/front_end/models/issues_manager/BUILD.gn
@@ -45,6 +45,7 @@
"CoepCorpNotSameSite.md",
"CoepFrameResourceNeedsCoepHeader.md",
"corsAllowCredentialsRequired.md",
+ "corsDisabledScheme.md",
"corsDisallowedByMode.md",
"corsHeaderDisallowedByPreflightResponse.md",
"corsInsecurePrivateNetwork.md",
diff --git a/front_end/models/issues_manager/CorsIssue.ts b/front_end/models/issues_manager/CorsIssue.ts
index f8b89d4..d66ccdc 100644
--- a/front_end/models/issues_manager/CorsIssue.ts
+++ b/front_end/models/issues_manager/CorsIssue.ts
@@ -198,6 +198,13 @@
}],
};
case IssueCode.CorsDisabledScheme:
+ return {
+ file: 'corsDisabledScheme.md',
+ links: [{
+ link: 'https://web.dev/cross-origin-resource-sharing',
+ linkTitle: i18nString(UIStrings.CORS),
+ }],
+ };
case IssueCode.PreflightMissingAllowExternal:
case IssueCode.PreflightInvalidAllowExternal:
case IssueCode.InvalidResponse:
diff --git a/front_end/models/issues_manager/descriptions/corsDisabledScheme.md b/front_end/models/issues_manager/descriptions/corsDisabledScheme.md
new file mode 100644
index 0000000..c8d18ef
--- /dev/null
+++ b/front_end/models/issues_manager/descriptions/corsDisabledScheme.md
@@ -0,0 +1,7 @@
+# Ensure CORS requests are made on supported schemes
+
+A cross-origin resource sharing (CORS) request was blocked because the scheme of the request's URL doesn't support CORS.
+
+To fix this issue, ensure all CORS request URLs specify a supported scheme, e.g. most commonly https://.
+
+Note that if an opaque response is sufficient, then for some schemes the request's mode can be set to `no-cors` to fetch the resource with CORS disabled; that way the scheme doesn't need to support CORS, but the response content is inaccessible (opaque).
diff --git a/front_end/panels/issues/CorsIssueDetailsView.ts b/front_end/panels/issues/CorsIssueDetailsView.ts
index de42db4..af90333 100644
--- a/front_end/panels/issues/CorsIssueDetailsView.ts
+++ b/front_end/panels/issues/CorsIssueDetailsView.ts
@@ -112,6 +112,10 @@
*@description Header for the source location column
*/
sourceLocation: 'Source Location',
+ /**
+ *@description Header for the column with the URL scheme that is not supported by fetch
+ */
+ unsupportedScheme: 'Unsupported Scheme',
};
const str_ = i18n.i18n.registerUIStrings('panels/issues/CorsIssueDetailsView.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -190,9 +194,13 @@
this.appendColumnTitle(header, i18nString(UIStrings.initiatorContext));
this.appendColumnTitle(header, i18nString(UIStrings.sourceLocation));
break;
+ case IssuesManager.CorsIssue.IssueCode.CorsDisabledScheme:
+ this.appendColumnTitle(header, i18nString(UIStrings.initiatorContext));
+ this.appendColumnTitle(header, i18nString(UIStrings.sourceLocation));
+ this.appendColumnTitle(header, i18nString(UIStrings.unsupportedScheme));
+ break;
default:
Platform.assertUnhandled<IssuesManager.CorsIssue.IssueCode.NoCorsRedirectModeNotFollow|
- IssuesManager.CorsIssue.IssueCode.CorsDisabledScheme|
IssuesManager.CorsIssue.IssueCode.PreflightMissingAllowExternal|
IssuesManager.CorsIssue.IssueCode.PreflightInvalidAllowExternal|
IssuesManager.CorsIssue.IssueCode.InvalidResponse>(issueCode);
@@ -383,11 +391,22 @@
this.appendIssueDetailCell(element, details.initiatorOrigin ?? '', 'code-example');
this.appendSourceLocation(element, details.location, issue.model()?.getTargetIfNotDisposed());
break;
+ case IssuesManager.CorsIssue.IssueCode.CorsDisabledScheme:
+ element.appendChild(this.createRequestCell(details.request, {
+ highlightHeader: {
+ section: Network.NetworkSearchScope.UIHeaderSection.Response,
+ name: CorsIssueDetailsView.getHeaderFromError(corsError),
+ },
+ }));
+ this.appendStatus(element, details.isWarning);
+ this.appendIssueDetailCell(element, details.initiatorOrigin ?? '', 'code-example');
+ this.appendSourceLocation(element, details.location, issue.model()?.getTargetIfNotDisposed());
+ this.appendIssueDetailCell(element, details.corsErrorStatus.failedParameter ?? '', 'code-example');
+ break;
default:
element.appendChild(this.createRequestCell(details.request));
this.appendStatus(element, details.isWarning);
Platform.assertUnhandled<IssuesManager.CorsIssue.IssueCode.NoCorsRedirectModeNotFollow|
- IssuesManager.CorsIssue.IssueCode.CorsDisabledScheme|
IssuesManager.CorsIssue.IssueCode.PreflightMissingAllowExternal|
IssuesManager.CorsIssue.IssueCode.PreflightInvalidAllowExternal|
IssuesManager.CorsIssue.IssueCode.InvalidResponse>(issueCode);
diff --git a/test/e2e/issues/cors-issues_test.ts b/test/e2e/issues/cors-issues_test.ts
index 8ebcf39..72c3cf8 100644
--- a/test/e2e/issues/cors-issues_test.ts
+++ b/test/e2e/issues/cors-issues_test.ts
@@ -409,4 +409,43 @@
/.*:\d+/,
]);
});
+
+ it('should display CORS issues that are unsupported by the scheme', async () => {
+ await goToResource('empty.html');
+ const {target} = getBrowserAndPages();
+ await target.evaluate(async () => {
+ try {
+ const url = new URL('/', document.location.toString())
+ .toString()
+ .replace('https://localhost', 'webdav://devtools.oopif.test');
+ await fetch(url);
+ } catch (e) {
+ }
+ });
+ await navigateToIssuesTab();
+ await expandIssue();
+ const issueElement = await getIssueByTitle('Ensure CORS requests are made on supported schemes');
+ assertNotNull(issueElement);
+ const section = await getResourcesElement('request', issueElement, '.cors-issue-affected-resource-label');
+ const text = await section.label.evaluate(el => el.textContent);
+ assert.strictEqual(text, '1 request');
+ await ensureResourceSectionIsExpanded(section);
+ const table = await extractTableFromResourceSection(section.content);
+ assertNotNull(table);
+ assert.strictEqual(table.length, 2);
+ assert.deepEqual(table[0], [
+ 'Request',
+ 'Status',
+ 'Initiator Context',
+ 'Source Location',
+ 'Unsupported Scheme',
+ ]);
+ assertMatchArray(table[1], [
+ /^devtools.oopif.test.*\//,
+ 'blocked',
+ /^https:\/\/localhost.*/,
+ /.*:\d+/,
+ 'webdav',
+ ]);
+ });
});