Hello community,

here is the log from the commit of package haproxy for openSUSE:Factory checked 
in at 2017-03-02 19:38:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/haproxy (Old)
 and      /work/SRC/openSUSE:Factory/.haproxy.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "haproxy"

Thu Mar  2 19:38:34 2017 rev:47 rq:460861 version:1.7.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes  2017-02-03 
17:42:18.141625423 +0100
+++ /work/SRC/openSUSE:Factory/.haproxy.new/haproxy.changes     2017-03-02 
19:38:35.568961394 +0100
@@ -1,0 +2,20 @@
+Tue Feb 28 11:31:02 UTC 2017 - kgronl...@suse.com
+
+- Update to version 1.7.3:
+  * BUG/MINOR: stream: Fix how backend-specific analyzers are set on a stream
+  * BUG/MEDIUM: tcp: don't poll for write when connect() succeeds
+  * BUG/MINOR: unix: fix connect's polling in case no data are scheduled
+  * BUG/MINOR: lua: Map.end are not reliable because "end" is a reserved 
keyword
+  * MINOR: dns: give ability to dns_init_resolvers() to close a socket when 
requested
+  * BUG/MAJOR: dns: restart sockets after fork()
+  * MINOR: chunks: implement a simple dynamic allocator for trash buffers
+  * BUG/MEDIUM: http: prevent redirect from overwriting a buffer
+  * BUG/MEDIUM: filters: Do not truncate HTTP response when body length is 
undefined
+  * BUG/MEDIUM: http: Prevent replace-header from overwriting a buffer
+  * BUG/MINOR: http: Return an error when a replace-header rule failed on the 
response
+  * BUG/MINOR: sendmail: The return of vsnprintf is not cleanly tested
+  * BUG/MAJOR: lua segmentation fault when the request is like 'GET ?arg=val 
HTTP/1.1'
+  * BUG/MEDIUM: config: reject anything but "if" or "unless" after a 
use-backend rule
+  * MINOR: http: don't close when redirect location doesn't start with "/"
+
+-------------------------------------------------------------------

Old:
----
  haproxy-1.7.2.tar.gz

New:
----
  haproxy-1.7.3.tar.gz

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

Other differences:
------------------
++++++ haproxy.spec ++++++
--- /var/tmp/diff_new_pack.QrU3j0/_old  2017-03-02 19:38:36.372847639 +0100
+++ /var/tmp/diff_new_pack.QrU3j0/_new  2017-03-02 19:38:36.372847639 +0100
@@ -41,7 +41,7 @@
 %bcond_without  apparmor
 
 Name:           haproxy
-Version:        1.7.2
+Version:        1.7.3
 Release:        0
 #
 #

++++++ _service ++++++
--- /var/tmp/diff_new_pack.QrU3j0/_old  2017-03-02 19:38:36.404843111 +0100
+++ /var/tmp/diff_new_pack.QrU3j0/_new  2017-03-02 19:38:36.408842545 +0100
@@ -3,8 +3,8 @@
     <param name="url">http://git.haproxy.org/git/haproxy-1.7.git</param>
     <param name="scm">git</param>
     <param name="filename">haproxy</param>
-    <param name="versionformat">1.7.2</param>
-    <param name="revision">v1.7.2</param>
+    <param name="versionformat">1.7.3</param>
+    <param name="revision">v1.7.3</param>
     <param name="changesgenerate">enable</param>
   </service>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.QrU3j0/_old  2017-03-02 19:38:36.424840281 +0100
+++ /var/tmp/diff_new_pack.QrU3j0/_new  2017-03-02 19:38:36.428839716 +0100
@@ -3,4 +3,4 @@
             <param 
name="url">http://git.haproxy.org/git/haproxy-1.6.git</param>
           <param 
name="changesrevision">864bf78c3b6898eb12ece5f0a44032090f26f57f</param></service><service
 name="tar_scm">
             <param 
name="url">http://git.haproxy.org/git/haproxy-1.7.git</param>
-          <param 
name="changesrevision">ddb646ee9182df570017ddf280873a1360a28898</param></service></servicedata>
\ No newline at end of file
+          <param 
name="changesrevision">9cb532a34ae190b350cdeb8bbbae25d524b10949</param></service></servicedata>
\ No newline at end of file

++++++ haproxy-1.7.2.tar.gz -> haproxy-1.7.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/CHANGELOG new/haproxy-1.7.3/CHANGELOG
--- old/haproxy-1.7.2/CHANGELOG 2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/CHANGELOG 2017-02-28 09:59:23.000000000 +0100
@@ -1,6 +1,27 @@
 ChangeLog :
 ===========
 
+2017/02/28 : 1.7.3
+    - BUG/MINOR: stream: Fix how backend-specific analyzers are set on a stream
+    - BUILD: ssl: fix build on OpenSSL 1.0.0
+    - BUILD: ssl: silence a warning reported for ERR_remove_state()
+    - BUILD: ssl: eliminate warning with OpenSSL 1.1.0 regarding 
RAND_pseudo_bytes()
+    - BUG/MEDIUM: tcp: don't poll for write when connect() succeeds
+    - BUG/MINOR: unix: fix connect's polling in case no data are scheduled
+    - DOC: lua: improve links
+    - BUG/MINOR: lua: Map.end are not reliable because "end" is a reserved 
keyword
+    - MINOR: dns: give ability to dns_init_resolvers() to close a socket when 
requested
+    - BUG/MAJOR: dns: restart sockets after fork()
+    - MINOR: chunks: implement a simple dynamic allocator for trash buffers
+    - BUG/MEDIUM: http: prevent redirect from overwriting a buffer
+    - BUG/MEDIUM: filters: Do not truncate HTTP response when body length is 
undefined
+    - BUG/MEDIUM: http: Prevent replace-header from overwriting a buffer
+    - BUG/MINOR: http: Return an error when a replace-header rule failed on 
the response
+    - BUG/MINOR: sendmail: The return of vsnprintf is not cleanly tested
+    - BUG/MAJOR: lua segmentation fault when the request is like 'GET ?arg=val 
HTTP/1.1'
+    - BUG/MEDIUM: config: reject anything but "if" or "unless" after a 
use-backend rule
+    - MINOR: http: don't close when redirect location doesn't start with "/"
+
 2017/01/13 : 1.7.2
     - BUG/MEDIUM: lua: In some case, the return of sample-fetches is ignored 
(2)
     - SCRIPTS: git-show-backports: fix a harmless typo
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/README new/haproxy-1.7.3/README
--- old/haproxy-1.7.2/README    2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/README    2017-02-28 09:59:23.000000000 +0100
@@ -3,7 +3,7 @@
                          ----------------------
                               version 1.7
                              willy tarreau
-                               2017/01/13
+                               2017/02/28
 
 
 1) How to build it
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/VERDATE new/haproxy-1.7.3/VERDATE
--- old/haproxy-1.7.2/VERDATE   2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/VERDATE   2017-02-28 09:59:23.000000000 +0100
@@ -1,2 +1,2 @@
 $Format:%ci$
-2017/01/13
+2017/02/28
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/VERSION new/haproxy-1.7.3/VERSION
--- old/haproxy-1.7.2/VERSION   2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/VERSION   2017-02-28 09:59:23.000000000 +0100
@@ -1 +1 @@
-1.7.2
+1.7.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/doc/configuration.txt 
new/haproxy-1.7.3/doc/configuration.txt
--- old/haproxy-1.7.2/doc/configuration.txt     2017-01-13 10:03:00.000000000 
+0100
+++ new/haproxy-1.7.3/doc/configuration.txt     2017-02-28 09:59:23.000000000 
+0100
@@ -4,7 +4,7 @@
                          ----------------------
                               version 1.7
                              willy tarreau
-                              2017/01/13
+                              2017/02/28
 
 
 This document covers the configuration language as implemented in the version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/doc/lua-api/index.rst 
new/haproxy-1.7.3/doc/lua-api/index.rst
--- old/haproxy-1.7.2/doc/lua-api/index.rst     2017-01-13 10:03:00.000000000 
+0100
+++ new/haproxy-1.7.3/doc/lua-api/index.rst     2017-02-28 09:59:23.000000000 
+0100
@@ -165,6 +165,14 @@
 
   This attribute is an integer, it contains the value of the loglevel "debug" 
(7).
 
+.. js:attribute:: core.proxies
+
+  **context**: task, action, sample-fetch, converter
+
+  This attribute is an array of declared proxies (frontend and backends). Each
+  proxy give an access to his list of listeners and servers. Each entry is of
+  type :ref:`proxy_class`
+
 .. js:function:: core.log(loglevel, msg)
 
   **context**: body, init, task, action, sample-fetch, converter
@@ -176,19 +184,20 @@
   :param integer loglevel: Is the log level asociated with the message. It is a
     number between 0 and 7.
   :param string msg: The log content.
-  :see: core.emerg, core.alert, core.crit, core.err, core.warning, core.notice,
-    core.info, core.debug (log level definitions)
-  :see: code.Debug
-  :see: core.Info
-  :see: core.Warning
-  :see: core.Alert
+  :see: :js:attr:`core.emerg`, :js:attr:`core.alert`, :js:attr:`core.crit`,
+    :js:attr:`core.err`, :js:attr:`core.warning`, :js:attr:`core.notice`,
+    :js:attr:`core.info`, :js:attr:`core.debug` (log level definitions)
+  :see: :js:func:`core.Debug`
+  :see: :js:func:`core.Info`
+  :see: :js:func:`core.Warning`
+  :see: :js:func:`core.Alert`
 
 .. js:function:: core.Debug(msg)
 
   **context**: body, init, task, action, sample-fetch, converter
 
   :param string msg: The log content.
-  :see: log
+  :see: :js:func:`core.log`
 
   Does the same job than:
 
@@ -204,7 +213,7 @@
   **context**: body, init, task, action, sample-fetch, converter
 
   :param string msg: The log content.
-  :see: log
+  :see: :js:func:`core.log`
 
 .. code-block:: lua
 
@@ -218,7 +227,7 @@
   **context**: body, init, task, action, sample-fetch, converter
 
   :param string msg: The log content.
-  :see: log
+  :see: :js:func:`core.log`
 
 .. code-block:: lua
 
@@ -232,7 +241,7 @@
   **context**: body, init, task, action, sample-fetch, converter
 
   :param string msg: The log content.
-  :see: log
+  :see: :js:func:`core.log`
 
 .. code-block:: lua
 
@@ -1097,8 +1106,8 @@
   **warning** some sample fetches are not available in some context. These
   limitations are specified in this documentation when theire useful.
 
-  :see: TXN.f
-  :see: TXN.sf
+  :see: :js:attr:`TXN.f`
+  :see: :js:attr:`TXN.sf`
 
   Fetches are useful for:
 
@@ -1131,8 +1140,8 @@
   HAProxy documentation "configuration.txt" for more information about her
   usage. Its the chapter 7.3.1.
 
-  :see: TXN.c
-  :see: TXN.sc
+  :see: :js:attr:`TXN.c`
+  :see: :js:attr:`TXN.sc`
 
   Converters provides statefull transformation. They are useful for:
 
@@ -1275,7 +1284,7 @@
 
   :param class_http http: The related http object.
   :returns: array of headers.
-  :see: HTTP.res_get_headers()
+  :see: :js:func:`HTTP.res_get_headers`
 
   This is the form of the returned array:
 
@@ -1296,7 +1305,7 @@
 
   :param class_http http: The related http object.
   :returns: array of headers.
-  :see: HTTP.req_get_headers()
+  :see: :js:func:`HTTP.req_get_headers`
 
   This is the form of the returned array:
 
@@ -1319,7 +1328,7 @@
   :param class_http http: The related http object.
   :param string name: The header name.
   :param string value: The header value.
-  :see: HTTP.res_add_header()
+  :see: :js:func:`HTTP.res_add_header`
 
 .. js:function:: HTTP.res_add_header(http, name, value)
 
@@ -1329,7 +1338,7 @@
   :param class_http http: The related http object.
   :param string name: The header name.
   :param string value: The header value.
-  :see: HTTP.req_add_header()
+  :see: :js:func:`HTTP.req_add_header`
 
 .. js:function:: HTTP.req_del_header(http, name)
 
@@ -1338,7 +1347,7 @@
 
   :param class_http http: The related http object.
   :param string name: The header name.
-  :see: HTTP.res_del_header()
+  :see: :js:func:`HTTP.res_del_header`
 
 .. js:function:: HTTP.res_del_header(http, name)
 
@@ -1347,7 +1356,7 @@
 
   :param class_http http: The related http object.
   :param string name: The header name.
-  :see: HTTP.req_del_header()
+  :see: :js:func:`HTTP.req_del_header`
 
 .. js:function:: HTTP.req_set_header(http, name, value)
 
@@ -1357,7 +1366,7 @@
   :param class_http http: The related http object.
   :param string name: The header name.
   :param string value: The header value.
-  :see: HTTP.res_set_header()
+  :see: :js:func:`HTTP.res_set_header`
 
   This function does the same work as the folowwing code:
 
@@ -1377,7 +1386,7 @@
   :param class_http http: The related http object.
   :param string name: The header name.
   :param string value: The header value.
-  :see: HTTP.req_rep_header()
+  :see: :js:func:`HTTP.req_rep_header()`
 
 .. js:function:: HTTP.req_rep_header(http, name, regex, replace)
 
@@ -1390,7 +1399,7 @@
   :param string name: The header name.
   :param string regex: The match regular expression.
   :param string replace: The replacement value.
-  :see: HTTP.res_rep_header()
+  :see: :js:func:`HTTP.res_rep_header()`
 
 .. js:function:: HTTP.res_rep_header(http, name, regex, string)
 
@@ -1403,7 +1412,7 @@
   :param string name: The header name.
   :param string regex: The match regular expression.
   :param string replace: The replacement value.
-  :see: HTTP.req_replace_header()
+  :see: :js:func:`HTTP.req_rep_header()`
 
 .. js:function:: HTTP.req_set_method(http, method)
 
@@ -1516,13 +1525,14 @@
   :param integer loglevel: Is the log level asociated with the message. It is a
     number between 0 and 7.
   :param string msg: The log content.
-  :see: core.emerg, core.alert, core.crit, core.err, core.warning, core.notice,
-    core.info, core.debug (log level definitions)
-  :see: TXN.deflog
-  :see: TXN.Debug
-  :see: TXN.Info
-  :see: TXN.Warning
-  :see: TXN.Alert
+  :see: :js:attr:`core.emerg`, :js:attr:`core.alert`, :js:attr:`core.crit`,
+    :js:attr:`core.err`, :js:attr:`core.warning`, :js:attr:`core.notice`,
+    :js:attr:`core.info`, :js:attr:`core.debug` (log level definitions)
+  :see: :js:func:`TXN.deflog`
+  :see: :js:func:`TXN.Debug`
+  :see: :js:func:`TXN.Info`
+  :see: :js:func:`TXN.Warning`
+  :see: :js:func:`TXN.Alert`
 
 .. js:function:: TXN.deflog(TXN, msg)
 
@@ -1531,13 +1541,13 @@
 
   :param class_txn txn: The class txn object containing the data.
   :param string msg: The log content.
