Skip to content

fix(lib/vscode): patch authority in asWebviewUri #3895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/vscode/src/vs/workbench/api/common/shared/webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ export function asWebviewUri(
});
}

// NOTE@coder: Add the port separately because if the port is in the domain the
// URL will be invalid and the browser will not request it.
const authorityUrl = new URL(`${resource.scheme}://${resource.authority}`);
return URI.from({
scheme: Schemas.https,
authority: `${resource.scheme}+${resource.authority}.${webviewRootResourceAuthority}`,
authority: `${resource.scheme}+${authorityUrl.hostname}.${webviewRootResourceAuthority}${authorityUrl.port ? (':' + authorityUrl.port) : ''}`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsjoeio IMO the bug stems from modifying URLs as strings, rather than leaning on the browser’s innate URL constructor Would something like this help with URL?

// e.g. new URL(‘abc://localhost:3000/foo/bar?baz=qux')
// The scheme isn’t too big of a deal here but it helps to lean on what’s known from above.
const authorityUrl = new URL(`${resource.scheme}://${resource.authority}`);

authorityUrl.hostname = `${authorityUrl.hostname}+${resource.authority}.${webviewRootResourceAuthority}`;
// Remove the protocol
const authority = authorityUrl.toString().slice(`${authorityUrl.protocol}//`.length);

return URI.from({
  scheme: Schemas.https,
  authority,
  path: resource.path,
  fragment: resource.fragment,
  query: resource.query,
});

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That might work! It sounds like a more complete fix. I'll give it a try and report back! (thanks for the through codeblock too!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converting to draft stage and then i'll re-request a review

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we try/catch the URL construction?

Copy link
Contributor Author

@jsjoeio jsjoeio Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, I think we'll leave as is and let it bubble up.

Copy link
Contributor Author

@jsjoeio jsjoeio Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay...looking at your solution, I don't think I fully understand how it helps (more on my lack of understanding, not critiquing your code 😅). I tried it, but I think either the hostname or the port gets mangled (though I might be doing something else wrong). I'm going to leave as is for now. And if you want to follow-up with more details or have me submit another PR to improve this, happy to do so!

path: resource.path,
fragment: resource.fragment,
query: resource.query,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ async function processResourceRequest(event, requestUrl) {

const firstHostSegment = requestUrl.hostname.slice(0, requestUrl.hostname.length - (resourceBaseAuthority.length + 1));
const scheme = firstHostSegment.split('+', 1)[0];
const authority = firstHostSegment.slice(scheme.length + 1); // may be empty
const authority = firstHostSegment.slice(scheme.length + 1) + requestUrl.port ? (':' + requestUrl.port) : ''; // may be empty

for (const parentClient of parentClients) {
parentClient.postMessage({
Expand Down