Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Name the configured host in the SSH clone link

268b93688db5dd045cf92f61dc0922919b074fc6 · Keenan Nemetz · 19h ago · parent 2c988ecd

Name the configured host in the SSH clone link

ssh_addr is a bind address, so an instance listening on 0.0.0.0 showed
ssh://git@0.0.0.0:2222/... in the clone menu. Take the host from public_url,
which is the configured name, and keep ssh_addr for the port. The instance
repository page reads the same helper.

server/web/codebrowser.go +29−5

@@ -11,6 +11,7 @@ import (
11 11 "fmt"
12 12 "html/template"
13 13 "io"
14 "net"
14 15 "net/http"
15 16 "sort"
16 17 "strconv"
@@ -18,6 +19,7 @@ import (
18 19 "unicode/utf8"
19 20
20 21 "github.com/rodent-software/vole/core/git"
22 "github.com/rodent-software/vole/forge/config"
21 23 "github.com/rodent-software/vole/forge/repo"
22 24 )
23 25
@@ -424,17 +426,39 @@ func (w *Web) siteURL(r *http.Request, name string) string {
424 426 return scheme + "://" + name + "." + w.Cfg.PagesDomain
425 427 }
426 428
427 func sshURL(addr, name string) string {
428 host, port, ok := strings.Cut(addr, ":")
429 if !ok {
430 host = addr
429 // sshURL is the SSH transport the repository header offers. The host is the
430 // instance's configured name, from public_url, when there is one: ssh_addr is
431 // the address the SSH listener binds, and a bind address such as 0.0.0.0 is not
432 // something a person can connect to. The port always comes from ssh_addr,
433 // because that is the port the listener answers on. Without a public_url there
434 // is no configured name, so the listener's own address is all there is.
435 func (w *Web) sshURL(name string) string {
436 host, port := "", ""
437 if w.Cfg != nil {
438 host, port = splitSSHAddr(w.Cfg.SSHAddr)
439 if u, err := config.ParsePublicURL(w.Cfg.PublicURL); err == nil && u != nil {
440 host = u.Hostname()
441 }
431 442 }
432 443 return fmt.Sprintf("ssh://git@%s/%s.git", netJoin(host, port), name)
433 444 }
434 445
446 // splitSSHAddr separates a listen address into the host and the port, tolerating
447 // a bare address with no port the way config validation does. An IPv6 host is
448 // returned bare; netJoin puts the brackets back.
449 func splitSSHAddr(addr string) (host, port string) {
450 if h, p, err := net.SplitHostPort(addr); err == nil {
451 return h, p
452 }
453 return addr, ""
454 }
455
435 456 func netJoin(host, port string) string {
436 457 if port == "" || port == "22" {
458 if strings.Contains(host, ":") {
459 return "[" + host + "]"
460 }
437 461 return host
438 462 }
439 return host + ":" + port
463 return net.JoinHostPort(host, port)
440 464 }