Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
galene
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
galene
Commits
b55e531a
Commit
b55e531a
authored
Sep 01, 2022
by
Juliusz Chroboczek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Encode group location in the status.json file.
parent
4bc873a5
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
67 additions
and
34 deletions
+67
-34
README.PROTOCOL
README.PROTOCOL
+18
-16
group/group.go
group/group.go
+34
-3
group/group_test.go
group/group_test.go
+1
-1
static/mainpage.js
static/mainpage.js
+1
-1
webserver/webserver.go
webserver/webserver.go
+13
-13
No files found.
README.PROTOCOL
View file @
b55e531a
...
...
@@ -28,31 +28,33 @@ server to client direction.
## Before connecting
Before it connects and joins a group, a client may perform an HTTP GET
request on the URL `/public-groups.json`. This yields a JSON array of
objects, one for each group that has been marked public in its
configuration file. Each object has the following fields:
The client needs to know the location of the group, the (user-visible) URL
at which the group is found. This may be obtained either by explicit
configuration by the user, or by parsing the `/public-groups.json` file
which may contain an array of group statuses (see below).
A client then performs an HTTP GET request on the file `.status.json` at
the group's location. This yields a single JSON object, which contains
the following fields:
- `name`: the group's name
- `displayName` (optional): a longer version of the name used for display;
- `description` (optional): a user-readable description.
- `location`: the group's location
- `endpoint`: the URL of the server's WebSocket endpoint
- `displayName`: a longer version of the name used for display;
- `description`: a user-readable description;
- `authServer`: the URL of the authentication server, if any;
- `authPortal`: the uRL of the authentication portal, if any;
- `locked`: true if the group is locked;
- `clientCount`: the number of clients currently in the group.
If token-based authorisation is in use for the group, then the dictionary
contains the following additional field:
- `authServer`: the URL of the authorisation server.
All fields are optional except `name`, `location` and `endpoint`.
A client may also fetch the URL `/group/name/.status.json` to retrieve the
status of a single group. If the group has not been marked as public,
then the fields `locked` and `clientCount` are omitted.
## Connecting
The client connects to the websocket at
`/ws`. Galene uses a symmetric,
asynchronous protocol: there are no requests and responses, and most
messages may be sent by either peer.
The client connects to the websocket at
the URL obtained at the previous
step. Galene uses a symmetric, asynchronous protocol: there are no
requests and responses, and most
messages may be sent by either peer.
## Message syntax
...
...
group/group.go
View file @
b55e531a
...
...
@@ -1177,6 +1177,7 @@ func (desc *Description) GetPermission(group string, creds ClientCredentials) (s
type
Status
struct
{
Name
string
`json:"name"`
Location
string
`json:"location"`
Endpoint
string
`json:"endpoint"`
DisplayName
string
`json:"displayName,omitempty"`
Description
string
`json:"description,omitempty"`
...
...
@@ -1186,10 +1187,40 @@ type Status struct {
ClientCount
*
int
`json:"clientCount,omitempty"`
}
func
(
g
*
Group
)
Status
(
authentified
bool
,
endpoint
string
)
Status
{
// Status returns a group's status.
// Base is the base URL for groups; if omitted, then both the Location and
// Endpoint members are omitted from the result.
func
(
g
*
Group
)
Status
(
authentified
bool
,
base
string
)
Status
{
desc
:=
g
.
Description
()
var
location
,
endpoint
string
if
base
!=
""
{
burl
,
err
:=
url
.
Parse
(
base
)
if
err
==
nil
{
wss
:=
"wss"
if
burl
.
Scheme
==
"http"
{
wss
=
"ws"
}
l
:=
url
.
URL
{
Scheme
:
burl
.
Scheme
,
Host
:
burl
.
Host
,
Path
:
path
.
Join
(
burl
.
Path
,
g
.
name
)
+
"/"
,
}
location
=
l
.
String
()
e
:=
url
.
URL
{
Scheme
:
wss
,
Host
:
burl
.
Host
,
Path
:
"/ws"
,
}
endpoint
=
e
.
String
()
}
else
{
log
.
Printf
(
"Couldn't parse base URL %v"
,
base
)
}
}
d
:=
Status
{
Name
:
g
.
name
,
Location
:
location
,
Endpoint
:
endpoint
,
DisplayName
:
desc
.
DisplayName
,
AuthServer
:
desc
.
AuthServer
,
...
...
@@ -1207,11 +1238,11 @@ func (g *Group) Status(authentified bool, endpoint string) Status {
return
d
}
func
GetPublic
()
[]
Status
{
func
GetPublic
(
base
string
)
[]
Status
{
gs
:=
make
([]
Status
,
0
)
Range
(
func
(
g
*
Group
)
bool
{
if
g
.
Description
()
.
Public
{
gs
=
append
(
gs
,
g
.
Status
(
false
,
""
))
gs
=
append
(
gs
,
g
.
Status
(
false
,
base
))
}
return
true
})
...
...
group/group_test.go
View file @
b55e531a
...
...
@@ -42,7 +42,7 @@ func TestGroup(t *testing.T) {
t
.
Errorf
(
"Expected [], got %v"
,
subs
)
}
if
public
:=
GetPublic
();
len
(
public
)
!=
1
||
public
[
0
]
.
Name
!=
"group/subgroup"
{
if
public
:=
GetPublic
(
""
);
len
(
public
)
!=
1
||
public
[
0
]
.
Name
!=
"group/subgroup"
{
t
.
Errorf
(
"Expected group/subgroup, got %v"
,
public
)
}
}
...
...
static/mainpage.js
View file @
b55e531a
...
...
@@ -110,7 +110,7 @@ async function listPublicGroups() {
let
td
=
document
.
createElement
(
'
td
'
);
let
a
=
document
.
createElement
(
'
a
'
);
a
.
textContent
=
group
.
displayName
||
group
.
name
;
a
.
href
=
'
/group/
'
+
group
.
name
+
'
/
'
;
a
.
href
=
group
.
location
;
td
.
appendChild
(
a
);
tr
.
appendChild
(
td
);
let
td2
=
document
.
createElement
(
'
td
'
);
...
...
webserver/webserver.go
View file @
b55e531a
...
...
@@ -332,9 +332,18 @@ func groupHandler(w http.ResponseWriter, r *http.Request) {
serveFile
(
w
,
r
,
filepath
.
Join
(
StaticRoot
,
"galene.html"
))
}
func
groupBase
(
r
*
http
.
Request
)
string
{
base
:=
url
.
URL
{
Scheme
:
r
.
URL
.
Scheme
,
Host
:
r
.
Host
,
Path
:
"/group/"
,
}
return
base
.
String
()
}
func
groupStatusHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
p
a
th
:=
path
.
Dir
(
r
.
URL
.
Path
)
name
:=
parseGroupName
(
"/group/"
,
p
a
th
)
pth
:=
path
.
Dir
(
r
.
URL
.
Path
)
name
:=
parseGroupName
(
"/group/"
,
pth
)
if
name
==
""
{
notFound
(
w
)
return
...
...
@@ -351,16 +360,7 @@ func groupStatusHandler(w http.ResponseWriter, r *http.Request) {
return
}
scheme
:=
"wss"
if
Insecure
{
scheme
=
"ws"
}
endpoint
:=
url
.
URL
{
Scheme
:
scheme
,
Host
:
r
.
Host
,
Path
:
"/ws"
,
}
d
:=
g
.
Status
(
false
,
endpoint
.
String
())
d
:=
g
.
Status
(
false
,
groupBase
(
r
))
w
.
Header
()
.
Set
(
"content-type"
,
"application/json"
)
w
.
Header
()
.
Set
(
"cache-control"
,
"no-cache"
)
...
...
@@ -380,7 +380,7 @@ func publicHandler(w http.ResponseWriter, r *http.Request) {
return
}
g
:=
group
.
GetPublic
()
g
:=
group
.
GetPublic
(
groupBase
(
r
)
)
e
:=
json
.
NewEncoder
(
w
)
e
.
Encode
(
g
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment