Skip to content
This repository was archived by the owner on Mar 6, 2025. It is now read-only.

Commit 506448b

Browse files
committed
feat: add server public url
* Specify server public http url in a environment variable Fixes: #37 Related: #58
1 parent 19d0156 commit 506448b

File tree

6 files changed

+56
-39
lines changed

6 files changed

+56
-39
lines changed

docker.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ services:
4343
4444
To set up TLS under Docker, consider using a reverse proxy such as
4545
[traefik](https://doc.traefik.io/traefik/https/overview/) or a web server with
46-
automatic HTTPS like [caddy](https://caddyserver.com/docs/automatic-https).
46+
automatic HTTPS like [caddy](https://caddyserver.com/docs/automatic-https). If
47+
you're using a reverse proxy, you will need to set `CHARM_SERVER_HOST` to your
48+
public host, and `CHARM_SERVER_PUBLIC_URL` to the full public URL of your
49+
reverse proxy i.e. `CHARM_SERVER_PUBLIC_URL=https://cloud.charm.sh:35354`.
4750

4851
***
4952

server/auth.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ func (me *SSHServer) handleAPIAuth(s ssh.Session) {
5959
me.errorLog.Printf("Error fetching encrypt keys: %s\n", err)
6060
return
6161
}
62+
httpScheme := me.config.httpURL().Scheme
6263
_ = me.sendJSON(s, charm.Auth{
6364
JWT: j,
6465
ID: u.CharmID,
65-
HTTPScheme: me.config.httpScheme,
66+
HTTPScheme: httpScheme,
6667
PublicKey: u.PublicKey.Key,
6768
EncryptKeys: eks,
6869
})

server/http.go

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ const resultsPerPage = 50
2828

2929
// HTTPServer is the HTTP server for the Charm Cloud backend.
3030
type HTTPServer struct {
31-
db db.DB
32-
fstore storage.FileStore
33-
cfg *Config
34-
handler http.Handler
35-
server *http.Server
36-
health *http.Server
31+
db db.DB
32+
fstore storage.FileStore
33+
cfg *Config
34+
server *http.Server
35+
health *http.Server
36+
httpScheme string
3737
}
3838

3939
type providerJSON struct {
@@ -59,13 +59,24 @@ func NewHTTPServer(cfg *Config) (*HTTPServer, error) {
5959
}
6060
mux := goji.NewMux()
6161
s := &HTTPServer{
62-
cfg: cfg,
63-
handler: mux,
64-
health: health,
62+
cfg: cfg,
63+
health: health,
64+
httpScheme: "http",
6565
}
66+
s.server = &http.Server{
67+
Addr: fmt.Sprintf("%s:%d", s.cfg.BindAddr, s.cfg.HTTPPort),
68+
Handler: mux,
69+
ErrorLog: s.cfg.errorLog,
70+
}
71+
if cfg.UseTLS {
72+
s.httpScheme = "https"
73+
s.health.TLSConfig = s.cfg.tlsConfig
74+
s.server.TLSConfig = s.cfg.tlsConfig
75+
}
76+
6677
jwtMiddleware, err := JWTMiddleware(
6778
cfg.jwtKeyPair.JWK.Public(),
68-
cfg.httpURL(),
79+
cfg.httpURL().String(),
6980
[]string{"charm"},
7081
)
7182
if err != nil {
@@ -97,24 +108,19 @@ func NewHTTPServer(cfg *Config) (*HTTPServer, error) {
97108

98109
// Start start the HTTP and health servers on the ports specified in the Config.
99110
func (s *HTTPServer) Start() {
100-
useTLS := s.cfg.httpScheme == "https"
101-
listenAddr := fmt.Sprintf("%s:%d", s.cfg.BindAddr, s.cfg.HTTPPort)
102-
s.server = &http.Server{
103-
Addr: listenAddr,
104-
Handler: s.handler,
105-
TLSConfig: s.cfg.tlsConfig,
106-
ErrorLog: s.cfg.errorLog,
107-
}
108-
111+
scheme := strings.ToUpper(s.httpScheme)
109112
go func() {
110-
log.Printf("Starting HTTP health server on: %s", s.health.Addr)
111-
if err := s.health.ListenAndServe(); err != nil {
112-
log.Fatalf("http health endpoint server exited with error: %s", err)
113+
log.Printf("Starting %s health server on: %s", scheme, s.health.Addr)
114+
if s.cfg.UseTLS {
115+
log.Fatalf("http health endpoint server exited with error: %s",
116+
s.health.ListenAndServeTLS(s.cfg.TLSCertFile, s.cfg.TLSKeyFile))
117+
} else {
118+
log.Fatalf("http health endpoint server exited with error: %s", s.health.ListenAndServe())
113119
}
114120
}()
115121

116-
log.Printf("Starting %s server on: %s", strings.ToUpper(s.cfg.httpScheme), listenAddr)
117-
if useTLS {
122+
log.Printf("Starting %s server on: %s", scheme, s.server.Addr)
123+
if s.cfg.UseTLS {
118124
log.Fatalf("Server crashed: %s", s.server.ListenAndServeTLS(s.cfg.TLSCertFile, s.cfg.TLSKeyFile))
119125
} else {
120126
log.Fatalf("Server crashed: %s", s.server.ListenAndServe())
@@ -123,8 +129,9 @@ func (s *HTTPServer) Start() {
123129

124130
// Shutdown gracefully shut down the HTTP and health servers.
125131
func (s *HTTPServer) Shutdown(ctx context.Context) error {
126-
log.Printf("Stopping %s server on %s", strings.ToUpper(s.cfg.httpScheme), s.server.Addr)
127-
log.Printf("Stopping HTTP health server on %s", s.health.Addr)
132+
scheme := strings.ToUpper(s.httpScheme)
133+
log.Printf("Stopping %s server on %s", scheme, s.server.Addr)
134+
log.Printf("Stopping %s health server on %s", scheme, s.health.Addr)
128135
if err := s.health.Shutdown(ctx); err != nil {
129136
return err
130137
}

server/server.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"crypto/tls"
88
"fmt"
99
"log"
10+
"net/url"
1011
"path/filepath"
1112

1213
"github.com/caarlos0/env/v6"
@@ -29,8 +30,10 @@ type Config struct {
2930
StatsPort int `env:"CHARM_SERVER_STATS_PORT" envDefault:"35355"`
3031
HealthPort int `env:"CHARM_SERVER_HEALTH_PORT" envDefault:"35356"`
3132
DataDir string `env:"CHARM_SERVER_DATA_DIR" envDefault:"data"`
33+
UseTLS bool `env:"CHARM_SERVER_USE_TLS" envDefault:"false"`
3234
TLSKeyFile string `env:"CHARM_SERVER_TLS_KEY_FILE"`
3335
TLSCertFile string `env:"CHARM_SERVER_TLS_CERT_FILE"`
36+
PublicURL string `env:"CHARM_SERVER_PUBLIC_URL"`
3437
errorLog *log.Logger
3538
PublicKey []byte
3639
PrivateKey []byte
@@ -105,8 +108,17 @@ func (cfg *Config) WithLinkQueue(q charm.LinkQueue) *Config {
105108
return cfg
106109
}
107110

108-
func (cfg *Config) httpURL() string {
109-
return fmt.Sprintf("%s://%s:%d", cfg.httpScheme, cfg.Host, cfg.HTTPPort)
111+
func (cfg *Config) httpURL() *url.URL {
112+
s := fmt.Sprintf("%s://%s:%d", cfg.httpScheme, cfg.Host, cfg.HTTPPort)
113+
if cfg.PublicURL != "" {
114+
s = cfg.PublicURL
115+
}
116+
url, err := url.Parse(s)
117+
if err != nil {
118+
log.Fatalf("could not parse URL: %s", err)
119+
}
120+
log.Print(url.String())
121+
return url
110122
}
111123

112124
// NewServer returns a *Server with the specified Config.
@@ -119,12 +131,6 @@ func NewServer(cfg *Config) (*Server, error) {
119131
return nil, err
120132
}
121133
cfg.jwtKeyPair = NewJSONWebKeyPair(pk.(*ed25519.PrivateKey))
122-
123-
// Use HTTPS when TLS is configured.
124-
if cfg.tlsConfig != nil || (cfg.TLSCertFile != "" && cfg.TLSKeyFile != "") {
125-
cfg.httpScheme = "https"
126-
}
127-
128134
ss, err := NewSSHServer(cfg)
129135
if err != nil {
130136
return nil, err

server/ssh.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (me *SSHServer) newJWT(charmID string, audience ...string) (string, error)
127127
claims := &jwt.RegisteredClaims{
128128
Subject: charmID,
129129
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)),
130-
Issuer: me.config.httpURL(),
130+
Issuer: me.config.httpURL().String(),
131131
Audience: audience,
132132
}
133133
token := jwt.NewWithClaims(&jwt.SigningMethodEd25519{}, claims)

systemd.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ in the systemd service file as described below.
2828

2929
## TLS
3030

31-
To set up TLS, you should set `CHARM_SERVER_HTTP_SCHEME` environment variable to
32-
`https` and specify `CHARM_SERVER_HOST`, `CHARM_SERVER_TLS_KEY_FILE`, and
31+
To set up TLS, you should set `CHARM_SERVER_USE_TLS` to `true`, and specify
32+
`CHARM_SERVER_HOST`, `CHARM_SERVER_TLS_KEY_FILE`, and
3333
`CHARM_SERVER_TLS_CERT_FILE` file paths.
3434

3535
***

0 commit comments

Comments
 (0)