Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita7e5bd6

Browse files
committed
Add basic router for applications using same codepath
1 parent35ee5d6 commita7e5bd6

File tree

3 files changed

+119
-46
lines changed

3 files changed

+119
-46
lines changed

‎coderd/subdomain.go‎

Lines changed: 67 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
package coderd
22

33
import (
4+
"database/sql"
45
"fmt"
56
"net/http"
67
"regexp"
78
"strings"
89

10+
"github.com/coder/coder/coderd/httpapi"
11+
"github.com/coder/coder/codersdk"
12+
13+
"github.com/coder/coder/coderd/database"
14+
915
"golang.org/x/xerrors"
1016
)
1117

@@ -17,20 +23,66 @@ const (
1723
)
1824

1925
typeApplicationstruct {
20-
AppURLstring
21-
AppNamestring
22-
Workspacestring
23-
Agentstring
24-
Userstring
25-
Pathstring
26+
AppURLstring
27+
AppNamestring
28+
WorkspaceNamestring
29+
Agentstring
30+
Usernamestring
31+
Pathstring
2632

2733
// Domain is used to output the url to reach the app.
2834
Domainstring
2935
}
3036

3137
func (api*API)handleSubdomain(next http.Handler) http.Handler {
32-
returnhttp.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {
33-
38+
returnhttp.HandlerFunc(func(rw http.ResponseWriter,r*http.Request) {
39+
ctx:=r.Context()
40+
app,err:=ParseSubdomainAppURL(r)
41+
iferr!=nil {
42+
// Not a Dev URL, proceed as usual.
43+
// TODO: @emyrk we should probably catch invalid subdomains. Meaning
44+
// an invalid devurl should not route to the coderd.
45+
next.ServeHTTP(rw,r)
46+
return
47+
}
48+
49+
user,err:=api.Database.GetUserByEmailOrUsername(ctx, database.GetUserByEmailOrUsernameParams{
50+
Username:app.Username,
51+
})
52+
iferr!=nil {
53+
ifxerrors.Is(err,sql.ErrNoRows) {
54+
httpapi.ResourceNotFound(rw)
55+
return
56+
}
57+
httpapi.Write(rw,http.StatusInternalServerError, codersdk.Response{
58+
Message:"Internal error fetching user.",
59+
Detail:err.Error(),
60+
})
61+
return
62+
}
63+
64+
workspace,err:=api.Database.GetWorkspaceByOwnerIDAndName(ctx, database.GetWorkspaceByOwnerIDAndNameParams{
65+
OwnerID:user.ID,
66+
Name:app.WorkspaceName,
67+
})
68+
iferr!=nil {
69+
ifxerrors.Is(err,sql.ErrNoRows) {
70+
httpapi.ResourceNotFound(rw)
71+
return
72+
}
73+
httpapi.Write(rw,http.StatusInternalServerError, codersdk.Response{
74+
Message:"Internal error fetching workspace.",
75+
Detail:err.Error(),
76+
})
77+
return
78+
}
79+
80+
api.proxyWorkspaceApplication(proxyApplication{
81+
Workspace:workspace,
82+
// TODO: Fetch workspace agent
83+
Agent: database.WorkspaceAgent{},
84+
AppName:app.AppName,
85+
},rw,r)
3486
})
3587
}
3688

@@ -64,13 +116,13 @@ func ParseSubdomainAppURL(r *http.Request) (Application, error) {
64116
matchGroup:=matches[0]
65117

66118
returnApplication{
67-
AppURL:"",
68-
AppName:matchGroup[appURL.SubexpIndex("AppName")],
69-
Workspace:matchGroup[appURL.SubexpIndex("WorkspaceName")],
70-
Agent:matchGroup[appURL.SubexpIndex("AgentName")],
71-
User:matchGroup[appURL.SubexpIndex("UserName")],
72-
Path:r.URL.Path,
73-
Domain:domain,
119+
AppURL:"",
120+
AppName:matchGroup[appURL.SubexpIndex("AppName")],
121+
WorkspaceName:matchGroup[appURL.SubexpIndex("WorkspaceName")],
122+
Agent:matchGroup[appURL.SubexpIndex("AgentName")],
123+
Username:matchGroup[appURL.SubexpIndex("UserName")],
124+
Path:r.URL.Path,
125+
Domain:domain,
74126
},nil
75127
}
76128

‎coderd/subdomain_test.go‎

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,52 +40,52 @@ func TestParseSubdomainAppURL(t *testing.T) {
4040
Name:"User+Workspace+App",
4141
URL:"https://user--workspace--app.coder.com",
4242
Expected: coderd.Application{
43-
AppURL:"",
44-
AppName:"app",
45-
Workspace:"workspace",
46-
Agent:"",
47-
User:"user",
48-
Path:"",
49-
Domain:"coder.com",
43+
AppURL:"",
44+
AppName:"app",
45+
WorkspaceName:"workspace",
46+
Agent:"",
47+
User:"user",
48+
Path:"",
49+
Domain:"coder.com",
5050
},
5151
},
5252
{
5353
Name:"User+Workspace+Port",
5454
URL:"https://user--workspace--8080.coder.com",
5555
Expected: coderd.Application{
56-
AppURL:"",
57-
AppName:"8080",
58-
Workspace:"workspace",
59-
Agent:"",
60-
User:"user",
61-
Path:"",
62-
Domain:"coder.com",
56+
AppURL:"",
57+
AppName:"8080",
58+
WorkspaceName:"workspace",
59+
Agent:"",
60+
User:"user",
61+
Path:"",
62+
Domain:"coder.com",
6363
},
6464
},
6565
{
6666
Name:"User+Workspace.Agent+App",
6767
URL:"https://user--workspace--agent--app.coder.com",
6868
Expected: coderd.Application{
69-
AppURL:"",
70-
AppName:"app",
71-
Workspace:"workspace",
72-
Agent:"agent",
73-
User:"user",
74-
Path:"",
75-
Domain:"coder.com",
69+
AppURL:"",
70+
AppName:"app",
71+
WorkspaceName:"workspace",
72+
Agent:"agent",
73+
User:"user",
74+
Path:"",
75+
Domain:"coder.com",
7676
},
7777
},
7878
{
7979
Name:"User+Workspace.Agent+Port",
8080
URL:"https://user--workspace--agent--8080.coder.com",
8181
Expected: coderd.Application{
82-
AppURL:"",
83-
AppName:"8080",
84-
Workspace:"workspace",
85-
Agent:"agent",
86-
User:"user",
87-
Path:"",
88-
Domain:"coder.com",
82+
AppURL:"",
83+
AppName:"8080",
84+
WorkspaceName:"workspace",
85+
Agent:"agent",
86+
User:"user",
87+
Path:"",
88+
Domain:"coder.com",
8989
},
9090
},
9191
}

