Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
镜像
Coder
code-server
提交
58c1be57
C
code-server
项目概览
镜像
/
Coder
/
code-server
2022-09-21 03:15:05同步失败
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
code-server
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
58c1be57
编写于
12月 10, 2020
作者:
A
Asher
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement callback endpoints
VS Code uses these during the authentication flow.
上级
98338e9a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
120 addition
and
3 deletion
+120
-3
src/common/util.ts
src/common/util.ts
+11
-0
src/node/routes/static.ts
src/node/routes/static.ts
+3
-2
src/node/routes/vscode.ts
src/node/routes/vscode.ts
+106
-1
未找到文件。
src/common/util.ts
浏览文件 @
58c1be57
...
...
@@ -101,3 +101,14 @@ export const arrayify = <T>(value?: T | T[]): T[] => {
}
return
[
value
]
}
/**
* Get the first string. If there's no string return undefined.
*/
export
const
getFirstString
=
(
value
:
string
|
string
[]
|
object
|
undefined
):
string
|
undefined
=>
{
if
(
Array
.
isArray
(
value
))
{
return
value
[
0
]
}
return
typeof
value
!==
"
object
"
?
value
:
undefined
}
src/node/routes/static.ts
浏览文件 @
58c1be57
...
...
@@ -6,6 +6,7 @@ import { Readable } from "stream"
import
*
as
tarFs
from
"
tar-fs
"
import
*
as
zlib
from
"
zlib
"
import
{
HttpCode
,
HttpError
}
from
"
../../common/http
"
import
{
getFirstString
}
from
"
../../common/util
"
import
{
rootPath
}
from
"
../constants
"
import
{
authenticated
,
ensureAuthenticated
,
replaceTemplates
}
from
"
../http
"
import
{
getMediaMime
,
pathToFsPath
}
from
"
../util
"
...
...
@@ -15,8 +16,8 @@ export const router = Router()
// The commit is for caching.
router
.
get
(
"
/(:commit)(/*)?
"
,
async
(
req
,
res
)
=>
{
// Used by VS Code to load extensions into the web worker.
const
tar
=
Array
.
isArray
(
req
.
query
.
tar
)
?
req
.
query
.
tar
[
0
]
:
req
.
query
.
tar
if
(
t
ypeof
tar
===
"
string
"
)
{
const
tar
=
getFirstString
(
req
.
query
.
tar
)
if
(
t
ar
)
{
ensureAuthenticated
(
req
)
let
stream
:
Readable
=
tarFs
.
pack
(
pathToFsPath
(
tar
))
if
(
req
.
headers
[
"
accept-encoding
"
]
&&
req
.
headers
[
"
accept-encoding
"
].
includes
(
"
gzip
"
))
{
...
...
src/node/routes/vscode.ts
浏览文件 @
58c1be57
import
*
as
crypto
from
"
crypto
"
import
{
Router
}
from
"
express
"
import
{
R
equest
,
R
outer
}
from
"
express
"
import
{
promises
as
fs
}
from
"
fs
"
import
*
as
path
from
"
path
"
import
qs
from
"
qs
"
import
{
Emitter
}
from
"
../../common/emitter
"
import
{
HttpCode
,
HttpError
}
from
"
../../common/http
"
import
{
getFirstString
}
from
"
../../common/util
"
import
{
commit
,
rootPath
,
version
}
from
"
../constants
"
import
{
authenticated
,
ensureAuthenticated
,
redirect
,
replaceTemplates
}
from
"
../http
"
import
{
getMediaMime
,
pathToFsPath
}
from
"
../util
"
...
...
@@ -86,6 +90,107 @@ router.get("/webview/*", ensureAuthenticated, async (req, res) => {
)
})
interface
Callback
{
uri
:
{
scheme
:
string
authority
?:
string
path
?:
string
query
?:
string
fragment
?:
string
}
timeout
:
NodeJS
.
Timeout
}
const
callbacks
=
new
Map
<
string
,
Callback
>
()
const
callbackEmitter
=
new
Emitter
<
{
id
:
string
;
callback
:
Callback
}
>
()
/**
* Get vscode-requestId from the query and throw if it's missing or invalid.
*/
const
getRequestId
=
(
req
:
Request
):
string
=>
{
if
(
!
req
.
query
[
"
vscode-requestId
"
])
{
throw
new
HttpError
(
"
vscode-requestId is missing
"
,
HttpCode
.
BadRequest
)
}
if
(
typeof
req
.
query
[
"
vscode-requestId
"
]
!==
"
string
"
)
{
throw
new
HttpError
(
"
vscode-requestId is not a string
"
,
HttpCode
.
BadRequest
)
}
return
req
.
query
[
"
vscode-requestId
"
]
}
// Matches VS Code's fetch timeout.
const
fetchTimeout
=
5
*
60
*
1000
// The callback endpoints are used during authentication. A URI is stored on
// /callback and then fetched later on /fetch-callback.
// See ../../../lib/vscode/resources/web/code-web.js
router
.
get
(
"
/callback
"
,
ensureAuthenticated
,
async
(
req
,
res
)
=>
{
const
uriKeys
=
[
"
vscode-requestId
"
,
"
vscode-scheme
"
,
"
vscode-authority
"
,
"
vscode-path
"
,
"
vscode-query
"
,
"
vscode-fragment
"
,
]
const
id
=
getRequestId
(
req
)
// Move any query variables that aren't URI keys into the URI's query
// (importantly, this will include the code for oauth).
const
query
:
qs
.
ParsedQs
=
{}
for
(
const
key
in
req
.
query
)
{
if
(
!
uriKeys
.
includes
(
key
))
{
query
[
key
]
=
req
.
query
[
key
]
}
}
const
callback
=
{
uri
:
{
scheme
:
getFirstString
(
req
.
query
[
"
vscode-scheme
"
])
||
"
code-oss
"
,
authority
:
getFirstString
(
req
.
query
[
"
vscode-authority
"
]),
path
:
getFirstString
(
req
.
query
[
"
vscode-path
"
]),
query
:
(
getFirstString
(
req
.
query
.
query
)
?
getFirstString
(
req
.
query
.
query
)
+
"
&
"
:
""
)
+
qs
.
stringify
(
query
),
fragment
:
getFirstString
(
req
.
query
[
"
vscode-fragment
"
]),
},
// Make sure the map doesn't leak if nothing fetches this URI.
timeout
:
setTimeout
(()
=>
callbacks
.
delete
(
id
),
fetchTimeout
),
}
callbacks
.
set
(
id
,
callback
)
callbackEmitter
.
emit
({
id
,
callback
})
res
.
sendFile
(
path
.
join
(
rootPath
,
"
lib/vscode/resources/web/callback.html
"
))
})
router
.
get
(
"
/fetch-callback
"
,
ensureAuthenticated
,
async
(
req
,
res
)
=>
{
const
id
=
getRequestId
(
req
)
const
send
=
(
callback
:
Callback
)
=>
{
clearTimeout
(
callback
.
timeout
)
callbacks
.
delete
(
id
)
res
.
json
(
callback
.
uri
)
}
const
callback
=
callbacks
.
get
(
id
)
if
(
callback
)
{
return
send
(
callback
)
}
// VS Code will try again if the route returns no content but it seems more
// efficient to just wait on this request for as long as possible?
const
handler
=
callbackEmitter
.
event
(({
id
:
emitId
,
callback
})
=>
{
if
(
id
===
emitId
)
{
handler
.
dispose
()
send
(
callback
)
}
})
// If the client closes the connection.
req
.
on
(
"
close
"
,
()
=>
handler
.
dispose
())
})
export
const
wsRouter
=
WsRouter
()
wsRouter
.
ws
(
"
/
"
,
ensureAuthenticated
,
async
(
req
)
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录