Merge branch 'master' of github.com:clonos/control-pane

This commit is contained in:
MOVe
2021-11-24 23:51:45 +03:00
35 changed files with 1062 additions and 1610 deletions

View File

@@ -1,3 +1,3 @@
Defaults env_keep += "workdir DIALOG NOCOLOR" Defaults env_keep += "workdir DIALOG NOCOLOR CBSD_RNODE"
Cmnd_Alias WEB_CMD = /usr/local/bin/cbsd Cmnd_Alias WEB_CMD = /usr/local/bin/cbsd
www ALL=(ALL) NOPASSWD:SETENV: WEB_CMD www ALL=(ALL) NOPASSWD:SETENV: WEB_CMD

View File

@@ -41,6 +41,24 @@ pid = run/php-fpm.pid
; Default Value: notice ; Default Value: notice
;log_level = notice ;log_level = notice
; Log limit on number of characters in the single line (log entry). If the
; line is over the limit, it is wrapped on multiple lines. The limit is for
; all logged characters including message prefix and suffix if present. However
; the new line character does not count into it as it is present only when
; logging to a file descriptor. It means the new line character is not present
; when logging to syslog.
; Default Value: 1024
;log_limit = 4096
; Log buffering specifies if the log line is buffered which means that the
; line is written in a single write operation. If the value is false, then the
; data is written directly into the file descriptor. It is an experimental
; option that can potentionaly improve logging performance and memory usage
; for some heavy logging scenarios. This option is ignored if logging to syslog
; as it has to be always buffered.
; Default value: yes
;log_buffering = no
; If this number of child processes exit with SIGSEGV or SIGBUS within the time ; If this number of child processes exit with SIGSEGV or SIGBUS within the time
; interval set by emergency_restart_interval then FPM will restart. A value ; interval set by emergency_restart_interval then FPM will restart. A value
; of '0' means 'Off'. ; of '0' means 'Off'.

View File

