Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package goaccess for openSUSE:Factory checked in at 2022-07-05 12:09:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/goaccess (Old) and /work/SRC/openSUSE:Factory/.goaccess.new.1548 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "goaccess" Tue Jul 5 12:09:07 2022 rev:22 rq:986593 version:1.6.1 Changes: -------- --- /work/SRC/openSUSE:Factory/goaccess/goaccess.changes 2022-06-01 17:35:26.870796513 +0200 +++ /work/SRC/openSUSE:Factory/.goaccess.new.1548/goaccess.changes 2022-07-05 12:09:40.948574162 +0200 @@ -1,0 +2,15 @@ +Mon Jul 4 09:22:38 UTC 2022 - Michael Vetter <[email protected]> + +- Update to 1.6.1: + * Added a `--ping-interval=<secs>` in an attempt to keep the WebSocket + connection opened. + * Added support for timezone conversion via `--datetime-format=<format>` and + `--tz=<timezone>`. + * Added the ability to reconnect to WebSocket server after 1 sec with + exponential backoff (x20). + * Fixed issue where an invalid client connection would stall data out to + clients via the WebSocket server. + * Fixed issue where real-time data would be parsed multiple times under + `Cygwin`. + +------------------------------------------------------------------- Old: ---- goaccess-1.6.tar.gz New: ---- goaccess-1.6.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ goaccess.spec ++++++ --- /var/tmp/diff_new_pack.HandtV/_old 2022-07-05 12:09:41.452574886 +0200 +++ /var/tmp/diff_new_pack.HandtV/_new 2022-07-05 12:09:41.456574891 +0200 @@ -1,4 +1,3 @@ -# vim: set sw=4 ts=4 et nu: # # spec file for package goaccess # @@ -21,7 +20,7 @@ %global goaccess_services [email protected] [email protected] Name: goaccess -Version: 1.6 +Version: 1.6.1 Release: 0 Summary: Apache Web Log Analyzer License: GPL-2.0-or-later ++++++ goaccess-1.6.tar.gz -> goaccess-1.6.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/AUTHORS new/goaccess-1.6.1/AUTHORS --- old/goaccess-1.6/AUTHORS 2022-06-01 05:34:16.000000000 +0200 +++ new/goaccess-1.6.1/AUTHORS 2022-06-30 16:17:12.000000000 +0200 @@ -80,6 +80,7 @@ * kyle sloan <[email protected]> * LeoAttn <[email protected]> * Maksim Losev <[email protected]> + * mario-donnarumma <[email protected]> * markiewb <[email protected]> * Mark J. Berger <[email protected]> * Martins Polakovs <[email protected]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/ChangeLog new/goaccess-1.6.1/ChangeLog --- old/goaccess-1.6/ChangeLog 2022-06-01 05:04:44.000000000 +0200 +++ new/goaccess-1.6.1/ChangeLog 2022-06-30 16:17:12.000000000 +0200 @@ -1,3 +1,16 @@ +Changes to GoAccess 1.6.1 - Thursday, June 30, 2022 + + - Added a `--ping-interval=<secs>` in an attempt to keep the WebSocket + connection opened. + - Added support for timezone conversion via `--datetime-format=<format>` and + `--tz=<timezone>`. + - Added the ability to reconnect to WebSocket server after 1 sec with + exponential backoff (x20). + - Fixed issue where an invalid client connection would stall data out to + clients via the WebSocket server. + - Fixed issue where real-time data would be parsed multiple times under + `Cygwin`. + Changes to GoAccess 1.6 - Tuesday, May 31, 2022 - Changed slightly how the XFF field is specified. See man page for details. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/NEWS new/goaccess-1.6.1/NEWS --- old/goaccess-1.6/NEWS 2022-06-01 04:56:02.000000000 +0200 +++ new/goaccess-1.6.1/NEWS 2022-06-30 16:17:12.000000000 +0200 @@ -2,6 +2,8 @@ Gerardo Orellana <[email protected]> * Version history: + - 1.6.1 [Thursday, June 30 , 2022] + . GoAccess 1.6.1 Released. See ChangeLog for new features/bug-fixes. - 1.6 [Tuesday, May 31 , 2022] . GoAccess 1.6 Released. See ChangeLog for new features/bug-fixes. - 1.5.7 [Thursday, April 28 , 2022] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/config/goaccess.conf new/goaccess-1.6.1/config/goaccess.conf --- old/goaccess-1.6/config/goaccess.conf 2022-05-27 04:06:44.000000000 +0200 +++ new/goaccess-1.6.1/config/goaccess.conf 2022-06-25 18:26:16.000000000 +0200 @@ -52,6 +52,21 @@ #date-format %s ###################################### +# Date/Time Format Option +###################################### +# +# The datetime-format variable followed by a space, specifies +# the log format date and time containing any combination of regular +# characters and special format specifiers. They all begin with a +# percentage (%) sign. See `man strftime` +# +# This gives the ability to get the timezone from a request and +# convert it to another timezone for output. See --tz=<timezone> in +# the man page. +# +#datetime-format %d/%b/%Y:%H:%M:%S %z + +###################################### # Log Format Options (required) ###################################### # @@ -194,6 +209,12 @@ # #no-html-last-updated true +# Ouputs the report date/time data in the given timezone. Note that it +# uses the canonical timezone name. See --datetime-format in order to +# properly specify a timezone in the date/time format. +# +#tz Europe/Berlin + # Enable mouse support on main dashboard. # with-mouse false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/configure new/goaccess-1.6.1/configure --- old/goaccess-1.6/configure 2022-06-01 05:34:51.000000000 +0200 +++ new/goaccess-1.6.1/configure 2022-06-30 16:17:26.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for goaccess 1.6. +# Generated by GNU Autoconf 2.69 for goaccess 1.6.1. # # Report bugs to <[email protected]>. # @@ -580,8 +580,8 @@ # Identity of this package. PACKAGE_NAME='goaccess' PACKAGE_TARNAME='goaccess' -PACKAGE_VERSION='1.6' -PACKAGE_STRING='goaccess 1.6' +PACKAGE_VERSION='1.6.1' +PACKAGE_STRING='goaccess 1.6.1' PACKAGE_BUGREPORT='[email protected]' PACKAGE_URL='https://goaccess.io' @@ -1333,7 +1333,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures goaccess 1.6 to adapt to many kinds of systems. +\`configure' configures goaccess 1.6.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1404,7 +1404,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of goaccess 1.6:";; + short | recursive ) echo "Configuration of goaccess 1.6.1:";; esac cat <<\_ACEOF @@ -1514,7 +1514,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -goaccess configure 1.6 +goaccess configure 1.6.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2067,7 +2067,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by goaccess $as_me 1.6, which was +It was created by goaccess $as_me 1.6.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2934,7 +2934,7 @@ # Define the identity of the package. PACKAGE='goaccess' - VERSION='1.6' + VERSION='1.6.1' cat >>confdefs.h <<_ACEOF @@ -9097,6 +9097,17 @@ fi done +for ac_func in timegm +do : + ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm" +if test "x$ac_cv_func_timegm" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TIMEGM 1 +_ACEOF + +fi +done + ac_config_files="$ac_config_files Makefile po/Makefile.in" @@ -9658,7 +9669,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by goaccess $as_me 1.6, which was +This file was extended by goaccess $as_me 1.6.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -9725,7 +9736,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -goaccess config.status 1.6 +goaccess config.status 1.6.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/configure.ac new/goaccess-1.6.1/configure.ac --- old/goaccess-1.6/configure.ac 2022-06-01 04:51:48.000000000 +0200 +++ new/goaccess-1.6.1/configure.ac 2022-06-30 16:17:12.000000000 +0200 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([goaccess],[1.6],[[email protected]],[],[https://goaccess.io]) +AC_INIT([goaccess],[1.6.1],[[email protected]],[],[https://goaccess.io]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/goaccess.c]) AC_CONFIG_HEADERS([src/config.h]) @@ -243,6 +243,7 @@ AC_CHECK_FUNCS([strstr]) AC_CHECK_FUNCS([strtol]) AC_CHECK_FUNCS([strtoull]) +AC_CHECK_FUNCS([timegm]) AC_CONFIG_FILES([Makefile po/Makefile.in]) AC_OUTPUT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/goaccess.1 new/goaccess-1.6.1/goaccess.1 --- old/goaccess-1.6/goaccess.1 2022-06-01 05:32:59.000000000 +0200 +++ new/goaccess-1.6.1/goaccess.1 2022-06-30 16:17:12.000000000 +0200 @@ -1,4 +1,4 @@ -.TH goaccess 1 "MAY 2022" GNU+Linux "User Manuals" +.TH goaccess 1 "JUNE 2022" GNU+Linux "User Manuals" .SH NAME goaccess \- fast web log analyzer and interactive viewer. .SH SYNOPSIS @@ -204,6 +204,19 @@ .I %* must be used as date-format. .TP +\fB\-\-datetime-format=<date_time_format> +The date and time format combines the two variables into a single option. This +gives the ability to get the timezone from a request and convert it to another +timezone for output. See +.I --tz=<timezone> +.IP +They all begin with a percentage (%) sign. See `man strftime`. e.g., +.I %d/%b/%Y:%H:%M:%S %z. +.IP +Note that if --datetime-format is used, +.I %x +must be passed in the log-format variable to represent the date and time field. +.TP \fB\-\-log-format=<logformat> The log-format variable followed by a space or .I \\\\t @@ -374,6 +387,18 @@ .TP \fB\-\-no-parsing-spinner Do now show the progress metrics and parsing spinner. +.TP +\fB\-\-tz=<timezone> +Ouputs the report date/time data in the given timezone. Note that it uses the +canonical timezone name. e.g., +.I Europe/Berlin +or +.I America/Chicago +or +.I Africa/Cairo +If an invalid timezone name is given, the ouput will be in GMT. See +.I --datetime-format +in order to properly specify a timezone in the date/time format. .SS SERVER OPTIONS .P @@ -443,6 +468,10 @@ GoAccess is running on a remote server, the host of the remote server should be specified here. Also, make sure it is a valid host and NOT an http address. .TP +\fB\-\-ping-interval=<secs> +Enable WebSocket ping with specified interval in seconds. This helps prevent +idle connections getting disconnected. +.TP \fB\-\-fifo-in=<path/file> Creates a named pipe (FIFO) that reads from on the given path/file. .TP @@ -1238,6 +1267,9 @@ .P A hit is a request (line in the access log), e.g., 10 requests = 10 hits. HTTP requests with the same IP, date, and user agent are considered a unique visit. +.P +The generated report will attempt to reconnect to the WebSocket server after 1 +second with exponential backoff. It will attempt to connect 20 times. .SH BUGS If you think you have found a bug, please send me an email to .I [email protected] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/de.po new/goaccess-1.6.1/po/de.po --- old/goaccess-1.6/po/de.po 2022-06-01 05:35:17.000000000 +0200 +++ new/goaccess-1.6.1/po/de.po 2022-06-30 16:17:12.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2019-05-05 16:03+0200\n" "Last-Translator: Axel Wehner <[email protected]>\n" "Language: de\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/es.po new/goaccess-1.6.1/po/es.po --- old/goaccess-1.6/po/es.po 2022-06-01 05:35:17.000000000 +0200 +++ new/goaccess-1.6.1/po/es.po 2022-06-30 16:17:12.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Goaccess\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2017-08-04 13:00-0300\n" "Last-Translator: Enrique Becerra <[email protected]>\n" "Language-Team: \n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/fr.po new/goaccess-1.6.1/po/fr.po --- old/goaccess-1.6/po/fr.po 2022-06-01 05:35:17.000000000 +0200 +++ new/goaccess-1.6.1/po/fr.po 2022-06-30 16:17:12.000000000 +0200 @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: goaccess 1.4\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2020-07-10 11:44+0200\n" "Last-Translator: Coban L. <[email protected]>\n" "Language-Team: fran??ais\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/goaccess.pot new/goaccess-1.6.1/po/goaccess.pot --- old/goaccess-1.6/po/goaccess.pot 2022-06-01 05:35:17.000000000 +0200 +++ new/goaccess-1.6.1/po/goaccess.pot 2022-06-30 16:17:12.000000000 +0200 @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: goaccess 1.6\n" +"Project-Id-Version: goaccess 1.6.1\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <[email protected]>\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/it.po new/goaccess-1.6.1/po/it.po --- old/goaccess-1.6/po/it.po 2022-06-01 05:35:18.000000000 +0200 +++ new/goaccess-1.6.1/po/it.po 2022-06-30 16:17:12.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Goaccess\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2017-08-04 13:00-0300\n" "Last-Translator: Mario Donnarumma <[email protected]>\n" "Language-Team: \n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/ja.po new/goaccess-1.6.1/po/ja.po --- old/goaccess-1.6/po/ja.po 2022-06-01 05:35:17.000000000 +0200 +++ new/goaccess-1.6.1/po/ja.po 2022-06-30 16:17:12.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: goaccess 1.3\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2020-08-19 06:27+0900\n" "Last-Translator: Kamino <[email protected]>\n" "Language-Team: Japanese\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/pt_BR.po new/goaccess-1.6.1/po/pt_BR.po --- old/goaccess-1.6/po/pt_BR.po 2022-06-01 05:35:18.000000000 +0200 +++ new/goaccess-1.6.1/po/pt_BR.po 2022-06-30 16:17:12.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Goaccess\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2019-04-25 20:34-0300\n" "Last-Translator: Alan Placidina Maria <[email protected]>\n" "Language-Team: \n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/ru.po new/goaccess-1.6.1/po/ru.po --- old/goaccess-1.6/po/ru.po 2022-06-01 05:35:18.000000000 +0200 +++ new/goaccess-1.6.1/po/ru.po 2022-06-30 16:18:42.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: goaccess 1.5.6\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2022-04-21 10:17+0300\n" "Last-Translator: Artyom Karlov <[email protected]>\n" "Language-Team: \n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/sv.po new/goaccess-1.6.1/po/sv.po --- old/goaccess-1.6/po/sv.po 2022-06-01 05:35:18.000000000 +0200 +++ new/goaccess-1.6.1/po/sv.po 2022-06-30 16:17:12.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: goaccess 1.3\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2018-12-13 22:48-0600\n" "Last-Translator: Anders Johansson <[email protected]>\n" "Language-Team: none\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/uk.po new/goaccess-1.6.1/po/uk.po --- old/goaccess-1.6/po/uk.po 2022-06-01 05:35:18.000000000 +0200 +++ new/goaccess-1.6.1/po/uk.po 2022-06-30 16:18:42.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: goaccess 1.5.6\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2022-04-21 10:17+0300\n" "Last-Translator: Artyom Karlov <[email protected]>\n" "Language-Team: \n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/po/zh_CN.po new/goaccess-1.6.1/po/zh_CN.po --- old/goaccess-1.6/po/zh_CN.po 2022-06-01 05:35:18.000000000 +0200 +++ new/goaccess-1.6.1/po/zh_CN.po 2022-06-30 16:17:12.000000000 +0200 @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: goaccess 1.5.6\n" "Report-Msgid-Bugs-To: [email protected]\n" -"POT-Creation-Date: 2022-05-31 22:35-0500\n" +"POT-Creation-Date: 2022-06-30 08:32-0500\n" "PO-Revision-Date: 2017-04-03 09:43+0200\n" "Last-Translator: Ai<[email protected]>\n" "Language-Team: Ai\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/resources/js/app.js new/goaccess-1.6.1/resources/js/app.js --- old/goaccess-1.6/resources/js/app.js 2022-05-31 18:47:25.000000000 +0200 +++ new/goaccess-1.6.1/resources/js/app.js 2022-06-30 16:17:04.000000000 +0200 @@ -56,6 +56,12 @@ }; this.AppPrefs = GoAccess.Util.merge(this.AppPrefs, this.opts.prefs); + // WebSocket reconnection + this.wsDelay = this.currDelay = 1E3; + this.maxDelay = 20E3; + this.retries = 0; + this.maxRetries = 20; + if (GoAccess.Util.hasLocalStorage()) { var ls = JSON.parse(localStorage.getItem('AppPrefs')); this.AppPrefs = GoAccess.Util.merge(this.AppPrefs, ls); @@ -83,14 +89,31 @@ return panel ? this.AppData[panel] : this.AppData; }, + reconnect: function (wsConn) { + if (this.retries >= this.maxRetries) + return window.clearTimeout(this.wsTimer); + + this.retries++; + if (this.currDelay < this.maxDelay) + this.currDelay *= 2; // Exponential backoff + this.setWebSocket(wsConn); + }, + setWebSocket: function (wsConn) { - var host = null; + var host = null, pingId = null; host = wsConn.url ? wsConn.url : window.location.hostname ? window.location.hostname : "localhost"; var str = /^(wss?:\/\/)?[^\/]+:[0-9]{1,5}\//.test(host + "/") ? host : String(host + ':' + wsConn.port); str = !/^wss?:\/\//i.test(str) ? (window.location.protocol === "https:" ? 'wss://' : 'ws://') + str : str; var socket = new WebSocket(str); socket.onopen = function (event) { + this.currDelay = this.wsDelay; + this.retries = 0; + + // attempt to keep connection alive (e.g., ping/pong) + if (wsConn.ping_interval) + pingId = setInterval(() => { socket.send('ping'); }, wsConn.ping_interval * 1E3); + GoAccess.Nav.WSOpen(); }.bind(this); @@ -102,6 +125,9 @@ socket.onclose = function (event) { GoAccess.Nav.WSClose(); + window.clearInterval(pingId); + socket = null; + this.wsTimer = setTimeout(() => { this.reconnect(wsConn); }, this.currDelay); }.bind(this); }, }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/commons.h new/goaccess-1.6.1/src/commons.h --- old/goaccess-1.6/src/commons.h 2022-06-01 04:50:36.000000000 +0200 +++ new/goaccess-1.6.1/src/commons.h 2022-06-30 16:17:12.000000000 +0200 @@ -43,7 +43,7 @@ #define __attribute__(x) /**/ #endif #define GO_UNUSED __attribute__((unused)) -#define GO_VERSION "1.6" +#define GO_VERSION "1.6.1" #define GO_WEBSITE "https://goaccess.io/" extern struct tm now_tm; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/config.h.in new/goaccess-1.6.1/src/config.h.in --- old/goaccess-1.6/src/config.h.in 2022-06-01 05:35:16.000000000 +0200 +++ new/goaccess-1.6.1/src/config.h.in 2022-06-30 16:18:41.000000000 +0200 @@ -227,6 +227,9 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the `timegm' function. */ +#undef HAVE_TIMEGM + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/gkhash.c new/goaccess-1.6.1/src/gkhash.c --- old/goaccess-1.6/src/gkhash.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/gkhash.c 2022-06-30 16:17:04.000000000 +0200 @@ -128,7 +128,7 @@ return h; } -/* Initialize a new uint32_t key - GLastParse value hash table */ +/* Initialize a new uint64_t key - GLastParse value hash table */ static void * new_iglp_ht (void) { khash_t (iglp) * h = kh_init (iglp); @@ -896,7 +896,7 @@ * On error, -1 is returned. * On success 0 is returned */ int -ins_iglp (khash_t (iglp) * hash, uint32_t key, GLastParse lp) { +ins_iglp (khash_t (iglp) * hash, uint64_t key, GLastParse lp) { khint_t k; int ret; @@ -1600,7 +1600,7 @@ * On error, -1 is returned. * On success the GLastParse value for the given key is returned */ static GLastParse -get_iglp (khash_t (iglp) * hash, uint32_t key) { +get_iglp (khash_t (iglp) * hash, uint64_t key) { khint_t k; GLastParse lp = { 0 }; @@ -1817,7 +1817,7 @@ } int -ht_insert_last_parse (uint32_t key, GLastParse lp) { +ht_insert_last_parse (uint64_t key, GLastParse lp) { GKDB *db = get_db_instance (DB_INSTANCE); khash_t (iglp) * hash = get_hdb (db, MTRC_LAST_PARSE); @@ -2303,7 +2303,7 @@ } GLastParse -ht_get_last_parse (uint32_t key) { +ht_get_last_parse (uint64_t key) { GKDB *db = get_db_instance (DB_INSTANCE); khash_t (iglp) * hash = get_hdb (db, MTRC_LAST_PARSE); return get_iglp (hash, key); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/gkhash.h new/goaccess-1.6.1/src/gkhash.h --- old/goaccess-1.6/src/gkhash.h 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/gkhash.h 2022-06-30 16:17:04.000000000 +0200 @@ -64,7 +64,7 @@ MTRC_TYPE_IGKH, /* uint64_t key - uint32_t val */ MTRC_TYPE_U648, - /* uint32_t key - GLastParse val */ + /* uint64_t key - GLastParse val */ MTRC_TYPE_IGLP, } GSMetricType; @@ -90,8 +90,8 @@ KHASH_MAP_INIT_INT (ii08 , uint8_t); /* string keys , string payload */ KHASH_MAP_INIT_STR (ss32 , char *); -/* uint32_t key , GLastParse payload */ -KHASH_MAP_INIT_INT (iglp , GLastParse); +/* uint64_t key , GLastParse payload */ +KHASH_MAP_INIT_INT64 (iglp , GLastParse); /* uint32_t keys , GSLList payload */ KHASH_MAP_INIT_INT (igsl , GSLList *); /* string keys , uint64_t payload */ @@ -349,7 +349,7 @@ int ht_insert_date (uint32_t key); int ht_insert_hostname (const char *ip, const char *host); int ht_insert_json_logfmt (GO_UNUSED void *userdata, char *key, char *spec); -int ht_insert_last_parse (uint32_t key, GLastParse lp); +int ht_insert_last_parse (uint64_t key, GLastParse lp); int ht_insert_maxts (GModule module, uint32_t date, uint32_t key, uint64_t value, uint32_t ckey); int ht_insert_meta_data (GModule module, uint32_t date, const char *key, uint64_t value); int ht_insert_method (GModule module, uint32_t date, uint32_t key, const char *value, uint32_t ckey); @@ -396,7 +396,7 @@ void init_storage (void); void u64decode (uint64_t n, uint32_t * x, uint32_t * y); -int ins_iglp (khash_t (iglp) * hash, uint32_t key, GLastParse lp); +int ins_iglp (khash_t (iglp) * hash, uint64_t key, GLastParse lp); int ins_igsl (khash_t (igsl) * hash, uint32_t key, uint32_t value); int ins_ii08 (khash_t (ii08) * hash, uint32_t key, uint8_t value); int ins_ii32 (khash_t (ii32) * hash, uint32_t key, uint32_t value); @@ -410,7 +410,7 @@ void * get_hash (int module, uint64_t key, GSMetric metric); void *get_hdb (GKDB * db, GAMetric mtrc); -GLastParse ht_get_last_parse (uint32_t key); +GLastParse ht_get_last_parse (uint64_t key); GRawData *parse_raw_data (GModule module); GSLList *ht_get_host_agent_list (GModule module, uint32_t key); GSLList *ht_get_keymap_list_from_key (GModule module, uint32_t key); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/gstorage.c new/goaccess-1.6.1/src/gstorage.c --- old/goaccess-1.6/src/gstorage.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/gstorage.c 2022-06-30 16:17:04.000000000 +0200 @@ -1314,37 +1314,15 @@ static int gen_visit_time_key (GKeyData * kdata, GLogItem * logitem) { char *hmark = NULL; - char hour[HRMI_LEN] = ""; /* %H:%M */ if (!logitem->time) return 1; - /* if not a timestamp, then it must be a string containing the hour. - * this is faster than actual date conversion */ - if (!has_timestamp (conf.time_format) && (hmark = strchr (logitem->time, ':'))) { + /* it must be a string containing the hour. */ + if ((hmark = strchr (logitem->time, ':'))) parse_time_specificity_string (hmark, logitem->time); - kdata->numdate = logitem->numdate; - get_kdata (kdata, logitem->time, logitem->time); - return 0; - } - - /* otherwise it attempts to convert the date given a time format, - * though this is slower */ - memset (hour, 0, sizeof *hour); - if (convert_date (hour, logitem->time, "%T", "%H:%M", HRMI_LEN) != 0) - return 1; - - if (*hour == '\0') - return 1; - - if ((hmark = strchr (hour, ':'))) - parse_time_specificity_string (hmark, hour); - - free (logitem->time); - logitem->time = xstrdup (hour); - - get_kdata (kdata, logitem->time, logitem->time); kdata->numdate = logitem->numdate; + get_kdata (kdata, logitem->time, logitem->time); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/options.c new/goaccess-1.6.1/src/options.c --- old/goaccess-1.6/src/options.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/options.c 2022-06-25 18:35:28.000000000 +0200 @@ -91,6 +91,7 @@ {"color-scheme" , required_argument , 0 , 0 } , {"crawlers-only" , no_argument , 0 , 0 } , {"daemonize" , no_argument , 0 , 0 } , + {"datetime-format" , required_argument , 0 , 0 } , {"date-format" , required_argument , 0 , 0 } , {"date-spec" , required_argument , 0 , 0 } , {"db-path" , required_argument , 0 , 0 } , @@ -139,6 +140,7 @@ {"restore" , no_argument , 0 , 0 } , {"sort-panel" , required_argument , 0 , 0 } , {"static-file" , required_argument , 0 , 0 } , + {"tz" , required_argument , 0 , 0 } , {"user-name" , required_argument , 0 , 0 } , #ifdef HAVE_LIBSSL {"ssl-cert" , required_argument , 0 , 0 } , @@ -146,6 +148,7 @@ #endif {"time-format" , required_argument , 0 , 0 } , {"ws-url" , required_argument , 0 , 0 } , + {"ping-interval" , required_argument , 0 , 0 } , #ifdef HAVE_GEOLOCATION {"geoip-database" , required_argument , 0 , 0 } , #endif @@ -165,9 +168,10 @@ printf ( /* Log & Date Format Options */ CYN "LOG & DATE FORMAT OPTIONS\n\n" RESET - " --date-format=<dateformat> - Specify log date format. e.g., %%d/%%b/%%Y\n" " --log-format=<logformat> - Specify log format. Inner quotes need escaping, or use single quotes.\n" - " --time-format=<timeformat> - Specify log time format. e.g., %%H:%%M:%%S\n\n" + " --date-format=<dateformat> - Specify log date format. e.g., %%d/%%b/%%Y\n" + " --time-format=<timeformat> - Specify log time format. e.g., %%H:%%M:%%S\n" + " --datetime-format=<dt-format> - Specify log date and time format. e.g., %%d/%%b/%%Y %%H:%%M:%%S %%z\n" "\n" /* User Interface Options */ CYN "USER INTERFACE OPTIONS\n\n" RESET @@ -190,6 +194,7 @@ " --no-parsing-spinner - Disable progress metrics and parsing spinner.\n" " --no-progress - Disable progress metrics.\n" " --no-tab-scroll - Disable scrolling through panels on TAB.\n" + " --tz=<timezone> - Use the specified timezone (canonical name, e.g., America/Chicago).\n" "\n" "" /* Server Options */ @@ -207,6 +212,7 @@ " --ssl-key=<priv.key> - Path to TLS/SSL private key.\n" " --user-name=<username> - Run as the specified user.\n" " --ws-url=<url> - URL to which the WebSocket server responds.\n" + " --ping-interval=<secs> - Enable WebSocket ping with specified interval in seconds.\n" "\n" "" /* File Options */ @@ -312,6 +318,13 @@ /* LOG & DATE FORMAT OPTIONS * ========================= */ + + /* datetime format */ + if (!strcmp ("datetime-format", name) && !conf.date_format && !conf.time_format) { + set_date_format_str (oarg); + set_time_format_str (oarg); + } + /* log format */ if (!strcmp ("log-format", name)) set_log_format_str (oarg); @@ -458,10 +471,18 @@ if (!strcmp ("ssl-key", name)) conf.sslkey = oarg; + /* timezone */ + if (!strcmp ("tz", name)) + conf.tz_name = oarg; + /* URL to which the WebSocket server responds. */ if (!strcmp ("ws-url", name)) conf.ws_url = oarg; + /* WebSocket ping interval in seconds */ + if (!strcmp ("ping-interval", name)) + conf.ping_interval = oarg; + /* FILE OPTIONS * ========================= */ /* invalid requests */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/output.c new/goaccess-1.6.1/src/output.c --- old/goaccess-1.6/src/output.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/output.c 2022-06-30 16:17:04.000000000 +0200 @@ -506,7 +506,9 @@ fpopen_obj (fp, sp); fpskeysval (fp, "url", (conf.ws_url ? conf.ws_url : ""), sp, 0); - fpskeyival (fp, "port", (conf.port ? atoi (conf.port) : 7890), sp, 1); + fpskeyival (fp, "port", (conf.port ? atoi (conf.port) : 7890), sp, 0); + fpskeyival (fp, "ping_interval", (conf.ping_interval ? atoi (conf.ping_interval) : 0), sp, + 1); fpclose_obj (fp, sp, 1); fprintf (fp, "</script>"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/parser.c new/goaccess-1.6.1/src/parser.c --- old/goaccess-1.6/src/parser.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/parser.c 2022-06-30 16:17:12.000000000 +0200 @@ -844,6 +844,7 @@ errno = 0; memset (&tm, 0, sizeof (tm)); + tm.tm_isdst = -1; localtime_r (&now, &tm); switch (*p) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/parser.h new/goaccess-1.6.1/src/parser.h --- old/goaccess-1.6/src/parser.h 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/parser.h 2022-06-30 16:17:04.000000000 +0200 @@ -115,7 +115,7 @@ uint8_t piping:1; uint8_t log_erridx; uint32_t read; /* lines read/parsed */ - uint32_t inode; /* inode of the log */ + uint64_t inode; /* inode of the log */ uint64_t bytes; /* bytes read on each iteration */ uint64_t size; /* original size of log */ uint64_t length; /* length read from the log so far */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/persistence.c new/goaccess-1.6.1/src/persistence.c --- old/goaccess-1.6/src/persistence.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/persistence.c 2022-06-30 16:17:04.000000000 +0200 @@ -201,14 +201,14 @@ tpl_free (tn); } -/* Given a database filename, restore a uint32_t key, GLastParse value back to +/* Given a database filename, restore a uint64_t key, GLastParse value back to * the storage */ static void restore_global_iglp (khash_t (iglp) * hash, const char *fn) { tpl_node *tn; - uint32_t key; + uint64_t key; GLastParse val = { 0 }; - char fmt[] = "A(uS(uIUvc#))"; + char fmt[] = "A(US(uIUvc#))"; tn = tpl_map (fmt, &key, &val, READ_BYTES); tpl_load (tn, TPL_FILE, fn); @@ -218,14 +218,14 @@ tpl_free (tn); } -/* Given a hash and a filename, persist to disk a uint32_t key, uint32_t value */ +/* Given a hash and a filename, persist to disk a uint64_t key, uint32_t value */ static void persist_global_iglp (khash_t (iglp) * hash, const char *fn) { tpl_node *tn; khint_t k; - uint32_t key; + uint64_t key; GLastParse val = { 0 }; - char fmt[] = "A(uS(uIUvc#))"; + char fmt[] = "A(US(uIUvc#))"; if (!hash || kh_size (hash) == 0) return; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/settings.c new/goaccess-1.6.1/src/settings.c --- old/goaccess-1.6/src/settings.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/settings.c 2022-06-30 16:17:04.000000000 +0200 @@ -228,6 +228,7 @@ free (conf.spec_date_time_format); free (conf.spec_date_time_num_format); free (conf.time_format); + free (conf.date_time_format); } /* Clean malloc'd command line arguments. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/settings.h new/goaccess-1.6.1/src/settings.h --- old/goaccess-1.6/src/settings.h 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/settings.h 2022-06-25 18:35:28.000000000 +0200 @@ -108,6 +108,8 @@ const char *static_files[MAX_EXTENSIONS]; /* static extensions */ /* Log/date/time formats */ + const char *tz_name; /* Canonical TZ name, e.g., America/Chicago */ + char *date_time_format; /* date & time format */ char *date_format; /* date format */ char *date_num_format; /* numeric date format %Y%m%d */ char *time_format; /* time format as given by the user */ @@ -138,6 +140,7 @@ const char *sslcert; /* TLS/SSL path to certificate */ const char *sslkey; /* TLS/SSL path to private key */ const char *ws_url; /* WebSocket URL */ + const char *ping_interval; /* WebSocket ping interval in seconds */ const char *unix_socket; /* unix socket to bind to */ /* User flags */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/util.c new/goaccess-1.6.1/src/util.c --- old/goaccess-1.6/src/util.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/util.c 2022-06-30 16:17:04.000000000 +0200 @@ -33,6 +33,7 @@ #define _FILE_OFFSET_BITS 64 #define _XOPEN_SOURCE 700 +#define _GNU_SOURCE #include <arpa/inet.h> #include <ctype.h> @@ -511,6 +512,29 @@ return xstrdup ("---"); } +static time_t +tm2time (const struct tm *src) { + struct tm tmp; + + tmp = *src; + return timegm (&tmp) - src->tm_gmtoff; +} + +static void +set_tz (void) { + char tz[TZ_NAME_LEN] = { 0 }; + + if (!conf.tz_name) + return; + + snprintf (tz, TZ_NAME_LEN, "TZ=%s", conf.tz_name); + if ((putenv (tz)) != 0) { + LOG_DEBUG (("Can't set TZ env variable %s: %s\n", tz, strerror (errno))); + return; + } + tzset (); +} + /* Format the given date/time according the given format. * * On error, 1 is returned. @@ -518,6 +542,7 @@ #pragma GCC diagnostic ignored "-Wformat-nonliteral" int str_to_time (const char *str, const char *fmt, struct tm *tm) { + time_t t; char *end = NULL, *sEnd = NULL; unsigned long long ts = 0; int us, ms; @@ -550,6 +575,8 @@ return 1; seconds = (us) ? ts / SECS : ((ms) ? ts / MILS : ts); + + set_tz (); /* if GMT needed, gmtime_r instead of localtime_r. */ localtime_r (&seconds, tm); @@ -560,6 +587,17 @@ if (end == NULL || *end != '\0') return 1; + if (!conf.tz_name) + return 0; + + if ((t = tm2time (tm)) == -1) { + LOG_DEBUG (("Can't set time via tm2time() %s: %s\n", str, strerror (errno))); + return 0; + } + + set_tz (); + localtime_r (&t, tm); + return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/util.h new/goaccess-1.6.1/src/util.h --- old/goaccess-1.6/src/util.h 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/util.h 2022-06-30 16:17:04.000000000 +0200 @@ -45,6 +45,7 @@ #define MINS 60000000ULL #define HOUR 3600000000ULL #define DAY 86400000000ULL +#define TZ_NAME_LEN 48 /* Convenient macros */ #define MIN(a,b) \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goaccess-1.6/src/websocket.c new/goaccess-1.6.1/src/websocket.c --- old/goaccess-1.6/src/websocket.c 2022-05-31 18:48:57.000000000 +0200 +++ new/goaccess-1.6.1/src/websocket.c 2022-06-25 18:35:28.000000000 +0200 @@ -1599,9 +1599,12 @@ readh = client->headers->buflen; /* Probably the connection was closed before finishing handshake */ if ((bytes = read_socket (client, buf + readh, WS_MAX_HEAD_SZ - readh)) < 1) { - if (client->status & WS_CLOSE) + if (client->status & WS_CLOSE) { + LOG (("Connection aborted %d [%s]...\n", client->listener, client->remote_ip)); http_error (client, WS_BAD_REQUEST_STR); - return bytes; + } + LOG (("Can't establish handshake %d [%s]...\n", client->listener, client->remote_ip)); + return ws_set_status (client, WS_CLOSE, bytes); } client->headers->buflen += bytes; @@ -1609,21 +1612,26 @@ /* Must have a \r\n\r\n */ if (strstr (buf, "\r\n\r\n") == NULL) { - if (strlen (buf) < WS_MAX_HEAD_SZ) + if (strlen (buf) < WS_MAX_HEAD_SZ) { + LOG (("Headers too long %d [%s]...\n", client->listener, client->remote_ip)); return ws_set_status (client, WS_READING, bytes); + } + LOG (("Invalid newlines for handshake %d [%s]...\n", client->listener, client->remote_ip)); http_error (client, WS_BAD_REQUEST_STR); return ws_set_status (client, WS_CLOSE, bytes); } /* Ensure we have valid HTTP headers for the handshake */ if (parse_headers (client->headers) != 0) { + LOG (("Invalid headers for handshake %d [%s]...\n", client->listener, client->remote_ip)); http_error (client, WS_BAD_REQUEST_STR); return ws_set_status (client, WS_CLOSE, bytes); } /* Ensure we have the required headers */ if (ws_verify_req_headers (client->headers) != 0) { + LOG (("Missing headers for handshake %d [%s]...\n", client->listener, client->remote_ip)); http_error (client, WS_BAD_REQUEST_STR); return ws_set_status (client, WS_CLOSE, bytes); } @@ -2145,6 +2153,8 @@ /* Handle a tcp close connection. */ static void handle_tcp_close (int conn, WSClient * client, WSServer * server) { + LOG (("Closing TCP %d [%s]\n", client->listener, client->remote_ip)); + #ifdef HAVE_LIBSSL if (client->ssl) shutdown_ssl (client); @@ -2178,13 +2188,15 @@ /* remove client from our list */ ws_remove_client_from_list (client, server); - LOG (("Active: %d\n", list_count (server->colist))); + LOG (("Connection Closed.\nActive: %d\n", list_count (server->colist))); } /* Handle a tcp read close connection. */ static void handle_read_close (int *conn, WSClient * client, WSServer * server) { - if (client->status & WS_SENDING) { + /* We can still try to send a message to the client if not forcing close, (nice + * goodbye), else proceed to close it */ + if (!(client->status & WS_CLOSE) && client->status & WS_SENDING) { server->closing = 1; set_pollfd (client->listener, POLLOUT); return; @@ -2211,7 +2223,7 @@ client->sslstatus |= WS_TLS_ACCEPTING; #endif - LOG (("Accepted: %d %s\n", newfd, client->remote_ip)); + LOG (("Accepted: %d [%s]\n", newfd, client->remote_ip)); } /* Handle a tcp read. */ @@ -2222,6 +2234,8 @@ if (!(client = ws_get_client_from_list (*conn, &server->colist))) return; + LOG (("Handling read %d [%s]...\n", client->listener, client->remote_ip)); + #ifdef HAVE_LIBSSL if (handle_ssl_pending_rw (conn, server, client) == 0) return; @@ -2495,21 +2509,54 @@ /* Broadcast to all connected clients the given message. */ static int -ws_broadcast_fifo (void *value, void *user_data) { - WSClient *client = value; - WSPacket *packet = user_data; +ws_broadcast_fifo (WSClient * client, WSServer * server) { + WSPacket *packet = server->pipein->packet; - if (client == NULL || user_data == NULL) - return 1; - /* no handshake for this client */ - if (client->headers == NULL || client->headers->ws_accept == NULL) + LOG (("Broadcasting to %d [%s] ", client->listener, client->remote_ip)); + if (client == NULL) return 1; + if (client->headers == NULL || client->headers->ws_accept == NULL) { + /* no handshake for this client */ + LOG (("No headers. Closing %d [%s]\n", client->listener, client->remote_ip)); + return -1; + } + + LOG ((" - Sending...\n")); ws_send_data (client, packet->type, packet->data, packet->size); return 0; } +static void +ws_broadcast_fifo_to_clients (WSServer * server) { + WSClient *client = NULL; + void *data = NULL; + uint32_t *close_list = NULL; + int n = 0, idx = 0, i = 0, listener = 0; + + if ((n = list_count (server->colist)) == 0) + return; + + close_list = xcalloc (n, sizeof (uint32_t)); + /* *INDENT-OFF* */ + GSLIST_FOREACH (server->colist, data, { + client = data; + if (ws_broadcast_fifo(client, server) == -1) + close_list[idx++] = client->listener; + }); + /* *INDENT-ON* */ + + client = NULL; + for (i = 0; i < idx; ++i) { + listener = close_list[i]; + if ((client = ws_get_client_from_list (listener, &server->colist))) + handle_tcp_close (listener, client, server); + } + + free (close_list); +} + /* Send a message from the incoming named pipe to specific client * given the socket id. */ static void @@ -2519,8 +2566,12 @@ if (!(client = ws_get_client_from_list (listener, &server->colist))) return; /* no handshake for this client */ - if (client->headers == NULL || client->headers->ws_accept == NULL) + if (client->headers == NULL || client->headers->ws_accept == NULL) { + LOG (("No headers. Closing %d [%s]\n", client->listener, client->remote_ip)); + + handle_tcp_close (client->listener, client, server); return; + } ws_send_data (client, pa->type, pa->data, pa->len); } @@ -2644,7 +2695,7 @@ if (listener != 0) ws_send_strict_fifo_to_client (server, listener, *pa); else - list_foreach (server->colist, ws_broadcast_fifo, *pa); + ws_broadcast_fifo_to_clients (server); clear_fifo_packet (pi); } @@ -2677,7 +2728,7 @@ } /* broadcast message to all clients */ - list_foreach (server->colist, ws_broadcast_fifo, *pa); + ws_broadcast_fifo_to_clients (server); clear_fifo_packet (pi); }
