diff --git a/API.go b/API.go new file mode 100644 index 0000000..d0f5b7e --- /dev/null +++ b/API.go @@ -0,0 +1,7 @@ +/* +File Name: API.go +Copyright: 2022 Peernet s.r.o. +Author: Peter Kleissner +*/ + +package main diff --git a/Gateway.go b/Gateway.go new file mode 100644 index 0000000..0685514 --- /dev/null +++ b/Gateway.go @@ -0,0 +1,82 @@ +/* +File Name: Gateway.go +Copyright: 2022 Peernet s.r.o. +Author: Peter Kleissner +*/ + +package main + +import ( + "crypto/tls" + "net" + "net/http" + "time" + + "github.com/PeernetOfficial/core" + "github.com/gorilla/mux" +) + +func startWebGateway(backend *core.Backend) { + router := mux.NewRouter() + router.PathPrefix("/").Handler(http.HandlerFunc(webGatewayHandler)).Methods("GET") + router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir(config.WebFiles)))).Methods("GET") + + for _, listen := range config.WebListen { + go startWebServer(backend, listen, config.WebUseSSL, config.WebCertificateFile, config.WebCertificateKey, router, "Web Listen", parseDuration(config.WebTimeoutRead), parseDuration(config.WebTimeoutWrite)) + } + + if config.Redirect80 != "" { + go webRedirect80(config.Redirect80) + } + + // wait forever + select {} +} + +// startWebServer starts the web-server and may block forever +func startWebServer(backend *core.Backend, WebListen string, UseSSL bool, CertificateFile, CertificateKey string, Handler http.Handler, Info string, ReadTimeout, WriteTimeout time.Duration) { + //func startWebServer(backend *core.Backend, webListen string, useSSL bool, certificateFile, certificateKey string, server *http.Server) { + backend.LogError("startWebServer", "Web Gateway to listen on '%s'", WebListen) + + tlsConfig := &tls.Config{MinVersion: tls.VersionTLS12} // for security reasons disable TLS 1.0/1.1 + + server := &http.Server{ + Addr: WebListen, + Handler: Handler, + ReadTimeout: ReadTimeout, // ReadTimeout is the maximum duration for reading the entire request, including the body. + WriteTimeout: WriteTimeout, // WriteTimeout is the maximum duration before timing out writes of the response. This includes processing time and is therefore the max time any HTTP function may take. + //IdleTimeout: IdleTimeout, // IdleTimeout is the maximum amount of time to wait for the next request when keep-alives are enabled. + TLSConfig: tlsConfig, + } + + if UseSSL { + // HTTPS + if err := server.ListenAndServeTLS(CertificateFile, CertificateKey); err != nil { + backend.LogError("startWebServer", "Error listening on '%s': %v\n", WebListen, err) + } + } else { + // HTTP + if err := server.ListenAndServe(); err != nil { + backend.LogError("startWebServer", "Error listening on '%s': %v\n", WebListen, err) + } + } +} + +// parseDuration is the same as time.ParseDuration without returning an error. Valid units are ms, s, m, h. For example "10s". +func parseDuration(input string) (result time.Duration) { + result, _ = time.ParseDuration(input) + return +} + +func redirect(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "https://"+r.Host+r.URL.String(), http.StatusMovedPermanently) +} + +func webRedirect80(listen80 string) { + // redirect HTTP -> HTTPS + http.ListenAndServe(net.JoinHostPort(listen80, "80"), http.HandlerFunc(redirect)) +} + +func webGatewayHandler(w http.ResponseWriter, r *http.Request) { + http.Error(w, "404 page not found", http.StatusNotFound) +} diff --git a/Main.go b/Main.go index 6826594..6722c0a 100644 --- a/Main.go +++ b/Main.go @@ -24,6 +24,10 @@ var config struct { WebCertificateKey string `yaml:"WebCertificateKey"` // This is the private key. WebTimeoutRead string `yaml:"WebTimeoutRead"` // The maximum duration for reading the entire request, including the body. WebTimeoutWrite string `yaml:"WebTimeoutWrite"` // The maximum duration before timing out writes of the response. This includes processing time and is therefore the max time any HTTP function may take. + Redirect80 string `yaml:"Redirect80"` // Redirect 80 listen address. Empty if not used. + + // WebFiles is the directory holding all HTML and other files to be served by the server + WebFiles string `yaml:"WebFiles"` } func main() { @@ -49,7 +53,9 @@ func main() { backend.Stdout.Subscribe(os.Stdout) - //startWebGateway(backend, ) + go startWebGateway(backend) backend.Connect() + + select {} } diff --git a/README.md b/README.md index fd78a4c..254cec8 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,21 @@ The config filename is hard-coded to `Config.yaml` and is created on the first r Todo. +## Static Pages + +Access to `/` will show a generic information page. + +The main functionality is to provide URLs in the format `/[blockchain public key]/[file hash]` and other variations (using a directory name instead of file hash). This page shall provide access to one or multiple files shared via a user's blockchain. Access shall include download, preview, and providing a native Peernet link. The blockchain public key may be the node ID or the peer ID. Currently only hex encoding is supported. + +Native Peernet linsk should start with the `peernet://` custom scheme. On Windows such links can be opened with a registered protocol handler. + +To provide the best user experience, those static pages shall be generated immediately and use JavaScript to dynamically load the requested resource using the embedded API. + ## API Todo. +## Cache + +Todo. A cache folder should temporarily cache requested files so that they are available faster. + diff --git a/go.mod b/go.mod index 39c8305..2815db3 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,20 @@ module github.com/PeernetOfficial/Cmd -go 1.18 +go 1.19 -require github.com/PeernetOfficial/core v0.0.0-20220329002833-346f38c61138 +require ( + github.com/PeernetOfficial/core v0.0.0-20220601150942-0e3e8dc9885c + github.com/gorilla/mux v1.8.0 +) require ( github.com/akrylysov/pogreb v0.10.1 // indirect github.com/enfipy/locker v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/klauspost/cpuid/v2 v2.0.12 // indirect - golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 // indirect - golang.org/x/net v0.0.0-20220325170049-de3da57026de // indirect - golang.org/x/sys v0.0.0-20220325203850-36772127a21f // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/go.sum b/go.sum index 3276ca1..7a59a99 100644 --- a/go.sum +++ b/go.sum @@ -1,23 +1,25 @@ -github.com/PeernetOfficial/core v0.0.0-20220329002833-346f38c61138 h1:AhFNcWzqLU/LXRN4qsCkhX4+oH1LuJPCHBkvAYNDnMI= -github.com/PeernetOfficial/core v0.0.0-20220329002833-346f38c61138/go.mod h1:X2a4/PoJKp0UWnaUZRa6sg+TrMgyNp9b3hj7axyQRuE= +github.com/PeernetOfficial/core v0.0.0-20220601150942-0e3e8dc9885c h1:n+NGYHQulohXk//v2LYOgCVsbL9h5COupt+2ZhbtGqs= +github.com/PeernetOfficial/core v0.0.0-20220601150942-0e3e8dc9885c/go.mod h1:Ek4/3aKyKnA/KDSNe/yeorX5TA0fckpN7etZ+nCelGc= github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w= github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI= github.com/enfipy/locker v1.1.0 h1:2zVJ0ky7cS1Vjs0x6OQWFiT2dSEiHrI5/O2KCz1fgGc= github.com/enfipy/locker v1.1.0/go.mod h1:uuj+dvWHECshK8rkHcw+ZOb9SLo16yc0Em/JGUqRqko= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 h1:S25/rfnfsMVgORT4/J61MJ7rdyseOZOyvLIrZEZ7s6s= -golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/net v0.0.0-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/sys v0.0.0-20220325203850-36772127a21f h1:TrmogKRsSOxRMJbLYGrB4SBbW+LJcEllYBLME5Zk5pU= -golang.org/x/sys v0.0.0-20220325203850-36772127a21f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= +golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/html/favicon.ico b/html/favicon.ico new file mode 100644 index 0000000..1106e91 Binary files /dev/null and b/html/favicon.ico differ diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..506959b --- /dev/null +++ b/html/index.html @@ -0,0 +1,12 @@ + + + +
+This is a web gateway to access Peernet files on the legacy web. Why don't you try the native Peernet Browser?
+ + + \ No newline at end of file