‎coderd/workspaceapps.go‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,30 @@ func (api *API) workspaceAppsProxyPath(rw http.ResponseWriter, r *http.Request)
9696
}
9797
}
9898

99+
api.proxyWorkspaceApplication(proxyApplication{
100+
Workspace:workspace,
101+
Agent:agent,
102+
AppName:chi.URLParam(r,"workspaceapp"),
103+
},rw,r)
104+
}
105+
106+
// proxyApplication are the required fields to proxy a workspace application.
107+
typeproxyApplicationstruct {
108+
Workspace database.Workspace
109+
Agent database.WorkspaceAgent
110+
111+
AppNamestring
112+
}
113+
114+
func (api*API)proxyWorkspaceApplication(proxyAppproxyApplication,rw http.ResponseWriter,r*http.Request) {
115+
if!api.Authorize(r,rbac.ActionCreate,proxyApp.Workspace.ExecutionRBAC()) {
116+
httpapi.ResourceNotFound(rw)
117+
return
118+
}
119+
99120
app,err:=api.Database.GetWorkspaceAppByAgentIDAndName(r.Context(), database.GetWorkspaceAppByAgentIDAndNameParams{
100-
AgentID:agent.ID,
101-
Name:chi.URLParam(r,"workspaceapp"),
121+
AgentID:proxyApp.Agent.ID,
122+
Name:proxyApp.AppName,
102123
})
103124
iferrors.Is(err,sql.ErrNoRows) {
104125
httpapi.Write(rw,http.StatusNotFound, codersdk.Response{
@@ -161,7 +182,7 @@ func (api *API) workspaceAppsProxyPath(rw http.ResponseWriter, r *http.Request)
161182
}
162183
r.URL.Path=path
163184

164-
conn,release,err:=api.workspaceAgentCache.Acquire(r,agent.ID)
185+
conn,release,err:=api.workspaceAgentCache.Acquire(r,proxyApp.Agent.ID)
165186
iferr!=nil {
166187
httpapi.Write(rw,http.StatusInternalServerError, codersdk.Response{
167188
Message:"Failed to dial workspace agent.",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp