Hello community,

here is the log from the commit of package siege for openSUSE:Factory checked 
in at 2020-04-16 23:04:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/siege (Old)
 and      /work/SRC/openSUSE:Factory/.siege.new.2738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "siege"

Thu Apr 16 23:04:17 2020 rev:8 rq:794511 version:4.0.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/siege/siege.changes      2017-09-18 
19:55:06.781649587 +0200
+++ /work/SRC/openSUSE:Factory/.siege.new.2738/siege.changes    2020-04-16 
23:04:17.903730590 +0200
@@ -1,0 +2,7 @@
+Thu Apr 16 08:59:33 UTC 2020 - Martin Pluskal <[email protected]>
+
+- Update to version 4.0.5:
+  * -j/--json-output
+  * For full list of changes see attached ChangeLog
+
+-------------------------------------------------------------------

Old:
----
  siege-4.0.4.tar.gz

New:
----
  siege-4.0.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ siege.spec ++++++
--- /var/tmp/diff_new_pack.6YYYdA/_old  2020-04-16 23:04:18.351730988 +0200
+++ /var/tmp/diff_new_pack.6YYYdA/_new  2020-04-16 23:04:18.355730992 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package siege
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 # Copyright (c) 2012 Pascal Bleser <[email protected]>
 #
 # All modifications and additions to the file contributed by third parties
@@ -13,17 +13,17 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           siege
-Version:        4.0.4
+Version:        4.0.5
 Release:        0
 Summary:        HTTP Regression Testing/Benchmarking Utility
-License:        GPL-2.0+
+License:        GPL-2.0-or-later
 Group:          Productivity/Networking/Web/Utilities
-Url:            https://www.joedog.org/siege-home/
+URL:            https://www.joedog.org/siege-home/
 Source:         http://download.joedog.org/siege/siege-%{version}.tar.gz
 BuildRequires:  perl
 BuildRequires:  pkgconfig
@@ -53,7 +53,8 @@
 %make_install
 
 %files
-%doc AUTHORS ChangeLog COPYING README.md
+%license COPYING
+%doc AUTHORS ChangeLog README.md
 %dir %{_sysconfdir}/%{name}
 %config(noreplace) %{_sysconfdir}/%{name}/siegerc
 %config(noreplace) %{_sysconfdir}/%{name}/urls.txt

++++++ siege-4.0.4.tar.gz -> siege-4.0.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/ChangeLog new/siege-4.0.5/ChangeLog
--- old/siege-4.0.4/ChangeLog   2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/ChangeLog   2020-02-19 18:46:22.000000000 +0100
@@ -1,6 +1,47 @@
 To email a contributor remove "DELETE" from the email address.
 (The DELETEs are necessary as this list is published online.)
 
+2020/02/19 Jeffrey Fulmer http://www.joedog.org/support/
+ * src/version.c          Version increment: 4.0.5
+
+2020/02/10 Ben Baker-Smith <[email protected]>
+ * src/main.c             Added -j/--json-output 
+ * src/init.c             Added -j/--json-output - force quiet mode
+ * src/setup.h            Added variable for json output
+ * doc/siegerc.in         Added documentation to the config file
+
+2018/02/18 Benjamin Pearson <[email protected]>
+ * src/url.c              Adding DELETE and OPTIONS support.
+ * src/browser.c          Adding DELETE and OPTIONS support.
+
+2018/02/18 "Mr. Baileys" <[email protected]>
+ * src/http.c            Correct capitalization for Content-Type & 
Content-Length
+
+2018/02/18 root <[email protected]>
+ * src/response.c        Handle case of incorrect server response header
+
+2018/02/18 Viktor Szepe <[email protected]>
+ * README.md              Make readme's title nice
+
+2018/02/18 Michael McConville <[email protected]>
+ * src/page.c             Remove needless memset(2)
+
+2018/02/18 James Wang <https://github.com/wjn740>
+ * src/cookies.c          Bug fix - prevent segfault when getenv(HOME) is null
+
+2017/09/13 Jeffrey Fulmer http://www.joedog.org/support/
+ * src/load.c             Bug fix - allow content-type override at cmd line
+ * src/version.c          Version increment: 4.0.4r3
+
+2017/09/13 Florin Papa <https://github.com/florinpapa>
+ * src/url.c              Skipped URL escaping for the host and port 
+ * src/version.c          Version increment: 4.0.4r2
+
+2017/09/11 Florin Papa <https://github.com/florinpapa>
+ * src/sock.c             Added support for IPv6
+ * src/url.c              Added support for parsing IPv6 addresses
+ * src/version.c          Version increment: 4.0.4r1
+
 2017/09/05 Jeffrey Fulmer http://www.joedog.org/support/
  * src/perl.c             Added integrity checks
  * src/version.c          Version increment: 4.0.3rc6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/INSTALL new/siege-4.0.5/INSTALL
--- old/siege-4.0.4/INSTALL     2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/INSTALL     2020-02-19 18:42:11.000000000 +0100
@@ -171,7 +171,7 @@
     -r, --reps=NUM            REPS, number of times to run the test.
     -t, --time=NUMm           TIMED testing where "m" is modifier S, M, or H
                               ex: --time=1H, one hour test.
-    -d, --delay=NUM           Time DELAY, random delay before each requst
+    -d, --delay=NUM           Time DELAY, random delay before each request
     -b, --benchmark           BENCHMARK: no delays between requests.
     -i, --internet            INTERNET user simulation, hits URLs randomly.
     -f, --file=FILE           FILE, select a specific URLS FILE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/README.md new/siege-4.0.5/README.md
--- old/siege-4.0.4/README.md   2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/README.md   2020-02-19 18:42:11.000000000 +0100
@@ -1,5 +1,4 @@
-
-                       Siege README
+# Siege
 
 WHAT IS IT?
 -----------
@@ -140,5 +139,3 @@
 If you do  not wish  to do so,  delete this exception  statement 
 from your version. If you delete  this exception  statement from 
 all source files in the program, then also delete it here.  
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/configure new/siege-4.0.5/configure
--- old/siege-4.0.4/configure   2017-09-11 19:36:29.000000000 +0200
+++ new/siege-4.0.5/configure   2020-02-19 18:46:49.000000000 +0100
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for siege 4.0.4.
+# Generated by GNU Autoconf 2.68 for siege 4.0.5.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -711,8 +711,8 @@
 # Identity of this package.
 PACKAGE_NAME='siege'
 PACKAGE_TARNAME='siege'
-PACKAGE_VERSION='4.0.4'
-PACKAGE_STRING='siege 4.0.4'
+PACKAGE_VERSION='4.0.5'
+PACKAGE_STRING='siege 4.0.5'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1454,7 +1454,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures siege 4.0.4 to adapt to many kinds of systems.
+\`configure' configures siege 4.0.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1524,7 +1524,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of siege 4.0.4:";;
+     short | recursive ) echo "Configuration of siege 4.0.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1635,7 +1635,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-siege configure 4.0.4
+siege configure 4.0.5
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2259,7 +2259,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by siege $as_me 4.0.4, which was
+It was created by siege $as_me 4.0.5, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3083,7 +3083,7 @@
 
 # Define the identity of the package.
  PACKAGE='siege'
- VERSION='4.0.4'
+ VERSION='4.0.5'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -21932,7 +21932,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by siege $as_me 4.0.4, which was
+This file was extended by siege $as_me 4.0.5, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21998,7 +21998,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-siege config.status 4.0.4
+siege config.status 4.0.5
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/doc/bombardment.1.in 
new/siege-4.0.5/doc/bombardment.1.in
--- old/siege-4.0.4/doc/bombardment.1.in        2017-09-11 19:36:30.000000000 
+0200
+++ new/siege-4.0.5/doc/bombardment.1.in        2020-02-19 18:46:49.000000000 
+0100
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BOMBARDMENT 1"
-.TH BOMBARDMENT 1 "2017-09-11" "JoeDog" "bombardment"
+.TH BOMBARDMENT 1 "2020-02-19" "JoeDog" "bombardment"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/doc/siege.1.in 
new/siege-4.0.5/doc/siege.1.in
--- old/siege-4.0.4/doc/siege.1.in      2017-09-11 19:36:29.000000000 +0200
+++ new/siege-4.0.5/doc/siege.1.in      2020-02-19 18:46:49.000000000 +0100
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "SIEGE 1"
-.TH SIEGE 1 "2017-09-11" "JoeDog" "Siege Load Tester"
+.TH SIEGE 1 "2020-02-19" "JoeDog" "Siege Load Tester"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -143,14 +143,14 @@
 .IX Header "DESCRIPTION"
 \&\f(CW$_PROGRAM\fR is a multi-threaded \s-1HTTP/FTP\s0 load tester and 
benchmarking 
 utility. It supports most of the features detailed in RFCs 2616 (\s-1HTTP\s0)
-and 959 (\s-1FTP\s0). Properties can be set at both from the command line and
-in a configuration file. When the same propertie is set in both 
-locations, the command line takes precedent.
+and 959 (\s-1FTP\s0). Properties can be set both from the command line and in
+a configuration file. When the same property is set in both locations,
+the command line takes precedence.
 .PP
 The default configuration file is \f(CW$HOME\fR/.siege/siege.conf If you don't 
 have a \f(CW$HOME\fR/.siege directory and a siege.conf and cookies.txt file, 
 siege will generate a new config directory when it runs. You can 
-generate your configu directory with the following command: siege.config
+generate your config directory with the following command: siege.config
 .SH "OPTIONS"
 .IX Header "OPTIONS"
 .SS "Option Syntax"
@@ -173,8 +173,8 @@
 .IX Item "-C, --config"
 Prints a detailed summary of all the currently configured options, most
 of which are sent in \f(CW$HOME\fR/.siege/siege.conf
-.IP "\fB\-v\fR, \fB\-\-vebose\fR" 4
-.IX Item "-v, --vebose"
+.IP "\fB\-v\fR, \fB\-\-verbose\fR" 4
+.IX Item "-v, --verbose"
 This directive puts \f(CW$_PROGRAM\fR into verbose mode which is actually a 
 default setting. This command-line option is useful when the config 
 file is set to 'verbose = false' since it will allow you to override 
@@ -230,7 +230,7 @@
 \&  CF\-RAY: 27219407eeff084a\-IAD
 .Ve
 .Sp
-\&\s-1NOTE:\s0 It's best practice to quote the \s-1URL\s0 when it's passed to 
\f(CW$_PROGRAM\fR 
+\&\s-1NOTE:\s0 It's a best practice to quote the \s-1URL\s0 when it's passed 
to \f(CW$_PROGRAM\fR 
 from the the command-line.
 .IP "\fB\-p \s-1URL\s0\fR, \fB\-\-print=URL\fR" 4
 .IX Item "-p URL, --print=URL"
@@ -278,7 +278,7 @@
 then please don't complain to us.
 .IP "\fB\-r \s-1NUM\s0\fR, \fB\-\-reps=NUM|once\fR" 4
 .IX Item "-r NUM, --reps=NUM|once"
-This option tells each siege user how times it should run. The value 
+This option tells each siege user how many times it should run. The value 
 should generally be a number greater than zero but it may be the keyword
 \&'once'.
 .Sp
@@ -308,9 +308,9 @@
 .Sp
 The time between delay requests is \s-1NOT\s0 applied toward the transaction 
 time. If two 0.1 second transactions have a 2 second delay between them,
-their average transaction time is run is 0.1 seconds. It is applied 
-toward the total elapsed time. In this scenario, the elapsed time would 
-be 2.2 seconds.
+their average transaction time is 0.1 seconds. It is applied toward the
+total elapsed time. In this scenario, the elapsed time would be 2.2 
+seconds.
 .Sp
 \&\s-1NOTE:\s0 when the parser is enabled (see: \-p/\-\-parser), there is no 
delay
 between the page and its elements, i.e., style sheets, javascripts, etc. 
@@ -339,7 +339,7 @@
 .IP "\fB\-L \s-1FILE\s0\fR, \fB\-\-log=FILE\fR" 4
 .IX Item "-L FILE, --log=FILE"
 The default log file is \f(CW$prefix\fR/var/log/siege.log. This directive 
-allows you to specify and alternative file for logging.
+allows you to specify an alternative file for logging.
 .ie n .IP "\fB\-m ""string""\fR, \fB\-\-mark=""string""\fR" 4
 .el .IP "\fB\-m ``string''\fR, \fB\-\-mark=``string''\fR" 4
 .IX Item "-m string, --mark=string"
@@ -352,7 +352,7 @@
 .el .IP "\fB\-H ``header: value''\fR, \fB\-\-header=``Header: value''\fR" 4
 .IX Item "-H header: value, --header=Header: value"
 This options allows you to set a custom header in the request. 
-Generally speaking, this request will override an existing header. The
+Generally speaking, this header will override an existing header. The
 Cookie header is a special case.  If you set \-H \*(L"Cookie: value\*(R" then 
 siege will send that cookie in addition to the other ones.
 .ie n .IP "\fB\-A ""string""\fR, \fB\-\-agent=""string""\fR" 4
@@ -396,14 +396,14 @@
 An \s-1RFC\s0 1738 \s-1URL\s0 looks like this:
   
<scheme>://<username>:<password>@<hostname>:<port>/<path>;<params>?<query>#<frag>
 .PP
-A \f(CW$_PROGRAM\fR \s-1URL\s0 with a method idicator looks like this:
+A \f(CW$_PROGRAM\fR \s-1URL\s0 with a method indicator looks like this:
   <scheme>://<username>:<password>@<hostname>:<port>/<path> \s-1POST\s0 <query>
 .PP
 You can also post the contents of a file using the redirect character
 like this:
   <scheme>://<username>:<password>@<hostname>:<port>/<path> \s-1POST\s0 
</home/jeff/haha.txt
 .PP
-Here's two examples with the \f(CW$_PROGRAM\fR method indicator:
+Here are two examples with the \f(CW$_PROGRAM\fR method indicator:
   http://www.joedog.org/ \s-1POST\s0 haha=papa&dada=mama
   ftp://ftp.armstrong.com/ \s-1PUT\s0 </home/jdfulmer/etc/tests/bbc.jpg
 .PP
@@ -440,7 +440,7 @@
 .PP
 It supports shell-style variable declaration and references. This is 
 convenient if you want to run the same test on two different tiers or
-two different shemes:
+two different schemes:
 .PP
 .Vb 5
 \&  SCHEME=https
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/doc/siege.config.1.in 
new/siege-4.0.5/doc/siege.config.1.in
--- old/siege-4.0.4/doc/siege.config.1.in       2017-09-11 19:36:30.000000000 
+0200
+++ new/siege-4.0.5/doc/siege.config.1.in       2020-02-19 18:46:49.000000000 
+0100
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "SIEGE.CONFIG 1"
-.TH SIEGE.CONFIG 1 "2017-09-11" "JoeDog" "siege.config utility"
+.TH SIEGE.CONFIG 1 "2020-02-19" "JoeDog" "siege.config utility"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/doc/siege.pod 
new/siege-4.0.5/doc/siege.pod
--- old/siege-4.0.4/doc/siege.pod       2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/doc/siege.pod       2020-02-19 18:42:11.000000000 +0100
@@ -15,14 +15,14 @@
 
 $_PROGRAM is a multi-threaded HTTP/FTP load tester and benchmarking 
 utility. It supports most of the features detailed in RFCs 2616 (HTTP)
-and 959 (FTP). Properties can be set at both from the command line and
-in a configuration file. When the same propertie is set in both 
-locations, the command line takes precedent.
+and 959 (FTP). Properties can be set both from the command line and in
+a configuration file. When the same property is set in both locations,
+the command line takes precedence.
 
 The default configuration file is $HOME/.siege/siege.conf If you don't 
 have a $HOME/.siege directory and a siege.conf and cookies.txt file, 
 siege will generate a new config directory when it runs. You can 
-generate your configu directory with the following command: siege.config
+generate your config directory with the following command: siege.config
 
 =head1 OPTIONS
 
@@ -52,7 +52,7 @@
 Prints a detailed summary of all the currently configured options, most
 of which are sent in $HOME/.siege/siege.conf
 
-=item B<-v>, B<--vebose>
+=item B<-v>, B<--verbose>
 
 This directive puts $_PROGRAM into verbose mode which is actually a 
 default setting. This command-line option is useful when the config 
@@ -107,7 +107,7 @@
   Vary: Accept-Encoding,Cookie
   CF-RAY: 27219407eeff084a-IAD
 
-NOTE: It's best practice to quote the URL when it's passed to $_PROGRAM 
+NOTE: It's a best practice to quote the URL when it's passed to $_PROGRAM 
 from the the command-line.
 
 =item B<-p URL>, B<--print=URL>
@@ -156,7 +156,7 @@
 
 =item B<-r NUM>, B<--reps=NUM|once>
 
-This option tells each siege user how times it should run. The value 
+This option tells each siege user how many times it should run. The value 
 should generally be a number greater than zero but it may be the keyword
 'once'.
 
@@ -188,9 +188,9 @@
 
 The time between delay requests is NOT applied toward the transaction 
 time. If two 0.1 second transactions have a 2 second delay between them,
-their average transaction time is run is 0.1 seconds. It is applied 
-toward the total elapsed time. In this scenario, the elapsed time would 
-be 2.2 seconds.
+their average transaction time is 0.1 seconds. It is applied toward the
+total elapsed time. In this scenario, the elapsed time would be 2.2 
+seconds.
 
 NOTE: when the parser is enabled (see: -p/--parser), there is no delay
 between the page and its elements, i.e., style sheets, javascripts, etc. 
@@ -224,7 +224,7 @@
 =item B<-L FILE>, B<--log=FILE>
 
 The default log file is $prefix/var/log/siege.log. This directive 
-allows you to specify and alternative file for logging.
+allows you to specify an alternative file for logging.
 
 =item B<-m "string">, B<--mark="string">
 
@@ -237,7 +237,7 @@
 =item B<-H "header: value">, B<--header="Header: value">
 
 This options allows you to set a custom header in the request. 
-Generally speaking, this request will override an existing header. The
+Generally speaking, this header will override an existing header. The
 Cookie header is a special case.  If you set -H "Cookie: value" then 
 siege will send that cookie in addition to the other ones.
 
@@ -282,14 +282,14 @@
 An RFC 1738 URL looks like this:
   
<scheme>://<username>:<password>@<hostname>:<port>/<path>;<params>?<query>#<frag>
 
-A $_PROGRAM URL with a method idicator looks like this:
+A $_PROGRAM URL with a method indicator looks like this:
   <scheme>://<username>:<password>@<hostname>:<port>/<path> POST <query>
 
 You can also post the contents of a file using the redirect character
 like this:
   <scheme>://<username>:<password>@<hostname>:<port>/<path> POST 
</home/jeff/haha.txt
 
-Here's two examples with the $_PROGRAM method indicator:
+Here are two examples with the $_PROGRAM method indicator:
   http://www.joedog.org/ POST haha=papa&dada=mama
   ftp://ftp.armstrong.com/ PUT </home/jdfulmer/etc/tests/bbc.jpg
 
@@ -327,7 +327,7 @@
 
 It supports shell-style variable declaration and references. This is 
 convenient if you want to run the same test on two different tiers or
-two different shemes:
+two different schemes:
 
   SCHEME=https
   HOST=bart.joedog.org
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/doc/siege2csv.1.in 
new/siege-4.0.5/doc/siege2csv.1.in
--- old/siege-4.0.4/doc/siege2csv.1.in  2017-09-11 19:36:30.000000000 +0200
+++ new/siege-4.0.5/doc/siege2csv.1.in  2020-02-19 18:46:49.000000000 +0100
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BOMBARDMENT 1"
-.TH BOMBARDMENT 1 "2017-09-11" "JoeDog" "siege2csv"
+.TH BOMBARDMENT 1 "2020-02-19" "JoeDog" "siege2csv"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/doc/siegerc.in 
new/siege-4.0.5/doc/siegerc.in
--- old/siege-4.0.4/doc/siegerc.in      2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/doc/siegerc.in      2020-02-19 18:42:11.000000000 +0100
@@ -35,7 +35,6 @@
 # 
 color = on
 
-
 #
 # Quiet mode: With this featured enabled, siege goes mostly silent.
 # It will display the opening message and the final stats but nothing
@@ -61,6 +60,17 @@
 quiet = false
 
 #
+# JSON output - With this feature enabled, siege will print the final stats as
+# JSON to stdout. It monopolizes stdout, superceding verbose and debug modes.
+#
+# The default value is false.
+#
+# ex: json_output = true | false
+#
+json_output = true
+
+
+#
 # Show logfile location. By default, siege displays the logfile 
 # location at the end of every run when logging. You can turn this
 # message off with this directive.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/browser.c 
new/siege-4.0.5/src/browser.c
--- old/siege-4.0.4/src/browser.c       2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/browser.c       2020-02-19 18:42:11.000000000 +0100
@@ -470,7 +470,8 @@
   /**
    * write to socket with a GET/POST/PUT/DELETE/HEAD
    */
-  if (url_get_method(U) == POST || url_get_method(U) == PUT || 
url_get_method(U) == PATCH) {
+  if (url_get_method(U) == POST   || url_get_method(U) == PUT || 
url_get_method(U) == PATCH || 
+      url_get_method(U) == DELETE || url_get_method(U) == OPTIONS) {
     if ((http_post(this->conn, U)) == FALSE) {
       this->conn->connection.reuse = 0;
       socket_close(this->conn);
@@ -622,7 +623,9 @@
           url_set_conttype(redirect_url,url_get_conttype(U));
           url_set_method(redirect_url, url_get_method(U));
 
-          if (url_get_method(redirect_url) == POST || 
url_get_method(redirect_url) == PUT || url_get_method(redirect_url) == PATCH) {
+          if (url_get_method(redirect_url) == POST  || 
url_get_method(redirect_url) == PUT || 
+              url_get_method(redirect_url) == PATCH || url_get_method(U) == 
DELETE         || 
+              url_get_method(U) == OPTIONS) {
             url_set_postdata(redirect_url, url_get_postdata(U), 
url_get_postlen(U));
           }
         }
@@ -664,6 +667,7 @@
           this->auth.type.www =  BASIC;
           auth_set_basic_header(my.auth, HTTP, 
response_get_www_auth_realm(resp));
         }
+        printf("%s %d\n", url_get_absolute(U), url_get_method(U));
         if ((__request(this, U)) == FALSE) {
           fprintf(stderr, "ERROR from http_request\n");
           return FALSE;
@@ -797,7 +801,8 @@
       return FALSE;
     }
   }
-  if (url_get_method(U) == POST || url_get_method(U) == PUT || 
url_get_method(U) == PATCH) {
+  if (url_get_method(U) == POST   || url_get_method(U) == PUT || 
url_get_method(U) == PATCH || 
+      url_get_method(U) == DELETE || url_get_method(U) == OPTIONS) {
     ftp_stor(this->conn, U);
     bytes = ftp_put(D, U);
     code  = this->conn->ftp.code;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/cookies.c 
new/siege-4.0.5/src/cookies.c
--- old/siege-4.0.4/src/cookies.c       2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/cookies.c       2020-02-19 18:42:11.000000000 +0100
@@ -39,7 +39,9 @@
   if (pthread_mutex_init( &(this->mutex), NULL) != 0) {
     NOTIFY(FATAL, "cookies: pthread_mutex_init");
   } 
-  int len    = strlen(getenv("HOME")) + 20;
+  int len;
+  char *p = getenv("HOME");
+  len = p ? strlen(p) : 20;
   this->file = malloc(sizeof (char*) * len);
   memset(this->file, '\0', len);
   snprintf(this->file, len, "%s/.siege/cookies.txt", getenv("HOME"));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/handler.c 
new/siege-4.0.5/src/handler.c
--- old/siege-4.0.4/src/handler.c       2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/handler.c       2020-02-19 18:42:11.000000000 +0100
@@ -70,7 +70,9 @@
    */
   sigwait(&sigs, &gotsig);
   my.verbose = FALSE;
-  fprintf(stderr, "\nLifting the server siege..."); 
+  if (!my.quiet) {
+    fprintf(stderr, "\nLifting the server siege...");
+  }
   crew_cancel(crew);
 
   /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/http.c new/siege-4.0.5/src/http.c
--- old/siege-4.0.4/src/http.c  2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/http.c  2020-02-19 18:42:11.000000000 +0100
@@ -394,8 +394,8 @@
     "%s"
     "User-Agent: %s\015\012%s"
     "Connection: %s\015\012"
-    "Content-type: %s\015\012"
-    "Content-length: %ld\015\012\015\012",
+    "Content-Type: %s\015\012"
+    "Content-Length: %ld\015\012\015\012",
     url_get_method_name(U), fullpath, protocol, hoststr,
     (C->auth.www==TRUE)?authwww:"",
     (C->auth.proxy==TRUE)?authpxy:"",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/init.c new/siege-4.0.5/src/init.c
--- old/siege-4.0.4/src/init.c  2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/init.c  2020-02-19 18:42:11.000000000 +0100
@@ -119,6 +119,7 @@
   my.timestamp      = FALSE;
   my.chunked        = FALSE;
   my.unique         = TRUE;
+  my.json_output    = FALSE;
   my.extra[0]       = 0;
   my.follow         = TRUE;
   my.zero_ok        = TRUE; 
@@ -237,6 +238,7 @@
   printf("allow zero byte data:           %s\n", my.zero_ok?"true":"false"); 
   printf("allow chunked encoding:         %s\n", my.chunked?"true":"false"); 
   printf("upload unique files:            %s\n", my.unique?"true":"false"); 
+  printf("json output:                    %s\n", 
my.json_output?"true":"false");
   if (my.parser == TRUE && my.nomap->index > 0) {
     int i;
     printf("no-follow:\n"); 
@@ -244,8 +246,8 @@
       printf(" - %s\n", my.nomap->line[i]);
     } 
   }
-  //printf("proxy auth:                     " ); 
display_authorization(PROXY);printf("\n");
-  //printf("www auth:                       " ); display_authorization(WWW); 
+  printf("proxy auth:                     " ); auth_display(my.auth, 
PROXY);printf("\n");
+  printf("www auth:                       " ); auth_display(my.auth, HTTP); 
   printf("\n");
 
   xfree(method);
@@ -586,6 +588,12 @@
       else
         my.unique = FALSE;  
     }
+    else if (strmatch(option, "json_output")) {
+      if (!strncasecmp(value, "true", 4))
+        my.json_output = TRUE;
+      else
+        my.json_output = FALSE;
+    }
     else if (strmatch(option, "header")) {
       if (!strchr(value,':')) NOTIFY(FATAL, "no ':' in http-header");
       if ((strlen(value) + strlen(my.extra) + 3) > 512) NOTIFY(FATAL, "too 
many headers");
@@ -679,8 +687,12 @@
     my.logging = FALSE;
     my.bench   = TRUE;
   }
-  
-  if (my.quiet) { 
+
+  if (my.json_output) {
+    my.quiet = TRUE;
+  }
+
+  if (my.quiet) {
     my.verbose = FALSE; // Why would you set quiet and verbose???
     my.debug   = FALSE; // why would you set quiet and debug?????
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/load.c new/siege-4.0.5/src/load.c
--- old/siege-4.0.4/src/load.c  2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/load.c  2020-02-19 18:42:11.000000000 +0100
@@ -140,6 +140,7 @@
   {"ppt",     FALSE, "application/mspowerpoint"},
   {"ppz",     FALSE, "application/mspowerpoint"},
   {"pre",     FALSE, "application/x-freelance"},
+  {"proto",   FALSE, "application/x-protobuf"},
   {"prt",     FALSE, "application/pro_eng"},
   {"ps",      FALSE, "application/postscript"},
   {"qt",      FALSE, "video/quicktime"},
@@ -268,7 +269,6 @@
   filename = trim(file);
 
   memset(mode, '\0', sizeof(mode));
-  printf("IS ASCII: %s\n", is_ascii(filename) ? "TRUE" : "FALSE");
   snprintf(mode, sizeof(mode), "%s", (is_ascii(filename))?"r":"rb");
   fp = fopen(filename, mode);
   if (! fp) {
@@ -293,7 +293,12 @@
   fclose(fp); 
 
   if (len > 0) {
-    url_set_conttype(U, get_content_type(filename));
+    if (! empty(my.conttype)) {
+      // We're overriding the content-type at the cmd line
+      url_set_conttype(U, my.conttype);
+    } else {
+      url_set_conttype(U, get_content_type(filename));
+    }
     url_set_postdata(U, buf, len);
   } 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/main.c new/siege-4.0.5/src/main.c
--- old/siege-4.0.4/src/main.c  2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/main.c  2020-02-19 18:42:11.000000000 +0100
@@ -83,7 +83,8 @@
   { "header",       required_argument, NULL, 'H' },
   { "user-agent",   required_argument, NULL, 'A' },
   { "content-type", required_argument, NULL, 'T' },
-  {0, 0, 0, 0} 
+  { "json-output",  no_argument,       NULL, 'j' },
+  {0, 0, 0, 0}
 };
 
 /**
@@ -145,7 +146,7 @@
   puts("  -r, --reps=NUM            REPS, number of times to run the test." );
   puts("  -t, --time=NUMm           TIMED testing where \"m\" is modifier S, 
M, or H");
   puts("                            ex: --time=1H, one hour test." );
-  puts("  -d, --delay=NUM           Time DELAY, random delay before each 
requst");
+  puts("  -d, --delay=NUM           Time DELAY, random delay before each 
request");
   puts("  -b, --benchmark           BENCHMARK: no delays between requests." );
   puts("  -i, --internet            INTERNET user simulation, hits URLs 
randomly.");
   puts("  -f, --file=FILE           FILE, select a specific URLS FILE." );
@@ -157,6 +158,7 @@
   puts("  -H, --header=\"text\"       Add a header to request (can be many)" 
); 
   puts("  -A, --user-agent=\"text\"   Sets User-Agent in request" ); 
   puts("  -T, --content-type=\"text\" Sets Content-Type in request" ); 
+  puts("  -j, --json-output         JSON OUTPUT, print final stats to stdout 
as JSON");
   puts("      --no-parser           NO PARSER, turn off the HTML page parser");
   puts("      --no-follow           NO FOLLOW, do not follow HTTP redirects");
   puts("");
@@ -179,7 +181,7 @@
   strcpy(my.rc, "");
   
   while( a > -1 ){
-    a = getopt_long(argc, argv, "VhvqCDNFpgl::ibr:t:f:d:c:m:H:R:A:T:", 
long_options, (int*)0);
+    a = getopt_long(argc, argv, "VhvqCDNFpgl::ibr:t:f:d:c:m:H:R:A:T:j", 
long_options, (int*)0);
     if(a == 'R'){
       strcpy(my.rc, optarg);
       a = -1;
@@ -198,7 +200,7 @@
 {
   int c = 0;
   int nargs;
-  while ((c = getopt_long(argc, argv, "VhvqCDNFpgl::ibr:t:f:d:c:m:H:R:A:T:", 
long_options, (int *)0)) != EOF) {
+  while ((c = getopt_long(argc, argv, "VhvqCDNFpgl::ibr:t:f:d:c:m:H:R:A:T:j", 
long_options, (int *)0)) != EOF) {
   switch (c) {
       case 'V':
         display_version(TRUE);
@@ -295,7 +297,10 @@
           strcat(my.extra,optarg);
           strcat(my.extra,"\015\012");
         }
-        break; 
+        break;
+      case 'j':
+        my.json_output = TRUE;
+        break;
 
     } /* end of switch( c )           */
   }   /* end of while c = getopt_long */
@@ -542,6 +547,38 @@
     fprintf(stderr, "Shortest transaction:\t%12.2f\n",       
data_get_lowest(data));
     fprintf(stderr, " \n");
   }
+
+  if (my.json_output) {
+    fprintf(stderr, "\n");
+    printf("{");
+    printf("\t\"transactions\":\t\t\t%12u,\n", data_get_count(data));
+
+    double availability;
+    if (data_get_count(data) == 0) {
+      availability = 0;
+    } else {
+      availability = (double)data_get_count(data) / (data_get_count(data) + 
my.failed) * 100;
+    }
+
+    printf("\t\"availability\":\t\t\t%12.2f,\n", availability);
+    printf("\t\"elapsed_time\":\t\t\t%12.2f,\n", data_get_elapsed(data));
+    printf("\t\"data_transferred\":\t\t%12.2f,\n", data_get_megabytes(data)); 
/*%12llu*/
+    printf("\t\"response_time\":\t\t%12.2f,\n", data_get_response_time(data));
+    printf("\t\"transaction_rate\":\t\t%12.2f,\n", 
data_get_transaction_rate(data));
+    printf("\t\"throughput\":\t\t\t%12.2f,\n", data_get_throughput(data));
+    printf("\t\"concurrency\":\t\t\t%12.2f,\n", data_get_concurrency(data));
+    printf("\t\"successful_transactions\":\t%12u,\n", data_get_code(data));
+
+    if (my.debug) {
+      printf("\t\"http_ok_received\":\t\t%12u,\n", data_get_okay(data));
+    }
+
+    printf("\t\"failed_transactions\":\t\t%12u,\n", my.failed);
+    printf("\t\"longest_transaction\":\t\t%12.2f,\n", data_get_highest(data));
+    printf("\t\"shortest_transaction\":\t\t%12.2f\n", data_get_lowest(data));
+    puts("}");
+  }
+
   if (my.mark)    mark_log_file(my.markstr);
   if (my.logging) {
     log_transaction(data);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/page.c new/siege-4.0.5/src/page.c
--- old/siege-4.0.4/src/page.c  2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/page.c  2020-02-19 18:42:11.000000000 +0100
@@ -23,7 +23,6 @@
   this->len  = strlen(str);
   this->size = this->len + 24576;
   this->buf = calloc(1,   this->size);
-  memset(this->buf, '\0', this->size);
   memcpy(this->buf,  str, this->len);
  
   return this;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/response.c 
new/siege-4.0.5/src/response.c
--- old/siege-4.0.4/src/response.c      2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/response.c      2020-02-19 18:42:11.000000000 +0100
@@ -173,8 +173,10 @@
   if (strstr(line, ";") != NULL) {
     ptr  = line+(strlen(CONTENT_TYPE)+2);
     type = strtok_r(ptr, ";", &aid);
-    hash_add(this->headers, CONTENT_TYPE, type);
-    res = TRUE;
+    if (type != NULL) {
+      hash_add(this->headers, CONTENT_TYPE, type);
+      res = TRUE;
+    }
 
     /** 
      * We found a ';', do we have a charset?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/setup.h new/siege-4.0.5/src/setup.h
--- old/siege-4.0.4/src/setup.h 2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/setup.h 2020-02-19 18:42:11.000000000 +0100
@@ -217,6 +217,7 @@
   char    *ssl_key;     /* PEM private key file for client auth    */
   char    *ssl_ciphers; /* SSL chiphers to use : delimited         */ 
   METHOD  method;       /* HTTP method for --get requests          */
+  BOOLEAN json_output;  /* boolean, TRUE == print stats in json    */
   pthread_cond_t  cond;
   pthread_mutex_t lock;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/sock.c new/siege-4.0.5/src/sock.c
--- old/siege-4.0.4/src/sock.c  2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/sock.c  2020-02-19 18:42:11.000000000 +0100
@@ -62,6 +62,8 @@
 # include <openssl/rand.h>
 #endif/*HAVE_SSL*/
 
+#define MAX_PORT_NO 65535
+
 /** 
  * local prototypes 
  */
@@ -69,6 +71,8 @@
 private ssize_t __socket_write(int sock, const void *vbuf, size_t len);  
 private BOOLEAN __socket_check(CONN *C, SDSET mode);
 private BOOLEAN __socket_select(CONN *C, SDSET mode);
+private int     __socket_create(CONN *C, int domain);
+private void   __hostname_strip(char *hn, int len);
 #ifdef  HAVE_POLL
 private BOOLEAN __socket_poll(CONN *C, SDSET mode);
 #endif/*HAVE_POLL*/
@@ -85,16 +89,22 @@
 {
   int conn;
   int res;
-  int opt;
-  int herrno;
-  struct sockaddr_in cli; 
-  struct hostent     *hp;
+  int addrlen;
+  struct sockaddr *s_addr;
   char   hn[512];
   int    port;
+  int    domain;
 #if defined(__GLIBC__)
-  struct hostent hent;
-  char hbf[8192];
-#elif defined(sun)
+  char port_str[10];
+  struct addrinfo hints;
+  struct addrinfo *addr_res;
+  struct addrinfo *r;
+#else
+  struct sockaddr_in cli;
+  struct hostent     *hp;
+  int herrno;
+#endif
+#if defined(sun)
 # ifndef HAVE_GETIPNODEBYNAME
   struct hostent hent;
   char hbf[8192];
@@ -125,29 +135,33 @@
     snprintf(hn, sizeof(hn), "%s", hostparam);
     port = portparam;
   }
+  __hostname_strip(hn, 512);
 
-  /* create a socket, return -1 on failure */
-  if ((C->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-    switch (errno) {
-      case EPROTONOSUPPORT: { NOTIFY(ERROR, "unsupported protocol %s:%d",  
__FILE__, __LINE__); break; }
-      case EMFILE:          { NOTIFY(ERROR, "descriptor table full %s:%d", 
__FILE__, __LINE__); break; }
-      case ENFILE:          { NOTIFY(ERROR, "file table full %s:%d",       
__FILE__, __LINE__); break; }
-      case EACCES:          { NOTIFY(ERROR, "permission denied %s:%d",     
__FILE__, __LINE__); break; }
-      case ENOBUFS:         { NOTIFY(ERROR, "insufficient buffer %s:%d",   
__FILE__, __LINE__); break; }
-      default:              { NOTIFY(ERROR, "unknown socket error %s:%d",  
__FILE__, __LINE__); break; }
-    } socket_close(C); return -1;
-  }
-  if (fcntl(C->sock, F_SETFD, O_NDELAY) < 0) {
-    NOTIFY(ERROR, "unable to set close control %s:%d", __FILE__, __LINE__);
+  /* sanity check */
+  if (port < 1 || port > MAX_PORT_NO) {
+    NOTIFY(ERROR, "invalid port number %d in %s:%d", port, __FILE__, __LINE__);
+    return -1;
   }
 
 #if defined(__GLIBC__)
   {
-    memset(hbf, '\0', sizeof hbf);
-    /* for systems using GNU libc */
-    if ((gethostbyname_r(hostparam, &hent, hbf, sizeof(hbf), &hp, &herrno) < 
0)) {
-      hp = NULL;
+    snprintf(port_str, sizeof(port_str), "%d", port);
+
+    /* hints for address lookup */
+    memset(&hints, 0, sizeof(struct addrinfo));
+    hints.ai_family=AF_UNSPEC;
+    hints.ai_socktype=SOCK_STREAM;
+    hints.ai_protocol=IPPROTO_TCP;
+
+    res = getaddrinfo(hn, port_str, &hints, &addr_res);
+    if (res != 0) {
+      NOTIFY(ERROR, "Address resolution failed at %s:%d with the following 
error:", __FILE__, __LINE__);
+      NOTIFY(ERROR, "%s", gai_strerror(res));
+      return -1;
     }
+    s_addr = addr_res->ai_addr;
+    addrlen = addr_res->ai_addrlen;
+    domain = addr_res->ai_family;
   }
 #elif defined(sun)
 # ifdef HAVE_GETIPNODEBYNAME
@@ -174,6 +188,10 @@
   herrno = h_errno;
 #endif/*OS SPECIFICS*/ 
 
+#if !defined(__GLIBC__)
+  /* gethostbyname only offers IPv4 support */
+  domain = AF_INET;
+
   /**
    * If hp is NULL, then we did not get good information
    * from the name server. Let's notify the user and bail
@@ -199,22 +217,13 @@
   cli.sin_family = AF_INET;
   cli.sin_port = htons(port);
 
-  if (C->connection.keepalive) {
-    opt = 1; 
-    if (setsockopt(C->sock,SOL_SOCKET,SO_KEEPALIVE,(char 
*)&opt,sizeof(opt))<0) {
-      switch (errno) {
-        case EBADF:       { NOTIFY(ERROR, "invalid descriptor %s:%d",    
__FILE__, __LINE__); break; }
-        case ENOTSOCK:    { NOTIFY(ERROR, "not a socket %s:%d",          
__FILE__, __LINE__); break; }
-        case ENOPROTOOPT: { NOTIFY(ERROR, "not a protocol option %s:%d", 
__FILE__, __LINE__); break; }
-        case EFAULT:      { NOTIFY(ERROR, "setsockopt unknown %s:%d",    
__FILE__, __LINE__); break; }
-        default:          { NOTIFY(ERROR, "unknown sockopt error %s:%d", 
__FILE__, __LINE__); break; }
-      } socket_close(C); return -1;
-    }
-  }
+  s_addr = (struct sockaddr *)&cli;
+  addrlen = sizeof(struct sockaddr_in);
+#endif /* end of __GLIBC__ not defined */
 
-  if ((__socket_block(C->sock, FALSE)) < 0) {
-    NOTIFY(ERROR, "socket: unable to set socket to non-blocking %s:%d", 
__FILE__, __LINE__);
-    return -1; 
+  /* create a socket, return -1 on failure */
+  if (__socket_create(C, domain) < 0) {
+    return -1;
   }
 
   /**
@@ -222,8 +231,32 @@
    * evaluate the server response and check for
    * readability/writeability of the socket....
    */ 
-  conn = connect(C->sock, (struct sockaddr *)&cli, sizeof(struct sockaddr_in));
+  conn = connect(C->sock, s_addr, addrlen);
   pthread_testcancel();
+#if defined(__GLIBC__)
+  /**
+    * The result of getaddrinfo is a linked list. Attempt
+    * to connect to each result until successful
+    */
+  if (conn < 0 && errno != EINPROGRESS) {
+    addr_res = addr_res->ai_next;
+    for (r = addr_res; r; r = r->ai_next) {
+      /* close previously opened socket */
+      socket_close(C);
+
+      /* create a socket, return -1 on failure */
+      if (__socket_create(C, domain) < 0) {
+        return -1;
+      }
+
+      conn = connect(C->sock, s_addr, addrlen);
+      pthread_testcancel();
+      if (conn == 0) {
+        break;
+      }
+    }
+  }
+#endif
   if (conn < 0 && errno != EINPROGRESS) {
     switch (errno) {
       case EACCES:        {NOTIFY(ERROR, "socket: %d EACCES",                  
pthread_self()); break;}
@@ -244,7 +277,7 @@
       /**
        * If we reconnect and receive EISCONN, then we have a successful 
connection
        */
-      res = connect(C->sock, (struct sockaddr *)&cli, sizeof(struct 
sockaddr_in)); 
+      res = connect(C->sock, s_addr, addrlen);
       if((res < 0)&&(errno != EISCONN)){
         NOTIFY(ERROR, "socket: unable to connect %s:%d", __FILE__, __LINE__);
         socket_close(C);
@@ -356,6 +389,69 @@
   }
 }
 
+/**
+ * Create new socket and set socket options.
+ * Handle possible error codes.
+ */
+private int
+__socket_create(CONN *C, int domain)
+{
+  if ((C->sock = socket(domain, SOCK_STREAM, 0)) < 0) {
+    switch (errno) {
+      case EPROTONOSUPPORT: { NOTIFY(ERROR, "unsupported protocol %s:%d",  
__FILE__, __LINE__); break; }
+      case EMFILE:          { NOTIFY(ERROR, "descriptor table full %s:%d", 
__FILE__, __LINE__); break; }
+      case ENFILE:          { NOTIFY(ERROR, "file table full %s:%d",       
__FILE__, __LINE__); break; }
+      case EACCES:          { NOTIFY(ERROR, "permission denied %s:%d",     
__FILE__, __LINE__); break; }
+      case ENOBUFS:         { NOTIFY(ERROR, "insufficient buffer %s:%d",   
__FILE__, __LINE__); break; }
+      default:              { NOTIFY(ERROR, "unknown socket error %s:%d",  
__FILE__, __LINE__); break; }
+    } socket_close(C); return -1;
+  }
+  if (fcntl(C->sock, F_SETFD, O_NDELAY) < 0) {
+    NOTIFY(ERROR, "unable to set close control %s:%d", __FILE__, __LINE__);
+  }
+
+  if (C->connection.keepalive) {
+    int opt = 1;
+    if (setsockopt(C->sock,SOL_SOCKET,SO_KEEPALIVE,(char 
*)&opt,sizeof(opt))<0) {
+      switch (errno) {
+        case EBADF:       { NOTIFY(ERROR, "invalid descriptor %s:%d",    
__FILE__, __LINE__); break; }
+        case ENOTSOCK:    { NOTIFY(ERROR, "not a socket %s:%d",          
__FILE__, __LINE__); break; }
+        case ENOPROTOOPT: { NOTIFY(ERROR, "not a protocol option %s:%d", 
__FILE__, __LINE__); break; }
+        case EFAULT:      { NOTIFY(ERROR, "setsockopt unknown %s:%d",    
__FILE__, __LINE__); break; }
+        default:          { NOTIFY(ERROR, "unknown sockopt error %s:%d", 
__FILE__, __LINE__); break; }
+      } socket_close(C); return -1;
+    }
+  }
+
+  if ((__socket_block(C->sock, FALSE)) < 0) {
+    NOTIFY(ERROR, "socket: unable to set socket to non-blocking %s:%d", 
__FILE__, __LINE__);
+    return -1;
+  }
+
+  return 0;
+}
+
+/**
+ * remove square bracket
+ * around IPv6 addresses
+ */
+private void
+__hostname_strip(char *hn, int len)
+{
+  int i;
+
+  if (startswith("[", hn)) {
+    memmove(hn, hn + 1, len - 1);
+
+    /* skip to matching square bracket */
+    for (i = 0; hn[i] && hn[i] != ']'; i++);
+
+    if (hn[i] == ']') {
+      memmove(hn + i, hn + i + 1, len - i - 1);
+    }
+  }
+}
+
 /**
  * local function
  * set socket to non-blocking
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/url.c new/siege-4.0.5/src/url.c
--- old/siege-4.0.4/src/url.c   2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/url.c   2020-02-19 18:42:11.000000000 +0100
@@ -379,6 +379,8 @@
       return "PUT";
     case DELETE:
       return "DELETE";
+    case OPTIONS:
+      return "OPTIONS";
     case HEAD:
      return "HEAD";
     case GET:
@@ -581,6 +583,14 @@
   if (! post) {
     post = strstr(this->url, " PATCH");
   }
+       
+  if (! post) {
+    post = strstr(this->url, " OPTIONS");
+  }
+       
+  if (! post) {
+    post = strstr(this->url, " DELETE");
+  }
 
   if (post != NULL){
     if (!strncasecmp(post," PUT", 4)) {
@@ -591,6 +601,14 @@
       this->method = POST;
       *post = '\0';
       post += 5;
+    } else if (!strncasecmp(post," DELETE", 7)) {
+      this->method = DELETE;
+      *post = '\0';
+      post += 7;
+    } else if (!strncasecmp(post," OPTIONS", 8)) {
+      this->method = OPTIONS;
+      *post = '\0';
+      post += 8;
     } else {
       this->method = PATCH;
       *post = '\0';
@@ -847,8 +865,22 @@
     memmove(str, str+n, len - n + 1);
   }
 
-  /* skip to end, slash, or port colon */
-  for (i = 0; str[i] && str[i] != '/' && str[i] != '#' && str[i] != ':'; i++);
+  /**
+   * Check for IPv6 address. The convention here is to use square brackets
+   * around the IPv6 address in order to have a clear delimitation between
+   * address and port
+   */
+  if (startswith("[", str)) {
+    /* skip to matching square bracket */
+    for (i = 0; str[i] && str[i] != ']'; i++);
+
+    if (str[i] == ']') {
+      i++;
+    }
+  } else {
+    /* skip to end, slash, or port colon */
+    for (i = 0; str[i] && str[i] != '/' && str[i] != '#' && str[i] != ':'; 
i++);
+  }
 
   this->hostname = xmalloc(i + 1);
   memset(this->hostname, '\0', i+1);
@@ -1162,7 +1194,8 @@
 {
   const char *p1;
   char *newstr, *p2;
-  int oldlen, newlen;
+  int oldlen, newlen, host_len;
+  char *path_start, *host_start;
 
   int encode_count = 0;
   int decode_count = 0;
@@ -1176,9 +1209,24 @@
     return (char *)s;
   }  
 
+  /* skip directly to path */
+  host_start = strstr(s, "//");
+  if (host_start) {
+    host_start += 2;
+  } else {
+    host_start = (char *)s;
+  }
+
+  path_start = strstr(host_start, "/");
+  if (path_start) {
+    path_start += 1;
+  } else { /* there is no path to escape */
+    return (char *)s;
+  }
+
   /* First, pass through the string to see if there's anything to do,
      and to calculate the new length.  */
-  for (p1 = s; *p1; p1++) {
+  for (p1 = path_start; *p1; p1++) {
     switch (decide_copy_method (p1)) {
       case CM_ENCODE:
         ++encode_count;
@@ -1195,13 +1243,16 @@
     return (char *)s; /* C const model sucks. */
 
   oldlen = p1 - s;
+  host_len = path_start - s;
   /* Each encoding adds two characters (hex digits), while each
      decoding removes two characters.  */
   newlen = oldlen + 2 * (encode_count - decode_count);
   newstr = xmalloc (newlen + 1);
 
-  p1 = s;
-  p2 = newstr;
+  /* copy unmodified to new_str up to path_start */
+  memcpy(newstr, s, host_len);
+  p1 = path_start;
+  p2 = newstr + host_len;
 
   while (*p1) {
     switch (decide_copy_method (p1)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/siege-4.0.4/src/version.c 
new/siege-4.0.5/src/version.c
--- old/siege-4.0.4/src/version.c       2017-09-11 19:36:08.000000000 +0200
+++ new/siege-4.0.5/src/version.c       2020-02-19 18:43:41.000000000 +0100
@@ -4,12 +4,12 @@
  * used by configure to dynamically assign those values 
  * to documentation files.
  */
-const char *version_string = "4.0.4";
+const char *version_string = "4.0.5";
 const char *program_name   = "siege";
 const char *author_name    = "Jeffrey Fulmer, et al.";
 const char *email_address  = "[email protected]";
-const char *years          = "1999-2017";
-const char *copyright      = "Copyright (C) 2017 by Jeffrey Fulmer, et al.\n\
+const char *years          = "1999-2020";
+const char *copyright      = "Copyright (C) 2020 by Jeffrey Fulmer, et al.\n\
 This is free software; see the source for copying conditions.\n\
 There is NO warranty; not even for MERCHANTABILITY or FITNESS\n\
 FOR A PARTICULAR PURPOSE.\n";


Reply via email to