Skip to content

Convert code-server http code to use Express #2238

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 84 commits into from
Nov 12, 2020
Merged

Conversation

code-asher
Copy link
Member

@code-asher code-asher commented Oct 26, 2020

Story details: https://app.clubhouse.io/coder/story/1385

Couple items still remaining but existing code is ready to review:

  • I keep getting log directories created in the code-server directory over and over with new timestamps.
  • Need a way to register disposables for when the application is killed.

Closes #2128
Closes #1899

@code-asher code-asher requested a review from nhooyr as a code owner October 26, 2020 22:48
@code-asher code-asher changed the base branch from v3.6.1 to master October 26, 2020 22:48
Copy link

@wbobeirne wbobeirne left a comment

Choose a reason for hiding this comment

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

There's a lot in this PR that I don't have the context to parse, but I caught a couple of items. VSCode seems to fire up just fine for me though, no bugs that I found with some cursory usage.

The patchRouter is the only big unknown to me. I haven't worked with modifying the underlying implementation of Express to know enough about where to do that, but I'm pretty sure this ain't it.

code-asher and others added 7 commits October 27, 2020 17:17
- Use accept header.
- Match /login and /login/ exactly.
- Match /static/ (trailing slash).
- Use req.path. Same result but feels more accurate to me.
We now guarantee there is an address.
Co-authored-by: Teffen Ellis <TeffenEllis@users.noreply.github.com>
Opening the URL can fail if the user doesn't have something appropriate
installed to handle it.
Makes typing much easier. Addresse's Will's last comment.
Unfortunately we can't use node-mocks-http to test a express.Router
that has async routes. See eugef/node-mocks-http#225

router will just return undefined if the executing handler is async and
so the test will have no way to wait for it to complete. Thus, we have
to use supertest which starts an actual HTTP server in the background
and uses a HTTP client to send requests.
Plugin API to add more applications to code-server
response.statusCode < 400 &&
response.headers.location
) {
++redirects
Copy link
Contributor

Choose a reason for hiding this comment

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

Yea if we can I'd much rather we use a library here. It's really error prone to write this all ourself. I'm sure we're probably missing a few HTTP gotchas too.

That's the default so it's extra visual noise.
Hopefully is a bit easier to read.
Also add a check that the domain has a dot. This covers the localhost
case as well, so remove that.
@code-asher
Copy link
Member Author

I think all comments have been addressed except the following which I think we could tackle a bit later:

  • Store last update internally instead of to disk
  • Use a library to fetch the latest version from GitHub
  • Split or rename setDefaults

Lemme know if I missed something.

One problem though is that the error handler doesn't seem to work. It never gets called so we just get the default Express error page. I'm not sure if it has something to do with the Express 5 update (I didn't see anything relevant in the migration guide: https://expressjs.com/en/guide/migrating-5.html) or what.

@nhooyr
Copy link
Contributor

nhooyr commented Nov 12, 2020

One problem though is that the error handler doesn't seem to work. It never gets called so we just get the default Express error page. I'm not sure if it has something to do with the Express 5 update (I didn't see anything relevant in the migration guide: https://expressjs.com/en/guide/migrating-5.html) or what.

Let's make that a release blocking issue.

Copy link
Contributor

@nhooyr nhooyr left a comment

Choose a reason for hiding this comment

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

Approval after these last few concerns.

)

const message = await this.onMessage<ipc.OptionsMessage>(vscode, (message): message is ipc.OptionsMessage => {
// There can be parallel initializations so wait for the right ID.
Copy link
Contributor

Choose a reason for hiding this comment

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

How would a parallel init occur?

Copy link
Member Author

Choose a reason for hiding this comment

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

Loading the page in two separate tabs is the main way I think. If we had some sort of collaborative mode it would probably be a bigger problem then.

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess in theory it could also happen if you refresh a page before it finishes loading to send off two almost-parallel requests although I don't think I've hit it that way before.

Copy link
Contributor

Choose a reason for hiding this comment

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

Loading the page in two separate tabs is the main way I think. If we had some sort of collaborative mode it would probably be a bigger problem then.

Shouldn't we prevent sending parallel init's at the same time?

Copy link
Contributor

Choose a reason for hiding this comment

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

Or actually, doesn't each websocket get it's own vscode process? Or is that only its own extension host?

Copy link
Member Author

@code-asher code-asher Nov 12, 2020

Choose a reason for hiding this comment

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

There's a single VS Code process for all websockets and an extension host for each websocket. Each page also gets its own "management" websocket where we initialize all the services VS Code uses (like the file service, environment service, language initialization, and so on).

Copy link
Member Author

@code-asher code-asher Nov 12, 2020

Choose a reason for hiding this comment

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

The services are shared too actually, come to think. Language stuff isn't though, and there are some other differences in the initialization like which folder to open up (depending on the query parameter for example).

Turns out that while Typescript can't infer the callback return type
from it, Typescript can do the opposite and infer it from the callback
return type.
This will make the route more robust since it'll work under more than
just the root.
Copy link
Contributor

@nhooyr nhooyr left a comment

Choose a reason for hiding this comment

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

🚀

Also switch `once` to `on` since we `off` them later anyway so no point
in making Node do it twice.
Feels like it parallels better with the other handlers.
I'm not sure why other builds are passing with this still in.
@code-asher code-asher merged commit 5e60305 into master Nov 12, 2020
@code-asher code-asher deleted the code-asher/ch1385 branch November 12, 2020 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants