@@ -35,7 +35,7 @@ import (
35
35
//
36
36
// The VS Code extension is located at https://github.com/coder/vscode-coder. The
37
37
// extension downloads the slim binary from `/bin/*` and executes `coder vscodeipc`
38
- // which calls this function. This API must maintain backawards compatibility with
38
+ // which calls this function. This API must maintain backward compatibility with
39
39
// the extension to support prior versions of Coder.
40
40
func New (ctx context.Context , client * codersdk.Client , agentID uuid.UUID , options * codersdk.DialWorkspaceAgentOptions ) (http.Handler , io.Closer , error ) {
41
41
if options == nil {
@@ -54,28 +54,12 @@ func New(ctx context.Context, client *codersdk.Client, agentID uuid.UUID, option
54
54
r := chi .NewRouter ()
55
55
// This is to prevent unauthorized clients on the same machine from executing
56
56
// requests on behalf of the workspace.
57
- r .Use (func (h http.Handler ) http.Handler {
58
- return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
59
- token := r .Header .Get ("Coder-Session-Token" )
60
- if token == "" {
61
- httpapi .Write (r .Context (), w , http .StatusUnauthorized , codersdk.Response {
62
- Message : "A session token must be provided in the `Coder-Session-Token` header." ,
63
- })
64
- return
65
- }
66
- if token != client .SessionToken () {
67
- httpapi .Write (r .Context (), w , http .StatusUnauthorized , codersdk.Response {
68
- Message : "The session token provided doesn't match the one used to create the client." ,
69
- })
70
- return
71
- }
72
- w .Header ().Set ("Access-Control-Allow-Origin" , "*" )
73
- h .ServeHTTP (w , r )
74
- })
57
+ r .Use (sessionTokenMiddleware (client .SessionToken ()))
58
+ r .Route ("/v1" , func (r chi.Router ) {
59
+ r .Get ("/port/{port}" , api .port )
60
+ r .Get ("/network" , api .network )
61
+ r .Post ("/execute" , api .execute )
75
62
})
76
- r .Get ("/port/{port}" , api .port )
77
- r .Get ("/network" , api .network )
78
- r .Post ("/execute" , api .execute )
79
63
return r , api , nil
80
64
}
81
65
@@ -137,9 +121,9 @@ func (api *api) port(w http.ResponseWriter, r *http.Request) {
137
121
httpapi .InternalServerError (w , err )
138
122
return
139
123
}
124
+ defer localConn .Close ()
140
125
141
126
_ = brw .Flush ()
142
- defer localConn .Close ()
143
127
agent .Bicopy (r .Context (), localConn , remoteConn )
144
128
}
145
129
@@ -222,6 +206,9 @@ func (api *api) execute(w http.ResponseWriter, r *http.Request) {
222
206
api .sshClientOnce .Do (func () {
223
207
// The SSH client is lazily created because it's not needed for
224
208
// all requests. It's only needed for the execute endpoint.
209
+ //
210
+ // It's alright if this fails on the first execution, because
211
+ // a new instance of this API is created for each remote SSH request.
225
212
api .sshClient , api .sshClientErr = api .agentConn .SSHClient (context .Background ())
226
213
})
227
214
if api .sshClientErr != nil {
@@ -292,7 +279,32 @@ func (e *execWriter) Write(data []byte) (int, error) {
292
279
if err != nil {
293
280
return 0 , err
294
281
}
295
- _ , _ = e .w .Write (js )
282
+ _ , err = e .w .Write (js )
283
+ if err != nil {
284
+ return 0 , err
285
+ }
296
286
e .f .Flush ()
297
287
return len (data ), nil
298
288
}
289
+
290
+ func sessionTokenMiddleware (sessionToken string ) func (h http.Handler ) http.Handler {
291
+ return func (h http.Handler ) http.Handler {
292
+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
293
+ token := r .Header .Get ("Coder-IPC-Token" )
294
+ if token == "" {
295
+ httpapi .Write (r .Context (), w , http .StatusUnauthorized , codersdk.Response {
296
+ Message : "A session token must be provided in the `Coder-IPC-Token` header." ,
297
+ })
298
+ return
299
+ }
300
+ if token != sessionToken {
301
+ httpapi .Write (r .Context (), w , http .StatusUnauthorized , codersdk.Response {
302
+ Message : "The session token provided doesn't match the one used to create the client." ,
303
+ })
304
+ return
305
+ }
306
+ w .Header ().Set ("Access-Control-Allow-Origin" , "*" )
307
+ h .ServeHTTP (w , r )
308
+ })
309
+ }
310
+ }
0 commit comments