@@ -15,7 +15,7 @@
; 5. The web server's directory (for SAPI modules), or directory of PHP ; 5. The web server's directory (for SAPI modules), or directory of PHP
; (otherwise in Windows) ; (otherwise in Windows)
; 6. The directory from the --with-config-file-path compile time option, or the ; 6. The directory from the --with-config-file-path compile time option, or the
; Windows directory (C:\windows or C:\winnt) ; Windows directory (usually C:\windows)
; See the PHP docs for more specific information. ; See the PHP docs for more specific information.
; http://php.net/configuration.file ; http://php.net/configuration.file
@@ -58,9 +58,9 @@
; An empty string can be denoted by simply not writing anything after the equal ; An empty string can be denoted by simply not writing anything after the equal
; sign, or by using the None keyword: ; sign, or by using the None keyword:
; foo = ; sets foo to an empty string ; foo = ; sets foo to an empty string
; foo = None ; sets foo to an empty string ; foo = None ; sets foo to an empty string
; foo = "None" ; sets foo to the string 'None' ; foo = "None" ; sets foo to the string 'None'
; If you use constants in your value, and these constants belong to a ; If you use constants in your value, and these constants belong to a
; dynamically loaded extension (either a PHP extension or a Zend extension), ; dynamically loaded extension (either a PHP extension or a Zend extension),
@@ -83,11 +83,12 @@
; development version only in development environments, as errors shown to ; development version only in development environments, as errors shown to
; application users can inadvertently leak otherwise secure information. ; application users can inadvertently leak otherwise secure information.
; This is php.ini-production INI file. ; This is the php.ini-production INI file.
;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
; Quick Reference ; ; Quick Reference ;
;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
; The following are all the settings which are different in either the production ; The following are all the settings which are different in either the production
; or development versions of the INIs with respect to PHP's default behavior. ; or development versions of the INIs with respect to PHP's default behavior.
; Please see the actual settings later in the document for more details as to why ; Please see the actual settings later in the document for more details as to why
@@ -99,20 +100,15 @@
; Production Value: Off ; Production Value: Off
; display_startup_errors ; display_startup_errors
; Default Value: Off ; Default Value: On
; Development Value: On ; Development Value: On
; Production Value: Off ; Production Value: Off
; error_reporting ; error_reporting
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED ; Default Value: E_ALL
; Development Value: E_ALL ; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT ; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; html_errors
; Default Value: On
; Development Value: On
; Production value: On
; log_errors ; log_errors
; Default Value: Off ; Default Value: Off
; Development Value: On ; Development Value: On
@@ -153,23 +149,28 @@
; Development Value: Off ; Development Value: Off
; Production Value: Off ; Production Value: Off
; track_errors
; Default Value: Off
; Development Value: On
; Production Value: Off
; variables_order ; variables_order
; Default Value: "EGPCS" ; Default Value: "EGPCS"
; Development Value: "GPCS" ; Development Value: "GPCS"
; Production Value: "GPCS" ; Production Value: "GPCS"
; zend.exception_ignore_args
; Default Value: Off
; Development Value: Off
; Production Value: On
; zend.exception_string_param_max_len
; Default Value: 15
; Development Value: 15
; Production Value: 0
;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;
; php.ini Options ; ; php.ini Options ;
;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;
; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini" ; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
;user_ini.filename = ".user.ini" ;user_ini.filename = ".user.ini"
; To disable this feature set this option to empty value ; To disable this feature set this option to an empty value
;user_ini.filename = ;user_ini.filename =
; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes) ; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)
@@ -248,7 +249,7 @@ output_buffering = 4096
; Production Value: "form=" ; Production Value: "form="
;url_rewriter.tags ;url_rewriter.tags
; URL rewriter will not rewrites absolute URL nor form by default. To enable ; URL rewriter will not rewrite absolute URL nor form by default. To enable
; absolute URL rewrite, allowed hosts must be defined at RUNTIME. ; absolute URL rewrite, allowed hosts must be defined at RUNTIME.
; Refer to session.trans_sid_hosts for more details. ; Refer to session.trans_sid_hosts for more details.
; Default Value: "" ; Default Value: ""
@@ -294,6 +295,13 @@ implicit_flush = Off
; callback-function. ; callback-function.
unserialize_callback_func = unserialize_callback_func =
; The unserialize_max_depth specifies the default depth limit for unserialized
; structures. Setting the depth limit too high may result in stack overflows
; during unserialization. The unserialize_max_depth ini setting can be
; overridden by the max_depth option on individual unserialize() calls.
; A value of 0 disables the depth limit.
;unserialize_max_depth = 4096
; When floats & doubles are serialized, store serialize_precision significant ; When floats & doubles are serialized, store serialize_precision significant
; digits after the floating point. The default value ensures that when floats ; digits after the floating point. The default value ensures that when floats
; are decoded with unserialize, the data will remain the same. ; are decoded with unserialize, the data will remain the same.
@@ -305,15 +313,16 @@ serialize_precision = -1
; open_basedir, if set, limits all file operations to the defined directory ; open_basedir, if set, limits all file operations to the defined directory
; and below. This directive makes most sense if used in a per-directory ; and below. This directive makes most sense if used in a per-directory
; or per-virtualhost web server configuration file. ; or per-virtualhost web server configuration file.
; Note: disables the realpath cache
; http://php.net/open-basedir ; http://php.net/open-basedir
;open_basedir = ;open_basedir =
; This directive allows you to disable certain functions for security reasons. ; This directive allows you to disable certain functions.
; It receives a comma-delimited list of function names. ; It receives a comma-delimited list of function names.
; http://php.net/disable-functions ; http://php.net/disable-functions
disable_functions = disable_functions =
; This directive allows you to disable certain classes for security reasons. ; This directive allows you to disable certain classes.
; It receives a comma-delimited list of class names. ; It receives a comma-delimited list of class names.
; http://php.net/disable-classes ; http://php.net/disable-classes
disable_classes = disable_classes =
@@ -337,6 +346,7 @@ disable_classes =
; Determines the size of the realpath cache to be used by PHP. This value should ; Determines the size of the realpath cache to be used by PHP. This value should
; be increased on systems where PHP opens many files to reflect the quantity of ; be increased on systems where PHP opens many files to reflect the quantity of
; the file operations performed. ; the file operations performed.
; Note: if open_basedir is set, the cache is disabled
; http://php.net/realpath-cache-size ; http://php.net/realpath-cache-size
;realpath_cache_size = 4096k ;realpath_cache_size = 4096k
@@ -353,15 +363,31 @@ zend.enable_gc = On
; If enabled, scripts may be written in encodings that are incompatible with ; If enabled, scripts may be written in encodings that are incompatible with
; the scanner. CP936, Big5, CP949 and Shift_JIS are the examples of such ; the scanner. CP936, Big5, CP949 and Shift_JIS are the examples of such
; encodings. To use this feature, mbstring extension must be enabled. ; encodings. To use this feature, mbstring extension must be enabled.
; Default: Off
;zend.multibyte = Off ;zend.multibyte = Off
; Allows to set the default encoding for the scripts. This value will be used ; Allows to set the default encoding for the scripts. This value will be used
; unless "declare(encoding=...)" directive appears at the top of the script. ; unless "declare(encoding=...)" directive appears at the top of the script.
; Only affects if zend.multibyte is set. ; Only affects if zend.multibyte is set.
; Default: ""
;zend.script_encoding = ;zend.script_encoding =
; Allows to include or exclude arguments from stack traces generated for exceptions.
; In production, it is recommended to turn this setting on to prohibit the output
; of sensitive information in stack traces
; Default Value: Off
; Development Value: Off
; Production Value: On
zend.exception_ignore_args = On
; Allows setting the maximum string length in an argument of a stringified stack trace
; to a value between 0 and 1000000.
; This has no effect when zend.exception_ignore_args is enabled.
; Default Value: 15
; Development Value: 15
; Production Value: 0
; In production, it is recommended to set this to 0 to reduce the output
; of sensitive information in stack traces.
zend.exception_string_param_max_len = 0
;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;
; Miscellaneous ; ; Miscellaneous ;
;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;
@@ -397,9 +423,9 @@ max_input_time = 60
;max_input_nesting_level = 64 ;max_input_nesting_level = 64
; How many GET/POST/COOKIE input variables may be accepted ; How many GET/POST/COOKIE input variables may be accepted
; max_input_vars = 1000 ;max_input_vars = 1000
; Maximum amount of memory a script may consume (128MB) ; Maximum amount of memory a script may consume
; http://php.net/memory-limit ; http://php.net/memory-limit
memory_limit = 256M memory_limit = 256M
@@ -453,7 +479,7 @@ memory_limit = 256M
; E_ALL & ~E_NOTICE (Show all errors, except for notices) ; E_ALL & ~E_NOTICE (Show all errors, except for notices)
; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.) ; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.)
; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors) ; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED ; Default Value: E_ALL
; Development Value: E_ALL ; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT ; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting ; http://php.net/error-reporting
@@ -477,11 +503,9 @@ error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off display_errors = Off
; The display of errors which occur during PHP's startup sequence are handled ; The display of errors which occur during PHP's startup sequence are handled
; separately from display_errors. PHP's default behavior is to suppress those ; separately from display_errors. We strongly recommend you set this to 'off'
; errors from clients. Turning the display of startup errors on can be useful in ; for production servers to avoid leaking configuration details.
; debugging configuration problems. We strongly recommend you ; Default Value: On
; set this to 'off' for production servers.
; Default Value: Off
; Development Value: On ; Development Value: On
; Production Value: Off ; Production Value: Off
; http://php.net/display-startup-errors ; http://php.net/display-startup-errors
@@ -514,24 +538,14 @@ ignore_repeated_errors = Off
ignore_repeated_source = Off ignore_repeated_source = Off
; If this parameter is set to Off, then memory leaks will not be shown (on ; If this parameter is set to Off, then memory leaks will not be shown (on
; stdout or in the log). This has only effect in a debug compile, and if ; stdout or in the log). This is only effective in a debug compile, and if
; error reporting includes E_WARNING in the allowed list ; error reporting includes E_WARNING in the allowed list
; http://php.net/report-memleaks ; http://php.net/report-memleaks
report_memleaks = On report_memleaks = On
; This setting is on by default. ; This setting is off by default.
;report_zend_debug = 0 ;report_zend_debug = 0
; Store the last error/warning message in $php_errormsg (boolean). Setting this value
; to On can assist in debugging and is appropriate for development servers. It should
; however be disabled on production servers.
; This directive is DEPRECATED.
; Default Value: Off
; Development Value: Off
; Production Value: Off
; http://php.net/track-errors
;track_errors = Off
; Turn off normal error reporting and emit XML-RPC error XML ; Turn off normal error reporting and emit XML-RPC error XML
; http://php.net/xmlrpc-errors ; http://php.net/xmlrpc-errors
;xmlrpc_errors = 0 ;xmlrpc_errors = 0
@@ -543,9 +557,6 @@ report_memleaks = On
; error message as HTML for easier reading. This directive controls whether ; error message as HTML for easier reading. This directive controls whether
; the error message is formatted as HTML or not. ; the error message is formatted as HTML or not.
; Note: This directive is hardcoded to Off for the CLI SAPI ; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: On
; Development Value: On
; Production value: On
; http://php.net/html-errors ; http://php.net/html-errors
html_errors = On html_errors = On
@@ -585,6 +596,26 @@ html_errors = On
; Log errors to syslog (Event Log on Windows). ; Log errors to syslog (Event Log on Windows).
;error_log = syslog ;error_log = syslog
; The syslog ident is a string which is prepended to every message logged
; to syslog. Only used when error_log is set to syslog.
;syslog.ident = php
; The syslog facility is used to specify what type of program is logging
; the message. Only used when error_log is set to syslog.
;syslog.facility = user
; Set this to disable filtering control characters (the default).
; Some loggers only accept NVT-ASCII, others accept anything that's not
; control characters. If your logger accepts everything, then no filtering
; is needed at all.
; Allowed values are:
; ascii (all printable ASCII characters and NL)
; no-ctrl (all characters except control characters)
; all (all characters)
; raw (like "all", but messages are not split at newlines)
; http://php.net/syslog.filter
;syslog.filter = ascii
;windows.show_crt_warning ;windows.show_crt_warning
; Default value: 0 ; Default value: 0
; Development value: 0 ; Development value: 0
@@ -652,7 +683,7 @@ register_argc_argv = Off
; first used (Just In Time) instead of when the script starts. If these ; first used (Just In Time) instead of when the script starts. If these
; variables are not used within a script, having this directive on will result ; variables are not used within a script, having this directive on will result
; in a performance gain. The PHP directive register_argc_argv must be disabled ; in a performance gain. The PHP directive register_argc_argv must be disabled
; for this directive to have any affect. ; for this directive to have any effect.
; http://php.net/auto-globals-jit ; http://php.net/auto-globals-jit
auto_globals_jit = On auto_globals_jit = On
@@ -734,13 +765,13 @@ user_dir =
; Directory in which the loadable extensions (modules) reside. ; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir ; http://php.net/extension-dir
; extension_dir = "./" ;extension_dir = "./"
; On windows: ; On windows:
; extension_dir = "ext" ;extension_dir = "ext"
; Directory where the temporary files should be placed. ; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir) ; Defaults to the system default (see sys_get_temp_dir)
; sys_temp_dir = "/tmp" ;sys_temp_dir = "/tmp"
; Whether or not to enable the dl() function. The dl() function does NOT work ; Whether or not to enable the dl() function. The dl() function does NOT work
; properly in multithreaded servers, such as IIS or Zeus, and is automatically ; properly in multithreaded servers, such as IIS or Zeus, and is automatically
@@ -777,10 +808,9 @@ enable_dl = Off
; if cgi.discard_path is enabled, the PHP CGI binary can safely be placed outside ; if cgi.discard_path is enabled, the PHP CGI binary can safely be placed outside
; of the web tree and people will not be able to circumvent .htaccess security. ; of the web tree and people will not be able to circumvent .htaccess security.
; http://php.net/cgi.dicard-path
;cgi.discard_path=1 ;cgi.discard_path=1
; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate ; FastCGI under IIS supports the ability to impersonate
; security tokens of the calling client. This allows IIS to define the ; security tokens of the calling client. This allows IIS to define the
; security context that the request runs under. mod_fastcgi under Apache ; security context that the request runs under. mod_fastcgi under Apache
; does not currently support this feature (03/17/2002) ; does not currently support this feature (03/17/2002)
@@ -891,18 +921,20 @@ default_socket_timeout = 60
; ;
;extension=bz2 ;extension=bz2
;extension=curl ;extension=curl
;extension=ffi
;extension=ftp
;extension=fileinfo ;extension=fileinfo
;extension=gd2 ;extension=gd
;extension=gettext ;extension=gettext
;extension=gmp ;extension=gmp
;extension=intl ;extension=intl
;extension=imap ;extension=imap
;extension=interbase
;extension=ldap ;extension=ldap
;extension=mbstring ;extension=mbstring
;extension=exif ; Must be after mbstring as it depends on it ;extension=exif ; Must be after mbstring as it depends on it
;extension=mysqli ;extension=mysqli
;extension=oci8_12c ; Use with Oracle Database 12c Instant Client ;extension=oci8_12c ; Use with Oracle Database 12c Instant Client
;extension=oci8_19 ; Use with Oracle Database 19 Instant Client
;extension=odbc ;extension=odbc
;extension=openssl ;extension=openssl
;extension=pdo_firebird ;extension=pdo_firebird
@@ -920,11 +952,13 @@ default_socket_timeout = 60
;extension=soap ;extension=soap
;extension=sockets ;extension=sockets
;extension=sodium
;extension=sqlite3 ;extension=sqlite3
;extension=tidy ;extension=tidy
;extension=xmlrpc
;extension=xsl ;extension=xsl
;zend_extension=opcache
;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
; Module Settings ; ; Module Settings ;
;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
@@ -945,10 +979,10 @@ cli_server.color = On
;date.default_longitude = 35.2333 ;date.default_longitude = 35.2333
; http://php.net/date.sunrise-zenith ; http://php.net/date.sunrise-zenith
;date.sunrise_zenith = 90.583333 ;date.sunrise_zenith = 90.833333
; http://php.net/date.sunset-zenith ; http://php.net/date.sunset-zenith
;date.sunset_zenith = 90.583333 ;date.sunset_zenith = 90.833333
[filter] [filter]
; http://php.net/filter.default ; http://php.net/filter.default
@@ -960,7 +994,7 @@ cli_server.color = On
[iconv] [iconv]
; Use of this INI entry is deprecated, use global input_encoding instead. ; Use of this INI entry is deprecated, use global input_encoding instead.
; If empty, default_charset or input_encoding or iconv.input_encoding is used. ; If empty, default_charset or input_encoding or iconv.input_encoding is used.
; The precedence is: default_charset < intput_encoding < iconv.input_encoding ; The precedence is: default_charset < input_encoding < iconv.input_encoding
;iconv.input_encoding = ;iconv.input_encoding =
; Use of this INI entry is deprecated, use global internal_encoding instead. ; Use of this INI entry is deprecated, use global internal_encoding instead.
@@ -975,6 +1009,13 @@ cli_server.color = On
; otherwise output encoding conversion cannot be performed. ; otherwise output encoding conversion cannot be performed.
;iconv.output_encoding = ;iconv.output_encoding =
[imap]
; rsh/ssh logins are disabled by default. Use this INI entry if you want to
; enable them. Note that the IMAP library does not filter mailbox names before
; passing them to rsh/ssh command, thus passing untrusted data to this function
; with rsh/ssh enabled is insecure.
;imap.enable_insecure_rsh=0
[intl] [intl]
;intl.default_locale = ;intl.default_locale =
; This directive allows you to produce PHP errors when some error ; This directive allows you to produce PHP errors when some error
@@ -984,22 +1025,33 @@ cli_server.color = On
;intl.use_exceptions = 0 ;intl.use_exceptions = 0
[sqlite3] [sqlite3]
; Directory pointing to SQLite3 extensions
; http://php.net/sqlite3.extension-dir
;sqlite3.extension_dir = ;sqlite3.extension_dir =
; SQLite defensive mode flag (only available from SQLite 3.26+)
; When the defensive flag is enabled, language features that allow ordinary
; SQL to deliberately corrupt the database file are disabled. This forbids
; writing directly to the schema, shadow tables (eg. FTS data tables), or
; the sqlite_dbpage virtual table.
; https://www.sqlite.org/c3ref/c_dbconfig_defensive.html
; (for older SQLite versions, this flag has no use)
;sqlite3.defensive = 1
[Pcre] [Pcre]
;PCRE library backtracking limit. ; PCRE library backtracking limit.
; http://php.net/pcre.backtrack-limit ; http://php.net/pcre.backtrack-limit
;pcre.backtrack_limit=100000 ;pcre.backtrack_limit=100000
;PCRE library recursion limit. ; PCRE library recursion limit.
;Please note that if you set this value to a high number you may consume all ; Please note that if you set this value to a high number you may consume all
;the available process stack and eventually crash PHP (due to reaching the ; the available process stack and eventually crash PHP (due to reaching the
;stack size limit imposed by the Operating System). ; stack size limit imposed by the Operating System).
; http://php.net/pcre.recursion-limit ; http://php.net/pcre.recursion-limit
;pcre.recursion_limit=100000 ;pcre.recursion_limit=100000
;Enables or disables JIT compilation of patterns. This requires the PCRE ; Enables or disables JIT compilation of patterns. This requires the PCRE
;library to be compiled with JIT support. ; library to be compiled with JIT support.
;pcre.jit=1 ;pcre.jit=1
[Pdo] [Pdo]
@@ -1007,16 +1059,9 @@ cli_server.color = On
; http://php.net/pdo-odbc.connection-pooling ; http://php.net/pdo-odbc.connection-pooling
;pdo_odbc.connection_pooling=strict ;pdo_odbc.connection_pooling=strict
;pdo_odbc.db2_instance_name
[Pdo_mysql] [Pdo_mysql]
; If mysqlnd is used: Number of cache slots for the internal result set cache
; http://php.net/pdo_mysql.cache_size
pdo_mysql.cache_size = 2000
; Default socket name for local MySQL connects. If empty, uses the built-in ; Default socket name for local MySQL connects. If empty, uses the built-in
; MySQL defaults. ; MySQL defaults.
; http://php.net/pdo_mysql.default-socket
pdo_mysql.default_socket= pdo_mysql.default_socket=
[Phar] [Phar]
@@ -1098,39 +1143,6 @@ odbc.defaultlrl = 4096
; http://php.net/odbc.defaultbinmode ; http://php.net/odbc.defaultbinmode
odbc.defaultbinmode = 1 odbc.defaultbinmode = 1
;birdstep.max_links = -1
[Interbase]
; Allow or prevent persistent links.
ibase.allow_persistent = 1
; Maximum number of persistent links. -1 means no limit.
ibase.max_persistent = -1
; Maximum number of links (persistent + non-persistent). -1 means no limit.
ibase.max_links = -1
; Default database name for ibase_connect().
;ibase.default_db =
; Default username for ibase_connect().
;ibase.default_user =
; Default password for ibase_connect().
;ibase.default_password =
; Default charset for ibase_connect().
;ibase.default_charset =
; Default timestamp format.
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
; Default date format.
ibase.dateformat = "%Y-%m-%d"
; Default time format.
ibase.timeformat = "%H:%M:%S"
[MySQLi] [MySQLi]
; Maximum number of persistent links. -1 means no limit. ; Maximum number of persistent links. -1 means no limit.
@@ -1149,10 +1161,6 @@ mysqli.allow_persistent = On
; http://php.net/mysqli.max-links ; http://php.net/mysqli.max-links
mysqli.max_links = -1 mysqli.max_links = -1
; If mysqlnd is used: Number of cache slots for the internal result set cache
; http://php.net/mysqli.cache_size
mysqli.cache_size = 2000
; Default port number for mysqli_connect(). If unset, mysqli_connect() will use ; Default port number for mysqli_connect(). If unset, mysqli_connect() will use
; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the ; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
; compile-time value defined MYSQL_PORT (in that order). Win32 will only look ; compile-time value defined MYSQL_PORT (in that order). Win32 will only look
@@ -1165,11 +1173,11 @@ mysqli.default_port = 3306
; http://php.net/mysqli.default-socket ; http://php.net/mysqli.default-socket
mysqli.default_socket = mysqli.default_socket =
; Default host for mysql_connect() (doesn't apply in safe mode). ; Default host for mysqli_connect() (doesn't apply in safe mode).
; http://php.net/mysqli.default-host ; http://php.net/mysqli.default-host
mysqli.default_host = mysqli.default_host =
; Default user for mysql_connect() (doesn't apply in safe mode). ; Default user for mysqli_connect() (doesn't apply in safe mode).
; http://php.net/mysqli.default-user ; http://php.net/mysqli.default-user
mysqli.default_user = mysqli.default_user =
@@ -1187,12 +1195,10 @@ mysqli.reconnect = Off
[mysqlnd] [mysqlnd]
; Enable / Disable collection of general statistics by mysqlnd which can be ; Enable / Disable collection of general statistics by mysqlnd which can be
; used to tune and monitor MySQL operations. ; used to tune and monitor MySQL operations.
; http://php.net/mysqlnd.collect_statistics
mysqlnd.collect_statistics = On mysqlnd.collect_statistics = On
; Enable / Disable collection of memory usage statistics by mysqlnd which can be ; Enable / Disable collection of memory usage statistics by mysqlnd which can be
; used to tune and monitor MySQL operations. ; used to tune and monitor MySQL operations.
; http://php.net/mysqlnd.collect_memory_statistics
mysqlnd.collect_memory_statistics = Off mysqlnd.collect_memory_statistics = Off
; Records communication from all extensions using mysqlnd to the specified log ; Records communication from all extensions using mysqlnd to the specified log
@@ -1201,29 +1207,23 @@ mysqlnd.collect_memory_statistics = Off
;mysqlnd.debug = ;mysqlnd.debug =
; Defines which queries will be logged. ; Defines which queries will be logged.
; http://php.net/mysqlnd.log_mask
;mysqlnd.log_mask = 0 ;mysqlnd.log_mask = 0
; Default size of the mysqlnd memory pool, which is used by result sets. ; Default size of the mysqlnd memory pool, which is used by result sets.
; http://php.net/mysqlnd.mempool_default_size
;mysqlnd.mempool_default_size = 16000 ;mysqlnd.mempool_default_size = 16000
; Size of a pre-allocated buffer used when sending commands to MySQL in bytes. ; Size of a pre-allocated buffer used when sending commands to MySQL in bytes.
; http://php.net/mysqlnd.net_cmd_buffer_size
;mysqlnd.net_cmd_buffer_size = 2048 ;mysqlnd.net_cmd_buffer_size = 2048
; Size of a pre-allocated buffer used for reading data sent by the server in ; Size of a pre-allocated buffer used for reading data sent by the server in
; bytes. ; bytes.
; http://php.net/mysqlnd.net_read_buffer_size
;mysqlnd.net_read_buffer_size = 32768 ;mysqlnd.net_read_buffer_size = 32768
; Timeout for network requests in seconds. ; Timeout for network requests in seconds.
; http://php.net/mysqlnd.net_read_timeout
;mysqlnd.net_read_timeout = 31536000 ;mysqlnd.net_read_timeout = 31536000
; SHA-256 Authentication Plugin related. File with the MySQL server public RSA ; SHA-256 Authentication Plugin related. File with the MySQL server public RSA
; key. ; key.
; http://php.net/mysqlnd.sha256_server_public_key
;mysqlnd.sha256_server_public_key = ;mysqlnd.sha256_server_public_key =
[OCI8] [OCI8]
@@ -1351,10 +1351,11 @@ session.save_handler = files
;session.save_path = "/tmp" ;session.save_path = "/tmp"
; Whether to use strict session mode. ; Whether to use strict session mode.
; Strict session mode does not accept uninitialized session ID and regenerate ; Strict session mode does not accept an uninitialized session ID, and
; session ID if browser sends uninitialized session ID. Strict mode protects ; regenerates the session ID if the browser sends an uninitialized session ID.
; applications from session fixation via session adoption vulnerability. It is ; Strict mode protects applications from session fixation via a session adoption
; disabled by default for maximum compatibility, but enabling it is encouraged. ; vulnerability. It is disabled by default for maximum compatibility, but
; enabling it is encouraged.
; https://wiki.php.net/rfc/strict_sessions ; https://wiki.php.net/rfc/strict_sessions
session.use_strict_mode = 0 session.use_strict_mode = 0
@@ -1392,20 +1393,24 @@ session.cookie_path = /
; http://php.net/session.cookie-domain ; http://php.net/session.cookie-domain
session.cookie_domain = session.cookie_domain =
; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript. ; Whether or not to add the httpOnly flag to the cookie, which makes it
; inaccessible to browser scripting languages such as JavaScript.
; http://php.net/session.cookie-httponly ; http://php.net/session.cookie-httponly
session.cookie_httponly = session.cookie_httponly =
; Handler used to serialize data. php is the standard serializer of PHP. ; Add SameSite attribute to cookie to help mitigate Cross-Site Request Forgery (CSRF/XSRF)
; Current valid values are "Strict", "Lax" or "None". When using "None",
; make sure to include the quotes, as `none` is interpreted like `false` in ini files.
; https://tools.ietf.org/html/draft-west-first-party-cookies-07
session.cookie_samesite =
; Handler used to serialize data. php is the standard serializer of PHP.
; http://php.net/session.serialize-handler ; http://php.net/session.serialize-handler
session.serialize_handler = php session.serialize_handler = php
; Defines the probability that the 'garbage collection' process is started ; Defines the probability that the 'garbage collection' process is started on every
; on every session initialization. The probability is calculated by using ; session initialization. The probability is calculated by using gc_probability/gc_divisor,
; gc_probability/gc_divisor. Where session.gc_probability is the numerator ; e.g. 1/100 means there is a 1% chance that the GC process starts on each request.
; and gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request.
; Default Value: 1 ; Default Value: 1
; Development Value: 1 ; Development Value: 1
; Production Value: 1 ; Production Value: 1
@@ -1413,13 +1418,9 @@ session.serialize_handler = php
session.gc_probability = 1 session.gc_probability = 1
; Defines the probability that the 'garbage collection' process is started on every ; Defines the probability that the 'garbage collection' process is started on every
; session initialization. The probability is calculated by using the following equation: ; session initialization. The probability is calculated by using gc_probability/gc_divisor,
; gc_probability/gc_divisor. Where session.gc_probability is the numerator and ; e.g. 1/100 means there is a 1% chance that the GC process starts on each request.
; session.gc_divisor is the denominator in the equation. Setting this value to 1 ; For high volume production servers, using a value of 1000 is a more efficient approach.
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request. Increasing this value to 1000 will give you
; a 0.1% chance the gc will run on any give request. For high volume production servers,
; this is a more efficient approach.
; Default Value: 100 ; Default Value: 100
; Development Value: 1000 ; Development Value: 1000
; Production Value: 1000 ; Production Value: 1000
@@ -1435,8 +1436,8 @@ session.gc_maxlifetime = 1440
; (see session.save_path above), then garbage collection does *not* ; (see session.save_path above), then garbage collection does *not*
; happen automatically. You will need to do your own garbage ; happen automatically. You will need to do your own garbage
; collection through a shell script, cron entry, or some other method. ; collection through a shell script, cron entry, or some other method.
; For example, the following script would is the equivalent of ; For example, the following script is the equivalent of setting
; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): ; session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
; find /path/to/sessions -cmin +24 -type f | xargs rm ; find /path/to/sessions -cmin +24 -type f | xargs rm
; Check HTTP Referer to invalidate externally stored URLs containing ids. ; Check HTTP Referer to invalidate externally stored URLs containing ids.
@@ -1488,7 +1489,7 @@ session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form=" session.trans_sid_tags = "a=href,area=href,frame=src,form="
; URL rewriter does not rewrite absolute URLs by default. ; URL rewriter does not rewrite absolute URLs by default.
; To enable rewrites for absolute pathes, target hosts must be specified ; To enable rewrites for absolute paths, target hosts must be specified
; at RUNTIME. i.e. use ini_set() ; at RUNTIME. i.e. use ini_set()
; <form> tags is special. PHP will check action attribute's URL regardless ; <form> tags is special. PHP will check action attribute's URL regardless
; of session.trans_sid_tags setting. ; of session.trans_sid_tags setting.
@@ -1577,7 +1578,7 @@ zend.assertions = -1
; http://php.net/assert.active ; http://php.net/assert.active
;assert.active = On ;assert.active = On
; Throw an AssertationException on failed assertions ; Throw an AssertionError on failed assertions
; http://php.net/assert.exception ; http://php.net/assert.exception
;assert.exception = On ;assert.exception = On
@@ -1593,11 +1594,6 @@ zend.assertions = -1
; http://php.net/assert.callback ; http://php.net/assert.callback
;assert.callback = 0 ;assert.callback = 0
; Eval the expression with current error_reporting(). Set to true if you want
; error_reporting(0) around the eval().
; http://php.net/assert.quiet-eval
;assert.quiet_eval = 0
[COM] [COM]
; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs ; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs
; http://php.net/com.typelib-file ; http://php.net/com.typelib-file
@@ -1607,7 +1603,7 @@ zend.assertions = -1
; http://php.net/com.allow-dcom ; http://php.net/com.allow-dcom
;com.allow_dcom = true ;com.allow_dcom = true
; autoregister constants of a components typlib on com_load() ; autoregister constants of a component's typlib on com_load()
; http://php.net/com.autoregister-typelib ; http://php.net/com.autoregister-typelib
;com.autoregister_typelib = true ;com.autoregister_typelib = true
@@ -1623,6 +1619,10 @@ zend.assertions = -1
; Default: system ANSI code page ; Default: system ANSI code page
;com.code_page= ;com.code_page=
; The version of the .NET framework to use. The value of the setting are the first three parts
; of the framework's version number, separated by dots, and prefixed with "v", e.g. "v4.0.30319".
;com.dotnet_version=
[mbstring] [mbstring]
; language for internal character representation. ; language for internal character representation.
; This affects mb_send_mail() and mbstring.detect_order. ; This affects mb_send_mail() and mbstring.detect_order.
@@ -1638,9 +1638,9 @@ zend.assertions = -1
; Use of this INI entry is deprecated, use global input_encoding instead. ; Use of this INI entry is deprecated, use global input_encoding instead.
; http input encoding. ; http input encoding.
; mbstring.encoding_traslation = On is needed to use this setting. ; mbstring.encoding_translation = On is needed to use this setting.
; If empty, default_charset or input_encoding or mbstring.input is used. ; If empty, default_charset or input_encoding or mbstring.input is used.
; The precedence is: default_charset < intput_encoding < mbsting.http_input ; The precedence is: default_charset < input_encoding < mbstring.http_input
; http://php.net/mbstring.http-input ; http://php.net/mbstring.http-input
;mbstring.http_input = ;mbstring.http_input =
@@ -1672,26 +1672,22 @@ zend.assertions = -1
; http://php.net/mbstring.substitute-character ; http://php.net/mbstring.substitute-character
;mbstring.substitute_character = none ;mbstring.substitute_character = none
; overload(replace) single byte functions by mbstring functions. ; Enable strict encoding detection.
; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(), ;mbstring.strict_detection = Off
; etc. Possible values are 0,1,2,4 or combination of them.
; For example, 7 for overload everything.
; 0: No overload
; 1: Overload mail() function
; 2: Overload str*() functions
; 4: Overload ereg*() functions
; http://php.net/mbstring.func-overload
;mbstring.func_overload = 0
; enable strict encoding detection.
; Default: Off
;mbstring.strict_detection = On
; This directive specifies the regex pattern of content types for which mb_output_handler() ; This directive specifies the regex pattern of content types for which mb_output_handler()
; is activated. ; is activated.
; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml) ; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml)
;mbstring.http_output_conv_mimetype= ;mbstring.http_output_conv_mimetype=
; This directive specifies maximum stack depth for mbstring regular expressions. It is similar
; to the pcre.recursion_limit for PCRE.
;mbstring.regex_stack_limit=100000
; This directive specifies maximum retry count for mbstring regular expressions. It is similar
; to the pcre.backtrack_limit for PCRE.
;mbstring.regex_retry_limit=1000000
[gd] [gd]
; Tell the jpeg decode to ignore warnings and try to create ; Tell the jpeg decode to ignore warnings and try to create
; a gd image. The warning will then be displayed as notices ; a gd image. The warning will then be displayed as notices
@@ -1804,14 +1800,18 @@ opcache.enable=1
; size of the optimized code. ; size of the optimized code.
;opcache.save_comments=1 ;opcache.save_comments=1
; If enabled, compilation warnings (including notices and deprecations) will
; be recorded and replayed each time a file is included. Otherwise, compilation
; warnings will only be emitted when the file is first cached.
;opcache.record_warnings=0
; Allow file existence override (file_exists, etc.) performance feature. ; Allow file existence override (file_exists, etc.) performance feature.
;opcache.enable_file_override=0 ;opcache.enable_file_override=0
; A bitmask, where each bit enables or disables the appropriate OPcache ; A bitmask, where each bit enables or disables the appropriate OPcache
; passes ; passes
;opcache.optimization_level=0xffffffff ;opcache.optimization_level=0x7FFFBFFF
;opcache.inherited_hack=1
;opcache.dups_fix=0 ;opcache.dups_fix=0
; The location of the OPcache blacklist file (wildcards allowed). ; The location of the OPcache blacklist file (wildcards allowed).
@@ -1860,6 +1860,10 @@ opcache.enable=1
; errors. ; errors.
;opcache.mmap_base= ;opcache.mmap_base=
; Facilitates multiple OPcache instances per user (for Windows only). All PHP
; processes with the same cache ID and user share an OPcache instance.
;opcache.cache_id=
; Enables and sets the second level cache directory. ; Enables and sets the second level cache directory.
; It should improve performance when SHM memory is full, at server restart or ; It should improve performance when SHM memory is full, at server restart or
; SHM reset. The default "" disables file based caching. ; SHM reset. The default "" disables file based caching.
@@ -1890,6 +1894,24 @@ opcache.enable=1
; optimizations. ; optimizations.
;opcache.opt_debug_level=0 ;opcache.opt_debug_level=0
; Specifies a PHP script that is going to be compiled and executed at server
; start-up.
; http://php.net/opcache.preload
;opcache.preload=
; Preloading code as root is not allowed for security reasons. This directive
; facilitates to let the preloading to be run as another user.
; http://php.net/opcache.preload_user
;opcache.preload_user=
; Prevents caching files that are less than this number of seconds old. It
; protects from caching of incompletely updated files. In case all file updates
; on your site are atomic, you may increase performance by setting it to "0".
;opcache.file_update_protection=2
; Absolute path used to store shared lockfiles (for *nix only).
;opcache.lockfile_path=/tmp
[curl] [curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an ; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path. ; absolute path.
@@ -1913,6 +1935,12 @@ opcache.enable=1
; SSL stream context option. ; SSL stream context option.
;openssl.capath= ;openssl.capath=
; Local Variables: [ffi]
; tab-width: 4 ; FFI API restriction. Possible values:
; End: ; "preload" - enabled in CLI scripts and preloaded files (default)
; "false" - always disabled
; "true" - always enabled
;ffi.enable=preload
; List of headers files to preload, wildcard patterns allowed.
;ffi.preload=

View File

@@ -27,10 +27,14 @@ group = www
; Valid syntaxes are: ; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port; ; a specific port;
; '0.0.0.0:port' - to listen on a TCP socket to all IPv4 addresses on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on ; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port; ; a specific port;
; 'port' - to listen on a TCP socket to all addresses ; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port; ; (IPv6 and IPv4-mapped) on a specific port;
; Note: IPv4-mapped addresses are disabled by-default in
; FreeBSD for security reasons;
; '/path/to/unix/socket' - to listen on a unix socket. ; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory. ; Note: This value is mandatory.
listen = /tmp/php-fpm.sock listen = /tmp/php-fpm.sock
@@ -41,7 +45,8 @@ listen.backlog = -1
; Set permissions for unix socket, if one is used. In Linux, read/write ; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many ; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions. ; BSD-derived systems allow connections regardless of permissions. The owner
; and group can be specified either by name or by their numeric IDs.
; Default Values: user and group are set as the running user ; Default Values: user and group are set as the running user
; mode is set to 0660 ; mode is set to 0660
listen.owner = www listen.owner = www
@@ -70,7 +75,7 @@ listen.mode = 0660
; process.priority = -19 ; process.priority = -19
; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user ; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user
; or group is differrent than the master process user. It allows to create process ; or group is different than the master process user. It allows to create process
; core dump and ptrace the process for the pool user. ; core dump and ptrace the process for the pool user.
; Default Value: no ; Default Value: no
; process.dumpable = yes ; process.dumpable = yes
@@ -114,7 +119,7 @@ pm.max_children = 5
; The number of child processes created on startup. ; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic' ; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 ; Default Value: (min_spare_servers + max_spare_servers) / 2
pm.start_servers = 2 pm.start_servers = 2
; The desired minimum number of idle server processes. ; The desired minimum number of idle server processes.
@@ -139,7 +144,7 @@ pm.max_spare_servers = 3
;pm.max_requests = 500 ;pm.max_requests = 500
; The URI to view the FPM status page. If this value is not set, no URI will be ; The URI to view the FPM status page. If this value is not set, no URI will be
; recognized as a status page. It shows the following informations: ; recognized as a status page. It shows the following information:
; pool - the name of the pool; ; pool - the name of the pool;
; process manager - static, dynamic or ondemand; ; process manager - static, dynamic or ondemand;
; start time - the date and time FPM has started; ; start time - the date and time FPM has started;
@@ -237,6 +242,22 @@ pm.max_spare_servers = 3
; Default Value: not set ; Default Value: not set
;pm.status_path = /status ;pm.status_path = /status
; The address on which to accept FastCGI status request. This creates a new
; invisible pool that can handle requests independently. This is useful
; if the main pool is busy with long running requests because it is still possible
; to get the status before finishing the long running requests.
;
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Default Value: value of the listen option
;pm.status_listen = 127.0.0.1:9001
; The ping URI to call the monitoring page of FPM. If this value is not set, no ; The ping URI to call the monitoring page of FPM. If this value is not set, no
; URI will be recognized as a ping page. This could be used to test from outside ; URI will be recognized as a ping page. This could be used to test from outside
; that FPM is alive and responding, or to ; that FPM is alive and responding, or to
@@ -269,13 +290,13 @@ pm.max_spare_servers = 3
; %d: time taken to serve the request ; %d: time taken to serve the request
; it can accept the following format: ; it can accept the following format:
; - %{seconds}d (default) ; - %{seconds}d (default)
; - %{miliseconds}d ; - %{milliseconds}d
; - %{mili}d ; - %{mili}d
; - %{microseconds}d ; - %{microseconds}d
; - %{micro}d ; - %{micro}d
; %e: an environment variable (same as $_ENV or $_SERVER) ; %e: an environment variable (same as $_ENV or $_SERVER)
; it must be associated with embraces to specify the name of the env ; it must be associated with embraces to specify the name of the env
; variable. Some exemples: ; variable. Some examples:
; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e ; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e ; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
; %f: script filename ; %f: script filename
@@ -339,6 +360,14 @@ pm.max_spare_servers = 3
; Default Value: 0 ; Default Value: 0
;request_terminate_timeout = 0 ;request_terminate_timeout = 0
; The timeout set by 'request_terminate_timeout' ini option is not engaged after
; application calls 'fastcgi_finish_request' or when application has finished and
; shutdown functions are being called (registered via register_shutdown_function).
; This option will enable timeout limit to be applied unconditionally
; even in such cases.
; Default Value: no
;request_terminate_timeout_track_finished = no
; Set open file descriptor rlimit. ; Set open file descriptor rlimit.
; Default Value: system defined value ; Default Value: system defined value
;rlimit_files = 1024 ;rlimit_files = 1024
@@ -366,11 +395,18 @@ pm.max_spare_servers = 3
; Redirect worker stdout and stderr into main error log. If not set, stdout and ; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs. ; stderr will be redirected to /dev/null according to FastCGI specs.
; Note: on highloaded environement, this can cause some delay in the page ; Note: on highloaded environment, this can cause some delay in the page
; process time (several ms). ; process time (several ms).
; Default Value: no ; Default Value: no
;catch_workers_output = yes ;catch_workers_output = yes
; Decorate worker output with prefix and suffix containing information about
; the child that writes to the log and if stdout or stderr is used as well as
; log level and time. This options is used only if catch_workers_output is yes.
; Settings to "no" will output data as written to the stdout or stderr.
; Default value: yes
;decorate_workers_output = no
; Clear environment in FPM workers ; Clear environment in FPM workers
; Prevents arbitrary environment variables from reaching FPM worker processes ; Prevents arbitrary environment variables from reaching FPM worker processes
; by clearing the environment in workers before env vars specified in this ; by clearing the environment in workers before env vars specified in this

2
node/node_modules/async-limiter/.eslintignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
coverage
.nyc_output

10
node/node_modules/async-limiter/.nycrc generated vendored Normal file
View File

@@ -0,0 +1,10 @@
{
"check-coverage": false,
"lines": 99,
"statements": 99,
"functions": 99,
"branches": 99,
"include": [
"index.js"
]
}

View File

@@ -1,6 +1,8 @@
language: node_js language: node_js
node_js: node_js:
- "6" - "6"
- "8"
- "10"
- "node" - "node"
script: npm run travis script: npm run travis
cache: cache:

View File

@@ -1 +0,0 @@
{"/Users/samuelreed/git/forks/async-throttle/index.js":{"path":"/Users/samuelreed/git/forks/async-throttle/index.js","s":{"1":1,"2":7,"3":1,"4":6,"5":6,"6":6,"7":6,"8":6,"9":6,"10":1,"11":1,"12":3,"13":13,"14":13,"15":13,"16":1,"17":19,"18":1,"19":45,"20":6,"21":39,"22":13,"23":13,"24":13,"25":13,"26":39,"27":18,"28":6,"29":6,"30":1,"31":6,"32":6,"33":6,"34":1,"35":13,"36":13,"37":1},"b":{"1":[1,6],"2":[6,5],"3":[6,5],"4":[6,39],"5":[13,26],"6":[18,21],"7":[6,0]},"f":{"1":7,"2":3,"3":13,"4":19,"5":45,"6":6,"7":13},"fnMap":{"1":{"name":"Queue","line":3,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":24}}},"2":{"name":"(anonymous_2)","line":22,"loc":{"start":{"line":22,"column":24},"end":{"line":22,"column":41}}},"3":{"name":"(anonymous_3)","line":23,"loc":{"start":{"line":23,"column":28},"end":{"line":23,"column":39}}},"4":{"name":"(anonymous_4)","line":31,"loc":{"start":{"line":31,"column":7},"end":{"line":31,"column":18}}},"5":{"name":"(anonymous_5)","line":36,"loc":{"start":{"line":36,"column":23},"end":{"line":36,"column":34}}},"6":{"name":"(anonymous_6)","line":55,"loc":{"start":{"line":55,"column":25},"end":{"line":55,"column":38}}},"7":{"name":"done","line":62,"loc":{"start":{"line":62,"column":0},"end":{"line":62,"column":16}}}},"statementMap":{"1":{"start":{"line":3,"column":0},"end":{"line":14,"column":1}},"2":{"start":{"line":4,"column":2},"end":{"line":6,"column":3}},"3":{"start":{"line":5,"column":4},"end":{"line":5,"column":30}},"4":{"start":{"line":8,"column":2},"end":{"line":8,"column":26}},"5":{"start":{"line":9,"column":2},"end":{"line":9,"column":53}},"6":{"start":{"line":10,"column":2},"end":{"line":10,"column":19}},"7":{"start":{"line":11,"column":2},"end":{"line":11,"column":17}},"8":{"start":{"line":12,"column":2},"end":{"line":12,"column":16}},"9":{"start":{"line":13,"column":2},"end":{"line":13,"column":31}},"10":{"start":{"line":16,"column":0},"end":{"line":20,"column":2}},"11":{"start":{"line":22,"column":0},"end":{"line":28,"column":3}},"12":{"start":{"line":23,"column":2},"end":{"line":27,"column":4}},"13":{"start":{"line":24,"column":4},"end":{"line":24,"column":75}},"14":{"start":{"line":25,"column":4},"end":{"line":25,"column":16}},"15":{"start":{"line":26,"column":4},"end":{"line":26,"column":24}},"16":{"start":{"line":30,"column":0},"end":{"line":34,"column":3}},"17":{"start":{"line":32,"column":4},"end":{"line":32,"column":43}},"18":{"start":{"line":36,"column":0},"end":{"line":53,"column":2}},"19":{"start":{"line":37,"column":2},"end":{"line":39,"column":3}},"20":{"start":{"line":38,"column":4},"end":{"line":38,"column":11}},"21":{"start":{"line":40,"column":2},"end":{"line":45,"column":3}},"22":{"start":{"line":41,"column":4},"end":{"line":41,"column":32}},"23":{"start":{"line":42,"column":4},"end":{"line":42,"column":19}},"24":{"start":{"line":43,"column":4},"end":{"line":43,"column":20}},"25":{"start":{"line":44,"column":4},"end":{"line":44,"column":16}},"26":{"start":{"line":47,"column":2},"end":{"line":52,"column":3}},"27":{"start":{"line":48,"column":4},"end":{"line":51,"column":5}},"28":{"start":{"line":49,"column":6},"end":{"line":49,"column":30}},"29":{"start":{"line":50,"column":6},"end":{"line":50,"column":27}},"30":{"start":{"line":55,"column":0},"end":{"line":60,"column":2}},"31":{"start":{"line":56,"column":2},"end":{"line":59,"column":3}},"32":{"start":{"line":57,"column":4},"end":{"line":57,"column":22}},"33":{"start":{"line":58,"column":4},"end":{"line":58,"column":16}},"34":{"start":{"line":62,"column":0},"end":{"line":65,"column":1}},"35":{"start":{"line":63,"column":2},"end":{"line":63,"column":17}},"36":{"start":{"line":64,"column":2},"end":{"line":64,"column":14}},"37":{"start":{"line":67,"column":0},"end":{"line":67,"column":23}}},"branchMap":{"1":{"line":4,"type":"if","locations":[{"start":{"line":4,"column":2},"end":{"line":4,"column":2}},{"start":{"line":4,"column":2},"end":{"line":4,"column":2}}]},"2":{"line":8,"type":"binary-expr","locations":[{"start":{"line":8,"column":12},"end":{"line":8,"column":19}},{"start":{"line":8,"column":23},"end":{"line":8,"column":25}}]},"3":{"line":9,"type":"binary-expr","locations":[{"start":{"line":9,"column":21},"end":{"line":9,"column":40}},{"start":{"line":9,"column":44},"end":{"line":9,"column":52}}]},"4":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":37,"column":2}},{"start":{"line":37,"column":2},"end":{"line":37,"column":2}}]},"5":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":40,"column":2}},{"start":{"line":40,"column":2},"end":{"line":40,"column":2}}]},"6":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":2},"end":{"line":47,"column":2}},{"start":{"line":47,"column":2},"end":{"line":47,"column":2}}]},"7":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":56,"column":2}},{"start":{"line":56,"column":2},"end":{"line":56,"column":2}}]}}}}

