filestash/server/plugin/plg_starter_http2/index.go

122 lines
2.8 KiB
Go

package plg_starter_http2
/*
* In golang, HTTP2 server are written in the same way as HTTPS server, the only difference beeing
* describe in the documentation: https://golang.org/src/net/http/doc.go#L81
* In our implementation, we use the 'TLSNextProto' trick
*/
import (
"crypto/tls"
"fmt"
"net/http"
"os"
"path/filepath"
"time"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/mickael-kerjean/filestash/server/common/ssl"
"github.com/gorilla/mux"
"golang.org/x/crypto/acme/autocert"
)
var (
SSL_PATH string
config_port func() int
)
func init() {
config_port = func() int {
return Config.Get("general.port").Int()
}
Hooks.Register.Onload(func() {
SSL_PATH = filepath.Join(GetAbsolutePath(CERT_PATH), "ssl")
os.MkdirAll(SSL_PATH, os.ModePerm)
})
Hooks.Register.Starter(func(r *mux.Router) {
domain := Config.Get("general.host").String()
Log.Info("[https] starting ...%s", domain)
srv := &http.Server{
Addr: fmt.Sprintf(":%d", config_port()),
Handler: r,
TLSConfig: &DefaultTLSConfig,
ErrorLog: NewNilLogger(),
}
switch domain {
case "":
TLSCert, roots, err := ssl.GenerateSelfSigned()
if err != nil {
return
}
srv.TLSConfig.Certificates = []tls.Certificate{TLSCert}
HTTPClient.Transport.(*TransformedTransport).Orig.(*http.Transport).TLSClientConfig = &tls.Config{
RootCAs: roots,
}
HTTP.Transport.(*TransformedTransport).Orig.(*http.Transport).TLSClientConfig = &tls.Config{
RootCAs: roots,
}
default:
mngr := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(domain),
Cache: autocert.DirCache(SSL_PATH),
}
srv.TLSConfig.GetCertificate = mngr.GetCertificate
}
go func() {
srv = &http.Server{
Addr: fmt.Sprintf(":http"),
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Connection", "close")
http.Redirect(
w,
req,
"https://"+req.Host+req.URL.String(),
http.StatusMovedPermanently,
)
}),
}
if err := srv.ListenAndServe(); err != nil {
return
}
}()
go ensureAppHasBooted(
fmt.Sprintf("https://127.0.0.1:%d/about", config_port()),
fmt.Sprintf("[https] started"),
)
if err := srv.ListenAndServeTLS("", ""); err != nil {
Log.Error("[https]: listen_serve %v", err)
return
}
})
}
func ensureAppHasBooted(address string, message string) {
i := 0
for {
if i > 10 {
Log.Warning("[https] no boot")
break
}
time.Sleep(250 * time.Millisecond)
res, err := HTTPClient.Get(address)
if err != nil {
i += 1
continue
}
res.Body.Close()
if res.StatusCode != http.StatusOK {
i += 1
continue
}
Log.Info(message)
break
}
}