@@ -376,12 +376,12 @@ func (api *API) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) {
376
376
})
377
377
return
378
378
}
379
- defer func () {
380
- _ = conn .Close (websocket .StatusNormalClosure ,"ended" )
381
- }()
379
+
382
380
// Accept text connections, because it's more developer friendly.
383
- wsNetConn := websocket .NetConn (r .Context (),conn ,websocket .MessageBinary )
384
- agentConn ,err := api .dialWorkspaceAgent (r ,workspaceAgent .ID )
381
+ ctx ,wsNetConn := websocketNetConn (r .Context (),conn ,websocket .MessageBinary )
382
+ defer wsNetConn .Close ()// Also closes conn.
383
+
384
+ agentConn ,err := api .dialWorkspaceAgent (ctx ,r ,workspaceAgent .ID )
385
385
if err != nil {
386
386
_ = conn .Close (websocket .StatusInternalError ,httpapi .WebsocketCloseSprintf ("dial workspace agent: %s" ,err ))
387
387
return
@@ -400,11 +400,13 @@ func (api *API) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) {
400
400
_ ,_ = io .Copy (ptNetConn ,wsNetConn )
401
401
}
402
402
403
- // dialWorkspaceAgent connects to a workspace agent by ID.
404
- func (api * API )dialWorkspaceAgent (r * http.Request ,agentID uuid.UUID ) (* agent.Conn ,error ) {
403
+ // dialWorkspaceAgent connects to a workspace agent by ID. Only rely on
404
+ // r.Context() for cancellation if it's use is safe or r.Hijack() has
405
+ // not been performed.
406
+ func (api * API )dialWorkspaceAgent (ctx context.Context ,r * http.Request ,agentID uuid.UUID ) (* agent.Conn ,error ) {
405
407
client ,server := provisionersdk .TransportPipe ()
406
408
go func () {
407
- _ = peerbroker .ProxyListen (r . Context () ,server , peerbroker.ProxyOptions {
409
+ _ = peerbroker .ProxyListen (ctx ,server , peerbroker.ProxyOptions {
408
410
ChannelID :agentID .String (),
409
411
Logger :api .Logger .Named ("peerbroker-proxy-dial" ),
410
412
Pubsub :api .Pubsub ,
@@ -414,7 +416,7 @@ func (api *API) dialWorkspaceAgent(r *http.Request, agentID uuid.UUID) (*agent.C
414
416
}()
415
417
416
418
peerClient := proto .NewDRPCPeerBrokerClient (provisionersdk .Conn (client ))
417
- stream ,err := peerClient .NegotiateConnection (r . Context () )
419
+ stream ,err := peerClient .NegotiateConnection (ctx )
418
420
if err != nil {
419
421
return nil ,xerrors .Errorf ("negotiate: %w" ,err )
420
422
}
@@ -426,7 +428,7 @@ func (api *API) dialWorkspaceAgent(r *http.Request, agentID uuid.UUID) (*agent.C
426
428
options .SettingEngine .SetICEProxyDialer (turnconn .ProxyDialer (func () (c net.Conn ,err error ) {
427
429
clientPipe ,serverPipe := net .Pipe ()
428
430
go func () {
429
- <- r . Context () .Done ()
431
+ <- ctx .Done ()
430
432
_ = clientPipe .Close ()
431
433
_ = serverPipe .Close ()
432
434
}()