View File

@@ -1,73 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for async-throttle/</title>
<meta charset="utf-8">
<link rel="stylesheet" href="../prettify.css">
<link rel="stylesheet" href="../base.css">
<style type='text/css'>
div.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class="header high">
<h1>Code coverage report for <span class="entity">async-throttle/</span></h1>
<h2>
Statements: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Branches: <span class="metric">92.86% <small>(13 / 14)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Functions: <span class="metric">100% <small>(7 / 7)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Lines: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Ignored: <span class="metric"><span class="ignore-none">none</span></span> &nbsp;&nbsp;&nbsp;&nbsp;
</h2>
<div class="path"><a href="../index.html">All files</a> &#187; async-throttle/</div>
</div>
<div class="body">
<div class="coverage-summary">
<table>
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody><tr>
<td class="file high" data-value="index.js"><a href="index.js.html">index.js</a></td>
<td data-value="100" class="pic high"><span class="cover-fill cover-full" style="width: 100px;"></span><span class="cover-empty" style="width:0px;"></span></td>
<td data-value="100" class="pct high">100%</td>
<td data-value="37" class="abs high">(37&nbsp;/&nbsp;37)</td>
<td data-value="92.86" class="pct high">92.86%</td>
<td data-value="14" class="abs high">(13&nbsp;/&nbsp;14)</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="7" class="abs high">(7&nbsp;/&nbsp;7)</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="37" class="abs high">(37&nbsp;/&nbsp;37)</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="footer">
<div class="meta">Generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Mon Sep 11 2017 11:14:14 GMT-0500 (CDT)</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>

View File

@@ -1,246 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for async-throttle/index.js</title>
<meta charset="utf-8">
<link rel="stylesheet" href="../prettify.css">
<link rel="stylesheet" href="../base.css">
<style type='text/css'>
div.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class="header high">
<h1>Code coverage report for <span class="entity">async-throttle/index.js</span></h1>
<h2>
Statements: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Branches: <span class="metric">92.86% <small>(13 / 14)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Functions: <span class="metric">100% <small>(7 / 7)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Lines: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Ignored: <span class="metric"><span class="ignore-none">none</span></span> &nbsp;&nbsp;&nbsp;&nbsp;
</h2>
<div class="path"><a href="../index.html">All files</a> &#187; <a href="index.html">async-throttle/</a> &#187; index.js</div>
</div>
<div class="body">
<pre><table class="coverage">
<tr><td class="line-count">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68</td><td class="line-coverage"><span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">7</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">3</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">19</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">45</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">39</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">39</span>
<span class="cline-any cline-yes">18</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-yes">6</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-yes">13</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">'use strict';
&nbsp;
function Queue(options) {
if (!(this instanceof Queue)) {
return new Queue(options);
}
&nbsp;
options = options || {};
this.concurrency = options.concurrency || Infinity;
this.pending = 0;
this.jobs = [];
this.cbs = [];
this._done = done.bind(this);
}
&nbsp;
var arrayAddMethods = [
'push',
'unshift',
'splice'
];
&nbsp;
arrayAddMethods.forEach(function(method) {
Queue.prototype[method] = function() {
var methodResult = Array.prototype[method].apply(this.jobs, arguments);
this._run();
return methodResult;
};
});
&nbsp;
Object.defineProperty(Queue.prototype, 'length', {
get: function() {
return this.pending + this.jobs.length;
}
});
&nbsp;
Queue.prototype._run = function() {
if (this.pending === this.concurrency) {
return;
}
if (this.jobs.length) {
var job = this.jobs.shift();
this.pending++;
job(this._done);
this._run();
}
&nbsp;
if (this.pending === 0) {
while (this.cbs.length !== 0) {
var cb = this.cbs.pop();
process.nextTick(cb);
}
}
};
&nbsp;
Queue.prototype.onDone = function(cb) {
<span class="missing-if-branch" title="else path not taken" >E</span>if (typeof cb === 'function') {
this.cbs.push(cb);
this._run();
}
};
&nbsp;
function done() {
this.pending--;
this._run();
}
&nbsp;
module.exports = Queue;
&nbsp;</pre></td></tr>
</table></pre>
</div>
<div class="footer">
<div class="meta">Generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Mon Sep 11 2017 11:14:14 GMT-0500 (CDT)</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>

View File

