Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
b4e4bd16
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b4e4bd16
编写于
1月 13, 2021
作者:
A
Alex Ross
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Allow tunnel providers to support making a tunnel public
上级
a4f9e607
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
166 addition
and
51 deletion
+166
-51
src/vs/platform/remote/common/tunnel.ts
src/vs/platform/remote/common/tunnel.ts
+35
-10
src/vs/platform/remote/node/tunnelService.ts
src/vs/platform/remote/node/tunnelService.ts
+4
-10
src/vs/vscode.proposed.d.ts
src/vs/vscode.proposed.d.ts
+3
-0
src/vs/workbench/api/browser/mainThreadTunnelService.ts
src/vs/workbench/api/browser/mainThreadTunnelService.ts
+1
-0
src/vs/workbench/api/common/extHostTunnelService.ts
src/vs/workbench/api/common/extHostTunnelService.ts
+10
-2
src/vs/workbench/api/node/extHostTunnelService.ts
src/vs/workbench/api/node/extHostTunnelService.ts
+2
-1
src/vs/workbench/contrib/remote/browser/tunnelView.ts
src/vs/workbench/contrib/remote/browser/tunnelView.ts
+72
-4
src/vs/workbench/contrib/remote/common/tunnelFactory.ts
src/vs/workbench/contrib/remote/common/tunnelFactory.ts
+2
-1
src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts
src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts
+4
-3
src/vs/workbench/services/remote/browser/tunnelServiceImpl.ts
...vs/workbench/services/remote/browser/tunnelServiceImpl.ts
+3
-10
src/vs/workbench/services/remote/common/remoteExplorerService.ts
...workbench/services/remote/common/remoteExplorerService.ts
+26
-10
src/vs/workbench/workbench.web.api.ts
src/vs/workbench/workbench.web.api.ts
+4
-0
未找到文件。
src/vs/platform/remote/common/tunnel.ts
浏览文件 @
b4e4bd16
...
...
@@ -18,13 +18,15 @@ export interface RemoteTunnel {
readonly
tunnelRemoteHost
:
string
;
readonly
tunnelLocalPort
?:
number
;
readonly
localAddress
:
string
;
readonly
public
:
boolean
;
dispose
(
silent
?:
boolean
):
Promise
<
void
>
;
}
export
interface
TunnelOptions
{
remoteAddress
:
{
port
:
number
,
host
:
string
};
remoteAddress
:
{
port
:
number
,
host
:
string
;
};
localAddressPort
?:
number
;
label
?:
string
;
public
?:
boolean
;
}
export
interface
TunnelCreationOptions
{
...
...
@@ -33,6 +35,7 @@ export interface TunnelCreationOptions {
export
interface
TunnelProviderFeatures
{
elevation
:
boolean
;
public
:
boolean
;
}
export
interface
ITunnelProvider
{
...
...
@@ -43,17 +46,18 @@ export interface ITunnelService {
readonly
_serviceBrand
:
undefined
;
readonly
tunnels
:
Promise
<
readonly
RemoteTunnel
[]
>
;
readonly
canMakePublic
:
boolean
;
readonly
onTunnelOpened
:
Event
<
RemoteTunnel
>
;
readonly
onTunnelClosed
:
Event
<
{
host
:
string
,
port
:
number
}
>
;
readonly
onTunnelClosed
:
Event
<
{
host
:
string
,
port
:
number
;
}
>
;
readonly
canElevate
:
boolean
;
canTunnel
(
uri
:
URI
):
boolean
;
openTunnel
(
addressProvider
:
IAddressProvider
|
undefined
,
remoteHost
:
string
|
undefined
,
remotePort
:
number
,
localPort
?:
number
,
elevateIfNeeded
?:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
;
openTunnel
(
addressProvider
:
IAddressProvider
|
undefined
,
remoteHost
:
string
|
undefined
,
remotePort
:
number
,
localPort
?:
number
,
elevateIfNeeded
?:
boolean
,
isPublic
?:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
;
closeTunnel
(
remoteHost
:
string
,
remotePort
:
number
):
Promise
<
void
>
;
setTunnelProvider
(
provider
:
ITunnelProvider
|
undefined
,
features
:
TunnelProviderFeatures
):
IDisposable
;
}
export
function
extractLocalHostUriMetaDataForPortMapping
(
uri
:
URI
):
{
address
:
string
,
port
:
number
}
|
undefined
{
export
function
extractLocalHostUriMetaDataForPortMapping
(
uri
:
URI
):
{
address
:
string
,
port
:
number
;
}
|
undefined
{
if
(
uri
.
scheme
!==
'
http
'
&&
uri
.
scheme
!==
'
https
'
)
{
return
undefined
;
}
...
...
@@ -90,11 +94,12 @@ export abstract class AbstractTunnelService implements ITunnelService {
private
_onTunnelOpened
:
Emitter
<
RemoteTunnel
>
=
new
Emitter
();
public
onTunnelOpened
:
Event
<
RemoteTunnel
>
=
this
.
_onTunnelOpened
.
event
;
private
_onTunnelClosed
:
Emitter
<
{
host
:
string
,
port
:
number
}
>
=
new
Emitter
();
public
onTunnelClosed
:
Event
<
{
host
:
string
,
port
:
number
}
>
=
this
.
_onTunnelClosed
.
event
;
protected
readonly
_tunnels
=
new
Map
<
/*host*/
string
,
Map
<
/* port */
number
,
{
refcount
:
number
,
readonly
value
:
Promise
<
RemoteTunnel
|
undefined
>
}
>>
();
private
_onTunnelClosed
:
Emitter
<
{
host
:
string
,
port
:
number
;
}
>
=
new
Emitter
();
public
onTunnelClosed
:
Event
<
{
host
:
string
,
port
:
number
;
}
>
=
this
.
_onTunnelClosed
.
event
;
protected
readonly
_tunnels
=
new
Map
<
/*host*/
string
,
Map
<
/* port */
number
,
{
refcount
:
number
,
readonly
value
:
Promise
<
RemoteTunnel
|
undefined
>
;
}
>>
();
protected
_tunnelProvider
:
ITunnelProvider
|
undefined
;
protected
_canElevate
:
boolean
=
false
;
private
_canMakePublic
:
boolean
=
false
;
public
constructor
(
@
ILogService
protected
readonly
logService
:
ILogService
...
...
@@ -105,14 +110,18 @@ export abstract class AbstractTunnelService implements ITunnelService {
if
(
!
provider
)
{
// clear features
this
.
_canElevate
=
false
;
this
.
_canMakePublic
=
false
;
return
{
dispose
:
()
=>
{
}
};
}
this
.
_canElevate
=
features
.
elevation
;
this
.
_canMakePublic
=
features
.
public
;
return
{
dispose
:
()
=>
{
this
.
_tunnelProvider
=
undefined
;
this
.
_canElevate
=
false
;
this
.
_canMakePublic
=
false
;
}
};
}
...
...
@@ -121,6 +130,10 @@ export abstract class AbstractTunnelService implements ITunnelService {
return
this
.
_canElevate
;
}
public
get
canMakePublic
()
{
return
this
.
_canMakePublic
;
}
public
get
tunnels
():
Promise
<
readonly
RemoteTunnel
[]
>
{
return
new
Promise
(
async
(
resolve
)
=>
{
const
tunnels
:
RemoteTunnel
[]
=
[];
...
...
@@ -148,7 +161,7 @@ export abstract class AbstractTunnelService implements ITunnelService {
this
.
_tunnels
.
clear
();
}
openTunnel
(
addressProvider
:
IAddressProvider
|
undefined
,
remoteHost
:
string
|
undefined
,
remotePort
:
number
,
localPort
?:
number
,
elevateIfNeeded
:
boolean
=
false
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
{
openTunnel
(
addressProvider
:
IAddressProvider
|
undefined
,
remoteHost
:
string
|
undefined
,
remotePort
:
number
,
localPort
?:
number
,
elevateIfNeeded
:
boolean
=
false
,
isPublic
:
boolean
=
false
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
{
if
(
!
addressProvider
)
{
return
undefined
;
}
...
...
@@ -157,7 +170,7 @@ export abstract class AbstractTunnelService implements ITunnelService {
remoteHost
=
'
localhost
'
;
}
const
resolvedTunnel
=
this
.
retainOrCreateTunnel
(
addressProvider
,
remoteHost
,
remotePort
,
localPort
,
elevateIfNeeded
);
const
resolvedTunnel
=
this
.
retainOrCreateTunnel
(
addressProvider
,
remoteHost
,
remotePort
,
localPort
,
elevateIfNeeded
,
isPublic
);
if
(
!
resolvedTunnel
)
{
return
resolvedTunnel
;
}
...
...
@@ -182,6 +195,7 @@ export abstract class AbstractTunnelService implements ITunnelService {
tunnelRemoteHost
:
tunnel
.
tunnelRemoteHost
,
tunnelLocalPort
:
tunnel
.
tunnelLocalPort
,
localAddress
:
tunnel
.
localAddress
,
public
:
tunnel
.
public
,
dispose
:
async
()
=>
{
const
existingHost
=
this
.
_tunnels
.
get
(
tunnel
.
tunnelRemoteHost
);
if
(
existingHost
)
{
...
...
@@ -261,7 +275,18 @@ export abstract class AbstractTunnelService implements ITunnelService {
return
!!
extractLocalHostUriMetaDataForPortMapping
(
uri
);
}
protected
abstract
retainOrCreateTunnel
(
addressProvider
:
IAddressProvider
,
remoteHost
:
string
,
remotePort
:
number
,
localPort
:
number
|
undefined
,
elevateIfNeeded
:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
;
protected
abstract
retainOrCreateTunnel
(
addressProvider
:
IAddressProvider
,
remoteHost
:
string
,
remotePort
:
number
,
localPort
:
number
|
undefined
,
elevateIfNeeded
:
boolean
,
isPublic
:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
;
protected
createWithProvider
(
tunnelProvider
:
ITunnelProvider
,
remoteHost
:
string
,
remotePort
:
number
,
localPort
:
number
|
undefined
,
elevateIfNeeded
:
boolean
,
isPublic
:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
{
const
preferredLocalPort
=
localPort
===
undefined
?
remotePort
:
localPort
;
const
creationInfo
=
{
elevationRequired
:
elevateIfNeeded
?
isPortPrivileged
(
preferredLocalPort
)
:
false
};
const
tunnelOptions
:
TunnelOptions
=
{
remoteAddress
:
{
host
:
remoteHost
,
port
:
remotePort
},
localAddressPort
:
localPort
,
public
:
isPublic
};
const
tunnel
=
tunnelProvider
.
forwardPort
(
tunnelOptions
,
creationInfo
);
if
(
tunnel
)
{
this
.
addTunnelToMap
(
remoteHost
,
remotePort
,
tunnel
);
}
return
tunnel
;
}
}
src/vs/platform/remote/node/tunnelService.ts
浏览文件 @
b4e4bd16
...
...
@@ -11,7 +11,7 @@ import { NodeSocket } from 'vs/base/parts/ipc/node/ipc.net';
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
IProductService
}
from
'
vs/platform/product/common/productService
'
;
import
{
connectRemoteAgentTunnel
,
IConnectionOptions
,
IAddressProvider
,
ISocketFactory
}
from
'
vs/platform/remote/common/remoteAgentConnection
'
;
import
{
AbstractTunnelService
,
isPortPrivileged
,
RemoteTunnel
}
from
'
vs/platform/remote/common/tunnel
'
;
import
{
AbstractTunnelService
,
RemoteTunnel
}
from
'
vs/platform/remote/common/tunnel
'
;
import
{
nodeSocketFactory
}
from
'
vs/platform/remote/node/nodeSocketFactory
'
;
import
{
ISignService
}
from
'
vs/platform/sign/common/sign
'
;
...
...
@@ -26,6 +26,7 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel {
public
tunnelLocalPort
!
:
number
;
public
tunnelRemoteHost
:
string
;
public
localAddress
!
:
string
;
public
readonly
public
=
false
;
private
readonly
_options
:
IConnectionOptions
;
private
readonly
_server
:
net
.
Server
;
...
...
@@ -139,7 +140,7 @@ export class BaseTunnelService extends AbstractTunnelService {
super
(
logService
);
}
protected
retainOrCreateTunnel
(
addressProvider
:
IAddressProvider
,
remoteHost
:
string
,
remotePort
:
number
,
localPort
:
number
|
undefined
,
elevateIfNeeded
:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
{
protected
retainOrCreateTunnel
(
addressProvider
:
IAddressProvider
,
remoteHost
:
string
,
remotePort
:
number
,
localPort
:
number
|
undefined
,
elevateIfNeeded
:
boolean
,
isPublic
:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
{
const
existing
=
this
.
getTunnelFromMap
(
remoteHost
,
remotePort
);
if
(
existing
)
{
++
existing
.
refcount
;
...
...
@@ -147,14 +148,7 @@ export class BaseTunnelService extends AbstractTunnelService {
}
if
(
this
.
_tunnelProvider
)
{
const
preferredLocalPort
=
localPort
===
undefined
?
remotePort
:
localPort
;
const
creationInfo
=
{
elevationRequired
:
elevateIfNeeded
?
isPortPrivileged
(
preferredLocalPort
)
:
false
};
const
tunnelOptions
=
{
remoteAddress
:
{
host
:
remoteHost
,
port
:
remotePort
},
localAddressPort
:
localPort
};
const
tunnel
=
this
.
_tunnelProvider
.
forwardPort
(
tunnelOptions
,
creationInfo
);
if
(
tunnel
)
{
this
.
addTunnelToMap
(
remoteHost
,
remotePort
,
tunnel
);
}
return
tunnel
;
return
this
.
createWithProvider
(
this
.
_tunnelProvider
,
remoteHost
,
remotePort
,
localPort
,
elevateIfNeeded
,
isPublic
);
}
else
{
const
options
:
IConnectionOptions
=
{
commit
:
this
.
productService
.
commit
,
...
...
src/vs/vscode.proposed.d.ts
浏览文件 @
b4e4bd16
...
...
@@ -154,12 +154,14 @@ declare module 'vscode' {
// The desired local port. If this port can't be used, then another will be chosen.
localAddressPort
?:
number
;
label
?:
string
;
public
?:
boolean
;
}
export
interface
TunnelDescription
{
remoteAddress
:
{
port
:
number
,
host
:
string
;
};
//The complete local address(ex. localhost:1234)
localAddress
:
{
port
:
number
,
host
:
string
;
}
|
string
;
public
?:
boolean
;
}
export
interface
Tunnel
extends
TunnelDescription
{
...
...
@@ -221,6 +223,7 @@ declare module 'vscode' {
*/
tunnelFeatures
?:
{
elevation
:
boolean
;
public
:
boolean
;
};
}
...
...
src/vs/workbench/api/browser/mainThreadTunnelService.ts
浏览文件 @
b4e4bd16
...
...
@@ -66,6 +66,7 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
tunnelRemoteHost
:
tunnel
.
remoteAddress
.
host
,
localAddress
:
typeof
tunnel
.
localAddress
===
'
string
'
?
tunnel
.
localAddress
:
makeAddress
(
tunnel
.
localAddress
.
host
,
tunnel
.
localAddress
.
port
),
tunnelLocalPort
:
typeof
tunnel
.
localAddress
!==
'
string
'
?
tunnel
.
localAddress
.
port
:
undefined
,
public
:
tunnel
.
public
,
dispose
:
async
(
silent
?:
boolean
)
=>
{
return
this
.
_proxy
.
$closeTunnel
({
host
:
tunnel
.
remoteAddress
.
host
,
port
:
tunnel
.
remoteAddress
.
port
},
silent
);
}
...
...
src/vs/workbench/api/common/extHostTunnelService.ts
浏览文件 @
b4e4bd16
...
...
@@ -15,14 +15,22 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'
export
interface
TunnelDto
{
remoteAddress
:
{
port
:
number
,
host
:
string
};
localAddress
:
{
port
:
number
,
host
:
string
}
|
string
;
public
:
boolean
;
}
export
namespace
TunnelDto
{
export
function
fromApiTunnel
(
tunnel
:
vscode
.
Tunnel
):
TunnelDto
{
return
{
remoteAddress
:
tunnel
.
remoteAddress
,
localAddress
:
tunnel
.
localAddress
};
return
{
remoteAddress
:
tunnel
.
remoteAddress
,
localAddress
:
tunnel
.
localAddress
,
public
:
!!
tunnel
.
public
};
}
export
function
fromServiceTunnel
(
tunnel
:
RemoteTunnel
):
TunnelDto
{
return
{
remoteAddress
:
{
host
:
tunnel
.
tunnelRemoteHost
,
port
:
tunnel
.
tunnelRemotePort
},
localAddress
:
tunnel
.
localAddress
};
return
{
remoteAddress
:
{
host
:
tunnel
.
tunnelRemoteHost
,
port
:
tunnel
.
tunnelRemotePort
},
localAddress
:
tunnel
.
localAddress
,
public
:
tunnel
.
public
};
}
}
...
...
src/vs/workbench/api/node/extHostTunnelService.ts
浏览文件 @
b4e4bd16
...
...
@@ -196,7 +196,8 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
if
(
provider
.
tunnelFactory
)
{
this
.
_forwardPortProvider
=
provider
.
tunnelFactory
;
await
this
.
_proxy
.
$setTunnelProvider
(
provider
.
tunnelFeatures
??
{
elevation
:
false
elevation
:
false
,
public
:
false
});
}
}
else
{
...
...
src/vs/workbench/contrib/remote/browser/tunnelView.ts
浏览文件 @
b4e4bd16
...
...
@@ -26,7 +26,7 @@ import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
import
{
ActionRunner
,
IAction
}
from
'
vs/base/common/actions
'
;
import
{
IMenuService
,
MenuId
,
IMenu
,
MenuRegistry
,
MenuItemAction
,
ILocalizedString
,
SubmenuItemAction
,
Action2
,
registerAction2
}
from
'
vs/platform/actions/common/actions
'
;
import
{
createAndFillInContextMenuActions
,
createAndFillInActionBarActions
,
MenuEntryActionViewItem
,
SubmenuEntryActionViewItem
}
from
'
vs/platform/actions/browser/menuEntryActionViewItem
'
;
import
{
IRemoteExplorerService
,
TunnelModel
,
makeAddress
,
TunnelType
,
ITunnelItem
,
Tunnel
,
mapHasAddressLocalhostOrAllInterfaces
,
TUNNEL_VIEW_ID
,
parseAddress
,
CandidatePort
}
from
'
vs/workbench/services/remote/common/remoteExplorerService
'
;
import
{
IRemoteExplorerService
,
TunnelModel
,
makeAddress
,
TunnelType
,
ITunnelItem
,
Tunnel
,
mapHasAddressLocalhostOrAllInterfaces
,
TUNNEL_VIEW_ID
,
parseAddress
,
CandidatePort
,
TunnelPrivacy
}
from
'
vs/workbench/services/remote/common/remoteExplorerService
'
;
import
{
IClipboardService
}
from
'
vs/platform/clipboard/common/clipboardService
'
;
import
{
INotificationService
,
Severity
}
from
'
vs/platform/notification/common/notification
'
;
import
{
InputBox
,
MessageType
}
from
'
vs/base/browser/ui/inputbox/inputBox
'
;
...
...
@@ -410,7 +410,17 @@ interface ITunnelGroup {
class
TunnelItem
implements
ITunnelItem
{
static
createFromTunnel
(
tunnel
:
Tunnel
,
type
:
TunnelType
=
TunnelType
.
Forwarded
,
closeable
?:
boolean
)
{
return
new
TunnelItem
(
type
,
tunnel
.
remoteHost
,
tunnel
.
remotePort
,
tunnel
.
localAddress
,
tunnel
.
localPort
,
closeable
===
undefined
?
tunnel
.
closeable
:
closeable
,
tunnel
.
name
,
tunnel
.
runningProcess
,
tunnel
.
source
,
tunnel
.
pid
);
return
new
TunnelItem
(
type
,
tunnel
.
remoteHost
,
tunnel
.
remotePort
,
tunnel
.
localAddress
,
tunnel
.
localPort
,
closeable
===
undefined
?
tunnel
.
closeable
:
closeable
,
tunnel
.
name
,
tunnel
.
runningProcess
,
tunnel
.
source
,
tunnel
.
pid
,
tunnel
.
privacy
);
}
constructor
(
...
...
@@ -423,7 +433,8 @@ class TunnelItem implements ITunnelItem {
public
name
?:
string
,
private
runningProcess
?:
string
,
private
source
?:
string
,
private
pid
?:
number
private
pid
?:
number
,
public
privacy
?:
TunnelPrivacy
,
)
{
}
get
label
():
string
{
if
(
this
.
name
)
{
...
...
@@ -511,6 +522,7 @@ class TunnelItem implements ITunnelItem {
export
const
TunnelTypeContextKey
=
new
RawContextKey
<
TunnelType
>
(
'
tunnelType
'
,
TunnelType
.
Add
);
export
const
TunnelCloseableContextKey
=
new
RawContextKey
<
boolean
>
(
'
tunnelCloseable
'
,
false
);
const
TunnelPrivacyContextKey
=
new
RawContextKey
<
TunnelPrivacy
|
undefined
>
(
'
tunnelPrivacy
'
,
undefined
);
const
TunnelViewFocusContextKey
=
new
RawContextKey
<
boolean
>
(
'
tunnelViewFocus
'
,
false
);
const
TunnelViewSelectionKeyName
=
'
tunnelViewSelection
'
;
const
TunnelViewSelectionContextKey
=
new
RawContextKey
<
ITunnelItem
|
undefined
>
(
TunnelViewSelectionKeyName
,
undefined
);
...
...
@@ -524,6 +536,7 @@ export class TunnelPanel extends ViewPane {
private
tree
!
:
TunnelDataTree
;
private
tunnelTypeContext
:
IContextKey
<
TunnelType
>
;
private
tunnelCloseableContext
:
IContextKey
<
boolean
>
;
private
tunnelPrivacyContext
:
IContextKey
<
TunnelPrivacy
|
undefined
>
;
private
tunnelViewFocusContext
:
IContextKey
<
boolean
>
;
private
tunnelViewSelectionContext
:
IContextKey
<
ITunnelItem
|
undefined
>
;
private
portChangableContextKey
:
IContextKey
<
boolean
>
;
...
...
@@ -552,6 +565,7 @@ export class TunnelPanel extends ViewPane {
super
(
options
,
keybindingService
,
contextMenuService
,
configurationService
,
contextKeyService
,
viewDescriptorService
,
instantiationService
,
openerService
,
themeService
,
telemetryService
);
this
.
tunnelTypeContext
=
TunnelTypeContextKey
.
bindTo
(
contextKeyService
);
this
.
tunnelCloseableContext
=
TunnelCloseableContextKey
.
bindTo
(
contextKeyService
);
this
.
tunnelPrivacyContext
=
TunnelPrivacyContextKey
.
bindTo
(
contextKeyService
);
this
.
tunnelViewFocusContext
=
TunnelViewFocusContextKey
.
bindTo
(
contextKeyService
);
this
.
tunnelViewSelectionContext
=
TunnelViewSelectionContextKey
.
bindTo
(
contextKeyService
);
this
.
portChangableContextKey
=
PortChangableContextKey
.
bindTo
(
contextKeyService
);
...
...
@@ -679,11 +693,13 @@ export class TunnelPanel extends ViewPane {
this
.
tunnelViewSelectionContext
.
set
(
item
);
this
.
tunnelTypeContext
.
set
(
item
.
tunnelType
);
this
.
tunnelCloseableContext
.
set
(
!!
item
.
closeable
);
this
.
tunnelPrivacyContext
.
set
(
item
.
privacy
);
this
.
portChangableContextKey
.
set
(
!!
item
.
localPort
);
}
else
{
this
.
tunnelTypeContext
.
reset
();
this
.
tunnelViewSelectionContext
.
reset
();
this
.
tunnelCloseableContext
.
reset
();
this
.
tunnelPrivacyContext
.
reset
();
this
.
portChangableContextKey
.
reset
();
}
}
...
...
@@ -702,10 +718,12 @@ export class TunnelPanel extends ViewPane {
this
.
tree
!
.
setFocus
([
node
]);
this
.
tunnelTypeContext
.
set
(
node
.
tunnelType
);
this
.
tunnelCloseableContext
.
set
(
!!
node
.
closeable
);
this
.
tunnelPrivacyContext
.
set
(
node
.
privacy
);
this
.
portChangableContextKey
.
set
(
!!
node
.
localPort
);
}
else
{
this
.
tunnelTypeContext
.
set
(
TunnelType
.
Add
);
this
.
tunnelCloseableContext
.
set
(
false
);
this
.
tunnelPrivacyContext
.
set
(
undefined
);
this
.
portChangableContextKey
.
set
(
false
);
}
...
...
@@ -1073,6 +1091,36 @@ namespace ChangeLocalPortAction {
}
}
namespace
MakePortPublicAction
{
export
const
ID
=
'
remote.tunnel.makePublic
'
;
export
const
LABEL
=
nls
.
localize
(
'
remote.tunnel.makePublic
'
,
"
Make Public
"
);
export
function
handler
():
ICommandHandler
{
return
async
(
accessor
,
arg
)
=>
{
if
(
arg
instanceof
TunnelItem
)
{
const
remoteExplorerService
=
accessor
.
get
(
IRemoteExplorerService
);
await
remoteExplorerService
.
close
({
host
:
arg
.
remoteHost
,
port
:
arg
.
remotePort
});
return
remoteExplorerService
.
forward
({
host
:
arg
.
remoteHost
,
port
:
arg
.
remotePort
},
arg
.
localPort
,
arg
.
name
,
undefined
,
true
,
true
);
}
};
}
}
namespace
MakePortPrivateAction
{
export
const
ID
=
'
remote.tunnel.makePrivate
'
;
export
const
LABEL
=
nls
.
localize
(
'
remote.tunnel.makePrivate
'
,
"
Make Private
"
);
export
function
handler
():
ICommandHandler
{
return
async
(
accessor
,
arg
)
=>
{
if
(
arg
instanceof
TunnelItem
)
{
const
remoteExplorerService
=
accessor
.
get
(
IRemoteExplorerService
);
await
remoteExplorerService
.
close
({
host
:
arg
.
remoteHost
,
port
:
arg
.
remotePort
});
return
remoteExplorerService
.
forward
({
host
:
arg
.
remoteHost
,
port
:
arg
.
remotePort
},
arg
.
localPort
,
arg
.
name
,
undefined
,
true
,
false
);
}
};
}
}
const
tunnelViewCommandsWeightBonus
=
10
;
// give our commands a little bit more weight over other default list/tree commands
KeybindingsRegistry
.
registerCommandAndKeybindingRule
({
...
...
@@ -1110,6 +1158,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
});
CommandsRegistry
.
registerCommand
(
CopyAddressAction
.
COMMANDPALETTE_ID
,
CopyAddressAction
.
commandPaletteHandler
());
CommandsRegistry
.
registerCommand
(
ChangeLocalPortAction
.
ID
,
ChangeLocalPortAction
.
handler
());
CommandsRegistry
.
registerCommand
(
MakePortPublicAction
.
ID
,
MakePortPublicAction
.
handler
());
CommandsRegistry
.
registerCommand
(
MakePortPrivateAction
.
ID
,
MakePortPrivateAction
.
handler
());
MenuRegistry
.
appendMenuItem
(
MenuId
.
CommandPalette
,
({
command
:
{
...
...
@@ -1188,6 +1238,24 @@ MenuRegistry.appendMenuItem(MenuId.TunnelContext, ({
MenuRegistry
.
appendMenuItem
(
MenuId
.
TunnelContext
,
({
group
:
'
1_manage
'
,
order
:
0
,
command
:
{
id
:
MakePortPublicAction
.
ID
,
title
:
MakePortPublicAction
.
LABEL
,
},
when
:
TunnelPrivacyContextKey
.
isEqualTo
(
TunnelPrivacy
.
Private
)
}));
MenuRegistry
.
appendMenuItem
(
MenuId
.
TunnelContext
,
({
group
:
'
1_manage
'
,
order
:
0
,
command
:
{
id
:
MakePortPrivateAction
.
ID
,
title
:
MakePortPrivateAction
.
LABEL
,
},
when
:
TunnelPrivacyContextKey
.
isEqualTo
(
TunnelPrivacy
.
Public
)
}));
MenuRegistry
.
appendMenuItem
(
MenuId
.
TunnelContext
,
({
group
:
'
1_manage
'
,
order
:
1
,
command
:
{
id
:
ChangeLocalPortAction
.
ID
,
title
:
ChangeLocalPortAction
.
LABEL
,
...
...
@@ -1205,7 +1273,7 @@ MenuRegistry.appendMenuItem(MenuId.TunnelContext, ({
}));
MenuRegistry
.
appendMenuItem
(
MenuId
.
TunnelContext
,
({
group
:
'
1_manage
'
,
order
:
1
,
order
:
2
,
command
:
{
id
:
ClosePortAction
.
INLINE_ID
,
title
:
ClosePortAction
.
LABEL
,
...
...
src/vs/workbench/contrib/remote/common/tunnelFactory.ts
浏览文件 @
b4e4bd16
...
...
@@ -36,13 +36,14 @@ export class TunnelFactoryContribution extends Disposable implements IWorkbenchC
// The tunnel factory may give us an inaccessible local address.
// To make sure this doesn't happen, resolve the uri immediately.
localAddress
:
(
await
openerService
.
resolveExternalUri
(
URI
.
parse
(
localAddress
))).
resolved
.
toString
(),
public
:
!!
tunnel
.
public
,
dispose
:
async
()
=>
{
await
tunnel
.
dispose
;
}
};
resolve
(
remoteTunnel
);
});
});
}
},
environmentService
.
options
?.
tunnelProvider
?.
features
??
{
elevation
:
false
}));
},
environmentService
.
options
?.
tunnelProvider
?.
features
??
{
elevation
:
false
,
public
:
false
}));
remoteExplorerService
.
setTunnelInformation
(
undefined
);
}
}
...
...
src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts
浏览文件 @
b4e4bd16
...
...
@@ -31,7 +31,7 @@ import { IWebviewService, WebviewContentOptions, WebviewElement, WebviewExtensio
import
{
ITextFileService
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
import
{
AbstractTextFileService
}
from
'
vs/workbench/services/textfile/browser/textFileService
'
;
import
{
IExtensionManagementServer
,
IExtensionManagementServerService
}
from
'
vs/workbench/services/extensionManagement/common/extensionManagement
'
;
import
{
ITunnelProvider
,
ITunnelService
,
RemoteTunnel
}
from
'
vs/platform/remote/common/tunnel
'
;
import
{
ITunnelProvider
,
ITunnelService
,
RemoteTunnel
,
TunnelProviderFeatures
}
from
'
vs/platform/remote/common/tunnel
'
;
import
{
Disposable
,
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IManualSyncTask
,
IResourcePreview
,
ISyncResourceHandle
,
ISyncTask
,
IUserDataAutoSyncService
,
IUserDataSyncService
,
IUserDataSyncStore
,
IUserDataSyncStoreManagementService
,
SyncResource
,
SyncStatus
,
UserDataSyncStoreType
}
from
'
vs/platform/userDataSync/common/userDataSync
'
;
import
{
IUserDataSyncAccount
,
IUserDataSyncAccountService
}
from
'
vs/platform/userDataSync/common/userDataSyncAccount
'
;
...
...
@@ -560,14 +560,15 @@ class SimpleTunnelService implements ITunnelService {
tunnels
:
Promise
<
readonly
RemoteTunnel
[]
>
=
Promise
.
resolve
([]);
canElevate
:
boolean
=
false
;
canMakePublic
=
false
;
onTunnelOpened
=
Event
.
None
;
onTunnelClosed
=
Event
.
None
;
canTunnel
(
uri
:
URI
):
boolean
{
return
false
;
}
openTunnel
(
addressProvider
:
IAddressProvider
|
undefined
,
remoteHost
:
string
|
undefined
,
remotePort
:
number
,
localPort
?:
number
):
Promise
<
RemoteTunnel
>
|
undefined
{
return
undefined
;
}
async
changeTunnelPrivacy
(
remoteHost
:
string
,
remotePort
:
number
,
isPublic
:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
{
return
undefined
;
}
async
closeTunnel
(
remoteHost
:
string
,
remotePort
:
number
):
Promise
<
void
>
{
}
setTunnelProvider
(
provider
:
ITunnelProvider
|
undefined
):
IDisposable
{
return
Disposable
.
None
;
}
setTunnelProvider
(
provider
:
ITunnelProvider
|
undefined
,
features
:
TunnelProviderFeatures
):
IDisposable
{
return
Disposable
.
None
;
}
}
registerSingleton
(
ITunnelService
,
SimpleTunnelService
);
...
...
src/vs/workbench/services/remote/browser/tunnelServiceImpl.ts
浏览文件 @
b4e4bd16
...
...
@@ -6,7 +6,7 @@
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
IAddressProvider
}
from
'
vs/platform/remote/common/remoteAgentConnection
'
;
import
{
AbstractTunnelService
,
isPortPrivileged
,
RemoteTunnel
}
from
'
vs/platform/remote/common/tunnel
'
;
import
{
AbstractTunnelService
,
RemoteTunnel
}
from
'
vs/platform/remote/common/tunnel
'
;
import
{
IWorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/common/environmentService
'
;
export
class
TunnelService
extends
AbstractTunnelService
{
...
...
@@ -17,7 +17,7 @@ export class TunnelService extends AbstractTunnelService {
super
(
logService
);
}
protected
retainOrCreateTunnel
(
_addressProvider
:
IAddressProvider
,
remoteHost
:
string
,
remotePort
:
number
,
localPort
:
number
|
undefined
,
elevateIfNeeded
:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
{
protected
retainOrCreateTunnel
(
_addressProvider
:
IAddressProvider
,
remoteHost
:
string
,
remotePort
:
number
,
localPort
:
number
|
undefined
,
elevateIfNeeded
:
boolean
,
isPublic
:
boolean
):
Promise
<
RemoteTunnel
|
undefined
>
|
undefined
{
const
existing
=
this
.
getTunnelFromMap
(
remoteHost
,
remotePort
);
if
(
existing
)
{
++
existing
.
refcount
;
...
...
@@ -25,14 +25,7 @@ export class TunnelService extends AbstractTunnelService {
}
if
(
this
.
_tunnelProvider
)
{
const
preferredLocalPort
=
localPort
===
undefined
?
remotePort
:
localPort
;
const
tunnelOptions
=
{
remoteAddress
:
{
host
:
remoteHost
,
port
:
remotePort
},
localAddressPort
:
localPort
};
const
creationInfo
=
{
elevationRequired
:
elevateIfNeeded
?
isPortPrivileged
(
preferredLocalPort
)
:
false
};
const
tunnel
=
this
.
_tunnelProvider
.
forwardPort
(
tunnelOptions
,
creationInfo
);
if
(
tunnel
)
{
this
.
addTunnelToMap
(
remoteHost
,
remotePort
,
tunnel
);
}
return
tunnel
;
this
.
createWithProvider
(
this
.
_tunnelProvider
,
remoteHost
,
remotePort
,
localPort
,
elevateIfNeeded
,
isPublic
);
}
return
undefined
;
}
...
...
src/vs/workbench/services/remote/common/remoteExplorerService.ts
浏览文件 @
b4e4bd16
...
...
@@ -29,6 +29,12 @@ export enum TunnelType {
Add
=
'
Add
'
}
export
enum
TunnelPrivacy
{
ConstantPrivate
=
'
ConstantPrivate
'
,
// private, and changing is unsupported
Private
=
'
Private
'
,
Public
=
'
Public
'
}
export
interface
ITunnelItem
{
tunnelType
:
TunnelType
;
remoteHost
:
string
;
...
...
@@ -37,6 +43,7 @@ export interface ITunnelItem {
localPort
?:
number
;
name
?:
string
;
closeable
?:
boolean
;
privacy
?:
TunnelPrivacy
;
description
?:
string
;
wideDescription
?:
string
;
readonly
icon
?:
ThemeIcon
;
...
...
@@ -50,6 +57,7 @@ export interface Tunnel {
localPort
?:
number
;
name
?:
string
;
closeable
?:
boolean
;
privacy
:
TunnelPrivacy
;
runningProcess
:
string
|
undefined
;
pid
:
number
|
undefined
;
source
?:
string
;
...
...
@@ -252,7 +260,8 @@ export class TunnelModel extends Disposable {
localAddress
:
tunnel
.
localAddress
,
localPort
:
tunnel
.
tunnelLocalPort
,
runningProcess
:
matchingCandidate
?.
detail
,
pid
:
matchingCandidate
?.
pid
pid
:
matchingCandidate
?.
pid
,
privacy
:
this
.
makeTunnelPrivacy
(
tunnel
.
public
)
});
this
.
remoteTunnels
.
set
(
key
,
tunnel
);
}
...
...
@@ -271,7 +280,8 @@ export class TunnelModel extends Disposable {
localPort
:
tunnel
.
tunnelLocalPort
,
closeable
:
true
,
runningProcess
:
matchingCandidate
?.
detail
,
pid
:
matchingCandidate
?.
pid
pid
:
matchingCandidate
?.
pid
,
privacy
:
this
.
makeTunnelPrivacy
(
tunnel
.
public
)
});
}
this
.
storeForwarded
();
...
...
@@ -288,12 +298,16 @@ export class TunnelModel extends Disposable {
}));
}
private
makeTunnelPrivacy
(
isPublic
:
boolean
)
{
return
isPublic
?
TunnelPrivacy
.
Public
:
this
.
tunnelService
.
canMakePublic
?
TunnelPrivacy
.
Private
:
TunnelPrivacy
.
ConstantPrivate
;
}
async
restoreForwarded
()
{
if
(
this
.
configurationService
.
getValue
(
'
remote.restoreForwardedPorts
'
))
{
if
(
this
.
tunnelRestoreValue
)
{
(
<
Tunnel
[]
|
undefined
>
JSON
.
parse
(
this
.
tunnelRestoreValue
))?.
forEach
(
tunnel
=>
{
if
(
!
mapHasAddressLocalhostOrAllInterfaces
(
this
.
detected
,
tunnel
.
remoteHost
,
tunnel
.
remotePort
))
{
this
.
forward
({
host
:
tunnel
.
remoteHost
,
port
:
tunnel
.
remotePort
},
tunnel
.
localPort
,
tunnel
.
name
);
this
.
forward
({
host
:
tunnel
.
remoteHost
,
port
:
tunnel
.
remotePort
},
tunnel
.
localPort
,
tunnel
.
name
,
undefined
,
undefined
,
tunnel
.
privacy
===
TunnelPrivacy
.
Public
);
}
});
}
...
...
@@ -306,7 +320,7 @@ export class TunnelModel extends Disposable {
}
}
async
forward
(
remote
:
{
host
:
string
,
port
:
number
},
local
?:
number
,
name
?:
string
,
source
?:
string
,
elevateIfNeeded
?:
boolean
):
Promise
<
RemoteTunnel
|
void
>
{
async
forward
(
remote
:
{
host
:
string
,
port
:
number
},
local
?:
number
,
name
?:
string
,
source
?:
string
,
elevateIfNeeded
?:
boolean
,
isPublic
?:
boolean
):
Promise
<
RemoteTunnel
|
void
>
{
const
existingTunnel
=
mapHasAddressLocalhostOrAllInterfaces
(
this
.
forwarded
,
remote
.
host
,
remote
.
port
);
if
(
!
existingTunnel
)
{
const
authority
=
this
.
environmentService
.
remoteAuthority
;
...
...
@@ -316,7 +330,7 @@ export class TunnelModel extends Disposable {
const
attributes
=
this
.
portsAttributes
.
getAttributes
(
local
!==
undefined
?
local
:
remote
.
port
);
const
tunnel
=
await
this
.
tunnelService
.
openTunnel
(
addressProvider
,
remote
.
host
,
remote
.
port
,
local
,
(
!
elevateIfNeeded
)
?
attributes
?.
elevateIfNeeded
:
elevateIfNeeded
);
const
tunnel
=
await
this
.
tunnelService
.
openTunnel
(
addressProvider
,
remote
.
host
,
remote
.
port
,
local
,
(
!
elevateIfNeeded
)
?
attributes
?.
elevateIfNeeded
:
elevateIfNeeded
,
isPublic
);
if
(
tunnel
&&
tunnel
.
localAddress
)
{
const
matchingCandidate
=
mapHasAddressLocalhostOrAllInterfaces
(
this
.
_candidates
??
new
Map
(),
remote
.
host
,
remote
.
port
);
const
newForward
:
Tunnel
=
{
...
...
@@ -328,7 +342,8 @@ export class TunnelModel extends Disposable {
localAddress
:
tunnel
.
localAddress
,
runningProcess
:
matchingCandidate
?.
detail
,
pid
:
matchingCandidate
?.
pid
,
source
source
,
privacy
:
this
.
makeTunnelPrivacy
(
tunnel
.
public
)
};
const
key
=
makeAddress
(
remote
.
host
,
remote
.
port
);
this
.
forwarded
.
set
(
key
,
newForward
);
...
...
@@ -380,7 +395,8 @@ export class TunnelModel extends Disposable {
localAddress
:
typeof
tunnel
.
localAddress
===
'
string
'
?
tunnel
.
localAddress
:
makeAddress
(
tunnel
.
localAddress
.
host
,
tunnel
.
localAddress
.
port
),
closeable
:
false
,
runningProcess
:
matchingCandidate
?.
detail
,
pid
:
matchingCandidate
?.
pid
pid
:
matchingCandidate
?.
pid
,
privacy
:
TunnelPrivacy
.
ConstantPrivate
});
});
}
...
...
@@ -469,7 +485,7 @@ export interface IRemoteExplorerService {
onDidChangeEditable
:
Event
<
ITunnelItem
|
undefined
>
;
setEditable
(
tunnelItem
:
ITunnelItem
|
undefined
,
data
:
IEditableData
|
null
):
void
;
getEditableData
(
tunnelItem
:
ITunnelItem
|
undefined
):
IEditableData
|
undefined
;
forward
(
remote
:
{
host
:
string
,
port
:
number
},
localPort
?:
number
,
name
?:
string
,
source
?:
string
,
elevateIfNeeded
?:
boolean
):
Promise
<
RemoteTunnel
|
void
>
;
forward
(
remote
:
{
host
:
string
,
port
:
number
},
localPort
?:
number
,
name
?:
string
,
source
?:
string
,
elevateIfNeeded
?:
boolean
,
isPublic
?:
boolean
):
Promise
<
RemoteTunnel
|
void
>
;
close
(
remote
:
{
host
:
string
,
port
:
number
}):
Promise
<
void
>
;
setTunnelInformation
(
tunnelInformation
:
TunnelInformation
|
undefined
):
void
;
setCandidateFilter
(
filter
:
((
candidates
:
CandidatePort
[])
=>
Promise
<
CandidatePort
[]
>
)
|
undefined
):
IDisposable
;
...
...
@@ -522,8 +538,8 @@ class RemoteExplorerService implements IRemoteExplorerService {
return
this
.
_tunnelModel
;
}
forward
(
remote
:
{
host
:
string
,
port
:
number
},
local
?:
number
,
name
?:
string
,
source
?:
string
,
elevateIfNeeded
?:
boolean
):
Promise
<
RemoteTunnel
|
void
>
{
return
this
.
tunnelModel
.
forward
(
remote
,
local
,
name
,
source
,
elevateIfNeeded
);
forward
(
remote
:
{
host
:
string
,
port
:
number
},
local
?:
number
,
name
?:
string
,
source
?:
string
,
elevateIfNeeded
?:
boolean
,
isPublic
?:
boolean
):
Promise
<
RemoteTunnel
|
void
>
{
return
this
.
tunnelModel
.
forward
(
remote
,
local
,
name
,
source
,
elevateIfNeeded
,
isPublic
);
}
close
(
remote
:
{
host
:
string
,
port
:
number
}):
Promise
<
void
>
{
...
...
src/vs/workbench/workbench.web.api.ts
浏览文件 @
b4e4bd16
...
...
@@ -70,6 +70,8 @@ interface ITunnelOptions {
localAddressPort
?:
number
;
label
?:
string
;
public
?:
boolean
;
}
export
interface
TunnelCreationOptions
{
...
...
@@ -87,6 +89,8 @@ interface ITunnel {
*/
localAddress
:
string
;
public
?:
boolean
;
/**
* Implementers of Tunnel should fire onDidDispose when dispose is called.
*/
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录