diff --git a/CHANGELOG.md b/CHANGELOG.md index 58c1c13..86d5d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,12 @@ _v6.1.12_ - Fix too many open files (issue #129). - Cosmetic: AVOID and PATCH flags now only appear when needed. +_v6.1.13_ + +- Better handling of dead client connections. +- Fix too many open files (issue #129). +- Remove net.http error messages from the output (issue #131). + ## Version 6.0 - Backend server rewritten in Go for better performance and ease of installation. diff --git a/COMPILING.md b/COMPILING.md index 3fac847..009926e 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -24,13 +24,13 @@ Clone the official repository on your computer and start the build process. When finished, you will find the precompiled versions for various platforms in the `dist` folder. - rdio-scanner-darwin-amd64-v6.1.12.zip - rdio-scanner-darwin-arm64-v6.1.12.zip - rdio-scanner-freebsd-amd64-v6.1.12.zip - rdio-scanner-linux-386-v6.1.12.zip - rdio-scanner-linux-amd64-v6.1.12.zip - rdio-scanner-linux-arm64-v6.1.12.zip - rdio-scanner-linux-arm-v6.1.12.zip - rdio-scanner-windows-amd64-v6.1.12.zip + rdio-scanner-darwin-amd64-v6.1.13.zip + rdio-scanner-darwin-arm64-v6.1.13.zip + rdio-scanner-freebsd-amd64-v6.1.13.zip + rdio-scanner-linux-386-v6.1.13.zip + rdio-scanner-linux-amd64-v6.1.13.zip + rdio-scanner-linux-arm64-v6.1.13.zip + rdio-scanner-linux-arm-v6.1.13.zip + rdio-scanner-windows-amd64-v6.1.13.zip **Happy Rdio scanning !** \ No newline at end of file diff --git a/Makefile b/Makefile index 930973b..974e9a7 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,8 @@ ################################################################################ app := rdio-scanner -date := 2022/02/14 -ver := 6.1.12 +date := 2022/02/17 +ver := 6.1.13 client := $(wildcard client/*.json client/*.ts) server := $(wildcard server/*.go) diff --git a/client/package.json b/client/package.json index ab65f62..42d207d 100644 --- a/client/package.json +++ b/client/package.json @@ -38,5 +38,5 @@ "build": "ng build --base-href ./ --configuration production", "start": "ng serve" }, - "version": "6.1.12" + "version": "6.1.13" } diff --git a/docs/platforms/darwin.md b/docs/platforms/darwin.md index 39e273a..e3cead6 100644 --- a/docs/platforms/darwin.md +++ b/docs/platforms/darwin.md @@ -42,8 +42,8 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd rdio@macos ~ % mkdir rdio-scanner rdio@macos ~ % cd rdio-scanner rdio@macos rdio-scanner % unzip \ - > ~/Downloads/rdio-scanner-darwin-arm64-v6.1.12.zip - Archive: /Users/rdio/Downloads/rdio-scanner-darwin-arm64-v6.1.12.zip + > ~/Downloads/rdio-scanner-darwin-arm64-v6.1.13.zip + Archive: /Users/rdio/Downloads/rdio-scanner-darwin-arm64-v6.1.13.zip inflating: rdio-scanner inflating: rdio-scanner.pdf @@ -51,11 +51,11 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd rdio@macos rdio-scanner % ./rdio-scanner - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 08:38:06 server started - 2022/02/14 08:38:06 main interface at http://macos.local:3000 - 2022/02/14 08:38:06 admin interface at http://macos.local:3000/admin + 2022/02/17 08:38:06 server started + 2022/02/17 08:38:06 main interface at http://macos.local:3000 + 2022/02/17 08:38:06 admin interface at http://macos.local:3000/admin 4. Access the administrative dashboard to finalize the configuration. @@ -77,11 +77,11 @@ Here we want our [Rdio Scanner](https://guthub.com/chuot/rdio-scanner) instance rdio@macos rdio-scanner % ./rdio-scanner --listen :80 - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 08:48:03 server started - 2022/02/14 08:48:03 main interface at http://macos.local - 2022/02/14 08:48:03 admin interface at http://macos.local/admin + 2022/02/17 08:48:03 server started + 2022/02/17 08:48:03 main interface at http://macos.local + 2022/02/17 08:48:03 admin interface at http://macos.local/admin ## Listening with SSL with self-signed certificates @@ -90,8 +90,8 @@ It is advised to share your [Rdio Scanner](https://github.com/chuot/rdio-scanner We can create such self-signed certificates by running [Rdio Scanner](https://github.com/chuot/rdio-scanner) with the **-ssl_create** argument. rdio@macos rdio-scanner % ./rdio-scanner -ssl_create - 2022/02/14 08:49:16 generating ssl certificate files - 2022/02/14 08:49:17 ssl files created + 2022/02/17 08:49:16 generating ssl certificate files + 2022/02/17 08:49:17 ssl files created This has generated these files in the same folder as your [Rdio Scanner](https://github.com/chuot/rdio-scanner) executable. @@ -108,12 +108,12 @@ Now we use the self-signed server certificate to run our instance. > -ssl_key_file server.key \ > -ssl_listen :443 - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 08:50:58 server started - 2022/02/14 08:50:58 main interface at http://macos.local - 2022/02/14 08:50:58 main interface at https://macos.local - 2022/02/14 08:50:58 admin interface at https://macos.local/admin + 2022/02/17 08:50:58 server started + 2022/02/17 08:50:58 main interface at http://macos.local + 2022/02/17 08:50:58 main interface at https://macos.local + 2022/02/17 08:50:58 admin interface at https://macos.local/admin ## Save your advanced configuration to a config file @@ -125,7 +125,7 @@ You don't want to have to type everytime a long list of arguments. No problem, y > -ssl_key_file server.key \ > -ssl_listen :443 \ > -config_save - 2022/02/14 08:52:24 rdio-scanner.ini file created + 2022/02/17 08:52:24 rdio-scanner.ini file created All of your parameters passed as arguments to [Rdio Scanner](https://github.com/chuot/rdio-scanner) have been saved to an INI file which has the same arguments/values list. @@ -140,12 +140,12 @@ Then simply run [Rdio Scanner](https://github.com/chuot/rdio-scanner) without an rdio@macos rdio-scanner % ./rdio-scanner - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 08:54:08 server started - 2022/02/14 08:54:08 main interface at http://macos.local - 2022/02/14 08:54:08 main interface at https://macos.local - 2022/02/14 08:54:08 admin interface at https://macos.local/admin + 2022/02/17 08:54:08 server started + 2022/02/17 08:54:08 main interface at http://macos.local + 2022/02/17 08:54:08 main interface at https://macos.local + 2022/02/17 08:54:08 admin interface at https://macos.local/admin ## Install Rdio Scanner as a service diff --git a/docs/platforms/freebsd.md b/docs/platforms/freebsd.md index 0879d13..25f0aa4 100644 --- a/docs/platforms/freebsd.md +++ b/docs/platforms/freebsd.md @@ -42,8 +42,8 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd rdio@pc-freebsd:~ $ mkdir rdio-scanner rdio@pc-freebsd:~ $ cd rdio-scanner rdio@pc-freebsd:~/rdio-scanner $ unzip \ - > ~/rdio-scanner-freebsd-amd64-v6.1.12.zip - Archive: ../rdio-scanner-freebsd-amd64-v6.1.12.zip + > ~/rdio-scanner-freebsd-amd64-v6.1.13.zip + Archive: ../rdio-scanner-freebsd-amd64-v6.1.13.zip extracting: rdio-scanner extracting: rdio-scanner.pdf @@ -51,11 +51,11 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd rdio@pc-freebsd:~/rdio-scanner $ ./rdio-scanner - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 08:16:36 server started - 2022/02/14 08:16:36 main interface at http://pc-freebsd:3000 - 2022/02/14 08:16:36 admin interface at http://pc-freebsd:3000/admin + 2022/02/17 08:16:36 server started + 2022/02/17 08:16:36 main interface at http://pc-freebsd:3000 + 2022/02/17 08:16:36 admin interface at http://pc-freebsd:3000/admin 4. Access the administrative dashboard to finalize the configuration. @@ -81,11 +81,11 @@ Here we want our [Rdio Scanner](https://guthub.com/chuot/rdio-scanner) instance Password: root@pc-freebsd:/home/rdio/rdio-scanner # ./rdio-scanner -listen :80 - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 08:19:38 server started - 2022/02/14 08:19:38 main interface at http://pc-freebsd - 2022/02/14 08:19:38 admin interface at http://pc-freebsd/admin + 2022/02/17 08:19:38 server started + 2022/02/17 08:19:38 main interface at http://pc-freebsd + 2022/02/17 08:19:38 admin interface at http://pc-freebsd/admin ## Listening with SSL with self-signed certificates @@ -94,8 +94,8 @@ It is advised to share your [Rdio Scanner](https://github.com/chuot/rdio-scanner We can create such self-signed certificates by running [Rdio Scanner](https://github.com/chuot/rdio-scanner) with the **-ssl_create** argument. rdio@pc-freebsd:~/rdio-scanner $ ./rdio-scanner -ssl_create - 2022/02/14 10:32:17 generating ssl certificate files - 2022/02/14 10:32:19 ssl files created + 2022/02/17 10:32:17 generating ssl certificate files + 2022/02/17 10:32:19 ssl files created This has generated these files in the same folder as your [Rdio Scanner](https://github.com/chuot/rdio-scanner) executable. @@ -114,12 +114,12 @@ Now we use the self-signed server certificate to run our instance. > -ssl_key_file server.key \ > -ssl_listen :443 - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 10:34:29 server started - 2022/02/14 10:34:29 main interface at http://pc-freebsd - 2022/02/14 10:34:29 main interface at https://pc-freebsd - 2022/02/14 10:34:29 admin interface at https://pc-freebsd/admin + 2022/02/17 10:34:29 server started + 2022/02/17 10:34:29 main interface at http://pc-freebsd + 2022/02/17 10:34:29 main interface at https://pc-freebsd + 2022/02/17 10:34:29 admin interface at https://pc-freebsd/admin ## Save your advanced configuration to a config file @@ -131,7 +131,7 @@ You don't want to have to type everytime a long list of arguments. No problem, y > -ssl_key_file server.key \ > -ssl_listen :443 \ > -config_save - 2022/02/14 10:37:00 rdio-scanner.ini file created + 2022/02/17 10:37:00 rdio-scanner.ini file created All of your parameters passed as arguments to [Rdio Scanner](https://github.com/chuot/rdio-scanner) have been saved to an INI file which has the same arguments/values list. @@ -148,12 +148,12 @@ Then simply run [Rdio Scanner](https://github.com/chuot/rdio-scanner) without an Password: root@pc-freebsd:/home/rdio/rdio-scanner # ./rdio-scanner - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 10:38:28 server started - 2022/02/14 10:38:29 main interface at http://pc-freebsd - 2022/02/14 10:38:29 main interface at https://pc-freebsd - 2022/02/14 10:38:29 admin interface at https://pc-freebsd/admin + 2022/02/17 10:38:28 server started + 2022/02/17 10:38:29 main interface at http://pc-freebsd + 2022/02/17 10:38:29 main interface at https://pc-freebsd + 2022/02/17 10:38:29 admin interface at https://pc-freebsd/admin ## Install Rdio Scanner as a service diff --git a/docs/platforms/linux.md b/docs/platforms/linux.md index fc5cef4..c3726d0 100644 --- a/docs/platforms/linux.md +++ b/docs/platforms/linux.md @@ -42,8 +42,8 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd [rdio@pc-linux ~]$ mkdir rdio-scanner [rdio@pc-linux ~]$ cd rdio-scanner [rdio@pc-linux rdio-scanner]$ unzip \ - > ~/Downloads/rdio-scanner-linux-amd64-v6.1.12.zip - Archive: /home/rdio/Downloads/rdio-scanner-linux-amd64-v6.1.12.zip + > ~/Downloads/rdio-scanner-linux-amd64-v6.1.13.zip + Archive: /home/rdio/Downloads/rdio-scanner-linux-amd64-v6.1.13.zip inflating: rdio-scanner inflating: rdio-scanner.pdf @@ -51,11 +51,11 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd [rdio@pc-linux rdio-scanner]$ ./rdio-scanner - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 09:11:48 server started - 2022/02/14 09:11:48 main interface at http://pc-linux:3000 - 2022/02/14 09:11:48 admin interface at http://pc-linux:3000/admin + 2022/02/17 09:11:48 server started + 2022/02/17 09:11:48 main interface at http://pc-linux:3000 + 2022/02/17 09:11:48 admin interface at http://pc-linux:3000/admin 4. Access the administrative dashboard to finalize the configuration. @@ -78,11 +78,11 @@ Here we want our [Rdio Scanner](https://guthub.com/chuot/rdio-scanner) instance [rdio@pc-linux rdio-scanner]$ sudo ./rdio-scanner -listen :80 [sudo] password for rdio: - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 09:14:00 server started - 2022/02/14 09:14:00 main interface at http://pc-linux - 2022/02/14 09:14:00 admin interface at http://pc-linux/admin + 2022/02/17 09:14:00 server started + 2022/02/17 09:14:00 main interface at http://pc-linux + 2022/02/17 09:14:00 admin interface at http://pc-linux/admin ## Listening with SSL with self-signed certificates @@ -91,8 +91,8 @@ It is advised to share your [Rdio Scanner](https://github.com/chuot/rdio-scanner We can create such self-signed certificates by running [Rdio Scanner](https://github.com/chuot/rdio-scanner) with the **-ssl_create** argument. [rdio@pc-linux rdio-scanner]$ ./rdio-scanner -ssl_create - 2022/02/14 09:15:03 generating ssl certificate files - 2022/02/14 09:15:05 ssl files created + 2022/02/17 09:15:03 generating ssl certificate files + 2022/02/17 09:15:05 ssl files created This has generated these files in the same folder as your [Rdio Scanner](https://github.com/chuot/rdio-scanner) executable. @@ -110,12 +110,12 @@ Now we use the self-signed server certificate to run our instance. > -ssl_listen :443 [sudo] password for rdio: - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 09:16:47 server started - 2022/02/14 09:16:47 main interface at http://pc-linux - 2022/02/14 09:16:47 main interface at https://pc-linux - 2022/02/14 09:16:47 admin interface at https://pc-linux/admin + 2022/02/17 09:16:47 server started + 2022/02/17 09:16:47 main interface at http://pc-linux + 2022/02/17 09:16:47 main interface at https://pc-linux + 2022/02/17 09:16:47 admin interface at https://pc-linux/admin ## Save your advanced configuration to a config file @@ -127,7 +127,7 @@ You don't want to have to type everytime a long list of arguments. No problem, y > -ssl_key_file server.key \ > -ssl_listen :443 \ > -config_save - 2022/02/14 09:19:29 rdio-scanner.ini file created + 2022/02/17 09:19:29 rdio-scanner.ini file created All of your parameters passed as arguments to [Rdio Scanner](https://github.com/chuot/rdio-scanner) have been saved to an INI file which has the same arguments/values list. @@ -143,12 +143,12 @@ Then simply run [Rdio Scanner](https://github.com/chuot/rdio-scanner) without an [rdio@pc-linux rdio-scanner]$ sudo ./rdio-scanner [sudo] Mot de passe de rdio : - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 09:20:40 server started - 2022/02/14 09:20:40 main interface at http://pc-linux - 2022/02/14 09:20:40 main interface at https://pc-linux - 2022/02/14 09:20:40 admin interface at https://pc-linux/admin + 2022/02/17 09:20:40 server started + 2022/02/17 09:20:40 main interface at http://pc-linux + 2022/02/17 09:20:40 main interface at https://pc-linux + 2022/02/17 09:20:40 admin interface at https://pc-linux/admin ## Install Rdio Scanner as a service diff --git a/docs/platforms/windows.md b/docs/platforms/windows.md index f068c42..53fbc0d 100644 --- a/docs/platforms/windows.md +++ b/docs/platforms/windows.md @@ -44,7 +44,7 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd C:\Users\rdio> cd rdio-scanner C:\Users\rdio\rdio-scanner> tar -xvf ^ - ..\downloads\rdio-scanner-windows-amd64-v6.1.12.zip + ..\downloads\rdio-scanner-windows-amd64-v6.1.13.zip x rdio-scanner.exe x rdio-scanner.pdf @@ -52,11 +52,11 @@ ALWAYS DOWNLOAD THE LATEST VERSION OF [RDIO SCANNER](https://github.com/chuot/rd C:\Users\rdio\rdio-scanner>rdio-scanner - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 13:48:48 server started - 2022/02/14 13:48:48 main interface at http://pc-windows:3000 - 2022/02/14 13:48:48 admin interface at http://pc-windows:3000/admin + 2022/02/17 13:48:48 server started + 2022/02/17 13:48:48 main interface at http://pc-windows:3000 + 2022/02/17 13:48:48 admin interface at http://pc-windows:3000/admin 4. Access the administrative dashboard to finalize the configuration. @@ -78,11 +78,11 @@ Here we want our [Rdio Scanner](https://guthub.com/chuot/rdio-scanner) instance C:\Users\rdio\rdio-scanner>rdio-scanner -listen :80 - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 10:53:31 server started - 2022/02/14 10:53:31 main interface at http://pc-windows - 2022/02/14 10:53:31 admin interface at http://pc-windows/admin + 2022/02/17 10:53:31 server started + 2022/02/17 10:53:31 main interface at http://pc-windows + 2022/02/17 10:53:31 admin interface at http://pc-windows/admin ## Listening with SSL with self-signed certificates @@ -91,8 +91,8 @@ It is advised to share your [Rdio Scanner](https://github.com/chuot/rdio-scanner We can create such self-signed certificates by running [Rdio Scanner](https://github.com/chuot/rdio-scanner) with the **-ssl_create** argument. C:\Users\rdio\rdio-scanner>rdio-scanner -ssl_create - 2022/02/14 10:58:51 generating ssl certificate files - 2022/02/14 10:58:54 ssl files created + 2022/02/17 10:58:51 generating ssl certificate files + 2022/02/17 10:58:54 ssl files created This has generated these files in the same folder as your [Rdio Scanner](https://github.com/chuot/rdio-scanner) executable. @@ -109,12 +109,12 @@ Now we use the self-signed server certificate to run our instance. -ssl_key_file server.key ^ -ssl_listen :443 - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 11:05:43 server started - 2022/02/14 11:05:43 main interface at http://pc-windows - 2022/02/14 11:05:43 main interface at https://pc-windows - 2022/02/14 11:05:43 admin interface at https://pc-windows/admin + 2022/02/17 11:05:43 server started + 2022/02/17 11:05:43 main interface at http://pc-windows + 2022/02/17 11:05:43 main interface at https://pc-windows + 2022/02/17 11:05:43 admin interface at https://pc-windows/admin ## Save your advanced configuration to a config file @@ -126,7 +126,7 @@ You don't want to have to type everytime a long list of arguments. No problem, y -ssl_key_file server.key ^ -ssl_listen :443 ^ -config_save - 2022/02/14 11:08:28 rdio-scanner.ini file created + 2022/02/17 11:08:28 rdio-scanner.ini file created All of your parameters passed as arguments to [Rdio Scanner](https://github.com/chuot/rdio-scanner) have been saved to an INI file which has the same arguments/values list. @@ -141,12 +141,12 @@ Then simply run [Rdio Scanner](https://github.com/chuot/rdio-scanner) without an C:\Users\rdio\rdio-scanner>rdio-scanner - Rdio Scanner v6.1.12 + Rdio Scanner v6.1.13 ---------------------------------- - 2022/02/14 11:11:28 server started - 2022/02/14 11:11:28 main interface at http://pc-windows - 2022/02/14 11:11:28 main interface at https://pc-windows - 2022/02/14 11:11:28 admin interface at https://pc-windows/admin + 2022/02/17 11:11:28 server started + 2022/02/17 11:11:28 main interface at http://pc-windows + 2022/02/17 11:11:28 main interface at https://pc-windows + 2022/02/17 11:11:28 admin interface at https://pc-windows/admin \pagebreak{} @@ -206,9 +206,7 @@ To get the whole list of arguments you can pass to [Rdio Scanner](https://github listening address for ssl -version show application version - C:\Users\rdio\rdio-scanner> - \pagebreak{} # Need help ? diff --git a/server/admin.go b/server/admin.go index 5b38e80..5d2b276 100644 --- a/server/admin.go +++ b/server/admin.go @@ -30,14 +30,6 @@ import ( "golang.org/x/crypto/bcrypt" ) -const ( - AdminUrlConfig = "api/admin/config" - AdminUrlLogin = "api/admin/login" - AdminUrlLogout = "api/admin/logout" - AdminUrlLogs = "api/admin/logs" - AdminUrlPassword = "api/admin/password" -) - type Admin struct { Attempts AdminLoginAttempts AttemptsMax uint diff --git a/server/api.go b/server/api.go index a1b1f9e..8151288 100644 --- a/server/api.go +++ b/server/api.go @@ -24,11 +24,6 @@ import ( "strings" ) -const ( - ApiUrlCallUpload = "api/call-upload" - ApiUrlTrunkRecorderCallUpload = "api/trunk-recorder-call-upload" -) - type Api struct { Controller *Controller } diff --git a/server/client.go b/server/client.go index 8faca22..2a449d8 100644 --- a/server/client.go +++ b/server/client.go @@ -39,6 +39,13 @@ type Client struct { } func (client *Client) Init(controller *Controller, conn *websocket.Conn) error { + const ( + pongWait = 60 * time.Second + pingPeriod = pongWait / 10 * 9 + writeWait = 10 * time.Second + closeWait = 10 * time.Second + ) + if client.initialized { return errors.New("client.init: already initialized") } @@ -56,7 +63,17 @@ func (client *Client) Init(controller *Controller, conn *websocket.Conn) error { controller.Register <- client go func() { - client.Conn.SetReadDeadline(time.Time{}) + defer func() { + controller.Unregister <- client + client.Conn.Close() + }() + + client.Conn.SetReadDeadline(time.Now().Add(pongWait)) + + client.Conn.SetPongHandler(func(string) error { + client.Conn.SetReadDeadline(time.Now().Add(pongWait)) + return nil + }) for { _, b, err := client.Conn.ReadMessage() @@ -75,28 +92,43 @@ func (client *Client) Init(controller *Controller, conn *websocket.Conn) error { continue } } - - controller.Unregister <- client }() go func() { - ticker := time.NewTicker(30 * time.Second) + ticker := time.NewTicker(pingPeriod) + + timer := time.AfterFunc(writeWait, func() { + client.Conn.Close() + }) defer func() { - ticker.Stop() controller.Unregister <- client + + ticker.Stop() + timer.Stop() + + client.Conn.SetWriteDeadline(time.Now().Add(writeWait)) + client.Conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) + + time.Sleep(closeWait) + client.Conn.Close() }() + Loop: for { select { case message, ok := <-client.Send: if !ok { - return + break Loop } if client.Conn == nil { - return + break Loop + } + + if message.Command == MessageCommandConfig { + timer.Stop() } b, err := message.ToJson() @@ -104,18 +136,16 @@ func (client *Client) Init(controller *Controller, conn *websocket.Conn) error { log.Println(fmt.Errorf("client.message.tojson: %v", err)) } else { - client.Conn.SetWriteDeadline(time.Now().Add(30 * time.Second)) + client.Conn.SetWriteDeadline(time.Now().Add(writeWait)) if err = client.Conn.WriteMessage(websocket.TextMessage, b); err != nil { - return + break Loop } } case <-ticker.C: - client.Conn.SetWriteDeadline(time.Now().Add(30 * time.Second)) - - if err := client.Conn.WriteMessage(websocket.PingMessage, nil); err != nil { - return + if err := client.Conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(writeWait)); err != nil { + break Loop } } } diff --git a/server/controller.go b/server/controller.go index 511906e..fa8ba87 100644 --- a/server/controller.go +++ b/server/controller.go @@ -28,6 +28,7 @@ import ( "strconv" "strings" "sync" + "time" ) type Controller struct { @@ -647,6 +648,15 @@ func (controller *Controller) Start() error { }() go func() { + var timer *time.Timer + + logClientsCount := func() { + if timer != nil { + timer.Stop() + } + timer = time.AfterFunc(time.Second, controller.LogClientsCount) + } + for { select { case call := <-controller.Ingest: @@ -654,13 +664,13 @@ func (controller *Controller) Start() error { case client := <-controller.Register: controller.Clients[client] = true - controller.LogClientsCount() + logClientsCount() case client := <-controller.Unregister: if _, ok := controller.Clients[client]; ok { delete(controller.Clients, client) close(client.Send) - controller.LogClientsCount() + logClientsCount() } } } diff --git a/server/database.go b/server/database.go index 46eba2a..93ce4ca 100644 --- a/server/database.go +++ b/server/database.go @@ -42,7 +42,7 @@ func NewDatabase(config *Config) *Database { case DbTypeSqlite: database.DateTimeFormat = "2006-01-02 15:04:05.000 -07:00" - dsn := fmt.Sprintf("file:%s", config.GetDbFilePath()) + dsn := fmt.Sprintf("file:%s?_pragma=busy_timeout%%3d10000", config.GetDbFilePath()) if database.Sql, err = sql.Open("sqlite", dsn); err != nil { log.Fatal(err) @@ -61,10 +61,9 @@ func NewDatabase(config *Config) *Database { log.Fatalf("unknown database type %s\n", config.DbType) } - database.Sql.SetConnMaxIdleTime(time.Second * 5) - database.Sql.SetConnMaxLifetime(0) - database.Sql.SetMaxIdleConns(64) - database.Sql.SetMaxOpenConns(64) + database.Sql.SetConnMaxLifetime(5 * time.Minute) + database.Sql.SetMaxIdleConns(25) + database.Sql.SetMaxOpenConns(25) if err = database.migrate(); err != nil { log.Fatal(err) diff --git a/server/go.mod b/server/go.mod index df7fd5f..77b8706 100644 --- a/server/go.mod +++ b/server/go.mod @@ -10,7 +10,7 @@ require ( github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.4.2 github.com/kardianos/service v1.2.1 - golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2 + golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 gopkg.in/ini.v1 v1.66.4 modernc.org/sqlite v1.14.6 ) @@ -21,7 +21,7 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/stretchr/testify v1.7.0 // indirect golang.org/x/mod v0.5.1 // indirect - golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.9 // indirect diff --git a/server/go.sum b/server/go.sum index 076dfee..cadf50a 100644 --- a/server/go.sum +++ b/server/go.sum @@ -37,8 +37,8 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2 h1:XdAboW3BNMv9ocSCOk/u1MFioZGzCNkiJZ19v9Oe3Ig= -golang.org/x/crypto v0.0.0-20220210151621-f4118a5b28e2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 h1:EuGTJDfeg/PGZJp3gq1K+14eSLFTsrj1eg8KQuiUyKg= +golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= @@ -46,9 +46,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -65,11 +64,9 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/server/main.go b/server/main.go index f8c263f..bec1b31 100644 --- a/server/main.go +++ b/server/main.go @@ -16,13 +16,16 @@ package main import ( + "crypto/tls" "fmt" + "io/ioutil" "log" "mime" "net/http" "os" "path" "strings" + "time" "github.com/gorilla/websocket" "golang.org/x/crypto/acme/autocert" @@ -101,76 +104,66 @@ func main() { sslAddr = defaultAddr } + http.HandleFunc("/api/admin/config", controller.Admin.ConfigHandler) + + http.HandleFunc("/api/admin/login", controller.Admin.LoginHandler) + + http.HandleFunc("/api/admin/logout", controller.Admin.LogoutHandler) + + http.HandleFunc("/api/admin/logs", controller.Admin.LogsHandler) + + http.HandleFunc("/api/admin/password", controller.Admin.PasswordHandler) + + http.HandleFunc("/api/call-upload", controller.Api.CallUploadHandler) + + http.HandleFunc("/api/trunk-recorder-call-upload", controller.Api.TrunkRecorderCallUploadHandler) + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { url := r.URL.Path[1:] - switch url { - case AdminUrlConfig: - controller.Admin.ConfigHandler(w, r) + if strings.EqualFold(r.Header.Get("upgrade"), "websocket") { + upgrader := websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, + } - case AdminUrlLogin: - controller.Admin.LoginHandler(w, r) + conn, err := upgrader.Upgrade(w, r, nil) + if err != nil { + log.Println(err) + } - case AdminUrlLogout: - controller.Admin.LogoutHandler(w, r) + client := &Client{} + if err = client.Init(controller, conn); err != nil { + log.Println(err) + } - case AdminUrlLogs: - controller.Admin.LogsHandler(w, r) + } else { + if url == "" { + url = "index.html" + } - case AdminUrlPassword: - controller.Admin.PasswordHandler(w, r) - - case ApiUrlCallUpload: - controller.Api.CallUploadHandler(w, r) - - case ApiUrlTrunkRecorderCallUpload: - controller.Api.TrunkRecorderCallUploadHandler(w, r) - - default: - if strings.EqualFold(r.Header.Get("upgrade"), "websocket") { - upgrader := websocket.Upgrader{ - CheckOrigin: func(r *http.Request) bool { - return true - }, + if b, err := webapp.ReadFile(path.Join("webapp", url)); err == nil { + var t string + switch path.Ext(url) { + case ".js": + t = "text/javascript" // see https://github.com/golang/go/issues/32350 + default: + t = mime.TypeByExtension(path.Ext(url)) } + w.Header().Set("Content-Type", t) + w.Write(b) - conn, err := upgrader.Upgrade(w, r, nil) - if err != nil { - log.Println(err) - } - - client := &Client{} - if err = client.Init(controller, conn); err != nil { - log.Println(err) - } - - } else { - if url == "" { - url = "index.html" - } - - if b, err := webapp.ReadFile(path.Join("webapp", url)); err == nil { - var t string - switch path.Ext(url) { - case ".js": - t = "text/javascript" // see https://github.com/golang/go/issues/32350 - default: - t = mime.TypeByExtension(path.Ext(url)) - } - w.Header().Set("Content-Type", t) + } else if url[:len(url)-1] != "/" { + if b, err := webapp.ReadFile("webapp/index.html"); err == nil { w.Write(b) - } else if url[:len(url)-1] != "/" { - if b, err := webapp.ReadFile("webapp/index.html"); err == nil { - w.Write(b) - - } else { - w.WriteHeader(http.StatusNotFound) - } - } else { w.WriteHeader(http.StatusNotFound) } + + } else { + w.WriteHeader(http.StatusNotFound) } } }) @@ -192,6 +185,21 @@ func main() { } } + newServer := func(addr string, tlsConfig *tls.Config) *http.Server { + s := &http.Server{ + Addr: addr, + TLSConfig: tlsConfig, + ReadTimeout: 60 * time.Second, + WriteTimeout: 60 * time.Second, + IdleTimeout: 120 * time.Second, + ErrorLog: log.New(ioutil.Discard, "", 0), + } + + s.SetKeepAlivesEnabled(true) + + return s + } + if len(controller.Config.SslCertFile) > 0 && len(controller.Config.SslKeyFile) > 0 { go func() { sslPrintInfo() @@ -199,7 +207,9 @@ func main() { sslCert := controller.Config.GetSslCertFilePath() sslKey := controller.Config.GetSslKeyFilePath() - if err := http.ListenAndServeTLS(fmt.Sprintf("%s:%s", sslAddr, sslPort), sslCert, sslKey, nil); err != nil { + server := newServer(fmt.Sprintf("%s:%s", sslAddr, sslPort), nil) + + if err := server.ListenAndServeTLS(sslCert, sslKey); err != nil { log.Fatal(err) } }() @@ -214,10 +224,7 @@ func main() { HostPolicy: autocert.HostWhitelist(controller.Config.SslAutoCert), } - server := &http.Server{ - Addr: fmt.Sprintf("%s:%s", sslAddr, sslPort), - TLSConfig: manager.TLSConfig(), - } + server := newServer(fmt.Sprintf("%s:%s", sslAddr, sslPort), manager.TLSConfig()) if err := server.ListenAndServeTLS("", ""); err != nil { log.Fatal(err) @@ -231,7 +238,9 @@ func main() { log.Printf("admin interface at http://%s:%s/admin", hostname, port) } - if err := http.ListenAndServe(fmt.Sprintf("%s:%s", addr, port), nil); err != nil { + server := newServer(fmt.Sprintf("%s:%s", addr, port), nil) + + if err := server.ListenAndServe(); err != nil { log.Fatal(err) } } diff --git a/server/version.go b/server/version.go index 0aa0e3b..d7a3146 100644 --- a/server/version.go +++ b/server/version.go @@ -15,4 +15,4 @@ package main -const Version = "6.1.12" +const Version = "6.1.13"