mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 13:36:09 +05:00
* https service added on port 8091 default * https port check * format * readme * readme * readme * readme --------- Co-authored-by: evfedoto <evfedoto@cisco.com> Co-authored-by: nikk <tsynik@gmail.com>
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -35,3 +35,8 @@ toolchains/
|
||||
/toolchain/
|
||||
/test/
|
||||
/server/web/pages/template/pages/msx
|
||||
server/config.db
|
||||
/server/web/pages/template/pages/
|
||||
server/web/pages/template/route.go
|
||||
server/server.pem
|
||||
server/server.key
|
||||
|
||||
12
README.md
12
README.md
@@ -4,7 +4,7 @@ TorrServer, stream torrent to http
|
||||
### Installation
|
||||
Just download server from releases and exec file\
|
||||
https://github.com/YouROK/TorrServer/releases \
|
||||
After open browser link http://127.0.0.1:8090 \
|
||||
Then open the browser link http://127.0.0.1:8090 or https://127.0.0.1:8091 if the server was started with --ssl option \
|
||||
On linux systems you may need to set the environment variable before run \
|
||||
***export GODEBUG=madvdontneed=1***
|
||||
|
||||
@@ -38,11 +38,19 @@ path/to/Android/sdk/ndk/ver/toolchains/llvm/prebuilt/platform
|
||||
#
|
||||
### Server args:
|
||||
#### Usage
|
||||
TorrServer-darwin-arm64 [--port PORT] [--path PATH] [--logpath LOGPATH] [--weblogpath WEBLOGPATH] [--rdb] [--httpauth] [--dontkill] [--ui] [--torrentsdir TORRENTSDIR] [--torrentaddr TORRENTADDR] [--pubipv4 PUBIPV4] [--pubipv6 PUBIPV6] [--searchwa]
|
||||
TorrServer-darwin-arm64 [--port PORT] [--ssl] [--sslport PORT] [--sslcert PATH] [--sslkey PATH] [--path PATH] [--logpath LOGPATH] [--weblogpath WEBLOGPATH] [--rdb] [--httpauth] [--dontkill] [--ui] [--torrentsdir TORRENTSDIR] [--torrentaddr TORRENTADDR] [--pubipv4 PUBIPV4] [--pubipv6 PUBIPV6] [--searchwa]
|
||||
|
||||
#### Options
|
||||
* --port PORT, -p PORT
|
||||
* web server port, default 8090
|
||||
* --ssl
|
||||
* enables https
|
||||
* --sslport PORT
|
||||
* web server ssl port, If not set, will be set to default 8091 or taken from db(if stored previously). Accepted if --ssl enabled.
|
||||
* --sslcert PATH
|
||||
* path to ssl cert file. If not set, will be taken from db(if stored previously) or default self-signed certificate/key will be generated. Accepted if --ssl enabled.
|
||||
* --sslkey PATH
|
||||
* path to ssl key file. If not set, will be taken from db(if stored previously) or default self-signed certificate/key will be generated. Accepted if --ssl enabled.
|
||||
* --path PATH, -d PATH
|
||||
* database dir path
|
||||
* --logpath LOGPATH, -l LOGPATH
|
||||
|
||||
@@ -23,6 +23,10 @@ import (
|
||||
|
||||
type args struct {
|
||||
Port string `arg:"-p" help:"web server port, default 8090"`
|
||||
Ssl bool `help:"enables https"`
|
||||
SslPort string `help:"web server ssl port, If not set, will be set to default 8091 or taken from db(if stored previously). Accepted if --ssl enabled."`
|
||||
SslCert string `help:"path to ssl cert file. If not set, will be taken from db(if stored previously) or default self-signed certificate/key will be generated. Accepted if --ssl enabled."`
|
||||
SslKey string `help:"path to ssl key file. If not set, will be taken from db(if stored previously) or default self-signed certificate/key will be generated. Accepted if --ssl enabled."`
|
||||
Path string `arg:"-d" help:"database dir path"`
|
||||
LogPath string `arg:"-l" help:"server log file path"`
|
||||
WebLogPath string `arg:"-w" help:"web access log file path"`
|
||||
@@ -56,6 +60,10 @@ func main() {
|
||||
params.Port = "8090"
|
||||
}
|
||||
|
||||
if params.SslPort == "" {
|
||||
params.SslPort = "8091"
|
||||
}
|
||||
|
||||
settings.Path = params.Path
|
||||
settings.HttpAuth = params.HttpAuth
|
||||
log.Init(params.LogPath, params.WebLogPath)
|
||||
@@ -71,7 +79,11 @@ func main() {
|
||||
if params.UI {
|
||||
go func() {
|
||||
time.Sleep(time.Second)
|
||||
browser.OpenURL("http://127.0.0.1:" + params.Port)
|
||||
if params.Ssl {
|
||||
browser.OpenURL("https://127.0.0.1:" + params.SslPort)
|
||||
} else {
|
||||
browser.OpenURL("http://127.0.0.1:" + params.Port)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -91,7 +103,7 @@ func main() {
|
||||
go watchTDir(params.TorrentsDir)
|
||||
}
|
||||
|
||||
server.Start(params.Port, params.RDB, params.SearchWA)
|
||||
server.Start(params.Port, params.SslPort, params.SslCert, params.SslKey, params.Ssl, params.RDB, params.SearchWA)
|
||||
log.TLogln(server.WaitServer())
|
||||
log.Close()
|
||||
time.Sleep(time.Second * 3)
|
||||
|
||||
@@ -236,13 +236,23 @@ func loadTorrent(path, host string) (ret []interface{}) {
|
||||
|
||||
func getLink(host, path string) string {
|
||||
if !strings.HasPrefix(host, "http") {
|
||||
host = "http://" + host
|
||||
if settings.Ssl {
|
||||
host = "https://" + host
|
||||
} else {
|
||||
host = "http://" + host
|
||||
}
|
||||
|
||||
}
|
||||
pos := strings.LastIndex(host, ":")
|
||||
if pos > 7 {
|
||||
host = host[:pos]
|
||||
}
|
||||
return host + ":" + settings.Port + "/" + path
|
||||
if settings.Ssl {
|
||||
return host + ":" + settings.SslPort + "/" + path
|
||||
} else {
|
||||
return host + ":" + settings.Port + "/" + path
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func getObjFromTorrent(path, parent, host string, torr *torr.Torrent, file *state.TorrentFileStat) (ret interface{}) {
|
||||
|
||||
@@ -10,8 +10,40 @@ import (
|
||||
"server/web"
|
||||
)
|
||||
|
||||
func Start(port string, roSets, searchWA bool) {
|
||||
func Start(port, sslport, sslCert, sslKey string, sslEnabled, roSets, searchWA bool) {
|
||||
settings.InitSets(roSets, searchWA)
|
||||
|
||||
//// https checks
|
||||
// check if ssl enabled
|
||||
settings.Ssl = sslEnabled
|
||||
settings.BTsets.Ssl = sslEnabled
|
||||
if sslEnabled {
|
||||
// set settings ssl enabled
|
||||
if sslport == "" {
|
||||
if settings.BTsets.SslPort == "" {
|
||||
settings.BTsets.SslPort = "8091"
|
||||
}
|
||||
} else {
|
||||
settings.BTsets.SslPort = sslport
|
||||
}
|
||||
// check if ssl cert and key files exist
|
||||
if sslCert != "" && sslKey != "" {
|
||||
// set settings ssl cert and key files
|
||||
settings.BTsets.SslCert = sslCert
|
||||
settings.BTsets.SslKey = sslKey
|
||||
}
|
||||
log.TLogln("Check web ssl port", settings.BTsets.SslPort)
|
||||
l, err := net.Listen("tcp", ":"+settings.BTsets.SslPort)
|
||||
if l != nil {
|
||||
l.Close()
|
||||
}
|
||||
if err != nil {
|
||||
log.TLogln("Port", settings.BTsets.SslPort, "already in use! Please set different port for HTTP. Abort")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// http checks
|
||||
if port == "" {
|
||||
port = "8090"
|
||||
}
|
||||
@@ -21,13 +53,16 @@ func Start(port string, roSets, searchWA bool) {
|
||||
l.Close()
|
||||
}
|
||||
if err != nil {
|
||||
log.TLogln("Port", port, "already in use! Abort")
|
||||
log.TLogln("Port", port, "already in use! Please set different sslport for HTTPS. Abort")
|
||||
os.Exit(1)
|
||||
} else {
|
||||
go cleanCache()
|
||||
settings.Port = port
|
||||
web.Start(port)
|
||||
}
|
||||
|
||||
// set settings http and https ports. Start web server.
|
||||
go cleanCache()
|
||||
settings.Port = port
|
||||
settings.SslPort = settings.BTsets.SslPort
|
||||
web.Start()
|
||||
|
||||
}
|
||||
|
||||
func cleanCache() {
|
||||
|
||||
@@ -46,6 +46,12 @@ type BTSets struct {
|
||||
UploadRateLimit int // in kb, 0 - inf
|
||||
ConnectionsLimit int
|
||||
PeersListenPort int
|
||||
|
||||
//Https
|
||||
Ssl bool
|
||||
SslPort string
|
||||
SslCert string
|
||||
SslKey string
|
||||
}
|
||||
|
||||
func (v *BTSets) String() string {
|
||||
|
||||
@@ -11,6 +11,8 @@ var (
|
||||
tdb *TDB
|
||||
Path string
|
||||
Port string
|
||||
SslPort string
|
||||
Ssl bool
|
||||
ReadOnly bool
|
||||
HttpAuth bool
|
||||
SearchWA bool
|
||||
|
||||
@@ -71,6 +71,9 @@ func (t *Torrent) Preload(index int, size int64) {
|
||||
|
||||
if ffprobe.Exists() {
|
||||
link := "http://127.0.0.1:" + settings.Port + "/play/" + t.Hash().HexString() + "/" + strconv.Itoa(index)
|
||||
if settings.Ssl {
|
||||
link = "https://127.0.0.1:" + settings.SslPort + "/play/" + t.Hash().HexString() + "/" + strconv.Itoa(index)
|
||||
}
|
||||
if data, err := ffprobe.ProbeUrl(link); err == nil {
|
||||
t.BitRate = data.Format.BitRate
|
||||
t.DurationSeconds = data.Format.DurationSeconds
|
||||
|
||||
@@ -21,6 +21,9 @@ func ffp(c *gin.Context) {
|
||||
}
|
||||
|
||||
link := "http://127.0.0.1:" + sets.Port + "/play/" + hash + "/" + indexStr
|
||||
if sets.Ssl {
|
||||
link = "https://127.0.0.1:" + sets.SslPort + "/play/" + hash + "/" + indexStr
|
||||
}
|
||||
|
||||
data, err := ffprobe.ProbeUrl(link)
|
||||
if err != nil {
|
||||
|
||||
@@ -118,20 +118,20 @@ var Mstile150x150png []byte
|
||||
//go:embed pages/site.webmanifest
|
||||
var Sitewebmanifest []byte
|
||||
|
||||
//go:embed pages/static/js/2.84d4a004.chunk.js
|
||||
var Staticjs284d4a004chunkjs []byte
|
||||
//go:embed pages/static/js/2.0d7c02d7.chunk.js
|
||||
var Staticjs20d7c02d7chunkjs []byte
|
||||
|
||||
//go:embed pages/static/js/2.84d4a004.chunk.js.LICENSE.txt
|
||||
var Staticjs284d4a004chunkjsLICENSEtxt []byte
|
||||
//go:embed pages/static/js/2.0d7c02d7.chunk.js.LICENSE.txt
|
||||
var Staticjs20d7c02d7chunkjsLICENSEtxt []byte
|
||||
|
||||
//go:embed pages/static/js/2.84d4a004.chunk.js.map
|
||||
var Staticjs284d4a004chunkjsmap []byte
|
||||
//go:embed pages/static/js/2.0d7c02d7.chunk.js.map
|
||||
var Staticjs20d7c02d7chunkjsmap []byte
|
||||
|
||||
//go:embed pages/static/js/main.cc15501f.chunk.js
|
||||
var Staticjsmaincc15501fchunkjs []byte
|
||||
//go:embed pages/static/js/main.7efc8add.chunk.js
|
||||
var Staticjsmain7efc8addchunkjs []byte
|
||||
|
||||
//go:embed pages/static/js/main.cc15501f.chunk.js.map
|
||||
var Staticjsmaincc15501fchunkjsmap []byte
|
||||
//go:embed pages/static/js/main.7efc8add.chunk.js.map
|
||||
var Staticjsmain7efc8addchunkjsmap []byte
|
||||
|
||||
//go:embed pages/static/js/runtime-main.64d07802.js
|
||||
var Staticjsruntimemain64d07802js []byte
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"files": {
|
||||
"main.js": "/static/js/main.cc15501f.chunk.js",
|
||||
"main.js.map": "/static/js/main.cc15501f.chunk.js.map",
|
||||
"main.js": "/static/js/main.7efc8add.chunk.js",
|
||||
"main.js.map": "/static/js/main.7efc8add.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.64d07802.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.64d07802.js.map",
|
||||
"static/js/2.84d4a004.chunk.js": "/static/js/2.84d4a004.chunk.js",
|
||||
"static/js/2.84d4a004.chunk.js.map": "/static/js/2.84d4a004.chunk.js.map",
|
||||
"static/js/2.0d7c02d7.chunk.js": "/static/js/2.0d7c02d7.chunk.js",
|
||||
"static/js/2.0d7c02d7.chunk.js.map": "/static/js/2.0d7c02d7.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/js/2.84d4a004.chunk.js.LICENSE.txt": "/static/js/2.84d4a004.chunk.js.LICENSE.txt"
|
||||
"static/js/2.0d7c02d7.chunk.js.LICENSE.txt": "/static/js/2.0d7c02d7.chunk.js.LICENSE.txt"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.64d07802.js",
|
||||
"static/js/2.84d4a004.chunk.js",
|
||||
"static/js/main.cc15501f.chunk.js"
|
||||
"static/js/2.0d7c02d7.chunk.js",
|
||||
"static/js/main.7efc8add.chunk.js"
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
object-assign
|
||||
(c) Sindre Sorhus
|
||||
@license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
* @author Feross Aboukhadijeh <http://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/*! blob-to-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! https://mths.be/punycode v1.4.1 by @mathias */
|
||||
|
||||
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! magnet-uri. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */
|
||||
|
||||
/*! parse-torrent. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */
|
||||
|
||||
/*! queue-microtask. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
||||
|
||||
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! simple-concat. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! simple-get. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/**
|
||||
* A better abstraction over CSS.
|
||||
*
|
||||
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
|
||||
* @website https://github.com/cssinjs/jss
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/** @license React v0.20.2
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -161,24 +161,24 @@ func RouteWebPages(route *gin.RouterGroup) {
|
||||
c.Data(200, "application/manifest+json", Sitewebmanifest)
|
||||
})
|
||||
|
||||
route.GET("/static/js/2.84d4a004.chunk.js", func(c *gin.Context) {
|
||||
c.Data(200, "application/javascript; charset=utf-8", Staticjs284d4a004chunkjs)
|
||||
route.GET("/static/js/2.0d7c02d7.chunk.js", func(c *gin.Context) {
|
||||
c.Data(200, "application/javascript; charset=utf-8", Staticjs20d7c02d7chunkjs)
|
||||
})
|
||||
|
||||
route.GET("/static/js/2.84d4a004.chunk.js.LICENSE.txt", func(c *gin.Context) {
|
||||
c.Data(200, "text/plain; charset=utf-8", Staticjs284d4a004chunkjsLICENSEtxt)
|
||||
route.GET("/static/js/2.0d7c02d7.chunk.js.LICENSE.txt", func(c *gin.Context) {
|
||||
c.Data(200, "text/plain; charset=utf-8", Staticjs20d7c02d7chunkjsLICENSEtxt)
|
||||
})
|
||||
|
||||
route.GET("/static/js/2.84d4a004.chunk.js.map", func(c *gin.Context) {
|
||||
c.Data(200, "application/json", Staticjs284d4a004chunkjsmap)
|
||||
route.GET("/static/js/2.0d7c02d7.chunk.js.map", func(c *gin.Context) {
|
||||
c.Data(200, "application/json", Staticjs20d7c02d7chunkjsmap)
|
||||
})
|
||||
|
||||
route.GET("/static/js/main.cc15501f.chunk.js", func(c *gin.Context) {
|
||||
c.Data(200, "application/javascript; charset=utf-8", Staticjsmaincc15501fchunkjs)
|
||||
route.GET("/static/js/main.7efc8add.chunk.js", func(c *gin.Context) {
|
||||
c.Data(200, "application/javascript; charset=utf-8", Staticjsmain7efc8addchunkjs)
|
||||
})
|
||||
|
||||
route.GET("/static/js/main.cc15501f.chunk.js.map", func(c *gin.Context) {
|
||||
c.Data(200, "application/json", Staticjsmaincc15501fchunkjsmap)
|
||||
route.GET("/static/js/main.7efc8add.chunk.js.map", func(c *gin.Context) {
|
||||
c.Data(200, "application/json", Staticjsmain7efc8addchunkjsmap)
|
||||
})
|
||||
|
||||
route.GET("/static/js/runtime-main.64d07802.js", func(c *gin.Context) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"server/web/auth"
|
||||
"server/web/blocker"
|
||||
"server/web/pages"
|
||||
"server/web/sslcerts"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -29,7 +30,7 @@ var (
|
||||
waitChan = make(chan error)
|
||||
)
|
||||
|
||||
func Start(port string) {
|
||||
func Start() {
|
||||
log.TLogln("Start TorrServer " + version.Version + " torrent " + version.GetTorrentVersion())
|
||||
ips := getLocalIps()
|
||||
if len(ips) > 0 {
|
||||
@@ -71,8 +72,36 @@ func Start(port string) {
|
||||
if settings.BTsets.EnableDLNA {
|
||||
dlna.Start()
|
||||
}
|
||||
log.TLogln("Start web server at port", port)
|
||||
waitChan <- route.Run(":" + port)
|
||||
|
||||
log.TLogln(settings.BTsets)
|
||||
//check if https enabled
|
||||
if settings.Ssl {
|
||||
//if no cert and key files set in db/settings, generate new self-signed cert and key files
|
||||
if settings.BTsets.SslCert == "" || settings.BTsets.SslKey == "" {
|
||||
settings.BTsets.SslCert, settings.BTsets.SslKey = sslcerts.MakeCertKeyFiles(ips)
|
||||
log.TLogln("Saving path to ssl cert and key in db", settings.BTsets.SslCert, settings.BTsets.SslKey)
|
||||
settings.SetBTSets(settings.BTsets)
|
||||
}
|
||||
//verify if cert and key files are valid
|
||||
err = sslcerts.VerifyCertKeyFiles(settings.BTsets.SslCert, settings.BTsets.SslKey, settings.SslPort)
|
||||
//if not valid, generate new self-signed cert and key files
|
||||
if err != nil {
|
||||
log.TLogln("Error checking certificate and private key files:", err)
|
||||
settings.BTsets.SslCert, settings.BTsets.SslKey = sslcerts.MakeCertKeyFiles(ips)
|
||||
log.TLogln("Saving path to ssl cert and key in db", settings.BTsets.SslCert, settings.BTsets.SslKey)
|
||||
settings.SetBTSets(settings.BTsets)
|
||||
}
|
||||
go func() {
|
||||
log.TLogln("Starting https server at port", settings.SslPort)
|
||||
waitChan <- route.RunTLS(":"+settings.SslPort, settings.BTsets.SslCert, settings.BTsets.SslKey)
|
||||
}()
|
||||
}
|
||||
|
||||
go func() {
|
||||
log.TLogln("Start http server at port", settings.Port)
|
||||
waitChan <- route.Run(":" + settings.Port)
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
func Wait() error {
|
||||
|
||||
144
server/web/sslcerts/sslcerts.go
Normal file
144
server/web/sslcerts/sslcerts.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package sslcerts
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"server/log"
|
||||
"time"
|
||||
)
|
||||
|
||||
func generateSelfSignedCert(ips []string) ([]byte, []byte, error) {
|
||||
priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
notBefore := time.Now()
|
||||
notAfter := notBefore.Add(365 * 24 * time.Hour) // Valid for 1 year
|
||||
|
||||
serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
netIps := make([]net.IP, 0)
|
||||
if len(ips) != 0 {
|
||||
for _, ip := range ips {
|
||||
netIps = append(netIps, net.ParseIP(ip))
|
||||
}
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"Torrserver"},
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
DNSNames: []string{"localhost"},
|
||||
IPAddresses: netIps,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
|
||||
|
||||
privBytes, err := x509.MarshalECPrivateKey(priv)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
privPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: privBytes})
|
||||
|
||||
return certPEM, privPEM, nil
|
||||
}
|
||||
|
||||
func MakeCertKeyFiles(ips []string) (string, string) {
|
||||
certPEM, privPEM, err := generateSelfSignedCert(ips)
|
||||
if err != nil {
|
||||
log.TLogln("Error generating certificate:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
certFile, err := os.Create("server.pem")
|
||||
if err != nil {
|
||||
log.TLogln("Error creating certificate file:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer certFile.Close()
|
||||
|
||||
privFile, err := os.Create("server.key")
|
||||
if err != nil {
|
||||
log.TLogln("Error creating private key file:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer privFile.Close()
|
||||
|
||||
_, err = certFile.Write(certPEM)
|
||||
if err != nil {
|
||||
log.TLogln("Error writing certificate file:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
_, err = privFile.Write(privPEM)
|
||||
if err != nil {
|
||||
log.TLogln("Error writing private key file:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
log.TLogln("Self-signed certificate and private key generated successfully.")
|
||||
|
||||
return getAbsPath("server.pem"), getAbsPath("server.key")
|
||||
}
|
||||
|
||||
func getAbsPath(fileName string) string {
|
||||
filePath, err := filepath.Abs(fileName)
|
||||
if err != nil {
|
||||
log.TLogln("Error getting absolute path:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return filePath
|
||||
}
|
||||
|
||||
func VerifyCertKeyFiles(certFile, keyFile, port string) error {
|
||||
// Load the certificate and key
|
||||
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Check if the certificate chain is expired
|
||||
for _, cert := range cert.Certificate {
|
||||
x509Cert, err := x509.ParseCertificate(cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if x509Cert.NotAfter.Before(time.Now()) {
|
||||
return errors.New("certificate has expired")
|
||||
}
|
||||
}
|
||||
// Create a TLS configuration
|
||||
config := tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
// Create a listener to check the certificate and key
|
||||
ln, err := tls.Listen("tcp", ":"+port, &config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ln.Close()
|
||||
log.TLogln("Certificate and key are valid.")
|
||||
return nil
|
||||
}
|
||||
44278
web/package-lock.json
generated
Normal file
44278
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,7 @@ const Table = memo(
|
||||
return (
|
||||
(season === selectedSeason || !seasonAmount?.length) && (
|
||||
<tr key={id} className={isViewed ? 'viewed-file-row' : null}>
|
||||
<td data-label='viewed' className={isViewed ? 'viewed-file-indicator' : null} />
|
||||
<td data-label='viewed' aria-label='viewed' className={isViewed ? 'viewed-file-indicator' : null} />
|
||||
<td data-label='name'>{shouldDisplayFullFileName ? path : title}</td>
|
||||
{fileHasSeasonText && seasonAmount?.length === 1 && <td data-label='season'>{season}</td>}
|
||||
{fileHasEpisodeText && <td data-label='episode'>{episode}</td>}
|
||||
|
||||
4207
web/yarn.lock
4207
web/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user