-  :see: TXN.log
+  :see: :js:func:`TXN.log
 
 .. js:function:: TXN.Debug(txn, msg)
 
   :param class_txn txn: The class txn object containing the data.
   :param string msg: The log content.
-  :see: TXN.log
+  :see: :js:func:`TXN.log`
 
   Does the same job than:
 
@@ -1552,7 +1562,7 @@
 
   :param class_txn txn: The class txn object containing the data.
   :param string msg: The log content.
-  :see: TXN.log
+  :see: :js:func:`TXN.log`
 
 .. code-block:: lua
 
@@ -1565,7 +1575,7 @@
 
   :param class_txn txn: The class txn object containing the data.
   :param string msg: The log content.
-  :see: TXN.log
+  :see: :js:func:`TXN.log`
 
 .. code-block:: lua
 
@@ -1578,7 +1588,7 @@
 
   :param class_txn txn: The class txn object containing the data.
   :param string msg: The log content.
-  :see: TXN.log
+  :see: :js:func:`TXN.log`
 
 .. code-block:: lua
 
@@ -1647,7 +1657,9 @@
 
   :param class_txn txn: The class txn object containing the data.
   :param integer loglevel: The required log level. This variable can be one of
-  :see: core.<loglevel>
+  :see: :js:attr:`core.emerg`, :js:attr:`core.alert`, :js:attr:`core.crit`,
+    :js:attr:`core.err`, :js:attr:`core.warning`, :js:attr:`core.notice`,
+    :js:attr:`core.info`, :js:attr:`core.debug` (log level definitions)
 
 .. js:function:: TXN.set_tos(txn, tos)
 
@@ -1851,7 +1863,7 @@
   default = "usa"
 
   -- Create and load map
-  geo = Map.new("geo.map", Map.ip);
+  geo = Map.new("geo.map", Map._ip);
 
   -- Create new fetch that returns the user country
   core.register_fetches("country", function(txn)
@@ -1876,60 +1888,76 @@
     return loc;
   end);
 
-.. js:attribute:: Map.int
+.. js:attribute:: Map._int
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
-.. js:attribute:: Map.ip
+  Note that :js:attr:`Map.int` is also available for compatibility.
+
+.. js:attribute:: Map._ip
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
-.. js:attribute:: Map.str
+  Note that :js:attr:`Map.ip` is also available for compatibility.
+
+.. js:attribute:: Map._str
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
-.. js:attribute:: Map.beg
+  Note that :js:attr:`Map.str` is also available for compatibility.
+
+.. js:attribute:: Map._beg
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
-.. js:attribute:: Map.sub
+  Note that :js:attr:`Map.beg` is also available for compatibility.
+
+.. js:attribute:: Map._sub
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
-.. js:attribute:: Map.dir
+  Note that :js:attr:`Map.sub` is also available for compatibility.
+
+.. js:attribute:: Map._dir
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
-.. js:attribute:: Map.dom
+  Note that :js:attr:`Map.dir` is also available for compatibility.
+
+.. js:attribute:: Map._dom
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
-.. js:attribute:: Map.end
+  Note that :js:attr:`Map.dom` is also available for compatibility.
+
+.. js:attribute:: Map._end
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
-.. js:attribute:: Map.reg
+.. js:attribute:: Map._reg
 
   See the HAProxy configuration.txt file, chapter "Using ACLs and fetching
   samples" ans subchapter "ACL basics" to understand this pattern matching
   method.
 
+  Note that :js:attr:`Map.reg` is also available for compatibility.
+
 
 .. js:function:: Map.new(file, method)
 
@@ -1939,7 +1967,10 @@
   :param integer method: Is the map pattern matching method. See the attributes
     of the Map class.
   :returns: a class Map object.
-  :see: The Map attributes.
+  :see: The Map attributes: :js:attr:`Map._int`, :js:attr:`Map._ip`,
+    :js:attr:`Map._str`, :js:attr:`Map._beg`, :js:attr:`Map._sub`,
+    :js:attr:`Map._dir`, :js:attr:`Map._dom`, :js:attr:`Map._end` and
+    :js:attr:`Map._reg`.
 
 .. js:function:: Map.lookup(map, str)
 
@@ -2126,13 +2157,13 @@
 
 .. js:function:: AppletHTTP.get_priv(applet)
 
-  Return Lua data stored in the current transaction (with the
-  `AppletHTTP.set_priv()`) function. If no data are stored, it returns a nil
-  value.
+  Return Lua data stored in the current transaction. If no data are stored,
+  it returns a nil value.
 
   :param class_AppletHTTP applet: An :ref:`applethttp_class`
   :returns: the opaque data previsously stored, or nil if nothing is
      avalaible.
+  :see: :js:func:`AppletHTTP.set_priv`
 
 .. js:function:: AppletHTTP.set_priv(applet, data)
 
@@ -2141,6 +2172,7 @@
 
   :param class_AppletHTTP applet: An :ref:`applethttp_class`
   :param opaque data: The data which is stored in the transaction.
+  :see: :js:func:`AppletHTTP.get_priv`
 
 .. _applettcp_class:
 
@@ -2207,13 +2239,13 @@
 
 .. js:function:: AppletTCP.get_priv(applet)
 
-  Return Lua data stored in the current transaction (with the
-  `AppletTCP.set_priv()`) function. If no data are stored, it returns a nil
-  value.
+  Return Lua data stored in the current transaction. If no data are stored,
+  it returns a nil value.
 
   :param class_AppletTCP applet: An :ref:`applettcp_class`
   :returns: the opaque data previsously stored, or nil if nothing is
      avalaible.
+  :see: :js:func:`AppletTCP.set_priv`
 
 .. js:function:: AppletTCP.set_priv(applet, data)
 
@@ -2222,6 +2254,7 @@
 
   :param class_AppletTCP applet: An :ref:`applettcp_class`
   :param opaque data: The data which is stored in the transaction.
+  :see: :js:func:`AppletTCP.get_priv`
 
 External Lua libraries
 ======================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/examples/haproxy.spec 
new/haproxy-1.7.3/examples/haproxy.spec
--- old/haproxy-1.7.2/examples/haproxy.spec     2017-01-13 10:03:00.000000000 
+0100
+++ new/haproxy-1.7.3/examples/haproxy.spec     2017-02-28 09:59:23.000000000 
+0100
@@ -1,6 +1,6 @@
 Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability 
environments
 Name: haproxy
-Version: 1.7.2
+Version: 1.7.3
 Release: 1
 License: GPL
 Group: System Environment/Daemons
@@ -74,6 +74,9 @@
 %attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
 
 %changelog
+* Tue Feb 28 2017 Willy Tarreau <w...@1wt.eu>
+- updated to 1.7.3
+
 * Fri Jan 13 2017 Willy Tarreau <w...@1wt.eu>
 - updated to 1.7.2
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/include/common/chunk.h 
new/haproxy-1.7.3/include/common/chunk.h
--- old/haproxy-1.7.2/include/common/chunk.h    2017-01-13 10:03:00.000000000 
+0100
+++ new/haproxy-1.7.3/include/common/chunk.h    2017-02-28 09:59:23.000000000 
+0100
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include <common/config.h>
+#include <common/memory.h>
 
 
 /* describes a chunk of string */
@@ -35,6 +36,8 @@
        int len;        /* current size of the string from first to last char. 
<0 = uninit. */
 };
 
+struct pool_head *pool2_trash;
+
 /* function prototypes */
 
 int chunk_printf(struct chunk *chk, const char *fmt, ...)
@@ -50,6 +53,16 @@
 int alloc_trash_buffers(int bufsize);
 void free_trash_buffers(void);
 struct chunk *get_trash_chunk(void);
+struct chunk *alloc_trash_chunk(void);
+
+/*
+ * free a trash chunk allocated by alloc_trash_chunk(). NOP on NULL.
+ */
+static inline void free_trash_chunk(struct chunk *chunk)
+{
+       pool_free2(pool2_trash, chunk);
+}
+
 
 static inline void chunk_reset(struct chunk *chk)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/include/proto/dns.h 
new/haproxy-1.7.3/include/proto/dns.h
--- old/haproxy-1.7.2/include/proto/dns.h       2017-01-13 10:03:00.000000000 
+0100
+++ new/haproxy-1.7.3/include/proto/dns.h       2017-02-28 09:59:23.000000000 
+0100
@@ -30,7 +30,7 @@
 int dns_hostname_validation(const char *string, char **err);
 int dns_build_query(int query_id, int query_type, char *hostname_dn, int 
hostname_dn_len, char *buf, int bufsize);
 struct task *dns_process_resolve(struct task *t);
-int dns_init_resolvers(void);
+int dns_init_resolvers(int close_socket);
 uint16_t dns_rnd16(void);
 int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, 
struct dns_response_packet *dns_p);
 int dns_get_ip_from_response(struct dns_response_packet *dns_p,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/include/proto/openssl-compat.h 
new/haproxy-1.7.3/include/proto/openssl-compat.h
--- old/haproxy-1.7.2/include/proto/openssl-compat.h    2017-01-13 
10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/include/proto/openssl-compat.h    2017-02-28 
09:59:23.000000000 +0100
@@ -56,16 +56,7 @@
 
 
 #if (OPENSSL_VERSION_NUMBER < 0x1000000fL)
-/*
- * Functions introduced in OpenSSL 1.0.1
- */
-static inline int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned 
char *sid_ctx, unsigned int sid_ctx_len)
-{
-       s->sid_ctx_length = sid_ctx_len;
-       memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
-       return 1;
-}
-
+/* Functions introduced in OpenSSL 1.0.0 */
 static inline int EVP_PKEY_base_id(const EVP_PKEY *pkey)
 {
        return EVP_PKEY_type(pkey->type);
@@ -86,6 +77,18 @@
 
 #endif
 
+#if (OPENSSL_VERSION_NUMBER < 0x1000100fL)
+/*
+ * Functions introduced in OpenSSL 1.0.1
+ */
+static inline int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned 
char *sid_ctx, unsigned int sid_ctx_len)
+{
+       s->sid_ctx_length = sid_ctx_len;
+       memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
+       return 1;
+}
+#endif
+
 #if (OPENSSL_VERSION_NUMBER < 0x1010000fL) || defined(LIBRESSL_VERSION_NUMBER)
 /*
  * Functions introduced in OpenSSL 1.1.0 and not yet present in LibreSSL
@@ -147,4 +150,25 @@
 #define __OPENSSL_110_CONST__
 #endif
 
+/* ERR_remove_state() was deprecated in 1.0.0 in favor of
+ * ERR_remove_thread_state(), which was in turn deprecated in
+ * 1.1.0 and does nothing anymore. Let's simply silently kill
+ * it.
+ */
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
+#undef  ERR_remove_state
+#define ERR_remove_state(x)
+#endif
+
+
+/* RAND_pseudo_bytes() is deprecated in 1.1.0 in favor of RAND_bytes(). Note
+ * that the return codes differ, but it happens that the only use case (ticket
+ * key update) was already wrong, considering a non-cryptographic random as a
+ * failure.
+ */
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
+#undef  RAND_pseudo_bytes
+#define RAND_pseudo_bytes(x,y) RAND_bytes(x,y)
+#endif
+
 #endif /* _PROTO_OPENSSL_COMPAT_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/cfgparse.c 
new/haproxy-1.7.3/src/cfgparse.c
--- old/haproxy-1.7.2/src/cfgparse.c    2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/cfgparse.c    2017-02-28 09:59:23.000000000 +0100
@@ -3984,6 +3984,12 @@
 
                        err_code |= warnif_cond_conflicts(cond, 
SMP_VAL_FE_SET_BCK, file, linenum);
                }
+               else if (*args[2]) {
+                       Alert("parsing [%s:%d] : unexpected keyword '%s' after 
switching rule, only 'if' and 'unless' are allowed.\n",
+                             file, linenum, args[2]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
 
                rule = calloc(1, sizeof(*rule));
                if (!rule) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/checks.c 
new/haproxy-1.7.3/src/checks.c
--- old/haproxy-1.7.2/src/checks.c      2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/checks.c      2017-02-28 09:59:23.000000000 +0100
@@ -3407,7 +3407,7 @@
        len = vsnprintf(buf, sizeof(buf), format, argp);
        va_end(argp);
 
-       if (len < 0) {
+       if (len < 0 || len >= sizeof(buf)) {
                Alert("Email alert [%s] could not format message\n", p->id);
                return;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/chunk.c 
new/haproxy-1.7.3/src/chunk.c
--- old/haproxy-1.7.2/src/chunk.c       2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/chunk.c       2017-02-28 09:59:23.000000000 +0100
@@ -29,6 +29,9 @@
 static char *trash_buf1;
 static char *trash_buf2;
 
+/* the trash pool for reentrant allocations */
+struct pool_head *pool2_trash = NULL;
+
 /*
 * Returns a pre-allocated and initialized trash chunk that can be used for any
 * type of conversion. Two chunks and their respective buffers are alternatively
@@ -63,7 +66,8 @@
        trash_size = bufsize;
        trash_buf1 = (char *)my_realloc2(trash_buf1, bufsize);
        trash_buf2 = (char *)my_realloc2(trash_buf2, bufsize);
-       return trash_buf1 && trash_buf2;
+       pool2_trash = create_pool("trash", sizeof(struct chunk) + bufsize, 
MEM_F_EXACT);
+       return trash_buf1 && trash_buf2 && pool2_trash;
 }
 
 /*
@@ -78,6 +82,25 @@
 }
 
 /*
+ * Allocate a trash chunk from the reentrant pool. The buffer starts at the
+ * end of the chunk. This chunk must be freed using free_trash_chunk(). This
+ * call may fail and the caller is responsible for checking that the returned
+ * pointer is not NULL.
+ */
+struct chunk *alloc_trash_chunk(void)
+{
+       struct chunk *chunk;
+
+       chunk = pool_alloc2(pool2_trash);
+       if (chunk) {
+               char *buf = (char *)chunk + sizeof(struct chunk);
+               *buf = 0;
+               chunk_init(chunk, buf, pool2_trash->size - sizeof(struct 
chunk));
+       }
+       return chunk;
+}
+
+/*
  * Does an snprintf() at the beginning of chunk <chk>, respecting the limit of
  * at most chk->size chars. If the chk->len is over, nothing is added. Returns
  * the new chunk size, or < 0 in case of failure.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/dns.c new/haproxy-1.7.3/src/dns.c
--- old/haproxy-1.7.2/src/dns.c 2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/dns.c 2017-02-28 09:59:23.000000000 +0100
@@ -919,11 +919,13 @@
  * parses resolvers sections and initializes:
  *  - task (time events) for each resolvers section
  *  - the datagram layer (network IO events) for each nameserver
+ * It takes one argument:
+ *  - close_first takes 2 values: 0 or 1. If 1, the connection is closed first.
  * returns:
  *  0 in case of error
  *  1 when no error
  */
-int dns_init_resolvers(void)
+int dns_init_resolvers(int close_socket)
 {
        struct dns_resolvers *curr_resolvers;
        struct dns_nameserver *curnameserver;
@@ -961,7 +963,19 @@
                curr_resolvers->t = t;
 
                list_for_each_entry(curnameserver, 
&curr_resolvers->nameserver_list, list) {
-                       if ((dgram = calloc(1, sizeof(*dgram))) == NULL) {
+                       dgram = NULL;
+
+                       if (close_socket == 1) {
+                               if (curnameserver->dgram) {
+                                       close(curnameserver->dgram->t.sock.fd);
+                                       memset(curnameserver->dgram, '\0', 
sizeof(*dgram));
+                                       dgram = curnameserver->dgram;
+                               }
+                       }
+
+                       /* allocate memory only if it has not already been 
allocated
+                        * by a previous call to this function */
+                       if (!dgram && (dgram = calloc(1, sizeof(*dgram))) == 
NULL) {
                                Alert("Starting [%s/%s] nameserver: out of 
memory.\n", curr_resolvers->id,
                                                curnameserver->id);
                                return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/haproxy.c 
new/haproxy-1.7.3/src/haproxy.c
--- old/haproxy-1.7.2/src/haproxy.c     2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/haproxy.c     2017-02-28 09:59:23.000000000 +0100
@@ -1309,7 +1309,7 @@
                exit(1);
 
        /* initialize structures for name resolution */
-       if (!dns_init_resolvers())
+       if (!dns_init_resolvers(0))
                exit(1);
 
        free(err_msg);
@@ -1685,6 +1685,7 @@
        pool_destroy2(pool2_stream);
        pool_destroy2(pool2_session);
        pool_destroy2(pool2_connection);
+       pool_destroy2(pool2_trash);
        pool_destroy2(pool2_buffer);
        pool_destroy2(pool2_requri);
        pool_destroy2(pool2_task);
@@ -2090,6 +2091,10 @@
                fork_poller();
        }
 
+       /* initialize structures for name resolution */
+       if (!dns_init_resolvers(1))
+               exit(1);
+
        protocol_enable_all();
        /*
         * That's it : the central polling loop. Run until we stop.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/hlua.c new/haproxy-1.7.3/src/hlua.c
--- old/haproxy-1.7.2/src/hlua.c        2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/hlua.c        2017-02-28 09:59:23.000000000 +0100
@@ -3551,22 +3551,24 @@
 
        /* Get path and qs */
        path = http_get_path(txn);
-       end = txn->req.chn->buf->p + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
-       p = path;
-       while (p < end && *p != '?')
-               p++;
-
-       /* Stores the request path. */
-       lua_pushstring(L, "path");
-       lua_pushlstring(L, path, p - path);
-       lua_settable(L, -3);
+       if (path) {
+               end = txn->req.chn->buf->p + txn->req.sl.rq.u + 
txn->req.sl.rq.u_l;
+               p = path;
+               while (p < end && *p != '?')
+                       p++;
 
-       /* Stores the query string. */
-       lua_pushstring(L, "qs");
-       if (*p == '?')
-               p++;
-       lua_pushlstring(L, p, end - p);
-       lua_settable(L, -3);
+               /* Stores the request path. */
+               lua_pushstring(L, "path");
+               lua_pushlstring(L, path, p - path);
+               lua_settable(L, -3);
+
+               /* Stores the query string. */
+               lua_pushstring(L, "qs");
+               if (*p == '?')
+                       p++;
+               lua_pushlstring(L, p, end - p);
+               lua_settable(L, -3);
+       }
 
        /* Stores the request path. */
        lua_pushstring(L, "length");
@@ -7008,6 +7010,10 @@
        /* register pattern types. */
        for (i=0; i<PAT_MATCH_NUM; i++)
                hlua_class_const_int(gL.T, pat_match_names[i], i);
+       for (i=0; i<PAT_MATCH_NUM; i++) {
+               snprintf(trash.str, trash.size, "_%s", pat_match_names[i]);
+               hlua_class_const_int(gL.T, trash.str, i);
+       }
 
        /* register constructor. */
        hlua_class_function(gL.T, "new", hlua_map_new);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/proto_http.c 
new/haproxy-1.7.3/src/proto_http.c
--- old/haproxy-1.7.2/src/proto_http.c  2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/proto_http.c  2017-02-28 09:59:23.000000000 +0100
@@ -3419,13 +3419,22 @@
                                  struct list *fmt, struct my_regex *re,
                                  int action)
 {
-       struct chunk *replace = get_trash_chunk();
+       struct chunk *replace;
+       int ret = -1;
+
+       replace = alloc_trash_chunk();
+       if (!replace)
+               goto leave;
 
        replace->len = build_logline(s, replace->str, replace->size, fmt);
        if (replace->len >= replace->size - 1)
-               return -1;
+               goto leave;
+
+       ret = http_transform_header_str(s, msg, name, name_len, replace->str, 
re, action);
 
-       return http_transform_header_str(s, msg, name, name_len, replace->str, 
re, action);
+  leave:
+       free_trash_chunk(replace);
+       return ret;
 }
 
 /* Executes the http-request rules <rules> for stream <s>, proxy <px> and
@@ -3814,7 +3823,7 @@
                                                  rule->arg.hdr_add.name_len,
                                                  &rule->arg.hdr_add.fmt,
                                                  &rule->arg.hdr_add.re, 
rule->action))
-                               return HTTP_RULE_RES_STOP; /* note: we should 
report an error here */
+                               return HTTP_RULE_RES_BADREQ;
                        break;
 
                case ACT_HTTP_DEL_HDR:
@@ -4023,7 +4032,12 @@
        struct http_msg *req = &txn->req;
        struct http_msg *res = &txn->rsp;
        const char *msg_fmt;
-       const char *location;
+       struct chunk *chunk;
+       int ret = 0;
+
+       chunk = alloc_trash_chunk();
+       if (!chunk)
+               goto leave;
 
        /* build redirect message */
        switch(rule->code) {
@@ -4045,10 +4059,8 @@
                break;
        }
 
-       if (unlikely(!chunk_strcpy(&trash, msg_fmt)))
-               return 0;
-
-       location = trash.str + trash.len;
+       if (unlikely(!chunk_strcpy(chunk, msg_fmt)))
+               goto leave;
 
        switch(rule->type) {
        case REDIRECT_TYPE_SCHEME: {
@@ -4087,40 +4099,40 @@
 
                if (rule->rdr_str) { /* this is an old "redirect" rule */
                        /* check if we can add scheme + "://" + host + path */
-                       if (trash.len + rule->rdr_len + 3 + hostlen + pathlen > 
trash.size - 4)
-                               return 0;
+                       if (chunk->len + rule->rdr_len + 3 + hostlen + pathlen 
> chunk->size - 4)
+                               goto leave;
 
                        /* add scheme */
-                       memcpy(trash.str + trash.len, rule->rdr_str, 
rule->rdr_len);
-                       trash.len += rule->rdr_len;
+                       memcpy(chunk->str + chunk->len, rule->rdr_str, 
rule->rdr_len);
+                       chunk->len += rule->rdr_len;
                }
                else {
                        /* add scheme with executing log format */
-                       trash.len += build_logline(s, trash.str + trash.len, 
trash.size - trash.len, &rule->rdr_fmt);
+                       chunk->len += build_logline(s, chunk->str + chunk->len, 
chunk->size - chunk->len, &rule->rdr_fmt);
 
                        /* check if we can add scheme + "://" + host + path */
-                       if (trash.len + 3 + hostlen + pathlen > trash.size - 4)
-                               return 0;
+                       if (chunk->len + 3 + hostlen + pathlen > chunk->size - 
4)
+                               goto leave;
                }
                /* add "://" */
-               memcpy(trash.str + trash.len, "://", 3);
-               trash.len += 3;
+               memcpy(chunk->str + chunk->len, "://", 3);
+               chunk->len += 3;
 
                /* add host */
-               memcpy(trash.str + trash.len, host, hostlen);
-               trash.len += hostlen;
+               memcpy(chunk->str + chunk->len, host, hostlen);
+               chunk->len += hostlen;
 
                /* add path */
-               memcpy(trash.str + trash.len, path, pathlen);
-               trash.len += pathlen;
+               memcpy(chunk->str + chunk->len, path, pathlen);
+               chunk->len += pathlen;
 
                /* append a slash at the end of the location if needed and 
missing */
-               if (trash.len && trash.str[trash.len - 1] != '/' &&
+               if (chunk->len && chunk->str[chunk->len - 1] != '/' &&
                    (rule->flags & REDIRECT_FLAG_APPEND_SLASH)) {
-                       if (trash.len > trash.size - 5)
-                               return 0;
-                       trash.str[trash.len] = '/';
-                       trash.len++;
+                       if (chunk->len > chunk->size - 5)
+                               goto leave;
+                       chunk->str[chunk->len] = '/';
+                       chunk->len++;
                }
 
                break;
@@ -4149,38 +4161,38 @@
                }
 
                if (rule->rdr_str) { /* this is an old "redirect" rule */
-                       if (trash.len + rule->rdr_len + pathlen > trash.size - 
4)
-                               return 0;
+                       if (chunk->len + rule->rdr_len + pathlen > chunk->size 
- 4)
+                               goto leave;
 
                        /* add prefix. Note that if prefix == "/", we don't 
want to
                         * add anything, otherwise it makes it hard for the 
user to
                         * configure a self-redirection.
                         */
                        if (rule->rdr_len != 1 || *rule->rdr_str != '/') {
-                               memcpy(trash.str + trash.len, rule->rdr_str, 
rule->rdr_len);
-                               trash.len += rule->rdr_len;
+                               memcpy(chunk->str + chunk->len, rule->rdr_str, 
rule->rdr_len);
+                               chunk->len += rule->rdr_len;
                        }
                }
                else {
                        /* add prefix with executing log format */
-                       trash.len += build_logline(s, trash.str + trash.len, 
trash.size - trash.len, &rule->rdr_fmt);
+                       chunk->len += build_logline(s, chunk->str + chunk->len, 
chunk->size - chunk->len, &rule->rdr_fmt);
 
                        /* Check length */
-                       if (trash.len + pathlen > trash.size - 4)
-                               return 0;
+                       if (chunk->len + pathlen > chunk->size - 4)
+                               goto leave;
                }
 
                /* add path */
-               memcpy(trash.str + trash.len, path, pathlen);
-               trash.len += pathlen;
+               memcpy(chunk->str + chunk->len, path, pathlen);
+               chunk->len += pathlen;
 
                /* append a slash at the end of the location if needed and 
missing */
-               if (trash.len && trash.str[trash.len - 1] != '/' &&
+               if (chunk->len && chunk->str[chunk->len - 1] != '/' &&
                    (rule->flags & REDIRECT_FLAG_APPEND_SLASH)) {
-                       if (trash.len > trash.size - 5)
-                               return 0;
-                       trash.str[trash.len] = '/';
-                       trash.len++;
+                       if (chunk->len > chunk->size - 5)
+                               goto leave;
+                       chunk->str[chunk->len] = '/';
+                       chunk->len++;
                }
 
                break;
@@ -4188,59 +4200,54 @@
        case REDIRECT_TYPE_LOCATION:
        default:
                if (rule->rdr_str) { /* this is an old "redirect" rule */
-                       if (trash.len + rule->rdr_len > trash.size - 4)
-                               return 0;
+                       if (chunk->len + rule->rdr_len > chunk->size - 4)
+                               goto leave;
 
                        /* add location */
-                       memcpy(trash.str + trash.len, rule->rdr_str, 
rule->rdr_len);
-                       trash.len += rule->rdr_len;
+                       memcpy(chunk->str + chunk->len, rule->rdr_str, 
rule->rdr_len);
+                       chunk->len += rule->rdr_len;
                }
                else {
                        /* add location with executing log format */
-                       trash.len += build_logline(s, trash.str + trash.len, 
trash.size - trash.len, &rule->rdr_fmt);
+                       chunk->len += build_logline(s, chunk->str + chunk->len, 
chunk->size - chunk->len, &rule->rdr_fmt);
 
                        /* Check left length */
-                       if (trash.len > trash.size - 4)
-                               return 0;
+                       if (chunk->len > chunk->size - 4)
+                               goto leave;
                }
                break;
        }
 
        if (rule->cookie_len) {
-               memcpy(trash.str + trash.len, "\r\nSet-Cookie: ", 14);
-               trash.len += 14;
-               memcpy(trash.str + trash.len, rule->cookie_str, 
rule->cookie_len);
-               trash.len += rule->cookie_len;
+               memcpy(chunk->str + chunk->len, "\r\nSet-Cookie: ", 14);
+               chunk->len += 14;
+               memcpy(chunk->str + chunk->len, rule->cookie_str, 
rule->cookie_len);
+               chunk->len += rule->cookie_len;
        }
 
-       /* add end of headers and the keep-alive/close status.
-        * We may choose to set keep-alive if the Location begins
-        * with a slash, because the client will come back to the
-        * same server.
-        */
+       /* add end of headers and the keep-alive/close status. */
        txn->status = rule->code;
        /* let's log the request time */
        s->logs.tv_request = now;
 
-       if (*location == '/' &&
-           (req->flags & HTTP_MSGF_XFER_LEN) &&
+       if ((req->flags & HTTP_MSGF_XFER_LEN) &&
            ((!(req->flags & HTTP_MSGF_TE_CHNK) && !req->body_len) || 
(req->msg_state == HTTP_MSG_DONE)) &&
            ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL ||
             (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL)) {
                /* keep-alive possible */
                if (!(req->flags & HTTP_MSGF_VER_11)) {
                        if (unlikely(txn->flags & TX_USE_PX_CONN)) {
-                               memcpy(trash.str + trash.len, 
"\r\nProxy-Connection: keep-alive", 30);
-                               trash.len += 30;
+                               memcpy(chunk->str + chunk->len, 
"\r\nProxy-Connection: keep-alive", 30);
+                               chunk->len += 30;
                        } else {
-                               memcpy(trash.str + trash.len, "\r\nConnection: 
keep-alive", 24);
-                               trash.len += 24;
+                               memcpy(chunk->str + chunk->len, 
"\r\nConnection: keep-alive", 24);
+                               chunk->len += 24;
                        }
                }
-               memcpy(trash.str + trash.len, "\r\n\r\n", 4);
-               trash.len += 4;
-               FLT_STRM_CB(s, flt_http_reply(s, txn->status, &trash));
-               bo_inject(res->chn, trash.str, trash.len);
+               memcpy(chunk->str + chunk->len, "\r\n\r\n", 4);
+               chunk->len += 4;
+               FLT_STRM_CB(s, flt_http_reply(s, txn->status, chunk));
+               bo_inject(res->chn, chunk->str, chunk->len);
                /* "eat" the request */
                bi_fast_delete(req->chn->buf, req->sov);
                req->next -= req->sov;
@@ -4255,13 +4262,13 @@
        } else {
                /* keep-alive not possible */
                if (unlikely(txn->flags & TX_USE_PX_CONN)) {
-                       memcpy(trash.str + trash.len, "\r\nProxy-Connection: 
close\r\n\r\n", 29);
-                       trash.len += 29;
+                       memcpy(chunk->str + chunk->len, "\r\nProxy-Connection: 
close\r\n\r\n", 29);
+                       chunk->len += 29;
                } else {
-                       memcpy(trash.str + trash.len, "\r\nConnection: 
close\r\n\r\n", 23);
-                       trash.len += 23;
+                       memcpy(chunk->str + chunk->len, "\r\nConnection: 
close\r\n\r\n", 23);
+                       chunk->len += 23;
                }
-               http_reply_and_close(s, txn->status, &trash);
+               http_reply_and_close(s, txn->status, chunk);
                req->chn->analysers &= AN_REQ_FLT_END;
        }
 
@@ -4270,7 +4277,10 @@
        if (!(s->flags & SF_FINST_MASK))
                s->flags |= SF_FINST_R;
 
-       return 1;
+       ret = 1;
+ leave:
+       free_trash_chunk(chunk);
+       return ret;
 }
 
 /* This stream analyser runs all HTTP request processing which is common to
@@ -6820,7 +6830,7 @@
        }
 
  skip_header_mangling:
-       if ((msg->flags & HTTP_MSGF_XFER_LEN) || HAS_FILTERS(s) ||
+       if ((msg->flags & HTTP_MSGF_XFER_LEN) || HAS_DATA_FILTERS(s, rep) ||
            (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_TUN) {
                rep->analysers &= ~AN_RES_FLT_XFER_DATA;
                rep->analysers |= AN_RES_HTTP_XFER_BODY;
@@ -6971,8 +6981,8 @@
         * keep-alive is set on the client side or if there are filters
         * registered on the stream, we don't want to forward a close
         */
-       if ((msg->flags & HTTP_MSGF_TE_CHNK) || !msg->body_len ||
-           HAS_FILTERS(s) ||
+       if ((msg->flags & HTTP_MSGF_TE_CHNK) || !(msg->flags & 
HTTP_MSGF_XFER_LEN) ||
+           HAS_DATA_FILTERS(s, res) ||
            (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
            (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL)
                channel_dont_close(res);
@@ -7064,11 +7074,10 @@
                goto missing_data_or_waiting;
        }
 
-       if (!(msg->flags & HTTP_MSGF_XFER_LEN) && !(chn->flags & CF_SHUTR) &&
-           HAS_DATA_FILTERS(s, chn)) {
-               /* The server still sending data that should be filtered */
+       /* The server still sending data that should be filtered */
+       if (!(msg->flags & HTTP_MSGF_XFER_LEN) && !(chn->flags & CF_SHUTR))
                goto missing_data_or_waiting;
-       }
+
        msg->msg_state = HTTP_MSG_ENDING;
 
   ending:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/proto_tcp.c 
new/haproxy-1.7.3/src/proto_tcp.c
--- old/haproxy-1.7.2/src/proto_tcp.c   2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/proto_tcp.c   2017-02-28 09:59:23.000000000 +0100
@@ -474,10 +474,16 @@
        if (global.tune.server_rcvbuf)
                 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, 
&global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf));
 
-       if ((connect(fd, (struct sockaddr *)&conn->addr.to, 
get_addr_len(&conn->addr.to)) == -1) &&
-           (errno != EINPROGRESS) && (errno != EALREADY) && (errno != 
EISCONN)) {
-
-               if (errno == EAGAIN || errno == EADDRINUSE || errno == 
EADDRNOTAVAIL) {
+       if (connect(fd, (struct sockaddr *)&conn->addr.to, 
get_addr_len(&conn->addr.to)) == -1) {
+               if (errno == EINPROGRESS || errno == EALREADY) {
+                       /* common case, let's wait for connect status */
+                       conn->flags |= CO_FL_WAIT_L4_CONN;
+               }
+               else if (errno == EISCONN) {
+                       /* should normally not happen but if so, indicates that 
it's OK */
+                       conn->flags &= ~CO_FL_WAIT_L4_CONN;
+               }
+               else if (errno == EAGAIN || errno == EADDRINUSE || errno == 
EADDRNOTAVAIL) {
                        char *msg;
                        if (errno == EAGAIN || errno == EADDRNOTAVAIL) {
                                msg = "no free ports";
@@ -514,6 +520,10 @@
                        return SF_ERR_SRVCL;
                }
        }
+       else {
+               /* connect() == 0, this is great! */
+               conn->flags &= ~CO_FL_WAIT_L4_CONN;
+       }
 
        conn->flags |= CO_FL_ADDR_TO_SET;
 
@@ -523,7 +533,6 @@
 
        conn_ctrl_init(conn);       /* registers the FD */
        fdtab[fd].linger_risk = 1;  /* close hard if needed */
-       conn_sock_want_send(conn);  /* for connect status */
 
        if (conn_xprt_init(conn) < 0) {
                conn_force_close(conn);
@@ -531,6 +540,17 @@
                return SF_ERR_RESOURCE;
        }
 
+       if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_WAIT_L4_CONN)) {
+               conn_sock_want_send(conn);  /* for connect status, proxy 
protocol or SSL */
+       }
+       else {
+               /* If there's no more handshake, we need to notify the data
+                * layer when the connection is already OK otherwise we'll have
+                * no other opportunity to do it later (eg: health checks).
+                */
+               data = 1;
+       }
+
        if (data)
                conn_data_want_send(conn);  /* prepare to send data if any */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/proto_uxst.c 
new/haproxy-1.7.3/src/proto_uxst.c
--- old/haproxy-1.7.2/src/proto_uxst.c  2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/proto_uxst.c  2017-02-28 09:59:23.000000000 +0100
@@ -495,12 +495,12 @@
                 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, 
&global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf));
 
        if (connect(fd, (struct sockaddr *)&conn->addr.to, 
get_addr_len(&conn->addr.to)) == -1) {
-               if (errno == EALREADY || errno == EISCONN) {
-                       conn->flags &= ~CO_FL_WAIT_L4_CONN;
-               }
-               else if (errno == EINPROGRESS) {
+               if (errno == EINPROGRESS || errno == EALREADY) {
                        conn->flags |= CO_FL_WAIT_L4_CONN;
                }
+               else if (errno == EISCONN) {
+                       conn->flags &= ~CO_FL_WAIT_L4_CONN;
+               }
                else if (errno == EAGAIN || errno == EADDRINUSE || errno == 
EADDRNOTAVAIL) {
                        char *msg;
                        if (errno == EAGAIN || errno == EADDRNOTAVAIL) {
@@ -533,13 +533,9 @@
        }
        else {
                /* connect() already succeeded, which is quite usual for unix
-                * sockets. Let's avoid a second connect() probe to complete it,
-                * but we need to ensure we'll wake up if there's no more 
handshake
-                * pending (eg: for health checks).
+                * sockets. Let's avoid a second connect() probe to complete it.
                 */
                conn->flags &= ~CO_FL_WAIT_L4_CONN;
-               if (!(conn->flags & CO_FL_HANDSHAKE))
-                       data = 1;
        }
 
        conn->flags |= CO_FL_ADDR_TO_SET;
@@ -550,8 +546,6 @@
 
        conn_ctrl_init(conn);       /* registers the FD */
        fdtab[fd].linger_risk = 0;  /* no need to disable lingering */
-       if (conn->flags & CO_FL_HANDSHAKE)
-               conn_sock_want_send(conn);  /* for connect status or proxy 
protocol */
 
        if (conn_xprt_init(conn) < 0) {
                conn_force_close(conn);
@@ -559,6 +553,17 @@
                return SF_ERR_RESOURCE;
        }
 
+       if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_WAIT_L4_CONN)) {
+               conn_sock_want_send(conn);  /* for connect status, proxy 
protocol or SSL */
+       }
+       else {
+               /* If there's no more handshake, we need to notify the data
+                * layer when the connection is already OK otherwise we'll have
+                * no other opportunity to do it later (eg: health checks).
+                */
+               data = 1;
+       }
+
        if (data)
                conn_data_want_send(conn);  /* prepare to send data if any */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-1.7.2/src/proxy.c 
new/haproxy-1.7.3/src/proxy.c
--- old/haproxy-1.7.2/src/proxy.c       2017-01-13 10:03:00.000000000 +0100
+++ new/haproxy-1.7.3/src/proxy.c       2017-02-28 09:59:23.000000000 +0100
@@ -1156,7 +1156,7 @@
         * be more reliable to store the list of analysers that have been run,
         * but what we do here is OK for now.
         */
-       s->req.analysers |= be->be_req_ana & (strm_li(s) ? 
~strm_li(s)->analysers : 0);
+       s->req.analysers |= be->be_req_ana & ~(strm_li(s) ? 
strm_li(s)->analysers : 0);
 
        /* If the target backend requires HTTP processing, we have to allocate
         * the HTTP transaction and hdr_idx if we did not have one.


Reply via email to