@@ -1,182 +0,0 @@
body, html {
margin:0; padding: 0;
}
body {
font-family: Helvetica Neue, Helvetica,Arial;
font-size: 10pt;
}
div.header, div.footer {
background: #eee;
padding: 1em;
}
div.header {
z-index: 100;
position: fixed;
top: 0;
border-bottom: 1px solid #666;
width: 100%;
}
div.footer {
border-top: 1px solid #666;
}
div.body {
margin-top: 10em;
}
div.meta {
font-size: 90%;
text-align: center;
}
h1, h2, h3 {
font-weight: normal;
}
h1 {
font-size: 12pt;
}
h2 {
font-size: 10pt;
}
pre {
font-family: Consolas, Menlo, Monaco, monospace;
margin: 0;
padding: 0;
line-height: 1.3;
font-size: 14px;
-moz-tab-size: 2;
-o-tab-size: 2;
tab-size: 2;
}
div.path { font-size: 110%; }
div.path a:link, div.path a:visited { color: #000; }
table.coverage { border-collapse: collapse; margin:0; padding: 0 }
table.coverage td {
margin: 0;
padding: 0;
color: #111;
vertical-align: top;
}
table.coverage td.line-count {
width: 50px;
text-align: right;
padding-right: 5px;
}
table.coverage td.line-coverage {
color: #777 !important;
text-align: right;
border-left: 1px solid #666;
border-right: 1px solid #666;
}
table.coverage td.text {
}
table.coverage td span.cline-any {
display: inline-block;
padding: 0 5px;
width: 40px;
}
table.coverage td span.cline-neutral {
background: #eee;
}
table.coverage td span.cline-yes {
background: #b5d592;
color: #999;
}
table.coverage td span.cline-no {
background: #fc8c84;
}
.cstat-yes { color: #111; }
.cstat-no { background: #fc8c84; color: #111; }
.fstat-no { background: #ffc520; color: #111 !important; }
.cbranch-no { background: yellow !important; color: #111; }
.cstat-skip { background: #ddd; color: #111; }
.fstat-skip { background: #ddd; color: #111 !important; }
.cbranch-skip { background: #ddd !important; color: #111; }
.missing-if-branch {
display: inline-block;
margin-right: 10px;
position: relative;
padding: 0 4px;
background: black;
color: yellow;
}
.skip-if-branch {
display: none;
margin-right: 10px;
position: relative;
padding: 0 4px;
background: #ccc;
color: white;
}
.missing-if-branch .typ, .skip-if-branch .typ {
color: inherit !important;
}
.entity, .metric { font-weight: bold; }
.metric { display: inline-block; border: 1px solid #333; padding: 0.3em; background: white; }
.metric small { font-size: 80%; font-weight: normal; color: #666; }
div.coverage-summary table { border-collapse: collapse; margin: 3em; font-size: 110%; }
div.coverage-summary td, div.coverage-summary table th { margin: 0; padding: 0.25em 1em; border-top: 1px solid #666; border-bottom: 1px solid #666; }
div.coverage-summary th { text-align: left; border: 1px solid #666; background: #eee; font-weight: normal; }
div.coverage-summary th.file { border-right: none !important; }
div.coverage-summary th.pic { border-left: none !important; text-align: right; }
div.coverage-summary th.pct { border-right: none !important; }
div.coverage-summary th.abs { border-left: none !important; text-align: right; }
div.coverage-summary td.pct { text-align: right; border-left: 1px solid #666; }
div.coverage-summary td.abs { text-align: right; font-size: 90%; color: #444; border-right: 1px solid #666; }
div.coverage-summary td.file { border-left: 1px solid #666; white-space: nowrap; }
div.coverage-summary td.pic { min-width: 120px !important; }
div.coverage-summary a:link { text-decoration: none; color: #000; }
div.coverage-summary a:visited { text-decoration: none; color: #777; }
div.coverage-summary a:hover { text-decoration: underline; }
div.coverage-summary tfoot td { border-top: 1px solid #666; }
div.coverage-summary .sorter {
height: 10px;
width: 7px;
display: inline-block;
margin-left: 0.5em;
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
}
div.coverage-summary .sorted .sorter {
background-position: 0 -20px;
}
div.coverage-summary .sorted-desc .sorter {
background-position: 0 -10px;
}
.high { background: #b5d592 !important; }
.medium { background: #ffe87c !important; }
.low { background: #fc8c84 !important; }
span.cover-fill, span.cover-empty {
display:inline-block;
border:1px solid #444;
background: white;
height: 12px;
}
span.cover-fill {
background: #ccc;
border-right: 1px solid #444;
}
span.cover-empty {
background: white;
border-left: none;
}
span.cover-full {
border-right: none !important;
}
pre.prettyprint {
border: none !important;
padding: 0 !important;
margin: 0 !important;
}
.com { color: #999 !important; }
.ignore-none { color: #999; font-weight: normal; }

View File

@@ -1,73 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for All files</title>
<meta charset="utf-8">
<link rel="stylesheet" href="prettify.css">
<link rel="stylesheet" href="base.css">
<style type='text/css'>
div.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class="header high">
<h1>Code coverage report for <span class="entity">All files</span></h1>
<h2>
Statements: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Branches: <span class="metric">92.86% <small>(13 / 14)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Functions: <span class="metric">100% <small>(7 / 7)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Lines: <span class="metric">100% <small>(37 / 37)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
Ignored: <span class="metric"><span class="ignore-none">none</span></span> &nbsp;&nbsp;&nbsp;&nbsp;
</h2>
<div class="path"></div>
</div>
<div class="body">
<div class="coverage-summary">
<table>
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody><tr>
<td class="file high" data-value="async-throttle/"><a href="async-throttle/index.html">async-throttle/</a></td>
<td data-value="100" class="pic high"><span class="cover-fill cover-full" style="width: 100px;"></span><span class="cover-empty" style="width:0px;"></span></td>
<td data-value="100" class="pct high">100%</td>
<td data-value="37" class="abs high">(37&nbsp;/&nbsp;37)</td>
<td data-value="92.86" class="pct high">92.86%</td>
<td data-value="14" class="abs high">(13&nbsp;/&nbsp;14)</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="7" class="abs high">(7&nbsp;/&nbsp;7)</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="37" class="abs high">(37&nbsp;/&nbsp;37)</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="footer">
<div class="meta">Generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Mon Sep 11 2017 11:14:14 GMT-0500 (CDT)</div>
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="sorter.js"></script>
</body>
</html>

View File

@@ -1 +0,0 @@
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

View File

@@ -1,156 +0,0 @@
var addSorting = (function () {
"use strict";
var cols,
currentSort = {
index: 0,
desc: false
};
// returns the summary table element
function getTable() { return document.querySelector('.coverage-summary table'); }
// returns the thead element of the summary table
function getTableHeader() { return getTable().querySelector('thead tr'); }
// returns the tbody element of the summary table
function getTableBody() { return getTable().querySelector('tbody'); }
// returns the th element for nth column
function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
// loads all columns
function loadColumns() {
var colNodes = getTableHeader().querySelectorAll('th'),
colNode,
cols = [],
col,
i;
for (i = 0; i < colNodes.length; i += 1) {
colNode = colNodes[i];
col = {
key: colNode.getAttribute('data-col'),
sortable: !colNode.getAttribute('data-nosort'),
type: colNode.getAttribute('data-type') || 'string'
};
cols.push(col);
if (col.sortable) {
col.defaultDescSort = col.type === 'number';
colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
}
}
return cols;
}
// attaches a data attribute to every tr element with an object
// of data values keyed by column name
function loadRowData(tableRow) {
var tableCols = tableRow.querySelectorAll('td'),
colNode,
col,
data = {},
i,
val;
for (i = 0; i < tableCols.length; i += 1) {
colNode = tableCols[i];
col = cols[i];
val = colNode.getAttribute('data-value');
if (col.type === 'number') {
val = Number(val);
}
data[col.key] = val;
}
return data;
}
// loads all row data
function loadData() {
var rows = getTableBody().querySelectorAll('tr'),
i;
for (i = 0; i < rows.length; i += 1) {
rows[i].data = loadRowData(rows[i]);
}
}
// sorts the table using the data for the ith column
function sortByIndex(index, desc) {
var key = cols[index].key,
sorter = function (a, b) {
a = a.data[key];
b = b.data[key];
return a < b ? -1 : a > b ? 1 : 0;
},
finalSorter = sorter,
tableBody = document.querySelector('.coverage-summary tbody'),
rowNodes = tableBody.querySelectorAll('tr'),
rows = [],
i;
if (desc) {
finalSorter = function (a, b) {
return -1 * sorter(a, b);
};
}
for (i = 0; i < rowNodes.length; i += 1) {
rows.push(rowNodes[i]);
tableBody.removeChild(rowNodes[i]);
}
rows.sort(finalSorter);
for (i = 0; i < rows.length; i += 1) {
tableBody.appendChild(rows[i]);
}
}
// removes sort indicators for current column being sorted
function removeSortIndicators() {
var col = getNthColumn(currentSort.index),
cls = col.className;
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
col.className = cls;
}
// adds sort indicators for current column being sorted
function addSortIndicators() {
getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
}
// adds event listeners for all sorter widgets
function enableUI() {
var i,
el,
ithSorter = function ithSorter(i) {
var col = cols[i];
return function () {
var desc = col.defaultDescSort;
if (currentSort.index === i) {
desc = !currentSort.desc;
}
sortByIndex(i, desc);
removeSortIndicators();
currentSort.index = i;
currentSort.desc = desc;
addSortIndicators();
};
};
for (i =0 ; i < cols.length; i += 1) {
if (cols[i].sortable) {
el = getNthColumn(i).querySelector('.sorter');
if (el.addEventListener) {
el.addEventListener('click', ithSorter(i));
} else {
el.attachEvent('onclick', ithSorter(i));
}
}
}
}
// adds sorting functionality to the UI
return function () {
if (!getTable()) {
return;
}
cols = loadColumns();
loadData(cols);
addSortIndicators();
enableUI();
};
})();
window.addEventListener('load', addSorting);

View File

@@ -1,74 +0,0 @@
TN:
SF:/Users/samuelreed/git/forks/async-throttle/index.js
FN:3,Queue
FN:22,(anonymous_2)
FN:23,(anonymous_3)
FN:31,(anonymous_4)
FN:36,(anonymous_5)
FN:55,(anonymous_6)
FN:62,done
FNF:7
FNH:7
FNDA:7,Queue
FNDA:3,(anonymous_2)
FNDA:13,(anonymous_3)
FNDA:19,(anonymous_4)
FNDA:45,(anonymous_5)
FNDA:6,(anonymous_6)
FNDA:13,done
DA:3,1
DA:4,7
DA:5,1
DA:8,6
DA:9,6
DA:10,6
DA:11,6
DA:12,6
DA:13,6
DA:16,1
DA:22,1
DA:23,3
DA:24,13
DA:25,13
DA:26,13
DA:30,1
DA:32,19
DA:36,1
DA:37,45
DA:38,6
DA:40,39
DA:41,13
DA:42,13
DA:43,13
DA:44,13
DA:47,39
DA:48,18
DA:49,6
DA:50,6
DA:55,1
DA:56,6
DA:57,6
DA:58,6
DA:62,1
DA:63,13
DA:64,13
DA:67,1
LF:37
LH:37
BRDA:4,1,0,1
BRDA:4,1,1,6
BRDA:8,2,0,6
BRDA:8,2,1,5
BRDA:9,3,0,6
BRDA:9,3,1,5
BRDA:37,4,0,6
BRDA:37,4,1,39
BRDA:40,5,0,13
BRDA:40,5,1,26
BRDA:47,6,0,18
BRDA:47,6,1,21
BRDA:56,7,0,6
BRDA:56,7,1,0
BRF:14
BRH:13
end_of_record

View File

@@ -1,45 +1,48 @@
{ {
"_from": "async-limiter@~1.0.0", "_args": [
"_id": "async-limiter@1.0.0", [
"async-limiter@1.0.1",
"/usr/local/www/clonos/node"
]
],
"_from": "async-limiter@1.0.1",
"_id": "async-limiter@1.0.1",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", "_integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
"_location": "/async-limiter", "_location": "/async-limiter",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
"type": "range", "type": "version",
"registry": true, "registry": true,
"raw": "async-limiter@~1.0.0", "raw": "async-limiter@1.0.1",
"name": "async-limiter", "name": "async-limiter",
"escapedName": "async-limiter", "escapedName": "async-limiter",
"rawSpec": "~1.0.0", "rawSpec": "1.0.1",
"saveSpec": null, "saveSpec": null,
"fetchSpec": "~1.0.0" "fetchSpec": "1.0.1"
}, },
"_requiredBy": [ "_requiredBy": [
"/ws" "/ws"
], ],
"_resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "_resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"_shasum": "78faed8c3d074ab81f22b4e985d79e8738f720f8", "_spec": "1.0.1",
"_spec": "async-limiter@~1.0.0", "_where": "/usr/local/www/clonos/node",
"_where": "/usr/home/web/cp/clonos/node/node_modules/ws",
"author": { "author": {
"name": "Samuel Reed" "name": "Samuel Reed"
}, },
"bugs": { "bugs": {
"url": "https://github.com/strml/async-limiter/issues" "url": "https://github.com/strml/async-limiter/issues"
}, },
"bundleDependencies": false,
"dependencies": {}, "dependencies": {},
"deprecated": false,
"description": "asynchronous function queue with adjustable concurrency", "description": "asynchronous function queue with adjustable concurrency",
"devDependencies": { "devDependencies": {
"coveralls": "^2.11.2", "coveralls": "^3.0.3",
"eslint": "^4.6.1", "eslint": "^5.16.0",
"eslint-plugin-mocha": "^4.11.0", "eslint-plugin-mocha": "^5.3.0",
"intelli-espower-loader": "^1.0.1", "intelli-espower-loader": "^1.0.1",
"istanbul": "^0.3.2", "mocha": "^6.1.4",
"mocha": "^3.5.2", "nyc": "^14.1.1",
"power-assert": "^1.4.4" "power-assert": "^1.6.1"
}, },
"homepage": "https://github.com/strml/async-limiter#readme", "homepage": "https://github.com/strml/async-limiter#readme",
"keywords": [ "keywords": [
@@ -59,11 +62,11 @@
"url": "git+https://github.com/strml/async-limiter.git" "url": "git+https://github.com/strml/async-limiter.git"
}, },
"scripts": { "scripts": {
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls", "coverage": "nyc npm test && nyc report --reporter=text-lcov | coveralls",
"example": "node example", "example": "node example",
"lint": "eslint .", "lint": "eslint .",
"test": "mocha --R intelli-espower-loader test/", "test": "mocha --require intelli-espower-loader test/",
"travis": "npm run lint && npm run coverage" "travis": "npm run lint && npm run test"
}, },
"version": "1.0.0" "version": "1.0.1"
} }

View File

@@ -93,7 +93,7 @@ console.time('deflate');
for(let i = 0; i < 30000; ++i) { for(let i = 0; i < 30000; ++i) {
deflate(payload, function (err, buffer) {}); deflate(payload, function (err, buffer) {});
} }
q.onDone(function() { t.onDone(function() {
console.timeEnd('deflate'); console.timeEnd('deflate');
}); });
``` ```
@@ -110,23 +110,23 @@ q.onDone(function() {
### `var t = new Limiter([opts])` ### `var t = new Limiter([opts])`
Constructor. `opts` may contain inital values for: Constructor. `opts` may contain inital values for:
* `q.concurrency` * `t.concurrency`
## Instance methods ## Instance methods
### `q.onDone(fn)` ### `t.onDone(fn)`
`fn` will be called once and only once, when the queue is empty. `fn` will be called once and only once, when the queue is empty.
## Instance methods mixed in from `Array` ## Instance methods mixed in from `Array`
Mozilla has docs on how these methods work [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array). Mozilla has docs on how these methods work [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).
### `q.push(element1, ..., elementN)` ### `t.push(element1, ..., elementN)`
### `q.unshift(element1, ..., elementN)` ### `t.unshift(element1, ..., elementN)`
### `q.splice(index , howMany[, element1[, ...[, elementN]]])` ### `t.splice(index , howMany[, element1[, ...[, elementN]]])`
## Properties ## Properties
### `q.concurrency` ### `t.concurrency`
Max number of jobs the queue should process concurrently, defaults to `Infinity`. Max number of jobs the queue should process concurrently, defaults to `Infinity`.
### `q.length` ### `t.length`
Jobs pending + jobs to process (readonly). Jobs pending + jobs to process (readonly).

158
node/node_modules/ws/README.md generated vendored
View File

@@ -1,12 +1,12 @@
# ws: a Node.js WebSocket library # ws: a Node.js WebSocket library
[![Version npm](https://img.shields.io/npm/v/ws.svg)](https://www.npmjs.com/package/ws) [![Version npm](https://img.shields.io/npm/v/ws.svg?logo=npm)](https://www.npmjs.com/package/ws)
[![Linux Build](https://img.shields.io/travis/websockets/ws/master.svg)](https://travis-ci.org/websockets/ws) [![Linux Build](https://img.shields.io/travis/websockets/ws/master.svg?logo=travis)](https://travis-ci.org/websockets/ws)
[![Windows Build](https://ci.appveyor.com/api/projects/status/github/websockets/ws?branch=master&svg=true)](https://ci.appveyor.com/project/lpinca/ws) [![Windows Build](https://img.shields.io/appveyor/ci/lpinca/ws/master.svg?logo=appveyor)](https://ci.appveyor.com/project/lpinca/ws)
[![Coverage Status](https://img.shields.io/coveralls/websockets/ws/master.svg)](https://coveralls.io/r/websockets/ws?branch=master) [![Coverage Status](https://img.shields.io/coveralls/websockets/ws/master.svg)](https://coveralls.io/github/websockets/ws)
ws is a simple to use, blazing fast, and thoroughly tested WebSocket client ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and
and server implementation. server implementation.
Passes the quite extensive Autobahn test suite: [server][server-report], Passes the quite extensive Autobahn test suite: [server][server-report],
[client][client-report]. [client][client-report].
@@ -14,44 +14,45 @@ Passes the quite extensive Autobahn test suite: [server][server-report],
**Note**: This module does not work in the browser. The client in the docs is a **Note**: This module does not work in the browser. The client in the docs is a
reference to a back end with the role of a client in the WebSocket reference to a back end with the role of a client in the WebSocket
communication. Browser clients must use the native communication. Browser clients must use the native
[`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object. [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
To make the same code work seamlessly on Node.js and the browser, you can use object. To make the same code work seamlessly on Node.js and the browser, you
one of the many wrappers available on npm, like can use one of the many wrappers available on npm, like
[isomorphic-ws](https://github.com/heineiuo/isomorphic-ws). [isomorphic-ws](https://github.com/heineiuo/isomorphic-ws).
## Table of Contents ## Table of Contents
* [Protocol support](#protocol-support) - [Protocol support](#protocol-support)
* [Installing](#installing) - [Installing](#installing)
+ [Opt-in for performance and spec compliance](#opt-in-for-performance-and-spec-compliance) - [Opt-in for performance and spec compliance](#opt-in-for-performance-and-spec-compliance)
* [API docs](#api-docs) - [API docs](#api-docs)
* [WebSocket compression](#websocket-compression) - [WebSocket compression](#websocket-compression)
* [Usage examples](#usage-examples) - [Usage examples](#usage-examples)
+ [Sending and receiving text data](#sending-and-receiving-text-data) - [Sending and receiving text data](#sending-and-receiving-text-data)
+ [Sending binary data](#sending-binary-data) - [Sending binary data](#sending-binary-data)
+ [Simple server](#simple-server) - [Simple server](#simple-server)
+ [External HTTP/S server](#external-https-server) - [External HTTP/S server](#external-https-server)
+ [Multiple servers sharing a single HTTP/S server](#multiple-servers-sharing-a-single-https-server) - [Multiple servers sharing a single HTTP/S server](#multiple-servers-sharing-a-single-https-server)
+ [Server broadcast](#server-broadcast) - [Server broadcast](#server-broadcast)
+ [echo.websocket.org demo](#echowebsocketorg-demo) - [echo.websocket.org demo](#echowebsocketorg-demo)
+ [Other examples](#other-examples) - [Other examples](#other-examples)
* [Error handling best practices](#error-handling-best-practices) - [Error handling best practices](#error-handling-best-practices)
* [FAQ](#faq) - [FAQ](#faq)
+ [How to get the IP address of the client?](#how-to-get-the-ip-address-of-the-client) - [How to get the IP address of the client?](#how-to-get-the-ip-address-of-the-client)
+ [How to detect and close broken connections?](#how-to-detect-and-close-broken-connections) - [How to detect and close broken connections?](#how-to-detect-and-close-broken-connections)
+ [How to connect via a proxy?](#how-to-connect-via-a-proxy) - [How to connect via a proxy?](#how-to-connect-via-a-proxy)
* [Changelog](#changelog) - [Changelog](#changelog)
* [License](#license) - [License](#license)
## Protocol support ## Protocol support
* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`) - **HyBi drafts 07-12** (Use the option `protocolVersion: 8`)
* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`) - **HyBi drafts 13-17** (Current default, alternatively option
`protocolVersion: 13`)
## Installing ## Installing
``` ```
npm install --save ws npm install ws
``` ```
### Opt-in for performance and spec compliance ### Opt-in for performance and spec compliance
@@ -64,8 +65,8 @@ necessarily need to have a C++ compiler installed on your machine.
- `npm install --save-optional bufferutil`: Allows to efficiently perform - `npm install --save-optional bufferutil`: Allows to efficiently perform
operations such as masking and unmasking the data payload of the WebSocket operations such as masking and unmasking the data payload of the WebSocket
frames. frames.
- `npm install --save-optional utf-8-validate`: Allows to efficiently check - `npm install --save-optional utf-8-validate`: Allows to efficiently check if a
if a message contains valid UTF-8 as required by the spec. message contains valid UTF-8 as required by the spec.
## API docs ## API docs
@@ -73,21 +74,20 @@ See [`/doc/ws.md`](./doc/ws.md) for Node.js-like docs for the ws classes.
## WebSocket compression ## WebSocket compression
ws supports the [permessage-deflate extension][permessage-deflate] which ws supports the [permessage-deflate extension][permessage-deflate] which enables
enables the client and server to negotiate a compression algorithm and its the client and server to negotiate a compression algorithm and its parameters,
parameters, and then selectively apply it to the data payloads of each and then selectively apply it to the data payloads of each WebSocket message.
WebSocket message.
The extension is disabled by default on the server and enabled by default on The extension is disabled by default on the server and enabled by default on the
the client. It adds a significant overhead in terms of performance and memory client. It adds a significant overhead in terms of performance and memory
consumption so we suggest to enable it only if it is really needed. consumption so we suggest to enable it only if it is really needed.
Note that Node.js has a variety of issues with high-performance compression, Note that Node.js has a variety of issues with high-performance compression,
where increased concurrency, especially on Linux, can lead to where increased concurrency, especially on Linux, can lead to [catastrophic
[catastrophic memory fragmentation][node-zlib-bug] and slow performance. memory fragmentation][node-zlib-bug] and slow performance. If you intend to use
If you intend to use permessage-deflate in production, it is worthwhile to set permessage-deflate in production, it is worthwhile to set up a test
up a test representative of your workload and ensure Node.js/zlib will handle representative of your workload and ensure Node.js/zlib will handle it with
it with acceptable performance and memory usage. acceptable performance and memory usage.
Tuning of permessage-deflate can be done via the options defined below. You can Tuning of permessage-deflate can be done via the options defined below. You can
also use `zlibDeflateOptions` and `zlibInflateOptions`, which is passed directly also use `zlibDeflateOptions` and `zlibInflateOptions`, which is passed directly
@@ -101,10 +101,11 @@ const WebSocket = require('ws');
const wss = new WebSocket.Server({ const wss = new WebSocket.Server({
port: 8080, port: 8080,
perMessageDeflate: { perMessageDeflate: {
zlibDeflateOptions: { // See zlib defaults. zlibDeflateOptions: {
// See zlib defaults.
chunkSize: 1024, chunkSize: 1024,
memLevel: 7, memLevel: 7,
level: 3, level: 3
}, },
zlibInflateOptions: { zlibInflateOptions: {
chunkSize: 10 * 1024 chunkSize: 10 * 1024
@@ -112,12 +113,11 @@ const wss = new WebSocket.Server({
// Other options settable: // Other options settable:
clientNoContextTakeover: true, // Defaults to negotiated value. clientNoContextTakeover: true, // Defaults to negotiated value.
serverNoContextTakeover: true, // Defaults to negotiated value. serverNoContextTakeover: true, // Defaults to negotiated value.
clientMaxWindowBits: 10, // Defaults to negotiated value. serverMaxWindowBits: 10, // Defaults to negotiated value.
serverMaxWindowBits: 10, // Defaults to negotiated value.
// Below options specified as default values. // Below options specified as default values.
concurrencyLimit: 10, // Limits zlib concurrency for perf. concurrencyLimit: 10, // Limits zlib concurrency for perf.
threshold: 1024, // Size (in bytes) below which messages threshold: 1024 // Size (in bytes) below which messages
// should not be compressed. // should not be compressed.
} }
}); });
``` ```
@@ -326,8 +326,11 @@ ws.send('something', function ack(error) {
// Immediate errors can also be handled with `try...catch`, but **note** that // Immediate errors can also be handled with `try...catch`, but **note** that
// since sends are inherently asynchronous, socket write failures will *not* be // since sends are inherently asynchronous, socket write failures will *not* be
// captured when this technique is used. // captured when this technique is used.
try { ws.send('something'); } try {
catch (e) { /* handle error */ } ws.send('something');
} catch (e) {
/* handle error */
}
``` ```
## FAQ ## FAQ
@@ -357,8 +360,8 @@ wss.on('connection', function connection(ws, req) {
### How to detect and close broken connections? ### How to detect and close broken connections?
Sometimes the link between the server and the client can be interrupted in a Sometimes the link between the server and the client can be interrupted in a way
way that keeps both the server and the client unaware of the broken state of the that keeps both the server and the client unaware of the broken state of the
connection (e.g. when pulling the cord). connection (e.g. when pulling the cord).
In these cases ping messages can be used as a means to verify that the remote In these cases ping messages can be used as a means to verify that the remote
@@ -367,14 +370,14 @@ endpoint is still responsive.
```js ```js
const WebSocket = require('ws'); const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
function noop() {} function noop() {}
function heartbeat() { function heartbeat() {
this.isAlive = true; this.isAlive = true;
} }
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) { wss.on('connection', function connection(ws) {
ws.isAlive = true; ws.isAlive = true;
ws.on('pong', heartbeat); ws.on('pong', heartbeat);
@@ -390,8 +393,35 @@ const interval = setInterval(function ping() {
}, 30000); }, 30000);
``` ```
Pong messages are automatically sent in response to ping messages as required Pong messages are automatically sent in response to ping messages as required by
by the spec. the spec.
Just like the server example above your clients might as well lose connection
without knowing it. You might want to add a ping listener on your clients to
prevent that. A simple implementation would be:
```js
const WebSocket = require('ws');
function heartbeat() {
clearTimeout(this.pingTimeout);
// Use `WebSocket#terminate()` and not `WebSocket#close()`. Delay should be
// equal to the interval at which your server sends out pings plus a
// conservative assumption of the latency.
this.pingTimeout = setTimeout(() => {
this.terminate();
}, 30000 + 1000);
}
const client = new WebSocket('wss://echo.websocket.org/');
client.on('open', heartbeat);
client.on('ping', heartbeat);
client.on('close', function clear() {
clearTimeout(this.pingTimeout);
});
```
### How to connect via a proxy? ### How to connect via a proxy?
@@ -413,5 +443,7 @@ We're using the GitHub [releases][changelog] for changelog entries.
[permessage-deflate]: https://tools.ietf.org/html/rfc7692 [permessage-deflate]: https://tools.ietf.org/html/rfc7692
[changelog]: https://github.com/websockets/ws/releases [changelog]: https://github.com/websockets/ws/releases
[node-zlib-bug]: https://github.com/nodejs/node/issues/8871 [node-zlib-bug]: https://github.com/nodejs/node/issues/8871
[node-zlib-deflaterawdocs]: https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options [node-zlib-deflaterawdocs]:
[ws-server-options]: https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options
[ws-server-options]:
https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback

2
node/node_modules/ws/browser.js generated vendored
View File

@@ -1,6 +1,6 @@
'use strict'; 'use strict';
module.exports = function () { module.exports = function() {
throw new Error( throw new Error(
'ws does not work in the browser. Browser clients must use the native ' + 'ws does not work in the browser. Browser clients must use the native ' +
'WebSocket object' 'WebSocket object'

View File

@@ -1,5 +1,7 @@
'use strict'; 'use strict';
const { EMPTY_BUFFER } = require('./constants');
/** /**
* Merges an array of buffers into a new buffer. * Merges an array of buffers into a new buffer.
* *
@@ -8,7 +10,10 @@
* @return {Buffer} The resulting buffer * @return {Buffer} The resulting buffer
* @public * @public
*/ */
function concat (list, totalLength) { function concat(list, totalLength) {
if (list.length === 0) return EMPTY_BUFFER;
if (list.length === 1) return list[0];
const target = Buffer.allocUnsafe(totalLength); const target = Buffer.allocUnsafe(totalLength);
var offset = 0; var offset = 0;
@@ -31,7 +36,7 @@ function concat (list, totalLength) {
* @param {Number} length The number of bytes to mask. * @param {Number} length The number of bytes to mask.
* @public * @public
*/ */
function _mask (source, mask, output, offset, length) { function _mask(source, mask, output, offset, length) {
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
output[offset + i] = source[i] ^ mask[i & 3]; output[offset + i] = source[i] ^ mask[i & 3];
} }
@@ -44,7 +49,7 @@ function _mask (source, mask, output, offset, length) {
* @param {Buffer} mask The mask to use * @param {Buffer} mask The mask to use
* @public * @public
*/ */
function _unmask (buffer, mask) { function _unmask(buffer, mask) {
// Required until https://github.com/nodejs/node/issues/9006 is resolved. // Required until https://github.com/nodejs/node/issues/9006 is resolved.
const length = buffer.length; const length = buffer.length;
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
@@ -52,21 +57,88 @@ function _unmask (buffer, mask) {
} }
} }
/**
* Converts a buffer to an `ArrayBuffer`.
*
* @param {Buffer} buf The buffer to convert
* @return {ArrayBuffer} Converted buffer
* @public
*/
function toArrayBuffer(buf) {
if (buf.byteLength === buf.buffer.byteLength) {
return buf.buffer;
}
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
}
/**
* Converts `data` to a `Buffer`.
*
* @param {*} data The data to convert
* @return {Buffer} The buffer
* @throws {TypeError}
* @public
*/
function toBuffer(data) {
toBuffer.readOnly = true;
if (Buffer.isBuffer(data)) return data;
var buf;
if (data instanceof ArrayBuffer) {
buf = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
buf = viewToBuffer(data);
} else {
buf = Buffer.from(data);
toBuffer.readOnly = false;
}
return buf;
}
/**
* Converts an `ArrayBuffer` view into a buffer.
*
* @param {(DataView|TypedArray)} view The view to convert
* @return {Buffer} Converted view
* @private
*/
function viewToBuffer(view) {
const buf = Buffer.from(view.buffer);
if (view.byteLength !== view.buffer.byteLength) {
return buf.slice(view.byteOffset, view.byteOffset + view.byteLength);
}
return buf;
}
try { try {
const bufferUtil = require('bufferutil'); const bufferUtil = require('bufferutil');
const bu = bufferUtil.BufferUtil || bufferUtil; const bu = bufferUtil.BufferUtil || bufferUtil;
module.exports = { module.exports = {
mask (source, mask, output, offset, length) { concat,
mask(source, mask, output, offset, length) {
if (length < 48) _mask(source, mask, output, offset, length); if (length < 48) _mask(source, mask, output, offset, length);
else bu.mask(source, mask, output, offset, length); else bu.mask(source, mask, output, offset, length);
}, },
unmask (buffer, mask) { toArrayBuffer,
toBuffer,
unmask(buffer, mask) {
if (buffer.length < 32) _unmask(buffer, mask); if (buffer.length < 32) _unmask(buffer, mask);
else bu.unmask(buffer, mask); else bu.unmask(buffer, mask);
}, }
concat
}; };
} catch (e) /* istanbul ignore next */ { } catch (e) /* istanbul ignore next */ {
module.exports = { concat, mask: _mask, unmask: _unmask }; module.exports = {
concat,
mask: _mask,
toArrayBuffer,
toBuffer,
unmask: _unmask
};
} }

View File

@@ -12,7 +12,7 @@ class Event {
* @param {String} type The name of the event * @param {String} type The name of the event
* @param {Object} target A reference to the target to which the event was dispatched * @param {Object} target A reference to the target to which the event was dispatched
*/ */
constructor (type, target) { constructor(type, target) {
this.target = target; this.target = target;
this.type = type; this.type = type;
} }
@@ -31,7 +31,7 @@ class MessageEvent extends Event {
* @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data
* @param {WebSocket} target A reference to the target to which the event was dispatched * @param {WebSocket} target A reference to the target to which the event was dispatched
*/ */
constructor (data, target) { constructor(data, target) {
super('message', target); super('message', target);
this.data = data; this.data = data;
@@ -52,7 +52,7 @@ class CloseEvent extends Event {
* @param {String} reason A human-readable string explaining why the connection is closing * @param {String} reason A human-readable string explaining why the connection is closing
* @param {WebSocket} target A reference to the target to which the event was dispatched * @param {WebSocket} target A reference to the target to which the event was dispatched
*/ */
constructor (code, reason, target) { constructor(code, reason, target) {
super('close', target); super('close', target);
this.wasClean = target._closeFrameReceived && target._closeFrameSent; this.wasClean = target._closeFrameReceived && target._closeFrameSent;
@@ -73,7 +73,7 @@ class OpenEvent extends Event {
* *
* @param {WebSocket} target A reference to the target to which the event was dispatched * @param {WebSocket} target A reference to the target to which the event was dispatched
*/ */
constructor (target) { constructor(target) {
super('open', target); super('open', target);
} }
} }
@@ -91,7 +91,7 @@ class ErrorEvent extends Event {
* @param {Object} error The error that generated this event * @param {Object} error The error that generated this event
* @param {WebSocket} target A reference to the target to which the event was dispatched * @param {WebSocket} target A reference to the target to which the event was dispatched
*/ */
constructor (error, target) { constructor(error, target) {
super('error', target); super('error', target);
this.message = error.message; this.message = error.message;
@@ -113,22 +113,22 @@ const EventTarget = {
* @param {Function} listener The listener to add * @param {Function} listener The listener to add
* @public * @public
*/ */
addEventListener (method, listener) { addEventListener(method, listener) {
if (typeof listener !== 'function') return; if (typeof listener !== 'function') return;
function onMessage (data) { function onMessage(data) {
listener.call(this, new MessageEvent(data, this)); listener.call(this, new MessageEvent(data, this));
} }
function onClose (code, message) { function onClose(code, message) {
listener.call(this, new CloseEvent(code, message, this)); listener.call(this, new CloseEvent(code, message, this));
} }
function onError (error) { function onError(error) {
listener.call(this, new ErrorEvent(error, this)); listener.call(this, new ErrorEvent(error, this));
} }
function onOpen () { function onOpen() {
listener.call(this, new OpenEvent(this)); listener.call(this, new OpenEvent(this));
} }
@@ -156,7 +156,7 @@ const EventTarget = {
* @param {Function} listener The listener to remove * @param {Function} listener The listener to remove
* @public * @public
*/ */
removeEventListener (method, listener) { removeEventListener(method, listener) {
const listeners = this.listeners(method); const listeners = this.listeners(method);
for (var i = 0; i < listeners.length; i++) { for (var i = 0; i < listeners.length; i++) {

View File

@@ -11,6 +11,7 @@
// tokenChars[34] === 0 // '"' // tokenChars[34] === 0 // '"'
// ... // ...
// //
// prettier-ignore
const tokenChars = [ const tokenChars = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
@@ -32,7 +33,7 @@ const tokenChars = [
* parameter value * parameter value
* @private * @private
*/ */
function push (dest, name, elem) { function push(dest, name, elem) {
if (Object.prototype.hasOwnProperty.call(dest, name)) dest[name].push(elem); if (Object.prototype.hasOwnProperty.call(dest, name)) dest[name].push(elem);
else dest[name] = [elem]; else dest[name] = [elem];
} }
@@ -44,7 +45,7 @@ function push (dest, name, elem) {
* @return {Object} The parsed object * @return {Object} The parsed object
* @public * @public
*/ */
function parse (header) { function parse(header) {
const offers = {}; const offers = {};
if (header === undefined || header === '') return offers; if (header === undefined || header === '') return offers;
@@ -64,9 +65,9 @@ function parse (header) {
if (extensionName === undefined) { if (extensionName === undefined) {
if (end === -1 && tokenChars[code] === 1) { if (end === -1 && tokenChars[code] === 1) {
if (start === -1) start = i; if (start === -1) start = i;
} else if (code === 0x20/* ' ' */|| code === 0x09/* '\t' */) { } else if (code === 0x20 /* ' ' */ || code === 0x09 /* '\t' */) {
if (end === -1 && start !== -1) end = i; if (end === -1 && start !== -1) end = i;
} else if (code === 0x3b/* ';' */ || code === 0x2c/* ',' */) { } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {
if (start === -1) { if (start === -1) {
throw new SyntaxError(`Unexpected character at index ${i}`); throw new SyntaxError(`Unexpected character at index ${i}`);
} }
@@ -103,7 +104,7 @@ function parse (header) {
} }
start = end = -1; start = end = -1;
} else if (code === 0x3d/* '=' */&& start !== -1 && end === -1) { } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {
paramName = header.slice(start, i); paramName = header.slice(start, i);
start = end = -1; start = end = -1;
} else { } else {
@@ -125,10 +126,10 @@ function parse (header) {
} else if (inQuotes) { } else if (inQuotes) {
if (tokenChars[code] === 1) { if (tokenChars[code] === 1) {
if (start === -1) start = i; if (start === -1) start = i;
} else if (code === 0x22/* '"' */ && start !== -1) { } else if (code === 0x22 /* '"' */ && start !== -1) {
inQuotes = false; inQuotes = false;
end = i; end = i;
} else if (code === 0x5c/* '\' */) { } else if (code === 0x5c /* '\' */) {
isEscaping = true; isEscaping = true;
} else { } else {
throw new SyntaxError(`Unexpected character at index ${i}`); throw new SyntaxError(`Unexpected character at index ${i}`);
@@ -194,18 +195,28 @@ function parse (header) {
* @return {String} A string representing the given object * @return {String} A string representing the given object
* @public * @public
*/ */
function format (extensions) { function format(extensions) {
return Object.keys(extensions).map((extension) => { return Object.keys(extensions)
var configurations = extensions[extension]; .map((extension) => {
if (!Array.isArray(configurations)) configurations = [configurations]; var configurations = extensions[extension];
return configurations.map((params) => { if (!Array.isArray(configurations)) configurations = [configurations];
return [extension].concat(Object.keys(params).map((k) => { return configurations
var values = params[k]; .map((params) => {
if (!Array.isArray(values)) values = [values]; return [extension]
return values.map((v) => v === true ? k : `${k}=${v}`).join('; '); .concat(
})).join('; '); Object.keys(params).map((k) => {
}).join(', '); var values = params[k];
}).join(', '); if (!Array.isArray(values)) values = [values];
return values
.map((v) => (v === true ? k : `${k}=${v}`))
.join('; ');
})
)
.join('; ');
})
.join(', ');
})
.join(', ');
} }
module.exports = { format, parse }; module.exports = { format, parse };

View File

@@ -4,14 +4,12 @@ const Limiter = require('async-limiter');
const zlib = require('zlib'); const zlib = require('zlib');
const bufferUtil = require('./buffer-util'); const bufferUtil = require('./buffer-util');
const constants = require('./constants'); const { kStatusCode, NOOP } = require('./constants');
const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]); const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
const EMPTY_BLOCK = Buffer.from([0x00]); const EMPTY_BLOCK = Buffer.from([0x00]);
const kPerMessageDeflate = Symbol('permessage-deflate'); const kPerMessageDeflate = Symbol('permessage-deflate');
const kWriteInProgress = Symbol('write-in-progress');
const kPendingClose = Symbol('pending-close');
const kTotalLength = Symbol('total-length'); const kTotalLength = Symbol('total-length');
const kCallback = Symbol('callback'); const kCallback = Symbol('callback');
const kBuffers = Symbol('buffers'); const kBuffers = Symbol('buffers');
@@ -52,12 +50,11 @@ class PerMessageDeflate {
* mode * mode
* @param {Number} maxPayload The maximum allowed message length * @param {Number} maxPayload The maximum allowed message length
*/ */
constructor (options, isServer, maxPayload) { constructor(options, isServer, maxPayload) {
this._maxPayload = maxPayload | 0; this._maxPayload = maxPayload | 0;
this._options = options || {}; this._options = options || {};
this._threshold = this._options.threshold !== undefined this._threshold =
? this._options.threshold this._options.threshold !== undefined ? this._options.threshold : 1024;
: 1024;
this._isServer = !!isServer; this._isServer = !!isServer;
this._deflate = null; this._deflate = null;
this._inflate = null; this._inflate = null;
@@ -65,9 +62,10 @@ class PerMessageDeflate {
this.params = null; this.params = null;
if (!zlibLimiter) { if (!zlibLimiter) {
const concurrency = this._options.concurrencyLimit !== undefined const concurrency =
? this._options.concurrencyLimit this._options.concurrencyLimit !== undefined
: 10; ? this._options.concurrencyLimit
: 10;
zlibLimiter = new Limiter({ concurrency }); zlibLimiter = new Limiter({ concurrency });
} }
} }
@@ -75,7 +73,7 @@ class PerMessageDeflate {
/** /**
* @type {String} * @type {String}
*/ */
static get extensionName () { static get extensionName() {
return 'permessage-deflate'; return 'permessage-deflate';
} }
@@ -85,7 +83,7 @@ class PerMessageDeflate {
* @return {Object} Extension parameters * @return {Object} Extension parameters
* @public * @public
*/ */
offer () { offer() {
const params = {}; const params = {};
if (this._options.serverNoContextTakeover) { if (this._options.serverNoContextTakeover) {
@@ -113,7 +111,7 @@ class PerMessageDeflate {
* @return {Object} Accepted configuration * @return {Object} Accepted configuration
* @public * @public
*/ */
accept (configurations) { accept(configurations) {
configurations = this.normalizeParams(configurations); configurations = this.normalizeParams(configurations);
this.params = this._isServer this.params = this._isServer
@@ -128,22 +126,15 @@ class PerMessageDeflate {
* *
* @public * @public
*/ */
cleanup () { cleanup() {
if (this._inflate) { if (this._inflate) {
if (this._inflate[kWriteInProgress]) { this._inflate.close();
this._inflate[kPendingClose] = true; this._inflate = null;
} else {
this._inflate.close();
this._inflate = null;
}
} }
if (this._deflate) { if (this._deflate) {
if (this._deflate[kWriteInProgress]) { this._deflate.close();
this._deflate[kPendingClose] = true; this._deflate = null;
} else {
this._deflate.close();
this._deflate = null;
}
} }
} }
@@ -154,7 +145,7 @@ class PerMessageDeflate {
* @return {Object} Accepted configuration * @return {Object} Accepted configuration
* @private * @private
*/ */
acceptAsServer (offers) { acceptAsServer(offers) {
const opts = this._options; const opts = this._options;
const accepted = offers.find((params) => { const accepted = offers.find((params) => {
if ( if (
@@ -205,7 +196,7 @@ class PerMessageDeflate {
* @return {Object} Accepted configuration * @return {Object} Accepted configuration
* @private * @private
*/ */
acceptAsClient (response) { acceptAsClient(response) {
const params = response[0]; const params = response[0];
if ( if (
@@ -239,7 +230,7 @@ class PerMessageDeflate {
* @return {Array} The offers/response with normalized parameters * @return {Array} The offers/response with normalized parameters
* @private * @private
*/ */
normalizeParams (configurations) { normalizeParams(configurations) {
configurations.forEach((params) => { configurations.forEach((params) => {
Object.keys(params).forEach((key) => { Object.keys(params).forEach((key) => {
var value = params[key]; var value = params[key];
@@ -300,7 +291,7 @@ class PerMessageDeflate {
* @param {Function} callback Callback * @param {Function} callback Callback
* @public * @public
*/ */
decompress (data, fin, callback) { decompress(data, fin, callback) {
zlibLimiter.push((done) => { zlibLimiter.push((done) => {
this._decompress(data, fin, (err, result) => { this._decompress(data, fin, (err, result) => {
done(); done();
@@ -317,7 +308,7 @@ class PerMessageDeflate {
* @param {Function} callback Callback * @param {Function} callback Callback
* @public * @public
*/ */
compress (data, fin, callback) { compress(data, fin, callback) {
zlibLimiter.push((done) => { zlibLimiter.push((done) => {
this._compress(data, fin, (err, result) => { this._compress(data, fin, (err, result) => {
done(); done();
@@ -334,14 +325,15 @@ class PerMessageDeflate {
* @param {Function} callback Callback * @param {Function} callback Callback
* @private * @private
*/ */
_decompress (data, fin, callback) { _decompress(data, fin, callback) {
const endpoint = this._isServer ? 'client' : 'server'; const endpoint = this._isServer ? 'client' : 'server';
if (!this._inflate) { if (!this._inflate) {
const key = `${endpoint}_max_window_bits`; const key = `${endpoint}_max_window_bits`;
const windowBits = typeof this.params[key] !== 'number' const windowBits =
? zlib.Z_DEFAULT_WINDOWBITS typeof this.params[key] !== 'number'
: this.params[key]; ? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
this._inflate = zlib.createInflateRaw( this._inflate = zlib.createInflateRaw(
Object.assign({}, this._options.zlibInflateOptions, { windowBits }) Object.assign({}, this._options.zlibInflateOptions, { windowBits })
@@ -354,7 +346,6 @@ class PerMessageDeflate {
} }
this._inflate[kCallback] = callback; this._inflate[kCallback] = callback;
this._inflate[kWriteInProgress] = true;
this._inflate.write(data); this._inflate.write(data);
if (fin) this._inflate.write(TRAILER); if (fin) this._inflate.write(TRAILER);
@@ -374,14 +365,10 @@ class PerMessageDeflate {
this._inflate[kTotalLength] this._inflate[kTotalLength]
); );
if ( if (fin && this.params[`${endpoint}_no_context_takeover`]) {
(fin && this.params[`${endpoint}_no_context_takeover`]) ||
this._inflate[kPendingClose]
) {
this._inflate.close(); this._inflate.close();
this._inflate = null; this._inflate = null;
} else { } else {
this._inflate[kWriteInProgress] = false;
this._inflate[kTotalLength] = 0; this._inflate[kTotalLength] = 0;
this._inflate[kBuffers] = []; this._inflate[kBuffers] = [];
} }
@@ -398,7 +385,7 @@ class PerMessageDeflate {
* @param {Function} callback Callback * @param {Function} callback Callback
* @private * @private
*/ */
_compress (data, fin, callback) { _compress(data, fin, callback) {
if (!data || data.length === 0) { if (!data || data.length === 0) {
process.nextTick(callback, null, EMPTY_BLOCK); process.nextTick(callback, null, EMPTY_BLOCK);
return; return;
@@ -408,9 +395,10 @@ class PerMessageDeflate {
if (!this._deflate) { if (!this._deflate) {
const key = `${endpoint}_max_window_bits`; const key = `${endpoint}_max_window_bits`;
const windowBits = typeof this.params[key] !== 'number' const windowBits =
? zlib.Z_DEFAULT_WINDOWBITS typeof this.params[key] !== 'number'
: this.params[key]; ? zlib.Z_DEFAULT_WINDOWBITS
: this.params[key];
this._deflate = zlib.createDeflateRaw( this._deflate = zlib.createDeflateRaw(
Object.assign({}, this._options.zlibDeflateOptions, { windowBits }) Object.assign({}, this._options.zlibDeflateOptions, { windowBits })
@@ -420,17 +408,27 @@ class PerMessageDeflate {
this._deflate[kBuffers] = []; this._deflate[kBuffers] = [];
// //
// `zlib.DeflateRaw` emits an `'error'` event only when an attempt to use // An `'error'` event is emitted, only on Node.js < 10.0.0, if the
// it is made after it has already been closed. This cannot happen here, // `zlib.DeflateRaw` instance is closed while data is being processed.
// so we only add a listener for the `'data'` event. // This can happen if `PerMessageDeflate#cleanup()` is called at the wrong
// time due to an abnormal WebSocket closure.
// //
this._deflate.on('error', NOOP);
this._deflate.on('data', deflateOnData); this._deflate.on('data', deflateOnData);
} }
this._deflate[kWriteInProgress] = true;
this._deflate.write(data); this._deflate.write(data);
this._deflate.flush(zlib.Z_SYNC_FLUSH, () => { this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
if (!this._deflate) {
//
// This `if` statement is only needed for Node.js < 10.0.0 because as of
// commit https://github.com/nodejs/node/commit/5e3f5164, the flush
// callback is no longer called if the deflate stream is closed while
// data is being processed.
//
return;
}
var data = bufferUtil.concat( var data = bufferUtil.concat(
this._deflate[kBuffers], this._deflate[kBuffers],
this._deflate[kTotalLength] this._deflate[kTotalLength]
@@ -438,14 +436,10 @@ class PerMessageDeflate {
if (fin) data = data.slice(0, data.length - 4); if (fin) data = data.slice(0, data.length - 4);
if ( if (fin && this.params[`${endpoint}_no_context_takeover`]) {
(fin && this.params[`${endpoint}_no_context_takeover`]) ||
this._deflate[kPendingClose]
) {
this._deflate.close(); this._deflate.close();
this._deflate = null; this._deflate = null;
} else { } else {
this._deflate[kWriteInProgress] = false;
this._deflate[kTotalLength] = 0; this._deflate[kTotalLength] = 0;
this._deflate[kBuffers] = []; this._deflate[kBuffers] = [];
} }
@@ -463,7 +457,7 @@ module.exports = PerMessageDeflate;
* @param {Buffer} chunk A chunk of data * @param {Buffer} chunk A chunk of data
* @private * @private
*/ */
function deflateOnData (chunk) { function deflateOnData(chunk) {
this[kBuffers].push(chunk); this[kBuffers].push(chunk);
this[kTotalLength] += chunk.length; this[kTotalLength] += chunk.length;
} }
@@ -474,7 +468,7 @@ function deflateOnData (chunk) {
* @param {Buffer} chunk A chunk of data * @param {Buffer} chunk A chunk of data
* @private * @private
*/ */
function inflateOnData (chunk) { function inflateOnData(chunk) {
this[kTotalLength] += chunk.length; this[kTotalLength] += chunk.length;
if ( if (
@@ -486,7 +480,7 @@ function inflateOnData (chunk) {
} }
this[kError] = new RangeError('Max payload size exceeded'); this[kError] = new RangeError('Max payload size exceeded');
this[kError][constants.kStatusCode] = 1009; this[kError][kStatusCode] = 1009;
this.removeListener('data', inflateOnData); this.removeListener('data', inflateOnData);
this.reset(); this.reset();
} }
@@ -497,12 +491,12 @@ function inflateOnData (chunk) {
* @param {Error} err The emitted error * @param {Error} err The emitted error
* @private * @private
*/ */
function inflateOnError (err) { function inflateOnError(err) {
// //
// There is no need to call `Zlib#close()` as the handle is automatically // There is no need to call `Zlib#close()` as the handle is automatically
// closed when an error is emitted. // closed when an error is emitted.
// //
this[kPerMessageDeflate]._inflate = null; this[kPerMessageDeflate]._inflate = null;
err[constants.kStatusCode] = 1007; err[kStatusCode] = 1007;
this[kCallback](err); this[kCallback](err);
} }

111
node/node_modules/ws/lib/receiver.js generated vendored
View File

@@ -1,11 +1,16 @@
'use strict'; 'use strict';
const stream = require('stream'); const { Writable } = require('stream');
const PerMessageDeflate = require('./permessage-deflate'); const PerMessageDeflate = require('./permessage-deflate');
const bufferUtil = require('./buffer-util'); const {
const validation = require('./validation'); BINARY_TYPES,
const constants = require('./constants'); EMPTY_BUFFER,
kStatusCode,
kWebSocket
} = require('./constants');
const { concat, toArrayBuffer, unmask } = require('./buffer-util');
const { isValidStatusCode, isValidUTF8 } = require('./validation');
const GET_INFO = 0; const GET_INFO = 0;
const GET_PAYLOAD_LENGTH_16 = 1; const GET_PAYLOAD_LENGTH_16 = 1;
@@ -19,7 +24,7 @@ const INFLATING = 5;
* *
* @extends stream.Writable * @extends stream.Writable
*/ */
class Receiver extends stream.Writable { class Receiver extends Writable {
/** /**
* Creates a Receiver instance. * Creates a Receiver instance.
* *
@@ -27,11 +32,11 @@ class Receiver extends stream.Writable {
* @param {Object} extensions An object containing the negotiated extensions * @param {Object} extensions An object containing the negotiated extensions
* @param {Number} maxPayload The maximum allowed message length * @param {Number} maxPayload The maximum allowed message length
*/ */
constructor (binaryType, extensions, maxPayload) { constructor(binaryType, extensions, maxPayload) {
super(); super();
this._binaryType = binaryType || constants.BINARY_TYPES[0]; this._binaryType = binaryType || BINARY_TYPES[0];
this[constants.kWebSocket] = undefined; this[kWebSocket] = undefined;
this._extensions = extensions || {}; this._extensions = extensions || {};
this._maxPayload = maxPayload | 0; this._maxPayload = maxPayload | 0;
@@ -61,8 +66,8 @@ class Receiver extends stream.Writable {
* @param {String} encoding The character encoding of `chunk` * @param {String} encoding The character encoding of `chunk`
* @param {Function} cb Callback * @param {Function} cb Callback
*/ */
_write (chunk, encoding, cb) { _write(chunk, encoding, cb) {
if (this._opcode === 0x08) return cb(); if (this._opcode === 0x08 && this._state == GET_INFO) return cb();
this._bufferedBytes += chunk.length; this._bufferedBytes += chunk.length;
this._buffers.push(chunk); this._buffers.push(chunk);
@@ -76,7 +81,7 @@ class Receiver extends stream.Writable {
* @return {Buffer} The consumed bytes * @return {Buffer} The consumed bytes
* @private * @private
*/ */
consume (n) { consume(n) {
this._bufferedBytes -= n; this._bufferedBytes -= n;
if (n === this._buffers[0].length) return this._buffers.shift(); if (n === this._buffers[0].length) return this._buffers.shift();
@@ -111,7 +116,7 @@ class Receiver extends stream.Writable {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
startLoop (cb) { startLoop(cb) {
var err; var err;
this._loop = true; this._loop = true;
@@ -132,7 +137,8 @@ class Receiver extends stream.Writable {
case GET_DATA: case GET_DATA:
err = this.getData(cb); err = this.getData(cb);
break; break;
default: // `INFLATING` default:
// `INFLATING`
this._loop = false; this._loop = false;
return; return;
} }
@@ -147,7 +153,7 @@ class Receiver extends stream.Writable {
* @return {(RangeError|undefined)} A possible error * @return {(RangeError|undefined)} A possible error
* @private * @private
*/ */
getInfo () { getInfo() {
if (this._bufferedBytes < 2) { if (this._bufferedBytes < 2) {
this._loop = false; this._loop = false;
return; return;
@@ -229,7 +235,7 @@ class Receiver extends stream.Writable {
* @return {(RangeError|undefined)} A possible error * @return {(RangeError|undefined)} A possible error
* @private * @private
*/ */
getPayloadLength16 () { getPayloadLength16() {
if (this._bufferedBytes < 2) { if (this._bufferedBytes < 2) {
this._loop = false; this._loop = false;
return; return;
@@ -245,7 +251,7 @@ class Receiver extends stream.Writable {
* @return {(RangeError|undefined)} A possible error * @return {(RangeError|undefined)} A possible error
* @private * @private
*/ */
getPayloadLength64 () { getPayloadLength64() {
if (this._bufferedBytes < 8) { if (this._bufferedBytes < 8) {
this._loop = false; this._loop = false;
return; return;
@@ -278,7 +284,7 @@ class Receiver extends stream.Writable {
* @return {(RangeError|undefined)} A possible error * @return {(RangeError|undefined)} A possible error
* @private * @private
*/ */
haveLength () { haveLength() {
if (this._payloadLength && this._opcode < 0x08) { if (this._payloadLength && this._opcode < 0x08) {
this._totalPayloadLength += this._payloadLength; this._totalPayloadLength += this._payloadLength;
if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) { if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
@@ -296,7 +302,7 @@ class Receiver extends stream.Writable {
* *
* @private * @private
*/ */
getMask () { getMask() {
if (this._bufferedBytes < 4) { if (this._bufferedBytes < 4) {
this._loop = false; this._loop = false;
return; return;
@@ -313,8 +319,8 @@ class Receiver extends stream.Writable {
* @return {(Error|RangeError|undefined)} A possible error * @return {(Error|RangeError|undefined)} A possible error
* @private * @private
*/ */
getData (cb) { getData(cb) {
var data = constants.EMPTY_BUFFER; var data = EMPTY_BUFFER;
if (this._payloadLength) { if (this._payloadLength) {
if (this._bufferedBytes < this._payloadLength) { if (this._bufferedBytes < this._payloadLength) {
@@ -323,7 +329,7 @@ class Receiver extends stream.Writable {
} }
data = this.consume(this._payloadLength); data = this.consume(this._payloadLength);
if (this._masked) bufferUtil.unmask(data, this._mask); if (this._masked) unmask(data, this._mask);
} }
if (this._opcode > 0x07) return this.controlMessage(data); if (this._opcode > 0x07) return this.controlMessage(data);
@@ -353,7 +359,7 @@ class Receiver extends stream.Writable {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
decompress (data, cb) { decompress(data, cb) {
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
perMessageDeflate.decompress(data, this._fin, (err, buf) => { perMessageDeflate.decompress(data, this._fin, (err, buf) => {
@@ -362,7 +368,9 @@ class Receiver extends stream.Writable {
if (buf.length) { if (buf.length) {
this._messageLength += buf.length; this._messageLength += buf.length;
if (this._messageLength > this._maxPayload && this._maxPayload > 0) { if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
return cb(error(RangeError, 'Max payload size exceeded', false, 1009)); return cb(
error(RangeError, 'Max payload size exceeded', false, 1009)
);
} }
this._fragments.push(buf); this._fragments.push(buf);
@@ -381,7 +389,7 @@ class Receiver extends stream.Writable {
* @return {(Error|undefined)} A possible error * @return {(Error|undefined)} A possible error
* @private * @private
*/ */
dataMessage () { dataMessage() {
if (this._fin) { if (this._fin) {
const messageLength = this._messageLength; const messageLength = this._messageLength;
const fragments = this._fragments; const fragments = this._fragments;
@@ -395,18 +403,18 @@ class Receiver extends stream.Writable {
var data; var data;
if (this._binaryType === 'nodebuffer') { if (this._binaryType === 'nodebuffer') {
data = toBuffer(fragments, messageLength); data = concat(fragments, messageLength);
} else if (this._binaryType === 'arraybuffer') { } else if (this._binaryType === 'arraybuffer') {
data = toArrayBuffer(toBuffer(fragments, messageLength)); data = toArrayBuffer(concat(fragments, messageLength));
} else { } else {
data = fragments; data = fragments;
} }
this.emit('message', data); this.emit('message', data);
} else { } else {
const buf = toBuffer(fragments, messageLength); const buf = concat(fragments, messageLength);
if (!validation.isValidUTF8(buf)) { if (!isValidUTF8(buf)) {
this._loop = false; this._loop = false;
return error(Error, 'invalid UTF-8 sequence', true, 1007); return error(Error, 'invalid UTF-8 sequence', true, 1007);
} }
@@ -425,7 +433,7 @@ class Receiver extends stream.Writable {
* @return {(Error|RangeError|undefined)} A possible error * @return {(Error|RangeError|undefined)} A possible error
* @private * @private
*/ */
controlMessage (data) { controlMessage(data) {
if (this._opcode === 0x08) { if (this._opcode === 0x08) {
this._loop = false; this._loop = false;
@@ -437,26 +445,25 @@ class Receiver extends stream.Writable {
} else { } else {
const code = data.readUInt16BE(0); const code = data.readUInt16BE(0);
if (!validation.isValidStatusCode(code)) { if (!isValidStatusCode(code)) {
return error(RangeError, `invalid status code ${code}`, true, 1002); return error(RangeError, `invalid status code ${code}`, true, 1002);
} }
const buf = data.slice(2); const buf = data.slice(2);
if (!validation.isValidUTF8(buf)) { if (!isValidUTF8(buf)) {
return error(Error, 'invalid UTF-8 sequence', true, 1007); return error(Error, 'invalid UTF-8 sequence', true, 1007);
} }
this.emit('conclude', code, buf.toString()); this.emit('conclude', code, buf.toString());
this.end(); this.end();
} }
} else if (this._opcode === 0x09) {
return; this.emit('ping', data);
} else {
this.emit('pong', data);
} }
if (this._opcode === 0x09) this.emit('ping', data);
else this.emit('pong', data);
this._state = GET_INFO; this._state = GET_INFO;
} }
} }
@@ -474,40 +481,12 @@ module.exports = Receiver;
* @return {(Error|RangeError)} The error * @return {(Error|RangeError)} The error
* @private * @private
*/ */
function error (ErrorCtor, message, prefix, statusCode) { function error(ErrorCtor, message, prefix, statusCode) {
const err = new ErrorCtor( const err = new ErrorCtor(
prefix ? `Invalid WebSocket frame: ${message}` : message prefix ? `Invalid WebSocket frame: ${message}` : message
); );
Error.captureStackTrace(err, error); Error.captureStackTrace(err, error);
err[constants.kStatusCode] = statusCode; err[kStatusCode] = statusCode;
return err; return err;
} }
/**
* Makes a buffer from a list of fragments.
*
* @param {Buffer[]} fragments The list of fragments composing the message
* @param {Number} messageLength The length of the message
* @return {Buffer}
* @private
*/
function toBuffer (fragments, messageLength) {
if (fragments.length === 1) return fragments[0];
if (fragments.length > 1) return bufferUtil.concat(fragments, messageLength);
return constants.EMPTY_BUFFER;
}
/**
* Converts a buffer to an `ArrayBuffer`.
*
* @param {Buffer} The buffer to convert
* @return {ArrayBuffer} Converted buffer
*/
function toArrayBuffer (buf) {
if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
return buf.buffer;
}
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
}

207
node/node_modules/ws/lib/sender.js generated vendored
View File

@@ -1,11 +1,11 @@
'use strict'; 'use strict';
const crypto = require('crypto'); const { randomBytes } = require('crypto');
const PerMessageDeflate = require('./permessage-deflate'); const PerMessageDeflate = require('./permessage-deflate');
const bufferUtil = require('./buffer-util'); const { EMPTY_BUFFER } = require('./constants');
const validation = require('./validation'); const { isValidStatusCode } = require('./validation');
const constants = require('./constants'); const { mask: applyMask, toBuffer } = require('./buffer-util');
/** /**
* HyBi Sender implementation. * HyBi Sender implementation.
@@ -17,7 +17,7 @@ class Sender {
* @param {net.Socket} socket The connection socket * @param {net.Socket} socket The connection socket
* @param {Object} extensions An object containing the negotiated extensions * @param {Object} extensions An object containing the negotiated extensions
*/ */
constructor (socket, extensions) { constructor(socket, extensions) {
this._extensions = extensions || {}; this._extensions = extensions || {};
this._socket = socket; this._socket = socket;
@@ -42,8 +42,8 @@ class Sender {
* @return {Buffer[]} The framed data as a list of `Buffer` instances * @return {Buffer[]} The framed data as a list of `Buffer` instances
* @public * @public
*/ */
static frame (data, options) { static frame(data, options) {
const merge = data.length < 1024 || (options.mask && options.readOnly); const merge = options.mask && options.readOnly;
var offset = options.mask ? 6 : 2; var offset = options.mask ? 6 : 2;
var payloadLength = data.length; var payloadLength = data.length;
@@ -60,6 +60,8 @@ class Sender {
target[0] = options.fin ? options.opcode | 0x80 : options.opcode; target[0] = options.fin ? options.opcode | 0x80 : options.opcode;
if (options.rsv1) target[0] |= 0x40; if (options.rsv1) target[0] |= 0x40;
target[1] = payloadLength;
if (payloadLength === 126) { if (payloadLength === 126) {
target.writeUInt16BE(data.length, 2); target.writeUInt16BE(data.length, 2);
} else if (payloadLength === 127) { } else if (payloadLength === 127) {
@@ -67,30 +69,22 @@ class Sender {
target.writeUInt32BE(data.length, 6); target.writeUInt32BE(data.length, 6);
} }
if (!options.mask) { if (!options.mask) return [target, data];
target[1] = payloadLength;
if (merge) {
data.copy(target, offset);
return [target];
}
return [target, data]; const mask = randomBytes(4);
}
const mask = crypto.randomBytes(4); target[1] |= 0x80;
target[1] = payloadLength | 0x80;
target[offset - 4] = mask[0]; target[offset - 4] = mask[0];
target[offset - 3] = mask[1]; target[offset - 3] = mask[1];
target[offset - 2] = mask[2]; target[offset - 2] = mask[2];
target[offset - 1] = mask[3]; target[offset - 1] = mask[3];
if (merge) { if (merge) {
bufferUtil.mask(data, mask, target, offset, data.length); applyMask(data, mask, target, offset, data.length);
return [target]; return [target];
} }
bufferUtil.mask(data, mask, data, 0, data.length); applyMask(data, mask, data, 0, data.length);
return [target, data]; return [target, data];
} }
@@ -103,12 +97,12 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @public * @public
*/ */
close (code, data, mask, cb) { close(code, data, mask, cb) {
var buf; var buf;
if (code === undefined) { if (code === undefined) {
buf = constants.EMPTY_BUFFER; buf = EMPTY_BUFFER;
} else if (typeof code !== 'number' || !validation.isValidStatusCode(code)) { } else if (typeof code !== 'number' || !isValidStatusCode(code)) {
throw new TypeError('First argument must be a valid error code number'); throw new TypeError('First argument must be a valid error code number');
} else if (data === undefined || data === '') { } else if (data === undefined || data === '') {
buf = Buffer.allocUnsafe(2); buf = Buffer.allocUnsafe(2);
@@ -134,14 +128,17 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
doClose (data, mask, cb) { doClose(data, mask, cb) {
this.sendFrame(Sender.frame(data, { this.sendFrame(
fin: true, Sender.frame(data, {
rsv1: false, fin: true,
opcode: 0x08, rsv1: false,
mask, opcode: 0x08,
readOnly: false mask,
}), cb); readOnly: false
}),
cb
);
} }
/** /**
@@ -152,24 +149,13 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @public * @public
*/ */
ping (data, mask, cb) { ping(data, mask, cb) {
var readOnly = true; const buf = toBuffer(data);
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
if (this._deflating) { if (this._deflating) {
this.enqueue([this.doPing, data, mask, readOnly, cb]); this.enqueue([this.doPing, buf, mask, toBuffer.readOnly, cb]);
} else { } else {
this.doPing(data, mask, readOnly, cb); this.doPing(buf, mask, toBuffer.readOnly, cb);
} }
} }
@@ -182,14 +168,17 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
doPing (data, mask, readOnly, cb) { doPing(data, mask, readOnly, cb) {
this.sendFrame(Sender.frame(data, { this.sendFrame(
fin: true, Sender.frame(data, {
rsv1: false, fin: true,
opcode: 0x09, rsv1: false,
mask, opcode: 0x09,
readOnly mask,
}), cb); readOnly
}),
cb
);
} }
/** /**
@@ -200,24 +189,13 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @public * @public
*/ */
pong (data, mask, cb) { pong(data, mask, cb) {
var readOnly = true; const buf = toBuffer(data);
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
if (this._deflating) { if (this._deflating) {
this.enqueue([this.doPong, data, mask, readOnly, cb]); this.enqueue([this.doPong, buf, mask, toBuffer.readOnly, cb]);
} else { } else {
this.doPong(data, mask, readOnly, cb); this.doPong(buf, mask, toBuffer.readOnly, cb);
} }
} }
@@ -230,14 +208,17 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
doPong (data, mask, readOnly, cb) { doPong(data, mask, readOnly, cb) {
this.sendFrame(Sender.frame(data, { this.sendFrame(
fin: true, Sender.frame(data, {
rsv1: false, fin: true,
opcode: 0x0a, rsv1: false,
mask, opcode: 0x0a,
readOnly mask,
}), cb); readOnly
}),
cb
);
} }
/** /**
@@ -252,28 +233,16 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @public * @public
*/ */
send (data, options, cb) { send(data, options, cb) {
const buf = toBuffer(data);
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
var opcode = options.binary ? 2 : 1; var opcode = options.binary ? 2 : 1;
var rsv1 = options.compress; var rsv1 = options.compress;
var readOnly = true;
if (!Buffer.isBuffer(data)) {
if (data instanceof ArrayBuffer) {
data = Buffer.from(data);
} else if (ArrayBuffer.isView(data)) {
data = viewToBuffer(data);
} else {
data = Buffer.from(data);
readOnly = false;
}
}
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
if (this._firstFragment) { if (this._firstFragment) {
this._firstFragment = false; this._firstFragment = false;
if (rsv1 && perMessageDeflate) { if (rsv1 && perMessageDeflate) {
rsv1 = data.length >= perMessageDeflate._threshold; rsv1 = buf.length >= perMessageDeflate._threshold;
} }
this._compress = rsv1; this._compress = rsv1;
} else { } else {
@@ -289,22 +258,25 @@ class Sender {
rsv1, rsv1,
opcode, opcode,
mask: options.mask, mask: options.mask,
readOnly readOnly: toBuffer.readOnly
}; };
if (this._deflating) { if (this._deflating) {
this.enqueue([this.dispatch, data, this._compress, opts, cb]); this.enqueue([this.dispatch, buf, this._compress, opts, cb]);
} else { } else {
this.dispatch(data, this._compress, opts, cb); this.dispatch(buf, this._compress, opts, cb);
} }
} else { } else {
this.sendFrame(Sender.frame(data, { this.sendFrame(
fin: options.fin, Sender.frame(buf, {
rsv1: false, fin: options.fin,
opcode, rsv1: false,
mask: options.mask, opcode,
readOnly mask: options.mask,
}), cb); readOnly: toBuffer.readOnly
}),
cb
);
} }
} }
@@ -322,7 +294,7 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
dispatch (data, compress, options, cb) { dispatch(data, compress, options, cb) {
if (!compress) { if (!compress) {
this.sendFrame(Sender.frame(data, options), cb); this.sendFrame(Sender.frame(data, options), cb);
return; return;
@@ -332,9 +304,9 @@ class Sender {
this._deflating = true; this._deflating = true;
perMessageDeflate.compress(data, options.fin, (_, buf) => { perMessageDeflate.compress(data, options.fin, (_, buf) => {
this._deflating = false;
options.readOnly = false; options.readOnly = false;
this.sendFrame(Sender.frame(buf, options), cb); this.sendFrame(Sender.frame(buf, options), cb);
this._deflating = false;
this.dequeue(); this.dequeue();
}); });
} }
@@ -344,7 +316,7 @@ class Sender {
* *
* @private * @private
*/ */
dequeue () { dequeue() {
while (!this._deflating && this._queue.length) { while (!this._deflating && this._queue.length) {
const params = this._queue.shift(); const params = this._queue.shift();
@@ -359,7 +331,7 @@ class Sender {
* @param {Array} params Send operation parameters. * @param {Array} params Send operation parameters.
* @private * @private
*/ */
enqueue (params) { enqueue(params) {
this._bufferedBytes += params[1].length; this._bufferedBytes += params[1].length;
this._queue.push(params); this._queue.push(params);
} }
@@ -371,10 +343,12 @@ class Sender {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
sendFrame (list, cb) { sendFrame(list, cb) {
if (list.length === 2) { if (list.length === 2) {
this._socket.cork();
this._socket.write(list[0]); this._socket.write(list[0]);
this._socket.write(list[1], cb); this._socket.write(list[1], cb);
this._socket.uncork();
} else { } else {
this._socket.write(list[0], cb); this._socket.write(list[0], cb);
} }
@@ -382,20 +356,3 @@ class Sender {
} }
module.exports = Sender; module.exports = Sender;
/**
* Converts an `ArrayBuffer` view into a buffer.
*
* @param {(DataView|TypedArray)} view The view to convert
* @return {Buffer} Converted view
* @private
*/
function viewToBuffer (view) {
const buf = Buffer.from(view.buffer);
if (view.byteLength !== view.buffer.byteLength) {
return buf.slice(view.byteOffset, view.byteOffset + view.byteLength);
}
return buf;
}

View File

@@ -3,9 +3,10 @@
try { try {
const isValidUTF8 = require('utf-8-validate'); const isValidUTF8 = require('utf-8-validate');
exports.isValidUTF8 = typeof isValidUTF8 === 'object' exports.isValidUTF8 =
? isValidUTF8.Validation.isValidUTF8 // utf-8-validate@<3.0.0 typeof isValidUTF8 === 'object'
: isValidUTF8; ? isValidUTF8.Validation.isValidUTF8 // utf-8-validate@<3.0.0
: isValidUTF8;
} catch (e) /* istanbul ignore next */ { } catch (e) /* istanbul ignore next */ {
exports.isValidUTF8 = () => true; exports.isValidUTF8 = () => true;
} }

View File

@@ -3,12 +3,13 @@
const EventEmitter = require('events'); const EventEmitter = require('events');
const crypto = require('crypto'); const crypto = require('crypto');
const http = require('http'); const http = require('http');
const url = require('url');
const PerMessageDeflate = require('./permessage-deflate'); const PerMessageDeflate = require('./permessage-deflate');
const extension = require('./extension'); const extension = require('./extension');
const constants = require('./constants');
const WebSocket = require('./websocket'); const WebSocket = require('./websocket');
const { GUID } = require('./constants');
const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
/** /**
* Class representing a WebSocket server. * Class representing a WebSocket server.
@@ -20,34 +21,41 @@ class WebSocketServer extends EventEmitter {
* Create a `WebSocketServer` instance. * Create a `WebSocketServer` instance.
* *
* @param {Object} options Configuration options * @param {Object} options Configuration options
* @param {Number} options.backlog The maximum length of the queue of pending
* connections
* @param {Boolean} options.clientTracking Specifies whether or not to track
* clients
* @param {Function} options.handleProtocols An hook to handle protocols
* @param {String} options.host The hostname where to bind the server * @param {String} options.host The hostname where to bind the server
* @param {Number} options.maxPayload The maximum allowed message size
* @param {Boolean} options.noServer Enable no server mode
* @param {String} options.path Accept only connections matching this path
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable
* permessage-deflate
* @param {Number} options.port The port where to bind the server * @param {Number} options.port The port where to bind the server
* @param {http.Server} options.server A pre-created HTTP/S server to use * @param {http.Server} options.server A pre-created HTTP/S server to use
* @param {Function} options.verifyClient An hook to reject connections * @param {Function} options.verifyClient An hook to reject connections
* @param {Function} options.handleProtocols An hook to handle protocols
* @param {String} options.path Accept only connections matching this path
* @param {Boolean} options.noServer Enable no server mode
* @param {Boolean} options.clientTracking Specifies whether or not to track clients
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable permessage-deflate
* @param {Number} options.maxPayload The maximum allowed message size
* @param {Function} callback A listener for the `listening` event * @param {Function} callback A listener for the `listening` event
*/ */
constructor (options, callback) { constructor(options, callback) {
super(); super();
options = Object.assign({ options = Object.assign(
maxPayload: 100 * 1024 * 1024, {
perMessageDeflate: false, maxPayload: 100 * 1024 * 1024,
handleProtocols: null, perMessageDeflate: false,
clientTracking: true, handleProtocols: null,
verifyClient: null, clientTracking: true,
noServer: false, verifyClient: null,
backlog: null, // use default (511 as implemented in net.js) noServer: false,
server: null, backlog: null, // use default (511 as implemented in net.js)
host: null, server: null,
path: null, host: null,
port: null path: null,
}, options); port: null
},
options
);
if (options.port == null && !options.server && !options.noServer) { if (options.port == null && !options.server && !options.noServer) {
throw new TypeError( throw new TypeError(
@@ -65,7 +73,12 @@ class WebSocketServer extends EventEmitter {
}); });
res.end(body); res.end(body);
}); });
this._server.listen(options.port, options.host, options.backlog, callback); this._server.listen(
options.port,
options.host,
options.backlog,
callback
);
} else if (options.server) { } else if (options.server) {
this._server = options.server; this._server = options.server;
} }
@@ -96,7 +109,7 @@ class WebSocketServer extends EventEmitter {
* @return {(Object|String|null)} The address of the server * @return {(Object|String|null)} The address of the server
* @public * @public
*/ */
address () { address() {
if (this.options.noServer) { if (this.options.noServer) {
throw new Error('The server is operating in "noServer" mode'); throw new Error('The server is operating in "noServer" mode');
} }
@@ -111,7 +124,7 @@ class WebSocketServer extends EventEmitter {
* @param {Function} cb Callback * @param {Function} cb Callback
* @public * @public
*/ */
close (cb) { close(cb) {
if (cb) this.once('close', cb); if (cb) this.once('close', cb);
// //
@@ -146,9 +159,12 @@ class WebSocketServer extends EventEmitter {
* @return {Boolean} `true` if the request is valid, else `false` * @return {Boolean} `true` if the request is valid, else `false`
* @public * @public
*/ */
shouldHandle (req) { shouldHandle(req) {
if (this.options.path && url.parse(req.url).pathname !== this.options.path) { if (this.options.path) {
return false; const index = req.url.indexOf('?');
const pathname = index !== -1 ? req.url.slice(0, index) : req.url;
if (pathname !== this.options.path) return false;
} }
return true; return true;
@@ -163,15 +179,22 @@ class WebSocketServer extends EventEmitter {
* @param {Function} cb Callback * @param {Function} cb Callback
* @public * @public
*/ */
handleUpgrade (req, socket, head, cb) { handleUpgrade(req, socket, head, cb) {
socket.on('error', socketOnError); socket.on('error', socketOnError);
const key =
req.headers['sec-websocket-key'] !== undefined
? req.headers['sec-websocket-key'].trim()
: false;
const version = +req.headers['sec-websocket-version']; const version = +req.headers['sec-websocket-version'];
const extensions = {}; const extensions = {};
if ( if (
req.method !== 'GET' || req.headers.upgrade.toLowerCase() !== 'websocket' || req.method !== 'GET' ||
!req.headers['sec-websocket-key'] || (version !== 8 && version !== 13) || req.headers.upgrade.toLowerCase() !== 'websocket' ||
!key ||
!keyRegex.test(key) ||
(version !== 8 && version !== 13) ||
!this.shouldHandle(req) !this.shouldHandle(req)
) { ) {
return abortHandshake(socket, 400); return abortHandshake(socket, 400);
@@ -185,9 +208,7 @@ class WebSocketServer extends EventEmitter {
); );
try { try {
const offers = extension.parse( const offers = extension.parse(req.headers['sec-websocket-extensions']);
req.headers['sec-websocket-extensions']
);
if (offers[PerMessageDeflate.extensionName]) { if (offers[PerMessageDeflate.extensionName]) {
perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]); perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
@@ -203,7 +224,8 @@ class WebSocketServer extends EventEmitter {
// //
if (this.options.verifyClient) { if (this.options.verifyClient) {
const info = { const info = {
origin: req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`], origin:
req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
secure: !!(req.connection.authorized || req.connection.encrypted), secure: !!(req.connection.authorized || req.connection.encrypted),
req req
}; };
@@ -214,7 +236,7 @@ class WebSocketServer extends EventEmitter {
return abortHandshake(socket, code || 401, message, headers); return abortHandshake(socket, code || 401, message, headers);
} }
this.completeUpgrade(extensions, req, socket, head, cb); this.completeUpgrade(key, extensions, req, socket, head, cb);
}); });
return; return;
} }
@@ -222,12 +244,13 @@ class WebSocketServer extends EventEmitter {
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401); if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
} }
this.completeUpgrade(extensions, req, socket, head, cb); this.completeUpgrade(key, extensions, req, socket, head, cb);
} }
/** /**
* Upgrade the connection to WebSocket. * Upgrade the connection to WebSocket.
* *
* @param {String} key The value of the `Sec-WebSocket-Key` header
* @param {Object} extensions The accepted extensions * @param {Object} extensions The accepted extensions
* @param {http.IncomingMessage} req The request object * @param {http.IncomingMessage} req The request object
* @param {net.Socket} socket The network socket between the server and client * @param {net.Socket} socket The network socket between the server and client
@@ -235,28 +258,29 @@ class WebSocketServer extends EventEmitter {
* @param {Function} cb Callback * @param {Function} cb Callback
* @private * @private
*/ */
completeUpgrade (extensions, req, socket, head, cb) { completeUpgrade(key, extensions, req, socket, head, cb) {
// //
// Destroy the socket if the client has already sent a FIN packet. // Destroy the socket if the client has already sent a FIN packet.
// //
if (!socket.readable || !socket.writable) return socket.destroy(); if (!socket.readable || !socket.writable) return socket.destroy();
const key = crypto.createHash('sha1') const digest = crypto
.update(req.headers['sec-websocket-key'] + constants.GUID, 'binary') .createHash('sha1')
.update(key + GUID)
.digest('base64'); .digest('base64');
const headers = [ const headers = [
'HTTP/1.1 101 Switching Protocols', 'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket', 'Upgrade: websocket',
'Connection: Upgrade', 'Connection: Upgrade',
`Sec-WebSocket-Accept: ${key}` `Sec-WebSocket-Accept: ${digest}`
]; ];
const ws = new WebSocket(null); const ws = new WebSocket(null);
var protocol = req.headers['sec-websocket-protocol']; var protocol = req.headers['sec-websocket-protocol'];
if (protocol) { if (protocol) {
protocol = protocol.trim().split(/ *, */); protocol = protocol.split(',').map(trim);
// //
// Optionally call external protocol selection handler. // Optionally call external protocol selection handler.
@@ -312,10 +336,10 @@ module.exports = WebSocketServer;
* @return {Function} A function that will remove the added listeners when called * @return {Function} A function that will remove the added listeners when called
* @private * @private
*/ */
function addListeners (server, map) { function addListeners(server, map) {
for (const event of Object.keys(map)) server.on(event, map[event]); for (const event of Object.keys(map)) server.on(event, map[event]);
return function removeListeners () { return function removeListeners() {
for (const event of Object.keys(map)) { for (const event of Object.keys(map)) {
server.removeListener(event, map[event]); server.removeListener(event, map[event]);
} }
@@ -328,7 +352,7 @@ function addListeners (server, map) {
* @param {EventEmitter} server The event emitter * @param {EventEmitter} server The event emitter
* @private * @private
*/ */
function emitClose (server) { function emitClose(server) {
server.emit('close'); server.emit('close');
} }
@@ -337,7 +361,7 @@ function emitClose (server) {
* *
* @private * @private
*/ */
function socketOnError () { function socketOnError() {
this.destroy(); this.destroy();
} }
@@ -350,23 +374,40 @@ function socketOnError () {
* @param {Object} [headers] Additional HTTP response headers * @param {Object} [headers] Additional HTTP response headers
* @private * @private
*/ */
function abortHandshake (socket, code, message, headers) { function abortHandshake(socket, code, message, headers) {
if (socket.writable) { if (socket.writable) {
message = message || http.STATUS_CODES[code]; message = message || http.STATUS_CODES[code];
headers = Object.assign({ headers = Object.assign(
'Connection': 'close', {
'Content-type': 'text/html', Connection: 'close',
'Content-Length': Buffer.byteLength(message) 'Content-type': 'text/html',
}, headers); 'Content-Length': Buffer.byteLength(message)
},
headers
);
socket.write( socket.write(
`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` + `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
Object.keys(headers).map(h => `${h}: ${headers[h]}`).join('\r\n') + Object.keys(headers)
'\r\n\r\n' + .map((h) => `${h}: ${headers[h]}`)
message .join('\r\n') +
'\r\n\r\n' +
message
); );
} }
socket.removeListener('error', socketOnError); socket.removeListener('error', socketOnError);
socket.destroy(); socket.destroy();
} }
/**
* Remove whitespace characters from both ends of a string.
*
* @param {String} str The string
* @return {String} A new string representing `str` stripped of whitespace
* characters from both its beginning and end
* @private
*/
function trim(str) {
return str.trim();
}

374
node/node_modules/ws/lib/websocket.js generated vendored
View File

@@ -11,14 +11,20 @@ const url = require('url');
const PerMessageDeflate = require('./permessage-deflate'); const PerMessageDeflate = require('./permessage-deflate');
const EventTarget = require('./event-target'); const EventTarget = require('./event-target');
const extension = require('./extension'); const extension = require('./extension');
const constants = require('./constants');
const Receiver = require('./receiver'); const Receiver = require('./receiver');
const Sender = require('./sender'); const Sender = require('./sender');
const {
BINARY_TYPES,
EMPTY_BUFFER,
GUID,
kStatusCode,
kWebSocket,
NOOP
} = require('./constants');
const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']; const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
const kWebSocket = constants.kWebSocket;
const protocolVersions = [8, 13]; const protocolVersions = [8, 13];
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly. const closeTimeout = 30 * 1000;
/** /**
* Class representing a WebSocket. * Class representing a WebSocket.
@@ -33,25 +39,27 @@ class WebSocket extends EventEmitter {
* @param {(String|String[])} protocols The subprotocols * @param {(String|String[])} protocols The subprotocols
* @param {Object} options Connection options * @param {Object} options Connection options
*/ */
constructor (address, protocols, options) { constructor(address, protocols, options) {
super(); super();
this.readyState = WebSocket.CONNECTING; this.readyState = WebSocket.CONNECTING;
this.protocol = ''; this.protocol = '';
this._binaryType = constants.BINARY_TYPES[0]; this._binaryType = BINARY_TYPES[0];
this._closeFrameReceived = false; this._closeFrameReceived = false;
this._closeFrameSent = false; this._closeFrameSent = false;
this._closeMessage = ''; this._closeMessage = '';
this._closeTimer = null; this._closeTimer = null;
this._closeCode = 1006; this._closeCode = 1006;
this._extensions = {}; this._extensions = {};
this._isServer = true;
this._receiver = null; this._receiver = null;
this._sender = null; this._sender = null;
this._socket = null; this._socket = null;
if (address !== null) { if (address !== null) {
this._isServer = false;
this._redirects = 0;
if (Array.isArray(protocols)) { if (Array.isArray(protocols)) {
protocols = protocols.join(', '); protocols = protocols.join(', ');
} else if (typeof protocols === 'object' && protocols !== null) { } else if (typeof protocols === 'object' && protocols !== null) {
@@ -59,27 +67,38 @@ class WebSocket extends EventEmitter {
protocols = undefined; protocols = undefined;
} }
initAsClient.call(this, address, protocols, options); initAsClient(this, address, protocols, options);
} else {
this._isServer = true;
} }
} }
get CONNECTING () { return WebSocket.CONNECTING; } get CONNECTING() {
get CLOSING () { return WebSocket.CLOSING; } return WebSocket.CONNECTING;
get CLOSED () { return WebSocket.CLOSED; } }
get OPEN () { return WebSocket.OPEN; } get CLOSING() {
return WebSocket.CLOSING;
}
get CLOSED() {
return WebSocket.CLOSED;
}
get OPEN() {
return WebSocket.OPEN;
}
/** /**
* This deviates from the WHATWG interface since ws doesn't support the required * This deviates from the WHATWG interface since ws doesn't support the
* default "blob" type (instead we define a custom "nodebuffer" type). * required default "blob" type (instead we define a custom "nodebuffer"
* type).
* *
* @type {String} * @type {String}
*/ */
get binaryType () { get binaryType() {
return this._binaryType; return this._binaryType;
} }
set binaryType (type) { set binaryType(type) {
if (constants.BINARY_TYPES.indexOf(type) < 0) return; if (!BINARY_TYPES.includes(type)) return;
this._binaryType = type; this._binaryType = type;
@@ -92,7 +111,7 @@ class WebSocket extends EventEmitter {
/** /**
* @type {Number} * @type {Number}
*/ */
get bufferedAmount () { get bufferedAmount() {
if (!this._socket) return 0; if (!this._socket) return 0;
// //
@@ -104,7 +123,7 @@ class WebSocket extends EventEmitter {
/** /**
* @type {String} * @type {String}
*/ */
get extensions () { get extensions() {
return Object.keys(this._extensions).join(); return Object.keys(this._extensions).join();
} }
@@ -116,7 +135,7 @@ class WebSocket extends EventEmitter {
* @param {Number} maxPayload The maximum allowed message size * @param {Number} maxPayload The maximum allowed message size
* @private * @private
*/ */
setSocket (socket, head, maxPayload) { setSocket(socket, head, maxPayload) {
const receiver = new Receiver( const receiver = new Receiver(
this._binaryType, this._binaryType,
this._extensions, this._extensions,
@@ -156,7 +175,7 @@ class WebSocket extends EventEmitter {
* *
* @private * @private
*/ */
emitClose () { emitClose() {
this.readyState = WebSocket.CLOSED; this.readyState = WebSocket.CLOSED;
if (!this._socket) { if (!this._socket) {
@@ -191,7 +210,7 @@ class WebSocket extends EventEmitter {
* @param {String} data A string explaining why the connection is closing * @param {String} data A string explaining why the connection is closing
* @public * @public
*/ */
close (code, data) { close(code, data) {
if (this.readyState === WebSocket.CLOSED) return; if (this.readyState === WebSocket.CLOSED) return;
if (this.readyState === WebSocket.CONNECTING) { if (this.readyState === WebSocket.CONNECTING) {
const msg = 'WebSocket was closed before the connection was established'; const msg = 'WebSocket was closed before the connection was established';
@@ -212,20 +231,16 @@ class WebSocket extends EventEmitter {
if (err) return; if (err) return;
this._closeFrameSent = true; this._closeFrameSent = true;
if (this._closeFrameReceived) this._socket.end();
if (this._socket.writable) {
if (this._closeFrameReceived) this._socket.end();
//
// Ensure that the connection is closed even if the closing handshake
// fails.
//
this._closeTimer = setTimeout(
this._socket.destroy.bind(this._socket),
closeTimeout
);
}
}); });
//
// Specify a timeout for the closing handshake to complete.
//
this._closeTimer = setTimeout(
this._socket.destroy.bind(this._socket),
closeTimeout
);
} }
/** /**
@@ -236,7 +251,7 @@ class WebSocket extends EventEmitter {
* @param {Function} cb Callback which is executed when the ping is sent * @param {Function} cb Callback which is executed when the ping is sent
* @public * @public
*/ */
ping (data, mask, cb) { ping(data, mask, cb) {
if (typeof data === 'function') { if (typeof data === 'function') {
cb = data; cb = data;
data = mask = undefined; data = mask = undefined;
@@ -257,7 +272,7 @@ class WebSocket extends EventEmitter {
if (typeof data === 'number') data = data.toString(); if (typeof data === 'number') data = data.toString();
if (mask === undefined) mask = !this._isServer; if (mask === undefined) mask = !this._isServer;
this._sender.ping(data || constants.EMPTY_BUFFER, mask, cb); this._sender.ping(data || EMPTY_BUFFER, mask, cb);
} }
/** /**
@@ -268,7 +283,7 @@ class WebSocket extends EventEmitter {
* @param {Function} cb Callback which is executed when the pong is sent * @param {Function} cb Callback which is executed when the pong is sent
* @public * @public
*/ */
pong (data, mask, cb) { pong(data, mask, cb) {
if (typeof data === 'function') { if (typeof data === 'function') {
cb = data; cb = data;
data = mask = undefined; data = mask = undefined;
@@ -289,7 +304,7 @@ class WebSocket extends EventEmitter {
if (typeof data === 'number') data = data.toString(); if (typeof data === 'number') data = data.toString();
if (mask === undefined) mask = !this._isServer; if (mask === undefined) mask = !this._isServer;
this._sender.pong(data || constants.EMPTY_BUFFER, mask, cb); this._sender.pong(data || EMPTY_BUFFER, mask, cb);
} }
/** /**
@@ -304,7 +319,7 @@ class WebSocket extends EventEmitter {
* @param {Function} cb Callback which is executed when data is written out * @param {Function} cb Callback which is executed when data is written out
* @public * @public
*/ */
send (data, options, cb) { send(data, options, cb) {
if (typeof options === 'function') { if (typeof options === 'function') {
cb = options; cb = options;
options = {}; options = {};
@@ -322,18 +337,21 @@ class WebSocket extends EventEmitter {
if (typeof data === 'number') data = data.toString(); if (typeof data === 'number') data = data.toString();
const opts = Object.assign({ const opts = Object.assign(
binary: typeof data !== 'string', {
mask: !this._isServer, binary: typeof data !== 'string',
compress: true, mask: !this._isServer,
fin: true compress: true,
}, options); fin: true
},
options
);
if (!this._extensions[PerMessageDeflate.extensionName]) { if (!this._extensions[PerMessageDeflate.extensionName]) {
opts.compress = false; opts.compress = false;
} }
this._sender.send(data || constants.EMPTY_BUFFER, opts, cb); this._sender.send(data || EMPTY_BUFFER, opts, cb);
} }
/** /**
@@ -341,7 +359,7 @@ class WebSocket extends EventEmitter {
* *
* @public * @public
*/ */
terminate () { terminate() {
if (this.readyState === WebSocket.CLOSED) return; if (this.readyState === WebSocket.CLOSED) return;
if (this.readyState === WebSocket.CONNECTING) { if (this.readyState === WebSocket.CONNECTING) {
const msg = 'WebSocket was closed before the connection was established'; const msg = 'WebSocket was closed before the connection was established';
@@ -356,7 +374,7 @@ class WebSocket extends EventEmitter {
} }
readyStates.forEach((readyState, i) => { readyStates.forEach((readyState, i) => {
WebSocket[readyStates[i]] = i; WebSocket[readyState] = i;
}); });
// //
@@ -371,11 +389,13 @@ readyStates.forEach((readyState, i) => {
* @return {(Function|undefined)} The event listener or `undefined` * @return {(Function|undefined)} The event listener or `undefined`
* @public * @public
*/ */
get () { get() {
const listeners = this.listeners(method); const listeners = this.listeners(method);
for (var i = 0; i < listeners.length; i++) { for (var i = 0; i < listeners.length; i++) {
if (listeners[i]._listener) return listeners[i]._listener; if (listeners[i]._listener) return listeners[i]._listener;
} }
return undefined;
}, },
/** /**
* Add a listener for the event. * Add a listener for the event.
@@ -383,7 +403,7 @@ readyStates.forEach((readyState, i) => {
* @param {Function} listener The listener to add * @param {Function} listener The listener to add
* @public * @public
*/ */
set (listener) { set(listener) {
const listeners = this.listeners(method); const listeners = this.listeners(method);
for (var i = 0; i < listeners.length; i++) { for (var i = 0; i < listeners.length; i++) {
// //
@@ -404,154 +424,200 @@ module.exports = WebSocket;
/** /**
* Initialize a WebSocket client. * Initialize a WebSocket client.
* *
* @param {WebSocket} websocket The client to initialize
* @param {(String|url.Url|url.URL)} address The URL to which to connect * @param {(String|url.Url|url.URL)} address The URL to which to connect
* @param {String} protocols The subprotocols * @param {String} protocols The subprotocols
* @param {Object} options Connection options * @param {Object} options Connection options
* @param {(Boolean|Object)} options.perMessageDeflate Enable/disable permessage-deflate * @param {(Boolean|Object)} options.perMessageDeflate Enable/disable
* @param {Number} options.handshakeTimeout Timeout in milliseconds for the handshake request * permessage-deflate
* @param {Number} options.protocolVersion Value of the `Sec-WebSocket-Version` header * @param {Number} options.handshakeTimeout Timeout in milliseconds for the
* @param {String} options.origin Value of the `Origin` or `Sec-WebSocket-Origin` header * handshake request
* @param {Number} options.protocolVersion Value of the `Sec-WebSocket-Version`
* header
* @param {String} options.origin Value of the `Origin` or
* `Sec-WebSocket-Origin` header
* @param {Number} options.maxPayload The maximum allowed message size * @param {Number} options.maxPayload The maximum allowed message size
* @param {Boolean} options.followRedirects Whether or not to follow redirects
* @param {Number} options.maxRedirects The maximum number of redirects allowed
* @private * @private
*/ */
function initAsClient (address, protocols, options) { function initAsClient(websocket, address, protocols, options) {
options = Object.assign({ const opts = Object.assign(
protocolVersion: protocolVersions[1], {
perMessageDeflate: true, protocolVersion: protocolVersions[1],
maxPayload: 100 * 1024 * 1024 maxPayload: 100 * 1024 * 1024,
}, options, { perMessageDeflate: true,
createConnection: undefined, followRedirects: false,
socketPath: undefined, maxRedirects: 10
hostname: undefined, },
protocol: undefined, options,
timeout: undefined, {
method: undefined, createConnection: undefined,
auth: undefined, socketPath: undefined,
host: undefined, hostname: undefined,
path: undefined, protocol: undefined,
port: undefined timeout: undefined,
}); method: undefined,
auth: undefined,
host: undefined,
path: undefined,
port: undefined
}
);
if (protocolVersions.indexOf(options.protocolVersion) === -1) { if (!protocolVersions.includes(opts.protocolVersion)) {
throw new RangeError( throw new RangeError(
`Unsupported protocol version: ${options.protocolVersion} ` + `Unsupported protocol version: ${opts.protocolVersion} ` +
`(supported versions: ${protocolVersions.join(', ')})` `(supported versions: ${protocolVersions.join(', ')})`
); );
} }
this._isServer = false;
var parsedUrl; var parsedUrl;
if (typeof address === 'object' && address.href !== undefined) { if (typeof address === 'object' && address.href !== undefined) {
parsedUrl = address; parsedUrl = address;
this.url = address.href; websocket.url = address.href;
} else { } else {
parsedUrl = url.parse(address); //
this.url = address; // The WHATWG URL constructor is not available on Node.js < 6.13.0
//
parsedUrl = url.URL ? new url.URL(address) : url.parse(address);
websocket.url = address;
} }
const isUnixSocket = parsedUrl.protocol === 'ws+unix:'; const isUnixSocket = parsedUrl.protocol === 'ws+unix:';
if (!parsedUrl.host && (!isUnixSocket || !parsedUrl.pathname)) { if (!parsedUrl.host && (!isUnixSocket || !parsedUrl.pathname)) {
throw new Error(`Invalid URL: ${this.url}`); throw new Error(`Invalid URL: ${websocket.url}`);
} }
const isSecure = parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:'; const isSecure =
parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
const defaultPort = isSecure ? 443 : 80;
const key = crypto.randomBytes(16).toString('base64'); const key = crypto.randomBytes(16).toString('base64');
const httpObj = isSecure ? https : http; const get = isSecure ? https.get : http.get;
const path = parsedUrl.search const path = parsedUrl.search
? `${parsedUrl.pathname || '/'}${parsedUrl.search}` ? `${parsedUrl.pathname || '/'}${parsedUrl.search}`
: parsedUrl.pathname || '/'; : parsedUrl.pathname || '/';
var perMessageDeflate; var perMessageDeflate;
options.createConnection = isSecure ? tlsConnect : netConnect; opts.createConnection = isSecure ? tlsConnect : netConnect;
options.port = parsedUrl.port || (isSecure ? 443 : 80); opts.defaultPort = opts.defaultPort || defaultPort;
options.host = parsedUrl.hostname.startsWith('[') opts.port = parsedUrl.port || defaultPort;
opts.host = parsedUrl.hostname.startsWith('[')
? parsedUrl.hostname.slice(1, -1) ? parsedUrl.hostname.slice(1, -1)
: parsedUrl.hostname; : parsedUrl.hostname;
options.headers = Object.assign({ opts.headers = Object.assign(
'Sec-WebSocket-Version': options.protocolVersion, {
'Sec-WebSocket-Key': key, 'Sec-WebSocket-Version': opts.protocolVersion,
'Connection': 'Upgrade', 'Sec-WebSocket-Key': key,
'Upgrade': 'websocket' Connection: 'Upgrade',
}, options.headers); Upgrade: 'websocket'
options.path = path; },
opts.headers
);
opts.path = path;
opts.timeout = opts.handshakeTimeout;
if (options.perMessageDeflate) { if (opts.perMessageDeflate) {
perMessageDeflate = new PerMessageDeflate( perMessageDeflate = new PerMessageDeflate(
options.perMessageDeflate !== true ? options.perMessageDeflate : {}, opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},
false, false,
options.maxPayload opts.maxPayload
); );
options.headers['Sec-WebSocket-Extensions'] = extension.format({ opts.headers['Sec-WebSocket-Extensions'] = extension.format({
[PerMessageDeflate.extensionName]: perMessageDeflate.offer() [PerMessageDeflate.extensionName]: perMessageDeflate.offer()
}); });
} }
if (protocols) { if (protocols) {
options.headers['Sec-WebSocket-Protocol'] = protocols; opts.headers['Sec-WebSocket-Protocol'] = protocols;
} }
if (options.origin) { if (opts.origin) {
if (options.protocolVersion < 13) { if (opts.protocolVersion < 13) {
options.headers['Sec-WebSocket-Origin'] = options.origin; opts.headers['Sec-WebSocket-Origin'] = opts.origin;
} else { } else {
options.headers.Origin = options.origin; opts.headers.Origin = opts.origin;
} }
} }
if (parsedUrl.auth) { if (parsedUrl.auth) {
options.auth = parsedUrl.auth; opts.auth = parsedUrl.auth;
} else if (parsedUrl.username || parsedUrl.password) { } else if (parsedUrl.username || parsedUrl.password) {
options.auth = `${parsedUrl.username}:${parsedUrl.password}`; opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
} }
if (isUnixSocket) { if (isUnixSocket) {
const parts = path.split(':'); const parts = path.split(':');
options.socketPath = parts[0]; opts.socketPath = parts[0];
options.path = parts[1]; opts.path = parts[1];
} }
var req = this._req = httpObj.get(options); var req = (websocket._req = get(opts));
if (options.handshakeTimeout) { if (opts.timeout) {
req.setTimeout( req.on('timeout', () => {
options.handshakeTimeout, abortHandshake(websocket, req, 'Opening handshake has timed out');
() => abortHandshake(this, req, 'Opening handshake has timed out') });
);
} }
req.on('error', (err) => { req.on('error', (err) => {
if (this._req.aborted) return; if (websocket._req.aborted) return;
req = this._req = null; req = websocket._req = null;
this.readyState = WebSocket.CLOSING; websocket.readyState = WebSocket.CLOSING;
this.emit('error', err); websocket.emit('error', err);
this.emitClose(); websocket.emitClose();
}); });
req.on('response', (res) => { req.on('response', (res) => {
if (this.emit('unexpected-response', req, res)) return; const location = res.headers.location;
const statusCode = res.statusCode;
abortHandshake(this, req, `Unexpected server response: ${res.statusCode}`); if (
location &&
opts.followRedirects &&
statusCode >= 300 &&
statusCode < 400
) {
if (++websocket._redirects > opts.maxRedirects) {
abortHandshake(websocket, req, 'Maximum redirects exceeded');
return;
}
req.abort();
const addr = url.URL
? new url.URL(location, address)
: url.resolve(address, location);
initAsClient(websocket, addr, protocols, options);
} else if (!websocket.emit('unexpected-response', req, res)) {
abortHandshake(
websocket,
req,
`Unexpected server response: ${res.statusCode}`
);
}
}); });
req.on('upgrade', (res, socket, head) => { req.on('upgrade', (res, socket, head) => {
this.emit('upgrade', res); websocket.emit('upgrade', res);
// //
// The user may have closed the connection from a listener of the `upgrade` // The user may have closed the connection from a listener of the `upgrade`
// event. // event.
// //
if (this.readyState !== WebSocket.CONNECTING) return; if (websocket.readyState !== WebSocket.CONNECTING) return;
req = this._req = null; req = websocket._req = null;
const digest = crypto.createHash('sha1') const digest = crypto
.update(key + constants.GUID, 'binary') .createHash('sha1')
.update(key + GUID)
.digest('base64'); .digest('base64');
if (res.headers['sec-websocket-accept'] !== digest) { if (res.headers['sec-websocket-accept'] !== digest) {
abortHandshake(this, socket, 'Invalid Sec-WebSocket-Accept header'); abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');
return; return;
} }
@@ -563,16 +629,16 @@ function initAsClient (address, protocols, options) {
protError = 'Server sent a subprotocol but none was requested'; protError = 'Server sent a subprotocol but none was requested';
} else if (protocols && !serverProt) { } else if (protocols && !serverProt) {
protError = 'Server sent no subprotocol'; protError = 'Server sent no subprotocol';
} else if (serverProt && protList.indexOf(serverProt) === -1) { } else if (serverProt && !protList.includes(serverProt)) {
protError = 'Server sent an invalid subprotocol'; protError = 'Server sent an invalid subprotocol';
} }
if (protError) { if (protError) {
abortHandshake(this, socket, protError); abortHandshake(websocket, socket, protError);
return; return;
} }
if (serverProt) this.protocol = serverProt; if (serverProt) websocket.protocol = serverProt;
if (perMessageDeflate) { if (perMessageDeflate) {
try { try {
@@ -581,18 +647,22 @@ function initAsClient (address, protocols, options) {
); );
if (extensions[PerMessageDeflate.extensionName]) { if (extensions[PerMessageDeflate.extensionName]) {
perMessageDeflate.accept( perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
extensions[PerMessageDeflate.extensionName] websocket._extensions[
); PerMessageDeflate.extensionName
this._extensions[PerMessageDeflate.extensionName] = perMessageDeflate; ] = perMessageDeflate;
} }
} catch (err) { } catch (err) {
abortHandshake(this, socket, 'Invalid Sec-WebSocket-Extensions header'); abortHandshake(
websocket,
socket,
'Invalid Sec-WebSocket-Extensions header'
);
return; return;
} }
} }
this.setSocket(socket, head, options.maxPayload); websocket.setSocket(socket, head, opts.maxPayload);
}); });
} }
@@ -603,7 +673,7 @@ function initAsClient (address, protocols, options) {
* @return {net.Socket} The newly created socket used to start the connection * @return {net.Socket} The newly created socket used to start the connection
* @private * @private
*/ */
function netConnect (options) { function netConnect(options) {
// //
// Override `options.path` only if `options` is a copy of the original options // Override `options.path` only if `options` is a copy of the original options
// object. This is always true on Node.js >= 8 but not on Node.js 6 where // object. This is always true on Node.js >= 8 but not on Node.js 6 where
@@ -621,7 +691,7 @@ function netConnect (options) {
* @return {tls.TLSSocket} The newly created socket used to start the connection * @return {tls.TLSSocket} The newly created socket used to start the connection
* @private * @private
*/ */
function tlsConnect (options) { function tlsConnect(options) {
options.path = undefined; options.path = undefined;
options.servername = options.servername || options.host; options.servername = options.servername || options.host;
return tls.connect(options); return tls.connect(options);
@@ -636,7 +706,7 @@ function tlsConnect (options) {
* @param {String} message The error message * @param {String} message The error message
* @private * @private
*/ */
function abortHandshake (websocket, stream, message) { function abortHandshake(websocket, stream, message) {
websocket.readyState = WebSocket.CLOSING; websocket.readyState = WebSocket.CLOSING;
const err = new Error(message); const err = new Error(message);
@@ -660,7 +730,7 @@ function abortHandshake (websocket, stream, message) {
* @param {String} reason The reason for closing * @param {String} reason The reason for closing
* @private * @private
*/ */
function receiverOnConclude (code, reason) { function receiverOnConclude(code, reason) {
const websocket = this[kWebSocket]; const websocket = this[kWebSocket];
websocket._socket.removeListener('data', socketOnData); websocket._socket.removeListener('data', socketOnData);
@@ -679,7 +749,7 @@ function receiverOnConclude (code, reason) {
* *
* @private * @private
*/ */
function receiverOnDrain () { function receiverOnDrain() {
this[kWebSocket]._socket.resume(); this[kWebSocket]._socket.resume();
} }
@@ -689,13 +759,13 @@ function receiverOnDrain () {
* @param {(RangeError|Error)} err The emitted error * @param {(RangeError|Error)} err The emitted error
* @private * @private
*/ */
function receiverOnError (err) { function receiverOnError(err) {
const websocket = this[kWebSocket]; const websocket = this[kWebSocket];
websocket._socket.removeListener('data', socketOnData); websocket._socket.removeListener('data', socketOnData);
websocket.readyState = WebSocket.CLOSING; websocket.readyState = WebSocket.CLOSING;
websocket._closeCode = err[constants.kStatusCode]; websocket._closeCode = err[kStatusCode];
websocket.emit('error', err); websocket.emit('error', err);
websocket._socket.destroy(); websocket._socket.destroy();
} }
@@ -705,7 +775,7 @@ function receiverOnError (err) {
* *
* @private * @private
*/ */
function receiverOnFinish () { function receiverOnFinish() {
this[kWebSocket].emitClose(); this[kWebSocket].emitClose();
} }
@@ -715,7 +785,7 @@ function receiverOnFinish () {
* @param {(String|Buffer|ArrayBuffer|Buffer[])} data The message * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The message
* @private * @private
*/ */
function receiverOnMessage (data) { function receiverOnMessage(data) {
this[kWebSocket].emit('message', data); this[kWebSocket].emit('message', data);
} }
@@ -725,10 +795,10 @@ function receiverOnMessage (data) {
* @param {Buffer} data The data included in the ping frame * @param {Buffer} data The data included in the ping frame
* @private * @private
*/ */
function receiverOnPing (data) { function receiverOnPing(data) {
const websocket = this[kWebSocket]; const websocket = this[kWebSocket];
websocket.pong(data, !websocket._isServer, constants.NOOP); websocket.pong(data, !websocket._isServer, NOOP);
websocket.emit('ping', data); websocket.emit('ping', data);
} }
@@ -738,7 +808,7 @@ function receiverOnPing (data) {
* @param {Buffer} data The data included in the pong frame * @param {Buffer} data The data included in the pong frame
* @private * @private
*/ */
function receiverOnPong (data) { function receiverOnPong(data) {
this[kWebSocket].emit('pong', data); this[kWebSocket].emit('pong', data);
} }
@@ -747,7 +817,7 @@ function receiverOnPong (data) {
* *
* @private * @private
*/ */
function socketOnClose () { function socketOnClose() {
const websocket = this[kWebSocket]; const websocket = this[kWebSocket];
this.removeListener('close', socketOnClose); this.removeListener('close', socketOnClose);
@@ -790,7 +860,7 @@ function socketOnClose () {
* @param {Buffer} chunk A chunk of data * @param {Buffer} chunk A chunk of data
* @private * @private
*/ */
function socketOnData (chunk) { function socketOnData(chunk) {
if (!this[kWebSocket]._receiver.write(chunk)) { if (!this[kWebSocket]._receiver.write(chunk)) {
this.pause(); this.pause();
} }
@@ -801,7 +871,7 @@ function socketOnData (chunk) {
* *
* @private * @private
*/ */
function socketOnEnd () { function socketOnEnd() {
const websocket = this[kWebSocket]; const websocket = this[kWebSocket];
websocket.readyState = WebSocket.CLOSING; websocket.readyState = WebSocket.CLOSING;
@@ -814,14 +884,12 @@ function socketOnEnd () {
* *
* @private * @private
*/ */
function socketOnError () { function socketOnError() {
const websocket = this[kWebSocket]; const websocket = this[kWebSocket];
this.removeListener('error', socketOnError); this.removeListener('error', socketOnError);
this.on('error', constants.NOOP); this.on('error', NOOP);
if (websocket) { websocket.readyState = WebSocket.CLOSING;
websocket.readyState = WebSocket.CLOSING; this.destroy();
this.destroy();
}
} }

54
node/node_modules/ws/package.json generated vendored
View File

@@ -1,27 +1,32 @@
{ {
"_from": "ws@6.1.0", "_args": [
"_id": "ws@6.1.0", [
"ws@6.2.2",
"/usr/local/www/clonos/node"
]
],
"_from": "ws@6.2.2",
"_id": "ws@6.2.2",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha512-H3dGVdGvW2H8bnYpIDc3u3LH8Wue3Qh+Zto6aXXFzvESkTVT6rAfKR6tR/+coaUvxs8yHtmNV0uioBF62ZGSTg==", "_integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"_location": "/ws", "_location": "/ws",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
"type": "version", "type": "version",
"registry": true, "registry": true,
"raw": "ws@6.1.0", "raw": "ws@6.2.2",
"name": "ws", "name": "ws",
"escapedName": "ws", "escapedName": "ws",
"rawSpec": "6.1.0", "rawSpec": "6.2.2",
"saveSpec": null, "saveSpec": null,
"fetchSpec": "6.1.0" "fetchSpec": "6.2.2"
}, },
"_requiredBy": [ "_requiredBy": [
"/" "/"
], ],
"_resolved": "https://registry.npmjs.org/ws/-/ws-6.1.0.tgz", "_resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"_shasum": "119a9dbf92c54e190ec18d10e871d55c95cf9373", "_spec": "6.2.2",
"_spec": "ws@6.1.0", "_where": "/usr/local/www/clonos/node",
"_where": "/usr/home/web/cp/clonos/node",
"author": { "author": {
"name": "Einar Otto Stangvik", "name": "Einar Otto Stangvik",
"email": "einaros@gmail.com", "email": "einaros@gmail.com",
@@ -31,29 +36,26 @@
"bugs": { "bugs": {
"url": "https://github.com/websockets/ws/issues" "url": "https://github.com/websockets/ws/issues"
}, },
"bundleDependencies": false,
"dependencies": { "dependencies": {
"async-limiter": "~1.0.0" "async-limiter": "~1.0.0"
}, },
"deprecated": false,
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js", "description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",
"devDependencies": { "devDependencies": {
"benchmark": "~2.1.2", "benchmark": "~2.1.4",
"bufferutil": "~4.0.0", "bufferutil": "~4.0.0",
"eslint": "~5.6.1", "coveralls": "~3.0.3",
"eslint-config-standard": "~12.0.0", "eslint": "~5.15.0",
"eslint-plugin-import": "~2.14.0", "eslint-config-prettier": "~4.1.0",
"eslint-plugin-node": "~7.0.0", "eslint-plugin-prettier": "~3.0.0",
"eslint-plugin-promise": "~4.0.0", "mocha": "~6.0.0",
"eslint-plugin-standard": "~4.0.0", "nyc": "~13.3.0",
"mocha": "~5.2.0", "prettier": "~1.16.1",
"nyc": "~13.0.1",
"utf-8-validate": "~5.0.0" "utf-8-validate": "~5.0.0"
}, },
"files": [ "files": [
"browser.js", "browser.js",
"index.js", "index.js",
"lib" "lib/*.js"
], ],
"homepage": "https://github.com/websockets/ws", "homepage": "https://github.com/websockets/ws",
"keywords": [ "keywords": [
@@ -72,9 +74,9 @@
"url": "git+https://github.com/websockets/ws.git" "url": "git+https://github.com/websockets/ws.git"
}, },
"scripts": { "scripts": {
"integration": "eslint . && mocha test/*.integration.js", "integration": "npm run lint && mocha test/*.integration.js",
"lint": "eslint .", "lint": "eslint --ignore-path .gitignore . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yml}\"",
"test": "eslint . && nyc --reporter=html --reporter=text mocha test/*.test.js" "test": "npm run lint && nyc --reporter=html --reporter=text mocha test/*.test.js"
}, },
"version": "6.1.0" "version": "6.2.2"
} }

View File

@@ -23,6 +23,9 @@ class CBSD {
die("Shell escape attempt"); die("Shell escape attempt");
} }
// olevole: to generic log_() function
// file_put_contents('/tmp/clonos-run_'.date("j.n.Y").'.log', $full_cmd . "\n", FILE_APPEND);
$process = proc_open($full_cmd,$specs,$pipes,null,null); $process = proc_open($full_cmd,$specs,$pipes,null,null);
$error=false; $error=false;

View File

@@ -1012,7 +1012,7 @@ class ClonOS {
function ccmd_jailStop(){ function ccmd_jailStop(){
//$cbsd_queue_name=trim($this->_vars['path'],'/'); //$cbsd_queue_name=trim($this->_vars['path'],'/');
$res=CBSD::run( $res=CBSD::run(
'task owner='.$username.' mode=new {cbsd_loc} jstop inter=0 jname=%s', 'task owner=%s mode=new {cbsd_loc} jstop inter=0 jname=%s',
array($this->_user_info['username'], $this->_vars['form_data']['jname']) array($this->_user_info['username'], $this->_vars['form_data']['jname'])
); );
//.' cbsd_queue_name=/clonos/'.$cbsd_queue_name.'/'); // autoflush=2 //.' cbsd_queue_name=/clonos/'.$cbsd_queue_name.'/'); // autoflush=2

View File

@@ -20,7 +20,7 @@ if(!isset($this->_vars['db_path']))
} }
$freejname=''; $freejname='';
$jres=$this->getFreeJname(true); $jres=$this->ccmd_getFreeJname(false,'jail');
if(!$jres['error']) $freejname=$jres['freejname']; if(!$jres['error']) $freejname=$jres['freejname'];
$jname_desc=$this->translate('will be created new jail with helper inside'); $jname_desc=$this->translate('will be created new jail with helper inside');

View File

@@ -1 +1 @@
21.06 21.10