Commit 29e00603 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Allow proxyURL to contain a path.

We now support or reasonable values for proxyURL, such as "http:"
or "/galene".
parent 6756e7f7
...@@ -78,7 +78,7 @@ The fields are as follows: ...@@ -78,7 +78,7 @@ The fields are as follows:
allowed. This is safe if the server is on the public Internet, but not allowed. This is safe if the server is on the public Internet, but not
necessarily so if it is on a private network. necessarily so if it is on a private network.
- `proxyURL`: if running behind a reverse proxy, this specifies the - `proxyURL`: if running behind a reverse proxy, this specifies the
address of the proxy. root URL that will be visible outside the proxy.
- `canonicalHost`: the canonical name of the host running the server; this - `canonicalHost`: the canonical name of the host running the server; this
will cause clients to be redirected if they use a different hostname to will cause clients to be redirected if they use a different hostname to
access the server. access the server.
......
...@@ -917,7 +917,6 @@ func GetConfiguration() (*Configuration, error) { ...@@ -917,7 +917,6 @@ func GetConfiguration() (*Configuration, error) {
return configuration.configuration, nil return configuration.configuration, nil
} }
// called locked // called locked
func (g *Group) getPasswordPermission(creds ClientCredentials) ([]string, error) { func (g *Group) getPasswordPermission(creds ClientCredentials) ([]string, error) {
desc := g.description desc := g.description
...@@ -1051,7 +1050,7 @@ type Status struct { ...@@ -1051,7 +1050,7 @@ type Status struct {
// Status returns a group's status. // Status returns a group's status.
// Base is the base URL for groups; if omitted, then both the Location and // Base is the base URL for groups; if omitted, then both the Location and
// Endpoint members are omitted from the result. // Endpoint members are omitted from the result.
func (g *Group) Status(authentified bool, base string) Status { func (g *Group) Status(authentified bool, base *url.URL) Status {
desc := g.Description() desc := g.Description()
if desc.Redirect != "" { if desc.Redirect != "" {
...@@ -1064,28 +1063,25 @@ func (g *Group) Status(authentified bool, base string) Status { ...@@ -1064,28 +1063,25 @@ func (g *Group) Status(authentified bool, base string) Status {
} }
var location, endpoint string var location, endpoint string
if base != "" { if base != nil {
burl, err := url.Parse(base) wss := "wss"
if err == nil { if base.Scheme == "http" {
wss := "wss" wss = "ws"
if burl.Scheme == "http" { }
wss = "ws" l := url.URL{
} Scheme: base.Scheme,
l := url.URL{ Host: base.Host,
Scheme: burl.Scheme, Path: path.Join(
Host: burl.Host, path.Join(base.Path, "/group/"),
Path: path.Join(burl.Path, g.name) + "/", g.Name()) + "/",
} }
location = l.String() location = l.String()
e := url.URL{ e := url.URL{
Scheme: wss, Scheme: wss,
Host: burl.Host, Host: base.Host,
Path: "/ws", Path: path.Join(base.Path, "/ws"),
}
endpoint = e.String()
} else {
log.Printf("Couldn't parse base URL %v", base)
} }
endpoint = e.String()
} }
d := Status{ d := Status{
...@@ -1108,7 +1104,7 @@ func (g *Group) Status(authentified bool, base string) Status { ...@@ -1108,7 +1104,7 @@ func (g *Group) Status(authentified bool, base string) Status {
return d return d
} }
func GetPublic(base string) []Status { func GetPublic(base *url.URL) []Status {
gs := make([]Status, 0) gs := make([]Status, 0)
Range(func(g *Group) bool { Range(func(g *Group) bool {
if g.Description().Public { if g.Description().Public {
......
...@@ -42,7 +42,7 @@ func TestGroup(t *testing.T) { ...@@ -42,7 +42,7 @@ func TestGroup(t *testing.T) {
t.Errorf("Expected [], got %v", subs) t.Errorf("Expected [], got %v", subs)
} }
if public := GetPublic(""); len(public) != 1 || public[0].Name != "group/subgroup" { if public := GetPublic(nil); len(public) != 1 || public[0].Name != "group/subgroup" {
t.Errorf("Expected group/subgroup, got %v", public) t.Errorf("Expected group/subgroup, got %v", public)
} }
} }
......
...@@ -1161,7 +1161,7 @@ func handleAction(c *webClient, a any) error { ...@@ -1161,7 +1161,7 @@ func handleAction(c *webClient, a any) error {
if a.group != "" { if a.group != "" {
g = group.Get(a.group) g = group.Get(a.group)
if g != nil { if g != nil {
s := g.Status(true, "") s := g.Status(true, nil)
status = &s status = &s
data = g.Data() data = g.Data()
} }
...@@ -1208,7 +1208,7 @@ func handleAction(c *webClient, a any) error { ...@@ -1208,7 +1208,7 @@ func handleAction(c *webClient, a any) error {
return errors.New("Permissions changed in no group") return errors.New("Permissions changed in no group")
} }
perms := append([]string(nil), c.permissions...) perms := append([]string(nil), c.permissions...)
status := g.Status(true, "") status := g.Status(true, nil)
username := c.username username := c.username
c.write(clientMessage{ c.write(clientMessage{
Type: "joined", Type: "joined",
......
...@@ -361,29 +361,44 @@ func groupHandler(w http.ResponseWriter, r *http.Request) { ...@@ -361,29 +361,44 @@ func groupHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
status := g.Status(false, "") status := g.Status(false, nil)
cspHeader(w, status.AuthServer) cspHeader(w, status.AuthServer)
serveFile(w, r, filepath.Join(StaticRoot, "galene.html")) serveFile(w, r, filepath.Join(StaticRoot, "galene.html"))
} }
func groupBase(r *http.Request) (string, error) { func baseURL(r *http.Request) (*url.URL, error) {
conf, err := group.GetConfiguration() conf, err := group.GetConfiguration()
if err != nil { if err != nil {
return "", err return nil, err
} }
var pu *url.URL
if conf.ProxyURL != "" { if conf.ProxyURL != "" {
return url.JoinPath(conf.ProxyURL, "/group/") pu, err = url.Parse(conf.ProxyURL)
if err != nil {
return nil, err
}
} }
scheme := "https" scheme := "https"
if r.TLS == nil { if r.TLS == nil {
scheme = "http" scheme = "http"
} }
host := r.Host
path := ""
if pu != nil {
if pu.Scheme != "" {
scheme = pu.Scheme
}
if pu.Host != "" {
host = pu.Host
}
path = pu.Path
}
base := url.URL{ base := url.URL{
Scheme: scheme, Scheme: scheme,
Host: r.Host, Host: host,
Path: "/group/", Path: path,
} }
return base.String(), nil return &base, nil
} }
func groupStatusHandler(w http.ResponseWriter, r *http.Request) { func groupStatusHandler(w http.ResponseWriter, r *http.Request) {
...@@ -404,9 +419,11 @@ func groupStatusHandler(w http.ResponseWriter, r *http.Request) { ...@@ -404,9 +419,11 @@ func groupStatusHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
base, err := groupBase(r) base, err := baseURL(r)
if err != nil { if err != nil {
httpError(w, err) log.Printf("Parse ProxyURL: %v", err)
http.Error(w, "Internal server error",
http.StatusInternalServerError)
return return
} }
d := g.Status(false, base) d := g.Status(false, base)
...@@ -422,7 +439,7 @@ func groupStatusHandler(w http.ResponseWriter, r *http.Request) { ...@@ -422,7 +439,7 @@ func groupStatusHandler(w http.ResponseWriter, r *http.Request) {
} }
func publicHandler(w http.ResponseWriter, r *http.Request) { func publicHandler(w http.ResponseWriter, r *http.Request) {
base, err := groupBase(r) base, err := baseURL(r)
if err != nil { if err != nil {
log.Printf("couldn't determine group base: %v", err) log.Printf("couldn't determine group base: %v", err)
httpError(w, err) httpError(w, err)
......
...@@ -42,12 +42,18 @@ func TestBase(t *testing.T) { ...@@ -42,12 +42,18 @@ func TestBase(t *testing.T) {
t bool t bool
h, res string h, res string
}{ }{
{"", true, "a.org", "https://a.org/group/"}, {"", true, "a.org", "https://a.org"},
{"", false, "a.org", "http://a.org/group/"}, {"", false, "a.org", "http://a.org"},
{"https://b.org", true, "a.org", "https://b.org/group/"}, {"/base", true, "a.org", "https://a.org/base"},
{"https://b.org", false, "a.org", "https://b.org/group/"}, {"/base", false, "a.org", "http://a.org/base"},
{"http://b.org", true, "a.org", "http://b.org/group/"}, {"http:", true, "a.org", "http://a.org"},
{"http://b.org", false, "a.org", "http://b.org/group/"}, {"https:", false, "a.org", "https://a.org"},
{"http:/base", true, "a.org", "http://a.org/base"},
{"https:/base", false, "a.org", "https://a.org/base"},
{"https://b.org", true, "a.org", "https://b.org"},
{"https://b.org", false, "a.org", "https://b.org"},
{"http://b.org", true, "a.org", "http://b.org"},
{"http://b.org", false, "a.org", "http://b.org"},
} }
dir := t.TempDir() dir := t.TempDir()
...@@ -75,13 +81,13 @@ func TestBase(t *testing.T) { ...@@ -75,13 +81,13 @@ func TestBase(t *testing.T) {
if v.t { if v.t {
tcs = &tls.ConnectionState{} tcs = &tls.ConnectionState{}
} }
base, err := groupBase(&http.Request{ base, err := baseURL(&http.Request{
TLS: tcs, TLS: tcs,
Host: v.h, Host: v.h,
}) })
if err != nil || base != v.res { if err != nil || base.String() != v.res {
t.Errorf("Expected %v, got %v (%v)", t.Errorf("Expected %v, got %v (%v)",
v.res, base, err, v.res, base.String(), err,
) )
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment